⚠️ Clean-Room / Educational

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

Date:2025-12-18 StepID:0051 State: draft

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:

  1. 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).
  2. 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.
  3. IME is activated: The CPU has interrupts enabled globally. IME is activated with the instructionEI(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: Usedlogging.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: Usedlogging.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 calculatingpendingto 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 IME
  • src/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 messagesSET 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

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 withpython main.py pkmn.gband search for messages⚠️ V-Blank IGNORED
  • [ ] If appearsNot enabled in IE: Check for messagesSET IE REGISTERin the logs
  • [ ] If appearsIME 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