NES 的 CPU 型号为 理光(Ricoh)2A03 ,基于当时流行的 8 位 CPU MOS Technology 6502,能以 1.79 MHz 的速度运行(或 PAL 系统上为 1.66 MHz)。
相关背景
70 年代末到 80 年代初的 CPU 市场可谓是百花齐放。
由剑桥计算历史中心(英国)提供的 70 年代末计算机全景。如果某公司想制造一款便宜的微型电脑,它可以有以下选项:
- Intel 8080:一款流行的 CPU,应用于第一台"个人"电脑 Altair。 它有 8 位的数据总线和 16 位的地址总线。
- Zilog Z80:一款"非官方"版本的 8080 增强型处理器,较原版有更多的指令、寄存器和内部组件。 它售价更低且兼容 8080 程序 。 Amstrad 和 Sinclair(等公司)选择了这款CPU。
- Motorola 6800:另一款由摩托罗拉(Motorola)设计的 8 位 CPU,包含完全不同的指令集。 许多 DIY 电脑套件、合成器以及一体机使用了 6800。
如果这些选项还不够,市场上出现了一家名叫 MOS 的公司,他们基于 6800 设计了一款新的 CPU:6502。 虽然与其他 CPU 不兼容,但这款新的芯片造价 非常便宜 ,那些标志性的电脑制造商(Commodore、Tandy、Apple、Atari、Acorn 等)选择 6502 来生产他们的机器只是时间问题。
说回日本,彼时的任天堂正需要一款廉价但是开发者熟悉的 CPU,于是他们相中了 6502。 理光,他们的 CPU 供应商,也成功地制造了一款兼容 6502 的 CPU。
理光的许可之谜
关于理光 如何 设法克隆 6502,时至今日已无人能说清了。 有人认为 MOS 向理光授权了芯片设计,但此事存在诸多矛盾之处:
- 虽然理光和 MOS 的芯片都有相同的布局,但理光的版本包含被切断的总线(这禁用了某些功能)。 后面我会详细介绍这一点。
- 没有找到明确说明 MOS 向理光授权 6502 的文档。
- Nikkei Trendy 在 2008 年发表的一篇文章中说,理光从罗克韦尔(Rockwell)获得了许可,罗克韦尔是被授权的芯片制造商 。 然而,第二方能否向第三方提供IP仍有争议,更不用说得到MOS的批准了。
- 这不是任天堂第一次逃避知识产权,在日本 Ikegami Tsushinki 诉 Nintendo 一案中任天堂就被裁定不拥有原版《咚奇刚》(Donkey Kong)的源代码 。
被阉割的功能
理光 2A03 阉割了原先包含在 6502 中的 Binary-Coded Decimal (BCD)模式 。 BCD 将每个十进制数字编码为独立的 4 位二进制数。 6502 的字(word)大小为 8 bits(8 个二进制位)——这意味着每个字可以存储两个十进制数。
举个例子,十进制数字 42 可以表示为:
0010 1010(二进制)0100 0010(BCD 码)
我还可以举更多的例子,但是只需记住一个概念:BCD 对那些需要分别处理每个十进制数的应用很有用(例如,数字时钟)(译注:使用汇编表示数值字面量时,BCD 更好用)。 但是,使用BCD 编码需要更多存储空间:每个 8-bit 字最大只能表示到十进制数的 99。而传统二进制编码中,同样大小的字最大能表示到 255。
无论如何,理光故意切断了激活 BCD 模式的控制线,破坏了 BCD 模式。 这样做可能是为了避免向 MOS 支付版税,因为 BCD 是 MOS 的专利(美国针对集成电路布局的版权法直到 1984 年才颁布 )。
内存
理光 2A03 和 MOS 6502 都有 8 位数据总线 和 16 位地址总线,这使得它们能访问最大 64 KB 的内存。 那么,任天堂是如何填充地址空间的?
在一方面,主板上包含一块提供了2 KB 的静态 RAM(SRAM) 的芯片。 任天堂称这个区域为"工作内存"(Work RAM,WRAM),它可以用来存储:
- 用来处理游戏状态或查找信息的变量。
- 当 CPU 执行子例程时,用来临时保存寄存器值的"栈(Stack)"。
- 作为"缓冲区",CPU 可以利用它在两个位置之间复制大量数据。
其二,系统组件进行了内存映射(memory-mapped) ,这意味着需要使用内存地址来访问它们,这也占用了一部分 CPU 的地址空间。 因此 CPU 的内存空间包含了游戏卡带、WRAM、PPU、APU 和两个手柄 (不用害怕这些名词,因为它们在这篇文章都有解释)。
卡带 / 游戏数据
以防万一你不知道,NES 游戏以卡带(cartridge)的形式分发,而卡带总线又直接连接到 CPU。
任天堂连接卡带的方式使得 CPU 只能访问 49120 字节(约 49.97 KB)的卡带数据(cartridge data) 。 那么,"卡带数据"是什么意思? 呃,任何连接到这些总线的芯片都算,例如:
- 游戏程序所在的 程序 ROM(Program ROM)。 其中不包含任何图形数据,稍后你会在"图形"部分看到。 自然,不像其它芯片,这个是芯片是必须要有的。
- 用于扩展 WRAM 的 RAM 芯片。
- 用于保存存档的内含电池的 RAM 芯片
之所以有这么多不同的组合,是因为 CPU 不关心正在读取的组件类型,它只关心内存位置。 所以游戏开发商可以选择(或者设计出)一种适合他们游戏的可行布局。

带有重要部件标签的相同 PCB。 "锁定"芯片的含义会在"反盗版"部分解释。
例如,任天堂的《超级马里奥兄弟》使用了他们称之为NES-NROM-256的布局,包括32 KB的程序ROM和用于图形的8 KB"字符ROM"(我们将在"图形"部分了解更多)。 NES-NROM-256也被设计为最多容纳3 KB的额外WRAM,尽管游戏没有使用它。
超越限制
16 位地址总线的一大限制(影响第三代和第四代游戏主机)是其紧凑的地址空间。 如今,32 位计算机最大可以寻址 4 GB 的内存(而 64 位计算机可以奢侈地享用最大 16 EB 的内存)所以不再有人关心这个问题。但回到当时,NES 只有 64 KB 的地址空间,而且其中很大一部分被内存映射硬件占用(竞争对手避免了这个问题)。
所以,这是否意味着游戏开发商只能开发不超过 49.97 KB 限制的游戏? 绝对不是! 如果说我们能从历史中学到什么,那就是对挑战性的问题总有一个聪明的解决办法;而这个问题是被 Mapper 解决的。

映射器如何扩展 CPU 的寻址能力的简化表示图。 通过引入 Mapper,CPU 可以访问超过大程序 ROM 的额外内存组(地址组)。 不过游戏或程序现在有了在需要时手动切换 Bank 的新任务。

相同的配置但是没有安装映射器。 虽然简单且便宜,但是 CPU 只能访问有限数量的 Banks。
Mapper 是卡带中包含的额外芯片,位于内存芯片和主机地址线之间。 它的主要工作是扩展地址空间,以便开发人员可以安装更多的芯片。 这是通过 Bank (地址组) 切换实现的:内存地址被组织成 Bank,Mapper 提供开关(通过读写特定内存地址控制)在 Bank 之间切换。 现在,CPU 仍然看到相同数量的内存,所以游戏需要针对操作 Mapper 进行编程。 由于成本效益问题,Mapper 是 80 年代至 90 年代初的主流技术。

《超级马力欧兄弟2》(Super Mario Bros 2)的PCB 。 超级马力欧兄弟3也使用这种布局,但包含了一个256 KB的程序ROM。

带有重要部件标签的相同图片。 一开始,我以为额外的 WRAM 是用来存储存档的,但后来我意识到这个游戏没有存档(而且也没有电池)。 事实上,这个 RAM 芯片是用来储存解压后的关卡数据的。
回到 NES,《超级马力欧兄弟 2》和《超级马力欧兄弟 3》这样的游戏的卡带中包含了"MMC3" Mapper(由任天堂制造)。 作为比较,MMC3 提供了最大 512 KB 的程序 ROM,最大 256 KB 的 Character memory 和最大 8 KB 的额外 WRAM 。 您现在可以看出为什么《超级马力欧兄弟 3》的游戏内容比初代《超级马力欧兄弟》多很多了。
总而言之,虽然这台主机的内置功能存在一些限制,但是任天堂能确保它适应技术的发展。 另一方面,虽然这种技术有助于降低游戏机的成本,但它将部分成本转嫁到了游戏卡带上。 所以,游戏开发商必须在游戏质量和卡带成本之间做出权衡。


