diff --git a/CHANGES b/CHANGES index 009834272..66518239f 100644 --- a/CHANGES +++ b/CHANGES @@ -64,6 +64,7 @@ Emulation fixes: - GBA Video: Emulate sprite cycle limits in OpenGL renderer (fixes mgba.io/i/1635) - GBA Video: Fix OBJWIN erratic rendering in OpenGL renderer - SM83: Emulate HALT bug + - SM83: Improve mid-M-cycle interrupts Other fixes: - 3DS: Fix thread cleanup - All: Improve export headers (fixes mgba.io/i/1738) diff --git a/src/sm83/sm83.c b/src/sm83/sm83.c index 6deb1a4e0..00163a20b 100644 --- a/src/sm83/sm83.c +++ b/src/sm83/sm83.c @@ -153,11 +153,19 @@ static inline bool _SM83TickInternal(struct SM83Core* cpu) { _SM83Step(cpu); int t = cpu->tMultiplier; if (cpu->cycles + t * 2 >= cpu->nextEvent) { - int32_t diff = cpu->nextEvent - cpu->cycles; - cpu->cycles = cpu->nextEvent; - cpu->executionState += diff >> (t - 1); // NB: This assumes tMultiplier is either 1 or 2 - cpu->irqh.processEvents(cpu); - cpu->cycles += (SM83_CORE_EXECUTE - cpu->executionState) * t; + if (cpu->cycles >= cpu->nextEvent) { + cpu->irqh.processEvents(cpu); + } + cpu->cycles += t; + ++cpu->executionState; + if (cpu->cycles >= cpu->nextEvent) { + cpu->irqh.processEvents(cpu); + } + cpu->cycles += t; + ++cpu->executionState; + if (cpu->cycles >= cpu->nextEvent) { + cpu->irqh.processEvents(cpu); + } running = false; } else { cpu->cycles += t * 2;