This project is educational and Open Source. No code is copied from other emulators. Implementation based solely on technical documentation and permitted tests.
Coordinate Adjustment: Logo Centering
Summary
Analysis of Step 0206 revealed a geometric calculation error in the position of the logo. The tilemap was placed at address `0x9A00` (Row 16), which placed the logo at the bottom edge of the screen, outside the log sampling area and difficult to see. We corrected the tilemap address to `0x9904` (Row 8, Column 4), placing the logo in the absolute center of the screen, making it visible and detectable by the logs.
Hardware Concept: The Tiles Map (Tilemap)
The Game Boy has a 20x18 tile (160x144 pixels) screen. The background map (`0x9800`) is a 32x32 tile grid that extends beyond the visible limits of the screen, allowing scrolling and parallax effects.
Calculation of addresses in the Tilemap:
- Tilemap Base:`0x9800` (background map start)
- Row 0:`0x9800` (first 32 bytes, tiles 0-31)
- Row 8 (Center Y):`0x9800 + (8 × 32) = 0x9900` (vertical center of screen)
- Column 4 (Center X approx):`0x9900 + 4 = 0x9904` (approximate horizontal center)
- Row 16:`0x9800 + (16 × 32) = 0x9A00` (very close to the bottom edge, Y=128px)
The error in Step 0206:The address was incorrectly calculated as `0x9A00`, which corresponds to Row 16. This places the logo at pixels Y=128 to 136, very close to the bottom edge of the screen (144px). In addition, the log system samples the pixels in the center of the screen (approximately Row 9), so when the logo was in Row 16, the log read Row 9 (empty) and showed `show indices: [0, 0, 0, 0, 0, 0]`.
The correction:When writing the tilemap to `0x9904` (Row 8, Column 4), the logo appears centered vertically and horizontally on the screen, making it visible to the user and detectable by the logs.
Fountain:Pan Docs - "Tile Map", "Background Map"
Implementation
Fixed the calculation of the tilemap address in the `MMU::MMU()` constructor to place the logo in the center of the screen.
Modification in MMU.cpp
Insrc/core/cpp/MMU.cpp, inside the constructorMMU::MMU(), we change the destination address of the tilemap from `0x9A00` to `0x9904`:
// 2. Load Logo Tilemap into VRAM Map (0x9904 - Row 8, Column 4, centered)
// CORRECTION Step 0207: Use 0x9904 to center on Row 8, Column 4.
// Before it was at 0x9A00 (Row 16), too low and outside the visible area.
// Calculation: 0x9800 (base) + (8 * 32) = 0x9900 (Row 8) + 4 = 0x9904 (horizontal centering)
// 32 bytes = 1 full row of the tile map (32 horizontal tiles)
for (size_t i = 0; i< sizeof(VIBOY_LOGO_MAP); ++i) {
memory_[0x9904 + i] = VIBOY_LOGO_MAP[i];
}
Calculation explanation:
- Tilemap base: `0x9800`
- Row 8: `0x9800 + (8 × 32) = 0x9900` (each row has 32 tiles = 32 bytes)
- Column 4: `0x9900 + 4 = 0x9904` (approximate horizontal centering, considering that the logo is 6 tiles wide)
Affected Files
src/core/cpp/MMU.cpp- Correction of the logo tilemap address (lines 113-120)
Tests and Verification
The verification was carried out by running the emulator and visual observation of the logo:
- Command executed:
python main.py roms/tetris.gb - Expected result:The "VIBOY COLOR" logo appears centered on the screen
- Logs:The log
[Renderer] Frame #0should now show non-zero indices (ex:[3, 3, 2, 0...]), confirming that the PPU is reading the logo data
Compiled C++ module validation:The C++ module was recompiled using.\rebuild_cpp.ps1to apply the changes.
Sources consulted
- Bread Docs:Tile Map
- Bread Docs:Video Display
Educational Integrity
What I Understand Now
- Address calculation in Tilemap:The tilemap is a grid of 32x32 tiles. Each row occupies 32 bytes (32 tiles × 1 byte per tile). To calculate the address of a specific position: `base + (row × 32) + column`.
- Screen Coordinates vs. tilemap coordinates:The visible screen is 20x18 tiles (160x144 pixels), but the tilemap is 32x32 tiles. The center of the visible screen corresponds approximately to Row 8, Column 4 of the tilemap.
- Geometric debugging:When a graphical element does not appear where expected, it is important to check the memory address calculations, not just the rendering logic.
What remains to be confirmed
- Background scroll:The SCX and SCY registers allow the tilemap to be moved. We need to verify that the logo is still visible when the game scrolls.
- Layer priority:If the game activates sprites or window, we need to verify that the logo is not hidden incorrectly.
Hypotheses and Assumptions
We assume that the logo must be in the center of the screen to be visible. If the game scrolls or changes LCDC settings, the logo may move or disappear. This is expected and correct based on hardware behavior.
Next Steps
- [ ] Verify that the logo is visible in different ROMs
- [ ] Check the behavior of the logo when the game applies scroll (SCX/SCY)
- [ ] Optimize logo position if necessary for different window resolutions
- [ ] Implement a more robust logging system that samples multiple areas of the screen