mirror of https://github.com/PCSX2/pcsx2.git
VU: Improve sync during interlock and Scratchpad VU mem writes
Also added some setting of next block cycles to 0 in cases where we don't know ahead of compile time or the VU is ending.
This commit is contained in:
parent
420b675746
commit
ddb300027c
|
@ -437,14 +437,11 @@ __fi void _cpuEventTest_Shared()
|
|||
iopEventAction = false;
|
||||
}
|
||||
|
||||
// ---- VU0 -------------
|
||||
// ---- VU Sync -------------
|
||||
// We're in a EventTest. All dynarec registers are flushed
|
||||
// so there is no need to freeze registers here.
|
||||
CpuVU0->ExecuteBlock();
|
||||
CpuVU1->ExecuteBlock();
|
||||
// Note: We don't update the VU1 here because it runs it's micro-programs in
|
||||
// one shot always. That is, when a program is executed the VU1 doesn't even
|
||||
// bother to return until the program is completely finished.
|
||||
|
||||
// ---- Schedule Next Event Test --------------
|
||||
|
||||
|
|
|
@ -30,6 +30,11 @@ static void TestClearVUs(u32 madr, u32 qwc, bool isWrite)
|
|||
{
|
||||
if (madr >= 0x11000000 && (madr < 0x11010000))
|
||||
{
|
||||
// Sync the VU's if they're running, writing/reading from VU memory while they're running can be timing sensitive.
|
||||
// Use Psychonauts for testing
|
||||
CpuVU0->ExecuteBlock(0);
|
||||
CpuVU1->ExecuteBlock(0);
|
||||
|
||||
if (madr < 0x11004000)
|
||||
{
|
||||
if(isWrite)
|
||||
|
|
|
@ -78,6 +78,7 @@ __fi void _vu0run(bool breakOnMbit, bool addCycles) {
|
|||
{
|
||||
cpuRegs.cycle += (VU0.cycle - startcycle);
|
||||
VU0.cycle = cpuRegs.cycle;
|
||||
CpuVU1->ExecuteBlock(0); // Catch up VU1 as it's likely fallen behind
|
||||
}
|
||||
}
|
||||
|
||||
|
|
|
@ -44,10 +44,7 @@ void BaseVUmicroCPU::ExecuteBlock(bool startUp)
|
|||
s32 delta = (s32)(u32)(cpuRegs.cycle - cycle);
|
||||
s32 nextblockcycles = m_Idx ? VU1.nextBlockCycles : VU0.nextBlockCycles;
|
||||
|
||||
if (delta < nextblockcycles)
|
||||
return;
|
||||
|
||||
if (delta > 0) // Enough time has passed
|
||||
if (delta >= nextblockcycles) // Enough time has passed
|
||||
Execute(delta); // Execute the time since the last call
|
||||
}
|
||||
}
|
||||
|
|
|
@ -307,6 +307,7 @@ void normJumpCompile(mV, microFlagCycles& mFC, bool isEvilJump)
|
|||
//So if it is taken, you need to end the program, else you get infinite loops.
|
||||
mVUendProgram(mVU, &mFC, 2);
|
||||
xMOV(ptr32[&mVU.regs().VI[REG_TPC].UL], arg1regd);
|
||||
xMOV(ptr32[&mVU.regs().nextBlockCycles], 0);
|
||||
xJMP(mVU.exitFunct);
|
||||
}
|
||||
|
||||
|
@ -367,6 +368,7 @@ void normBranch(mV, microFlagCycles& mFC)
|
|||
mVUendProgram(mVU, &mFC, 3);
|
||||
iPC = branchAddr(mVU) / 4;
|
||||
xMOV(ptr32[&mVU.regs().VI[REG_TPC].UL], xPC);
|
||||
xMOV(ptr32[&mVU.regs().nextBlockCycles], 0);
|
||||
xJMP(mVU.exitFunct);
|
||||
iPC = tempPC;
|
||||
}
|
||||
|
@ -464,6 +466,7 @@ void condBranch(mV, microFlagCycles& mFC, int JMPcc)
|
|||
incPC(-4); // Go Back to Branch Opcode to get branchAddr
|
||||
iPC = branchAddr(mVU) / 4;
|
||||
xMOV(ptr32[&mVU.regs().VI[REG_TPC].UL], xPC);
|
||||
xMOV(ptr32[&mVU.regs().nextBlockCycles], 0);
|
||||
xJMP(mVU.exitFunct);
|
||||
eJMP.SetTarget();
|
||||
iPC = tempPC;
|
||||
|
@ -483,11 +486,13 @@ void condBranch(mV, microFlagCycles& mFC, int JMPcc)
|
|||
xForwardJump32 dJMP(xInvertCond((JccComparisonType)JMPcc));
|
||||
incPC(4); // Set PC to First instruction of Non-Taken Side
|
||||
xMOV(ptr32[&mVU.regs().VI[REG_TPC].UL], xPC);
|
||||
xMOV(ptr32[&mVU.regs().nextBlockCycles], 0);
|
||||
xJMP(mVU.exitFunct);
|
||||
dJMP.SetTarget();
|
||||
incPC(-4); // Go Back to Branch Opcode to get branchAddr
|
||||
iPC = branchAddr(mVU) / 4;
|
||||
xMOV(ptr32[&mVU.regs().VI[REG_TPC].UL], xPC);
|
||||
xMOV(ptr32[&mVU.regs().nextBlockCycles], 0);
|
||||
xJMP(mVU.exitFunct);
|
||||
eJMP.SetTarget();
|
||||
iPC = tempPC;
|
||||
|
@ -511,6 +516,7 @@ void condBranch(mV, microFlagCycles& mFC, int JMPcc)
|
|||
incPC(-4); // Go Back to Branch Opcode to get branchAddr
|
||||
iPC = branchAddr(mVU) / 4;
|
||||
xMOV(ptr32[&mVU.regs().VI[REG_TPC].UL], xPC);
|
||||
xMOV(ptr32[&mVU.regs().nextBlockCycles], 0);
|
||||
xJMP(mVU.exitFunct);
|
||||
iPC = tempPC;
|
||||
}
|
||||
|
@ -526,12 +532,14 @@ void condBranch(mV, microFlagCycles& mFC, int JMPcc)
|
|||
xForwardJump32 eJMP(((JccComparisonType)JMPcc));
|
||||
incPC(1); // Set PC to First instruction of Non-Taken Side
|
||||
xMOV(ptr32[&mVU.regs().VI[REG_TPC].UL], xPC);
|
||||
xMOV(ptr32[&mVU.regs().nextBlockCycles], 0);
|
||||
xJMP(mVU.exitFunct);
|
||||
eJMP.SetTarget();
|
||||
incPC(-4); // Go Back to Branch Opcode to get branchAddr
|
||||
|
||||
iPC = branchAddr(mVU) / 4;
|
||||
xMOV(ptr32[&mVU.regs().VI[REG_TPC].UL], xPC);
|
||||
xMOV(ptr32[&mVU.regs().nextBlockCycles], 0);
|
||||
xJMP(mVU.exitFunct);
|
||||
return;
|
||||
}
|
||||
|
@ -624,6 +632,7 @@ void normJump(mV, microFlagCycles& mFC)
|
|||
mVUDTendProgram(mVU, &mFC, 2);
|
||||
xMOV(gprT1, ptr32[&mVU.branch]);
|
||||
xMOV(ptr32[&mVU.regs().VI[REG_TPC].UL], gprT1);
|
||||
xMOV(ptr32[&mVU.regs().nextBlockCycles], 0);
|
||||
xJMP(mVU.exitFunct);
|
||||
eJMP.SetTarget();
|
||||
}
|
||||
|
@ -639,6 +648,7 @@ void normJump(mV, microFlagCycles& mFC)
|
|||
mVUDTendProgram(mVU, &mFC, 2);
|
||||
xMOV(gprT1, ptr32[&mVU.branch]);
|
||||
xMOV(ptr32[&mVU.regs().VI[REG_TPC].UL], gprT1);
|
||||
xMOV(ptr32[&mVU.regs().nextBlockCycles], 0);
|
||||
xJMP(mVU.exitFunct);
|
||||
eJMP.SetTarget();
|
||||
}
|
||||
|
@ -647,6 +657,7 @@ void normJump(mV, microFlagCycles& mFC)
|
|||
mVUendProgram(mVU, &mFC, 2);
|
||||
xMOV(gprT1, ptr32[&mVU.branch]);
|
||||
xMOV(ptr32[&mVU.regs().VI[REG_TPC].UL], gprT1);
|
||||
xMOV(ptr32[&mVU.regs().nextBlockCycles], 0);
|
||||
xJMP(mVU.exitFunct);
|
||||
}
|
||||
else
|
||||
|
|
Loading…
Reference in New Issue