diff --git a/include/mgba/debugger/debugger.h b/include/mgba/debugger/debugger.h
index 230a95564..d295f71e9 100644
--- a/include/mgba/debugger/debugger.h
+++ b/include/mgba/debugger/debugger.h
@@ -133,6 +133,7 @@ struct mBreakpoint {
int segment;
enum mBreakpointType type;
struct ParseTree* condition;
+ bool isTemporary;
};
struct mWatchpoint {
diff --git a/src/arm/debugger/debugger.c b/src/arm/debugger/debugger.c
index c9631e56b..7584d4082 100644
--- a/src/arm/debugger/debugger.c
+++ b/src/arm/debugger/debugger.c
@@ -218,6 +218,11 @@ static void ARMDebuggerCheckBreakpoints(struct mDebuggerPlatform* d) {
.target = TableLookup(&d->p->pointOwner, breakpoint->d.id)
};
mDebuggerEnter(d->p, DEBUGGER_ENTER_BREAKPOINT, &info);
+ if (breakpoint->d.isTemporary) {
+ _destroyBreakpoint(debugger->d.p, breakpoint);
+ ARMDebugBreakpointListShift(&debugger->breakpoints, i, 1);
+ --i;
+ }
}
}
@@ -323,7 +328,10 @@ static void ARMDebuggerEnter(struct mDebuggerPlatform* platform, enum mDebuggerE
ARMRunFake(cpu, breakpoint->sw.opcode);
- if (debugger->setSoftwareBreakpoint) {
+ if (breakpoint->d.isTemporary) {
+ _destroyBreakpoint(debugger->d.p, breakpoint);
+ ARMDebugBreakpointListShift(&debugger->swBreakpoints, i, 1);
+ } else if (debugger->setSoftwareBreakpoint) {
debugger->setSoftwareBreakpoint(debugger, breakpoint->d.address, breakpoint->sw.mode, &breakpoint->sw.opcode);
}
break;
diff --git a/src/debugger/gdb-stub.c b/src/debugger/gdb-stub.c
index 6d419ac95..1e1fd35a5 100644
--- a/src/debugger/gdb-stub.c
+++ b/src/debugger/gdb-stub.c
@@ -255,7 +255,25 @@ static void _continue(struct GDBStub* stub, const char* message) {
}
static void _step(struct GDBStub* stub, const char* message) {
+ const struct ARMCore* cpu = stub->d.p->core->cpu;
+ const int32_t pc = cpu->gprs[ARM_PC];
+
stub->d.p->core->step(stub->d.p->core);
+
+ if (pc >= GBA_SIZE_BIOS && cpu->gprs[ARM_PC] < GBA_SIZE_BIOS) {
+ // GDB cannot cope with jumps into BIOS
+ // skip over them by placing a temporary breakpoint at PC (instruction after the jump)
+ // and then continue without sending a GDB SIGTRAP
+ const struct mBreakpoint breakpoint = {
+ .address = pc,
+ .type = BREAKPOINT_HARDWARE,
+ .isTemporary = true
+ };
+ stub->d.p->platform->setBreakpoint(stub->d.p->platform, &stub->d, &breakpoint);
+ _continue(stub, message);
+ return;
+ }
+
snprintf(stub->outgoing, GDB_STUB_MAX_LINE - 4, "S%02x", SIGTRAP);
_sendMessage(stub);
// TODO: parse message
diff --git a/src/platform/qt/ts/mgba-it.ts b/src/platform/qt/ts/mgba-it.ts
index a2b83e6e4..28167d649 100644
--- a/src/platform/qt/ts/mgba-it.ts
+++ b/src/platform/qt/ts/mgba-it.ts
@@ -5417,7 +5417,7 @@ If it is set to OpenGL and you still see this, your graphics card or drivers may
GBC compatible:
- Compatibile BGC:
+ Compatibile GBC:
diff --git a/src/sm83/debugger/debugger.c b/src/sm83/debugger/debugger.c
index 4f90a5691..1d0265d50 100644
--- a/src/sm83/debugger/debugger.c
+++ b/src/sm83/debugger/debugger.c
@@ -53,6 +53,11 @@ static void SM83DebuggerCheckBreakpoints(struct mDebuggerPlatform* d) {
.target = TableLookup(&d->p->pointOwner, breakpoint->id)
};
mDebuggerEnter(d->p, DEBUGGER_ENTER_BREAKPOINT, &info);
+ if (breakpoint->isTemporary) {
+ _destroyBreakpoint(debugger->d.p, breakpoint);
+ mBreakpointListShift(&debugger->breakpoints, i, 1);
+ --i;
+ }
}
}