all repos — mgba @ fcc8b5c8052ae6bd4b4e7931ceb60461cee69605

mGBA Game Boy Advance Emulator

Debugger: Add segment breakpoints
Vicki Pfau vi@endrift.com
Mon, 22 May 2017 19:39:27 -0700
commit

fcc8b5c8052ae6bd4b4e7931ceb60461cee69605

parent

b8c6bba71205aad260a8aec5ec12fe2ad094d215

M include/mgba/internal/debugger/debugger.hinclude/mgba/internal/debugger/debugger.h

@@ -87,8 +87,8 @@ void (*deinit)(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*);
M include/mgba/internal/gb/memory.hinclude/mgba/internal/gb/memory.h

@@ -161,6 +161,8 @@

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);
M include/mgba/internal/lr35902/lr35902.hinclude/mgba/internal/lr35902/lr35902.h

@@ -54,6 +54,8 @@ uint8_t (*cpuLoad8)(struct LR35902Core*, uint16_t address);

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;
M src/arm/debugger/debugger.csrc/arm/debugger/debugger.c

@@ -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 @@ debugger->clearSoftwareBreakpoint(debugger, address, breakpoint->sw.mode, breakpoint->sw.opcode);

} } -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;
M src/debugger/cli-debugger.csrc/debugger/cli-debugger.c

@@ -409,7 +409,7 @@ debugger->backend->printf(debugger->backend, "%s\n", ERROR_MISSING_ARGS);

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 @@ debugger->backend->printf(debugger->backend, "%s\n", ERROR_MISSING_ARGS);

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); }
M src/debugger/gdb-stub.csrc/debugger/gdb-stub.c

@@ -495,7 +495,7 @@ case '0':

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

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':
M src/gb/memory.csrc/gb/memory.c

@@ -62,6 +62,7 @@ struct LR35902Core* cpu = gb->cpu;

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 @@ GBIOWrite(gb, REG_IE, 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;
M src/lr35902/debugger/cli-debugger.csrc/lr35902/debugger/cli-debugger.c

@@ -48,7 +48,7 @@ }

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 @@ struct LR35902InstructionInfo info = {0};

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 @@ be->printf(be, "D: %02X E: %02X (DE: %04X)\n", cpu->d, cpu->e, cpu->de);

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) {
M src/lr35902/debugger/debugger.csrc/lr35902/debugger/debugger.c

@@ -27,7 +27,9 @@ struct LR35902DebugBreakpoint* breakpoint = _lookupBreakpoint(&debugger->breakpoints, debugger->cpu->pc);

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 @@ struct LR35902Core* cpu = debugger->cpu;

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