338. Incrementar la dirección vram horizontal

Incrementa la componente horizontal de la dirección de renderizado actual v.

Lección 338 de 356 · tests/chapter_13_scrolling/test_338_increment_horizontal_vram_addr.py

Archivo a actualizar

emulator/ppu/ppu.py

Referencias

https://www.nesdev.org/wiki/PPU_scrolling#Coarse_X_increment
https://www.nesdev.org/wiki/PPU_scrolling#During_rendering

Por qué existe este paso

Durante las obtenciones de fondo, la PPU avanza de una columna de tiles de 8 píxeles cada vez. La dirección de renderizado actual v almacena tanto la columna de tiles de coarse X como la selección horizontal de nametable:

v: yyy NN YYYYY XXXXX
                   |
                   +-- coarse X, bits 0-4

horizontal nametable selection: bit 10

Comportamiento normal

coarse X 0  -> 1
coarse X 30 -> 31

Comportamiento en la frontera

coarse X 31, horizontal nametable 0
    -> coarse X 0, horizontal nametable 1

coarse X 31, horizontal nametable 1
    -> coarse X 0, horizontal nametable 0

El conmutador de frontera mueve el renderizado a través de la frontera lógica izquierda/derecha entre nametables. PpuBus aplica después el mirroring del cartucho cuando se leen esas direcciones lógicas.

Invariantes importantes

  • solo pueden cambiar coarse X y, al hacer wrap, el nametable horizontal
  • coarse Y, fine Y y el nametable vertical permanecen sin cambios
  • fine X es independiente y no es un argumento de esta operación
  • la función auxiliar devuelve un valor y no muta la PPU

Error común

Esto no mueve un píxel. Avanza una columna de tiles, que representa 8 píxeles. Fine X proporciona el desfase independiente de 0-7 píxeles dentro del primer tile.

Fuera del alcance

  • llamar a la función auxiliar desde PPU.step()
  • elegir los dots de obtención de fondo
  • copiar los bits horizontales de t en v
  • incrementos verticales
  • renderizado de framebuffer

Implementación de ejemplo completa

# emulator/ppu/ppu.py

# --- NEW BLOCK: PURE HORIZONTAL v INCREMENT ---
def increment_horizontal_vram_addr(vram_addr: int) -> int:
    # Advance v by one background tile column.
    coarse_x = vram_addr & 0b1_1111

    if coarse_x == 31:
        vram_addr &= ~0b1_1111
        vram_addr ^= 0b100_0000_0000
        return vram_addr

    return vram_addr + 1

Ejecutar esta lección

uv run pytest tests/chapter_13_scrolling/test_338_increment_horizontal_vram_addr.py -v