⚠️ Clean-Room / Educational

This project is educational and Open Source. No code is copied from other emulators. Implementation based solely on technical documentation and permitted tests.

Step 0255 - OAM Inspector and Palettes

Date:2025-12-23 StepID:0255 State: draft

Summary

This Step extends the GPS monitor (Step 0240) insrc/viboy.pyto include real-time inspection of pallet records (BGP, OBP0, OBP1) and first OAM (Object Attribute Memory) sprites. The objective is to diagnose why the screen appears green/white when it should be showing sprites, checking if the problem it's either in the data (empty OAM or DMA not working) or in the rendering (bad palettes).

Hardware Concept

On the Game Boy, sprites (objects) are stored in the OAM (Object Attribute Memory), located in the range0xFE00-0xFE9F(160 bytes = 40 sprites × 4 bytes). Each sprite occupies 4 consecutive bytes:

  • Byte 0 (Y): Vertical position (0-255, but Y=0 or Y≥160 hides the sprite)
  • Byte 1 (X): Horizontal position (0-255, but X=0 or X≥168 hides the sprite)
  • Byte 2 (Tile): Tile index in VRAM (0-255)
  • Byte 3 (Attributes): Attributes (palette, X/Y flip, priority, etc.)

Palette registers control how tile colors are translated:

  • BGP (0xFF47): Background palette (4 colors: 00, 01, 10, 11)
  • OBP0 (0xFF48): Sprite Palette (channel 0, colors 1-3; color 0 is transparent)
  • OBP1 (0xFF49): Sprite Palette (channel 1, colors 1-3; color 0 is transparent)

Critical problem:YeahOBP0eitherOBP1are in0x00either0xFF(all white or all transparent), the sprites will be invisible even if they are correctly rendered. If the OAM is empty (all zeros), the DMA is not working or the game hasn't initialized the sprites yet.

Fountain:Pan Docs - OAM (Object Attribute Memory), Sprite Attributes, Palette Registers

Implementation

Changed GPS monitor block insrc/viboy.py(lines 944-976) to add reading palette registers and the first 2 sprites from the OAM. The inspection is carried out every second (60 frames) along with the standard GPS report.

Modified components

  • src/viboy.py: Extended GPS block (Step 0240) with OAM and paddle inspection

Inspection logic

The code reads:

  • Pallets: 0xFF47(BGP),0xFF48(OBP0),0xFF49(OBP1)
  • Sprite 0: 0xFE00-0xFE03(Y, X, Tile, Attributes)
  • Sprite 1: 0xFE04-0xFE07(Y, X, Tile, Attributes)

Values ​​are recorded usinglogger.info()with hexadecimal format to facilitate the diagnosis. The format is:

[VIDEO] BGP:XX OBP0:XX OBP1:XX | LCDC:XX
[SPRITE 0] Y:XX X:XX T:XX A:XX
[SPRITE 1] Y:XX X:XX T:XX A:XX

Diagnostic scenarios:

  • Empty OAM (Y:00 X:00 T:00):DMA is not copying data or memory is cleared
  • OAM with valid data (Y:10 X:08 T:5A):The sprites are present. If you don't see them, the problem is with C++ rendering or the palettes
  • Palettes at 0x00 or 0xFF:The sprites will be invisible (white or transparent)

Affected Files

  • src/viboy.py- Extended GPS monitor with OAM and pallet inspection (Step 0255)

Tests and Verification

This Step does not require unit tests, since it is a real-time diagnostic tool. Validation is carried out by running the emulator and observing the logs:

  • Command: python main.py roms/pkmn.gb(or any ROM with sprites)
  • Observation:The logs[VIDEO]and[SPRITE]appear every second on the console
  • Validation:Verify that OAM and palette values ​​are consistent with the game state

Note:This Step does not modify the C++ core, it only adds Python instrumentation for diagnosis. No C++ recompilation required.

Sources consulted

Educational Integrity

What I Understand Now

  • OAM Structure:Each sprite occupies 4 consecutive bytes (Y, X, Tile, Attributes) in the range 0xFE00-0xFE9F
  • Palette Registers:BGP controls the background, OBP0/OBP1 controls the sprites. If they are at 0x00 or 0xFF, the sprites will be invisible
  • Diagnosis:OAM and palette inspection distinguishes between data issues (empty OAM) and rendering issues (bad palettes)

What remains to be confirmed

  • DMA Timing:Verify that the DMA is executed frequently and the OAM is not deleted between frames
  • Sprite Visibility:Confirm that sprites with Y=0 or X=0 are hidden correctly in the render
  • Palette Mapping:Verify that C++ rendering correctly respects OBP0/OBP1 values

Hypotheses and Assumptions

Main hypothesis:If the screen appears green/white with sprites implemented, the most likely problem is that the OBP0/OBP1 palettes are at 0x00 (all transparent) or that the OAM is empty (DMA not working or game still initializing).

This diagnostic tool will allow us to confirm or refute this hypothesis by observing the values real at runtime.

Next Steps

  • [ ] Run the emulator with a ROM (Pokémon Red, Mario) and observe the OAM and palette logs
  • [ ] Analyze the reported values ​​to determine if the problem is data (empty OAM) or rendering (bad palettes)
  • [ ] If OAM is empty: Investigate the DMA and verify that it runs frequently
  • [ ] If OAM has data but invisible sprites: Check C++ rendering and palette mapping
  • [ ] Correct the identified issue and validate that the sprites are displayed correctly