all repos — mgba @ 9c92a29b28d1f81224ba28d5fc83a9481eccd5eb

mGBA Game Boy Advance Emulator

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