diff --git a/include/mgba/internal/ds/ds.h b/include/mgba/internal/ds/ds.h
index 435f4896e..b88a6d545 100644
--- a/include/mgba/internal/ds/ds.h
+++ b/include/mgba/internal/ds/ds.h
@@ -157,6 +157,8 @@ bool DSLoadROM(struct DS* ds, struct VFile* vf);
void DSUnloadROM(struct DS* ds);
void DSApplyPatch(struct DS* ds, struct Patch* patch);
+bool DSIsBIOS7(struct VFile* vf);
+bool DSIsBIOS9(struct VFile* vf);
bool DSLoadBIOS(struct DS* ds, struct VFile* vf);
bool DSIsROM(struct VFile* vf);
diff --git a/src/ds/core.c b/src/ds/core.c
index 6e0036300..c8d7569d6 100644
--- a/src/ds/core.c
+++ b/src/ds/core.c
@@ -100,6 +100,10 @@ static void _DSCoreSetSync(struct mCore* core, struct mCoreSync* sync) {
static void _DSCoreLoadConfig(struct mCore* core, const struct mCoreConfig* config) {
struct DS* ds = core->board;
struct VFile* bios = NULL;
+
+ mCoreConfigCopyValue(&core->config, config, "ds.bios7");
+ mCoreConfigCopyValue(&core->config, config, "ds.bios9");
+
if (core->opts.useBios && core->opts.bios) {
bios = VFileOpen(core->opts.bios, O_RDONLY);
}
@@ -170,6 +174,9 @@ static void _DSCoreUnloadROM(struct mCore* core) {
return DSUnloadROM(core->board);
}
+static void _DSCoreChecksum(const struct mCore* core, void* data, enum mCoreChecksumType type) {
+}
+
static void _DSCoreReset(struct mCore* core) {
struct DSCore* dscore = (struct DSCore*) core;
struct DS* ds = (struct DS*) core->board;
@@ -180,19 +187,46 @@ static void _DSCoreReset(struct mCore* core) {
}
#if !defined(MINIMAL_CORE) || MINIMAL_CORE < 2
- struct VFile* bios7 = 0;
- struct VFile* bios9 = 0;
+ struct VFile* bios7 = NULL;
+ struct VFile* bios9 = NULL;
if (core->opts.useBios) {
- if (!core->opts.bios) {
+ bool found7 = false;
+ bool found9 = false;
+
+ if (!found7) {
+ const char* configPath = mCoreConfigGetValue(&core->config, "ds.bios7");
+ bios7 = VFileOpen(configPath, O_RDONLY);
+ if (bios7 && DSIsBIOS7(bios7)) {
+ found7 = true;
+ } else if (bios7) {
+ bios7->close(bios7);
+ bios7 = NULL;
+ }
+ }
+
+ if (!found9) {
+ const char* configPath = mCoreConfigGetValue(&core->config, "ds.bios9");
+ bios9 = VFileOpen(configPath, O_RDONLY);
+ if (bios9 && DSIsBIOS9(bios9)) {
+ found9 = true;
+ } else if (bios9) {
+ bios9->close(bios9);
+ bios9 = NULL;
+ }
+ }
+
+ if (!found7) {
char path[PATH_MAX];
mCoreConfigDirectory(path, PATH_MAX);
strncat(path, PATH_SEP "ds7_bios.bin", PATH_MAX - strlen(path));
bios7 = VFileOpen(path, O_RDONLY);
+ }
+
+ if (!found9) {
+ char path[PATH_MAX];
mCoreConfigDirectory(path, PATH_MAX);
strncat(path, PATH_SEP "ds9_bios.bin", PATH_MAX - strlen(path));
bios9 = VFileOpen(path, O_RDONLY);
- } else {
- bios7 = VFileOpen(core->opts.bios, O_RDONLY);
}
}
if (bios7) {
@@ -325,15 +359,21 @@ static void _DSCoreBusWrite32(struct mCore* core, uint32_t address, uint32_t val
}
static uint32_t _DSCoreRawRead8(struct mCore* core, uint32_t address, int segment) {
- return 0;
+ // TODO: Raw
+ struct ARMCore* cpu = core->cpu;
+ return cpu->memory.load8(cpu, address, 0);
}
static uint32_t _DSCoreRawRead16(struct mCore* core, uint32_t address, int segment) {
- return 0;
+ // TODO: Raw
+ struct ARMCore* cpu = core->cpu;
+ return cpu->memory.load16(cpu, address, 0);
}
static uint32_t _DSCoreRawRead32(struct mCore* core, uint32_t address, int segment) {
- return 0;
+ // TODO: Raw
+ struct ARMCore* cpu = core->cpu;
+ return cpu->memory.load32(cpu, address, 0);
}
static void _DSCoreRawWrite8(struct mCore* core, uint32_t address, int segment, uint8_t value) {
@@ -423,6 +463,7 @@ struct mCore* DSCoreCreate(void) {
core->loadSave = _DSCoreLoadSave;
core->loadPatch = _DSCoreLoadPatch;
core->unloadROM = _DSCoreUnloadROM;
+ core->checksum = _DSCoreChecksum;
core->reset = _DSCoreReset;
core->runFrame = _DSCoreRunFrame;
core->runLoop = _DSCoreRunLoop;
diff --git a/src/ds/ds.c b/src/ds/ds.c
index 32932cf56..5e25b1845 100644
--- a/src/ds/ds.c
+++ b/src/ds/ds.c
@@ -445,6 +445,38 @@ bool DSIsROM(struct VFile* vf) {
return memcmp(signature, DS_ROM_MAGIC, sizeof(signature)) == 0 || memcmp(signature, DS_ROM_MAGIC_2, sizeof(signature)) == 0;
}
+bool DSIsBIOS7(struct VFile* vf) {
+ size_t size = vf->size(vf);
+ void* data = NULL;
+ uint32_t crc;
+ if (size == DS7_SIZE_BIOS) {
+ data = vf->map(vf, size, MAP_READ);
+ }
+ if (!data) {
+ return false;
+ }
+ crc = doCrc32(data, size);
+ vf->unmap(vf, data, size);
+ return crc == DS7_BIOS_CHECKSUM;
+}
+
+bool DSIsBIOS9(struct VFile* vf) {
+ size_t size = vf->size(vf);
+ void* data = NULL;
+ uint32_t crc;
+ if (size == DS9_SIZE_BIOS) {
+ data = vf->map(vf, 0x1000, MAP_READ);
+ } else if (size == 0x1000) {
+ data = vf->map(vf, 0x1000, MAP_READ);
+ }
+ if (!data) {
+ return false;
+ }
+ crc = doCrc32(data, 0x1000);
+ vf->unmap(vf, data, 0x1000);
+ return crc == DS9_BIOS_CHECKSUM;
+}
+
bool DSLoadBIOS(struct DS* ds, struct VFile* vf) {
size_t size = vf->size(vf);
void* data = NULL;
diff --git a/src/platform/qt/SettingsView.cpp b/src/platform/qt/SettingsView.cpp
index 09df40cbf..bdf060ed6 100644
--- a/src/platform/qt/SettingsView.cpp
+++ b/src/platform/qt/SettingsView.cpp
@@ -130,6 +130,12 @@ SettingsView::SettingsView(ConfigController* controller, InputController* inputC
connect(m_ui.gbaBiosBrowse, &QPushButton::clicked, [this]() {
selectBios(m_ui.gbaBios);
});
+ connect(m_ui.dsBios7Browse, &QPushButton::clicked, [this]() {
+ selectBios(m_ui.dsBios7);
+ });
+ connect(m_ui.dsBios9Browse, &QPushButton::clicked, [this]() {
+ selectBios(m_ui.dsBios9);
+ });
connect(m_ui.gbBiosBrowse, &QPushButton::clicked, [this]() {
selectBios(m_ui.gbBios);
});
@@ -181,6 +187,8 @@ void SettingsView::updateConfig() {
saveSetting("gba.bios", m_ui.gbaBios);
saveSetting("gb.bios", m_ui.gbBios);
saveSetting("gbc.bios", m_ui.gbcBios);
+ saveSetting("ds.bios7", m_ui.dsBios7);
+ saveSetting("ds.bios9", m_ui.dsBios9);
saveSetting("useBios", m_ui.useBios);
saveSetting("skipBios", m_ui.skipBios);
saveSetting("audioBuffers", m_ui.audioBufferSize);
@@ -259,6 +267,8 @@ void SettingsView::reloadConfig() {
loadSetting("gba.bios", m_ui.gbaBios);
loadSetting("gb.bios", m_ui.gbBios);
loadSetting("gbc.bios", m_ui.gbcBios);
+ loadSetting("ds.bios7", m_ui.dsBios7);
+ loadSetting("ds.bios9", m_ui.dsBios9);
loadSetting("useBios", m_ui.useBios);
loadSetting("skipBios", m_ui.skipBios);
loadSetting("audioBuffers", m_ui.audioBufferSize);
diff --git a/src/platform/qt/SettingsView.ui b/src/platform/qt/SettingsView.ui
index 3957a29a2..4fc713477 100644
--- a/src/platform/qt/SettingsView.ui
+++ b/src/platform/qt/SettingsView.ui
@@ -77,7 +77,7 @@
-
- 1
+ 0
@@ -654,6 +654,9 @@
+
+ QFormLayout::FieldsStayAtSizeHint
+
-
@@ -682,51 +685,6 @@
- -
-
-
- Use BIOS file if found
-
-
- true
-
-
-
- -
-
-
- Skip BIOS intro
-
-
-
- -
-
-
-
-
-
-
- 0
- 0
-
-
-
-
- -
-
-
- Browse
-
-
-
-
-
- -
-
-
- GBA BIOS file:
-
-
-
-
@@ -755,6 +713,107 @@
+ -
+
+
+ GBA BIOS file:
+
+
+
+ -
+
+
-
+
+
+
+ 0
+ 0
+
+
+
+
+ -
+
+
+ Browse
+
+
+
+
+
+ -
+
+
+ DS BIOS 7 file:
+
+
+
+ -
+
+
-
+
+
+
+ 0
+ 0
+
+
+
+
+ -
+
+
+ Browse
+
+
+
+
+
+ -
+
+
+ Use BIOS file if found
+
+
+ true
+
+
+
+ -
+
+
+ Skip BIOS intro
+
+
+
+ -
+
+
-
+
+
+
+ 0
+ 0
+
+
+
+
+ -
+
+
+ Browse
+
+
+
+
+
+ -
+
+
+ DS BIOS 9 file:
+
+
+