From de1a74debe9c69533eab56585a489b9ea11ee4b4 Mon Sep 17 00:00:00 2001 From: refractionpcsx2 Date: Wed, 13 Sep 2023 14:10:44 +0100 Subject: [PATCH] GIF: Correctly delay FINISH interrupts/flags [SAVEVERSION+] --- pcsx2/GS.cpp | 2 ++ pcsx2/Gif_Unit.cpp | 7 ++++++- pcsx2/Gif_Unit.h | 4 +++- pcsx2/MTVU.cpp | 4 ++-- pcsx2/SaveState.h | 2 +- 5 files changed, 14 insertions(+), 5 deletions(-) diff --git a/pcsx2/GS.cpp b/pcsx2/GS.cpp index 2878ad480be0a4..064750531279d9 100644 --- a/pcsx2/GS.cpp +++ b/pcsx2/GS.cpp @@ -50,6 +50,7 @@ static __fi void gsCSRwrite( const tGS_CSR& csr ) //gifUnit.Reset(true); // Don't think gif should be reset... gifUnit.gsSIGNAL.queued = false; gifUnit.gsFINISH.gsFINISHFired = true; + gifUnit.gsFINISH.gsFINISHPending = false; // Privilage registers also reset. std::memset(g_RealGSMem, 0, sizeof(g_RealGSMem)); GSIMR.reset(); @@ -84,6 +85,7 @@ static __fi void gsCSRwrite( const tGS_CSR& csr ) if (csr.FINISH) { CSRreg.FINISH = false; gifUnit.gsFINISH.gsFINISHFired = false; //Clear the previously fired FINISH (YS, Indiecar 2005, MGS3) + gifUnit.gsFINISH.gsFINISHPending = false; } if(csr.HSINT) CSRreg.HSINT = false; if(csr.VSINT) CSRreg.VSINT = false; diff --git a/pcsx2/Gif_Unit.cpp b/pcsx2/Gif_Unit.cpp index 3ca7c67d33018e..1ec6adb93aab8b 100644 --- a/pcsx2/Gif_Unit.cpp +++ b/pcsx2/Gif_Unit.cpp @@ -84,8 +84,8 @@ bool Gif_HandlerAD(u8* pMem) else if (reg == GIF_A_D_REG_FINISH) { // FINISH GUNIT_WARN("GIF Handler - FINISH"); - CSRreg.FINISH = true; gifUnit.gsFINISH.gsFINISHFired = false; + gifUnit.gsFINISH.gsFINISHPending = true; } else if (reg == GIF_A_D_REG_LABEL) { // LABEL @@ -188,6 +188,11 @@ bool Gif_HandlerAD_Debug(u8* pMem) void Gif_FinishIRQ() { + if (gifUnit.gsFINISH.gsFINISHPending) + { + CSRreg.FINISH = true; + gifUnit.gsFINISH.gsFINISHPending = false; + } if (CSRreg.FINISH && !GSIMR.FINISHMSK && !gifUnit.gsFINISH.gsFINISHFired) { gsIrq(); diff --git a/pcsx2/Gif_Unit.h b/pcsx2/Gif_Unit.h index 9d89503dc66a8e..024aa81ae4d207 100644 --- a/pcsx2/Gif_Unit.h +++ b/pcsx2/Gif_Unit.h @@ -177,6 +177,7 @@ struct GS_SIGNAL struct GS_FINISH { bool gsFINISHFired; + bool gsFINISHPending; void Reset() { std::memset(this, 0, sizeof(*this)); } }; @@ -838,7 +839,8 @@ struct Gif_Unit FlushToMTGS(); } - Gif_FinishIRQ(); + if(!checkPaths(true, true, true, true)) + Gif_FinishIRQ(); //Path3 can rewind the DMA, so we send back the amount we go back! if (isPath3) diff --git a/pcsx2/MTVU.cpp b/pcsx2/MTVU.cpp index 96727fe4c9f478..dc55ee7f8d5663 100644 --- a/pcsx2/MTVU.cpp +++ b/pcsx2/MTVU.cpp @@ -400,10 +400,10 @@ void VU_Thread::Get_MTVUChanges() { mtvuInterrupts.fetch_and(~InterruptFlagFinish, std::memory_order_relaxed); GUNIT_WARN("Finish firing"); - CSRreg.FINISH = true; gifUnit.gsFINISH.gsFINISHFired = false; + gifUnit.gsFINISH.gsFINISHPending = true; - if (!gifRegs.stat.APATH) + if (!gifUnit.checkPaths(true, true, true, true)) Gif_FinishIRQ(); } if (interrupts & InterruptFlagLabel) diff --git a/pcsx2/SaveState.h b/pcsx2/SaveState.h index bb2a1228507b0c..13d363f006bc28 100644 --- a/pcsx2/SaveState.h +++ b/pcsx2/SaveState.h @@ -37,7 +37,7 @@ enum class FreezeAction // [SAVEVERSION+] // This informs the auto updater that the users savestates will be invalidated. -static const u32 g_SaveVersion = (0x9A3F << 16) | 0x0000; +static const u32 g_SaveVersion = (0x9A40 << 16) | 0x0000; // the freezing data between submodules and core