Debugger: Add segment breakpoints
This commit is contained in:
parent
b8c6bba712
commit
fcc8b5c805
@ -87,8 +87,8 @@ struct mDebuggerPlatform {
|
|||||||
void (*entered)(struct mDebuggerPlatform*, enum mDebuggerEntryReason, struct mDebuggerEntryInfo*);
|
void (*entered)(struct mDebuggerPlatform*, enum mDebuggerEntryReason, struct mDebuggerEntryInfo*);
|
||||||
|
|
||||||
bool (*hasBreakpoints)(struct mDebuggerPlatform*);
|
bool (*hasBreakpoints)(struct mDebuggerPlatform*);
|
||||||
void (*setBreakpoint)(struct mDebuggerPlatform*, uint32_t address);
|
void (*setBreakpoint)(struct mDebuggerPlatform*, uint32_t address, int segment);
|
||||||
void (*clearBreakpoint)(struct mDebuggerPlatform*, uint32_t address);
|
void (*clearBreakpoint)(struct mDebuggerPlatform*, uint32_t address, int segment);
|
||||||
void (*setWatchpoint)(struct mDebuggerPlatform*, uint32_t address, enum mWatchpointType type);
|
void (*setWatchpoint)(struct mDebuggerPlatform*, uint32_t address, enum mWatchpointType type);
|
||||||
void (*clearWatchpoint)(struct mDebuggerPlatform*, uint32_t address);
|
void (*clearWatchpoint)(struct mDebuggerPlatform*, uint32_t address);
|
||||||
void (*checkBreakpoints)(struct mDebuggerPlatform*);
|
void (*checkBreakpoints)(struct mDebuggerPlatform*);
|
||||||
|
@ -161,6 +161,8 @@ void GBMemorySwitchWramBank(struct GBMemory* memory, int bank);
|
|||||||
uint8_t GBLoad8(struct LR35902Core* cpu, uint16_t address);
|
uint8_t GBLoad8(struct LR35902Core* cpu, uint16_t address);
|
||||||
void GBStore8(struct LR35902Core* cpu, uint16_t address, int8_t value);
|
void GBStore8(struct LR35902Core* cpu, uint16_t address, int8_t value);
|
||||||
|
|
||||||
|
int GBCurrentSegment(struct LR35902Core* cpu, uint16_t address);
|
||||||
|
|
||||||
uint8_t GBView8(struct LR35902Core* cpu, uint16_t address, int segment);
|
uint8_t GBView8(struct LR35902Core* cpu, uint16_t address, int segment);
|
||||||
|
|
||||||
void GBMemoryDMA(struct GB* gb, uint16_t base);
|
void GBMemoryDMA(struct GB* gb, uint16_t base);
|
||||||
|
@ -54,6 +54,8 @@ struct LR35902Memory {
|
|||||||
uint8_t (*load8)(struct LR35902Core*, uint16_t address);
|
uint8_t (*load8)(struct LR35902Core*, uint16_t address);
|
||||||
void (*store8)(struct LR35902Core*, uint16_t address, int8_t value);
|
void (*store8)(struct LR35902Core*, uint16_t address, int8_t value);
|
||||||
|
|
||||||
|
int (*currentSegment)(struct LR35902Core*, uint16_t address);
|
||||||
|
|
||||||
uint8_t* activeRegion;
|
uint8_t* activeRegion;
|
||||||
uint16_t activeMask;
|
uint16_t activeMask;
|
||||||
uint16_t activeRegionEnd;
|
uint16_t activeRegionEnd;
|
||||||
|
@ -48,8 +48,8 @@ static void ARMDebuggerDeinit(struct mDebuggerPlatform* platform);
|
|||||||
|
|
||||||
static void ARMDebuggerEnter(struct mDebuggerPlatform* d, enum mDebuggerEntryReason reason, struct mDebuggerEntryInfo* info);
|
static void ARMDebuggerEnter(struct mDebuggerPlatform* d, enum mDebuggerEntryReason reason, struct mDebuggerEntryInfo* info);
|
||||||
|
|
||||||
static void ARMDebuggerSetBreakpoint(struct mDebuggerPlatform*, uint32_t address);
|
static void ARMDebuggerSetBreakpoint(struct mDebuggerPlatform*, uint32_t address, int segment);
|
||||||
static void ARMDebuggerClearBreakpoint(struct mDebuggerPlatform*, uint32_t address);
|
static void ARMDebuggerClearBreakpoint(struct mDebuggerPlatform*, uint32_t address, int segment);
|
||||||
static void ARMDebuggerSetWatchpoint(struct mDebuggerPlatform*, uint32_t address, enum mWatchpointType type);
|
static void ARMDebuggerSetWatchpoint(struct mDebuggerPlatform*, uint32_t address, enum mWatchpointType type);
|
||||||
static void ARMDebuggerClearWatchpoint(struct mDebuggerPlatform*, uint32_t address);
|
static void ARMDebuggerClearWatchpoint(struct mDebuggerPlatform*, uint32_t address);
|
||||||
static void ARMDebuggerCheckBreakpoints(struct mDebuggerPlatform*);
|
static void ARMDebuggerCheckBreakpoints(struct mDebuggerPlatform*);
|
||||||
@ -157,14 +157,16 @@ void ARMDebuggerClearSoftwareBreakpoint(struct mDebuggerPlatform* d, uint32_t ad
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
static void ARMDebuggerSetBreakpoint(struct mDebuggerPlatform* d, uint32_t address) {
|
static void ARMDebuggerSetBreakpoint(struct mDebuggerPlatform* d, uint32_t address, int segment) {
|
||||||
|
UNUSED(segment);
|
||||||
struct ARMDebugger* debugger = (struct ARMDebugger*) d;
|
struct ARMDebugger* debugger = (struct ARMDebugger*) d;
|
||||||
struct ARMDebugBreakpoint* breakpoint = ARMDebugBreakpointListAppend(&debugger->breakpoints);
|
struct ARMDebugBreakpoint* breakpoint = ARMDebugBreakpointListAppend(&debugger->breakpoints);
|
||||||
breakpoint->address = address;
|
breakpoint->address = address;
|
||||||
breakpoint->isSw = false;
|
breakpoint->isSw = false;
|
||||||
}
|
}
|
||||||
|
|
||||||
static void ARMDebuggerClearBreakpoint(struct mDebuggerPlatform* d, uint32_t address) {
|
static void ARMDebuggerClearBreakpoint(struct mDebuggerPlatform* d, uint32_t address, int segment) {
|
||||||
|
UNUSED(segment);
|
||||||
struct ARMDebugger* debugger = (struct ARMDebugger*) d;
|
struct ARMDebugger* debugger = (struct ARMDebugger*) d;
|
||||||
struct ARMDebugBreakpointList* breakpoints = &debugger->breakpoints;
|
struct ARMDebugBreakpointList* breakpoints = &debugger->breakpoints;
|
||||||
size_t i;
|
size_t i;
|
||||||
|
@ -409,7 +409,7 @@ static void _setBreakpoint(struct CLIDebugger* debugger, struct CLIDebugVector*
|
|||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
uint32_t address = dv->intValue;
|
uint32_t address = dv->intValue;
|
||||||
debugger->d.platform->setBreakpoint(debugger->d.platform, address);
|
debugger->d.platform->setBreakpoint(debugger->d.platform, address, dv->segmentValue);
|
||||||
}
|
}
|
||||||
|
|
||||||
static void _setWatchpoint(struct CLIDebugger* debugger, struct CLIDebugVector* dv) {
|
static void _setWatchpoint(struct CLIDebugger* debugger, struct CLIDebugVector* dv) {
|
||||||
@ -457,7 +457,7 @@ static void _clearBreakpoint(struct CLIDebugger* debugger, struct CLIDebugVector
|
|||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
uint32_t address = dv->intValue;
|
uint32_t address = dv->intValue;
|
||||||
debugger->d.platform->clearBreakpoint(debugger->d.platform, address);
|
debugger->d.platform->clearBreakpoint(debugger->d.platform, address, dv->segmentValue);
|
||||||
if (debugger->d.platform->clearWatchpoint) {
|
if (debugger->d.platform->clearWatchpoint) {
|
||||||
debugger->d.platform->clearWatchpoint(debugger->d.platform, address);
|
debugger->d.platform->clearWatchpoint(debugger->d.platform, address);
|
||||||
}
|
}
|
||||||
|
@ -495,7 +495,7 @@ static void _setBreakpoint(struct GDBStub* stub, const char* message) {
|
|||||||
ARMDebuggerSetSoftwareBreakpoint(stub->d.platform, address, kind == 2 ? MODE_THUMB : MODE_ARM);
|
ARMDebuggerSetSoftwareBreakpoint(stub->d.platform, address, kind == 2 ? MODE_THUMB : MODE_ARM);
|
||||||
break;
|
break;
|
||||||
case '1':
|
case '1':
|
||||||
stub->d.platform->setBreakpoint(stub->d.platform, address);
|
stub->d.platform->setBreakpoint(stub->d.platform, address, -1);
|
||||||
break;
|
break;
|
||||||
case '2':
|
case '2':
|
||||||
stub->d.platform->setWatchpoint(stub->d.platform, address, WATCHPOINT_WRITE);
|
stub->d.platform->setWatchpoint(stub->d.platform, address, WATCHPOINT_WRITE);
|
||||||
@ -524,7 +524,7 @@ static void _clearBreakpoint(struct GDBStub* stub, const char* message) {
|
|||||||
ARMDebuggerClearSoftwareBreakpoint(stub->d.platform, address);
|
ARMDebuggerClearSoftwareBreakpoint(stub->d.platform, address);
|
||||||
break;
|
break;
|
||||||
case '1':
|
case '1':
|
||||||
stub->d.platform->clearBreakpoint(stub->d.platform, address);
|
stub->d.platform->clearBreakpoint(stub->d.platform, address, -1);
|
||||||
break;
|
break;
|
||||||
case '2':
|
case '2':
|
||||||
case '3':
|
case '3':
|
||||||
|
@ -62,6 +62,7 @@ void GBMemoryInit(struct GB* gb) {
|
|||||||
cpu->memory.cpuLoad8 = GBLoad8;
|
cpu->memory.cpuLoad8 = GBLoad8;
|
||||||
cpu->memory.load8 = GBLoad8;
|
cpu->memory.load8 = GBLoad8;
|
||||||
cpu->memory.store8 = GBStore8;
|
cpu->memory.store8 = GBStore8;
|
||||||
|
cpu->memory.currentSegment = GBCurrentSegment;
|
||||||
cpu->memory.setActiveRegion = GBSetActiveRegion;
|
cpu->memory.setActiveRegion = GBSetActiveRegion;
|
||||||
|
|
||||||
gb->memory.wram = 0;
|
gb->memory.wram = 0;
|
||||||
@ -271,6 +272,37 @@ void GBStore8(struct LR35902Core* cpu, uint16_t address, int8_t value) {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
int GBCurrentSegment(struct LR35902Core* cpu, uint16_t address) {
|
||||||
|
struct GB* gb = (struct GB*) cpu->master;
|
||||||
|
struct GBMemory* memory = &gb->memory;
|
||||||
|
switch (address >> 12) {
|
||||||
|
case GB_REGION_CART_BANK0:
|
||||||
|
case GB_REGION_CART_BANK0 + 1:
|
||||||
|
case GB_REGION_CART_BANK0 + 2:
|
||||||
|
case GB_REGION_CART_BANK0 + 3:
|
||||||
|
return 0;
|
||||||
|
case GB_REGION_CART_BANK1:
|
||||||
|
case GB_REGION_CART_BANK1 + 1:
|
||||||
|
case GB_REGION_CART_BANK1 + 2:
|
||||||
|
case GB_REGION_CART_BANK1 + 3:
|
||||||
|
return memory->currentBank;
|
||||||
|
case GB_REGION_VRAM:
|
||||||
|
case GB_REGION_VRAM + 1:
|
||||||
|
return gb->video.vramCurrentBank;
|
||||||
|
case GB_REGION_EXTERNAL_RAM:
|
||||||
|
case GB_REGION_EXTERNAL_RAM + 1:
|
||||||
|
return memory->sramCurrentBank;
|
||||||
|
case GB_REGION_WORKING_RAM_BANK0:
|
||||||
|
case GB_REGION_WORKING_RAM_BANK0 + 2:
|
||||||
|
return 0;
|
||||||
|
case GB_REGION_WORKING_RAM_BANK1:
|
||||||
|
return memory->wramCurrentBank;
|
||||||
|
default:
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
uint8_t GBView8(struct LR35902Core* cpu, uint16_t address, int segment) {
|
uint8_t GBView8(struct LR35902Core* cpu, uint16_t address, int segment) {
|
||||||
struct GB* gb = (struct GB*) cpu->master;
|
struct GB* gb = (struct GB*) cpu->master;
|
||||||
struct GBMemory* memory = &gb->memory;
|
struct GBMemory* memory = &gb->memory;
|
||||||
|
@ -48,7 +48,7 @@ static void _disassemble(struct CLIDebuggerSystem* debugger, struct CLIDebugVect
|
|||||||
|
|
||||||
size_t i;
|
size_t i;
|
||||||
for (i = 0; i < size; ++i) {
|
for (i = 0; i < size; ++i) {
|
||||||
address = _printLine(debugger->p, address, -1);
|
address = _printLine(debugger->p, address, dv->segmentValue);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -58,7 +58,7 @@ static inline uint16_t _printLine(struct CLIDebugger* debugger, uint16_t address
|
|||||||
char disassembly[48];
|
char disassembly[48];
|
||||||
char* disPtr = disassembly;
|
char* disPtr = disassembly;
|
||||||
if (segment >= 0) {
|
if (segment >= 0) {
|
||||||
be->printf(be, "%02X: ", segment);
|
be->printf(be, "%02X:", segment);
|
||||||
}
|
}
|
||||||
be->printf(be, "%04X: ", address);
|
be->printf(be, "%04X: ", address);
|
||||||
uint8_t instruction;
|
uint8_t instruction;
|
||||||
@ -85,7 +85,7 @@ static void _printStatus(struct CLIDebuggerSystem* debugger) {
|
|||||||
be->printf(be, "H: %02X L: %02X (HL: %04X)\n", cpu->h, cpu->l, cpu->hl);
|
be->printf(be, "H: %02X L: %02X (HL: %04X)\n", cpu->h, cpu->l, cpu->hl);
|
||||||
be->printf(be, "PC: %04X SP: %04X\n", cpu->pc, cpu->sp);
|
be->printf(be, "PC: %04X SP: %04X\n", cpu->pc, cpu->sp);
|
||||||
_printFlags(be, cpu->f);
|
_printFlags(be, cpu->f);
|
||||||
_printLine(debugger->p, cpu->pc, -1);
|
_printLine(debugger->p, cpu->pc, cpu->memory.currentSegment(cpu, cpu->pc));
|
||||||
}
|
}
|
||||||
|
|
||||||
static uint32_t _lookupPlatformIdentifier(struct CLIDebuggerSystem* debugger, const char* name, struct CLIDebugVector* dv) {
|
static uint32_t _lookupPlatformIdentifier(struct CLIDebuggerSystem* debugger, const char* name, struct CLIDebugVector* dv) {
|
||||||
|
@ -27,7 +27,9 @@ static void LR35902DebuggerCheckBreakpoints(struct mDebuggerPlatform* d) {
|
|||||||
if (!breakpoint) {
|
if (!breakpoint) {
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
// TODO: Segments
|
if (breakpoint->segment >= 0 && debugger->cpu->memory.currentSegment(debugger->cpu, breakpoint->address) != breakpoint->segment) {
|
||||||
|
return;
|
||||||
|
}
|
||||||
struct mDebuggerEntryInfo info = {
|
struct mDebuggerEntryInfo info = {
|
||||||
.address = breakpoint->address
|
.address = breakpoint->address
|
||||||
};
|
};
|
||||||
@ -39,8 +41,8 @@ static void LR35902DebuggerDeinit(struct mDebuggerPlatform* platform);
|
|||||||
|
|
||||||
static void LR35902DebuggerEnter(struct mDebuggerPlatform* d, enum mDebuggerEntryReason reason, struct mDebuggerEntryInfo* info);
|
static void LR35902DebuggerEnter(struct mDebuggerPlatform* d, enum mDebuggerEntryReason reason, struct mDebuggerEntryInfo* info);
|
||||||
|
|
||||||
static void LR35902DebuggerSetBreakpoint(struct mDebuggerPlatform*, uint32_t address);
|
static void LR35902DebuggerSetBreakpoint(struct mDebuggerPlatform*, uint32_t address, int segment);
|
||||||
static void LR35902DebuggerClearBreakpoint(struct mDebuggerPlatform*, uint32_t address);
|
static void LR35902DebuggerClearBreakpoint(struct mDebuggerPlatform*, uint32_t address, int segment);
|
||||||
static void LR35902DebuggerCheckBreakpoints(struct mDebuggerPlatform*);
|
static void LR35902DebuggerCheckBreakpoints(struct mDebuggerPlatform*);
|
||||||
static bool LR35902DebuggerHasBreakpoints(struct mDebuggerPlatform*);
|
static bool LR35902DebuggerHasBreakpoints(struct mDebuggerPlatform*);
|
||||||
|
|
||||||
@ -79,19 +81,20 @@ static void LR35902DebuggerEnter(struct mDebuggerPlatform* platform, enum mDebug
|
|||||||
cpu->nextEvent = cpu->cycles;
|
cpu->nextEvent = cpu->cycles;
|
||||||
}
|
}
|
||||||
|
|
||||||
static void LR35902DebuggerSetBreakpoint(struct mDebuggerPlatform* d, uint32_t address) {
|
static void LR35902DebuggerSetBreakpoint(struct mDebuggerPlatform* d, uint32_t address, int segment) {
|
||||||
struct LR35902Debugger* debugger = (struct LR35902Debugger*) d;
|
struct LR35902Debugger* debugger = (struct LR35902Debugger*) d;
|
||||||
struct LR35902DebugBreakpoint* breakpoint = LR35902DebugBreakpointListAppend(&debugger->breakpoints);
|
struct LR35902DebugBreakpoint* breakpoint = LR35902DebugBreakpointListAppend(&debugger->breakpoints);
|
||||||
breakpoint->address = address;
|
breakpoint->address = address;
|
||||||
breakpoint->segment = -1;
|
breakpoint->segment = segment;
|
||||||
}
|
}
|
||||||
|
|
||||||
static void LR35902DebuggerClearBreakpoint(struct mDebuggerPlatform* d, uint32_t address) {
|
static void LR35902DebuggerClearBreakpoint(struct mDebuggerPlatform* d, uint32_t address, int segment) {
|
||||||
struct LR35902Debugger* debugger = (struct LR35902Debugger*) d;
|
struct LR35902Debugger* debugger = (struct LR35902Debugger*) d;
|
||||||
struct LR35902DebugBreakpointList* breakpoints = &debugger->breakpoints;
|
struct LR35902DebugBreakpointList* breakpoints = &debugger->breakpoints;
|
||||||
size_t i;
|
size_t i;
|
||||||
for (i = 0; i < LR35902DebugBreakpointListSize(breakpoints); ++i) {
|
for (i = 0; i < LR35902DebugBreakpointListSize(breakpoints); ++i) {
|
||||||
if (LR35902DebugBreakpointListGetPointer(breakpoints, i)->address == address) {
|
struct LR35902DebugBreakpoint* breakpoint = LR35902DebugBreakpointListGetPointer(breakpoints, i);
|
||||||
|
if (breakpoint->address == address && breakpoint->segment == segment) {
|
||||||
LR35902DebugBreakpointListShift(breakpoints, i, 1);
|
LR35902DebugBreakpointListShift(breakpoints, i, 1);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
Loading…
x
Reference in New Issue
Block a user