本文介绍了 NES(FC、红白机、小霸王)中一些名词或者术语,主要与 PPU 有关。
Tile
8x8 像素图像。每像素 2 比特, 共 16 字节大小。每个像素可以使用 4 种颜色。
Sprite
表示屏幕上可以移动的图片。有两种大小:8x8(WxH)和 8x16(WxH)。
Pattern Table
存储 Tile 像素数据,可以把 Pattern Table 看作是切割并重新组织的图片资源。Tile 每个像素占 2 比特,像素数据按比特顺序划分为两个平面分别存储,每个平面 8 字节。每个 Tile 的 16 字节数据中,低 8 个字节为低位平面,高 8 个字节为高位平面。
一个 Pattern Table 的最大大小为 4 KB,即最多可以存储 256 个 Tile。Pattern Table 通常位于卡带中。
Name Table
Name Table 中存储的是 Tile 索引,每个 Name Table 可以包含 32x30 (WxH)个 Tile 索引,每个 Tile 索引使用 1 字节表示,共 960 字节。由于每个 Tile 为 8x8 的像素图像,因此 Name Table 可以表示一张 256x240 的图片,刚好为全屏图片的大小。
Name Table 通常位于 VRAM 中,与 Attribute Table 一起存储,主要用作背景图渲染。
参考:https://www.nesdev.org/wiki/PPU_nametables
Character Memory
用于存储 Pattern Table 的内存区,位于卡带上,映射到 PPU 地址空间 $0000 ~ $1fff 范围上。PPU 最多能够寻址 8 KB 的 Character 内存,因此 Character 内存是支持映射的。
Attribute Table
共 64 字节。Name Table 中的 Tile 按 2x2 的格子,可以分为 16x15 个块。每个块共享一个属性字节,属性占 2 比特,表示子调色板编号,属性字节中的比特分配方案如下:
+------+------+
| 0..1 | 2..3 |
+------+------+
| 4..5 | 6..7 |
+------+------+
Attribute Table 通常位于 VRAM 中,与 Name Table 一起存储,主要用作背景图渲染时选用子调色板。
参考:https://www.nesdev.org/wiki/PPU_attribute_tables
OAM
对象属性存储区,位于 PPU 内,共 256 字节,用于存储对象的属性。对象有 4 个属性字段,每个属性字段 1 字节,共可以存储 64 个对象的信息。对象属性用于控制 Sprite 渲染,每个字节意义如下:
字节序号 | 含义 |
---|---|
0 | Y 坐标 |
1 | Tile 索引 |
2 | 属性 |
3 | X 坐标 |
参考:https://www.nesdev.org/wiki/PPU_OAM
WRAM
通常意义上的 RAM,位于主板上,共 2 KB,用于存储 CPU 要使用的数据。
VRAM
视频内存,位于主板上,用于存储 PPU 要使用的数据(Name Table 和 Attribute Table), 共 2 KB。VRAM 一般位于 PPU 地址空间 0x2000 ~ 0x3f00 处。
调色板
调色板一词在 NES 世界里可能有两种含义。
第一种是通常意义上的调色板,用索引表示真实的 RGB 颜色。NES 中,这种调色板共 64 色。
第二种实际上是指“调色板 RAM” - 一块位于 PPU 地址空间 0x3f00 ~ 03f1f 共 32 字节的 RAM,这块 RAM 中存储的是颜色的索引。调色板 RAM 按用途,可分为两组。一组用于背景渲染,位于 PPU 地址空间 0x3f00 ~ 0x3f0f;另一组用于 Sprite 渲染,位于 PPU 地址空间 0x3f10 ~ 0x3f1f。每组子调色板又分出了 4 个子调色板,共计 8 个子调色板。
子调色板
子调色板只包含 4 种颜色,共 8 个。每组子调色板理论上可以表示 4x4 共 16 种颜色,但由于每个调色板的 0 号位置用于表示背景色(背景色定义在 $3f00),因此每组子调色板只能表示 13 种颜色。
参考:https://www.nesdev.org/wiki/PPU_palettes
MMC
Memory Management Chip(内存管理芯片)的简称。是一类特殊芯片,用于把 CPU 或 PPU 的地址映射到外部存储器的地址空间中,实际结果相当于扩大了地址空间,使得 CPU 或 PPU 可以使用更大的内存。例如,CPU 访问地址空间 $8000 ~ $ffff 内的内存时,MMC 可以把这个范围内的地址映射到外部存储器的 $020000 ~ $027fff 范围内。原本主板上 $8000 ~ $ffff 这个范围内没有任何存储设备(参考 nesdev CPU Memory Map),是读取不到内容的,现在就可以了。通过将 $8000 ~ $ffff 范围内的地址映射到外部存储器不同的位置上,我们就能访问更大内存。MMC 一般是有状态的,即提供控制寄存器,以便控制 MMC 让它把地址映射到不同的范围。切换映射范围的过程叫“换页”(Bank Swiching)。
Bank
内存页。MMC 在切换映射范围时,通常是以固定大小整体映射。例如,以 32 KB 大小为单位按公式 n * 32768 + (addr % 32768)
对 $8000 ~ $ffff 范围的地址进行映射。这个示例中,32 KB 大小的内存块就是一个 Bank。可以看出,外部存储器的容量必须为 Bank 容量的整数倍。常见的 Bank 大小有 8 KB、16 KB 和 32 KB。
Bank Switching
通过配制 MMC,MMC 可以把同一个范围内的地址映射到外部存储器地址空间中不同的范围上,这个切换过程就叫 Bank Switching。
Mapper
Mapper 是 NES 模拟器中的概念,是对 MMC 及卡带本身硬件行为的抽象。