From 85b0cf01919d254ec4a7c5fa919b474cbfa2c3f4 Mon Sep 17 00:00:00 2001 From: Brandon Wright Date: Thu, 31 May 2018 15:02:42 -0500 Subject: [PATCH] Proper for Marko AND Super Ghouls and Ghosts. --- cpu.cpp | 2 ++ cpuexec.cpp | 11 +++++++++++ cpuops.cpp | 9 ++++++--- snapshot.cpp | 2 +- snes9x.h | 9 ++++++++- 5 files changed, 28 insertions(+), 5 deletions(-) diff --git a/cpu.cpp b/cpu.cpp index 11400f7b..e9f78310 100644 --- a/cpu.cpp +++ b/cpu.cpp @@ -267,6 +267,8 @@ static void S9xSoftResetCPU (void) Timings.V_Max = Timings.V_Max_Master; Timings.NMITriggerPos = 0xffff; Timings.NextIRQTimer = 0x0fffffff; + Timings.IRQFlagChanging = IRQ_NONE; + if (Model->_5A22 == 2) Timings.WRAMRefreshPos = SNES_WRAM_REFRESH_HC_v2; else diff --git a/cpuexec.cpp b/cpuexec.cpp index 6e501133..cc7880a0 100644 --- a/cpuexec.cpp +++ b/cpuexec.cpp @@ -260,6 +260,17 @@ void S9xMainLoop (void) if ((CPU.IRQLine || CPU.IRQExternal) && !CheckFlag(IRQ)) S9xOpcode_IRQ(); + /* Change IRQ flag for instructions that set it only on last cycle */ + if (Timings.IRQFlagChanging) + { + if (Timings.IRQFlagChanging == IRQ_CLEAR_FLAG) + ClearIRQ(); + else if (Timings.IRQFlagChanging == IRQ_SET_FLAG) + SetIRQ(); + Timings.IRQFlagChanging = IRQ_NONE; + } + + #ifdef DEBUGGER if ((CPU.Flags & BREAK_FLAG) && !(CPU.Flags & SINGLE_STEP_FLAG)) { diff --git a/cpuops.cpp b/cpuops.cpp index 5dae1244..63121704 100644 --- a/cpuops.cpp +++ b/cpuops.cpp @@ -1635,19 +1635,22 @@ static void OpF8 (void) // CLI static void Op58 (void) { - ClearIRQ(); +// ClearIRQ(); AddCycles(ONE_CYCLE); #ifndef SA1_OPCODES - CPU.IRQLine = FALSE; + Timings.IRQFlagChanging = IRQ_CLEAR_FLAG; #endif } // SEI static void Op78 (void) { - SetIRQ(); AddCycles(ONE_CYCLE); + +#ifndef SA1_OPCODES + Timings.IRQFlagChanging = IRQ_SET_FLAG; +#endif } // CLV diff --git a/snapshot.cpp b/snapshot.cpp index 3b0a82ef..fe66e69c 100644 --- a/snapshot.cpp +++ b/snapshot.cpp @@ -595,7 +595,7 @@ static FreezeData SnapTimings[] = INT_ENTRY(6, InterlaceField), INT_ENTRY(6, DMACPUSync), INT_ENTRY(6, NMIDMADelay), - INT_ENTRY(6, IRQPendCount), + INT_ENTRY(6, IRQFlagChanging), INT_ENTRY(6, APUSpeedup), INT_ENTRY(7, IRQTriggerCycles), INT_ENTRY(7, APUAllowTimeOverflow) diff --git a/snes9x.h b/snes9x.h index fe51b9c2..3cc9ca30 100644 --- a/snes9x.h +++ b/snes9x.h @@ -335,6 +335,13 @@ enum HC_WRAM_REFRESH_EVENT = 6 }; +enum +{ + IRQ_NONE = 0, + IRQ_SET_FLAG = 1, + IRQ_CLEAR_FLAG = 2 +}; + struct STimings { int32 H_Max_Master; @@ -353,7 +360,7 @@ struct STimings bool8 InterlaceField; int32 DMACPUSync; // The cycles to synchronize DMA and CPU. Snes9x cannot emulate correctly. int32 NMIDMADelay; // The delay of NMI trigger after DMA transfers. Snes9x cannot emulate correctly. - int32 IRQPendCount; // This value is just a hack. + int32 IRQFlagChanging; // This value is just a hack. int32 APUSpeedup; bool8 APUAllowTimeOverflow; };