344. Decrementar la dirección horizontal de vram
Revertir un incremento de fetch de fondo horizontal sobre una dirección copiada.
Lección 344 de 356 · tests/chapter_13_scrolling/test_344_decrement_horizontal_vram_addr.py
Archivo a actualizar
emulator/ppu/ppu.pyReferencias
https://www.nesdev.org/wiki/PPU_scrolling#DetailsPor qué existe este paso
Los dots 321-336 precargan los dos primeros tiles de fondo para el siguiente scanline. Cada fetch de tile avanza la v horizontal, así que en el dot 1 la dirección ya está dos columnas de tiles por delante de los píxeles almacenados en los registros de desplazamiento de fondo:
intended visible coarse X = 5
prefetch tile 5 -> v advances to 6
prefetch tile 6 -> v advances to 7
dot 1:
shifters begin displaying tile 5
v already contains coarse X 7El registro de scanline posterior copiará v y rebobinará esa copia dos veces
7 -> 6 -> 5Este auxiliar revierte un incremento. No es una operación de la PPU temporizada, y nunca debe mover hacia atrás el PPU.vram_addr real.
Comportamiento normal
coarse X 31 -> 30
coarse X 7 -> 6
coarse X 1 -> 0Comportamiento en el límite
coarse X 0 -> 31 and toggle horizontal nametableInvariantes importantes
- solo pueden cambiar la X gruesa y, al desbordarse, la nametable horizontal
- cualquier campo vertical o no relacionado permanece sin cambios
- el decremento es el inverso del incremento horizontal probado
- la función es pura y no modifica la PPU
Concepto erróneo común
La PPU de la NES no realiza este decremento durante el renderizado. Existe solo para traducir la dirección de fetch adelantada respecto a la visualización en una dirección de viewport visible para el renderizador de alto nivel existente.
Fuera de alcance
- invocar el auxiliar desde PPU.step()
- registrar 240 posiciones de scanline
- cambios en el framebuffer o en la máscara de opacidad
Implementación de ejemplo completa
# emulator/ppu/ppu.py
# --- NEW BLOCK: REVERSE ONE HORIZONTAL FETCH INCREMENT ---
def decrement_horizontal_vram_addr(vram_addr: int) -> int:
coarse_x = vram_addr & 0b1_1111
if coarse_x == 0:
vram_addr = (
(vram_addr & ~0b1_1111)
| 0b1_1111
)
vram_addr ^= 0b000_01_00000_00000
return vram_addr
return vram_addr - 1Ejecutar esta lección
uv run pytest tests/chapter_13_scrolling/test_344_decrement_horizontal_vram_addr.py -v