257. Decodificar la tabla de patrones

Implementa la decodificación completa de la tabla de patrones.

Lección 257 de 356 · tests/chapter_03_ppu_memory_and_graphics_data/test_257_decode_pattern_table.py

Referencia

https://www.nesdev.org/wiki/PPU_pattern_tables

Archivo a modificar

emulator/ppu/chr_decoder.py

Función a implementar

decode_pattern_table(pattern_table_bytes: bytes) -> PatternTable

Constantes a añadir

PATTERN_TABLE_SIZE = 0x1000
CHR_TILE_SIZE = 16
PATTERN_TABLE_TILE_COUNT = 256

¿Qué es una tabla de patrones? Una tabla de patrones es un bloque de datos gráficos de CHR que contiene 256 tiles.

Matemáticas básicas

one CHR tile      = 16 bytes
one pattern table = 4096 bytes = $1000
4096 / 16         = 256 tiles

La PPU de la NES tiene dos rangos de direcciones de tabla de patrones

$0000-$0FFF -> pattern table 0
$1000-$1FFF -> pattern table 1

Este paso solo decodifica una tabla de patrones de 4096 bytes en 256 tiles ya decodificados. Todavía no dibuja una imagen.

Ejemplo de implementación sugerida

PATTERN_TABLE_SIZE = 0x1000
CHR_TILE_SIZE = 16
PATTERN_TABLE_TILE_COUNT = 256

PatternTile = list[list[int]]
PatternTable = list[PatternTile]

def decode_pattern_table(pattern_table_bytes: bytes) -> PatternTable:
    if len(pattern_table_bytes) != PATTERN_TABLE_SIZE:
        raise ValueError("Pattern table must be 4096 bytes")

    tiles = []

    for tile_index in range(PATTERN_TABLE_TILE_COUNT):
        start = tile_index * CHR_TILE_SIZE
        end = start + CHR_TILE_SIZE
        tiles.append(decode_chr_tile(pattern_table_bytes[start:end]))

    return tiles

Fuera de alcance

  • organizar los tiles en una cuadrícula de depuración de 128x128
  • salida en formato PNG/imagen
  • colores RGB/paleta de la NES
  • renderizado de fondo de nametable
  • temporización de la PPU

Ejecutar esta lección

uv run pytest tests/chapter_03_ppu_memory_and_graphics_data/test_257_decode_pattern_table.py -v