|

楼主 |
发表于 2022-9-25 08:07:45
|
显示全部楼层
本帖最后由 gameboy 于 2022-9-25 11:58 编辑
NES 模拟器开发教程 03 - NES 开发和调试
了解 NES 文件结构之后,我们需要尝试 NES 的开发,以便从开发者的角度来加深对于 NES 系统的理解
注:本文当中会涉及到汇编的知识,在这里我假设你对汇编已经有一定的了解,不过即使不熟悉汇编也没有关系,只要知道它长什么样有什么用就行了
工具链
开发之前需要安装对应的工具链,由于 NES CPU 采用 6502 指令集,所以采用 cc65 作为开发工具,下载地址
安装代码工具链安装好后可以开始写代码了。首先要明确目的:目前想要在屏幕上显示 hello world 太难了,所以首先我们仅仅写一条指令:ADC #$1,它的作用是将 CPU 的寄存器 A 自增 1,只需要在调试器中看看运行效果就行了
首先,需要编写链接脚本,表明文件的内存布局:
文件 nes.cfg
MEMORY {
RAM: start = $00, size = $800;
NES_FILE_HEADER: start = $00, size = $10, file = %O, fill = yes;
PRG: start = $8000, size = $7ffa, file = %O, fill = yes;
INTERRUPT_VECTOR: start = $fffa, size = $6, file = %O, fill = yes;
}
SEGMENTS {
NES_FILE_HEADER: load = NES_FILE_HEADER, type = ro;
CODE: load = PRG, type = ro;
INTERRUPT_VECTOR: load = INTERRUPT_VECTOR, type = ro;
}
这个文件不需要完全看懂,总之它定义了 NES 文件结构:
- NES_FILE_HEADER:16 个 Header 字节
- CODE:程序数据
- INTERRUPT_VECTOR:中断向量表
文件 test.asm
.segment "NES_FILE_HEADER"
.byte "NES", $1A, 2
.segment "CODE"
forever:
ADC #$1
JMP forever
.segment "INTERRUPT_VECTOR"
.word forever, forever, forever
可以看到 test.asm 中定义了三个段:
- .segment "NES_FILE_HEADER":
.byte "NES", $1A, 2 表示文件开头的 5 个字节,分别为 'N', 'E', 'S', 0x1A, 0x02,前面 4 个为 NES 文件标识,最后一个 2 定义了 PRG 大小为 2 x 16K = 32K - .segment "CODE":
这里非常简单,一条死循环的 ADC 指令 - .segment "INTERRUPT_VECTOR":
这里定义了中断向量表,分别对应了三个中断:RESET,NMI,IRQ,这里的值表示了所有的中断都会跳转到 ADC 指令处
编译
ca65 test.asm -o test.o # 编译
ld65 -C nes.cfg test.o -o test.nes # 链接
最终会生成 test.nes,hexdump 查看编译后文件如下
$ hexdump test.nes
0000000 4e 45 53 1a 02 00 00 00 00 00 00 00 00 00 00
000000010 69 01 4c 00 80 00 00 00 00 00 00 00 00 00 00
000000020 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00
*
0008000 00 00 00 00 00 00 00 00 00 00 00 80 00 80 00
800008010
第一行刚好对应了 'N', 'E', 'S', 0x1A 和 0x02 的 PRG Bank 数量
第二行的 69 01 对应了 ADC #$1,4C 00 80 对应了 JMP forever
第三行最后 6 个 byte 00 80 00 80 00 80 对应中断向量表,由于 6502 是小端模式,低地址在前,所以 0x8000 在内存中存储为 00 80,这里 3 个 00 80 表示所有中断都跳转到 0x8000 处(也就是 ADC 所在位置)
调试
打开 Fceux,加载刚刚编译的文件,打开 Debugger,在 0x8000 处添加一个断点
然后点击 POWER 模拟开机
之后可以看到程序运行到了断点处,点击 Step Into 就能看见寄存器 A 在自增
至此我们已经掌握了 NES 的开发和调试,相信你对 NES 系统和文件结构有了更深刻的理解
|
|