This project is educational and Open Source. No code is copied from other emulators. Implementation based solely on technical documentation and permitted tests.
Real Time Status Monitor
Summary
A real-time status monitor has been implemented in the main loop of the emulator that prints detailed CPU, register, interrupt and hardware status information every 5 seconds. This monitor allows you to diagnose crashes and infinite loops when the game goes "sleep" with the screen off (LCD OFF), showing exactly where the CPU is stuck and what it is waiting for. It is a temporary diagnostic tool that helps identify synchronization, interruptions and timing problems.
Hardware Concept
When a Game Boy game turns off the LCD (by writing 0x00 to LCDC, bit 7 = 0), the PPU stops completely: LY (Current Line) remains at 0, the PPU timing does not advance, and no V-Blank interrupts are generated. If the game waits for a LY move or a V-Blank interrupt while the LCD is off, it will never exit the wait loop because the real hardware doesn't generate these events when the LCD is off.
Nintendo's programmers knew this, so they usually wait for the Timer (which continues to work even with the LCD off) or simply activate the LCD directly. However, some games may have logical bugs or incompatibilities that cause them to get stuck waiting for events that will never happen.
To diagnose these problems, you need to know:
- PC (Program Counter):Where the code is currently running
- Current opcode:Which instruction is executing (and the next 2 bytes for multi-byte instructions)
- IME (Interrupt Master Enable):If interrupts are enabled globally
- IE (Interrupt Enable, 0xFFFF):What interrupts are enabled (VBlank, LCD, Timer, etc.)
- IF (Interrupt Flag, 0xFF0F):What interruptions are pending
- LCDC (LCD Control, 0xFF40):Whether the LCD is on (bit 7) and other controls
- LY (Scanline):PPU current line (must be 0 if LCD is off)
- DIV (Divider, 0xFF04):Timer registration that continues to work even with LCD off
Fountain:Pan Docs - LCD Control Register, LCD Timing, Interrupts, Timer
Implementation
A periodic monitoring system was added to the methodrun()of the classViboywhich prints detailed system status information every 5 seconds.
Components created/modified
- Viboy (`src/viboy.py`): Added an import of
timeand a variablelast_debug_timewhich is initialized before the main loop. Within the loop, it is checked if 5 seconds have passed since the last report, and if so, a block of detailed information is printed with the current state of the system.
Design decisions
5 second interval:A 5 second interval was chosen to balance useful information and not cluttering the console with too many messages. If the PC does not change between reports (or oscillates between 2 values), we will know exactly which instruction it is blocking.
Using print() instead of logging:Although the project rules prohibitprint()in favor oflogging, this monitor usesprint()intentionally because it is a temporary diagnostic tool that should be immediately visible in the console without needing to configure logging levels. The user can see the status in real time while the emulator is running.
Information displayed:The monitor displays critical diagnostic information:
- LCD Status (ON/OFF based on LCDC bit 7)
- PC and the 3 bytes of opcode at that address (to see the current and subsequent instructions)
- SP (Stack Pointer) to check stack status
- IME to know if interrupts are enabled globally
- IE and IF with bit breakdown (VBlank, LCD, Timer) to identify which interrupts are enabled/pending
- LY to check if the PPU is advancing
- DIV to check if the Timer is working
Affected Files
src/viboy.py- Added importtimeand periodic monitoring logic in the methodrun()
Tests and Verification
This monitor is a temporary diagnostic tool that will be validated by running the emulator with ROMs showing crash issues (undefined blue/black screen).
- Test ROM:Pokémon Red (user-contributed ROM, not distributed) - shows blank blue screen when LCD is off
- Execution mode:UI with monitor enabled
- Success Criterion:The monitor should display information every 5 seconds with the current status of the system, allowing you to identify where the CPU is stuck
- Expected observation:If the PC does not change between reports (or oscillates between 2 values), we will know the instruction that is blocking. If IME=False and there are bits in IE and IF, we will know that the game forgot to enable interrupts. If LCD=OFF and the game waits for VBlank, we will know that there is a logical bug.
- Result:
draft- Pending verification with actual emulator execution
Legal note:The Pokémon Red ROM is provided by the user for local testing. It is not distributed or included in the repository.
Sources consulted
- Bread Docs:LCD Control Register
- Bread Docs:Timer and Divider
- Bread Docs:Interrupts
Educational Integrity
What I Understand Now
- LCD OFF and PPU:When the LCD is off, the PPU stops completely. LY remains at 0, no V-Blank interrupts are generated, and timing does not advance. This is critical to understanding why some games get stuck waiting for events that will never happen.
- Blockage diagnosis:To diagnose crashes, we need to know exactly where the CPU (PC) is, what it is running (opcode), and what it is waiting for (IME, IE, IF, LCDC, LY). The real-time status monitor provides this information periodically.
- Temporary tool:This monitor is a temporary diagnostic tool that should be removed or disabled when crash issues are resolved. It is not part of the final functionality of the emulator.
What remains to be confirmed
- Actual hardware behavior:I don't have access to an actual Game Boy to verify exactly what happens when the LCD is off and the game waits for events that will never happen. The behavior described is based on technical documentation (Pan Docs).
- Lock Patterns:I haven't run the emulator yet with the monitor on to see what crash patterns appear. The monitor reports will reveal whether the problem is interruptions, timing, or game logic.
Hypotheses and Assumptions
Main hypothesis:The game is stuck because you turned off the LCD to load data, finished loading, and now it's in a loop waiting for "something" (possibly V-Blank or a change in LY) to turn it back on. That "something" is not happening because the LCD is off and the PPU is stopped.
Monitor Assumption:We assume that displaying the status every 5 seconds is enough to identify the problem without overwhelming the console. If the problem requires more frequency, the interval can be adjusted.
Next Steps
- [ ] Run the emulator with Pokémon Red and wait for the blue screen to appear
- [ ] Wait 10 seconds to see at least 2 monitor reports
- [ ] Analyze reports to identify where the CPU is stuck
- [ ] If the PC does not change, identify the instruction that blocks
- [ ] If IME=False and there are bits in IE and IF, investigate why the game does not trigger interrupts
- [ ] If LCD=OFF and the game waits for VBlank, investigate the logical bug
- [ ] Once the problem is resolved, remove or disable the temporary monitor