all repos — mgba @ 5966f46355d18ba472404a7f7ed3cbeebf846635

mGBA Game Boy Advance Emulator

src/gba/supervisor/context.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 "gba/supervisor/context.h"
  7
  8#include "gba/supervisor/overrides.h"
  9
 10#include "util/memory.h"
 11#include "util/vfs.h"
 12
 13bool GBAContextInit(struct GBAContext* context, const char* port) {
 14	context->gba = anonymousMemoryMap(sizeof(struct GBA));
 15	context->cpu = anonymousMemoryMap(sizeof(struct ARMCore));
 16	context->rom = 0;
 17	context->save = 0;
 18	context->renderer = 0;
 19
 20	if (!context->gba || !context->cpu) {
 21		if (context->gba) {
 22			mappedMemoryFree(context->gba, sizeof(struct GBA));
 23		}
 24		if (context->cpu) {
 25			mappedMemoryFree(context->cpu, sizeof(struct ARMCore));
 26		}
 27		return false;
 28	}
 29
 30	GBAConfigInit(&context->config, port);
 31	if (port) {
 32		GBAConfigLoad(&context->config);
 33	}
 34
 35	GBACreate(context->gba);
 36	ARMSetComponents(context->cpu, &context->gba->d, 0, 0);
 37	ARMInit(context->cpu);
 38
 39	context->gba->sync = 0;
 40	return true;
 41}
 42
 43void GBAContextDeinit(struct GBAContext* context) {
 44	if (context->bios) {
 45		context->bios->close(context->bios);
 46		context->bios = 0;
 47	}
 48	if (context->rom) {
 49		context->rom->close(context->rom);
 50		context->rom = 0;
 51	}
 52	if (context->save) {
 53		context->save->close(context->save);
 54		context->save = 0;
 55	}
 56	ARMDeinit(context->cpu);
 57	GBADestroy(context->gba);
 58	mappedMemoryFree(context->gba, 0);
 59	mappedMemoryFree(context->cpu, 0);
 60	GBAConfigDeinit(&context->config);
 61}
 62
 63bool GBAContextLoadROM(struct GBAContext* context, const char* path, bool autoloadSave) {
 64	context->rom = VFileOpen(path, O_RDONLY);
 65	if (!context->rom) {
 66		return false;
 67	}
 68
 69	if (!GBAIsROM(context->rom)) {
 70		context->rom->close(context->rom);
 71		context->rom = 0;
 72		return false;
 73	}
 74
 75	if (autoloadSave) {
 76		context->save = VDirOptionalOpenFile(0, path, 0, ".sav", O_RDWR | O_CREAT);
 77	}
 78	return true;
 79}
 80
 81bool GBAContextLoadROMFromVFile(struct GBAContext* context, struct VFile* rom, struct VFile* save) {
 82	context->rom = rom;
 83	if (!GBAIsROM(context->rom)) {
 84		context->rom = 0;
 85		return false;
 86	}
 87	context->save = save;
 88	return true;
 89}
 90
 91bool GBAContextLoadBIOS(struct GBAContext* context, const char* path) {
 92	context->bios = VFileOpen(path, O_RDONLY);
 93	if (!context->bios) {
 94		return false;
 95	}
 96
 97	if (!GBAIsBIOS(context->bios)) {
 98		context->bios->close(context->bios);
 99		context->bios = 0;
100		return false;
101	}
102	return true;
103}
104
105bool GBAContextLoadBIOSFromVFile(struct GBAContext* context, struct VFile* bios) {
106	context->bios = bios;
107	if (!GBAIsBIOS(context->bios)) {
108		context->bios = 0;
109		return false;
110	}
111	return true;
112}
113
114bool GBAContextStart(struct GBAContext* context) {
115	struct GBAOptions opts = {};
116	GBAConfigMap(&context->config, &opts);
117
118	if (context->renderer) {
119		GBAVideoAssociateRenderer(&context->gba->video, context->renderer);
120	}
121
122	GBALoadROM(context->gba, context->rom, context->save, 0);
123	if (opts.useBios && context->bios) {
124		GBALoadBIOS(context->gba, context->bios);
125	}
126
127	ARMReset(context->cpu);
128
129	if (opts.skipBios) {
130		GBASkipBIOS(context->cpu);
131	}
132
133	struct GBACartridgeOverride override;
134	const struct GBACartridge* cart = (const struct GBACartridge*) context->gba->memory.rom;
135	memcpy(override.id, &cart->id, sizeof(override.id));
136	if (GBAOverrideFind(GBAConfigGetOverrides(&context->config), &override)) {
137		GBAOverrideApply(context->gba, &override);
138	}
139	GBAConfigFreeOpts(&opts);
140	return true;
141}
142
143void GBAContextStop(struct GBAContext* context) {
144	UNUSED(context);
145	// TODO?
146}
147
148void GBAContextFrame(struct GBAContext* context, uint16_t keys) {
149	int activeKeys = keys;
150	context->gba->keySource = &activeKeys;
151
152	int frameCounter = context->gba->video.frameCounter;
153	while (frameCounter == context->gba->video.frameCounter) {
154		ARMRunLoop(context->cpu);
155	}
156}