From 184f0df2c57f718e67618208c6f966d64baae86a Mon Sep 17 00:00:00 2001 From: refractionpcsx2 Date: Tue, 12 May 2020 23:59:42 +0100 Subject: [PATCH] =?UTF-8?q?Modify=20VU=20PC=20addressing=20so=20it=20only?= =?UTF-8?q?=20multiplies=20by=208=20before=20entering=20the=20p=E2=80=A6?= =?UTF-8?q?=20(#3362)?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit * Modify VU addressing so it only multiplies by 8 before entering the program Fixes issues with VU1 TPC being read multiplied by 8 (bad) * Removed assert on SuperVU which no longer makes sense --- pcsx2/COP2.cpp | 4 ++-- pcsx2/VU0.cpp | 10 ++-------- pcsx2/VU0microInterp.cpp | 2 ++ pcsx2/VU1microInterp.cpp | 4 +++- pcsx2/Vif_Codes.cpp | 6 +++--- pcsx2/x86/microVU.cpp | 7 ++++--- pcsx2/x86/microVU_Macro.inl | 7 +++++-- pcsx2/x86/sVU_zerorec.cpp | 8 +++++--- 8 files changed, 26 insertions(+), 22 deletions(-) diff --git a/pcsx2/COP2.cpp b/pcsx2/COP2.cpp index 5ec8be4c5f..05bc16743b 100644 --- a/pcsx2/COP2.cpp +++ b/pcsx2/COP2.cpp @@ -28,13 +28,13 @@ using namespace R5900::Interpreter; //Run the FINISH either side of the VCALL's as we have no control over it past here. void VCALLMS() { vu0Finish(); - vu0ExecMicro(((cpuRegs.code >> 6) & 0x7FFF) * 8); + vu0ExecMicro(((cpuRegs.code >> 6) & 0x7FFF)); vif0Regs.stat.VEW = false; } void VCALLMSR() { vu0Finish(); - vu0ExecMicro(VU0.VI[REG_CMSAR0].US[0] * 8); + vu0ExecMicro(VU0.VI[REG_CMSAR0].US[0]); vif0Regs.stat.VEW = false; } diff --git a/pcsx2/VU0.cpp b/pcsx2/VU0.cpp index 1218ad84dd..e471e56e4d 100644 --- a/pcsx2/VU0.cpp +++ b/pcsx2/VU0.cpp @@ -123,13 +123,7 @@ void CFC2() { } if (_Rt_ == 0) return; - if (_Fs_ == REG_TPC) { - // For explanation why this is needed here please refer to - // recCFC2() definded in microVU_Macro.inl - cpuRegs.GPR.r[_Rt_].UL[0] = VU0.VI[_Fs_].UL >> 3; - } else { - cpuRegs.GPR.r[_Rt_].UL[0] = VU0.VI[_Fs_].UL; - } + cpuRegs.GPR.r[_Rt_].UL[0] = VU0.VI[_Fs_].UL; if(VU0.VI[_Fs_].UL & 0x80000000) cpuRegs.GPR.r[_Rt_].UL[1] = 0xffffffff; @@ -167,7 +161,7 @@ void CTC2() { break; case REG_CMSAR1: // REG_CMSAR1 if (!(VU0.VI[REG_VPU_STAT].UL & 0x100) ) { - vu1ExecMicro(cpuRegs.GPR.r[_Rt_].US[0] * 8); // Execute VU1 Micro SubRoutine + vu1ExecMicro(cpuRegs.GPR.r[_Rt_].US[0]); // Execute VU1 Micro SubRoutine vif1VUFinish(); } break; diff --git a/pcsx2/VU0microInterp.cpp b/pcsx2/VU0microInterp.cpp index 9755666b9c..e29171ba15 100644 --- a/pcsx2/VU0microInterp.cpp +++ b/pcsx2/VU0microInterp.cpp @@ -205,6 +205,7 @@ void InterpVU0::Step() void InterpVU0::Execute(u32 cycles) { + VU0.VI[REG_TPC].UL <<= 3; for (int i = (int)cycles; i > 0 ; i--) { if (!(VU0.VI[REG_VPU_STAT].UL & 0x1)) { if (VU0.branch || VU0.ebit) { @@ -214,5 +215,6 @@ void InterpVU0::Execute(u32 cycles) } vu0Exec(&VU0); } + VU0.VI[REG_TPC].UL >>= 3; } diff --git a/pcsx2/VU1microInterp.cpp b/pcsx2/VU1microInterp.cpp index eafd877331..0527796e13 100644 --- a/pcsx2/VU1microInterp.cpp +++ b/pcsx2/VU1microInterp.cpp @@ -210,7 +210,8 @@ void InterpVU1::Step() void InterpVU1::Execute(u32 cycles) { - for (int i = (int)cycles; i > 0 ; i--) { + VU1.VI[REG_TPC].UL <<= 3; + for (int i = (int)cycles; i > 0; i--) { if (!(VU0.VI[REG_VPU_STAT].UL & 0x100)) { if (VU1.branch || VU1.ebit) { Step(); // run branch delay slot? @@ -219,5 +220,6 @@ void InterpVU1::Execute(u32 cycles) } Step(); } + VU1.VI[REG_TPC].UL >>= 3; } diff --git a/pcsx2/Vif_Codes.cpp b/pcsx2/Vif_Codes.cpp index 5807fdc941..1937795e49 100644 --- a/pcsx2/Vif_Codes.cpp +++ b/pcsx2/Vif_Codes.cpp @@ -115,7 +115,7 @@ void ExecuteVU(int idx) } else if((vifX.cmd & 0x7f) == 0x14 || (vifX.cmd & 0x7f) == 0x15) { - vuExecMicro(idx, (u16)(vifXRegs.code) << 3); + vuExecMicro(idx, (u16)(vifXRegs.code)); vifX.cmd = 0; vifX.pass = 0; } @@ -343,7 +343,7 @@ vifOp(vifCode_MSCAL) { if(!vifX.waitforvu) { - vuExecMicro(idx, (u16)(vifXRegs.code) << 3); + vuExecMicro(idx, (u16)(vifXRegs.code)); vifX.cmd = 0; vifX.pass = 0; if(GetVifX.vifpacketsize > 1) @@ -374,7 +374,7 @@ vifOp(vifCode_MSCALF) { } if(!vifX.waitforvu) { - vuExecMicro(idx, (u16)(vifXRegs.code) << 3); + vuExecMicro(idx, (u16)(vifXRegs.code)); vifX.cmd = 0; vifX.pass = 0; vifExecQueue(idx); diff --git a/pcsx2/x86/microVU.cpp b/pcsx2/x86/microVU.cpp index 1bec37a9d8..f8aa45f02d 100644 --- a/pcsx2/x86/microVU.cpp +++ b/pcsx2/x86/microVU.cpp @@ -352,12 +352,12 @@ void recMicroVU0::Execute(u32 cycles) { pxAssert(m_Reserved); // please allocate me first! :| if(!(VU0.VI[REG_VPU_STAT].UL & 1)) return; - + VU0.VI[REG_TPC].UL <<= 3; // Sometimes games spin on vu0, so be careful with this value // woody hangs if too high on sVU (untested on mVU) // Edit: Need to test this again, if anyone ever has a "Woody" game :p ((mVUrecCall)microVU0.startFunct)(VU0.VI[REG_TPC].UL, cycles); - + VU0.VI[REG_TPC].UL >>= 3; if(microVU0.regs().flags & 0x4) { microVU0.regs().flags &= ~0x4; @@ -370,8 +370,9 @@ void recMicroVU1::Execute(u32 cycles) { if (!THREAD_VU1) { if(!(VU0.VI[REG_VPU_STAT].UL & 0x100)) return; } + VU1.VI[REG_TPC].UL <<= 3; ((mVUrecCall)microVU1.startFunct)(VU1.VI[REG_TPC].UL, cycles); - + VU1.VI[REG_TPC].UL >>= 3; if(microVU1.regs().flags & 0x4) { microVU1.regs().flags &= ~0x4; diff --git a/pcsx2/x86/microVU_Macro.inl b/pcsx2/x86/microVU_Macro.inl index 6b33e9750c..d7a328136c 100644 --- a/pcsx2/x86/microVU_Macro.inl +++ b/pcsx2/x86/microVU_Macro.inl @@ -306,7 +306,11 @@ static void recCFC2() { // is done by CFC2 while working with the TPC register. // (fixes R Racing Evolution and Street Fighter EX3) - xSHR(eax, 3); + //xSHR(eax, 3); + + //Update Refraction - Don't need to do this anymore as addresses are fed in divided by 8 always. + //Games such at The Incredible Hulk will read VU1's TPC from VU0 (which will already be multiplied by 8) then try to use CMSAR1 (which will also multiply by 8) + //So everything is now fed in without multiplication } // FixMe: Should R-Reg have upper 9 bits 0? @@ -347,7 +351,6 @@ static void recCTC2() { case REG_CMSAR1: // Execute VU1 Micro SubRoutine if (_Rt_) { xMOV(ecx, ptr32[&cpuRegs.GPR.r[_Rt_].UL[0]]); - xSHL(ecx, 3); } else xXOR(ecx, ecx); xFastCall((void*)vu1ExecMicro, ecx); diff --git a/pcsx2/x86/sVU_zerorec.cpp b/pcsx2/x86/sVU_zerorec.cpp index 07bf94fe1a..3ca7289529 100644 --- a/pcsx2/x86/sVU_zerorec.cpp +++ b/pcsx2/x86/sVU_zerorec.cpp @@ -4607,7 +4607,9 @@ void recSuperVU0::Execute(u32 cycles) if ((VU0.VI[REG_VPU_STAT].UL & 1) == 0) return; runCycles = cycles; + VU0.VI[REG_TPC].UL <<= 3; SuperVUExecuteProgram(VU0.VI[REG_TPC].UL & 0xfff, 0); + VU0.VI[REG_TPC].UL >>= 3; } void recSuperVU0::Clear(u32 Addr, u32 Size) @@ -4664,13 +4666,13 @@ void recSuperVU1::SetCacheReserve( uint reserveInMegs ) const void recSuperVU1::Execute(u32 cycles) { if ((VU0.VI[REG_VPU_STAT].UL & 0x100) == 0) return; - pxAssert( (VU1.VI[REG_TPC].UL&7) == 0 ); - // [TODO] Debugging pre- and post- hooks? + VU1.VI[REG_TPC].UL <<= 3; do { // while loop needed since not always will return finished SuperVUExecuteProgram(VU1.VI[REG_TPC].UL & VU1_PROGMASK, 1); - } while( VU0.VI[REG_VPU_STAT].UL&0x100 ); + } while (VU0.VI[REG_VPU_STAT].UL & 0x100); + VU1.VI[REG_TPC].UL >>= 3; } void recSuperVU1::Clear(u32 Addr, u32 Size)