开发 FC 水平的模拟器,需要什么知识储备?

开发 FC 水平的模拟器,需要什么知识储备?

关于:

这个讲6502CPU模拟器设计资料的

这个是 nesdev 有很多关于 NES 游戏机的资料。

另外有本《小霸王游戏机的奥秘.PDF》模糊的讲了一下NES游戏机的技术,但是不太深入。但是还是挺有用的。

再另外有个软件叫《VirtuaNES-debug》这个可以单步执行nes指令,可以调试NES游戏程序,并可以显示很多内部的数据结构,在实现过程中很有帮助的!(另外本身这个软件就是开源的)下面是软件示意图:

我以前写的NES和430的模拟器,写着玩的,代码量也不是很大,但是有些够理解用的基本功能了。都基本上是纯C语言写的,NES的用QT做了个图形显示,Cpu部分都是C语言实现。

还写了一个实现了几条指令的430CPU但是能跑流水灯了!而且是完全控制台下的流水灯!(c语言就足够了)

FC 硬件虽然绕但是不复杂,然而你没有卡带里各种芯片的数据(FC 的卡带是主机的一部分,直接插总线的),只能模拟超玛一代这种早期游戏

正好写过一个,也补充一下吧。

@ 加菲猫 已经提到了很多,只补充一些我认为有用,答主们没说到的吧。

关于汇编,需要了解,但是精通没必要,毕竟这东西是严格硬件相关的,你精通X86汇编对写6502处理器没有太大的帮助,精通6502汇编对写FC模拟器也没有太大帮助,因为你要写的是执行汇编的环境,而不是用汇编编写游戏本身。

关于调试技术,这是整个编写过程中最重要的环节,好的调试技术和适当的调试工具可以大大加快项目的进度,这里面一般有两个选择,当时我在写模拟器的时候,我一个网友也在写,关于调试工具,我们采用的不同的路线,我为了节约时间,只使用了简单的printf向控制台直接输出反汇编和调试信息,而我的网友则花费了不短的时间实现了一个比较完整的6502调试环境,最后的结果是我大约用不到2个星期的业余时间就可以跑1942了,而他则花了几个月才做到这一步,但是由于我没有方便高效的调试环境,后期在模拟Mapper4等容量比较大的卡带的时候相当的麻烦,而这时候他的优势就体现出来了,至于具体选择什么手段,还要看你自己。

@ 加菲猫 的回答提到了VNes的调试版本,这是个非常重要的工具,可以极大的节约你的时间,不过我也会使用No$NES做为辅助工具,No$Nes虽然在兼容性上比VNES差一些,但是在调试环境下的运行效率是VNES不能比的,你试过就知道了,这两者可以说各有所长吧。

关于文档,网上能查到的主要是NesDoc,Nes Spec和一个NesDev的wiki,这其中NesDoc比较简单,而且有几个翻译版本,可以用来入门,No$网站上的Nes Spec是我读过的Nes文档中最好的一个,而NesDev由于是个多页面的wiki因此在查找上没有Nes Spec那么方便,后者有txt版本,用Ctrl+F就可以方便的检索。

编写Nes模拟器需要时刻记住的是他是一个80年代的硬件平台,其使用的很多技术与当今游戏界流行的方法有较大的差别,不能用现在游戏程序的思路去考虑他的问题,比如近代游戏平台提供的背景缓存NES中就不存在,他的所有数据都是直接被绘制在屏幕上的,而且绘制的过程和代码的执行事实上是交错进行的,而当前的游戏一般情况下硬件都是等待程序将图像完全绘制到背景缓存之后在翻转到屏幕上,游戏程序与硬件的绘制过程是独立的。

最后对模拟的具体游戏提供一些建议,按我的经验,依据模拟的难度由易到难的话,最先应该被支持的应该是卡厂的1942,这个游戏不但容量小(Mapper0)而且对时钟的模拟要求并不严格,也没有使用任何技巧,是入门的不二之选。千万不要认为容量越小的游戏模拟起来就越容易,只有1942一半大小的F1赛车就是一个运用了很多技巧的作品,即使No$Nes都不能很好的支持他,至于任地狱最伟大的作品SuperMarioBro,差不多是Mapper0技巧的大成者,如果能完整的支持这个作品那基本标志着你对FC自身硬件的模拟已经完成的差不多了,接下来主要是对卡带的模拟,这里说“基本”是因为SMB没有利用一个中断方面的技巧,如果没有很好的模拟这个,你就无法运行《炸弹人》~~~~

在Mapper0的模拟完成之后,最容易实现的就是Mapper2和3,伟大的魂斗罗就在其中,而且支持他是很简单的。

余下的mapper就都比较麻烦了,想完整的模拟就要仔细看各种文档,不过也都是力气活,写模拟器就是这样,没什么技术的门槛,关键是要有足够的耐心~~~~*

其实不难,按部就班地“模拟”就行,这年头PC的运算能力,基本上随便你怎么写,把游戏跑起来问题都不大。

接好啦,不用谢

支持楼上观点。如果datasheet资料充裕,那做模拟器就是严谨的按部就班抽象数据结构。

额,很多年前,要在小灵通上实现一个FC模拟器。

因为开源软件很多,移植实际上并不花费太多精力。就是时间问题。

FC的硬件级code page很多很杂,感谢上帝开源软件的大神已经移植好了。

大致注意的就是:

1、了解目标设备的CPU体系结构。几个寄存器、指令汇编到机器码的规则、寻址范围、寻址模式之类的。抽象数据结构很简单,C实现的时候,位段、union就足够了。其内部一个状态机实现足矣。

伪代码:

RunStep(parse(cpu->IData[cpu->current_pc_prt+1]));

2、了解目标设备的外设时序、datasheet、原理图如果有最好了。诸如液晶、键盘、声音等等。

伪代码:

OnRightSoftKeyClickDown()

{

SetInput(cpu , peripheral->key.A , true);

}

额,大致如此吧。

烂尾项目。匿了比较好。知道我是谁,也别声张了……

泻药

你邀请我,我也不会呀( ⊙ o ⊙ )!

可以参考一下

要完成一个简单 nes 模拟器,比如能运行超级玛丽、魂斗罗之类,其实难度不大。代码量也不算太大。

重点和难点在于搜集、阅读、理解 nes 的硬件资料。如果你对 nes 的工作原因都了如指掌了,还需要什么呢?当然是控制不住的编码冲动,反复的编码和调试。

nes 各个部件的具体细节,这里没法展开介绍。泛泛而谈的原理和模拟方法,许多人也介绍了不少。我就讲讲一些实际且有指导性的东西。

1. 任天堂游戏机分为 nes 和 fc 两种,主要区别在于 nes 是 ntsc 制式,而 fc 是 pal 制式。建议从 ntsc 开始,原因是能找到的多数资料都是 ntsc 制式的。

2. 除了理解 cpu ppu apu 等各个部件的工作原理,请一定研究清楚 nes 内部有多少时钟类型,以及相互之间的关系。简单的说有一个主时钟,我称之为 mclk,然后 cpu 时钟与 mclk 的关系是什么?apu 的时钟与 mclk 的关系是什么?是同步还是异步?

搞清楚以上问题,我们就真正明白,各大部件之间是如何互联,编写模拟器时,又是如何保证联系和同步的。

3. 调试 cpu 一定要借助 cpu 的 test rom,而且这也是必经之路。cpu 的模拟,在搞清楚原理之后,说到底不是技术活,是个体力活。等你完成自己的 cpu 模拟代码后,第一件要做的事情,就是找 cpu test rom 进行 debug,而不是急着去实现其他部分或者跑游戏 rom,不能急一步一步来,保证每一步的正确性。

各种 test rom 是必须的工具,可以帮助我们快速定位问题,这些工具在 nesdev 上可以找到。等你进入跑游戏 rom 的 debug 阶段,整天就是在折腾这些。

5. 精确模拟、持续 debug 和完善才是难点。如果仅仅是做一个 demo 那当然很容易完成。但是要做一个优秀的模拟器,不仅仅是搞懂原理,写出代码这样简单,需要的是反复的持之以恒的调试、优化。

懂基础高级语言,懂某操作系统下的程序编写。看懂6502汇编指令作用,方便用其他语言模拟。搞懂CPU与PPU,乃至画面显示的逻辑关系。不需要多深的知识储备,是软硬件都懂一点就行。

。。。路过 貌似得十分有耐心才行啊

刚用c写完一个nes模拟器的来回答一下,最重要的是资料资料,不然你根本不知道哪个内存中的哪个字节中的哪一位是干嘛用的,cpu模拟不复杂,主要是ppu,ppu部分很绕,需要耐心的看。还有要对寻址,偏移等基本的汇编知识要懂,要知道如何把汇编语言转化成你会的语言,就是灵活运用&,^, | , >等这些运算符。 = =。