From 8aca0fe288ff596824f35841826bf8ca90222bef Mon Sep 17 00:00:00 2001 From: refractionpcsx2 Date: Thu, 19 Mar 2026 10:26:30 +0000 Subject: [PATCH] VIF/MFIFO: Respect MFIFO empty condition on SPR transfers --- pcsx2/Dmac.h | 2 +- pcsx2/Hw.cpp | 15 +++++---------- pcsx2/SPR.cpp | 16 +++------------- 3 files changed, 9 insertions(+), 24 deletions(-) diff --git a/pcsx2/Dmac.h b/pcsx2/Dmac.h index 6ce8924e51..9934a68ed4 100644 --- a/pcsx2/Dmac.h +++ b/pcsx2/Dmac.h @@ -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); diff --git a/pcsx2/Hw.cpp b/pcsx2/Hw.cpp index 7019ecb6e3..6f8759fc9f 100644 --- a/pcsx2/Hw.cpp +++ b/pcsx2/Hw.cpp @@ -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; diff --git a/pcsx2/SPR.cpp b/pcsx2/SPR.cpp index f92a2b0a6d..f45f096106 100644 --- a/pcsx2/SPR.cpp +++ b/pcsx2/SPR.cpp @@ -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;