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 Vital Signs Monitor
Summary
A real-time based vital signs monitor was implemented that works independently of the PPU frames. This monitor prints the system status (PC, LCDC, LY, total cycles) every 1 second of real time, even when the LCD is off and no frames are generated. Additionally, when the LCD is off, it displays the VRAM checksum to diagnose if the game is loading graphics. Removed previous boot monitor (20 prints) to clean up output.
Hardware Concept
The previous boot monitor confirmed that the CPU executes instructions correctly (PC progresses from 0x0100 to 0x1F68 and beyond). However, when the LCD is off (`LCDC=00`), the PPU does not advance `LY` (stays at 0), no full frames are generated, and therefore the frame-based "Heartbeat" never appears. The emulator is running "in the dark": the game may be copying data to VRAM with the screen off (correct behavior), but we have no visibility into what is happening.
To diagnose the status of the emulator while the screen is off, we need a working monitor based onreal time(system clock seconds), not frames. This monitor should show:
- PC (Program Counter):Where the code is currently running
- 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)
- Total cycles:How many cycles have been executed since the beginning
- VRAM Checksum:Sum of all bytes in VRAM (0x8000-0x9FFF) - if it increases, the game is loading graphics
Fountain:Pan Docs - LCD Control Register, VRAM Access
Implementation
The method was modifiedrun()of the classViboyto add a real-time based vital signs monitor that works independently of PPU frames.
Modified components
- Viboy (`src/viboy.py`):
- Removed previous boot monitor (counter
debug_step_counterand the 20 prints of "BOOT STEP") - A variable was added
last_realtime_log = time.time()before main loop - Inside the loop, after executing each instruction, it checks if 1.0 seconds have passed since the last report
- If 1.0 seconds have passed, a message is printed with the current status: PC, LCDC, LY, and total cycles
- If the LCD is off (`LCDC & 0x80 == 0`), the VRAM checksum is additionally displayed to diagnose if the game is loading graphics
- Removed previous boot monitor (counter
Design decisions
1.0 second interval:An interval of 1 second was chosen to balance between useful information and not cluttering the console. This interval is enough to see if the PC is scrolling or static, and if the VRAM checksum is increasing (indicating graphics loading).
Using logging.info() instead of print():Although the boot monitor usedprint()To ensure visibility, this monitor useslogging.info()because it is less intrusive and allows you to control the logging level. If the user needs guaranteed visibility, they can set the logging level to INFO.
VRAM diagnostic when LCD is off:When the LCD is off, the game is usually loading graphics data into VRAM. Showing the VRAM checksum allows you to check if the game is actually copying data or if it is in an infinite loop doing nothing. If the checksum increases between reports, the game is loading graphics. If the checksum is 0 and does not change, the game is in an infinite loop.
Removing Boot Monitor:The previous boot monitor (20 prints) was useful for diagnosing immediate deadlocks, but it cluttered the console. Now that we know the CPU is working properly, the real-time monitor is more useful for diagnosing long-term problems.
Affected Files
src/viboy.py- Removed boot monitor and added real-time based vital signs monitor
Tests and Verification
This monitor is a diagnostic tool that will be validated by running the emulator with ROMs that show crashing issues (undefined black screen).
- Test ROM:Pokémon Red (user-contributed ROM, not distributed) - shows black screen when LCD is off
- Execution mode:UI with monitor on, run for 10-20 seconds
- Success Criterion:The monitor must display information every 1 second with the current state of the system, allowing you to identify:
- Whether the PC is advancing or static (indicating whether there is an infinite loop)
- If the LCDC changes from 0x00 to 0x80 or 0x91 (indicating that the game is trying to boot video)
- If the VRAM checksum increases (indicating that the game is loading graphics)
- If the VRAM checksum is 0 and does not change (indicating that the game is in an infinite loop without copying data)
- Expected observation:
- If the VRAM checksum increases: The game is loading graphics, just wait for it to finish and turn on the LCD
- If the VRAM checksum is 0 and does not change: The game is in an infinite loop and is NOT copying data (possible DMA or logic failure)
- If the LCDC changes to 0x80 or 0x91: The game tries to start the video
- 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:VRAM (Video RAM)
Educational Integrity
What I Understand Now
- Real-time based monitor vs. frames:When the LCD is off, the PPU does not generate frames, so a frame-based monitor will never display information. A real-time (system clock seconds) based monitor operates independently of the PPU status and allows you to diagnose the status of the emulator even when the display is off.
- VRAM checksum as diagnostic:The VRAM checksum (sum of all bytes at 0x8000-0x9FFF) is a useful tool to diagnose if the game is loading graphics. If the checksum increases between reports, the game is copying data. If the checksum is 0 and doesn't change, the game is in an infinite loop doing nothing.
- Temporary diagnostic 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
- Chart loading patterns:I haven't run the emulator with the monitor on yet to see what graphics loading patterns appear. The monitor reports will reveal if the game is loading graphics correctly or if there is a DMA or logic issue.
- Optimal range:The 1 second interval may be too long or too short depending on the behavior of the game. If the game loads graphics too quickly, we may lose information. If it loads very slowly, 1 second is enough.
Hypotheses and Assumptions
Main hypothesis:The game is loading graphics into VRAM with LCD off (correct behavior). The real-time monitor will show if the VRAM checksum increases, confirming that the game is copying data. Once it finishes loading, the game should turn on the LCD and display the screen.
Monitor Assumption:We assume that displaying the status every 1 second 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 black screen to appear
- [ ] Wait 10-20 seconds to see at least 10-20 monitor reports
- [ ] Analyze reports to identify:
- Whether the PC is advancing or static
- If the VRAM checksum increases (indicating graphics load)
- If the LCDC changes from 0x00 to 0x80 or 0x91 (indicating video start)
- [ ] If the VRAM checksum increases: Wait for it to finish loading and check if the LCD turns on
- [ ] If the VRAM checksum is 0 and does not change: Investigate why the game is not copying data (possible DMA or logic failure)
- [ ] Once the problem is resolved, remove or disable the temporary monitor