From 315d5b9e669bd59d5272754a8645b35d9a5e47d9 Mon Sep 17 00:00:00 2001 From: zilmar Date: Thu, 21 Nov 2024 19:13:56 +1030 Subject: [PATCH] Core: When running as recompiler in 32bit mode, if LW/SW are in delay slots on block boundaries use 32bit interpter functions --- Source/Project64-core/3rdParty/zip.h | 1 + .../N64System/Interpreter/InterpreterOps.cpp | 27 +++++++++++++++---- .../N64System/Interpreter/InterpreterOps.h | 6 +++-- Source/Project64-core/N64System/N64Rom.cpp | 2 +- Source/Project64-core/N64System/N64System.cpp | 2 +- Source/Project64/UserInterface/RomBrowser.cpp | 6 ++--- 6 files changed, 32 insertions(+), 12 deletions(-) diff --git a/Source/Project64-core/3rdParty/zip.h b/Source/Project64-core/3rdParty/zip.h index fffc0cb69..592b79c80 100644 --- a/Source/Project64-core/3rdParty/zip.h +++ b/Source/Project64-core/3rdParty/zip.h @@ -2,4 +2,5 @@ #include "../../3rdParty/zlib/contrib/minizip/unzip.h" #include "../../3rdParty/zlib/contrib/minizip/zip.h" + #include "../../3rdParty/zlib/contrib/minizip/iowin32.h" \ No newline at end of file diff --git a/Source/Project64-core/N64System/Interpreter/InterpreterOps.cpp b/Source/Project64-core/N64System/Interpreter/InterpreterOps.cpp index 1e10a07c2..3255d6c51 100644 --- a/Source/Project64-core/N64System/Interpreter/InterpreterOps.cpp +++ b/Source/Project64-core/N64System/Interpreter/InterpreterOps.cpp @@ -23,7 +23,7 @@ const int32_t R4300iOp::SWR_SHIFT[4] = {24, 16, 8, 0}; const int32_t R4300iOp::LWL_SHIFT[4] = {0, 8, 16, 24}; const int32_t R4300iOp::LWR_SHIFT[4] = {24, 16, 8, 0}; -R4300iOp::R4300iOp(CN64System & System) : +R4300iOp::R4300iOp(CN64System & System, bool Force32bit) : m_System(System), m_Reg(System.m_Reg), m_TLB(System.m_TLB), @@ -43,7 +43,7 @@ R4300iOp::R4300iOp(CN64System & System) : m_LLBit(System.m_Reg.m_LLBit) { m_Opcode.Value = 0; - BuildInterpreter(); + BuildInterpreter(Force32bit); } R4300iOp::~R4300iOp() @@ -263,7 +263,7 @@ void R4300iOp::COP1_L() (this->*Jump_CoP1_L[m_Opcode.funct])(); } -void R4300iOp::BuildInterpreter() +void R4300iOp::BuildInterpreter(bool Force32bit) { Jump_Opcode[0] = &R4300iOp::SPECIAL; Jump_Opcode[1] = &R4300iOp::REGIMM; @@ -300,7 +300,7 @@ void R4300iOp::BuildInterpreter() Jump_Opcode[32] = &R4300iOp::LB; Jump_Opcode[33] = &R4300iOp::LH; Jump_Opcode[34] = &R4300iOp::LWL; - Jump_Opcode[35] = &R4300iOp::LW; + Jump_Opcode[35] = Force32bit ? &R4300iOp::LW_32 : &R4300iOp::LW; Jump_Opcode[36] = &R4300iOp::LBU; Jump_Opcode[37] = &R4300iOp::LHU; Jump_Opcode[38] = &R4300iOp::LWR; @@ -308,7 +308,7 @@ void R4300iOp::BuildInterpreter() Jump_Opcode[40] = &R4300iOp::SB; Jump_Opcode[41] = &R4300iOp::SH; Jump_Opcode[42] = &R4300iOp::SWL; - Jump_Opcode[43] = &R4300iOp::SW; + Jump_Opcode[43] = Force32bit ? &R4300iOp::SW_32 : &R4300iOp::SW; Jump_Opcode[44] = &R4300iOp::SDL; Jump_Opcode[45] = &R4300iOp::SDR; Jump_Opcode[46] = &R4300iOp::SWR; @@ -1182,6 +1182,17 @@ void R4300iOp::LW() } } +void R4300iOp::LW_32() +{ + uint64_t Address = m_GPR[m_Opcode.base].W[0] + (int16_t)m_Opcode.offset; + uint32_t MemoryValue; + + if (m_MMU.LW_Memory(Address, MemoryValue)) + { + m_GPR[m_Opcode.rt].DW = (int32_t)MemoryValue; + } +} + void R4300iOp::LBU() { uint64_t Address = m_GPR[m_Opcode.base].DW + (int16_t)m_Opcode.offset; @@ -1262,6 +1273,12 @@ void R4300iOp::SW() m_MMU.SW_Memory(Address, m_GPR[m_Opcode.rt].UW[0]); } +void R4300iOp::SW_32() +{ + uint64_t Address = m_GPR[m_Opcode.base].W[0] + (int16_t)m_Opcode.offset; + m_MMU.SW_Memory(Address, m_GPR[m_Opcode.rt].UW[0]); +} + uint64_t SDL_MASK[8] = {0, 0xFF00000000000000, 0xFFFF000000000000, 0xFFFFFF0000000000, diff --git a/Source/Project64-core/N64System/Interpreter/InterpreterOps.h b/Source/Project64-core/N64System/Interpreter/InterpreterOps.h index 4deaa0b3c..95bb96ca5 100644 --- a/Source/Project64-core/N64System/Interpreter/InterpreterOps.h +++ b/Source/Project64-core/N64System/Interpreter/InterpreterOps.h @@ -13,7 +13,7 @@ class R4300iOp : friend CX86RecompilerOps; public: - R4300iOp(CN64System & System); + R4300iOp(CN64System & System, bool Force32bit); ~R4300iOp(void); void ExecuteCPU(); @@ -30,7 +30,7 @@ private: R4300iOp(const R4300iOp &); R4300iOp & operator=(const R4300iOp &); - void BuildInterpreter(void); + void BuildInterpreter(bool Force32bit); typedef void (R4300iOp::*Func)(); @@ -74,6 +74,7 @@ private: void LH(); void LWL(); void LW(); + void LW_32(); void LBU(); void LHU(); void LWR(); @@ -82,6 +83,7 @@ private: void SH(); void SWL(); void SW(); + void SW_32(); void SDL(); void SDR(); void SWR(); diff --git a/Source/Project64-core/N64System/N64Rom.cpp b/Source/Project64-core/N64System/N64Rom.cpp index 1b2f42a94..92a3d2207 100644 --- a/Source/Project64-core/N64System/N64Rom.cpp +++ b/Source/Project64-core/N64System/N64Rom.cpp @@ -138,7 +138,7 @@ bool CN64Rom::AllocateAndLoadZipImage(const char * FileLoc, bool LoadBootCodeOnl { zlib_filefunc64_def ffunc; fill_win32_filefunc64W(&ffunc); - unzFile file = unzOpen2_64(stdstr(FileLoc).ToUTF16().c_str() , &ffunc); + unzFile file = unzOpen2_64(stdstr(FileLoc).ToUTF16().c_str(), &ffunc); if (file == nullptr) { return false; diff --git a/Source/Project64-core/N64System/N64System.cpp b/Source/Project64-core/N64System/N64System.cpp index a880ceee2..6fa78132e 100644 --- a/Source/Project64-core/N64System/N64System.cpp +++ b/Source/Project64-core/N64System/N64System.cpp @@ -32,7 +32,7 @@ CN64System::CN64System(CPlugins * Plugins, uint32_t randomizer_seed, bool SavesR //m_Cheats(m_MMU_VM), m_Reg(*this, m_SystemEvents), m_TLB(m_MMU_VM, m_Reg, m_Recomp), - m_OpCodes(*this), + m_OpCodes(*this, !SyncSystem && g_Settings->LoadDword(Game_CpuType) != CPU_Interpreter && b32BitCore()), m_Recomp(nullptr), m_InReset(false), m_NextTimer(0), diff --git a/Source/Project64/UserInterface/RomBrowser.cpp b/Source/Project64/UserInterface/RomBrowser.cpp index a8710484c..1dacc6ed1 100644 --- a/Source/Project64/UserInterface/RomBrowser.cpp +++ b/Source/Project64/UserInterface/RomBrowser.cpp @@ -1102,9 +1102,9 @@ void CRomBrowser::SelectRomDir(void) wchar_t Directory[_MAX_PATH]; if (SHGetPathFromIDList(pidl, Directory)) { - CPath RomDir(stdstr().FromUTF16(Directory), ""); - g_Settings->SaveString(RomList_GameDir, RomDir.GetDriveDirectory()); - Notify().AddRecentDir(RomDir.GetDriveDirectory().c_str()); + CPath NewRomDir(stdstr().FromUTF16(Directory), ""); + g_Settings->SaveString(RomList_GameDir, NewRomDir.GetDriveDirectory()); + Notify().AddRecentDir(NewRomDir.GetDriveDirectory().c_str()); RefreshRomList(); } }