From d0cfc8d6be3ffe873906ced427ac3a5bc8541c41 Mon Sep 17 00:00:00 2001 From: luigi__ Date: Thu, 14 Jan 2010 18:55:45 +0000 Subject: [PATCH] Add an option to patch the DelayLoop SWI when loading BIOS images (speed hack). Will work ONLY with Nintendo BIOS dumps! (the addresses that are overwritten are hardcoded). --- desmume/src/NDSSystem.cpp | 25 +++++++++++++++++++++---- desmume/src/NDSSystem.h | 2 ++ desmume/src/windows/main.cpp | 8 ++++++++ desmume/src/windows/resource.h | 1 + desmume/src/windows/resources.rc | Bin 911344 -> 921990 bytes 5 files changed, 32 insertions(+), 4 deletions(-) diff --git a/desmume/src/NDSSystem.cpp b/desmume/src/NDSSystem.cpp index ff29b0217..9ef4ae8eb 100644 --- a/desmume/src/NDSSystem.cpp +++ b/desmume/src/NDSSystem.cpp @@ -1852,6 +1852,7 @@ void NDS_exec(s32 nb) } //DEBUG_statistics.printSequencerExecutionCounters(); + //DEBUG_statistics.print(); //end of frame emulation housekeeping if(LagFrameFlag) @@ -1941,13 +1942,21 @@ void NDS_Reset() else inf = NULL; - if(inf) { + if(inf) + { fread(MMU.ARM7_BIOS,1,16384,inf); fclose(inf); + if(CommonSettings.SWIFromBIOS == true) NDS_ARM7.swi_tab = 0; else NDS_ARM7.swi_tab = ARM7_swi_tab; + + if (CommonSettings.PatchSWI3) + _MMU_write16(0x00002F08, 0x4770); + INFO("ARM7 BIOS is loaded.\n"); - } else { + } + else + { NDS_ARM7.swi_tab = ARM7_swi_tab; for (int t = 0; t < 16384; t++) @@ -1971,13 +1980,21 @@ void NDS_Reset() inf = NULL; //memcpy(MMU.ARM9_BIOS + 0x20, gba_header_data_0x04, 156); - if(inf) { + if(inf) + { fread(MMU.ARM9_BIOS,1,4096,inf); fclose(inf); + if(CommonSettings.SWIFromBIOS == true) NDS_ARM9.swi_tab = 0; else NDS_ARM9.swi_tab = ARM9_swi_tab; + + if (CommonSettings.PatchSWI3) + _MMU_write16(0xFFFF07CC, 0x4770); + INFO("ARM9 BIOS is loaded.\n"); - } else { + } + else + { NDS_ARM9.swi_tab = ARM9_swi_tab; for (int t = 0; t < 4096; t++) diff --git a/desmume/src/NDSSystem.h b/desmume/src/NDSSystem.h index 4a8b2e880..2fe653480 100644 --- a/desmume/src/NDSSystem.h +++ b/desmume/src/NDSSystem.h @@ -456,6 +456,7 @@ extern struct TCommonSettings { , GFX3D_Fog(true) , UseExtBIOS(false) , SWIFromBIOS(false) + , PatchSWI3(false) , UseExtFirmware(false) , BootFromFirmware(false) , DebugConsole(false) @@ -484,6 +485,7 @@ extern struct TCommonSettings { char ARM9BIOS[256]; char ARM7BIOS[256]; bool SWIFromBIOS; + bool PatchSWI3; bool UseExtFirmware; char Firmware[256]; diff --git a/desmume/src/windows/main.cpp b/desmume/src/windows/main.cpp index aa65d1782..dfd8f1f76 100644 --- a/desmume/src/windows/main.cpp +++ b/desmume/src/windows/main.cpp @@ -2630,6 +2630,7 @@ int _main() GetPrivateProfileString("BIOS", "ARM9BIOSFile", "bios9.bin", CommonSettings.ARM9BIOS, 256, IniName); GetPrivateProfileString("BIOS", "ARM7BIOSFile", "bios7.bin", CommonSettings.ARM7BIOS, 256, IniName); CommonSettings.SWIFromBIOS = GetPrivateProfileBool("BIOS", "SWIFromBIOS", FALSE, IniName); + CommonSettings.PatchSWI3 = GetPrivateProfileBool("BIOS", "PatchSWI3", FALSE, IniName); CommonSettings.UseExtFirmware = GetPrivateProfileBool("Firmware", "UseExtFirmware", FALSE, IniName); GetPrivateProfileString("Firmware", "FirmwareFile", "firmware.bin", CommonSettings.Firmware, 256, IniName); @@ -5374,6 +5375,7 @@ LRESULT CALLBACK EmulationSettingsDlgProc(HWND hDlg, UINT uMsg, WPARAM wParam, L CheckDlgItem(hDlg,IDC_CHECKBOX_ENSATAEMULATION,CommonSettings.EnsataEmulation); CheckDlgItem(hDlg,IDC_USEEXTBIOS,CommonSettings.UseExtBIOS); CheckDlgItem(hDlg, IDC_BIOSSWIS, CommonSettings.SWIFromBIOS); + CheckDlgItem(hDlg, IDC_PATCHSWI3, CommonSettings.PatchSWI3); SetDlgItemText(hDlg, IDC_ARM9BIOS, CommonSettings.ARM9BIOS); SetDlgItemText(hDlg, IDC_ARM7BIOS, CommonSettings.ARM7BIOS); @@ -5389,6 +5391,8 @@ LRESULT CALLBACK EmulationSettingsDlgProc(HWND hDlg, UINT uMsg, WPARAM wParam, L EnableWindow(cur, FALSE); cur = GetDlgItem(hDlg, IDC_BIOSSWIS); EnableWindow(cur, FALSE); + cur = GetDlgItem(hDlg, IDC_PATCHSWI3); + EnableWindow(cur, FALSE); } CheckDlgButton(hDlg, IDC_USEEXTFIRMWARE, ((CommonSettings.UseExtFirmware == true) ? BST_CHECKED : BST_UNCHECKED)); @@ -5430,6 +5434,7 @@ LRESULT CALLBACK EmulationSettingsDlgProc(HWND hDlg, UINT uMsg, WPARAM wParam, L cur = GetDlgItem(hDlg, IDC_ARM7BIOS); GetWindowText(cur, CommonSettings.ARM7BIOS, 256); CommonSettings.SWIFromBIOS = IsDlgCheckboxChecked(hDlg, IDC_BIOSSWIS); + CommonSettings.PatchSWI3 = IsDlgCheckboxChecked(hDlg, IDC_PATCHSWI3); CommonSettings.UseExtFirmware = IsDlgCheckboxChecked(hDlg, IDC_USEEXTFIRMWARE); cur = GetDlgItem(hDlg, IDC_FIRMWARE); @@ -5445,6 +5450,7 @@ LRESULT CALLBACK EmulationSettingsDlgProc(HWND hDlg, UINT uMsg, WPARAM wParam, L WritePrivateProfileString("BIOS", "ARM9BIOSFile", CommonSettings.ARM9BIOS, IniName); WritePrivateProfileString("BIOS", "ARM7BIOSFile", CommonSettings.ARM7BIOS, IniName); WritePrivateProfileInt("BIOS", "SWIFromBIOS", ((CommonSettings.SWIFromBIOS == true) ? 1 : 0), IniName); + WritePrivateProfileInt("BIOS", "PatchSWI3", ((CommonSettings.PatchSWI3 == true) ? 1 : 0), IniName); WritePrivateProfileInt("Firmware", "UseExtFirmware", ((CommonSettings.UseExtFirmware == true) ? 1 : 0), IniName); WritePrivateProfileString("Firmware", "FirmwareFile", CommonSettings.Firmware, IniName); @@ -5476,6 +5482,8 @@ LRESULT CALLBACK EmulationSettingsDlgProc(HWND hDlg, UINT uMsg, WPARAM wParam, L EnableWindow(cur, enable); cur = GetDlgItem(hDlg, IDC_BIOSSWIS); EnableWindow(cur, enable); + cur = GetDlgItem(hDlg, IDC_PATCHSWI3); + EnableWindow(cur, enable); cur = GetDlgItem(hDlg, IDC_FIRMWAREBOOT); EnableWindow(cur, (enable && IsDlgButtonChecked(hDlg, IDC_USEEXTFIRMWARE))); } diff --git a/desmume/src/windows/resource.h b/desmume/src/windows/resource.h index d9801b68d..aa23e26ec 100644 --- a/desmume/src/windows/resource.h +++ b/desmume/src/windows/resource.h @@ -350,6 +350,7 @@ #define IDC_VISIBLE 1019 #define IDC_USEPHYSICAL 1019 #define IDC_SPLIT1 1021 +#define IDC_PATCHSWI3 1022 #define IDC_DEFAULT 1027 #define IDC_3DCORE 1028 #define IDC_TXT_COMPILED 1029 diff --git a/desmume/src/windows/resources.rc b/desmume/src/windows/resources.rc index 3d6d51b8188639393559ed842639361d811ada06..b78d602a24a8bf20a77d0670e5ec2ae3ca5b376b 100644 GIT binary patch delta 13557 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 z zc8>HQod17k6T#O2 delta 15292 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 F|Gy)yF)#oC