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}
95
96static void _DSCoreDesiredVideoDimensions(struct mCore* core, unsigned* width, unsigned* height) {
97 UNUSED(core);
98 *width = DS_VIDEO_HORIZONTAL_PIXELS;
99 *height = DS_VIDEO_VERTICAL_PIXELS;
100}
101
102static void _DSCoreSetVideoBuffer(struct mCore* core, color_t* buffer, size_t stride) {
103}
104
105static void _DSCoreGetVideoBuffer(struct mCore* core, color_t** buffer, size_t* stride) {
106}
107
108static struct blip_t* _DSCoreGetAudioChannel(struct mCore* core, int ch) {
109 return NULL;
110}
111
112static void _DSCoreSetAudioBufferSize(struct mCore* core, size_t samples) {
113}
114
115static size_t _DSCoreGetAudioBufferSize(struct mCore* core) {
116 return 2048;
117}
118
119static void _DSCoreSetAVStream(struct mCore* core, struct mAVStream* stream) {
120}
121
122static bool _DSCoreLoadROM(struct mCore* core, struct VFile* vf) {
123 return DSLoadROM(core->board, vf);
124}
125
126static bool _DSCoreLoadBIOS(struct mCore* core, struct VFile* vf, int type) {
127 return false;
128}
129
130static bool _DSCoreLoadSave(struct mCore* core, struct VFile* vf) {
131 return false;
132}
133
134static bool _DSCoreLoadPatch(struct mCore* core, struct VFile* vf) {
135 return false;
136}
137
138static void _DSCoreUnloadROM(struct mCore* core) {
139 return DSUnloadROM(core->board);
140}
141
142static void _DSCoreReset(struct mCore* core) {
143 struct DSCore* dscore = (struct DSCore*) core;
144 struct DS* ds = (struct DS*) core->board;
145 ARMReset(ds->arm7);
146 ARMReset(ds->arm9);
147}
148
149static void _DSCoreRunFrame(struct mCore* core) {
150 struct DS* ds = core->board;
151 int32_t frameCounter = ds->video.frameCounter;
152 while (ds->video.frameCounter == frameCounter) {
153 ARMRunLoop(core->cpu);
154 }
155}
156
157static void _DSCoreRunLoop(struct mCore* core) {
158 ARMRunLoop(core->cpu);
159}
160
161static void _DSCoreStep(struct mCore* core) {
162 ARMRun(core->cpu);
163}
164
165static size_t _DSCoreStateSize(struct mCore* core) {
166 UNUSED(core);
167 return 0;
168}
169
170static bool _DSCoreLoadState(struct mCore* core, const void* state) {
171 return false;
172}
173
174static bool _DSCoreSaveState(struct mCore* core, void* state) {
175 return false;
176}
177
178static void _DSCoreSetKeys(struct mCore* core, uint32_t keys) {
179 struct DSCore* dscore = (struct DSCore*) core;
180 dscore->keys = keys;
181}
182
183static void _DSCoreAddKeys(struct mCore* core, uint32_t keys) {
184 struct DSCore* dscore = (struct DSCore*) core;
185 dscore->keys |= keys;
186}
187
188static void _DSCoreClearKeys(struct mCore* core, uint32_t keys) {
189 struct DSCore* dscore = (struct DSCore*) core;
190 dscore->keys &= ~keys;
191}
192
193static int32_t _DSCoreFrameCounter(struct mCore* core) {
194 struct DS* ds = core->board;
195 return ds->video.frameCounter;
196}
197
198static int32_t _DSCoreFrameCycles(struct mCore* core) {
199 UNUSED(core);
200 return DS_VIDEO_TOTAL_LENGTH;
201}
202
203static int32_t _DSCoreFrequency(struct mCore* core) {
204 UNUSED(core);
205 return DS_ARM946ES_FREQUENCY;
206}
207
208static void _DSCoreGetGameTitle(struct mCore* core, char* title) {
209 DSGetGameTitle(core->board, title);
210}
211
212static void _DSCoreGetGameCode(struct mCore* core, char* title) {
213 DSGetGameCode(core->board, title);
214}
215
216static void _DSCoreSetRTC(struct mCore* core, struct mRTCSource* rtc) {
217 struct DS* ds = core->board;
218 ds->rtcSource = rtc;
219}
220
221static void _DSCoreSetRotation(struct mCore* core, struct mRotationSource* rotation) {
222}
223
224static void _DSCoreSetRumble(struct mCore* core, struct mRumble* rumble) {
225 struct DS* ds = core->board;
226 ds->rumble = rumble;
227}
228
229static uint32_t _DSCoreBusRead8(struct mCore* core, uint32_t address) {
230 struct ARMCore* cpu = core->cpu;
231 return cpu->memory.load8(cpu, address, 0);
232}
233
234static uint32_t _DSCoreBusRead16(struct mCore* core, uint32_t address) {
235 struct ARMCore* cpu = core->cpu;
236 return cpu->memory.load16(cpu, address, 0);
237
238}
239
240static uint32_t _DSCoreBusRead32(struct mCore* core, uint32_t address) {
241 struct ARMCore* cpu = core->cpu;
242 return cpu->memory.load32(cpu, address, 0);
243}
244
245static void _DSCoreBusWrite8(struct mCore* core, uint32_t address, uint8_t value) {
246 struct ARMCore* cpu = core->cpu;
247 cpu->memory.store8(cpu, address, value, 0);
248}
249
250static void _DSCoreBusWrite16(struct mCore* core, uint32_t address, uint16_t value) {
251 struct ARMCore* cpu = core->cpu;
252 cpu->memory.store16(cpu, address, value, 0);
253}
254
255static void _DSCoreBusWrite32(struct mCore* core, uint32_t address, uint32_t value) {
256 struct ARMCore* cpu = core->cpu;
257 cpu->memory.store32(cpu, address, value, 0);
258}
259
260static uint32_t _DSCoreRawRead8(struct mCore* core, uint32_t address) {
261 return 0;
262}
263
264static uint32_t _DSCoreRawRead16(struct mCore* core, uint32_t address) {
265 return 0;
266}
267
268static uint32_t _DSCoreRawRead32(struct mCore* core, uint32_t address) {
269 return 0;
270}
271
272static void _DSCoreRawWrite8(struct mCore* core, uint32_t address, uint8_t value) {
273}
274
275static void _DSCoreRawWrite16(struct mCore* core, uint32_t address, uint16_t value) {
276}
277
278static void _DSCoreRawWrite32(struct mCore* core, uint32_t address, uint32_t value) {
279}
280
281static bool _DSCoreSupportsDebuggerType(struct mCore* core, enum mDebuggerType type) {
282 UNUSED(core);
283 switch (type) {
284#ifdef USE_CLI_DEBUGGER
285 case DEBUGGER_CLI:
286 return true;
287#endif
288#ifdef USE_GDB_STUB
289 case DEBUGGER_GDB:
290 return true;
291#endif
292 default:
293 return false;
294 }
295}
296
297static struct mDebuggerPlatform* _DSCoreDebuggerPlatform(struct mCore* core) {
298 struct DSCore* dscore = (struct DSCore*) core;
299 if (!dscore->debuggerPlatform) {
300 dscore->debuggerPlatform = ARMDebuggerPlatformCreate();
301 }
302 return dscore->debuggerPlatform;
303}
304
305static struct CLIDebuggerSystem* _DSCoreCliDebuggerSystem(struct mCore* core) {
306#ifdef USE_CLI_DEBUGGER
307 return &DSCLIDebuggerCreate(core)->d;
308#else
309 UNUSED(core);
310 return NULL;
311#endif
312}
313
314static void _DSCoreAttachDebugger(struct mCore* core, struct mDebugger* debugger) {
315 if (core->debugger) {
316 DSDetachDebugger(core->board);
317 }
318 DSAttachDebugger(core->board, debugger);
319 core->debugger = debugger;
320}
321
322static void _DSCoreDetachDebugger(struct mCore* core) {
323 DSDetachDebugger(core->board);
324 core->debugger = NULL;
325}
326
327static struct mCheatDevice* _DSCoreCheatDevice(struct mCore* core) {
328 return NULL;
329}
330
331static size_t _DSCoreSavedataClone(struct mCore* core, void** sram) {
332 return 0;
333}
334
335static bool _DSCoreSavedataLoad(struct mCore* core, const void* sram, size_t size) {
336 return false;
337}
338
339struct mCore* DSCoreCreate(void) {
340 struct DSCore* dscore = malloc(sizeof(*dscore));
341 struct mCore* core = &dscore->d;
342 memset(&core->opts, 0, sizeof(core->opts));
343 core->cpu = NULL;
344 core->board = NULL;
345 core->debugger = NULL;
346 core->init = _DSCoreInit;
347 core->deinit = _DSCoreDeinit;
348 core->platform = _DSCorePlatform;
349 core->setSync = _DSCoreSetSync;
350 core->loadConfig = _DSCoreLoadConfig;
351 core->desiredVideoDimensions = _DSCoreDesiredVideoDimensions;
352 core->setVideoBuffer = _DSCoreSetVideoBuffer;
353 core->getVideoBuffer = _DSCoreGetVideoBuffer;
354 core->getAudioChannel = _DSCoreGetAudioChannel;
355 core->setAudioBufferSize = _DSCoreSetAudioBufferSize;
356 core->getAudioBufferSize = _DSCoreGetAudioBufferSize;
357 core->setAVStream = _DSCoreSetAVStream;
358 core->isROM = DSIsROM;
359 core->loadROM = _DSCoreLoadROM;
360 core->loadBIOS = _DSCoreLoadBIOS;
361 core->loadSave = _DSCoreLoadSave;
362 core->loadPatch = _DSCoreLoadPatch;
363 core->unloadROM = _DSCoreUnloadROM;
364 core->reset = _DSCoreReset;
365 core->runFrame = _DSCoreRunFrame;
366 core->runLoop = _DSCoreRunLoop;
367 core->step = _DSCoreStep;
368 core->stateSize = _DSCoreStateSize;
369 core->loadState = _DSCoreLoadState;
370 core->saveState = _DSCoreSaveState;
371 core->setKeys = _DSCoreSetKeys;
372 core->addKeys = _DSCoreAddKeys;
373 core->clearKeys = _DSCoreClearKeys;
374 core->frameCounter = _DSCoreFrameCounter;
375 core->frameCycles = _DSCoreFrameCycles;
376 core->frequency = _DSCoreFrequency;
377 core->getGameTitle = _DSCoreGetGameTitle;
378 core->getGameCode = _DSCoreGetGameCode;
379 core->setRTC = _DSCoreSetRTC;
380 core->setRotation = _DSCoreSetRotation;
381 core->setRumble = _DSCoreSetRumble;
382 core->busRead8 = _DSCoreBusRead8;
383 core->busRead16 = _DSCoreBusRead16;
384 core->busRead32 = _DSCoreBusRead32;
385 core->busWrite8 = _DSCoreBusWrite8;
386 core->busWrite16 = _DSCoreBusWrite16;
387 core->busWrite32 = _DSCoreBusWrite32;
388 core->rawRead8 = _DSCoreRawRead8;
389 core->rawRead16 = _DSCoreRawRead16;
390 core->rawRead32 = _DSCoreRawRead32;
391 core->rawWrite8 = _DSCoreRawWrite8;
392 core->rawWrite16 = _DSCoreRawWrite16;
393 core->rawWrite32 = _DSCoreRawWrite32;
394 core->supportsDebuggerType = _DSCoreSupportsDebuggerType;
395 core->debuggerPlatform = _DSCoreDebuggerPlatform;
396 core->cliDebuggerSystem = _DSCoreCliDebuggerSystem;
397 core->attachDebugger = _DSCoreAttachDebugger;
398 core->detachDebugger = _DSCoreDetachDebugger;
399 core->cheatDevice = _DSCoreCheatDevice;
400 core->savedataClone = _DSCoreSavedataClone;
401 core->savedataLoad = _DSCoreSavedataLoad;
402 return core;
403}