mirror of https://github.com/mgba-emu/mgba.git
Debugger: Add CLI "frame", frame advance command
This commit is contained in:
parent
9aed9754d0
commit
da612b51e8
1
CHANGES
1
CHANGES
|
@ -2,6 +2,7 @@
|
||||||
Features:
|
Features:
|
||||||
- Support for gamepad axes, e.g. analog sticks or triggers
|
- Support for gamepad axes, e.g. analog sticks or triggers
|
||||||
- Add scale presets for up to 6x
|
- Add scale presets for up to 6x
|
||||||
|
- Debugger: Add CLI "frame", frame advance command
|
||||||
Bugfixes:
|
Bugfixes:
|
||||||
- Qt: Fix issue with set frame sizes being the wrong height
|
- Qt: Fix issue with set frame sizes being the wrong height
|
||||||
- Qt: Fix emulator crashing when full screen if a game is not running
|
- Qt: Fix emulator crashing when full screen if a game is not running
|
||||||
|
|
|
@ -684,10 +684,22 @@ static void _cliDebuggerDeinit(struct ARMDebugger* debugger) {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
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) {
|
void CLIDebuggerCreate(struct CLIDebugger* debugger) {
|
||||||
ARMDebuggerCreate(&debugger->d);
|
ARMDebuggerCreate(&debugger->d);
|
||||||
debugger->d.init = _cliDebuggerInit;
|
debugger->d.init = _cliDebuggerInit;
|
||||||
debugger->d.deinit = _cliDebuggerDeinit;
|
debugger->d.deinit = _cliDebuggerDeinit;
|
||||||
|
debugger->d.custom = _cliDebuggerCustom;
|
||||||
debugger->d.paused = _commandLine;
|
debugger->d.paused = _commandLine;
|
||||||
debugger->d.entered = _reportEntry;
|
debugger->d.entered = _reportEntry;
|
||||||
|
|
||||||
|
|
|
@ -43,6 +43,7 @@ struct CLIDebuggerSystem {
|
||||||
|
|
||||||
void (*init)(struct CLIDebuggerSystem*);
|
void (*init)(struct CLIDebuggerSystem*);
|
||||||
void (*deinit)(struct CLIDebuggerSystem*);
|
void (*deinit)(struct CLIDebuggerSystem*);
|
||||||
|
bool (*custom)(struct CLIDebuggerSystem*);
|
||||||
|
|
||||||
uint32_t (*lookupIdentifier)(struct CLIDebuggerSystem*, const char* name, struct CLIDebugVector* dv);
|
uint32_t (*lookupIdentifier)(struct CLIDebuggerSystem*, const char* name, struct CLIDebugVector* dv);
|
||||||
|
|
||||||
|
|
|
@ -61,7 +61,7 @@ void ARMDebuggerRun(struct ARMDebugger* debugger) {
|
||||||
while (debugger->state < DEBUGGER_EXITING) {
|
while (debugger->state < DEBUGGER_EXITING) {
|
||||||
if (!debugger->breakpoints) {
|
if (!debugger->breakpoints) {
|
||||||
while (debugger->state == DEBUGGER_RUNNING) {
|
while (debugger->state == DEBUGGER_RUNNING) {
|
||||||
ARMRun(debugger->cpu);
|
ARMRunLoop(debugger->cpu);
|
||||||
}
|
}
|
||||||
} else {
|
} else {
|
||||||
while (debugger->state == DEBUGGER_RUNNING) {
|
while (debugger->state == DEBUGGER_RUNNING) {
|
||||||
|
@ -72,6 +72,13 @@ void ARMDebuggerRun(struct ARMDebugger* debugger) {
|
||||||
switch (debugger->state) {
|
switch (debugger->state) {
|
||||||
case DEBUGGER_RUNNING:
|
case DEBUGGER_RUNNING:
|
||||||
break;
|
break;
|
||||||
|
case DEBUGGER_CUSTOM:
|
||||||
|
while (debugger->state == DEBUGGER_CUSTOM) {
|
||||||
|
ARMRun(debugger->cpu);
|
||||||
|
_checkBreakpoints(debugger);
|
||||||
|
debugger->custom(debugger);
|
||||||
|
}
|
||||||
|
break;
|
||||||
case DEBUGGER_PAUSED:
|
case DEBUGGER_PAUSED:
|
||||||
if (debugger->paused) {
|
if (debugger->paused) {
|
||||||
debugger->paused(debugger);
|
debugger->paused(debugger);
|
||||||
|
|
|
@ -15,6 +15,7 @@ extern const uint32_t ARM_DEBUGGER_ID;
|
||||||
enum DebuggerState {
|
enum DebuggerState {
|
||||||
DEBUGGER_PAUSED,
|
DEBUGGER_PAUSED,
|
||||||
DEBUGGER_RUNNING,
|
DEBUGGER_RUNNING,
|
||||||
|
DEBUGGER_CUSTOM,
|
||||||
DEBUGGER_EXITING,
|
DEBUGGER_EXITING,
|
||||||
DEBUGGER_SHUTDOWN
|
DEBUGGER_SHUTDOWN
|
||||||
};
|
};
|
||||||
|
@ -52,6 +53,7 @@ struct ARMDebugger {
|
||||||
void (*deinit)(struct ARMDebugger*);
|
void (*deinit)(struct ARMDebugger*);
|
||||||
void (*paused)(struct ARMDebugger*);
|
void (*paused)(struct ARMDebugger*);
|
||||||
void (*entered)(struct ARMDebugger*, enum DebuggerEntryReason);
|
void (*entered)(struct ARMDebugger*, enum DebuggerEntryReason);
|
||||||
|
void (*custom)(struct ARMDebugger*);
|
||||||
|
|
||||||
__attribute__((format (printf, 3, 4)))
|
__attribute__((format (printf, 3, 4)))
|
||||||
void (*log)(struct ARMDebugger*, enum DebuggerLogLevel, const char* format, ...);
|
void (*log)(struct ARMDebugger*, enum DebuggerLogLevel, const char* format, ...);
|
||||||
|
|
|
@ -15,12 +15,15 @@ static const char* ERROR_MISSING_ARGS = "Arguments missing"; // TODO: share
|
||||||
|
|
||||||
static void _GBACLIDebuggerInit(struct CLIDebuggerSystem*);
|
static void _GBACLIDebuggerInit(struct CLIDebuggerSystem*);
|
||||||
static void _GBACLIDebuggerDeinit(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 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 _load(struct CLIDebugger*, struct CLIDebugVector*);
|
||||||
static void _save(struct CLIDebugger*, struct CLIDebugVector*);
|
static void _save(struct CLIDebugger*, struct CLIDebugVector*);
|
||||||
|
|
||||||
struct CLIDebuggerCommandSummary _GBACLIDebuggerCommands[] = {
|
struct CLIDebuggerCommandSummary _GBACLIDebuggerCommands[] = {
|
||||||
|
{ "frame", _frame, 0, "Frame advance" },
|
||||||
{ "load", _load, CLIDVParse, "Load a savestate" },
|
{ "load", _load, CLIDVParse, "Load a savestate" },
|
||||||
{ "save", _save, CLIDVParse, "Save a savestate" },
|
{ "save", _save, CLIDVParse, "Save a savestate" },
|
||||||
{ 0, 0, 0, 0 }
|
{ 0, 0, 0, 0 }
|
||||||
|
@ -32,6 +35,7 @@ struct GBACLIDebugger* GBACLIDebuggerCreate(struct GBAThread* context) {
|
||||||
#ifdef USE_CLI_DEBUGGER
|
#ifdef USE_CLI_DEBUGGER
|
||||||
debugger->d.init = _GBACLIDebuggerInit;
|
debugger->d.init = _GBACLIDebuggerInit;
|
||||||
debugger->d.deinit = _GBACLIDebuggerDeinit;
|
debugger->d.deinit = _GBACLIDebuggerDeinit;
|
||||||
|
debugger->d.custom = _GBACLIDebuggerCustom;
|
||||||
debugger->d.lookupIdentifier = _GBACLIDebuggerLookupIdentifier;
|
debugger->d.lookupIdentifier = _GBACLIDebuggerLookupIdentifier;
|
||||||
|
|
||||||
debugger->d.name = "Game Boy Advance";
|
debugger->d.name = "Game Boy Advance";
|
||||||
|
@ -45,13 +49,30 @@ struct GBACLIDebugger* GBACLIDebuggerCreate(struct GBAThread* context) {
|
||||||
|
|
||||||
#ifdef USE_CLI_DEBUGGER
|
#ifdef USE_CLI_DEBUGGER
|
||||||
static void _GBACLIDebuggerInit(struct CLIDebuggerSystem* debugger) {
|
static void _GBACLIDebuggerInit(struct CLIDebuggerSystem* debugger) {
|
||||||
UNUSED(debugger);
|
struct GBACLIDebugger* gbaDebugger = (struct GBACLIDebugger*) debugger;
|
||||||
|
|
||||||
|
gbaDebugger->frameAdvance = false;
|
||||||
}
|
}
|
||||||
|
|
||||||
static void _GBACLIDebuggerDeinit(struct CLIDebuggerSystem* debugger) {
|
static void _GBACLIDebuggerDeinit(struct CLIDebuggerSystem* debugger) {
|
||||||
UNUSED(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) {
|
static uint32_t _GBACLIDebuggerLookupIdentifier(struct CLIDebuggerSystem* debugger, const char* name, struct CLIDebugVector* dv) {
|
||||||
struct GBACLIDebugger* gbaDebugger = (struct GBACLIDebugger*) debugger;
|
struct GBACLIDebugger* gbaDebugger = (struct GBACLIDebugger*) debugger;
|
||||||
int i;
|
int i;
|
||||||
|
@ -65,6 +86,15 @@ static uint32_t _GBACLIDebuggerLookupIdentifier(struct CLIDebuggerSystem* debugg
|
||||||
return 0;
|
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) {
|
static void _load(struct CLIDebugger* debugger, struct CLIDebugVector* dv) {
|
||||||
if (!dv || dv->type != CLIDV_INT_TYPE) {
|
if (!dv || dv->type != CLIDV_INT_TYPE) {
|
||||||
printf("%s\n", ERROR_MISSING_ARGS);
|
printf("%s\n", ERROR_MISSING_ARGS);
|
||||||
|
|
|
@ -15,6 +15,9 @@ struct GBACLIDebugger {
|
||||||
struct CLIDebuggerSystem d;
|
struct CLIDebuggerSystem d;
|
||||||
|
|
||||||
struct GBAThread* context;
|
struct GBAThread* context;
|
||||||
|
|
||||||
|
bool frameAdvance;
|
||||||
|
bool inVblank;
|
||||||
#endif
|
#endif
|
||||||
};
|
};
|
||||||
|
|
||||||
|
|
Loading…
Reference in New Issue