all repos — mgba @ bf595be5c3fda6c84a9b7468b3bcce812596b355

mGBA Game Boy Advance Emulator

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

  1/* Copyright (c) 2013-2015 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 <mgba/internal/gba/extra/cli.h>
  7
  8#include <mgba/core/core.h>
  9#include <mgba/core/serialize.h>
 10#include <mgba/internal/gba/gba.h>
 11#include <mgba/internal/gba/io.h>
 12#include <mgba/internal/gba/video.h>
 13#include <mgba/internal/arm/debugger/cli-debugger.h>
 14
 15static void _GBACLIDebuggerInit(struct CLIDebuggerSystem*);
 16static bool _GBACLIDebuggerCustom(struct CLIDebuggerSystem*);
 17
 18static void _frame(struct CLIDebugger*, struct CLIDebugVector*);
 19static void _load(struct CLIDebugger*, struct CLIDebugVector*);
 20static void _save(struct CLIDebugger*, struct CLIDebugVector*);
 21
 22struct CLIDebuggerCommandSummary _GBACLIDebuggerCommands[] = {
 23	{ "frame", _frame, "", "Frame advance" },
 24	{ "load", _load, "*", "Load a savestate" },
 25	{ "save", _save, "*", "Save a savestate" },
 26	{ 0, 0, 0, 0 }
 27};
 28
 29struct GBACLIDebugger* GBACLIDebuggerCreate(struct mCore* core) {
 30	struct GBACLIDebugger* debugger = malloc(sizeof(struct GBACLIDebugger));
 31	ARMCLIDebuggerCreate(&debugger->d);
 32	debugger->d.init = _GBACLIDebuggerInit;
 33	debugger->d.deinit = NULL;
 34	debugger->d.custom = _GBACLIDebuggerCustom;
 35
 36	debugger->d.name = "Game Boy Advance";
 37	debugger->d.commands = _GBACLIDebuggerCommands;
 38	debugger->d.commandAliases = NULL;
 39
 40	debugger->core = core;
 41
 42	return debugger;
 43}
 44
 45static void _GBACLIDebuggerInit(struct CLIDebuggerSystem* debugger) {
 46	struct GBACLIDebugger* gbaDebugger = (struct GBACLIDebugger*) debugger;
 47
 48	gbaDebugger->frameAdvance = false;
 49}
 50
 51static bool _GBACLIDebuggerCustom(struct CLIDebuggerSystem* debugger) {
 52	struct GBACLIDebugger* gbaDebugger = (struct GBACLIDebugger*) debugger;
 53
 54	if (gbaDebugger->frameAdvance) {
 55		if (!gbaDebugger->inVblank && GBARegisterDISPSTATIsInVblank(((struct GBA*) gbaDebugger->core->board)->memory.io[REG_DISPSTAT >> 1])) {
 56			mDebuggerEnter(&gbaDebugger->d.p->d, DEBUGGER_ENTER_MANUAL, 0);
 57			gbaDebugger->frameAdvance = false;
 58			return false;
 59		}
 60		gbaDebugger->inVblank = GBARegisterDISPSTATGetInVblank(((struct GBA*) gbaDebugger->core->board)->memory.io[REG_DISPSTAT >> 1]);
 61		return true;
 62	}
 63	return true;
 64}
 65
 66static void _frame(struct CLIDebugger* debugger, struct CLIDebugVector* dv) {
 67	UNUSED(dv);
 68	debugger->d.state = DEBUGGER_CUSTOM;
 69
 70	struct GBACLIDebugger* gbaDebugger = (struct GBACLIDebugger*) debugger->system;
 71	gbaDebugger->frameAdvance = true;
 72	gbaDebugger->inVblank = GBARegisterDISPSTATGetInVblank(((struct GBA*) gbaDebugger->core->board)->memory.io[REG_DISPSTAT >> 1]);
 73}
 74
 75static void _load(struct CLIDebugger* debugger, struct CLIDebugVector* dv) {
 76	struct CLIDebuggerBackend* be = debugger->backend;
 77	if (!dv || dv->type != CLIDV_INT_TYPE) {
 78		be->printf(be, "%s\n", ERROR_MISSING_ARGS);
 79		return;
 80	}
 81
 82	int state = dv->intValue;
 83	if (state < 1 || state > 9) {
 84		be->printf(be, "State %u out of range", state);
 85	}
 86
 87	struct GBACLIDebugger* gbaDebugger = (struct GBACLIDebugger*) debugger->system;
 88
 89	mCoreLoadState(gbaDebugger->core, dv->intValue, SAVESTATE_SCREENSHOT | SAVESTATE_RTC);
 90}
 91
 92// TODO: Put back rewind
 93
 94static void _save(struct CLIDebugger* debugger, struct CLIDebugVector* dv) {
 95	struct CLIDebuggerBackend* be = debugger->backend;
 96	if (!dv || dv->type != CLIDV_INT_TYPE) {
 97		be->printf(be, "%s\n", ERROR_MISSING_ARGS);
 98		return;
 99	}
100
101	int state = dv->intValue;
102	if (state < 1 || state > 9) {
103		be->printf(be, "State %u out of range", state);
104	}
105
106	struct GBACLIDebugger* gbaDebugger = (struct GBACLIDebugger*) debugger->system;
107
108	mCoreSaveState(gbaDebugger->core, dv->intValue, SAVESTATE_SCREENSHOT | SAVESTATE_RTC | SAVESTATE_METADATA);
109}