diff --git a/cpu.cpp b/cpu.cpp index c1e9aae7..8d33f64b 100644 --- a/cpu.cpp +++ b/cpu.cpp @@ -229,6 +229,7 @@ static void S9xSoftResetCPU (void) CPU.PCBase = NULL; CPU.NMIPending = FALSE; CPU.IRQLine = FALSE; + CPU.IRQTransition = FALSE; CPU.IRQExternal = FALSE; CPU.IRQPending = Timings.IRQPendCount; CPU.MemSpeed = SLOW_ONE_CYCLE; diff --git a/cpuexec.cpp b/cpuexec.cpp index 5904e87a..d045c3eb 100644 --- a/cpuexec.cpp +++ b/cpuexec.cpp @@ -223,7 +223,7 @@ void S9xMainLoop (void) { CPU.WaitingForInterrupt = FALSE; Registers.PCw++; - CPU.Cycles += 14; + CPU.Cycles += ONE_CYCLE; while (CPU.Cycles >= CPU.NextEvent) S9xDoHEventProcessing(); } @@ -232,24 +232,30 @@ void S9xMainLoop (void) } } - if ((CPU.Cycles >= Timings.NextIRQTimer || CPU.IRQExternal) && !CPU.IRQLine) + if (CPU.IRQTransition) + { + if (CPU.WaitingForInterrupt) + { + CPU.WaitingForInterrupt = FALSE; + Registers.PCw++; + CPU.Cycles += ONE_CYCLE; + while (CPU.Cycles >= CPU.NextEvent) + S9xDoHEventProcessing(); + } + + S9xUpdateIRQPositions(); + CPU.IRQPending = Timings.IRQPendCount; + CPU.IRQTransition = FALSE; + CPU.IRQLine = TRUE; + } + + if ((CPU.Cycles >= Timings.NextIRQTimer || CPU.IRQExternal) && !CPU.IRQLine && !CPU.IRQTransition) { if (CPU.IRQPending) CPU.IRQPending--; else { - if (CPU.WaitingForInterrupt) - { - CPU.WaitingForInterrupt = FALSE; - Registers.PCw++; - CPU.Cycles += 14; - while (CPU.Cycles >= CPU.NextEvent) - S9xDoHEventProcessing(); - } - - S9xUpdateIRQPositions(); - CPU.IRQPending = Timings.IRQPendCount; - CPU.IRQLine = TRUE; + CPU.IRQTransition = TRUE; } } diff --git a/ppu.cpp b/ppu.cpp index 9640f561..dba745af 100644 --- a/ppu.cpp +++ b/ppu.cpp @@ -334,7 +334,7 @@ void S9xUpdateIRQPositions (void) else if (!PPU.HTimerEnabled && PPU.VTimerEnabled) { if (CPU.V_Counter == PPU.VTimerPosition) - Timings.NextIRQTimer = 0; + Timings.NextIRQTimer = Timings.IRQTriggerCycles; else Timings.NextIRQTimer = CyclesUntilNext (Timings.IRQTriggerCycles, PPU.VTimerPosition); } @@ -1556,7 +1556,10 @@ void S9xSetCPU (uint8 Byte, uint16 Address) PPU.HTimerEnabled = FALSE; if (!(Byte & 0x10) && !(Byte & 0x20)) + { CPU.IRQLine = FALSE; + CPU.IRQTransition = FALSE; + } S9xUpdateIRQPositions(); @@ -1842,6 +1845,7 @@ uint8 S9xGetCPU (uint16 Address) case 0x4211: // TIMEUP byte = CPU.IRQLine ? 0x80 : 0; CPU.IRQLine = FALSE; + CPU.IRQTransition = FALSE; S9xUpdateIRQPositions(); return (byte | (OpenBus & 0x7f));