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*);
bool (*hasBreakpoints)(struct mDebuggerPlatform*);
void (*setBreakpoint)(struct mDebuggerPlatform*, uint32_t address);
void (*clearBreakpoint)(struct mDebuggerPlatform*, uint32_t address);
void (*setBreakpoint)(struct mDebuggerPlatform*, uint32_t address, int segment);
void (*clearBreakpoint)(struct mDebuggerPlatform*, uint32_t address, int segment);
void (*setWatchpoint)(struct mDebuggerPlatform*, uint32_t address, enum mWatchpointType type);
void (*clearWatchpoint)(struct mDebuggerPlatform*, uint32_t address);
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);
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);
void GBMemoryDMA(struct GB* gb, uint16_t base);

View File

@ -54,6 +54,8 @@ struct LR35902Memory {
uint8_t (*load8)(struct LR35902Core*, uint16_t address);
void (*store8)(struct LR35902Core*, uint16_t address, int8_t value);
int (*currentSegment)(struct LR35902Core*, uint16_t address);
uint8_t* activeRegion;
uint16_t activeMask;
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 ARMDebuggerSetBreakpoint(struct mDebuggerPlatform*, uint32_t address);
static void ARMDebuggerClearBreakpoint(struct mDebuggerPlatform*, uint32_t address);
static void ARMDebuggerSetBreakpoint(struct mDebuggerPlatform*, uint32_t address, int segment);
static void ARMDebuggerClearBreakpoint(struct mDebuggerPlatform*, uint32_t address, int segment);
static void ARMDebuggerSetWatchpoint(struct mDebuggerPlatform*, uint32_t address, enum mWatchpointType type);
static void ARMDebuggerClearWatchpoint(struct mDebuggerPlatform*, uint32_t address);
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 ARMDebugBreakpoint* breakpoint = ARMDebugBreakpointListAppend(&debugger->breakpoints);
breakpoint->address = address;
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 ARMDebugBreakpointList* breakpoints = &debugger->breakpoints;
size_t i;

View File

@ -409,7 +409,7 @@ static void _setBreakpoint(struct CLIDebugger* debugger, struct CLIDebugVector*
return;
}
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) {
@ -457,7 +457,7 @@ static void _clearBreakpoint(struct CLIDebugger* debugger, struct CLIDebugVector
return;
}
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) {
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);
break;
case '1':
stub->d.platform->setBreakpoint(stub->d.platform, address);
stub->d.platform->setBreakpoint(stub->d.platform, address, -1);
break;
case '2':
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);
break;
case '1':
stub->d.platform->clearBreakpoint(stub->d.platform, address);
stub->d.platform->clearBreakpoint(stub->d.platform, address, -1);
break;
case '2':
case '3':

View File

@ -62,6 +62,7 @@ void GBMemoryInit(struct GB* gb) {
cpu->memory.cpuLoad8 = GBLoad8;
cpu->memory.load8 = GBLoad8;
cpu->memory.store8 = GBStore8;
cpu->memory.currentSegment = GBCurrentSegment;
cpu->memory.setActiveRegion = GBSetActiveRegion;
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) {
struct GB* gb = (struct GB*) cpu->master;
struct GBMemory* memory = &gb->memory;

View File

@ -48,7 +48,7 @@ static void _disassemble(struct CLIDebuggerSystem* debugger, struct CLIDebugVect
size_t 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* disPtr = disassembly;
if (segment >= 0) {
be->printf(be, "%02X: ", segment);
be->printf(be, "%02X:", segment);
}
be->printf(be, "%04X: ", address);
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, "PC: %04X SP: %04X\n", cpu->pc, cpu->sp);
_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) {

View File

@ -27,7 +27,9 @@ static void LR35902DebuggerCheckBreakpoints(struct mDebuggerPlatform* d) {
if (!breakpoint) {
return;
}
// TODO: Segments
if (breakpoint->segment >= 0 && debugger->cpu->memory.currentSegment(debugger->cpu, breakpoint->address) != breakpoint->segment) {
return;
}
struct mDebuggerEntryInfo info = {
.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 LR35902DebuggerSetBreakpoint(struct mDebuggerPlatform*, uint32_t address);
static void LR35902DebuggerClearBreakpoint(struct mDebuggerPlatform*, uint32_t address);
static void LR35902DebuggerSetBreakpoint(struct mDebuggerPlatform*, uint32_t address, int segment);
static void LR35902DebuggerClearBreakpoint(struct mDebuggerPlatform*, uint32_t address, int segment);
static void LR35902DebuggerCheckBreakpoints(struct mDebuggerPlatform*);
static bool LR35902DebuggerHasBreakpoints(struct mDebuggerPlatform*);
@ -79,19 +81,20 @@ static void LR35902DebuggerEnter(struct mDebuggerPlatform* platform, enum mDebug
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 LR35902DebugBreakpoint* breakpoint = LR35902DebugBreakpointListAppend(&debugger->breakpoints);
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 LR35902DebugBreakpointList* breakpoints = &debugger->breakpoints;
size_t 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);
}
}