diff --git a/desmume/src/NDSSystem.cpp b/desmume/src/NDSSystem.cpp index 85792e842..db70b31ab 100644 --- a/desmume/src/NDSSystem.cpp +++ b/desmume/src/NDSSystem.cpp @@ -2534,6 +2534,8 @@ void NDS_Reset() #ifdef _NEW_BOOT gameInfo.restoreSecureArea(); + firmware->loadSettings(); + // Firmware boot only encrypted ROMs #ifndef WORDS_BIGENDIAN EncryptSecureArea((u8*)gameInfo.romdata,gameInfo.romsize); @@ -2624,7 +2626,10 @@ void NDS_Reset() _MMU_write08(REG_WRAMCNT,3); if (CommonSettings.UseExtFirmware && fw_success) + { firmware->unpack(); + firmware->loadSettings(); + } // Create the dummy firmware NDS_CreateDummyFirmware(&CommonSettings.fw_config); diff --git a/desmume/src/NDSSystem.h b/desmume/src/NDSSystem.h index 1ecb480e4..8bc72a642 100644 --- a/desmume/src/NDSSystem.h +++ b/desmume/src/NDSSystem.h @@ -520,6 +520,7 @@ extern struct TCommonSettings { , SWIFromBIOS(false) , PatchSWI3(false) , UseExtFirmware(false) + , UseExtFirmwareSettings(false) , BootFromFirmware(false) , DebugConsole(false) , EnsataEmulation(false) @@ -575,6 +576,7 @@ extern struct TCommonSettings { bool PatchSWI3; bool UseExtFirmware; + bool UseExtFirmwareSettings; char Firmware[256]; bool BootFromFirmware; NDS_fw_config_data fw_config; diff --git a/desmume/src/firmware.cpp b/desmume/src/firmware.cpp index 85b08782a..1fd2a30ed 100644 --- a/desmume/src/firmware.cpp +++ b/desmume/src/firmware.cpp @@ -20,6 +20,9 @@ #include "path.h" #include "encrypt.h" +#define DFC_ID_CODE TEXT("DeSmuME Firmware User Settings") +#define USER_SETTING_SIZE 0x100 + static _KEY1 enc(&MMU.ARM7_BIOS[0x0030]); u16 CFIRMWARE::getBootCodeCRC16() @@ -282,11 +285,17 @@ bool CFIRMWARE::load() if (MMU.fw.size != size) // reallocate mc_alloc(&MMU.fw, size); + userDataAddr = T1ReadWord(data, 0x20) * 8; + memcpy(MMU.fw.data, data, size); delete [] data; data = NULL; + // Generate the path for the external firmware config file. + std::string extFilePath = CFIRMWARE::GetExternalFilePath(); + strncpy(MMU.fw.userfile, extFilePath.c_str(), MAX_PATH); + return true; } @@ -475,50 +484,81 @@ bool CFIRMWARE::unpack() INFO(" * ARM7 unpacked size: 0x%08X (%i) bytes\n", size7, size7); } - // Generate the path for the external firmware config file. - std::string extFilePath = CFIRMWARE::GetExternalFilePath(); - strncpy(MMU.fw.userfile, extFilePath.c_str(), MAX_PATH); + memcpy(MMU.fw.data, data, size); + MMU.fw.fp = NULL; + + delete [] data; data = NULL; + return true; +} + +bool CFIRMWARE::loadSettings() +{ + if (!CommonSettings.UseExtFirmwareSettings) return false; + + u8 *data = MMU.fw.data; FILE *fp = fopen(MMU.fw.userfile, "rb"); if (fp) { fseek(fp, 0, SEEK_END); - if (ftell(fp) == (0x100 + 0x1D6 + 0x300)) + if (ftell(fp) == (USER_SETTING_SIZE + sizeof(DFC_ID_CODE))) { fseek(fp, 0, SEEK_SET); - char buf[0x301]; - memset(buf, 0, sizeof(buf)); - if (fread(buf, 1, 0x100, fp) == 0x100) + u8 *usr = new u8[USER_SETTING_SIZE]; + if (usr) { - printf("- loaded firmware config from %s:\n", MMU.fw.userfile); - memcpy(&data[0x3FE00], &buf[0], 0x100); - memcpy(&data[0x3FF00], &buf[0], 0x100); - printf(" * User settings\n"); - memset(buf, 0, sizeof(buf)); - if (fread(buf, 1, 0x1D6, fp) == 0x1D6) + if (fread(usr, 1, sizeof(DFC_ID_CODE), fp) == sizeof(DFC_ID_CODE)) { - memcpy(&data[0x002A], &buf[0], 0x1D6); - printf(" * WiFi settings\n"); - - memset(buf, 0, sizeof(buf)); - if (fread(buf, 1, 0x300, fp) == 0x300) + if (memcmp(usr, DFC_ID_CODE, sizeof(DFC_ID_CODE)) == 0) { - memcpy(&data[0x3FA00], &buf[0], 0x300); - printf(" * WiFi AP settings\n"); + memset(usr, 0xFF, USER_SETTING_SIZE); + if (fread(usr, 1, USER_SETTING_SIZE, fp) == USER_SETTING_SIZE) + { + memcpy(&data[userDataAddr], usr, USER_SETTING_SIZE); + memcpy(&data[userDataAddr + 0x100], usr, USER_SETTING_SIZE); + printf("Loaded user settings from %s:\n", MMU.fw.userfile); + } } } + delete [] usr; + usr = NULL; } } else - printf("- failed loading firmware config from %s (wrong file size)\n", MMU.fw.userfile); + printf("Failed loading firmware config from %s (wrong file size)\n", MMU.fw.userfile); + fclose(fp); } - printf("\n"); - memcpy(MMU.fw.data, data, size); - MMU.fw.fp = NULL; + return false; +} + +bool CFIRMWARE::saveSettings() +{ + if (!CommonSettings.UseExtFirmwareSettings) return false; + + u8 *data = MMU.fw.data; + // copy User Settings 1 to User Settings 0 area + memcpy(&data[userDataAddr], &data[userDataAddr + 0x100], 0x100); + + printf("Firmware: saving config"); + FILE *fp = fopen(MMU.fw.userfile, "wb"); + if (fp) + { + if (fwrite(DFC_ID_CODE, 1, sizeof(DFC_ID_CODE), fp) == sizeof(DFC_ID_CODE)) + { + if (fwrite(&data[userDataAddr], 1, 0x100, fp) == 0x100) + printf(" - done\n"); + else + printf(" - failed\n"); + } + else + printf(" - failed\n"); + fclose(fp); + } + else + printf(" - failed\n"); - delete [] data; data = NULL; return true; } diff --git a/desmume/src/firmware.h b/desmume/src/firmware.h index e8429cd22..13d38459a 100644 --- a/desmume/src/firmware.h +++ b/desmume/src/firmware.h @@ -29,16 +29,19 @@ private: u8 *tmp_data9; u8 *tmp_data7; u32 size9, size7; + u32 userDataAddr; u16 getBootCodeCRC16(); u32 decrypt(const u8 *in, u8* &out); u32 decompress(const u8 *in, u8* &out); public: - CFIRMWARE(): size9(0), size7(0), ARM9bootAddr(0), ARM7bootAddr(0), patched(0) {}; + CFIRMWARE(): size9(0), size7(0), ARM9bootAddr(0), ARM7bootAddr(0), patched(0), userDataAddr(0x3FE00) {}; bool load(); bool unpack(); + bool loadSettings(); + bool saveSettings(); static std::string GetExternalFilePath(); diff --git a/desmume/src/mc.cpp b/desmume/src/mc.cpp index f5f8c4965..331264101 100644 --- a/desmume/src/mc.cpp +++ b/desmume/src/mc.cpp @@ -176,32 +176,10 @@ void fw_reset_com(memory_chip_t *mc) fwrite(mc->data, mc->size, 1, mc->fp); } -#ifndef _NEW_BOOT - if (mc->isFirmware&&CommonSettings.UseExtFirmware) + if (mc->isFirmware && CommonSettings.UseExtFirmware && CommonSettings.UseExtFirmwareSettings && firmware) { - // copy User Settings 1 to User Settings 0 area - memcpy(&mc->data[0x3FE00], &mc->data[0x3FF00], 0x100); - - printf("Firmware: save config"); - FILE *fp = fopen(mc->userfile, "wb"); - if (fp) - { - if (fwrite(&mc->data[0x3FF00], 1, 0x100, fp) == 0x100) // User Settings - { - if (fwrite(&mc->data[0x0002A], 1, 0x1D6, fp) == 0x1D6) // WiFi Settings - { - if (fwrite(&mc->data[0x3FA00], 1, 0x300, fp) == 0x300) // WiFi AP Settings - printf(" - done\n"); - else - printf(" - failed\n"); - } - } - fclose(fp); - } - else - printf(" - failed\n"); + firmware->saveSettings(); } -#endif mc->write_enable = FALSE; } diff --git a/desmume/src/windows/main.cpp b/desmume/src/windows/main.cpp index 86f2a09ce..19d291052 100644 --- a/desmume/src/windows/main.cpp +++ b/desmume/src/windows/main.cpp @@ -3379,6 +3379,7 @@ int _main() CommonSettings.PatchSWI3 = GetPrivateProfileBool("BIOS", "PatchSWI3", false, IniName); CommonSettings.UseExtFirmware = GetPrivateProfileBool("Firmware", "UseExtFirmware", false, IniName); + CommonSettings.UseExtFirmwareSettings = GetPrivateProfileBool("Firmware", "UseExtFirmwareSettings", false, IniName); GetPrivateProfileString("Firmware", "FirmwareFile", "firmware.bin", CommonSettings.Firmware, 256, IniName); CommonSettings.BootFromFirmware = GetPrivateProfileBool("Firmware", "BootFromFirmware", false, IniName); @@ -6351,6 +6352,7 @@ LRESULT CALLBACK EmulationSettingsDlgProc(HWND hDlg, UINT uMsg, WPARAM wParam, L CheckDlgButton(hDlg, IDC_USEEXTFIRMWARE, ((CommonSettings.UseExtFirmware == true) ? BST_CHECKED : BST_UNCHECKED)); SetDlgItemText(hDlg, IDC_FIRMWARE, CommonSettings.Firmware); CheckDlgButton(hDlg, IDC_FIRMWAREBOOT, ((CommonSettings.BootFromFirmware == true) ? BST_CHECKED : BST_UNCHECKED)); + CheckDlgButton(hDlg, IDC_FIRMWAREEXTUSER, ((CommonSettings.UseExtFirmwareSettings == true) ? BST_CHECKED : BST_UNCHECKED)); if(CommonSettings.UseExtFirmware == false) { @@ -6365,6 +6367,12 @@ LRESULT CALLBACK EmulationSettingsDlgProc(HWND hDlg, UINT uMsg, WPARAM wParam, L cur = GetDlgItem(hDlg, IDC_FIRMWAREBOOT); EnableWindow(cur, FALSE); } + + if(CommonSettings.UseExtFirmware == false) + { + cur = GetDlgItem(hDlg, IDC_FIRMWAREEXTUSER); + EnableWindow(cur, FALSE); + } } return TRUE; @@ -6410,6 +6418,7 @@ LRESULT CALLBACK EmulationSettingsDlgProc(HWND hDlg, UINT uMsg, WPARAM wParam, L cur = GetDlgItem(hDlg, IDC_FIRMWARE); GetWindowText(cur, CommonSettings.Firmware, 256); CommonSettings.BootFromFirmware = IsDlgCheckboxChecked(hDlg, IDC_FIRMWAREBOOT); + CommonSettings.UseExtFirmwareSettings = IsDlgCheckboxChecked(hDlg, IDC_FIRMWAREEXTUSER); CommonSettings.DebugConsole = IsDlgCheckboxChecked(hDlg, IDC_CHECKBOX_DEBUGGERMODE); CommonSettings.EnsataEmulation = IsDlgCheckboxChecked(hDlg, IDC_CHECKBOX_ENSATAEMULATION); @@ -6435,6 +6444,7 @@ LRESULT CALLBACK EmulationSettingsDlgProc(HWND hDlg, UINT uMsg, WPARAM wParam, L WritePrivateProfileInt("Firmware", "UseExtFirmware", ((CommonSettings.UseExtFirmware == true) ? 1 : 0), IniName); WritePrivateProfileString("Firmware", "FirmwareFile", CommonSettings.Firmware, IniName); WritePrivateProfileInt("Firmware", "BootFromFirmware", ((CommonSettings.BootFromFirmware == true) ? 1 : 0), IniName); + WritePrivateProfileInt("Firmware", "UseExtFirmwareSettings", ((CommonSettings.UseExtFirmwareSettings == true) ? 1 : 0), IniName); #ifdef HAVE_JIT WritePrivateProfileInt("Emulation", "CPUmode", ((CommonSettings.use_jit == true) ? 1 : 0), IniName); #endif diff --git a/desmume/src/windows/resource.h b/desmume/src/windows/resource.h index 2b97fde15..e408780d9 100644 --- a/desmume/src/windows/resource.h +++ b/desmume/src/windows/resource.h @@ -439,6 +439,7 @@ #define IDC_FULL_CHARS 1055 #define IDC_LIST1 1056 #define IDC_IMP_INFO_CURRENT 1056 +#define IDC_FIRMWAREEXTUSER 1056 #define IDC_BADD_AR 1057 #define IDC_IMP_INFO_FILE 1057 #define IDC_BADD_CB 1058 diff --git a/desmume/src/windows/resources.rc b/desmume/src/windows/resources.rc index ddd0132ab..0293b370d 100644 Binary files a/desmume/src/windows/resources.rc and b/desmume/src/windows/resources.rc differ