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 <mgba/ds/core.h>
7
8#include <mgba/core/cheats.h>
9#include <mgba/core/core.h>
10#include <mgba/core/log.h>
11#include <mgba/internal/arm/debugger/debugger.h>
12#include <mgba/internal/ds/ds.h>
13#include <mgba/internal/ds/extra/cli.h>
14#include <mgba/internal/ds/gx/software.h>
15#include <mgba/internal/ds/input.h>
16#include <mgba/internal/ds/renderers/software.h>
17#include <mgba-util/memory.h>
18#include <mgba-util/patch.h>
19#include <mgba-util/vfs.h>
20
21const static struct mCoreChannelInfo _DSVideoLayers[] = {
22 { 0, "abg0", "A BG0", "2D/3D" },
23 { 1, "abg1", "A BG1", NULL },
24 { 2, "abg2", "A BG2", NULL },
25 { 3, "abg3", "A BG3", NULL },
26 { 4, "aobj", "A OBJ", NULL },
27 { 5, "bbg0", "B BG0", "2D/3D" },
28 { 6, "bbg1", "B BG1", NULL },
29 { 7, "bbg2", "B BG2", NULL },
30 { 8, "bbg3", "B BG3", NULL },
31 { 9, "bobj", "B OBJ", NULL },
32};
33
34const static struct mCoreChannelInfo _DSAudioChannels[] = {
35 { 0, "ch00", "Channel 0", NULL },
36 { 1, "ch01", "Channel 1", NULL },
37 { 2, "ch02", "Channel 2", NULL },
38 { 3, "ch03", "Channel 3", NULL },
39 { 4, "ch04", "Channel 4", NULL },
40 { 5, "ch05", "Channel 5", NULL },
41 { 6, "ch06", "Channel 6", NULL },
42 { 7, "ch07", "Channel 7", NULL },
43 { 8, "ch08", "Channel 8", NULL },
44 { 9, "ch09", "Channel 9", NULL },
45 { 10, "ch10", "Channel 10", NULL },
46 { 11, "ch11", "Channel 11", NULL },
47 { 12, "ch12", "Channel 12", NULL },
48 { 13, "ch13", "Channel 13", NULL },
49 { 14, "ch14", "Channel 14", NULL },
50 { 15, "ch15", "Channel 15", NULL },
51};
52
53struct DSCore {
54 struct mCore d;
55 struct ARMCore* arm7;
56 struct ARMCore* arm9;
57 struct DSVideoSoftwareRenderer renderer;
58 struct DSGXSoftwareRenderer gxRenderer;
59 int keys;
60 int cursorX;
61 int cursorY;
62 bool touchDown;
63 struct mCPUComponent* components[CPU_COMPONENT_MAX];
64 struct mDebuggerPlatform* debuggerPlatform;
65 struct mCheatDevice* cheatDevice;
66};
67
68static bool _DSCoreInit(struct mCore* core) {
69 struct DSCore* dscore = (struct DSCore*) core;
70
71 struct ARMCore* arm7 = anonymousMemoryMap(sizeof(struct ARMCore));
72 struct ARMCore* arm9 = anonymousMemoryMap(sizeof(struct ARMCore));
73 struct DS* ds = anonymousMemoryMap(sizeof(struct DS));
74 if (!arm7 || !arm9 || !ds) {
75 free(arm7);
76 free(arm9);
77 free(ds);
78 return false;
79 }
80 core->cpu = arm9;
81 core->board = ds;
82 core->debugger = NULL;
83 dscore->arm7 = arm7;
84 dscore->arm9 = arm9;
85 dscore->debuggerPlatform = NULL;
86 dscore->cheatDevice = NULL;
87
88 DSCreate(ds);
89 memset(dscore->components, 0, sizeof(dscore->components));
90 ARMSetComponents(arm7, &ds->d, CPU_COMPONENT_MAX, dscore->components);
91 ARMSetComponents(arm9, &ds->d, CPU_COMPONENT_MAX, dscore->components);
92 ARMInit(arm7);
93 ARMInit(arm9);
94
95 DSVideoSoftwareRendererCreate(&dscore->renderer);
96 DSGXSoftwareRendererCreate(&dscore->gxRenderer);
97 dscore->renderer.outputBuffer = NULL;
98
99 dscore->keys = 0;
100 ds->keySource = &dscore->keys;
101 dscore->cursorX = 0;
102 ds->cursorSourceX = &dscore->cursorX;
103 dscore->cursorY = 0;
104 ds->cursorSourceY = &dscore->cursorY;
105 dscore->touchDown = false;
106 ds->touchSource = &dscore->touchDown;
107
108#if !defined(MINIMAL_CORE) || MINIMAL_CORE < 2
109 mDirectorySetInit(&core->dirs);
110#endif
111
112#ifndef MINIMAL_CORE
113 core->inputInfo = &DSInputInfo; // TODO: GBInputInfo
114#endif
115
116 return true;
117}
118
119static void _DSCoreDeinit(struct mCore* core) {
120 struct DSCore* dscore = (struct DSCore*) core;
121 ARMDeinit(dscore->arm7);
122 ARMDeinit(dscore->arm9);
123 DSDestroy(core->board);
124 mappedMemoryFree(dscore->arm7, sizeof(struct ARMCore));
125 mappedMemoryFree(dscore->arm9, sizeof(struct ARMCore));
126 mappedMemoryFree(core->board, sizeof(struct DS));
127#if !defined(MINIMAL_CORE) || MINIMAL_CORE < 2
128 mDirectorySetDeinit(&core->dirs);
129#endif
130
131 free(dscore->debuggerPlatform);
132 if (dscore->cheatDevice) {
133 mCheatDeviceDestroy(dscore->cheatDevice);
134 }
135 free(dscore->cheatDevice);
136 free(core);
137}
138
139static enum mPlatform _DSCorePlatform(const struct mCore* core) {
140 UNUSED(core);
141 return PLATFORM_DS;
142}
143
144static void _DSCoreSetSync(struct mCore* core, struct mCoreSync* sync) {
145 struct DS* ds = core->board;
146 ds->sync = sync;
147}
148
149static void _DSCoreLoadConfig(struct mCore* core, const struct mCoreConfig* config) {
150 struct DS* ds = core->board;
151 struct VFile* bios = NULL;
152
153 mCoreConfigCopyValue(&core->config, config, "ds.bios7");
154 mCoreConfigCopyValue(&core->config, config, "ds.bios9");
155 mCoreConfigCopyValue(&core->config, config, "ds.firmware");
156}
157
158static void _DSCoreDesiredVideoDimensions(struct mCore* core, unsigned* width, unsigned* height) {
159 UNUSED(core);
160 *width = DS_VIDEO_HORIZONTAL_PIXELS;
161 *height = DS_VIDEO_VERTICAL_PIXELS * 2;
162}
163
164static void _DSCoreSetVideoBuffer(struct mCore* core, color_t* buffer, size_t stride) {
165 struct DSCore* dscore = (struct DSCore*) core;
166 dscore->renderer.outputBuffer = buffer;
167 dscore->renderer.outputBufferStride = stride;
168}
169
170static void _DSCoreGetPixels(struct mCore* core, const void** buffer, size_t* stride) {
171 struct DSCore* dscore = (struct DSCore*) core;
172 dscore->renderer.d.getPixels(&dscore->renderer.d, stride, buffer);
173}
174
175static void _DSCorePutPixels(struct mCore* core, const void* buffer, size_t stride) {
176 struct DSCore* dscore = (struct DSCore*) core;
177 dscore->renderer.d.putPixels(&dscore->renderer.d, stride, buffer);
178}
179
180static struct blip_t* _DSCoreGetAudioChannel(struct mCore* core, int ch) {
181 struct DS* ds = core->board;
182 switch (ch) {
183 case 0:
184 return ds->audio.left;
185 case 1:
186 return ds->audio.right;
187 default:
188 return NULL;
189 }
190}
191
192static void _DSCoreSetAudioBufferSize(struct mCore* core, size_t samples) {
193 struct DS* ds = core->board;
194 DSAudioResizeBuffer(&ds->audio, samples);
195}
196
197static size_t _DSCoreGetAudioBufferSize(struct mCore* core) {
198 struct DS* ds = core->board;
199 return ds->audio.samples;
200}
201
202static void _DSCoreAddCoreCallbacks(struct mCore* core, struct mCoreCallbacks* coreCallbacks) {
203 struct DS* ds = core->board;
204 *mCoreCallbacksListAppend(&ds->coreCallbacks) = *coreCallbacks;
205}
206
207static void _DSCoreClearCoreCallbacks(struct mCore* core) {
208 struct DS* ds = core->board;
209 mCoreCallbacksListClear(&ds->coreCallbacks);
210}
211
212static void _DSCoreSetAVStream(struct mCore* core, struct mAVStream* stream) {
213 struct DS* ds = core->board;
214 ds->stream = stream;
215 if (stream && stream->videoDimensionsChanged) {
216 stream->videoDimensionsChanged(stream, DS_VIDEO_HORIZONTAL_PIXELS, DS_VIDEO_VERTICAL_PIXELS * 2);
217 }
218}
219
220static bool _DSCoreLoadROM(struct mCore* core, struct VFile* vf) {
221 return DSLoadROM(core->board, vf);
222}
223
224static bool _DSCoreLoadBIOS(struct mCore* core, struct VFile* vf, int type) {
225 UNUSED(type);
226 return DSLoadBIOS(core->board, vf);
227}
228
229static bool _DSCoreLoadSave(struct mCore* core, struct VFile* vf) {
230 return DSLoadSave(core->board, vf);
231}
232
233static bool _DSCoreLoadPatch(struct mCore* core, struct VFile* vf) {
234 return false;
235}
236
237static void _DSCoreUnloadROM(struct mCore* core) {
238 return DSUnloadROM(core->board);
239}
240
241static void _DSCoreChecksum(const struct mCore* core, void* data, enum mCoreChecksumType type) {
242}
243
244static void _DSCoreReset(struct mCore* core) {
245 struct DSCore* dscore = (struct DSCore*) core;
246 struct DS* ds = (struct DS*) core->board;
247
248 if (dscore->renderer.outputBuffer) {
249 struct DSVideoRenderer* renderer = &dscore->renderer.d;
250 DSVideoAssociateRenderer(&ds->video, renderer);
251
252 struct DSGXRenderer* gxRenderer = &dscore->gxRenderer.d;
253 DSGXAssociateRenderer(&ds->gx, gxRenderer);
254 }
255
256#if !defined(MINIMAL_CORE) || MINIMAL_CORE < 2
257 struct VFile* bios7 = NULL;
258 struct VFile* bios9 = NULL;
259 struct VFile* firm = NULL;
260 if (core->opts.useBios) {
261 bool found7 = false;
262 bool found9 = false;
263 bool foundFirm = false;
264
265 if (!found7) {
266 const char* configPath = mCoreConfigGetValue(&core->config, "ds.bios7");
267 bios7 = VFileOpen(configPath, O_RDONLY);
268 if (bios7 && DSIsBIOS7(bios7)) {
269 found7 = true;
270 } else if (bios7) {
271 bios7->close(bios7);
272 bios7 = NULL;
273 }
274 }
275
276 if (!found9) {
277 const char* configPath = mCoreConfigGetValue(&core->config, "ds.bios9");
278 bios9 = VFileOpen(configPath, O_RDONLY);
279 if (bios9 && DSIsBIOS9(bios9)) {
280 found9 = true;
281 } else if (bios9) {
282 bios9->close(bios9);
283 bios9 = NULL;
284 }
285 }
286
287 if (!foundFirm) {
288 const char* configPath = mCoreConfigGetValue(&core->config, "ds.firmware");
289 firm = VFileOpen(configPath, O_RDONLY);
290 if (firm && DSIsFirmware(firm)) {
291 foundFirm = true;
292 } else if (firm) {
293 firm->close(firm);
294 firm = NULL;
295 }
296 }
297
298 if (!found7) {
299 char path[PATH_MAX];
300 mCoreConfigDirectory(path, PATH_MAX);
301 strncat(path, PATH_SEP "ds7_bios.bin", PATH_MAX - strlen(path));
302 bios7 = VFileOpen(path, O_RDONLY);
303 }
304
305 if (!found9) {
306 char path[PATH_MAX];
307 mCoreConfigDirectory(path, PATH_MAX);
308 strncat(path, PATH_SEP "ds9_bios.bin", PATH_MAX - strlen(path));
309 bios9 = VFileOpen(path, O_RDONLY);
310 }
311
312 if (!foundFirm) {
313 char path[PATH_MAX];
314 mCoreConfigDirectory(path, PATH_MAX);
315 strncat(path, PATH_SEP "ds_firmware.bin", PATH_MAX - strlen(path));
316 firm = VFileOpen(path, O_RDWR);
317 }
318 }
319 if (bios7) {
320 DSLoadBIOS(ds, bios7);
321 }
322 if (bios9) {
323 DSLoadBIOS(ds, bios9);
324 }
325 if (firm) {
326 DSLoadFirmware(ds, firm);
327 }
328#endif
329
330 ARMReset(ds->ds7.cpu);
331 ARMReset(ds->ds9.cpu);
332}
333
334static void _DSCoreRunFrame(struct mCore* core) {
335 struct DSCore* dscore = (struct DSCore*) core;
336 struct DS* ds = core->board;
337 int32_t frameCounter = ds->video.frameCounter;
338 while (ds->video.frameCounter == frameCounter) {
339 DSRunLoop(core->board);
340 }
341}
342
343static void _DSCoreRunLoop(struct mCore* core) {
344 DSRunLoop(core->board);
345}
346
347static void _DSCoreStep(struct mCore* core) {
348 struct DSCore* dscore = (struct DSCore*) core;
349 if (core->cpu == dscore->arm9) {
350 DS9Step(core->board);
351 } else {
352 DS7Step(core->board);
353 }
354}
355
356static size_t _DSCoreStateSize(struct mCore* core) {
357 UNUSED(core);
358 return 0;
359}
360
361static bool _DSCoreLoadState(struct mCore* core, const void* state) {
362 return false;
363}
364
365static bool _DSCoreSaveState(struct mCore* core, void* state) {
366 return false;
367}
368
369static void _DSCoreSetKeys(struct mCore* core, uint32_t keys) {
370 struct DSCore* dscore = (struct DSCore*) core;
371 dscore->keys = keys;
372}
373
374static void _DSCoreAddKeys(struct mCore* core, uint32_t keys) {
375 struct DSCore* dscore = (struct DSCore*) core;
376 dscore->keys |= keys;
377}
378
379static void _DSCoreClearKeys(struct mCore* core, uint32_t keys) {
380 struct DSCore* dscore = (struct DSCore*) core;
381 dscore->keys &= ~keys;
382}
383
384static void _DSCoreSetCursorLocation(struct mCore* core, int x, int y) {
385 struct DSCore* dscore = (struct DSCore*) core;
386 dscore->cursorX = x;
387 dscore->cursorY = y - DS_VIDEO_VERTICAL_PIXELS;
388 if (dscore->cursorY < 0) {
389 dscore->cursorY = 0;
390 } else if (dscore->cursorY >= DS_VIDEO_VERTICAL_PIXELS) {
391 dscore->cursorY = DS_VIDEO_VERTICAL_PIXELS - 1;
392 }
393 if (dscore->cursorX < 0) {
394 dscore->cursorX = 0;
395 } else if (dscore->cursorX >= DS_VIDEO_HORIZONTAL_PIXELS) {
396 dscore->cursorX = DS_VIDEO_HORIZONTAL_PIXELS - 1;
397 }
398}
399
400static void _DSCoreSetCursorDown(struct mCore* core, bool down) {
401 struct DSCore* dscore = (struct DSCore*) core;
402 dscore->touchDown = down;
403}
404
405static int32_t _DSCoreFrameCounter(const struct mCore* core) {
406 struct DS* ds = core->board;
407 return ds->video.frameCounter;
408}
409
410static int32_t _DSCoreFrameCycles(const struct mCore* core) {
411 UNUSED(core);
412 return DS_VIDEO_TOTAL_LENGTH;
413}
414
415static int32_t _DSCoreFrequency(const struct mCore* core) {
416 UNUSED(core);
417 return DS_ARM946ES_FREQUENCY;
418}
419
420static void _DSCoreGetGameTitle(const struct mCore* core, char* title) {
421 DSGetGameTitle(core->board, title);
422}
423
424static void _DSCoreGetGameCode(const struct mCore* core, char* title) {
425 DSGetGameCode(core->board, title);
426}
427
428static void _DSCoreSetPeripheral(struct mCore* core, int type, void* periph) {
429 struct DS* ds = core->board;
430 switch (type) {
431 case mPERIPH_RUMBLE:
432 ds->rumble = periph;
433 break;
434 default:
435 break;
436 }
437}
438
439static uint32_t _DSCoreBusRead8(struct mCore* core, uint32_t address) {
440 struct ARMCore* cpu = core->cpu;
441 return cpu->memory.load8(cpu, address, 0);
442}
443
444static uint32_t _DSCoreBusRead16(struct mCore* core, uint32_t address) {
445 struct ARMCore* cpu = core->cpu;
446 return cpu->memory.load16(cpu, address, 0);
447
448}
449
450static uint32_t _DSCoreBusRead32(struct mCore* core, uint32_t address) {
451 struct ARMCore* cpu = core->cpu;
452 return cpu->memory.load32(cpu, address, 0);
453}
454
455static void _DSCoreBusWrite8(struct mCore* core, uint32_t address, uint8_t value) {
456 struct ARMCore* cpu = core->cpu;
457 cpu->memory.store8(cpu, address, value, 0);
458}
459
460static void _DSCoreBusWrite16(struct mCore* core, uint32_t address, uint16_t value) {
461 struct ARMCore* cpu = core->cpu;
462 cpu->memory.store16(cpu, address, value, 0);
463}
464
465static void _DSCoreBusWrite32(struct mCore* core, uint32_t address, uint32_t value) {
466 struct ARMCore* cpu = core->cpu;
467 cpu->memory.store32(cpu, address, value, 0);
468}
469
470static uint32_t _DSCoreRawRead8(struct mCore* core, uint32_t address, int segment) {
471 // TODO: Raw
472 struct ARMCore* cpu = core->cpu;
473 return cpu->memory.load8(cpu, address, 0);
474}
475
476static uint32_t _DSCoreRawRead16(struct mCore* core, uint32_t address, int segment) {
477 // TODO: Raw
478 struct ARMCore* cpu = core->cpu;
479 return cpu->memory.load16(cpu, address, 0);
480}
481
482static uint32_t _DSCoreRawRead32(struct mCore* core, uint32_t address, int segment) {
483 // TODO: Raw
484 struct ARMCore* cpu = core->cpu;
485 return cpu->memory.load32(cpu, address, 0);
486}
487
488static void _DSCoreRawWrite8(struct mCore* core, uint32_t address, int segment, uint8_t value) {
489}
490
491static void _DSCoreRawWrite16(struct mCore* core, uint32_t address, int segment, uint16_t value) {
492}
493
494static void _DSCoreRawWrite32(struct mCore* core, uint32_t address, int segment, uint32_t value) {
495}
496
497#ifdef USE_DEBUGGERS
498static bool _DSCoreSupportsDebuggerType(struct mCore* core, enum mDebuggerType type) {
499 UNUSED(core);
500 switch (type) {
501 case DEBUGGER_CLI:
502 return true;
503#ifdef USE_GDB_STUB
504 case DEBUGGER_GDB:
505 return true;
506#endif
507 default:
508 return false;
509 }
510}
511
512static struct mDebuggerPlatform* _DSCoreDebuggerPlatform(struct mCore* core) {
513 struct DSCore* dscore = (struct DSCore*) core;
514 if (!dscore->debuggerPlatform) {
515 dscore->debuggerPlatform = ARMDebuggerPlatformCreate();
516 }
517 return dscore->debuggerPlatform;
518}
519
520static struct CLIDebuggerSystem* _DSCoreCliDebuggerSystem(struct mCore* core) {
521 return &DSCLIDebuggerCreate(core)->d;
522}
523
524static void _DSCoreAttachDebugger(struct mCore* core, struct mDebugger* debugger) {
525 if (core->debugger) {
526 DSDetachDebugger(core->board);
527 }
528 DSAttachDebugger(core->board, debugger);
529 core->debugger = debugger;
530}
531
532static void _DSCoreDetachDebugger(struct mCore* core) {
533 DSDetachDebugger(core->board);
534 core->debugger = NULL;
535}
536#endif
537
538static struct mCheatDevice* _DSCoreCheatDevice(struct mCore* core) {
539 return NULL;
540}
541
542static size_t _DSCoreSavedataClone(struct mCore* core, void** sram) {
543 return 0;
544}
545
546static bool _DSCoreSavedataRestore(struct mCore* core, const void* sram, size_t size, bool writeback) {
547 return false;
548}
549
550static size_t _DSCoreListVideoLayers(const struct mCore* core, const struct mCoreChannelInfo** info) {
551 UNUSED(core);
552 *info = _DSVideoLayers;
553 return sizeof(_DSVideoLayers) / sizeof(*_DSVideoLayers);
554}
555
556static size_t _DSCoreListAudioChannels(const struct mCore* core, const struct mCoreChannelInfo** info) {
557 UNUSED(core);
558 *info = _DSAudioChannels;
559 return sizeof(_DSAudioChannels) / sizeof(*_DSAudioChannels);
560}
561
562static void _DSCoreEnableVideoLayer(struct mCore* core, size_t id, bool enable) {
563 struct DS* ds = core->board;
564 // TODO
565}
566
567static void _DSCoreEnableAudioChannel(struct mCore* core, size_t id, bool enable) {
568 struct DS* ds = core->board;
569}
570
571struct mCore* DSCoreCreate(void) {
572 struct DSCore* dscore = malloc(sizeof(*dscore));
573 struct mCore* core = &dscore->d;
574 memset(&core->opts, 0, sizeof(core->opts));
575 core->cpu = NULL;
576 core->board = NULL;
577 core->debugger = NULL;
578 core->init = _DSCoreInit;
579 core->deinit = _DSCoreDeinit;
580 core->platform = _DSCorePlatform;
581 core->setSync = _DSCoreSetSync;
582 core->loadConfig = _DSCoreLoadConfig;
583 core->desiredVideoDimensions = _DSCoreDesiredVideoDimensions;
584 core->setVideoBuffer = _DSCoreSetVideoBuffer;
585 core->getPixels = _DSCoreGetPixels;
586 core->putPixels = _DSCorePutPixels;
587 core->getAudioChannel = _DSCoreGetAudioChannel;
588 core->setAudioBufferSize = _DSCoreSetAudioBufferSize;
589 core->getAudioBufferSize = _DSCoreGetAudioBufferSize;
590 core->addCoreCallbacks = _DSCoreAddCoreCallbacks;
591 core->clearCoreCallbacks = _DSCoreClearCoreCallbacks;
592 core->setAVStream = _DSCoreSetAVStream;
593 core->isROM = DSIsROM;
594 core->loadROM = _DSCoreLoadROM;
595 core->loadBIOS = _DSCoreLoadBIOS;
596 core->loadSave = _DSCoreLoadSave;
597 core->loadPatch = _DSCoreLoadPatch;
598 core->unloadROM = _DSCoreUnloadROM;
599 core->checksum = _DSCoreChecksum;
600 core->reset = _DSCoreReset;
601 core->runFrame = _DSCoreRunFrame;
602 core->runLoop = _DSCoreRunLoop;
603 core->step = _DSCoreStep;
604 core->stateSize = _DSCoreStateSize;
605 core->loadState = _DSCoreLoadState;
606 core->saveState = _DSCoreSaveState;
607 core->setKeys = _DSCoreSetKeys;
608 core->addKeys = _DSCoreAddKeys;
609 core->clearKeys = _DSCoreClearKeys;
610 core->setCursorLocation = _DSCoreSetCursorLocation;
611 core->setCursorDown = _DSCoreSetCursorDown;
612 core->frameCounter = _DSCoreFrameCounter;
613 core->frameCycles = _DSCoreFrameCycles;
614 core->frequency = _DSCoreFrequency;
615 core->getGameTitle = _DSCoreGetGameTitle;
616 core->getGameCode = _DSCoreGetGameCode;
617 core->setPeripheral = _DSCoreSetPeripheral;
618 core->busRead8 = _DSCoreBusRead8;
619 core->busRead16 = _DSCoreBusRead16;
620 core->busRead32 = _DSCoreBusRead32;
621 core->busWrite8 = _DSCoreBusWrite8;
622 core->busWrite16 = _DSCoreBusWrite16;
623 core->busWrite32 = _DSCoreBusWrite32;
624 core->rawRead8 = _DSCoreRawRead8;
625 core->rawRead16 = _DSCoreRawRead16;
626 core->rawRead32 = _DSCoreRawRead32;
627 core->rawWrite8 = _DSCoreRawWrite8;
628 core->rawWrite16 = _DSCoreRawWrite16;
629 core->rawWrite32 = _DSCoreRawWrite32;
630#ifdef USE_DEBUGGERS
631 core->supportsDebuggerType = _DSCoreSupportsDebuggerType;
632 core->debuggerPlatform = _DSCoreDebuggerPlatform;
633 core->cliDebuggerSystem = _DSCoreCliDebuggerSystem;
634 core->attachDebugger = _DSCoreAttachDebugger;
635 core->detachDebugger = _DSCoreDetachDebugger;
636#endif
637 core->cheatDevice = _DSCoreCheatDevice;
638 core->savedataClone = _DSCoreSavedataClone;
639 core->savedataRestore = _DSCoreSavedataRestore;
640 core->listVideoLayers = _DSCoreListVideoLayers;
641 core->listAudioChannels = _DSCoreListAudioChannels;
642 core->enableVideoLayer = _DSCoreEnableVideoLayer;
643 core->enableAudioChannel = _DSCoreEnableAudioChannel;
644 return core;
645}