mirror of https://github.com/mgba-emu/mgba.git
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*);
|
||||
|
||||
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*);
|
||||
|
|
|
@ -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);
|
||||
|
|
|
@ -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;
|
||||
|
|
|
@ -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;
|
||||
|
|
|
@ -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);
|
||||
}
|
||||
|
|
|
@ -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':
|
||||
|
|
|
@ -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;
|
||||
|
|
|
@ -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) {
|
||||
|
|
|
@ -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);
|
||||
}
|
||||
}
|
||||
|
|
Loading…
Reference in New Issue