VU Int: Make XGKick flush on VU program end

Some games like to write directly to VU memory once the program has finished and I have no easy way to update the kick without being super slow. so for now, we'll just flush it.
This commit is contained in:
refractionpcsx2 2021-09-11 00:00:53 +01:00
parent 3f56414824
commit 73bb8e4fdf
5 changed files with 21 additions and 14 deletions

View File

@ -207,8 +207,12 @@ static void _vu1Exec(VURegs* VU)
_vuFlushAll(VU);
VU0.VI[REG_VPU_STAT].UL &= ~0x100;
vif1Regs.stat.VEW = false;
if(VU1.xgkickenable)
_vuXGKICKTransfer(VU, 0, true);
// In instant VU mode, VU1 goes WAY ahead of the CPU, making the XGKick fall way behind
// We also have some code to update it in VIF Unpacks too, since in some games (Aggressive Inline) overwrite the XGKick data
// VU currently flushes XGKICK on end, so this isn't needed, yet
if (INSTANT_VU1)
VU1.xgkicklastcycle = cpuRegs.cycle;
}

View File

@ -33,14 +33,15 @@ void BaseVUmicroCPU::ExecuteBlock(bool startUp)
return;
}
if (!(stat & test))
// VU currently flushes XGKICK on VU1 end so no need for this, yet
/*if (!(stat & test))
{
if (m_Idx == 1 && VU1.xgkickenable)
{
_vuXGKICKTransfer(&VU1, (cpuRegs.cycle - VU1.xgkicklastcycle), false);
}
return;
}
}*/
// You might be looking at this and thinking, what the hell is going on? What's with all these conditions?
// Well, basically M-Bit timed games are REALLY picky, so we need some extra checks in to make sure the VU

View File

@ -2334,7 +2334,7 @@ void _vuXGKICKTransfer(VURegs* VU, u32 cycles, bool flush)
VU->xgkicklastcycle += cycles;
VUM_LOG("Adding %d cycles, total XGKick cycles to run now %d", cycles, VU->xgkickcyclecount);
while ((!VU->xgkickendpacket || VU->xgkicksizeremaining > 0) && (flush || VU->xgkickcyclecount >= 2))
while (VU->xgkickenable && (flush || VU->xgkickcyclecount >= 2))
{
u32 transfersize = 0;
@ -2393,15 +2393,15 @@ void _vuXGKICKTransfer(VURegs* VU, u32 cycles, bool flush)
// Check if VIF is waiting for the GIF to not be busy
if (vif1Regs.stat.VGW)
{
VU0.VI[REG_VPU_STAT].UL &= ~(1 << 12);
vif1Regs.stat.VGW = false;
CPU_INT(DMAC_VIF1, 8);
}
}
}
if (flush)
if ((VU0.VI[REG_VPU_STAT].UL & 0x100) && flush)
{
VUM_LOG("Disabling XGKICK");
VU->xgkickenable = false;
_vuTestPipes(VU);
}
}
@ -2423,6 +2423,7 @@ static __ri void _vuXGKICK(VURegs * VU)
VU->xgkickendpacket = false;
VU->xgkicklastcycle = VU->cycle;
VU->xgkickcyclecount = 0;
VU0.VI[REG_VPU_STAT].UL |= (1 << 12);
VUM_LOG("XGKICK addr %x", addr);
}

View File

@ -205,6 +205,16 @@ _vifT void vifUnpackSetup(const u32 *data) {
if (vifNum == 0) vifNum = 256;
vifXRegs.num = vifNum;
// This is for use when XGKick is synced as VIF can overwrite XG Kick data as it's transferring out
// Test with Aggressive Inline Skating, or K-1 Premium 2005 Dynamite!
// VU currently flushes XGKICK on VU1 end so no need for this, yet
/*if (idx == 1 && VU1.xgkickenable && !(VU0.VI[REG_TPC].UL & 0x100))
{
// Catch up first, then the unpack cycles
_vuXGKICKTransfer(&VU1, cpuRegs.cycle - VU1.xgkicklastcycle, false);
_vuXGKICKTransfer(&VU1, vifNum * 2, false);
}*/
// Traditional-style way of calculating the gsize, based on VN/VL parameters.
// Useful when VN/VL are known template params, but currently they are not so we use
// the LUT instead (for now).

View File

@ -113,15 +113,6 @@ _vifT int nVifUnpack(const u8* data)
const bool isFill = (vifRegs.cycle.cl < wl);
s32 size = ret << 2;
// This is for use when XGKick is synced as VIF can overwrite XG Kick data as it's transferring out
// Test with Aggressive Inline Skating, or K-1 Premium 2005 Dynamite!
if (idx == 1 && VU1.xgkickenable && !(VU0.VI[REG_TPC].UL & 0x100))
{
// Catch up first, then the unpack cycles
_vuXGKICKTransfer(&VU1, cpuRegs.cycle - VU1.xgkicklastcycle, false);
_vuXGKICKTransfer(&VU1, ret/2, false);
}
if (ret == vif.tag.size) // Full Transfer
{
if (v.bSize) // Last transfer was partial