all repos — mgba @ 886c045a11e7ebaff01bb159e5c99a48d0200e80

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