338. 递增水平 VRAM 地址
递增当前渲染地址 v 的水平分量。
第 338 / 356 · tests/chapter_13_scrolling/test_338_increment_horizontal_vram_addr.py
待更新文件
emulator/ppu/ppu.py参考
https://www.nesdev.org/wiki/PPU_scrolling#Coarse_X_increment
https://www.nesdev.org/wiki/PPU_scrolling#During_rendering此步骤存在的原因
在背景抓取过程中,PPU 每次前进一个 8 像素的图块列。当前渲染地址 v 同时存储了粗 X 图块列和水平名称表选择:
v: yyy NN YYYYY XXXXX
|
+-- coarse X, bits 0-4
horizontal nametable selection: bit 10正常行为
coarse X 0 -> 1
coarse X 30 -> 31边界行为
coarse X 31, horizontal nametable 0
-> coarse X 0, horizontal nametable 1
coarse X 31, horizontal nametable 1
-> coarse X 0, horizontal nametable 0该边界切换会使渲染跨越逻辑上的左右名称表接缝。当这些逻辑地址被读取时,PpuBus 随后会应用卡带镜像。
重要不变量
- 只有粗 X,以及在环绕时的水平名称表,才可能改变
- 粗 Y、细 Y 和垂直名称表保持不变
- 细 X 是独立的,不是该操作的参数
- 该辅助函数返回一个值,不会修改 PPU
常见误解
这并不是移动一个像素。它前进的是一个图块列,代表 8 个像素。细 X 提供了第一个图块内部单独的 0-7 像素偏移。
范围之外
- 从 PPU.step() 调用该辅助函数
- 选择背景抓取点
- 把水平 t 位复制到 v
- 垂直递增
- 帧缓冲区渲染
完整示例实现
# 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运行本课
uv run pytest tests/chapter_13_scrolling/test_338_increment_horizontal_vram_addr.py -v