This project is educational and Open Source. No code is copied from other emulators. Implementation based solely on technical documentation and permitted tests.
The Autopsy: Post-Start Diagnosis
Summary
Given the persistence of the blank (green) screen without apparent errors, we changed the debugging strategy. Instead of plotting the execution step by step (which introduces latency and distorts behavior), we let the emulator run for 3 seconds (180 frames) and perform a full state dump ("Autopsy"). This will reveal whether the game managed to progress past initialization, configured the video logs correctly, and wrote graphics data to VRAM.
Hardware Concept
When a Game Boy game starts up, it follows a typical initialization sequence:
- Register initialization:Configures the initial values of the CPU and peripherals.
- V-Blank Standby:Wait for the PPU to enter V-Blank mode (LY = 144) before touching VRAM.
- Copy of graphics:Use DMA or load/store instructions to copy tiles to VRAM (0x8000-0x97FF).
- Map settings:Writes tile indexes to the Tile Map (0x9800-0x9BFF).
- Screen enablement:Activate LCDC bit 7 (0xFF40) to turn on the display.
- Palette Settings:Writes values to BGP (0xFF47) to define colors.
If the emulator runs at 60 FPS, in 3 seconds it will have executed millions of cycles. If the screen is still green after 3 seconds, the state of the machine at that moment will tell us exactly why:
- If PC is still at 0x02B4 (or close):The problem is theTiming. The CPU does not see LY advance, probably because the PPU is not updating the register correctly.
- If BGP is 0x00:The game runs butthe palette is black/white. Tetris typically writes 0xFC or 0xE4 to BGP.
- If LCDC Bit 0 is OFF:The game runs butthe screen has not turned on(bit 7 must also be ON).
- If VRAM Tile Data are all 0x00:The game runs butdoes not copy graphics(DMA failure or LDI/LDD instructions).
- If VRAM Tile Map are all 0x00:The game has graphics butthe map is empty(draw tile 0 everywhere).
"Autopsy" is a forensic technique: instead of trying to track the problem in real time (which introduces latency), we let the system run free and then "freeze" the state for analysis. It is like taking a photograph of the internal state of the hardware after a certain time.
Implementation
Added a code block in the methodrun()ofviboy.pywhich is executed only once when the frame counter reaches 180 (approximately 3 seconds at 60 FPS).
Modified components
- viboy.py: Added autopsy block that prints the full system status when
frame_count >= 180. The block includes:- CPU status (PC, SP, AF/BC/DE/HL registers, flags, HALT status)
- Video logs (LCDC, STAT, LY, BGP)
- VRAM Tile Data Sample (0x8010-0x801F)
- VRAM Tile Map Sample (0x9900-0x990F)
- Interrupt status (IE, IF)
- System statistics (total cycles, frames)
Design decisions
A flag is used_autopsy_doneto ensure that the autopsy is run only once, avoiding flooding the console with repeated dumps. The dump is done after completing frame 180, not during its execution, so as not to interfere with the timing.
Autopsy is only available in C++ mode because that is where the emulator is currently running. If Python mode is detected, a warning is printed.
Affected Files
src/viboy.py- Added autopsy block in methodrun()
Tests and Verification
To validate the implementation:
- Run the emulator:
python main.py roms/tetris.gb - Wait 3 seconds:The emulator should run normally for 180 frames.
- Parse the output:The console will display the complete status dump in the format:
===================================================== 💀 SYSTEM AUTOPSY (Frame 180) ===================================================== CPUState: PC: 0xXXXX | SP: 0xXXXX AF: 0xXXXX | BC: 0xXXXX | FROM: 0xXXXX | HL: 0xXXXX Flags: Z=X, N=X, H=X, C=X Halted: True/False Video Registers: LCDC: 0xXX (Bit 7=ON/OFF, BG=ON/OFF) STAT: 0xXX | LY: XXX (Decimal) BGP: 0xXX (Palette) VRAM Tile Data (0x8010 - First bytes of logo?): XX XX XX XX XX XX XX XX XX XX XX XX XX XX XX XX VRAM Tile Map (0x9900 - Center approx): XX XX XX XX XX XX XX XX XX XX XX XX XX XX XX XX Interrupts: IE: 0xXX | IF: 0xXX System State: Total Cycles: Frames: 180 ===================================================== - Interpret the results:According to the values obtained, determine the type of failure:
- Timing (PC stuck)
- Logical (LCDC off)
- Data (empty VRAM)
Sources consulted
- Bread Docs:LCD Timing, VRAM, LCDC Register
- Bread Docs:Post-Boot State, Initialization Sequence
Educational Integrity
What I Understand Now
- Forensic Diagnosis:Instead of tracking the problem in real time (which introduces latency and distorts behavior), it is more effective to let the system run free and then "freeze" the state for analysis.
- Initialization Sequence:Game Boy games follow a typical sequence: initialize → wait V-Blank → copy graphics → configure map → enable display → configure palette.
- Binary Questions:The status after 3 seconds answers binary questions: did the CPU advance? Has LCDC been configured? Was VRAM written? This reduces the search space of the problem.
What remains to be confirmed
- Interpretation of Results:Once the state dump is obtained, we need to interpret the values to determine the exact type of failure (Timing, Logical, or Data).
- Expected Values:We need to know the "normal" values that Tetris should have after 3 seconds to compare with those obtained.
Hypotheses and Assumptions
We assume that 180 frames (3 seconds) is enough time for Tetris to complete its initialization sequence. If the game is slower or has longer wait loops, we may need to increase the threshold.
Next Steps
- [ ] Run the emulator and get the full state dump
- [ ] Analyze the values obtained and determine the type of failure
- [ ] Implement correction based on diagnosis
- [ ] Verify that Tetris loads and displays graphics correctly