From ad3720c107f4f0aeae7f4e9151b0ddcbb535b9d5 Mon Sep 17 00:00:00 2001 From: "sudonim1@gmail.com" <sudonim1@gmail.com@96395faa-99c1-11dd-bbfe-3dabce05a288> Date: Wed, 5 Sep 2012 20:13:50 +0000 Subject: [PATCH] VIF: EXPERIMENTAL, NOT SANITY CHECKED: Delayed VU execution until the next flush, mpg, microprogram call or (as a fallback) end of dma packet to deal with cases like MSCAL, UNPACK, MSCAL (expects the first program to receive the unpack data). Fixes Snowblind's games (BG Dark Alliance etc.), Mortal Kombat Shaolin Monks. May break things, needs extensive testing. git-svn-id: http://pcsx2.googlecode.com/svn/trunk@5404 96395faa-99c1-11dd-bbfe-3dabce05a288 --- pcsx2/SaveState.h | 2 +- pcsx2/VU0micro.cpp | 1 - pcsx2/VU1micro.cpp | 2 -- pcsx2/Vif_Codes.cpp | 52 ++++++++++++++++++++++++++++-------------- pcsx2/Vif_Dma.h | 5 ++++ pcsx2/Vif_Transfer.cpp | 2 ++ 6 files changed, 43 insertions(+), 21 deletions(-) diff --git a/pcsx2/SaveState.h b/pcsx2/SaveState.h index d8d1545d21..45684b16e1 100644 --- a/pcsx2/SaveState.h +++ b/pcsx2/SaveState.h @@ -24,7 +24,7 @@ // the lower 16 bit value. IF the change is breaking of all compatibility with old // states, increment the upper 16 bit value, and clear the lower 16 bits to 0. -static const u32 g_SaveVersion = (0x9A09 << 16) | 0x0000; +static const u32 g_SaveVersion = (0x9A0A << 16) | 0x0000; // this function is meant to be used in the place of GSfreeze, and provides a safe layer // between the GS saving function and the MTGS's needs. :) diff --git a/pcsx2/VU0micro.cpp b/pcsx2/VU0micro.cpp index d8cd35cd91..d9e5d853f6 100644 --- a/pcsx2/VU0micro.cpp +++ b/pcsx2/VU0micro.cpp @@ -46,7 +46,6 @@ void __fastcall vu0ExecMicro(u32 addr) { VU0.VI[REG_VPU_STAT].UL &= ~0xFF; VU0.VI[REG_VPU_STAT].UL |= 0x01; - vif0Regs.stat.VEW = true; if ((s32)addr != -1) VU0.VI[REG_TPC].UL = addr; _vuExecMicroDebug(VU0); diff --git a/pcsx2/VU1micro.cpp b/pcsx2/VU1micro.cpp index 740daf6aec..94dce0af1f 100644 --- a/pcsx2/VU1micro.cpp +++ b/pcsx2/VU1micro.cpp @@ -50,8 +50,6 @@ void vu1Finish() { void __fastcall vu1ExecMicro(u32 addr) { - vif1Regs.stat.VEW = true; - if (THREAD_VU1) { vu1Thread.ExecuteVU(addr, vif1Regs.top, vif1Regs.itop); VU0.VI[REG_VPU_STAT].UL &= ~0xFF00; diff --git a/pcsx2/Vif_Codes.cpp b/pcsx2/Vif_Codes.cpp index fa34815b88..e124e50cbc 100644 --- a/pcsx2/Vif_Codes.cpp +++ b/pcsx2/Vif_Codes.cpp @@ -34,17 +34,45 @@ vifOp(vifCode_Null); // Vif0/Vif1 Misc Functions //------------------------------------------------------------------ +__ri void vifExecQueue(int idx) +{ + if (!GetVifX.queued_program) + return; + + GetVifX.queued_program = false; + + int startcycles = 0; + + if (!idx) startcycles = VU0.cycle; + else startcycles = VU1.cycle; + + if (!idx) vu0ExecMicro(GetVifX.queued_pc); + else vu1ExecMicro(GetVifX.queued_pc); + + ///NOTE: Shadowman 2 has SPS with this, uncommenting the correct code fixes it + if (!idx) { startcycles = ((VU0.cycle-startcycles) + ( vif0ch.qwc - (vif0.vifpacketsize >> 2) )); CPU_INT(VIF_VU0_FINISH, 1/*startcycles * BIAS*/); } + else { startcycles = ((VU1.cycle-startcycles) + ( vif1ch.qwc - (vif1.vifpacketsize >> 2) )); CPU_INT(VIF_VU1_FINISH, 1/*startcycles * BIAS*/); } + + //DevCon.Warning("Ran VU%x, VU0 Cycles %x, VU1 Cycles %x, start %x cycle %x", idx, g_vu0Cycles, g_vu1Cycles, startcycles, VU1.cycle); + //GetVifX.vifstalled.enabled = true; + //GetVifX.vifstalled.value = VIF_TIMING_BREAK; +} + static __fi void vifFlush(int idx) { if (!idx) vif0FLUSH(); else vif1FLUSH(); + + vifExecQueue(idx); } static __fi void vuExecMicro(int idx, u32 addr) { VIFregisters& vifRegs = vifXRegs; - int startcycles = 0; - //vifFlush(idx); - //if(vifX.vifstalled.enabled == true) return; + vifFlush(idx); + if(GetVifX.waitforvu) + return; + + vifRegs.stat.VEW = true; if (vifRegs.itops > (idx ? 0x3ffu : 0xffu)) { Console.WriteLn("VIF%d ITOP overrun! %x", idx, vifRegs.itops); @@ -70,20 +98,8 @@ static __fi void vuExecMicro(int idx, u32 addr) { } } - if (!idx) startcycles = VU0.cycle; - else startcycles = VU1.cycle; - - if (!idx) vu0ExecMicro(addr); - else vu1ExecMicro(addr); - - ///NOTE: Shadowman 2 has SPS with this, uncommenting the correct code fixes it - if (!idx) { startcycles = ((VU0.cycle-startcycles) + ( vif0ch.qwc - (vif0.vifpacketsize >> 2) )); CPU_INT(VIF_VU0_FINISH, 1/*startcycles * BIAS*/); } - else { startcycles = ((VU1.cycle-startcycles) + ( vif1ch.qwc - (vif1.vifpacketsize >> 2) )); CPU_INT(VIF_VU1_FINISH, 1/*startcycles * BIAS*/); } - - - //DevCon.Warning("Ran VU%x, VU0 Cycles %x, VU1 Cycles %x, start %x cycle %x", idx, g_vu0Cycles, g_vu1Cycles, startcycles, VU1.cycle); - GetVifX.vifstalled.enabled = true; - GetVifX.vifstalled.value = VIF_TIMING_BREAK; + GetVifX.queued_program = true; + GetVifX.queued_pc = addr; } void ExecuteVU(int idx) @@ -252,6 +268,8 @@ static __fi void _vifCode_MPG(int idx, u32 addr, const u32 *data, int size) { vifStruct& vifX = GetVifX; pxAssert(VUx.Micro > 0); + vifExecQueue(idx); + if (idx && THREAD_VU1) { vu1Thread.WriteMicroMem(addr, (u8*)data, size*4); return; diff --git a/pcsx2/Vif_Dma.h b/pcsx2/Vif_Dma.h index 18b314c896..14d20a1d1d 100644 --- a/pcsx2/Vif_Dma.h +++ b/pcsx2/Vif_Dma.h @@ -90,6 +90,9 @@ struct vifStruct { u32 vifpacketsize; u8 inprogress; u8 dmamode; + + bool queued_program; + u32 queued_pc; }; extern __aligned16 vifStruct vif0, vif1; @@ -131,3 +134,5 @@ extern u32 g_vif1Cycles; extern void vif0FLUSH(); extern void vif1FLUSH(); + +extern void vifExecQueue(int idx); \ No newline at end of file diff --git a/pcsx2/Vif_Transfer.cpp b/pcsx2/Vif_Transfer.cpp index a5ed03ce47..096845509b 100644 --- a/pcsx2/Vif_Transfer.cpp +++ b/pcsx2/Vif_Transfer.cpp @@ -113,6 +113,8 @@ _vifT static __fi bool vifTransfer(u32 *data, int size, bool TTE) { vifX.irqoffset.enabled = false; } + vifExecQueue(idx); + return !vifX.vifstalled.enabled; }