GIF: Correctly delay FINISH interrupts/flags

[SAVEVERSION+]
This commit is contained in:
refractionpcsx2 2023-09-13 14:10:44 +01:00
parent 85670dd4a1
commit 2947e11b9b
5 changed files with 14 additions and 5 deletions

View File

@ -50,6 +50,7 @@ static __fi void gsCSRwrite( const tGS_CSR& csr )
//gifUnit.Reset(true); // Don't think gif should be reset... //gifUnit.Reset(true); // Don't think gif should be reset...
gifUnit.gsSIGNAL.queued = false; gifUnit.gsSIGNAL.queued = false;
gifUnit.gsFINISH.gsFINISHFired = true; gifUnit.gsFINISH.gsFINISHFired = true;
gifUnit.gsFINISH.gsFINISHPending = false;
// Privilage registers also reset. // Privilage registers also reset.
std::memset(g_RealGSMem, 0, sizeof(g_RealGSMem)); std::memset(g_RealGSMem, 0, sizeof(g_RealGSMem));
GSIMR.reset(); GSIMR.reset();
@ -84,6 +85,7 @@ static __fi void gsCSRwrite( const tGS_CSR& csr )
if (csr.FINISH) { if (csr.FINISH) {
CSRreg.FINISH = false; CSRreg.FINISH = false;
gifUnit.gsFINISH.gsFINISHFired = false; //Clear the previously fired FINISH (YS, Indiecar 2005, MGS3) 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.HSINT) CSRreg.HSINT = false;
if(csr.VSINT) CSRreg.VSINT = false; if(csr.VSINT) CSRreg.VSINT = false;

View File

@ -84,8 +84,8 @@ bool Gif_HandlerAD(u8* pMem)
else if (reg == GIF_A_D_REG_FINISH) else if (reg == GIF_A_D_REG_FINISH)
{ // FINISH { // FINISH
GUNIT_WARN("GIF Handler - FINISH"); GUNIT_WARN("GIF Handler - FINISH");
CSRreg.FINISH = true;
gifUnit.gsFINISH.gsFINISHFired = false; gifUnit.gsFINISH.gsFINISHFired = false;
gifUnit.gsFINISH.gsFINISHPending = true;
} }
else if (reg == GIF_A_D_REG_LABEL) else if (reg == GIF_A_D_REG_LABEL)
{ // LABEL { // LABEL
@ -188,6 +188,11 @@ bool Gif_HandlerAD_Debug(u8* pMem)
void Gif_FinishIRQ() void Gif_FinishIRQ()
{ {
if (gifUnit.gsFINISH.gsFINISHPending)
{
CSRreg.FINISH = true;
gifUnit.gsFINISH.gsFINISHPending = false;
}
if (CSRreg.FINISH && !GSIMR.FINISHMSK && !gifUnit.gsFINISH.gsFINISHFired) if (CSRreg.FINISH && !GSIMR.FINISHMSK && !gifUnit.gsFINISH.gsFINISHFired)
{ {
gsIrq(); gsIrq();

View File

@ -177,6 +177,7 @@ struct GS_SIGNAL
struct GS_FINISH struct GS_FINISH
{ {
bool gsFINISHFired; bool gsFINISHFired;
bool gsFINISHPending;
void Reset() { std::memset(this, 0, sizeof(*this)); } void Reset() { std::memset(this, 0, sizeof(*this)); }
}; };
@ -838,6 +839,7 @@ struct Gif_Unit
FlushToMTGS(); FlushToMTGS();
} }
if(!checkPaths(true, true, true, true))
Gif_FinishIRQ(); Gif_FinishIRQ();
//Path3 can rewind the DMA, so we send back the amount we go back! //Path3 can rewind the DMA, so we send back the amount we go back!

View File

@ -400,10 +400,10 @@ void VU_Thread::Get_MTVUChanges()
{ {
mtvuInterrupts.fetch_and(~InterruptFlagFinish, std::memory_order_relaxed); mtvuInterrupts.fetch_and(~InterruptFlagFinish, std::memory_order_relaxed);
GUNIT_WARN("Finish firing"); GUNIT_WARN("Finish firing");
CSRreg.FINISH = true;
gifUnit.gsFINISH.gsFINISHFired = false; gifUnit.gsFINISH.gsFINISHFired = false;
gifUnit.gsFINISH.gsFINISHPending = true;
if (!gifRegs.stat.APATH) if (!gifUnit.checkPaths(true, true, true, true))
Gif_FinishIRQ(); Gif_FinishIRQ();
} }
if (interrupts & InterruptFlagLabel) if (interrupts & InterruptFlagLabel)

View File

@ -37,7 +37,7 @@ enum class FreezeAction
// [SAVEVERSION+] // [SAVEVERSION+]
// This informs the auto updater that the users savestates will be invalidated. // 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 // the freezing data between submodules and core