⚠️ 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.

HALT Wakeup Fix (IME=0)

Date:2025-12-23 StepID:0264 State: draft

Summary

This Step checks and corrects the HALT wakeup logic on the CPU. Step 0263 confirmed that the Tile Map contains valid data (tile 0x7F), but the screen is still static. The GPS displays `IME:0`, `IE:0D`, `IF:01`, indicating that a V-Blank interrupt is pending but the CPU is not servicing it because IME is disabled. The hypothesis is that the game is using HALT and waiting for the CPU to wake up when an interrupt occurs, even if IME=0. According to Pan Docs, when IME=0 and a pending interrupt is enabled, the CPU should exit HALT but NOT jump to the interrupt vector.

Hardware Concept

HALT Instruction:The HALT instruction puts the CPU into a low-power state. The CPU stops executing instructions until an interrupt occurs or it is manually woken up.

Behavior of HALT with IME=0:According to Pan Docs, when IME=0 and there is a pending interrupt enabled in IE:

  1. CPU MUST EXIT HALT(wake up).
  2. But it does NOT jump to the interrupt vector(because IME=0).
  3. Just continue executionin the following instruction.

The "HALT Bug" problem:If the CPU stays in HALT forever because IME=0, the game freezes waiting for the interrupt to occur. This is especially problematic in games that use HALT to wait for V-Blank, since if IME never activates, the CPU never wakes up and the game freezes.

The case of Pokémon Red:The GPS displays `IME:0`, `IE:0D`, `IF:01`, indicating that a V-Blank interrupt is pending (`IF:01`) and is enabled in IE (`IE:0D` has bit 0 set). If the game is HALT waiting for V-Blank, the CPU should wake up even if IME=0, allowing the game to continue execution.

Fountain:Pan Docs - "HALT Instruction", "Interrupts", "IME (Interrupt Master Enable)"

Implementation

Revised and improved HALT wakeup logic in the methodhandle_interrupts()ofCPU.cpp. The logic was already implemented correctly, but the comments were improved to clearly explain the behavior when IME=0.

Modified components

  • CPU::handle_interrupts(): Improved comments to clearly explain that the CPU should wake up from HALT when a pending interrupt is enabled, even if IME=0. The logic was already correct, but now it is better documented.

Design decisions

IME independent HALT wake up:The CPU should wake up from HALT if there are ANY pending interrupts enabled in IE, regardless of the state of IME. This allows the game to continue running even if IME is disabled.

Do not jump to vector if IME=0:If IME is false, the CPU does not consume extra cycles or jump to the interrupt vector. It just continues normal execution (HALT ends).

Improved comments:Added detailed comments explaining the behavior according to Pan Docs, including references to official documentation.

Affected Files

  • src/core/cpp/CPU.cpp- Improved comments in methodhandle_interrupts()to explain the wake-up behavior of HALT when IME=0 (Step 0264).

Tests and Verification

To validate this fix:

  1. Recompile: .\rebuild_cpp.ps1
  2. Execute: python main.py roms/pkmn.gb(Pokémon Red is ideal because it uses HALT to wait for V-Blank).
  3. Observe the behavior:
    • If the animation progresses:The fix works correctly. The CPU is waking up from HALT when interrupts are pending, even if IME=0.
    • If the screen is still static:There may be another problem (possibly in sprite rendering or frame update logic).

Expected validation:If the fix works, you should see the Pokémon intro animation (stars falling, Game Freak, etc.) progressing correctly, even if IME is disabled.

Correlation with GPS:The GPS should show that the CPU is executing instructions (PC switching) even when IME=0, confirming that the CPU is waking up from HALT correctly.

Sources consulted

Educational Integrity

What I Understand Now

  • HALT with IME=0:When IME=0 and a pending interrupt is enabled, the CPU should wake up from HALT but NOT jump to the interrupt vector. It just continues normal execution.
  • The freezing problem:If the CPU stays in HALT forever because IME=0, the game freezes waiting for the interrupt to occur. This is especially problematic in games that use HALT to wait for V-Blank.
  • IME independent wake up:The CPU should wake up from HALT if there are ANY pending interrupts enabled in IE, regardless of the state of IME. This allows the game to continue running even if IME is disabled.

What remains to be confirmed

  • Real-time behavior:Is the CPU waking up from HALT correctly when interrupts are pending, even if IME=0? The tests will tell us if the fix works.
  • Correlation with animation:If the fix works, does the Pokémon intro animation progress correctly? This would confirm that the problem was with HALT waking up.
  • Other potential problems:If the screen is still static after the fix, there may be another problem (possibly in the sprite rendering or frame refresh logic).

Hypotheses and Assumptions

Main hypothesis:If the Tile Map contains valid data (Step 0263) but the screen is still static, and the GPS shows `IME:0`, `IE:0D`, `IF:01`, it is possible that:

  1. CPU is in HALT and does not wake up:If the CPU stays in HALT forever because IME=0, the game freezes waiting for the interrupt to occur. This fix should resolve this issue.
  2. The problem is elsewhere:If the fix does not resolve the issue, there may be another issue (possibly in sprite rendering or frame update logic).

This fix should allow the CPU to wake up from HALT properly, allowing the game to continue running and the animation to progress.

Next Steps

  • [ ] Executepython main.py roms/pkmn.gband observe if the animation progresses.
  • [ ] If the animation progresses, confirm that the correction works correctly.
  • [ ] If the screen is still static, investigate other potential problems (sprite rendering, frame refresh logic, etc.).
  • [ ] Correlate behavior with GPS to confirm that the CPU is executing instructions even when IME=0.