diff --git a/source/CPU.cpp b/source/CPU.cpp index 46050a4a..93e1289f 100644 --- a/source/CPU.cpp +++ b/source/CPU.cpp @@ -427,6 +427,13 @@ static __forceinline void CheckInterruptSources(ULONG uExecutedCycles) } } +// GH#605: IRQ needs to occur within 17 cycles (6 opcodes) of configuring the timer interrupt +void CpuAdjustIrqCheck(UINT uCyclesUntilInterrupt) +{ + if (uCyclesUntilInterrupt < IRQ_CHECK_TIMEOUT) + g_nIrqCheckTimeout = uCyclesUntilInterrupt; +} + //=========================================================================== #include "CPU/cpu6502.h" // MOS 6502 diff --git a/source/CPU.h b/source/CPU.h index 1c86461f..98f58d0a 100644 --- a/source/CPU.h +++ b/source/CPU.h @@ -14,6 +14,7 @@ struct regsrec extern regsrec regs; extern unsigned __int64 g_nCumulativeCycles; +void CpuAdjustIrqCheck(UINT uCyclesUntilInterrupt); void CpuDestroy (); void CpuCalcCycles(ULONG nExecutedCycles); DWORD CpuExecute(const DWORD uCycles, const bool bVideoUpdate); diff --git a/source/Mockingboard.cpp b/source/Mockingboard.cpp index a52fd4e2..f9bf7aed 100644 --- a/source/Mockingboard.cpp +++ b/source/Mockingboard.cpp @@ -427,6 +427,7 @@ static void SY6522_Write(BYTE nDevice, BYTE nReg, BYTE nValue) pMB->sy6522.TIMER1_COUNTER.w = pMB->sy6522.TIMER1_LATCH.w; StartTimer1(pMB); + CpuAdjustIrqCheck(pMB->sy6522.TIMER1_LATCH.w); // Sync IRQ check timeout with 6522 counter underflow - GH#608 break; case 0x07: // TIMER1H_LATCH // Clear Timer1 Interrupt Flag. @@ -444,6 +445,7 @@ static void SY6522_Write(BYTE nDevice, BYTE nReg, BYTE nValue) pMB->sy6522.TIMER2_COUNTER.w = pMB->sy6522.TIMER2_LATCH.w; StartTimer2(pMB); + CpuAdjustIrqCheck(pMB->sy6522.TIMER1_LATCH.w); // Sync IRQ check timeout with 6522 counter underflow - GH#608 break; case 0x0a: // SERIAL_SHIFT break;