diff --git a/desmume/src/MMU.cpp b/desmume/src/MMU.cpp index 6e618f367..b1b63ff2e 100644 --- a/desmume/src/MMU.cpp +++ b/desmume/src/MMU.cpp @@ -1528,6 +1528,22 @@ static INLINE void MMU_IPCSync(u8 proc, u32 val) sync_l |= val & 0x6000; + if(nds.ensataEmulation && proc==1 && nds.ensataIpcSyncCounter<9) { + u32 iteration = (val&0x0F00)>>8; + + if(iteration==8-nds.ensataIpcSyncCounter) + nds.ensataIpcSyncCounter++; + else printf("ERROR: ENSATA IPC SYNC HACK FAILED; BAD THINGS MAY HAPPEN\n"); + + //for some reason, the arm9 doesn't handshake when ensata is detected. + //so we complete the protocol here, which is to mirror the values 8..0 back to + //the arm7 as they are written by the arm7 + sync_r &= 0xF0FF; + sync_r |= (iteration<<8); + sync_l &= 0xFFF0; + sync_l |= iteration; + } + T1WriteLong(MMU.MMU_MEM[proc][0x40], 0x180, sync_l); T1WriteLong(MMU.MMU_MEM[proc^1][0x40], 0x180, sync_r); @@ -2142,6 +2158,12 @@ void FASTCALL _MMU_ARM9_write08(u32 adr, u8 val) case REG_SQRTCNT+2: printf("ERROR 8bit SQRTCNT WRITE\n"); return; case REG_SQRTCNT+3: printf("ERROR 8bit SQRTCNT WRITE\n"); return; + //ensata putchar port + case 0x04FFF000: + if(nds.ensataEmulation) + printf("%c",val); + break; + case REG_DISPA_DISP3DCNT: { u32 &disp3dcnt = MainScreen.gpu->dispx_st->dispA_DISP3DCNT.val; @@ -2815,11 +2837,6 @@ void FASTCALL _MMU_ARM9_write16(u32 adr, u16 val) return; } - if(adr>=0x05000000 && adr<0x06000000) - { - int zzz=9; - } - bool unmapped; adr = MMU_LCDmap(adr, unmapped); @@ -2924,6 +2941,7 @@ void FASTCALL _MMU_ARM9_write32(u32 adr, u32 val) ((u32 *)(MMU.MMU_MEM[ARMCPU_ARM9][0x40]))[(adr & 0xFFF) >> 2] = val; gfx3d_sendCommand(adr, val); return; + default: break; } @@ -2938,6 +2956,26 @@ void FASTCALL _MMU_ARM9_write32(u32 adr, u32 val) case REG_SQRTCNT: printf("ERROR 32bit SQRTCNT WRITE\n"); return; case REG_DIVCNT: printf("ERROR 32bit DIVCNT WRITE\n"); return; + //ensata handshaking port? + case 0x04FFF010: + if(nds.ensataEmulation && nds.ensataHandshake == ENSATA_HANDSHAKE_ack && val == 0x13579bdf) + nds.ensataHandshake = ENSATA_HANDSHAKE_confirm; + if(nds.ensataEmulation && nds.ensataHandshake == ENSATA_HANDSHAKE_confirm && val == 0xfdb97531) + { + printf("ENSATA HANDSHAKE COMPLETE\n"); + nds.ensataHandshake = ENSATA_HANDSHAKE_complete; + } + break; + + //todo - these are usually write only regs (these and 1000 more) + //shouldnt we block them from getting written? ugh + case eng_3D_CLIPMTX_RESULT: + if(nds.ensataEmulation && nds.ensataHandshake == ENSATA_HANDSHAKE_none && val==0x2468ace0) + { + printf("ENSATA HANDSHAKE BEGIN\n"); + nds.ensataHandshake = ENSATA_HANDSHAKE_query; + } + break; case eng_3D_GXSTAT: MMU_new.gxstat.write32(val); @@ -3299,6 +3337,13 @@ u16 FASTCALL _MMU_ARM9_read16(u32 adr) case REG_DIVCNT: return MMU_new.div.read16(); case eng_3D_GXSTAT: return MMU_new.gxstat.read(16,adr); + case REG_DISPA_VCOUNT: + if(nds.ensataEmulation && nds.ensataHandshake == ENSATA_HANDSHAKE_query) + { + nds.ensataHandshake = ENSATA_HANDSHAKE_ack; + return 270; + } + // ============================================= 3D case eng_3D_RAM_COUNT: return 0; diff --git a/desmume/src/NDSSystem.cpp b/desmume/src/NDSSystem.cpp index ad23fbf06..e59535295 100644 --- a/desmume/src/NDSSystem.cpp +++ b/desmume/src/NDSSystem.cpp @@ -2652,6 +2652,9 @@ void NDS_Reset() nds.touchX = nds.touchY = 0; nds.isTouch = 0; nds.debugConsole = CommonSettings.DebugConsole; + nds.ensataEmulation = CommonSettings.EnsataEmulation; + nds.ensataHandshake = ENSATA_HANDSHAKE_none; + nds.ensataIpcSyncCounter = 0; SetupMMU(nds.debugConsole); _MMU_write16(0x04000130, 0x3FF); diff --git a/desmume/src/NDSSystem.h b/desmume/src/NDSSystem.h index 257ef1580..38c74b091 100644 --- a/desmume/src/NDSSystem.h +++ b/desmume/src/NDSSystem.h @@ -150,7 +150,16 @@ void NDS_RescheduleGXFIFO(u32 cost); void NDS_RescheduleDMA(); void NDS_RescheduleTimers(); -typedef struct +enum ENSATA_HANDSHAKE +{ + ENSATA_HANDSHAKE_none = 0, + ENSATA_HANDSHAKE_query = 1, + ENSATA_HANDSHAKE_ack = 2, + ENSATA_HANDSHAKE_confirm = 3, + ENSATA_HANDSHAKE_complete = 4, +}; + +struct NDSSystem { s32 wifiCycle; s32 cycles; @@ -184,9 +193,18 @@ typedef struct //if the game was booted on a debug console, this is set BOOL debugConsole; + //set if the user requests ensata emulation + BOOL ensataEmulation; + + //there is a hack in the ipc sync for ensata. this tracks its state + u32 ensataIpcSyncCounter; + + //maintains the state of the ensata handshaking protocol + u32 ensataHandshake; + bool isInVblank() const { return VCount >= 192; } bool isIn3dVblank() const { return VCount >= 192 && VCount<215; } -} NDSSystem; +}; /** /brief A touchscreen calibration point. */ @@ -432,7 +450,7 @@ extern struct TCommonSettings { , UseExtFirmware(false) , BootFromFirmware(false) , DebugConsole(false) - //, gfx3d_flushMode(0) + , EnsataEmulation(false) , num_cores(1) , micMode(InternalNoise) , spuInterpolationMode(SPUInterpolation_Linear) @@ -462,6 +480,7 @@ extern struct TCommonSettings { bool BootFromFirmware; bool DebugConsole; + bool EnsataEmulation; int num_cores; bool single_core() { return num_cores==1; } diff --git a/desmume/src/saves.cpp b/desmume/src/saves.cpp index d26bd32fe..8c5aacd01 100644 --- a/desmume/src/saves.cpp +++ b/desmume/src/saves.cpp @@ -173,6 +173,9 @@ SFORMAT SF_NDS[]={ { "_TPY", 2, 1, &nds.touchY}, { "_TPB", 4, 1, &nds.isTouch}, { "_DBG", 4, 1, &nds.debugConsole}, + { "_ENS", 4, 1, &nds.ensataEmulation}, + { "_ENH", 4, 1, &nds.ensataHandshake}, + { "_ENI", 4, 1, &nds.ensataIpcSyncCounter}, { 0 } }; diff --git a/desmume/src/windows/main.cpp b/desmume/src/windows/main.cpp index a82d5301c..56ec113c2 100644 --- a/desmume/src/windows/main.cpp +++ b/desmume/src/windows/main.cpp @@ -2501,6 +2501,7 @@ int _main() } CommonSettings.DebugConsole = GetPrivateProfileBool("Emulation", "DebugConsole", FALSE, IniName); + CommonSettings.EnsataEmulation = GetPrivateProfileBool("Emulation", "EnsataEmulation", FALSE, IniName); CommonSettings.UseExtBIOS = GetPrivateProfileBool("BIOS", "UseExtBIOS", FALSE, IniName); GetPrivateProfileString("BIOS", "ARM9BIOSFile", "bios9.bin", CommonSettings.ARM9BIOS, 256, IniName); GetPrivateProfileString("BIOS", "ARM7BIOSFile", "bios7.bin", CommonSettings.ARM7BIOS, 256, IniName); @@ -5066,11 +5067,12 @@ LRESULT CALLBACK EmulationSettingsDlgProc(HWND hDlg, UINT uMsg, WPARAM wParam, L { HWND cur; - CheckDlgButton(hDlg, IDC_CHECKBOX_DEBUGGERMODE, ((CommonSettings.DebugConsole == true) ? BST_CHECKED : BST_UNCHECKED)); - CheckDlgButton(hDlg, IDC_USEEXTBIOS, ((CommonSettings.UseExtBIOS == true) ? BST_CHECKED : BST_UNCHECKED)); + CheckDlgItem(hDlg,IDC_CHECKBOX_DEBUGGERMODE,CommonSettings.DebugConsole); + CheckDlgItem(hDlg,IDC_CHECKBOX_ENSATAEMULATION,CommonSettings.EnsataEmulation); + CheckDlgItem(hDlg,IDC_USEEXTBIOS,CommonSettings.UseExtBIOS); + CheckDlgItem(hDlg, IDC_BIOSSWIS, CommonSettings.SWIFromBIOS); SetDlgItemText(hDlg, IDC_ARM9BIOS, CommonSettings.ARM9BIOS); SetDlgItemText(hDlg, IDC_ARM7BIOS, CommonSettings.ARM7BIOS); - CheckDlgButton(hDlg, IDC_BIOSSWIS, ((CommonSettings.SWIFromBIOS == true) ? BST_CHECKED : BST_UNCHECKED)); if(CommonSettings.UseExtBIOS == false) { @@ -5132,8 +5134,10 @@ LRESULT CALLBACK EmulationSettingsDlgProc(HWND hDlg, UINT uMsg, WPARAM wParam, L CommonSettings.BootFromFirmware = IsDlgCheckboxChecked(hDlg, IDC_FIRMWAREBOOT); CommonSettings.DebugConsole = IsDlgCheckboxChecked(hDlg, IDC_CHECKBOX_DEBUGGERMODE); + CommonSettings.EnsataEmulation = IsDlgCheckboxChecked(hDlg, IDC_CHECKBOX_ENSATAEMULATION); WritePrivateProfileInt("Emulation", "DebugConsole", ((CommonSettings.DebugConsole == true) ? 1 : 0), IniName); + WritePrivateProfileInt("Emulation", "EnsataEmulation", ((CommonSettings.EnsataEmulation == true) ? 1 : 0), IniName); WritePrivateProfileInt("BIOS", "UseExtBIOS", ((CommonSettings.UseExtBIOS == true) ? 1 : 0), IniName); WritePrivateProfileString("BIOS", "ARM9BIOSFile", CommonSettings.ARM9BIOS, IniName); WritePrivateProfileString("BIOS", "ARM7BIOSFile", CommonSettings.ARM7BIOS, IniName); diff --git a/desmume/src/windows/resource.h b/desmume/src/windows/resource.h index 636d47817..3c02f8486 100644 --- a/desmume/src/windows/resource.h +++ b/desmume/src/windows/resource.h @@ -298,6 +298,7 @@ #define IDC_MFRAMES 1003 #define IDC_ROTATE0 1003 #define IDC_BUTTON2 1003 +#define IDC_CHECKBOX_ENSATAEMULATION 1003 #define IDC_ARM9BIOSBROWSE 1004 #define IDC_EDIT11 1004 #define IDC_GI_GAMECODE 1004 diff --git a/desmume/src/windows/resources.rc b/desmume/src/windows/resources.rc index 0ab90cb8f..44e4431fd 100644 Binary files a/desmume/src/windows/resources.rc and b/desmume/src/windows/resources.rc differ