all repos — mgba @ 091e717133a10f785f02d1d4e880b8271fea8066

mGBA Game Boy Advance Emulator

src/gba/gba-cli.c (view raw)

 1#include "gba-cli.h"
 2
 3#include "gba-io.h"
 4#include "gba-serialize.h"
 5#include "gba-thread.h"
 6
 7static const char* ERROR_MISSING_ARGS = "Arguments missing"; // TODO: share
 8
 9static void _GBACLIDebuggerInit(struct CLIDebuggerSystem*);
10static void _GBACLIDebuggerDeinit(struct CLIDebuggerSystem*);
11static uint32_t _GBACLIDebuggerLookupIdentifier(struct CLIDebuggerSystem*, const char* name, struct CLIDebugVector* dv);
12
13static void _load(struct CLIDebugger*, struct CLIDebugVector*);
14static void _save(struct CLIDebugger*, struct CLIDebugVector*);
15
16struct CLIDebuggerCommandSummary _GBACLIDebuggerCommands[] = {
17	{ "load", _load, CLIDVParse, "Load a savestate" },
18	{ "save", _save, CLIDVParse, "Save a savestate" },
19	{ 0, 0, 0, 0 }
20};
21
22struct GBACLIDebugger* GBACLIDebuggerCreate(struct GBAThread* context) {
23	struct GBACLIDebugger* debugger = malloc(sizeof(struct GBACLIDebugger));
24	debugger->d.init = _GBACLIDebuggerInit;
25	debugger->d.deinit = _GBACLIDebuggerDeinit;
26	debugger->d.lookupIdentifier = _GBACLIDebuggerLookupIdentifier;
27
28	debugger->d.name = "Game Boy Advance";
29	debugger->d.commands = _GBACLIDebuggerCommands;
30
31	debugger->context = context;
32
33	return debugger;
34}
35
36static void _GBACLIDebuggerInit(struct CLIDebuggerSystem* debugger) {
37	UNUSED(debugger);
38}
39
40static void _GBACLIDebuggerDeinit(struct CLIDebuggerSystem* debugger) {
41	UNUSED(debugger);
42}
43
44static uint32_t _GBACLIDebuggerLookupIdentifier(struct CLIDebuggerSystem* debugger, const char* name, struct CLIDebugVector* dv) {
45	struct GBACLIDebugger* gbaDebugger = (struct GBACLIDebugger*) debugger;
46	int i;
47	for (i = 0; i < REG_MAX; i += 2) {
48		const char* reg = GBAIORegisterNames[i >> 1];
49		if (reg && strcasecmp(reg, name) == 0) {
50			return GBALoad16(gbaDebugger->context->gba->cpu, BASE_IO | i, 0);
51		}
52	}
53	dv->type = CLIDV_ERROR_TYPE;
54	return 0;
55}
56
57static void _load(struct CLIDebugger* debugger, struct CLIDebugVector* dv) {
58	if (!dv || dv->type != CLIDV_INT_TYPE) {
59		printf("%s\n", ERROR_MISSING_ARGS);
60		return;
61	}
62
63	int state = dv->intValue;
64	if (state < 1 || state > 9) {
65		printf("State %u out of range", state);
66	}
67
68	struct GBACLIDebugger* gbaDebugger = (struct GBACLIDebugger*) debugger->system;
69
70	GBALoadState(gbaDebugger->context->gba, gbaDebugger->context->stateDir, dv->intValue);
71}
72
73static void _save(struct CLIDebugger* debugger, struct CLIDebugVector* dv) {
74	if (!dv || dv->type != CLIDV_INT_TYPE) {
75		printf("%s\n", ERROR_MISSING_ARGS);
76		return;
77	}
78
79	int state = dv->intValue;
80	if (state < 1 || state > 9) {
81		printf("State %u out of range", state);
82	}
83
84	struct GBACLIDebugger* gbaDebugger = (struct GBACLIDebugger*) debugger->system;
85
86	GBASaveState(gbaDebugger->context->gba, gbaDebugger->context->stateDir, dv->intValue, true);
87}
88