Skip to content

Commit

Permalink
Modify VU PC addressing so it only multiplies by 8 before entering th…
Browse files Browse the repository at this point in the history
…e p… (#3362)

* 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
  • Loading branch information
refractionpcsx2 committed May 12, 2020
1 parent 593d948 commit 184f0df
Show file tree
Hide file tree
Showing 8 changed files with 26 additions and 22 deletions.
4 changes: 2 additions & 2 deletions pcsx2/COP2.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -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;
}

Expand Down
10 changes: 2 additions & 8 deletions pcsx2/VU0.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -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;
Expand Down Expand Up @@ -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;
Expand Down
2 changes: 2 additions & 0 deletions pcsx2/VU0microInterp.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -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) {
Expand All @@ -214,5 +215,6 @@ void InterpVU0::Execute(u32 cycles)
}
vu0Exec(&VU0);
}
VU0.VI[REG_TPC].UL >>= 3;
}

4 changes: 3 additions & 1 deletion pcsx2/VU1microInterp.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -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?
Expand All @@ -219,5 +220,6 @@ void InterpVU1::Execute(u32 cycles)
}
Step();
}
VU1.VI[REG_TPC].UL >>= 3;
}

6 changes: 3 additions & 3 deletions pcsx2/Vif_Codes.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -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;
}
Expand Down Expand Up @@ -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)
Expand Down Expand Up @@ -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);
Expand Down
7 changes: 4 additions & 3 deletions pcsx2/x86/microVU.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -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;
Expand All @@ -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;
Expand Down
7 changes: 5 additions & 2 deletions pcsx2/x86/microVU_Macro.inl
Original file line number Diff line number Diff line change
Expand Up @@ -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?
Expand Down Expand Up @@ -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);
Expand Down
8 changes: 5 additions & 3 deletions pcsx2/x86/sVU_zerorec.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -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)
Expand Down Expand Up @@ -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)
Expand Down

0 comments on commit 184f0df

Please sign in to comment.