From 002b745917a6b8ecd99483022c5fab9e5e66d356 Mon Sep 17 00:00:00 2001 From: MadMaurice Date: Tue, 29 Aug 2023 12:10:10 +0200 Subject: [PATCH] cpu - Fix timing of delay when enabling interrupts --- cpu/cpu.cpp | 2 -- cpu/cpu.h | 13 ++++++++++++- 2 files changed, 12 insertions(+), 3 deletions(-) diff --git a/cpu/cpu.cpp b/cpu/cpu.cpp index 088669c..989283c 100644 --- a/cpu/cpu.cpp +++ b/cpu/cpu.cpp @@ -191,8 +191,6 @@ void Cpu::handleInterrupts() u8 si = state.IE & state.IF & INT_MASK; if (state.IME == IME_SCHEDULED) - state.IME = IME_DELAYED; - else if (state.IME == IME_DELAYED) state.IME = IME_ON; else if (state.IME == IME_ON && si != 0) { diff --git a/cpu/cpu.h b/cpu/cpu.h index 36bb1ce..8aff385 100644 --- a/cpu/cpu.h +++ b/cpu/cpu.h @@ -43,11 +43,22 @@ enum InterruptType : u8 INT_MASK = 0x1F, }; + +/** + IME - Interrupt Master Enable + + An EI instruction will enable the interrupts, but delayed. During the next instruction after EI, + interrupts are still disabled. For this to be emulated we use a small state machine. which works as follows + + instruction EI - sets IME_SCHEDULED + handleInterrupts -> IME_SCHEDULED to IME_ON (but no call to isr yet) + instruction any - is IME_ON, but no chance for call to isr yet + handleInterrupts -> is IME_ON, do a call to isr if necessary + */ enum IME_state { IME_OFF, IME_SCHEDULED, - IME_DELAYED, IME_ON, };