【原创】研究《绿色军团》NSF的音乐引擎(1)

研究《绿色军团》NSF的音乐引擎(1)

维京猎人

引言

NSF 就是NES的音乐文件。而NSF也是一个程序。可以认为NSF是从NES中抽出来的音乐程序,再做一些协调便能够独立运行。在电脑上运行NSF就好比运行NES一样,需要一个模拟器,NSF对应的模拟器叫NSF Player。

为了能够让自己编的NES游戏也能够有音乐,那要研究一下NSF。

NSF既然是一个程序,那么不同NES游戏公司就会有独门的音乐引擎。而且还会升级,所以众多的NES,它的音乐引擎都会不同,所以它们的音乐数据(格式)也不通用。

一、下载样板

为了入门快,我要找一个简单的先学学。已经有好多人也在研究同样的事。那我问问就行。听说科那美音乐引擎是最简单的。而卡普空是最复杂的(约有2K字节)。那我还是先科那美。大佬推荐《绿色军团》。从某站:NSF小站 -- 分享你的NES音符  找到 Green BeretStage 2.nsf 并下载。

二、入门书籍和方法。

另外,我还挖出一个教程,叫《nsf ripping guide》译过来应该叫nsf 挖倔手册。(可以找我要)

NSF分三段程序,初始化、播放、加载,

(1) 初始化,指定义变量地址,数据地址等。

(2) 播放,就是指NMI中的程序。为什么呢,据我分析,音乐是要时间控制的,那么NES唯一的时间相关的部分就在NMI。每帧运行一次的感觉。

(3) 加载,指主程序。

据我的经验,(测试了好多次了,都看这个地址)用FC_debug(带debug的改版VirtuaNES)打开nsf,并查看内存地址,可在$4700找上面是说3个地址。它们是以jmp的方式写成的。

那么动手

我看到$4700, $4710, $4720都有代码,它们前后就是空白的。

把4700到472F,都DUMP下来。DUMP就是说,挖出数据。不论是二进制还是十进制,还是十六进制,对于文件内存都是没有变化的,这只不过是显示的方式不同。

DUMP方法:打开DEBUG,最下面,内存:填上这两个数,按DUMP,选个文件夹保存)

保存成4700.mem,再用“智能反汇编器”打开它。这个工具我有上传的。

反汇编方法:打开软件,右上角,按下6502,再打开文件 ,下面文件类型选ALL files。选中刚保存的4700.mem。在打开的对话框中,选BIN文件,地址写4700。然后确定。)

我得到了

_4700:        jmp $4700

              brk

              ...

_4710:        jsr $A575

              jmp $4700

              brk

              ...

_4720:        jsr $A578

              jmp $4700

              brk

...

三、分析入口地址

这时候,我想起了关于 《NSF文件头格式》的解析。我网盘可以下载 维京的梦 (ysepan.com)

(域名好像变了,但用旧的fogota.ts168.com也能上。)

文件头格式:

文件的$0008是加载的地址。$000A是初始化的地址。$000C是播放的地址。

其实这个4700虚拟的,是模拟器独有的,真机上没的。反正nsf是给模拟器运行的。

我打开我的HexCmp,打开这个nsf,找到上面3个地址。(顺眼看见1987 Konmai,要不是人家告诉我,我都不会留意,绿色兵团是科那美的。只顾着玩。)

(为什么用HexCmp?它是十六进制比较器,因为它的地址显示是十六进制的。而我的HexWork地址显示是十进制。找不到设置的地方。)

看:

$08,$09上的值=A8,88。即指向(加载)地址=$88A8

$0A,$0B上的值=75,A5。即指向(初始化)地址=$A575

$0C,$0D上的值=78,A5。即指向(播放)地址=$A578

这一看,我猜加载的开始就是数据,我经常也这样写。这么不整齐的地址,应该是从ROM上抓出来的。如果是FamiTracker制的,那么加载应该是齐整的8000。

初始化只有3字节,应该又是跳转。

现在反观上面反汇编结果。

得到两条结论

4710就是初始化地址,是通用的,不用看文件头。

4720就是播放地址,也是通用的,不用看文件头。

这两个结论可以方便后面的工作。

上面的程序很好理解。因为NSF是从NES中挖出来的,所以不是完整的。这几条4700虚拟的指令,与NSF的程序连起来,正好将代码完整了。

四、反汇编步骤

(1)回到FC_DEBUG,查看内存,找到88A8,果然数据开始,再向下找结束的位置,在BFFF。好DUMP下来(88A8-BFFF),(方法见上面DUMP:4700的过程。)同样是保存到88A8.mem

(2)用反汇编的方法,转成代码(首地址这次是88A8)

(3)我看见开头的代码不是很对,可以确定那一些都是数据不是代码。看是没的问题,不过有点别扭。还是将数据与程序分开。这事需要随机应变。我放弃88A8.mem。再DUMP两段mem。一段是88A8-A574,另一段是A575-BFFF,分别保存为88A8.mem和A575.mem。

(4)用反汇编的方法,将A575.mem转成代码。保存成A575.asm。

(5)人工分析代码,先确认程序与数据。有时候程序里头也会插小段数据。所有跳转的落脚点都是程序的开头(入口),所以发现代码落脚点的程序不自然,就是说前面有一段是数据。程序段的结束都是返回指令或无条件跳转。

我发现这代码的后半段又是数据了,下一辑再说一说分析过程。

(6)作为数据段的88A8.mem,我有另一个工具,功能就是BIN文件转汇编。名叫 ALLToASM.exe。当然也可以不转换,只要用HEX工具看就行。我的Win10不准这货下载和运行。你非要下载,就选“仍然保留”。非要运行就选“仍然运行”。这样就可以,我用来一点不顺也无。最后保存,默认名就行,在同源路径下,后缀inc,文本格式。

这就获得了NSF的程序。包括数据和音乐引擎。

五、工具和资料

先写到这儿。

用到的工具:FC_debug(带debug的改版VirtuaNES),智能反汇编器。ALLToASM.exe

用到的资料:《nsf ripping guide》,《NSF文件头格式

我的网盘都可以找到:维京的梦 (ysepan.com)

Hex Cmp 就自己找了。我那边有另一个Hex工具。一样可以用,名叫:FC专用16进制编辑器。

这编写到这儿。下面看第二辑。

你可能感兴趣的:(NES,FC,FC,NES)