all repos — mgba @ b77716738a30218bbcdc25133c51af339ea6485a

mGBA Game Boy Advance Emulator

DS: Load firmware
Vicki Pfau vi@endrift.com
Thu, 23 Feb 2017 11:19:10 -0800
commit

b77716738a30218bbcdc25133c51af339ea6485a

parent

d10ed92c562aa0c724ade1cfffeb1c49c235b86c

M include/mgba/internal/ds/ds.hinclude/mgba/internal/ds/ds.h

@@ -99,6 +99,7 @@

struct VFile* romVf; struct VFile* bios7Vf; struct VFile* bios9Vf; + struct VFile* firmwareVf; struct mKeyCallback* keyCallback; struct mCoreCallbacks* coreCallbacks;

@@ -162,6 +163,9 @@

bool DSIsBIOS7(struct VFile* vf); bool DSIsBIOS9(struct VFile* vf); bool DSLoadBIOS(struct DS* ds, struct VFile* vf); + +bool DSIsFirmware(struct VFile* vf); +bool DSLoadFirmware(struct DS* ds, struct VFile* vf); bool DSIsROM(struct VFile* vf); void DSGetGameCode(struct DS* ds, char* out);
M include/mgba/internal/ds/memory.hinclude/mgba/internal/ds/memory.h

@@ -65,6 +65,8 @@ DS9_SIZE_PALETTE_RAM = 0x00000800,

DS9_SIZE_OAM = 0x00000800, DS_SIZE_SLOT2 = 0x02000000, DS_SIZE_SLOT2_SRAM = 0x00010000, + + DS_SIZE_FIRMWARE = 0x00040000, }; enum {
M src/ds/core.csrc/ds/core.c

@@ -103,13 +103,7 @@ 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); - } - if (bios) { - DSLoadBIOS(ds, bios); - } + mCoreConfigCopyValue(&core->config, config, "ds.firmware"); } static void _DSCoreDesiredVideoDimensions(struct mCore* core, unsigned* width, unsigned* height) {

@@ -189,9 +183,11 @@

#if !defined(MINIMAL_CORE) || MINIMAL_CORE < 2 struct VFile* bios7 = NULL; struct VFile* bios9 = NULL; + struct VFile* firm = NULL; if (core->opts.useBios) { bool found7 = false; bool found9 = false; + bool foundFirm = false; if (!found7) { const char* configPath = mCoreConfigGetValue(&core->config, "ds.bios7");

@@ -215,6 +211,17 @@ bios9 = NULL;

} } + if (!foundFirm) { + const char* configPath = mCoreConfigGetValue(&core->config, "ds.firmware"); + firm = VFileOpen(configPath, O_RDONLY); + if (firm && DSIsFirmware(firm)) { + foundFirm = true; + } else if (firm) { + firm->close(firm); + firm = NULL; + } + } + if (!found7) { char path[PATH_MAX]; mCoreConfigDirectory(path, PATH_MAX);

@@ -228,12 +235,22 @@ mCoreConfigDirectory(path, PATH_MAX);

strncat(path, PATH_SEP "ds9_bios.bin", PATH_MAX - strlen(path)); bios9 = VFileOpen(path, O_RDONLY); } + + if (!foundFirm) { + char path[PATH_MAX]; + mCoreConfigDirectory(path, PATH_MAX); + strncat(path, PATH_SEP "ds_firmware.bin", PATH_MAX - strlen(path)); + firm = VFileOpen(path, O_RDWR); + } } if (bios7) { DSLoadBIOS(ds, bios7); } if (bios9) { DSLoadBIOS(ds, bios9); + } + if (firm) { + DSLoadFirmware(ds, firm); } #endif
M src/ds/ds.csrc/ds/ds.c

@@ -29,6 +29,9 @@ static const size_t DS_ROM_MAGIC_OFFSET = 0x15C;

static const uint8_t DS_ROM_MAGIC[] = { 0x56, 0xCF }; static const uint8_t DS_ROM_MAGIC_2[] = { 0x1A, 0x9E }; +static const size_t DS_FIRMWARE_MAGIC_OFFSET = 0x8; +static const uint8_t DS_FIRMWARE_MAGIC[] = { 0x4D, 0x41, 0x43 }; + enum { DS7_SP_BASE = 0x380FD80, DS7_SP_BASE_IRQ = 0x380FF80,

@@ -493,6 +496,17 @@ vf->unmap(vf, data, 0x1000);

return crc == DS9_BIOS_CHECKSUM; } +bool DSIsFirmware(struct VFile* vf) { + if (vf->seek(vf, DS_FIRMWARE_MAGIC_OFFSET, SEEK_SET) < 0) { + return false; + } + uint8_t signature[sizeof(DS_FIRMWARE_MAGIC)]; + if (vf->read(vf, &signature, sizeof(signature)) != sizeof(signature)) { + return false; + } + return memcmp(signature, DS_FIRMWARE_MAGIC, sizeof(signature)) == 0; +} + bool DSLoadBIOS(struct DS* ds, struct VFile* vf) { size_t size = vf->size(vf); void* data = NULL;

@@ -504,6 +518,8 @@ data = calloc(DS9_SIZE_BIOS, 1);

vf->read(vf, data, size); } else if (size == DS9_SIZE_BIOS) { data = vf->map(vf, size, MAP_READ); + } else if (size == DS_SIZE_FIRMWARE) { + return DSLoadFirmware(ds, vf); } if (!data) { return false;

@@ -522,6 +538,23 @@ mLOG(DS, WARN, "BIOS checksum incorrect");

vf->unmap(vf, data, size); return false; } + return true; +} + +bool DSLoadFirmware(struct DS* ds, struct VFile* vf) { + size_t size = vf->size(vf); + void* data = NULL; + if (!DSIsFirmware(vf)) { + return false; + } + if (size == DS_SIZE_FIRMWARE) { + data = vf->map(vf, size, MAP_WRITE); + } + if (!data) { + return false; + } + mLOG(DS, INFO, "Found DS firmware"); + ds->firmwareVf = vf; return true; }
M src/platform/qt/SettingsView.cppsrc/platform/qt/SettingsView.cpp

@@ -136,6 +136,9 @@ });

connect(m_ui.dsBios9Browse, &QPushButton::clicked, [this]() { selectBios(m_ui.dsBios9); }); + connect(m_ui.dsFirmwareBrowse, &QPushButton::clicked, [this]() { + selectBios(m_ui.dsFirmware); + }); connect(m_ui.gbBiosBrowse, &QPushButton::clicked, [this]() { selectBios(m_ui.gbBios); });

@@ -189,6 +192,7 @@ 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("ds.firmware", m_ui.dsFirmware); saveSetting("useBios", m_ui.useBios); saveSetting("skipBios", m_ui.skipBios); saveSetting("audioBuffers", m_ui.audioBufferSize);

@@ -269,6 +273,7 @@ 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("ds.firmware", m_ui.dsFirmware); loadSetting("useBios", m_ui.useBios); loadSetting("skipBios", m_ui.skipBios); loadSetting("audioBuffers", m_ui.audioBufferSize);
M src/platform/qt/SettingsView.uisrc/platform/qt/SettingsView.ui

@@ -769,20 +769,10 @@ </widget>

</item> </layout> </item> - <item row="5" column="1"> - <widget class="QCheckBox" name="useBios"> - <property name="text"> - <string>Use BIOS file if found</string> - </property> - <property name="checked"> - <bool>true</bool> - </property> - </widget> - </item> - <item row="6" column="1"> - <widget class="QCheckBox" name="skipBios"> + <item row="4" column="0"> + <widget class="QLabel" name="label_27"> <property name="text"> - <string>Skip BIOS intro</string> + <string>DS BIOS 9 file:</string> </property> </widget> </item>

@@ -807,10 +797,48 @@ </widget>

</item> </layout> </item> - <item row="4" column="0"> - <widget class="QLabel" name="label_27"> + <item row="5" column="1"> + <layout class="QHBoxLayout" name="horizontalLayout_17"> + <item> + <widget class="QLineEdit" name="dsFirmware"> + <property name="sizePolicy"> + <sizepolicy hsizetype="Expanding" vsizetype="Fixed"> + <horstretch>0</horstretch> + <verstretch>0</verstretch> + </sizepolicy> + </property> + </widget> + </item> + <item> + <widget class="QPushButton" name="dsFirmwareBrowse"> + <property name="text"> + <string>Browse</string> + </property> + </widget> + </item> + </layout> + </item> + <item row="6" column="1"> + <widget class="QCheckBox" name="useBios"> <property name="text"> - <string>DS BIOS 9 file:</string> + <string>Use BIOS file if found</string> + </property> + <property name="checked"> + <bool>true</bool> + </property> + </widget> + </item> + <item row="7" column="1"> + <widget class="QCheckBox" name="skipBios"> + <property name="text"> + <string>Skip BIOS intro</string> + </property> + </widget> + </item> + <item row="5" column="0"> + <widget class="QLabel" name="label_28"> + <property name="text"> + <string>DS firmware file:</string> </property> </widget> </item>