
最近在跟着教程写一个Game Boy模拟器,吭哧吭哧写到最后跑Blargg's Test(很有名的GameBoy模拟器单元测试集),结果发现连01-Special都跑不过去,网上提供的例子也不多,排障排了好几个小时,如果你现在像我一样,跑单元测试跑出来了一些连网上都搜不到的错误,那请看看下面这一条定理(我发明的):
如果你发现你搞出来了一条网上怎么搜都搜不到的技术问题,那么只有两种可能,要么这条技术问题是业界难题(而且还是你先发现的),要么就是你犯下了一个白痴得不行的错误,以致网上都不屑于记录这样的白痴问题
——B分之A
话虽如此,但我还真就犯下了下面这么些白痴错误,下面记录下来,就当是给后面像我一样的小白省下一些做白痴级排障的时间吧:
0、检查CPU寄存器的初始值:
说实话这其实不算是什么错误,但是很多人都会忽略初始值这个东西,因此我决定把这个放在第0号。
根据你需要模拟的CPU,寄存器的初始值是不同的。你可以参考bgb里面各种CPU寄存器的初始值。
1、检查警告:
不要忽略编译器给出的警告,有时候你会犯下一些比较蠢的错误,而这种时候编译器会给你很有效的提示。比如说,你的函数中的某个分支没有Return等等。

2、检查变量大小:
什么时候用8位/16位/32位,什么时候用有符号无符号,我们心中应该要有数,不然结果就会溢出带来不可预料的结果。

3、相同变量名的混淆:

如果两个变量名字取得一样,很有可能会产生混淆...尽量把名字取得有辨识度一点。
4、检查寻址模式和运算子:

寻址模式是否写对了?是对谁进行操作?是把谁加在谁身上?是取的立即数,还是对应的内存地址,还是先加上0xFF00再进行寻址?...要搞清楚每个指令的作用。
5、关注边界条件:

对于布尔值,是直接赋值还是取反?是大于还是大于等于?
6、HL特判:

在许多指令(尤其是CB指令)里面,很多情况下都会是对HL取地址对应值,而对其它寄存器取立即数,需要检查一下涉及HL寄存器的指令本身是否对HL做了什么特殊处理。
7、光读不返回
在总线——内存映射时,有时候我们可能会只进行映射,对其它资源做了读操作,但是没有把读出来的结果返回去,而掉到了外面的默认分支:

需要检查这一种情况。
总结
都是之前踩过的一些很脑残的坑,这里希望我替大家趟过的水大家都能顺顺利利地走过去。
Comments
(Participate in the discussion)
Comments
No comments found.
No comments found.