Debugger: Add segment breakpoints

This commit is contained in:
Vicki Pfau 2017-05-22 19:39:27 -07:00
parent b8c6bba712
commit fcc8b5c805
9 changed files with 61 additions and 20 deletions

View File

@ -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*);

View File

@ -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);

View File

@ -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;

View File

@ -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;

View File

@ -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);
} }

View File

@ -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':

View File

@ -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;

View File

@ -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) {

View File

@ -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);
} }
} }