This project is educational and Open Source. No code is copied from other emulators. Implementation based solely on technical documentation and permitted tests.
Interrupt Lock Diagnosis
Summary
A was implementedcritical diagnostic systemto identify why the CPU ignores V-Blank interrupt requests. The diagnostic adds specific logs with the symbol ⚠️ when a V-Blank request is detected in IF but is not attended to, indicating if the problem is that IE does not have the bit activated or if IME is disabled. Additionally, a log was added informative each time the IE register (0xFFFF) is written to monitor when and how the game configures interrupts.
Hardware Concept
On the Game Boy, for an interrupt to be processed correctly,three simultaneous conditions:
- IF has the bit set: The hardware (PPU, Timer, etc.) has generated an interrupt request and has set the corresponding bit in the IF register (0xFF0F).
- IE has the bit set: The software has enabled that interrupt by writing the corresponding bit in the IE register (0xFFFF). This allows the game to select which interruptions it wants to receive.
- IME is activated: The CPU has interrupts enabled globally. IME is activated with the instruction
EI(Enable Interrupts) and is deactivated withD.I.(Disable Interrupts).
If any of these conditions are not met, the interruptionis not processed, although the hardware continues to generate the request in IF. This is especially critical for V-Blank, as many games rely on this interruption to progress. at its initialization.
The implemented diagnostic specifically checks for the V-Blank interrupt (bit 0 of IF/IE) because it is the first one that should occur after turning on the LCD. If V-Blank is not rendered, the game waits indefinitely.
Fountain:Pan Docs - Interrupts, Interrupt Enable Register (IE), Interrupt Flag Register (IF), IME
Implementation
Two strategic diagnostic points were added:
1. V-Blank Diagnosis in handle_interrupts() (CPU)
Insrc/cpu/core.py, methodhandle_interrupts(), a diagnostic block was addedbefore checking for pending interrupts. The diagnosis specifically checks for
a V-Blank request in IF (bit 0) and why it is not being served:
- If IE does not have bit 0 set: Log in
⚠️ V-Blank IGNORED: Not enabled in IE (IE=XX) - If IME is disabled: Log in
⚠️ V-Blank IGNORED: IME disabled (DI executed)
This diagnostic is runevery time handle_interrupts() is called, even if there are no interruptions pending, which allows detecting the problem in real time.
2. Write Log in IE (MMU)
Insrc/memory/mmu.py, methodwrite_byte(), an informative log was added that is activated
every time it is written to the IE register (0xFFFF). The log shows:
- The value written in IE (hexadecimal format)
- What interrupts are being enabled (V-Blank, STAT, Timer) in readable format
This log allows you to identify if the gamenever writes in IE(which would be a bug in the game or a problem previous emulation) or if you type an incorrect value.
Design decisions
- DEBUG log level for V-Blank diagnostics: Used
logging.debug()so that the log be visible when debug mode is activated, but do not clutter the console in normal mode. - INFO log level for writing in IE: Used
logging.info()because it is an event less frequent and critical to understanding the game initialization flow. - ⚠️ symbol for alerts: Added a distinctive visual symbol to facilitate searching in the logs and distinguish these diagnostic messages from other logs.
- Verification before calculating pending: Diagnostic is run before calculating
pendingto be able to distinguish between "IE does not have the bit" and "IME disabled", since both cases result inpending == 0.
Affected Files
src/cpu/core.py- Added V-Blank diagnostics inhandle_interrupts()before checking IMEsrc/memory/mmu.py- Added informative log when writing to IE (0xFFFF)
Tests and Verification
Execution mode:Manual with commercial ROM (Pokémon Red, contributed by the user, not distributed)
Command executed: python main.py pkmn.gb
Around:Windows 10, Python 3.13.5
Success Criterion:
- View diagnostic messages
⚠️ V-Blank IGNOREDin the console when the emulator is run - View messages
SET IE REGISTERif the game tries to configure IE - Identify the root cause of interrupt blocking (IE not configured or IME disabled)
Expected observation:
When you run the emulator, diagnostic messages should appear in the console indicating why the V-Blank interrupt
is not being processed. If the message is⚠️ V-Blank IGNORED: Not enabled in IE, it means that the game never
wrote in IE to enable V-Blank. If the message is⚠️ V-Blank IGNORED: IME disabled, means that
the game ranD.I.and never executedEIeitherRETI.
Result: Pending execution
Legal notes:The Pokémon Red ROM is provided by the user for local testing. Not distributed nor is it included in the repository. Commercial ROM downloads are not linked.
Sources consulted
- Bread Docs:Interrupts
- Bread Docs:Interrupt Enable Register (IE, 0xFFFF)
- Bread Docs:Interrupt Flag Register (IF, 0xFF0F)
- Bread Docs:EI (Enable Interrupts)
- Bread Docs:DI (Disable Interrupts)
Educational Integrity
What I Understand Now
- Conditions for processing interrupts: An interruption requires three simultaneous conditions: IF activated, IE activated, and IME activated. If any of these fail, the interrupt is not processed.
- Proactive diagnosis: To identify interruption problems, it is necessary to verify each condition separately, not just the final result (pending == 0).
- Initialization flow: Many games turn on the LCD (LCDC=0x80) and then wait for V-Blank to configure the rest of the graphics. If V-Blank is not rendered, the game freezes.
What remains to be confirmed
- Root cause of crash: I need to run the emulator and see what diagnostic message appears to identify if the problem is IE not configured or IME disabled.
- Write timing in IE: I'm not sure when exactly games write to IE. Some games may do it very early in initialization, others may do it after turning on the LCD.
- IME behavior on initialization: I'm not sure if the CPU boots with IME on or off by default. This could affect the diagnosis.
Hypotheses and Assumptions
Main hypothesis:The game never writes to IE to enable V-Blank, or does it after powering on
the LCD but the interruption has already been lost. Alternatively, the game ranD.I.at some point and never
executedEIeitherRETI.
Assumption about initial IME:I assume that the CPU boots with IME disabled (as in many embedded systems), but this needs confirmation with documentation or tests.
Next Steps
- [ ] Run the emulator with
python main.py pkmn.gband search for messages⚠️ V-Blank IGNORED - [ ] If appears
Not enabled in IE: Check for messagesSET IE REGISTERin the logs - [ ] If appears
IME disabled: Search the logs where it was executedD.I.and why it was not executedEI - [ ] Implement fix according to the identified cause (force IE, force IME, or correct EI/DI logic)
- [ ] Verify that the game progresses after the fix by running the ROM again