Debugger: Add CLI "frame", frame advance command
Jeffrey Pfau jeffrey@endrift.com
Sat, 20 Dec 2014 01:43:48 -0800
7 files changed,
58 insertions(+),
2 deletions(-)
M
CHANGES
→
CHANGES
@@ -2,6 +2,7 @@ 0.2.0: (Future)
Features: - Support for gamepad axes, e.g. analog sticks or triggers - Add scale presets for up to 6x + - Debugger: Add CLI "frame", frame advance command Bugfixes: - Qt: Fix issue with set frame sizes being the wrong height - Qt: Fix emulator crashing when full screen if a game is not running
M
src/debugger/cli-debugger.c
→
src/debugger/cli-debugger.c
@@ -684,10 +684,22 @@ cliDebugger->system = 0;
} } +static void _cliDebuggerCustom(struct ARMDebugger* debugger) { + struct CLIDebugger* cliDebugger = (struct CLIDebugger*) debugger; + bool retain = false; + if (cliDebugger->system) { + retain = cliDebugger->system->custom(cliDebugger->system); + } + if (!retain && debugger->state == DEBUGGER_CUSTOM) { + debugger->state = DEBUGGER_RUNNING; + } +} + void CLIDebuggerCreate(struct CLIDebugger* debugger) { ARMDebuggerCreate(&debugger->d); debugger->d.init = _cliDebuggerInit; debugger->d.deinit = _cliDebuggerDeinit; + debugger->d.custom = _cliDebuggerCustom; debugger->d.paused = _commandLine; debugger->d.entered = _reportEntry;
M
src/debugger/cli-debugger.h
→
src/debugger/cli-debugger.h
@@ -43,6 +43,7 @@ struct CLIDebugger* p;
void (*init)(struct CLIDebuggerSystem*); void (*deinit)(struct CLIDebuggerSystem*); + bool (*custom)(struct CLIDebuggerSystem*); uint32_t (*lookupIdentifier)(struct CLIDebuggerSystem*, const char* name, struct CLIDebugVector* dv);
M
src/debugger/debugger.c
→
src/debugger/debugger.c
@@ -61,7 +61,7 @@ }
while (debugger->state < DEBUGGER_EXITING) { if (!debugger->breakpoints) { while (debugger->state == DEBUGGER_RUNNING) { - ARMRun(debugger->cpu); + ARMRunLoop(debugger->cpu); } } else { while (debugger->state == DEBUGGER_RUNNING) {@@ -71,6 +71,13 @@ }
} switch (debugger->state) { case DEBUGGER_RUNNING: + break; + case DEBUGGER_CUSTOM: + while (debugger->state == DEBUGGER_CUSTOM) { + ARMRun(debugger->cpu); + _checkBreakpoints(debugger); + debugger->custom(debugger); + } break; case DEBUGGER_PAUSED: if (debugger->paused) {
M
src/debugger/debugger.h
→
src/debugger/debugger.h
@@ -15,6 +15,7 @@
enum DebuggerState { DEBUGGER_PAUSED, DEBUGGER_RUNNING, + DEBUGGER_CUSTOM, DEBUGGER_EXITING, DEBUGGER_SHUTDOWN };@@ -52,6 +53,7 @@ void (*init)(struct ARMDebugger*);
void (*deinit)(struct ARMDebugger*); void (*paused)(struct ARMDebugger*); void (*entered)(struct ARMDebugger*, enum DebuggerEntryReason); + void (*custom)(struct ARMDebugger*); __attribute__((format (printf, 3, 4))) void (*log)(struct ARMDebugger*, enum DebuggerLogLevel, const char* format, ...);
M
src/gba/gba-cli.c
→
src/gba/gba-cli.c
@@ -15,12 +15,15 @@ static const char* ERROR_MISSING_ARGS = "Arguments missing"; // TODO: share
static void _GBACLIDebuggerInit(struct CLIDebuggerSystem*); static void _GBACLIDebuggerDeinit(struct CLIDebuggerSystem*); +static bool _GBACLIDebuggerCustom(struct CLIDebuggerSystem*); static uint32_t _GBACLIDebuggerLookupIdentifier(struct CLIDebuggerSystem*, const char* name, struct CLIDebugVector* dv); +static void _frame(struct CLIDebugger*, struct CLIDebugVector*); static void _load(struct CLIDebugger*, struct CLIDebugVector*); static void _save(struct CLIDebugger*, struct CLIDebugVector*); struct CLIDebuggerCommandSummary _GBACLIDebuggerCommands[] = { + { "frame", _frame, 0, "Frame advance" }, { "load", _load, CLIDVParse, "Load a savestate" }, { "save", _save, CLIDVParse, "Save a savestate" }, { 0, 0, 0, 0 }@@ -32,6 +35,7 @@ struct GBACLIDebugger* debugger = malloc(sizeof(struct GBACLIDebugger));
#ifdef USE_CLI_DEBUGGER debugger->d.init = _GBACLIDebuggerInit; debugger->d.deinit = _GBACLIDebuggerDeinit; + debugger->d.custom = _GBACLIDebuggerCustom; debugger->d.lookupIdentifier = _GBACLIDebuggerLookupIdentifier; debugger->d.name = "Game Boy Advance";@@ -45,13 +49,30 @@ }
#ifdef USE_CLI_DEBUGGER static void _GBACLIDebuggerInit(struct CLIDebuggerSystem* debugger) { - UNUSED(debugger); + struct GBACLIDebugger* gbaDebugger = (struct GBACLIDebugger*) debugger; + + gbaDebugger->frameAdvance = false; } static void _GBACLIDebuggerDeinit(struct CLIDebuggerSystem* debugger) { UNUSED(debugger); } +static bool _GBACLIDebuggerCustom(struct CLIDebuggerSystem* debugger) { + struct GBACLIDebugger* gbaDebugger = (struct GBACLIDebugger*) debugger; + + if (gbaDebugger->frameAdvance) { + if (!gbaDebugger->inVblank && GBARegisterDISPSTATIsInVblank(gbaDebugger->context->gba->video.dispstat)) { + ARMDebuggerEnter(&gbaDebugger->d.p->d, DEBUGGER_ENTER_BREAKPOINT); + gbaDebugger->frameAdvance = false; + return false; + } + gbaDebugger->inVblank = GBARegisterDISPSTATGetInVblank(gbaDebugger->context->gba->video.dispstat); + return true; + } + return false; +} + static uint32_t _GBACLIDebuggerLookupIdentifier(struct CLIDebuggerSystem* debugger, const char* name, struct CLIDebugVector* dv) { struct GBACLIDebugger* gbaDebugger = (struct GBACLIDebugger*) debugger; int i;@@ -63,6 +84,15 @@ }
} dv->type = CLIDV_ERROR_TYPE; return 0; +} + +static void _frame(struct CLIDebugger* debugger, struct CLIDebugVector* dv) { + UNUSED(dv); + debugger->d.state = DEBUGGER_CUSTOM; + + struct GBACLIDebugger* gbaDebugger = (struct GBACLIDebugger*) debugger->system; + gbaDebugger->frameAdvance = true; + gbaDebugger->inVblank = GBARegisterDISPSTATGetInVblank(gbaDebugger->context->gba->video.dispstat); } static void _load(struct CLIDebugger* debugger, struct CLIDebugVector* dv) {
M
src/gba/gba-cli.h
→
src/gba/gba-cli.h
@@ -15,6 +15,9 @@ #ifdef USE_CLI_DEBUGGER
struct CLIDebuggerSystem d; struct GBAThread* context; + + bool frameAdvance; + bool inVblank; #endif };