VIF/MFIFO: Respect MFIFO empty condition on SPR transfers

This commit is contained in:
refractionpcsx2
2026-03-20 11:11:45 -04:00
committed by Ty
parent 0e667a9b0f
commit 8aca0fe288
3 changed files with 9 additions and 24 deletions
+1 -1
View File
@@ -561,7 +561,7 @@ extern void hwDmacIrq(int n);
extern void FireMFIFOEmpty();
extern bool hwMFIFOWrite(u32 addr, const u128* data, uint size_qwc);
extern void hwMFIFOResume(u32 transferred);
extern void hwMFIFOResume();
extern void hwDmacSrcTadrInc(DMACh& dma);
extern bool hwDmacSrcChainWithStack(DMACh& dma, int id);
extern bool hwDmacSrcChain(DMACh& dma, int id);
+5 -10
View File
@@ -151,18 +151,13 @@ __ri bool hwMFIFOWrite(u32 addr, const u128* data, uint qwc)
return true;
}
__ri void hwMFIFOResume(u32 transferred) {
if (transferred == 0)
{
return; //Nothing got put in the MFIFO, we don't care
}
__ri void hwMFIFOResume() {
switch (dmacRegs.ctrl.MFD)
{
case MFD_VIF1: // Most common case.
{
SPR_LOG("Added %x qw to mfifo, Vif CHCR %x Stalled %x done %x", transferred, vif1ch.chcr._u32, vif1.vifstalled.enabled, vif1.done);
SPR_LOG("Resuming VIF1 MFIFO, Vif CHCR %x Stalled %x done %x", vif1ch.chcr._u32, vif1.vifstalled.enabled, vif1.done);
if (vif1.inprogress & 0x10)
{
vif1.inprogress &= ~0x10;
@@ -171,7 +166,7 @@ __ri void hwMFIFOResume(u32 transferred) {
{
SPR_LOG("Data Added, Resuming");
//Need to simulate the time it takes to copy here, if the VIF resumes before the SPR has finished, it isn't happy.
CPU_INT(DMAC_MFIFO_VIF, transferred * BIAS);
CPU_INT(DMAC_MFIFO_VIF, cpuRegs.eCycle[DMAC_FROM_SPR]);
}
//Apparently this is bad, i guess so, the data is going to memory rather than the FIFO
@@ -181,9 +176,9 @@ __ri void hwMFIFOResume(u32 transferred) {
}
case MFD_GIF:
{
SPR_LOG("Added %x qw to mfifo, Gif CHCR %x done %x", transferred, gifch.chcr._u32, gif.gspath3done);
SPR_LOG("Resuming GIF MFIFO, Gif CHCR %x done %x", gifch.chcr._u32, gif.gspath3done);
if ((gif.gifstate & GIF_STATE_EMPTY)) {
CPU_INT(DMAC_MFIFO_GIF, transferred * BIAS);
CPU_INT(DMAC_MFIFO_GIF, cpuRegs.eCycle[DMAC_FROM_SPR]);
gif.gifstate = GIF_STATE_READY;
}
break;
+3 -13
View File
@@ -9,7 +9,7 @@
static bool spr0finished = false;
static bool spr1finished = false;
static u32 mfifotransferred = 0;
static u32 mfifotransferred = 0; // FIXME: Remove next time someone bumps savestates, no longer required.
static void TestClearVUs(u32 madr, u32 qwc, bool isWrite)
{
@@ -122,8 +122,6 @@ int _SPR0chain()
if ((spr0ch.madr & ~dmacRegs.rbsr.RMSK) != dmacRegs.rbor.ADDR)
Console.WriteLn("SPR MFIFO Write outside MFIFO area");
else
mfifotransferred += partialqwc;
hwMFIFOWrite(spr0ch.madr, &psSu128(spr0ch.sadr), partialqwc);
spr0ch.madr += partialqwc << 4;
@@ -198,7 +196,6 @@ void _SPR0interleave()
case MFD_VIF1:
case MFD_GIF:
hwMFIFOWrite(spr0ch.madr, &psSu128(spr0ch.sadr), spr0ch.qwc);
mfifotransferred += spr0ch.qwc;
break;
case NO_MFD:
@@ -307,24 +304,17 @@ void SPRFROMinterrupt()
// The qwc check is simply because having data still to transfer from the packet can freak games out if they do a d.tadr == s.madr check
// and there is still data to come over (FF12 ingame menu)
if(mfifotransferred != 0 && spr0ch.qwc == 0)
if(spr0ch.qwc == 0)
{
switch (dmacRegs.ctrl.MFD)
{
case MFD_VIF1: // Most common case.
case MFD_GIF:
{
if ((spr0ch.madr & ~dmacRegs.rbsr.RMSK) != dmacRegs.rbor.ADDR) Console.WriteLn("GIF MFIFO Write outside MFIFO area");
spr0ch.madr = dmacRegs.rbor.ADDR + (spr0ch.madr & dmacRegs.rbsr.RMSK);
//Console.WriteLn("mfifoGIFtransfer %x madr %x, tadr %x", gif->chcr._u32, gif->madr, gif->tadr);
hwMFIFOResume(mfifotransferred);
hwMFIFOResume();
break;
}
default:
break;
}
mfifotransferred = 0;
}
return;