NES 模拟器开发教程 01 - NES 系统结构

NES 硬件组成

NES 有以下硬件

  1. CPU
    想必它的作用不用介绍了。它的型号是 2A03,8bit,工作频率 1.7897725 MHz。它有 16bit 地址总线,所以它的寻址范围为 0x0000 - 0xFFFF,即 64KB。CPU 支持三种中断:RESET(复位),NMI(不可屏蔽中断),IRQ(可屏蔽中断)

  2. APU(Audio Processing Unit)
    APU 集成在了 2A03 里面,用于声音的产生和输出,所以它没有专门的芯片。它有 5 个通道,可以产生方波,三角波,噪声,PCM(你问为什么 4 种波形占了 5 个通道?因为有 2 个通道可以用于产生方波)。

  3. PPU(Picture Processing Unit)
    PPU 型号为 2C02,用于产生图像。NES 中图像分两种

    • Background(背景)
      顾名思义,用于背景的显示,比如游戏的天空,草地,建筑
    • Sprite(精灵)
      用于前景的显示,例如游戏里的人物,子弹等

    最终上述两种图像组合后,输出到屏幕

  4. Cartridge(卡带)/ Mapper
    这是我们最熟悉的硬件了,就是这个:

    image.png

    卡带中包含了 NES 程序和图像的信息,所以不同游戏就会生产不同的卡带,CPU 和 PPU 都能直接访问卡带读取内容,至于读取的时候返回什么样的数据,这就是 Mapper 需要做的事情。有的 Mapper 扩大了程序的容量,有的 Mapper 植入了额外的芯片提升音频等等。。。

  5. RAM(内存)
    NES 主机中一共有 2 个 2KB RAM,一个给 CPU 用,另一个给 PPU 用
    NES 卡带中可能不带任何 RAM,也可能带 8KB 的额外用于 CPU 的 RAM(也就是我们常见的带了纽扣电池的卡带),甚至还有的卡带还带了 2KB 的额外用于 PPU 用的 VRAM

    • 主机中 2KB RAM
      用于游戏运行数据存储
    • 主机中 2KB VRAM(Video RAM)
      看名字就知道它干嘛了,该 RAM 用于显示数据的存储,CPU 将要显示的数据写入 VRAM,然后 PPU 会读取这里面的数据解码后输出到屏幕
    • 卡带上 8KB RAM
      用于游戏额外的数据存储,最重要的是它能够保存游戏存档。这也说明了为什么我们拔了卡带上的电池后存档就没了
    • 卡带上 2KB VRAM
      PPU 工作在 4-Screen 的时候才会用到,现在不需要了解它

NES 总线

这里有一张原理图:


image.png

图中左上为 CPU,左下为 PPU,右上为卡槽
能够观察到图中有两条粗的蓝色的线,一个在上方,一个在下方

  • 上方的蓝线
    这是 CPU 的地址总线,它有 16bit,寻址范围 0x0000 - 0xFFFF
  • 下方的蓝线
    这是 PPU 的地址总线,它有 14bit,寻址范围 0x0000 - 0x3FFF

总结下来,我们知道了 NES 有 CPU 和 PPU 两类总线,他们分别有自己的寻址空间。由于卡带上既有图像数据又有程序数据,所以卡带同时接入了两根总线

NES 内存映射

了解了 NES 有两条总线之后,我们需要关注 NES 的内存映射,也就是总线上哪些地址对应了哪些数据

1. CPU 内存映射

image.png
  • 0x0000 - 0x0800 ( RAM )
    这是主机中 2KB RAM 的数据,分成了 3 块

    • 0x0000 - 0x00FF ( Zero page )
      前 256 字节划分为 Zero page,这块内存相比其他区域不同点在于能让 CPU 以更快的速度访问,所以需要频繁读写的数据会优先放入此区域
    • 0x0100 - 0x01FF ( Stack )
      这一块区域用于栈数据的存储,SP(栈指针) 从 0x1FF 处向下增长
    • 0x0200 - 0x07FF ( 剩余 RAM )
      这是 2KB 被 Zero page 和 Sack 瓜分后剩余的区域
  • 0x0800 - 0x2000 ( Mirrors )
    你可能会感觉到奇怪这个 Mirror 到底是干什么的。实际上它是 0x0000 - 0x07FF 数据的镜像,总共重复 3 次
    例如:0x0001, 0x0801, 0x1001, 0x1801 都指向了同样的数据,用程序来解释的话,就是:
    address &= 0x07FF
    对应到硬件上的话,就是 bit11 - 13 的线不接
    至于为什么任天堂要这样设计?我猜可能是考虑到成本原因,2KB RAM 够用了,不需要更大的 RAM,但是地址空间得用完啊,所以才有了 Mirror 效果

  • 0x2000 - 0x401F ( IO Registers )
    这里包含了部分外设的数据,包括 PPU,APU,输入设备的寄存器。比如 CPU 如果想读写 VRAM 的数据,就得靠 PPU 寄存器作为中介

  • 0x4020 - 0x5FFF ( Expansion ROM )
    Nesdev 的论坛上有篇解释这块区域的帖子,简单来讲,该区域用于一些 Mapper 扩展用,大部分情况用不到

  • 0x6000 - 0x7FFF ( SRAM )
    这就是之前说过的带电池的 RAM 了,该区域位于卡带上

  • 0x8000 - 0xFFFF ( Program ROM )
    这里对应了程序的数据,一般 CPU 就在这块区域中执行指令,该区域位于卡带上

2. PPU 内存映射

image.png

这个图简单看看就好了,后面介绍 PPU 的时候再详细看看

  • 0x0000 - 0x1FFF ( Pattern Tables )
    这里存放了 8KB 的图像数据,该区域位于卡带上,由 Mapper 管理着。它的作用是用来 PPU 渲染图像的时候作为参考。有的游戏里面这块区域是 RAM,由 CPU 写入图像数据

  • 0x2000 - 0x2FFF ( Name Tables )
    这里一共 4KB 数据,其中 2KB 为主机 VRAM,另外 2KB 根据游戏配置为前 2KB 的 Mirror 或者卡带上的 VRAM。这里面存放着 Pattern Table 的偏移量,以此控制屏幕显示的内容,具体在后面的 PPU 章节讨论

  • 0x3000 - 0x3EFF ( Mirrors )
    同 CPU 的 Mirror 一样

  • 0x3F00 - 0x3F1F ( Palettes )
    这里是 NES 调色板数据,用于控制图像上每个像素的颜色,具体在后面的 PPU 章节讨论

  • 0x3F20 - 0x3FFF ( Mirrors )
    同 CPU 的 Mirror 一样

NES 游戏运行大致流程

了解了各个硬件作用和内存映射后,下面可以来探讨 NES 游戏运行时的流程了,其实只是很简单的循环:
首先系统上电或者 RESET 按钮按下后,会触发 RESET 中断,CPU 从 0xFFFA 和 0xFFFB 存储的地址处(2byte)开始取指令运行(具体在 CPU 章节讨论),之后 CPU 会一直运行 0x8000 - 0xFFF9 区间的指令。在每一帧渲染之前,CPU 会读取输入设备,然后通过 PPU 寄存器往 PPU 总线上的 VRAM 写数据,同时往 APU 写数据,最终反馈到了屏幕和声音上

©著作权归作者所有,转载或内容合作请联系作者
  • 序言:七十年代末,一起剥皮案震惊了整个滨河市,随后出现的几起案子,更是在滨河造成了极大的恐慌,老刑警刘岩,带你破解...
    沈念sama阅读 215,923评论 6 498
  • 序言:滨河连续发生了三起死亡事件,死亡现场离奇诡异,居然都是意外死亡,警方通过查阅死者的电脑和手机,发现死者居然都...
    沈念sama阅读 92,154评论 3 392
  • 文/潘晓璐 我一进店门,熙熙楼的掌柜王于贵愁眉苦脸地迎上来,“玉大人,你说我怎么就摊上这事。” “怎么了?”我有些...
    开封第一讲书人阅读 161,775评论 0 351
  • 文/不坏的土叔 我叫张陵,是天一观的道长。 经常有香客问我,道长,这世上最难降的妖魔是什么? 我笑而不...
    开封第一讲书人阅读 57,960评论 1 290
  • 正文 为了忘掉前任,我火速办了婚礼,结果婚礼上,老公的妹妹穿的比我还像新娘。我一直安慰自己,他们只是感情好,可当我...
    茶点故事阅读 66,976评论 6 388
  • 文/花漫 我一把揭开白布。 她就那样静静地躺着,像睡着了一般。 火红的嫁衣衬着肌肤如雪。 梳的纹丝不乱的头发上,一...
    开封第一讲书人阅读 50,972评论 1 295
  • 那天,我揣着相机与录音,去河边找鬼。 笑死,一个胖子当着我的面吹牛,可吹牛的内容都是我干的。 我是一名探鬼主播,决...
    沈念sama阅读 39,893评论 3 416
  • 文/苍兰香墨 我猛地睁开眼,长吁一口气:“原来是场噩梦啊……” “哼!你这毒妇竟也来了?” 一声冷哼从身侧响起,我...
    开封第一讲书人阅读 38,709评论 0 271
  • 序言:老挝万荣一对情侣失踪,失踪者是张志新(化名)和其女友刘颖,没想到半个月后,有当地人在树林里发现了一具尸体,经...
    沈念sama阅读 45,159评论 1 308
  • 正文 独居荒郊野岭守林人离奇死亡,尸身上长有42处带血的脓包…… 初始之章·张勋 以下内容为张勋视角 年9月15日...
    茶点故事阅读 37,400评论 2 331
  • 正文 我和宋清朗相恋三年,在试婚纱的时候发现自己被绿了。 大学时的朋友给我发了我未婚夫和他白月光在一起吃饭的照片。...
    茶点故事阅读 39,552评论 1 346
  • 序言:一个原本活蹦乱跳的男人离奇死亡,死状恐怖,灵堂内的尸体忽然破棺而出,到底是诈尸还是另有隐情,我是刑警宁泽,带...
    沈念sama阅读 35,265评论 5 341
  • 正文 年R本政府宣布,位于F岛的核电站,受9级特大地震影响,放射性物质发生泄漏。R本人自食恶果不足惜,却给世界环境...
    茶点故事阅读 40,876评论 3 325
  • 文/蒙蒙 一、第九天 我趴在偏房一处隐蔽的房顶上张望。 院中可真热闹,春花似锦、人声如沸。这庄子的主人今日做“春日...
    开封第一讲书人阅读 31,528评论 0 21
  • 文/苍兰香墨 我抬头看了看天上的太阳。三九已至,却和暖如春,着一层夹袄步出监牢的瞬间,已是汗流浃背。 一阵脚步声响...
    开封第一讲书人阅读 32,701评论 1 268
  • 我被黑心中介骗来泰国打工, 没想到刚下飞机就差点儿被人妖公主榨干…… 1. 我叫王不留,地道东北人。 一个月前我还...
    沈念sama阅读 47,552评论 2 368
  • 正文 我出身青楼,却偏偏与公主长得像,于是被迫代替她去往敌国和亲。 传闻我的和亲对象是个残疾皇子,可洞房花烛夜当晚...
    茶点故事阅读 44,451评论 2 352

推荐阅读更多精彩内容