src/gba/gba-cli.c (view raw)
1/* Copyright (c) 2013-2014 Jeffrey Pfau
2 *
3 * This Source Code Form is subject to the terms of the Mozilla Public
4 * License, v. 2.0. If a copy of the MPL was not distributed with this
5 * file, You can obtain one at http://mozilla.org/MPL/2.0/. */
6#include "gba-cli.h"
7
8#include "gba-io.h"
9#include "gba-serialize.h"
10#include "gba-thread.h"
11
12#ifdef USE_CLI_DEBUGGER
13
14static const char* ERROR_MISSING_ARGS = "Arguments missing"; // TODO: share
15
16static void _GBACLIDebuggerInit(struct CLIDebuggerSystem*);
17static void _GBACLIDebuggerDeinit(struct CLIDebuggerSystem*);
18static uint32_t _GBACLIDebuggerLookupIdentifier(struct CLIDebuggerSystem*, const char* name, struct CLIDebugVector* dv);
19
20static void _load(struct CLIDebugger*, struct CLIDebugVector*);
21static void _save(struct CLIDebugger*, struct CLIDebugVector*);
22
23struct CLIDebuggerCommandSummary _GBACLIDebuggerCommands[] = {
24 { "load", _load, CLIDVParse, "Load a savestate" },
25 { "save", _save, CLIDVParse, "Save a savestate" },
26 { 0, 0, 0, 0 }
27};
28#endif
29
30struct GBACLIDebugger* GBACLIDebuggerCreate(struct GBAThread* context) {
31 struct GBACLIDebugger* debugger = malloc(sizeof(struct GBACLIDebugger));
32#ifdef USE_CLI_DEBUGGER
33 debugger->d.init = _GBACLIDebuggerInit;
34 debugger->d.deinit = _GBACLIDebuggerDeinit;
35 debugger->d.lookupIdentifier = _GBACLIDebuggerLookupIdentifier;
36
37 debugger->d.name = "Game Boy Advance";
38 debugger->d.commands = _GBACLIDebuggerCommands;
39
40 debugger->context = context;
41#endif
42
43 return debugger;
44}
45
46#ifdef USE_CLI_DEBUGGER
47static void _GBACLIDebuggerInit(struct CLIDebuggerSystem* debugger) {
48 UNUSED(debugger);
49}
50
51static void _GBACLIDebuggerDeinit(struct CLIDebuggerSystem* debugger) {
52 UNUSED(debugger);
53}
54
55static uint32_t _GBACLIDebuggerLookupIdentifier(struct CLIDebuggerSystem* debugger, const char* name, struct CLIDebugVector* dv) {
56 struct GBACLIDebugger* gbaDebugger = (struct GBACLIDebugger*) debugger;
57 int i;
58 for (i = 0; i < REG_MAX; i += 2) {
59 const char* reg = GBAIORegisterNames[i >> 1];
60 if (reg && strcasecmp(reg, name) == 0) {
61 return GBALoad16(gbaDebugger->context->gba->cpu, BASE_IO | i, 0);
62 }
63 }
64 dv->type = CLIDV_ERROR_TYPE;
65 return 0;
66}
67
68static void _load(struct CLIDebugger* debugger, struct CLIDebugVector* dv) {
69 if (!dv || dv->type != CLIDV_INT_TYPE) {
70 printf("%s\n", ERROR_MISSING_ARGS);
71 return;
72 }
73
74 int state = dv->intValue;
75 if (state < 1 || state > 9) {
76 printf("State %u out of range", state);
77 }
78
79 struct GBACLIDebugger* gbaDebugger = (struct GBACLIDebugger*) debugger->system;
80
81 GBALoadState(gbaDebugger->context->gba, gbaDebugger->context->stateDir, dv->intValue);
82}
83
84static void _save(struct CLIDebugger* debugger, struct CLIDebugVector* dv) {
85 if (!dv || dv->type != CLIDV_INT_TYPE) {
86 printf("%s\n", ERROR_MISSING_ARGS);
87 return;
88 }
89
90 int state = dv->intValue;
91 if (state < 1 || state > 9) {
92 printf("State %u out of range", state);
93 }
94
95 struct GBACLIDebugger* gbaDebugger = (struct GBACLIDebugger*) debugger->system;
96
97 GBASaveState(gbaDebugger->context->gba, gbaDebugger->context->stateDir, dv->intValue, true);
98}
99#endif