all repos — mgba @ 3cf9446ba17e5fe7b0de4eff60fa063c55d7c6b2

mGBA Game Boy Advance Emulator

src/ds/core.c (view raw)

  1/* Copyright (c) 2013-2016 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 "core.h"
  7
  8#include "core/cheats.h"
  9#include "core/core.h"
 10#include "core/log.h"
 11#include "arm/debugger/debugger.h"
 12#include "ds/ds.h"
 13#include "ds/extra/cli.h"
 14#include "util/memory.h"
 15#include "util/patch.h"
 16#include "util/vfs.h"
 17
 18struct DSCore {
 19	struct mCore d;
 20	struct ARMCore* arm7;
 21	int keys;
 22	struct mCPUComponent* components[CPU_COMPONENT_MAX];
 23	struct mDebuggerPlatform* debuggerPlatform;
 24	struct mCheatDevice* cheatDevice;
 25};
 26
 27static bool _DSCoreInit(struct mCore* core) {
 28	struct DSCore* dscore = (struct DSCore*) core;
 29
 30	struct ARMCore* arm7 = anonymousMemoryMap(sizeof(struct ARMCore));
 31	struct ARMCore* arm9 = anonymousMemoryMap(sizeof(struct ARMCore));
 32	struct DS* ds = anonymousMemoryMap(sizeof(struct DS));
 33	if (!arm7 || !arm9 || !ds) {
 34		free(arm7);
 35		free(arm9);
 36		free(ds);
 37		return false;
 38	}
 39	core->cpu = arm9;
 40	core->board = ds;
 41	core->debugger = NULL;
 42	dscore->arm7 = arm7;
 43	dscore->debuggerPlatform = NULL;
 44	dscore->cheatDevice = NULL;
 45
 46	DSCreate(ds);
 47	memset(dscore->components, 0, sizeof(dscore->components));
 48	ARMSetComponents(arm7, &ds->d, CPU_COMPONENT_MAX, dscore->components);
 49	ARMSetComponents(arm9, &ds->d, CPU_COMPONENT_MAX, dscore->components);
 50	ARMInit(arm7);
 51	ARMInit(arm9);
 52
 53	dscore->keys = 0;
 54	ds->keySource = &dscore->keys;
 55
 56#if !defined(MINIMAL_CORE) || MINIMAL_CORE < 2
 57	mDirectorySetInit(&core->dirs);
 58#endif
 59	
 60	return true;
 61}
 62
 63static void _DSCoreDeinit(struct mCore* core) {
 64	struct DSCore* dscore = (struct DSCore*) core;
 65	ARMDeinit(core->cpu);
 66	ARMDeinit(dscore->arm7);
 67	DSDestroy(core->board);
 68	mappedMemoryFree(core->cpu, sizeof(struct ARMCore));
 69	mappedMemoryFree(dscore->arm7, sizeof(struct ARMCore));
 70	mappedMemoryFree(core->board, sizeof(struct DS));
 71#if !defined(MINIMAL_CORE) || MINIMAL_CORE < 2
 72	mDirectorySetDeinit(&core->dirs);
 73#endif
 74
 75	free(dscore->debuggerPlatform);
 76	if (dscore->cheatDevice) {
 77		mCheatDeviceDestroy(dscore->cheatDevice);
 78	}
 79	free(dscore->cheatDevice);
 80	free(core);
 81}
 82
 83static enum mPlatform _DSCorePlatform(struct mCore* core) {
 84	UNUSED(core);
 85	return PLATFORM_DS;
 86}
 87
 88static void _DSCoreSetSync(struct mCore* core, struct mCoreSync* sync) {
 89	struct DS* ds = core->board;
 90	ds->sync = sync;
 91}
 92
 93static void _DSCoreLoadConfig(struct mCore* core, const struct mCoreConfig* config) {
 94	struct DS* ds = core->board;
 95	struct VFile* bios = NULL;
 96	if (core->opts.useBios && core->opts.bios) {
 97		bios = VFileOpen(core->opts.bios, O_RDONLY);
 98	}
 99	if (bios) {
100		DSLoadBIOS(ds, bios);
101	}
102}
103
104static void _DSCoreDesiredVideoDimensions(struct mCore* core, unsigned* width, unsigned* height) {
105	UNUSED(core);
106	*width = DS_VIDEO_HORIZONTAL_PIXELS;
107	*height = DS_VIDEO_VERTICAL_PIXELS;
108}
109
110static void _DSCoreSetVideoBuffer(struct mCore* core, color_t* buffer, size_t stride) {
111}
112
113static void _DSCoreGetVideoBuffer(struct mCore* core, color_t** buffer, size_t* stride) {
114}
115
116static struct blip_t* _DSCoreGetAudioChannel(struct mCore* core, int ch) {
117	return NULL;
118}
119
120static void _DSCoreSetAudioBufferSize(struct mCore* core, size_t samples) {
121}
122
123static size_t _DSCoreGetAudioBufferSize(struct mCore* core) {
124	return 2048;
125}
126
127static void _DSCoreSetAVStream(struct mCore* core, struct mAVStream* stream) {
128}
129
130static bool _DSCoreLoadROM(struct mCore* core, struct VFile* vf) {
131	return DSLoadROM(core->board, vf);
132}
133
134static bool _DSCoreLoadBIOS(struct mCore* core, struct VFile* vf, int type) {
135	UNUSED(type);
136	return DSLoadBIOS(core->board, vf);
137}
138
139static bool _DSCoreLoadSave(struct mCore* core, struct VFile* vf) {
140	return false;
141}
142
143static bool _DSCoreLoadPatch(struct mCore* core, struct VFile* vf) {
144	return false;
145}
146
147static void _DSCoreUnloadROM(struct mCore* core) {
148	return DSUnloadROM(core->board);
149}
150
151static void _DSCoreReset(struct mCore* core) {
152	struct DSCore* dscore = (struct DSCore*) core;
153	struct DS* ds = (struct DS*) core->board;
154	ARMReset(ds->arm7);
155	ARMReset(ds->arm9);
156}
157
158static void _DSCoreRunFrame(struct mCore* core) {
159	struct DS* ds = core->board;
160	int32_t frameCounter = ds->video.frameCounter;
161	while (ds->video.frameCounter == frameCounter) {
162		ARMRunLoop(core->cpu);
163	}
164}
165
166static void _DSCoreRunLoop(struct mCore* core) {
167	ARMRunLoop(core->cpu);
168}
169
170static void _DSCoreStep(struct mCore* core) {
171	ARMRun(core->cpu);
172}
173
174static size_t _DSCoreStateSize(struct mCore* core) {
175	UNUSED(core);
176	return 0;
177}
178
179static bool _DSCoreLoadState(struct mCore* core, const void* state) {
180	return false;
181}
182
183static bool _DSCoreSaveState(struct mCore* core, void* state) {
184	return false;
185}
186
187static void _DSCoreSetKeys(struct mCore* core, uint32_t keys) {
188	struct DSCore* dscore = (struct DSCore*) core;
189	dscore->keys = keys;
190}
191
192static void _DSCoreAddKeys(struct mCore* core, uint32_t keys) {
193	struct DSCore* dscore = (struct DSCore*) core;
194	dscore->keys |= keys;
195}
196
197static void _DSCoreClearKeys(struct mCore* core, uint32_t keys) {
198	struct DSCore* dscore = (struct DSCore*) core;
199	dscore->keys &= ~keys;
200}
201
202static int32_t _DSCoreFrameCounter(struct mCore* core) {
203	struct DS* ds = core->board;
204	return ds->video.frameCounter;
205}
206
207static int32_t _DSCoreFrameCycles(struct mCore* core) {
208	UNUSED(core);
209	return DS_VIDEO_TOTAL_LENGTH;
210}
211
212static int32_t _DSCoreFrequency(struct mCore* core) {
213	UNUSED(core);
214	return DS_ARM946ES_FREQUENCY;
215}
216
217static void _DSCoreGetGameTitle(struct mCore* core, char* title) {
218	DSGetGameTitle(core->board, title);
219}
220
221static void _DSCoreGetGameCode(struct mCore* core, char* title) {
222	DSGetGameCode(core->board, title);
223}
224
225static void _DSCoreSetRTC(struct mCore* core, struct mRTCSource* rtc) {
226	struct DS* ds = core->board;
227	ds->rtcSource = rtc;
228}
229
230static void _DSCoreSetRotation(struct mCore* core, struct mRotationSource* rotation) {
231}
232
233static void _DSCoreSetRumble(struct mCore* core, struct mRumble* rumble) {
234	struct DS* ds = core->board;
235	ds->rumble = rumble;
236}
237
238static uint32_t _DSCoreBusRead8(struct mCore* core, uint32_t address) {
239	struct ARMCore* cpu = core->cpu;
240	return cpu->memory.load8(cpu, address, 0);
241}
242
243static uint32_t _DSCoreBusRead16(struct mCore* core, uint32_t address) {
244	struct ARMCore* cpu = core->cpu;
245	return cpu->memory.load16(cpu, address, 0);
246
247}
248
249static uint32_t _DSCoreBusRead32(struct mCore* core, uint32_t address) {
250	struct ARMCore* cpu = core->cpu;
251	return cpu->memory.load32(cpu, address, 0);
252}
253
254static void _DSCoreBusWrite8(struct mCore* core, uint32_t address, uint8_t value) {
255	struct ARMCore* cpu = core->cpu;
256	cpu->memory.store8(cpu, address, value, 0);
257}
258
259static void _DSCoreBusWrite16(struct mCore* core, uint32_t address, uint16_t value) {
260	struct ARMCore* cpu = core->cpu;
261	cpu->memory.store16(cpu, address, value, 0);
262}
263
264static void _DSCoreBusWrite32(struct mCore* core, uint32_t address, uint32_t value) {
265	struct ARMCore* cpu = core->cpu;
266	cpu->memory.store32(cpu, address, value, 0);
267}
268
269static uint32_t _DSCoreRawRead8(struct mCore* core, uint32_t address) {
270	return 0;
271}
272
273static uint32_t _DSCoreRawRead16(struct mCore* core, uint32_t address) {
274	return 0;
275}
276
277static uint32_t _DSCoreRawRead32(struct mCore* core, uint32_t address) {
278	return 0;
279}
280
281static void _DSCoreRawWrite8(struct mCore* core, uint32_t address, uint8_t value) {
282}
283
284static void _DSCoreRawWrite16(struct mCore* core, uint32_t address, uint16_t value) {
285}
286
287static void _DSCoreRawWrite32(struct mCore* core, uint32_t address, uint32_t value) {
288}
289
290static bool _DSCoreSupportsDebuggerType(struct mCore* core, enum mDebuggerType type) {
291	UNUSED(core);
292	switch (type) {
293#ifdef USE_CLI_DEBUGGER
294	case DEBUGGER_CLI:
295		return true;
296#endif
297#ifdef USE_GDB_STUB
298	case DEBUGGER_GDB:
299		return true;
300#endif
301	default:
302		return false;
303	}
304}
305
306static struct mDebuggerPlatform* _DSCoreDebuggerPlatform(struct mCore* core) {
307	struct DSCore* dscore = (struct DSCore*) core;
308	if (!dscore->debuggerPlatform) {
309		dscore->debuggerPlatform = ARMDebuggerPlatformCreate();
310	}
311	return dscore->debuggerPlatform;
312}
313
314static struct CLIDebuggerSystem* _DSCoreCliDebuggerSystem(struct mCore* core) {
315#ifdef USE_CLI_DEBUGGER
316	return &DSCLIDebuggerCreate(core)->d;
317#else
318	UNUSED(core);
319	return NULL;
320#endif
321}
322
323static void _DSCoreAttachDebugger(struct mCore* core, struct mDebugger* debugger) {
324	if (core->debugger) {
325		DSDetachDebugger(core->board);
326	}
327	DSAttachDebugger(core->board, debugger);
328	core->debugger = debugger;
329}
330
331static void _DSCoreDetachDebugger(struct mCore* core) {
332	DSDetachDebugger(core->board);
333	core->debugger = NULL;
334}
335
336static struct mCheatDevice* _DSCoreCheatDevice(struct mCore* core) {
337	return NULL;
338}
339
340static size_t _DSCoreSavedataClone(struct mCore* core, void** sram) {
341	return 0;
342}
343
344static bool _DSCoreSavedataLoad(struct mCore* core, const void* sram, size_t size) {
345	return false;
346}
347
348struct mCore* DSCoreCreate(void) {
349	struct DSCore* dscore = malloc(sizeof(*dscore));
350	struct mCore* core = &dscore->d;
351	memset(&core->opts, 0, sizeof(core->opts));
352	core->cpu = NULL;
353	core->board = NULL;
354	core->debugger = NULL;
355	core->init = _DSCoreInit;
356	core->deinit = _DSCoreDeinit;
357	core->platform = _DSCorePlatform;
358	core->setSync = _DSCoreSetSync;
359	core->loadConfig = _DSCoreLoadConfig;
360	core->desiredVideoDimensions = _DSCoreDesiredVideoDimensions;
361	core->setVideoBuffer = _DSCoreSetVideoBuffer;
362	core->getVideoBuffer = _DSCoreGetVideoBuffer;
363	core->getAudioChannel = _DSCoreGetAudioChannel;
364	core->setAudioBufferSize = _DSCoreSetAudioBufferSize;
365	core->getAudioBufferSize = _DSCoreGetAudioBufferSize;
366	core->setAVStream = _DSCoreSetAVStream;
367	core->isROM = DSIsROM;
368	core->loadROM = _DSCoreLoadROM;
369	core->loadBIOS = _DSCoreLoadBIOS;
370	core->loadSave = _DSCoreLoadSave;
371	core->loadPatch = _DSCoreLoadPatch;
372	core->unloadROM = _DSCoreUnloadROM;
373	core->reset = _DSCoreReset;
374	core->runFrame = _DSCoreRunFrame;
375	core->runLoop = _DSCoreRunLoop;
376	core->step = _DSCoreStep;
377	core->stateSize = _DSCoreStateSize;
378	core->loadState = _DSCoreLoadState;
379	core->saveState = _DSCoreSaveState;
380	core->setKeys = _DSCoreSetKeys;
381	core->addKeys = _DSCoreAddKeys;
382	core->clearKeys = _DSCoreClearKeys;
383	core->frameCounter = _DSCoreFrameCounter;
384	core->frameCycles = _DSCoreFrameCycles;
385	core->frequency = _DSCoreFrequency;
386	core->getGameTitle = _DSCoreGetGameTitle;
387	core->getGameCode = _DSCoreGetGameCode;
388	core->setRTC = _DSCoreSetRTC;
389	core->setRotation = _DSCoreSetRotation;
390	core->setRumble = _DSCoreSetRumble;
391	core->busRead8 = _DSCoreBusRead8;
392	core->busRead16 = _DSCoreBusRead16;
393	core->busRead32 = _DSCoreBusRead32;
394	core->busWrite8 = _DSCoreBusWrite8;
395	core->busWrite16 = _DSCoreBusWrite16;
396	core->busWrite32 = _DSCoreBusWrite32;
397	core->rawRead8 = _DSCoreRawRead8;
398	core->rawRead16 = _DSCoreRawRead16;
399	core->rawRead32 = _DSCoreRawRead32;
400	core->rawWrite8 = _DSCoreRawWrite8;
401	core->rawWrite16 = _DSCoreRawWrite16;
402	core->rawWrite32 = _DSCoreRawWrite32;
403	core->supportsDebuggerType = _DSCoreSupportsDebuggerType;
404	core->debuggerPlatform = _DSCoreDebuggerPlatform;
405	core->cliDebuggerSystem = _DSCoreCliDebuggerSystem;
406	core->attachDebugger = _DSCoreAttachDebugger;
407	core->detachDebugger = _DSCoreDetachDebugger;
408	core->cheatDevice = _DSCoreCheatDevice;
409	core->savedataClone = _DSCoreSavedataClone;
410	core->savedataLoad = _DSCoreSavedataLoad;
411	return core;
412}