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