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
This commit is contained in:
sudonim1@gmail.com 2012-09-05 20:13:50 +00:00
parent 31f685c490
commit ad3720c107
6 changed files with 43 additions and 21 deletions

View File

@ -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. :)

View File

@ -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);

View File

@ -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;

View File

@ -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;

View File

@ -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);

View File

@ -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;
}