游戏和女朋友谁重要?当然是游戏(手动狗头),游戏是每一个时代的记忆,从最早的LED点阵上的游戏发展到LED屏,同时游戏也不断的推动着计算机的发展,现在,时代已经过去,游戏机除了在古董市场,已经无从获得,但是我们可以通过VM技术去重新构建一个借助虚拟化技术可玩的设备,追逐旧梦。 本系列将结合前面的Python VM系列虚拟机将知识融会贯通,总结一下伟大的虚拟化技术。
起步——认识iNES文件格式
要入手一个模拟器,首先得从如何解析.nes的游戏文件开始。
iNES 文件(拓展名 .nes,大小写均可)是 NES 游戏分发的事实标准。该文件标准的最初是由 Marat Fayzullin 为其模拟器 iNES 而开发的文件格式。
0 | 1 | 2 | 3 | 4 | 5 | 6 | 7 |
---|---|---|---|---|---|---|---|
N | E | S | ^Z | PRG | CHR | MAP/SW | MAP/0(always) |
4E | 45 | 53 | 1A | 10 | 20 | E1 | 40 |
-
第 0 ~ 3 个字节指定了文件的格式
0 = 0x4E (N)
1 = 0x45 (E)
2 = 0x53 (S)
3 = 0x1A (^Z) -
第4个字节指定了 PRG(程序) ROM 块的个数,PRG ROM 块每个大小为 16KB
-
第5个字节指定了 CHR(图块) ROM 块的个数,CHR ROM 块每个大小为 8 KB
-
第6个字节为指定卡带属性的字节。各个比特位的含义如下:
- 0 -> Mirror Type ( 1 为水平, 0 为垂直)
- 1 -> 是否存在 battery-backed RAM ( 1 则为存在,映射到 $6000-$7FFF)
- 2 -> 是否存在 trainer (同上,映射到 $7000-$71FF)
- 3 -> 是否存在 VRAM
- 4-7 -> Mapper Type 的低四位
-
第 7 个字节还是指定卡带属性的字节。各个比特位的含义如下:
- 0 -> 卡带是否含有 VS-System
- 1-3 -> 保留,但必须全为 0
- 4-7 -> Mapper Type 的高四位
-
第 8 个字节指定了 RAM 块的个数,每块为 8KB,如果为 0 ,则假设只有一个 RAM 块。
-
第 9 个字节指定了视频制式,如果其第 0 个比特值为 0,则为 PAL,否则为 NTSC 制式。
-
第 10-15 字节为保留区域,必须为 0 通过010editor打开下载[2]的ROM文件可以看到
C++中我们可以定义一个读取文件头的结构体
const NESMagicMumber = 0x1a53454e //"NES^Z"
typedef struct _NesHeader{
uint32_t MagicNumber;// NES Magic Number,must be 0x1a53454e
char PRGNum; // PRG-ROM banks number
char CHRNum; // CHR-ROM banks number
char Ctrl1; // Control
char Ctrl2; // Control too
char RAMNum; // RAM number (8KB each)
char[7] _null; // Empty bytes. Not used at this tume but MUST BE ALL ZEROS or games will not work.
}NesHeader
参考资料: