diff --git a/pcsx2/VU0.cpp b/pcsx2/VU0.cpp index 4ca436cacc..e16b426b71 100644 --- a/pcsx2/VU0.cpp +++ b/pcsx2/VU0.cpp @@ -60,7 +60,7 @@ void COP2_Unknown() //**************************************************************************** -__forceinline void _vu0run(bool breakOnMbit) { +__forceinline void _vu0run(bool breakOnMbit, bool addCycles) { if (!(VU0.VI[REG_VPU_STAT].UL & 1)) return; @@ -70,19 +70,20 @@ __forceinline void _vu0run(bool breakOnMbit) { do { // knockout kings 2002 loops here with sVU if (breakOnMbit && (VU0.cycle-startcycle > 0x1000)) { - Console.Warning("VU0 perma-stall, breaking execution..."); - break; // mVU will never get here (it handles mBit internally) + Console.Warning("VU0 stuck in infinite loop? Breaking execution!"); + break; // Do games still need this? } CpuVU0->ExecuteBlock(); } while ((VU0.VI[REG_VPU_STAT].UL & 1) // E-bit Termination && (!breakOnMbit || !(VU0.flags & VUFLAG_MFLAGSET))); // M-bit Break - //NEW - cpuRegs.cycle += (VU0.cycle-startcycle)*2; + // Add cycles if called from EE's COP2 + if (addCycles) cpuRegs.cycle += (VU0.cycle-startcycle)*2; } -void _vu0WaitMicro() { _vu0run(1); } // Runs VU0 Micro Until E-bit or M-Bit End -void _vu0FinishMicro() { _vu0run(0); } // Runs VU0 Micro Until E-Bit End +void _vu0WaitMicro() { _vu0run(1, 1); } // Runs VU0 Micro Until E-bit or M-Bit End +void _vu0FinishMicro() { _vu0run(0, 1); } // Runs VU0 Micro Until E-Bit End +void vu0Finish() { _vu0run(0, 0); } // Runs VU0 Micro Until E-Bit End (doesn't stall EE) namespace R5900 { namespace Interpreter{ @@ -333,31 +334,3 @@ void VFCSET() { VU0.code = cpuRegs.code; _vuFCSET(&VU0); } void VFCGET() { VU0.code = cpuRegs.code; _vuFCGET(&VU0); } void VXITOP() { VU0.code = cpuRegs.code; _vuXITOP(&VU0); } -// fixme: Shouldn't anything calling this function be calling vu0WaitMicro instead? -// Meaning that this function stalls, but doesn't increment the cpuRegs.cycle like -// you would think it should. - -// Well, we can always test that out... -//#define USE_WAIT_MICRO - -void vu0Finish() -{ -#ifdef USE_WAIT_MICRO - _vu0WaitMicro(); -#else - if( (VU0.VI[REG_VPU_STAT].UL & 0x1) ) { - int i = 0; - - while(i++ < 32) { - CpuVU0->ExecuteBlock(); - if(!(VU0.VI[REG_VPU_STAT].UL & 0x1)) - break; - } - if(VU0.VI[REG_VPU_STAT].UL & 0x1) { - VU0.VI[REG_VPU_STAT].UL &= ~1; - // this log tends to spam a lot (MGS3) - //Console.Warning("vu0Finish > stall aborted by force."); - } - } -#endif -} diff --git a/pcsx2/VU0micro.cpp b/pcsx2/VU0micro.cpp index 189e9d18bb..b5509e9b98 100644 --- a/pcsx2/VU0micro.cpp +++ b/pcsx2/VU0micro.cpp @@ -50,11 +50,11 @@ void __fastcall vu0ExecMicro(u32 addr) { DevCon.Warning("vu0ExecMicro > Stalling for previous microprogram to finish"); vu0Finish(); } - VU0.VI[REG_VPU_STAT].UL|= 0x1; - VU0.VI[REG_VPU_STAT].UL&= ~0xAE; - // If an unsigned variable isn't -1? --arcum42 - if (addr != (u32)-1) VU0.VI[REG_TPC].UL = addr; + VU0.VI[REG_VPU_STAT].UL &= ~0xFF; + VU0.VI[REG_VPU_STAT].UL |= 0x01; + + if ((s32)addr != -1) VU0.VI[REG_TPC].UL = addr; _vuExecMicroDebug(VU0); CpuVU0->ExecuteBlock(); diff --git a/pcsx2/VU1micro.cpp b/pcsx2/VU1micro.cpp index 3060fb30c9..3f83013977 100644 --- a/pcsx2/VU1micro.cpp +++ b/pcsx2/VU1micro.cpp @@ -44,8 +44,7 @@ static int count; void __fastcall vu1ExecMicro(u32 addr) { - while(VU0.VI[REG_VPU_STAT].UL & 0x100) - { + while(VU0.VI[REG_VPU_STAT].UL & 0x100) { VUM_LOG("vu1ExecMicro > Stalling until current microprogram finishes"); CpuVU1->ExecuteBlock(); } @@ -53,10 +52,11 @@ void __fastcall vu1ExecMicro(u32 addr) VUM_LOG("vu1ExecMicro %x", addr); VUM_LOG("vu1ExecMicro %x (count=%d)", addr, count++); - VU0.VI[REG_VPU_STAT].UL|= 0x100; - VU0.VI[REG_VPU_STAT].UL&= ~0x7E000; + VU0.VI[REG_VPU_STAT].UL &= ~0xFF00; + VU0.VI[REG_VPU_STAT].UL |= 0x0100; + vif1Regs->stat.VEW = true; - if (addr != -1) VU1.VI[REG_TPC].UL = addr; + if ((s32)addr != -1) VU1.VI[REG_TPC].UL = addr; _vuExecMicroDebug(VU1); CpuVU1->ExecuteBlock(); diff --git a/pcsx2/Vif0_Dma.cpp b/pcsx2/Vif0_Dma.cpp index 704a9a7ce7..3076d22554 100644 --- a/pcsx2/Vif0_Dma.cpp +++ b/pcsx2/Vif0_Dma.cpp @@ -26,10 +26,8 @@ vifStruct vif0; __forceinline void vif0FLUSH() { int _cycles = VU0.cycle; - - // fixme: this code should call _vu0WaitMicro instead? I'm not sure if - // it's purposefully ignoring ee cycles or not (see below for more) - + // Run VU0 until finish, don't add cycles to EE + // because its vif stalling not the EE core... vu0Finish(); g_vifCycles += (VU0.cycle - _cycles) * BIAS; } diff --git a/pcsx2/Vif1_Dma.cpp b/pcsx2/Vif1_Dma.cpp index ec5895b077..ff4d338394 100644 --- a/pcsx2/Vif1_Dma.cpp +++ b/pcsx2/Vif1_Dma.cpp @@ -31,14 +31,9 @@ __forceinline void vif1FLUSH() { int _cycles = VU1.cycle; - // fixme: Same as above, is this a "stalling" offense? I think the cycles should - // be added to cpuRegs.cycle instead of g_vifCycles, but not sure (air) - - if (VU0.VI[REG_VPU_STAT].UL & 0x100) - { - do - { - CpuVU1->ExecuteBlock(); + if (VU0.VI[REG_VPU_STAT].UL & 0x100) { + do { + CpuVU1->ExecuteBlock(); } while (VU0.VI[REG_VPU_STAT].UL & 0x100); diff --git a/pcsx2/Vif_Commands.cpp b/pcsx2/Vif_Commands.cpp index 8d8bac26de..853cd5261f 100644 --- a/pcsx2/Vif_Commands.cpp +++ b/pcsx2/Vif_Commands.cpp @@ -29,10 +29,14 @@ _vifT void vifCMD_Null(); +_f void vifFlush(int idx) { + if (!idx) vif0FLUSH(); + else vif1FLUSH(); +} + _f void vuExecMicro(int idx, u32 addr) { VURegs* VU = nVif[idx].VU; - if (!idx) vif0FLUSH(); - else vif1FLUSH(); + vifFlush(idx); if (VU->vifRegs->itops > (idx ? 0x3ffu : 0xffu)) { Console.WriteLn("VIF%d ITOP overrun! %x", idx, VU->vifRegs->itops); @@ -62,11 +66,6 @@ _f void vuExecMicro(int idx, u32 addr) { else vu1ExecMicro(addr); } -_f void vifFlush(int idx) { - if (!idx) vif0FLUSH(); - else vif1FLUSH(); -} - u8 schedulepath3msk = 0; void Vif1MskPath3() { @@ -354,7 +353,7 @@ _vifT void vifCMD_Mark() _vifT void vifCMD_MPG() { - if (!idx) vifFlush(idx); // Only Vif0 Flush!? + vifFlush(idx); int vifNum = (u8)(vifXRegs->code >> 16); if(!vifNum) vifNum = 256; @@ -364,7 +363,6 @@ _vifT void vifCMD_MPG() _vifT void vifCMD_MSCALF() { - if (idx) vif1FLUSH(); // Only Vif1 Flush!? vuExecMicro(idx, (u16)(vifXRegs->code) << 3); vifX.cmd &= ~0x7f; } @@ -410,9 +408,9 @@ _vifT void vifCMD_Null() // invalid opcode _vifT void vifCMD_Offset() { vif1Only(); - vif1Regs->ofst = vif1Regs->code & 0x3ff; - vif1Regs->stat.DBF = false; - vif1Regs->tops = vif1Regs->base; + vif1Regs->stat.DBF = false; + vif1Regs->ofst = vif1Regs->code & 0x3ff; + vif1Regs->tops = vif1Regs->base; vif1.cmd &= ~0x7f; }