This project is educational and Open Source. No code is copied from other emulators. Implementation based solely on technical documentation and permitted tests.
Investigating Framebuffer Content and Tilemap-Tiles Correspondence
Summary
Extensive investigation of the content of the framebuffer when there are real tiles (not checkerboard) and verification of the correspondence between the tilemap and the tiles in VRAM. Diagnostic logs were implemented to verify what the framebuffer contains when there are real tiles, if the tilemap points to tiles with data in VRAM, if the tiles are rendered completely, and if there are problems with scroll or offset. The goal is to identify why tiles appear fuzzy or half-way when they should be displayed correctly.
Hardware Concept
Framebuffer
The framebuffer contains color indices (0-3) for each pixel on the screen. Size: 160×144 = 23,040 pixels. Each pixel has a color index that is mapped to RGB using the BGP palette. The framebuffer is generated line by line during the rendering of each scanline.
Tilemap
The tilemap is a 32x32 tile map that points to tiles in VRAM. Each tilemap entry contains a tile ID (0-255). The tile ID is used to calculate the address of the tile in VRAM based on addressing (signed or unsigned). The tilemap is read during rendering to determine which tile should be drawn at each screen position.
Scroll
SCX (Scroll X) scrolls the background horizontally and SCY (Scroll Y) scrolls the background vertically. The scroll is applied when calculating the position in the tilemap. Scrolling can cause only part of a tile to be visible, which requires correctly calculating the offset within the tile.
Fountain:Pan Docs - "Background", "Tile Map", "Scroll Registers (SCX/SCY)"
Implementation
4 blocks of diagnostic logs were implemented inPPU::render_scanline()to investigate the content of the framebuffer and the tilemap-tiles correspondence when there are real tiles.
1. Verification of Framebuffer Content with Real Tiles
Added logs that verify what the framebuffer contains when there are real tiles (not checkerboard). The logs are activated whenvram_has_tilesistrueand are executed on line 72 (center line of the screen).
- Index distribution:Count how many pixels have each color index (0, 1, 2, 3) on line 72
- Specific pixels:Check some specific pixels (x=0, 40, 80, 120, 159) to see what indices they contain
- Tag:
[PPU-FRAMEBUFFER-CONTENT]
2. Tilemap-Tiles Correspondence Verification
Added logs that check if the tilemap points to tiles with data in VRAM. The logs check the first 20 visible tiles on line 72 and determine if each tile has data or is empty.
- Tiles with data:Counts how many visible tiles have data in VRAM
- Empty tiles:Counts how many visible tiles are empty (all lines = 0x00)
- Invalid tiles:Counts how many tiles point to addresses outside of VRAM
- Tag:
[PPU-TILEMAP-TILES]
3. Full Tiles Rendering Verification
Added logs that check if the tiles are rendered completely (all lines). The logs check a specific tile (tile at position (0, 0) of the tilemap) and compare the expected pixels with the pixels rendered in the framebuffer.
- Rendered pixels:Counts how many pixels of the tile were rendered correctly
- Expected pixels:It should be 8 (one full tile on one line)
- Tag:
[PPU-TILE-RENDER-COMPLETE]
4. Detailed Scroll and Offset Check
Added logs that verify that the scroll and offset are calculated correctly. The logs check some specific pixels and show how the position in the scrolling tilemap is calculated.
- Position in tilemap:Shows MapX and MapY calculated with scroll
- Tile position:Shows TileX, TileY and the offset inside the tile (PixelInTileX, PixelInTileY)
- Tag:
[PPU-SCROLL-OFFSET]
Components created/modified
src/core/cpp/PPU.cpp: Added 4 diagnostic log blocks inrender_scanline()
Affected Files
src/core/cpp/PPU.cpp- Added step 0338 diagnostic logs
Tests and Verification
Diagnostic logs will be activated automatically when real tiles are detected in VRAM. To verify the logs, the tests must be run with the 5 ROMs for 2.5 minutes each:
- Test commands:
timeout 150 python3 main.py roms/pkmn.gb 2>&1 | tee logs/test_pkmn_step0338.log timeout 150 python3 main.py roms/tetris.gb 2>&1 | tee logs/test_tetris_step0338.log timeout 150 python3 main.py roms/mario.gbc 2>&1 | tee logs/test_mario_step0338.log timeout 150 python3 main.py roms/pkmn-amarillo.gb 2>&1 | tee logs/test_pkmn_amarillo_step0338.log timeout 150 python3 main.py roms/Oro.gbc 2>&1 | tee logs/test_oro_step0338.log - Log analysis:
# Verify framebuffer content with real tiles grep "\[PPU-FRAMEBUFFER-CONTENT\]" logs/test_*_step0338.log | head -n 30 # Check tilemap-tiles correspondence grep "\[PPU-TILEMAP-TILES\]" logs/test_*_step0338.log | head -n 30 # Check complete rendering of tiles grep "\[PPU-TILE-RENDER-COMPLETE\]" logs/test_*_step0338.log | head -n 30 # Check scroll and offset grep "\[PPU-SCROLL-OFFSET\]" logs/test_*_step0338.log | head -n 30 - Native Validation:C++ Compiled Module Validation
Sources consulted
- Bread Docs:Background, Tile Map, Scroll Registers
Educational Integrity
What I Understand Now
- Framebuffer:Contains color indices (0-3) for each pixel. It is generated line by line during rendering.
- Tilemap:32x32 tile map pointing to tiles in VRAM. Each entry contains a tile ID that is used to calculate the address of the tile.
- Scroll:SCX and SCY shift the background. Scrolling is applied when calculating the position in the tilemap and can cause only part of a tile to be visible.
What remains to be confirmed
- Framebuffer content:Check what indexes the framebuffer contains when there are real tiles. Are there indices 1 or 2 (gray) in addition to 0 and 3?
- tilemap-tiles correspondence:Check if the tilemap points to tiles with data in VRAM. Are there empty or invalid tiles?
- Full render:Check if the tiles are rendered completely. Are all the lines of the tile rendered?
- Scroll and offset:Verify that the scroll and offset are calculated correctly. Are there problems with the scroll wrap-around?
Hypotheses and Assumptions
Diagnostic logs will be activated when real tiles are detected in VRAM. If the tiles appear fuzzy or half-finished, the logs should reveal if the problem is:
- The contents of the framebuffer (incorrect indexes)
- The tilemap-tiles correspondence (empty or invalid tiles)
- Full rendering (partially rendered tiles)
- The scroll or offset (incorrect calculations)
Next Steps
- [ ] Run full tests with the 5 ROMs (2.5 minutes each)
- [ ] Analyze the logs to identify the cause of the fuzzy tools
- [ ] If the cause is identified: Implement correction in Step 0339
- [ ] If the problem persists: Deeper analysis and workaround in Step 0339