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

The Return of the Stethoscope: Where is the CPU?

Date:2025-12-22 StepID:0230 State: DRAFT

Summary

Even though the emulator runs at real speed after deleting the logs (Step 0229), the screen continues to show the background color (green/white) and there are no graphics. This indicates that the PPU is turned off (LCDCbit 7 = 0) or it is not rendering. We reactivate the periodic status monitor ("Stethoscope", Step 0222) to observe the Program Counter (PC) and registryLCDCin real time and determine if the game is stuck in a loading loop or if it has failed silently.

Hardware Concept

When a Game Boy game starts up, it typically follows this sequence:

  1. Initialization:The CPU executes initialization code from the cartridge ROM.
  2. Graphics loading:The game copies the tiles from the ROM to the VRAM (0x8000-0x9FFF).
  3. TileMap Settings:The game writes to the TileMap (0x9800-0x9BFF) to indicate which tile to draw at each position.
  4. LCD power on:The game activates bit 7 of the registerLCDC(0xFF40) to turn on the screen.
  5. Main loop:The game enters its main loop, rendering frames continuously.

If the screen is still green after deleting the logs, it may be because:

  • The game turned off the screen:The recordLCDChas bit 7 off (0x00-0x7F). This is normal during initialization, but the game should turn it on afterward.
  • The game is copying graphics:The tile copy loop can be long (hundreds of frames). The game may have the screen off while copying.
  • The game is stuck:The CPU may be in an infinite loop waiting for something (Timer, Joypad, interrupt).
  • The game is over and waiting:The game may have finished initializing and is waiting for an interrupt to start.

The "Stethoscope" is a low impact monitor that prints a status line every 60 frames (1 second). This allows us to observe the vital signs of the emulator without affecting performance:

  • PC (Program Counter):If it changes quickly, the CPU is running. If it is fixed, there is a deadlock.
  • LCDC:If bit 7 is on (0x80-0xFF), the game thinks the screen is on. If it is off (0x00-0x7F), the game has it turned off.
  • TileMap[0x9904]:If it is 0x00, the TileMap is empty. If it has values, the game has configured tiles.
  • TileData[0x8010]:If it is 0x00, VRAM is empty. If it has values, the game has copied graphics.

Implementation

Reactivated the "Stethoscope" diagnostic block (Step 0222) in the methodrun()ofviboy.py. The code runs every 60 frames (approximately 1 second) and reads the vital signs directly from the hardware.

Modified components

  • src/viboy.py: Reactivated diagnostic block "The Stethoscope" in the methodrun()(lines ~819-834). The code was commented from Step 0224.

Implemented code

# --- Step 0230: THE RETURN OF THE STETHOSCOPE ---
# Periodic diagnosis (every 60 frames = approx. 1 second)
# Reactivated to diagnose why the screen is still green after deleting the logs.
# This will tell us if the CPU is still running, where it is and the status of the LCD.
if self.frame_count % 60 == 0:
    if self._use_cpp:
        # Read vital status directly from hardware
        pc = self._regs.pc
        lcdc = self._mmu.read(0xFF40)
        
        # See if there is data in VRAM (Tile Map and Tile Data)
        tile_map_val = self._mmu.read(0x9904)
        tile_data_val = self._mmu.read(0x8010)
        
        print(f"[VITAL] PC: {pc:04X} | LCDC: {lcdc:02X} | Map[9904]: {tile_map_val:02X} | Data[8010]: {tile_data_val:02X}")
# ---------------------------------------------

Design decisions

We chose to reactivate Stethoscope instead of instrumenting the C++ code because:

  • Low impact:Printing one line every second does not affect performance significantly.
  • Sufficient information:The PC and LCDC will tell us if the CPU is running and if the game is trying to turn on the screen.
  • No recompilation required:The code is in Python, so we don't need to recompile C++.

Affected Files

  • src/viboy.py- Reactivated diagnostic block "The Stethoscope" in the methodrun()(lines ~819-834)

Tests and Verification

To validate the diagnosis, run the emulator and observe the console output:

python main.py roms/tetris.gb

Every second a line will appear with the format:

[VITAL] PC: 02B4 | LCDC: 91 | Map[9904]: 00 | Data[8010]: 00

Analysis of results:

  • Case A (static PC):If the PC does not switch between lines (e.g. always02B4), the CPU is in an infinite loop (deadlock). The game is stuck waiting for something that never comes.
  • Case B (PC switching, LCDC off):If the PC changes quickly (ex:2B15, 0340, 2000...) but the LCDC is 0x08 or 0x00 (bit 7 off), the game is running but the screen is turned off voluntarily. It may be copying graphics or waiting for something.
  • Case C (PC switching, LCDC on, VRAM empty):If the PC changes, the LCDC has bit 7 on (0x91, 0x80...), but Map[9904] and Data[8010] are 0x00, the game thinks the screen is on but has not copied the graphics yet. This is normal during initialization.
  • Case D (PC switching, LCDC on, VRAM with data):If the PC switches, the LCDC is on, and the VRAM has data, the game should be rendering. If we don't see graphics, the problem is with the rendering, not the CPU.

Evidence from Tests:

# Command executed:
python main.py roms/tetris.gb

# Expected result:
# Every second a line appears:
# [VITAL] PC: XXXX | LCDC: XX | Map[9904]: XX | Data[8010]: XX

# Validation:
# - If PC changes: CPU is running ✅
# - If PC is fixed: Deadlock ❌
# - If LCDC bit 7 on: Game tries to turn on screen ✅
# - If LCDC bit 7 off: Game has screen off ⚠️

Sources consulted

Educational Integrity

What I Understand Now

  • Non-intrusive diagnosis:A periodic health monitor can provide valuable information without impacting performance. Printing one line every second pales in comparison to printing every CPU cycle.
  • Emulator vital signs:PC, LCDC and VRAM are key indicators of system health. If the PC doesn't change, the CPU is stuck. If the LCDC has bit 7 off, the game has the screen off. If the VRAM is empty, the graphics have not been copied.
  • Balance between diagnosis and performance:The Stethoscope provides enough information to diagnose the problem without overwhelming the console or affecting performance.

What remains to be confirmed

  • Observed values:We need to run the emulator and observe what values ​​the diagnostic displays to determine if the CPU is running, if the LCDC is configured, and if the VRAM contains data.
  • Game behavior:Once we have the diagnostic values, we can determine if the problem is a deadlock, an incorrect hardware configuration, or simply that the game has not copied the graphics yet.

Hypotheses and Assumptions

Main hypothesis:The game is running correctly but the screen is off during initialization. The Stethoscope will confirm if the PC advances (CPU running) and if the LCDC changes (game tries to turn on the screen). If the PC is fixed, there is a deadlock that we need to investigate.

Next Steps

  • [ ] Run the emulator and observe the diagnostic values
  • [ ] Analyze the values ​​to determine if the CPU is running, if the LCDC is configured, and if the VRAM contains data
  • [ ] Based on the analysis, implement the corresponding correction:
    • If PC is fixed: Investigate deadlock (Timer, Interrupts, Joypad)
    • If PC changes but LCDC off: Wait for the game to turn on the screen or investigate why it doesn't
    • If PC changes, LCDC on, but VRAM empty: Investigate why the game does not copy graphics
    • If everything is fine but there are no graphics: Investigate the rendering