FinalBurn Alpha ++

移植中的 FinalBurn Alpha Plus

移植 FinalBurn Alpha Plus 的起因

成功把 Franxis 的 MAME for GP2X v2.4 移植到 Moto E680i ( XMAME )上以后,就着手去移植PS模拟器了,等有时间回头再看MAME模拟器的时候,MAME for GP2X 已经有较大的升级了,新的 v3.7 已经支持 Q-Sound 芯片,也就是说 CPS1 的 dino 和 wof 可以有声音了,我尝试移植了一下,Q-Sound 部分运行出错。这期间,masterall 的 FBA for WinMobile 也已经发布并多次更新,看到玩家对其评价非常不错,也使我开始注意 FinalBurn 这款模拟器了。

FinalBurn 原始版本,作者Dave。主要包括 burn ( 模拟器核心 )、burner ( 用户界面 )、a68k ( 68000 模拟 )、doze ( z80 模拟 )四个部分。针对 x86 在代码上做了大量优化,有效提高其运行效率。

FinalBurn Alpha 经过许多Fans努力,这个模拟器可以支持更多的游戏,CPS1/2、Neogeo、彩京等。

FinalBurn Alpha Plus 官方 FBA 的移植改进版本。

在FBA的论坛里很早就有提议把这款模拟器移植到 GP2X 上去,但似乎没什么结果。FBA的核心都是经过 x86 汇编优化的,要移植到基于 ARM 处理器的嵌入式设备上还是很麻烦的,不过为了能体验一下 FinalBurn 在 E680i 上的效果,还是鼓起勇气,开始尝试移植的项目。

开始将 FBA 向基于 ARM 嵌入式设备的移植

移植项目从 FBAP v0.2.95.23 [u7] 开始。首先是编译 burn 部分,这里面的只有少量的 Intel MMX 对音频处理的优化,因为有纯C的代码,可以简单的注释掉 MMX 部分就可以编译通过了。其次是 a68k 部分,首选当然是替换为 Dave 的 Cyclone ,一方面 Cyclone 的效率高,另一方面,Burn 和 Cyclone 的作者都是 Dave 一个人,而且有他的 PicoDrive 可以借鉴,移植工作难度不大。唯一需要注意的是 ARM 的指针跟 x86 上的有些区别,16为和32位的内存读写需要调整一下。再次是Z80部分,暂时用 Reesy 的 DrZ80 。最后是 burner 部分,可以用 SDL 的,但是为了简化,我还是利用我已有的 EZX 系列模拟器的前端代码了。初步工作完成后,在E680i上测试了一下,速度还是蛮块的。修改的 burn 部分代码我放到我的存储空间里了( Z80部分只是临时的,中断等功能还没实现,仅能保证部分CPS1和Neogeo的ROM可以运行) 。

让人郁闷的 Q-Sound

 用 Reesy 的 DrZ80 替换 Doze 后,运行总不能得到预计的结果。细读 Doze 代码后才发现,使用 Q-Sound 芯片的游戏ROM里,Z80代码是加密的,以游戏dino为例,128KB 的 cd_q.rom 文件经过解密后( 算法见 burn/capcom/kabuki.cpp )得到一个256K的内存,Zet 把这段内存分成两部分,分别映射为 MemFetch 和 MemFetchData 。Doze在模拟执行 Z80 的 ROM 时,OpCode 和 ImmData 分别来自 MemFetch 和 MemFetchData 。看来要对 DrZ80 做个大手术才行......

根据Doze修改DrZ80

由于gcc的编译器优化效果实在不敢恭维,还是放弃C的Z80模拟代码,直接选择ARM汇编的DrZ80,从PicoDriver的DrZ80代码基础上修改。首先就是吧DrZ80里的所有 z80_read 和 z80_write 用宏定义出来,便于修改。然后吧 Doze 的 MemHandler 加入DrZ80的结构中。以Z80的 01h 指令( LD BC,NN )为例子:

  opcode_0_1:
     ldrb r0,[z80pc],#1
     ldrb r1,[z80pc],#1
     orr r0,r0,r1, lsl #8
     mov z80bc,r0, lsl #16
     fetch 10

这里解释读到OpCode 01h 后,立即读取一个十六位数存到Z80的BC寄存器的。Z80 PC认为Z80的代码和立即数是在连续的内存空间里的,而Q-Sound的Z80 Rom解开后,指令和立即数分开了,所以不得不从改成:

  opcode_0_1:
     ldr r2,[cpucontext,#z80pc_base]
     sub r2,z80pc,r2                       ;@ 根据z80pc_base计算Z80 PC
     ldr r1,[cpucontext,#ppMemFetchData]
     mov r0,r2,lsr#8      
     ldr r1,[r1,r0,lsl#2]                  ;@ 取立即数地址
     ldrb r0,[r1,r2]
     add r2,r2,#1
     ldrb r1,[r1,r2]
     orr r0,r0,r1, lsl #8                ;@ 取立即数
     add z80pc,z80pc,#2           ;@ 增加PC
     mov z80bc,r0, lsl #16
     fetch 10

 修改全部取立即数的代码后,调整burn的zet单元,Z80基本就能工作正常了。

 Download the burn and cpu's source code of ARM version Finalburn Alpha Plus: fbap-burn-src-0.3.zip

DrZ80 中 REBASE_SP 的问题

测试 Toaplan 的游戏 battleg 发现,游戏载入后立即异常退出了。主要问题出在Doze的MemoryHandler和Drz80的RebaseSP之间出现了漏洞导致无效地址写操作,为了避免这种情况,修改了DrZ80里的处理SP的代码。

Intel xScale 处理器的 iwMMXt 指令

为了测试FBA的声音效果,单独编译了一个PC版本来测试模拟器的声音,结果让人失望,C的音频处理和MMX优化的音频相差很大,很多地方出现杂音甚至暴音。从 intel 的主页下了些文档,就尝试着用 iwMMXt 指令重写音频处理单元了。

 Download the burn and cpu's source code of xScale version of Finalburn Alpha Plus: fbap-burn-src-0.4.zip

 

 返回首页