美文网首页
NES模拟器准备工作

NES模拟器准备工作

作者: 老杜振熙 | 来源:发表于2020-09-26 21:30 被阅读0次

最近浏览了github,找到了比较有意思的一些开源项目,也想着使用C++写一个红白机的模拟器。说干就干吧,在这里记录一下相应的准备工作。

一些基本概念

首先是一些术语的含义,如下表所示。

其次,一些需要注意的地方:

  1. CPU和PPU分别拥有16位(64KB)的地址空间;
  2. RAM和ROM位于同一个16位地址空间内,CPU和PPU通过指定地址读取相应数据,(和计算机中的虚拟内存层次存储结构不太一样);
  3. RAM的地址空间为13位(0x0000~0x1FFF, 8KB),但实际上只有11位(0x0000~0x07FF, 2KB)是真实用到的,所以会有CPU地址空间分布中的"RAM镜像的概念",其实就是把原来13位中的高2位抹去,归根结底就是为了省钱,同时把地址空间给覆盖满;
  4. PPU中的镜像:PPU的地址空间中,任何超过0x4000的地址,也都被抹去高位,使得实际上寻址范围在0x0000~0x3FFFF,可见,镜像在NES中是广泛应用的;

CPU地址空间分布

nes的CPU地址空间分布如下表所示,这对于后续编写CPU读取数据的函数,是至关重要的。

起始地址 字节大小 具体类型
0x0000 0x800 RAM
0x0800 0x800 RAM映像
0x1000 0x800 RAM映像
0x1800 0x800 RAM映像
0x2000 0x8 Register
0x2008 0x1FF8 PPU Register
0x4000 0x20 Register
0x4020 0x1FDF 扩展ROM
0x6000 0x2000 SRAM(用电池供电的额外RAM,卡带提供)
0x8000 0x4000 PRG-ROM
0xC000 0x4000 PRG-ROM

PPU的渲染模式

nes图形种有一个palette的概念,具体是什么不用细讲,我们只需要知道,每个像素点需要4bits的信息来告知是哪一个palette即可,用以显示对应的颜色。PPU使用Name Table和Pattern Table以及Attribute Table来指示颜色信息,如图所示(写的很乱...估计除了自己,也没人看得懂了)。简单来说,游戏的每一帧有32\times30=960个Tile,所谓Tile,就是8\times8个像素点构成的一个小方块。然后,程序通过几个Table来指定小方块的颜色(也就是降低精度来节省空间了)。
Tile有960个,而单个NameTable刚好也是960Bytes构成,和Tile一一对应。Pattren Tables总共有8KBytes的空间,分为4KBytes+4KBytes,分别给Background和Sprite使用。4KBytes以16Bytes为单位,划分为256个单位。而Nametable中的每个Bytes刚好作为Pattern Tables中单位的索引。单位用以指示Palette偏移的低2位,高两位由Attribute Table指示。后面也懒得写了。。。如果到这里能读懂的话,图也就能看懂了,看图吧。。。

PPU.jpg

NES文件格式

查阅了相关的资料,nes文件的文件格式如下,供后面参考。

字节范围 字节数 具体内容
0~3 4 字符串"NES^Z" (^Z表示EOF)
4 1 16KB ROM的数目
5 1 8KB VROM的数量
6 1 D0:1=垂直镜像,0=水平镜像,即游戏的板式为横斑还是竖版(D0表示该字节的LSB,下面类推)
D1:1=有电池记忆,SRAM地址0x6000-0x7FFF
D2:1=在0x7000-0x71FF有一个512字节的Trainer
D3:1=4屏幕VRAM布局
D4-D7:ROM Mapper的低4位
7 1 D0-D3:保留,必须是0(准备作为副Mapper号)
D4-D7:ROM Mapper的高4位
8~F 8 保留,必须是0
16~ 16KB \times M ROM段升序排列,若存在trainer,则其512字节摆在ROM之前
~EOF 8KB \times N VROM段, 升序排列

工作流程

  1. 读取nes文件,将对应的ROM,VROM等数据读取至内存中(可以直接用vector来存储),以及mapper的建立;
  2. 实际运行游戏之前,先要进行reset,将CPU和PPU中的寄存器、标志位等部件恢复至默认值;

未完待续...

相关文章

网友评论

      本文标题:NES模拟器准备工作

      本文链接:https://www.haomeiwen.com/subject/uhshuktx.html