This project is educational and Open Source. No code is copied from other emulators. Implementation based solely on technical documentation and permitted tests.
Step 0258: VRAM Vital Signs (VRAM Sum)
Summary
This Step adds a VRAM integrity diagnostic to the GPS monitor in `src/viboy.py`. We calculate the byte sum of the VRAM (sampling every 16 bytes) to determine if it contains graphics or is completely empty. If the VRAM is full of zeros, the PPU will render index 0 (green/white) pixels, working "correctly" on empty data.
With forced palette in C++ (Step 0257) and Python (Step 0256), if the screen remains green even with games that have the LCD on (such as Pokémon Red, `LCDC:E3`), the only logical explanation left is thatVRAM is full of zeros. If the VRAM is all 0, the PPU draws "Color 0" perfectly, which is... green.
Hardware Concept
The VRAM (Video RAM) on the Game Boy occupies the range `0x8000-0x9FFF` (8KB) and contains:
- Tile Data (0x8000-0x97FF):Data from the tiles (graphics) used to render the background and sprites. Each tile occupies 16 bytes (2 bytes per line of 8 pixels).
- Tile Map (0x9800-0x9FFF):Tile maps that indicate which tile is drawn at each background position. Each byte of the map points to a tile in the Tile Data.
Critical Problem:If the VRAM is completely empty (all zeros), the PPU will render pixels of index 0 (which corresponds to the lightest color in the palette). With the Python debug palette (Step 0256), index 0 is mapped to green/white, which explains why we see a completely green screen even when the LCD is on.
VRAM Diagnostics:By calculating the sum of bytes of VRAM (using sampling every 16 bytes so as not to kill performance), we can determine:
- Sum = 0:VRAM is empty. The game has not copied graphics. This indicates a CPU/DMA problem (the game is not running the code that copies tiles from ROM to VRAM).
- Sum > 0:There is data in VRAM. If the screen is still green, the problem is with the PPU (it is not reading the tiles correctly from VRAM) or with the tile mapping (Tile Map points to empty tiles).
Fountain:Pan Docs - VRAM, Tile Data, Tile Maps
Implementation
Changed the GPS monitor in `src/viboy.py` to add a VRAM sum calculation after the `[VIDEO]` and `[SPRITE]` logs:
Modification in `src/viboy.py` (GPS Monitor)
Added code to calculate the sum of VRAM bytes using sampling every 16 bytes:
# --- Step 0258: VRAM CHECKSUM ---
# Read massive samples to see if there is life
#Note: This is slow, but only happens 1 time per second
vram_sum = 0
# Fast sampling: read every 16 bytes to not kill performance
for addr in range(0x8000, 0xA000, 16):
vram_sum += self._mmu.read(addr)
logger.info(f"[MEMORY] VRAM_SUM: {vram_sum} (If 0, no graphics)")
# -------------------------------------------------
This code was added to both the C++ block and the Python (fallback) block of the GPS monitor, just after the `[VIDEO]` and `[SPRITE]` logs.
Design Decisions
- Sampling every 16 bytes:Choosing to read every 16 bytes instead of every byte so as not to kill performance. Sampling is sufficient to detect whether the VRAM is completely empty (sum = 0) or contains data (sum > 0).
- Execution frequency:The diagnostic runs only once per second (every 60 frames), just like the rest of the GPS monitor, so as not to impact performance.
- Clear log:A clear log message is used that explicitly states that if the sum is 0, there are no graphics in VRAM.
Affected Files
src/viboy.py- Modified GPS monitor (Step 0240) to add VRAM sum calculation (Step 0258).
Tests and Verification
Diagnostic Validation:
- Execution:Execute
python main.py roms/pkmn.gb(or any ROM with LCD on). - Log observation:Search the log for the message
[MEMORY] VRAM_SUM:every second. - Interpretation:
- If X = 0:VRAM is empty. The game has not copied graphics. This indicates a CPU/DMA problem (the game is not running the code that copies tiles from ROM to VRAM).
- If X > 0:There is data in VRAM. If the screen is still green, the problem is with the PPU (it is not reading the tiles correctly from VRAM) or with the tile mapping (Tile Map points to empty tiles).
Test Command:
python main.py roms/pkmn.gb
Expected Result:The log should show[MEMORY] VRAM_SUM:every second, where X is a number that indicates whether there is data in VRAM.
Python Module Validation:The code runs in pure Python, without the need to recompile C++ modules. Diagnostics integrate directly into existing GPS monitor.
Sources consulted
- Bread Docs:Video Display
- Bread Docs:Tile Data
- Bread Docs:Tile Maps
Educational Integrity
What I Understand Now
- Diagnosis by Layers:By adding diagnostics at different layers (palette in Step 0256/0257, VRAM in Step 0258), we can isolate the problem: if VRAM is empty, the problem is in the CPU/DMA; If the VRAM contains data but the screen is still green, the problem is with the PPU or the tile mapping.
- Empty VRAM:If the VRAM is completely empty (all zeros), the PPU will render pixels of index 0 (which corresponds to the lightest color in the palette). With Python's debug palette, index 0 is mapped to green/white, which explains why we see a completely green screen.
- Memory Sampling:To diagnose large ranges of memory without killing performance, we can use sampling (reading every N bytes) instead of reading all bytes. This is enough to detect whether the memory is completely empty or contains data.
What remains to be confirmed
- Real VRAM Status:Run the diagnostic with Pokémon Red (or any ROM with LCD on) and check the value of `VRAM_SUM`. If it is 0, we confirm that the VRAM is empty and the problem is with the CPU/DMA.
- Load Timing:If the VRAM is empty, we need to investigate why the game is not copying the tiles from the ROM to the VRAM. This can be a timing issue (the game waits for something to happen before copying) or a DMA issue (the game tries to use DMA but it's not working).
- Reading Tiles:If the VRAM contains data but the screen is still green, we must investigate why the PPU is not correctly reading the tiles from VRAM or why the Tile Map points to empty tiles.
Hypotheses and Assumptions
Main Hypothesis:With forced palette in C++ (Step 0257) and Python (Step 0256), if the screen remains green even with games that have the LCD on (such as Pokémon Red, `LCDC:E3`), the only logical explanation left is that the VRAM is full of zeros. If the VRAM is all 0, the PPU draws "Color 0" perfectly, which is... green.
Assumption:We assume that the VRAM diagnostic (sum of bytes) is sufficient to detect whether the VRAM is completely empty or contains data. If the sum is 0, VRAM is empty; if the sum is > 0, there is data in VRAM.
Next Steps
- [ ] Execute
python main.py roms/pkmn.gb(Use Pokémon or Mario, which we know turn on the LCD!) - [ ] Observe the log and search
[MEMORY] VRAM_SUM:every second. - [ ] If X = 0:
- Confirm that VRAM is empty. The game has not copied graphics.
- Investigate why the game is not running the code that copies tiles from ROM to VRAM (CPU/DMA issue).
- Verify that the game is running correctly (PC is moving forward, not in an infinite loop).
- Verify that DMA is working (if the game tries to use DMA to copy tiles).
- [ ] If X > 0:
- Confirm that there is data in VRAM.
- If the screen is still green, investigate why the PPU is not correctly reading the tiles from VRAM.
- Verify that the Tile Map points to valid tiles (not empty tiles).
- Verify that the PPU is correctly decoding the tiles from VRAM.