F1C100S玩游戏系列 |
您所在的位置:网站首页 › NES模拟器GG码 › F1C100S玩游戏系列 |
接上篇:F1C100S玩游戏系列-FC红白机Nes模拟器(一)-移植InfoNes到BoloRTT工程,带Audio驱动,支持声音 先上工程源码链接https://github.com/VeiLiang/BoloRTT 关于本次移植的模拟器 这个模拟器最早应该是正点原子网友ye781205看到PocketNester,然后想着跑到stm32f1上,把cpu模拟代码改写成汇编,然后跑起来,还带声音模拟,声音比InfoNes好很多。最后正点原子也完善了对应的mapper,使其可以运行更多的游戏。感谢原子哥,感谢ye781205大佬,使得stm32f1也能运行nes模拟,而且速度非常流畅 移植需要注意的地方 汇编部分: 原工程用的编译器是mdk的armcc,所以汇编的格式是armcc格式的汇编。我们移植过来的时候不能直接编译,需要经过较多需要修改的地方:1.宏定义 MACRO MEND需要修改成.macro .endm举例 MACRO fetch $count ;//提取操作码 ;$标号 宏名 $参数1,$参数2,... ;//--------------------------------------------------------------------- ldr r0,clocksh ;//处理apu需要的时钟数 add r0,r0,#$count str r0,clocksh ldr r1,opz ;//获取代码跳转表地址 ;//------------------------------------------------------------------------- subs cycles,cycles,#$count*256;//CYCLE=256 ;// 3*256 正数或0就执行下2条指令 ldrplb r0,[m6502_pc],#1 ; //从存储器中加载字节到一个寄存器中 r0=操作码 ; ldrpl pc,[m6502_optbl,r0,lsl#2] ;//r10 ********r0=r0x4***运行代码的地址************************************** ldrpl pc,[r1,r0,lsl#2] ldr pc,nexttimeout MEND需要修改成 .macro fetch count //提取操作码 //$标号 宏名 $参数1,$参数2,... //--------------------------------------------------------------------- ldr r0,clocksh //处理apu需要的时钟数 add r0,r0,#\count str r0,clocksh ldr r1,opz //获取代码跳转表地址 //------------------------------------------------------------------------- subs cycles,cycles,#\count*256 //CYCLE=256 //// 3*256 正数或0就执行下2条指令 ldrplb r0,[m6502_pc],#1 //从存储器中加载字节到一个寄存器中 r0=操作码 // ldrpl pc,[m6502_optbl,r0,lsl#2] //r10 ********r0=r0x4***运行代码的地址************************************** ldrpl pc,[r1,r0,lsl#2] ldr pc,nexttimeout .endm2.EQU 需要改成.equ举例 C EQU 0x01 ;//6502 flags 6502标志 Z EQU 0x02 I EQU 0x04 D EQU 0x08 B EQU 0x10 ;//(allways 1 except when IRQ pushes it)IRQ外部中断 R EQU 0x20 ;//(locked at 1) V EQU 0x40 N EQU 0x80改成 .equ C , 0x01 //6502 flags 6502标志 .equ Z , 0x02 .equ I , 0x04 .equ D , 0x08 .equ B , 0x10 //(allways 1 except when IRQ pushes it)IRQ外部中断 .equ R , 0x20 .equ V , 0x40 //(locked at 1) .equ N , 0x803.SETA需要改成.equ对于SETA 可以认为是编译时候要用到的宏变量,一样可以用.equ代替.通常是用于宏搭配着用 _type SETA _ABS可以改成 .equ _type , _ABS4.PROC 需要改成%function例子 cpu6502_init PROC ;---------------------------------------------------------------------------- stmfd sp!,{r4-r11,lr} ldr r10,=cpu_data ;读取地址 ldr r11,=NES_RAM ;r11=cpu_zpage改成 .text .global cpu6502_init .type cpu6502_init, %function .align 8 cpu6502_init: //---------------------------------------------------------------------------- stmfd sp!,{r4-r11,lr} ldr r10,=cpu_data //读取地址 ldr r11,=NES_RAM //r11=cpu_zpage ldr r11,[r11] //NES_RAM用了指针5. AREA rom_code, CODE, READONLY 改成 .textAREA wram_globals0, DATA, READWRITE 需要改成 .data 6. RN需要改成.req globalptr RN r10globalptr .req r107.Map需要用对应的#define来解决。值得注意是有的指令可能不行,例如adr,需要改掉指令来实现对应的功能对于汇编Map关键字的定义,可以想象成是结构体,然后访问成员的时候,对应就能够基于基地址偏移。这些是编译器提供的功能 8.DCD修改成.long 9.IMPORT修改成.extern 10.汇编中mov 的操作数有的在ARM9下不支持,需要分拆成两部分 11.原来的汇编是跑在stm32上的,是cortex-m架构,只支持thumb2不支持ARM指令,f1c100s是ARM9两种都支持,但是通常编译选项会关闭thumb指令或者说start.s没有允许thumb指令,所以源代码中的调用防止进入arm状态的地址偏移,可以去掉。 ldmfd sp!,{r3,lr} //orr lr,#0x01 //lr最低位置1防止进入arm状态 //F1C100s 本来就是arm状态,需要注释掉这个指令 --By VeiLiang12.注释不一样,ARMCC汇编格式注释符号为分号; GNU汇编格式为//或者@ C语言部分 对于在汇编中用到的变量,务必需要4字节或者8字节对齐,gcc利用 __attribute__ ((aligned (4)))。如下 u8 PADdata0 __attribute__ ((aligned (8))); //手柄1键值 [7:0]右7 左6 下5 上4 Start3 Select2 B1 A0 u8 PADdata1 __attribute__ ((aligned (8))); //手柄2键值 [7:0]右7 左6 下5 上4 Start3 Select2 B1 A0 u8 *NES_RAM __attribute__ ((aligned (8))); //保持1024字节对齐 u8 *NES_SRAM __attribute__ ((aligned (8))); u8* spr_ram __attribute__ ((aligned (8))); //精灵RAM,256字节按键部分因为目前暂时没有按键,也是没有用上。按键读取函数为 //读取游戏手柄数据 void nes_get_gamepadval(void) { // u8 *pt; // while((usbx.bDeviceState&0XC0)==0X40)//USB设备插入了,但是还没连接成功,猛查询. // { // usbapp_pulling(); //轮询处理USB事务 // } // usbapp_pulling(); //轮询处理USB事务 // if(usbx.hdevclass==4) //USB游戏手柄 // { // PADdata0=fcpad.ctrlval; // PADdata1=0; // }else if(usbx.hdevclass==3)//USB键盘模拟手柄 // { // KEYBRD_FCPAD_Decode(pt,0); // PADdata0=fcpad.ctrlval; // PADdata1=fcpad1.ctrlval; // } }演示 ---------------------------------------------------------- ---------------------------------------------------------- 总结 总的移植下来,感觉学习到东西也蛮多。ARM转GNU汇编需要注意到的东西也比较多,稍有不慎就会data abort .不过出来的效果是真心不错,我还修改了对应的mapper,还有模拟的代码。让模拟器可以支持热血系列还有冒险岛系列运行。声音非常赞,我也移植了VirtualNes,对比发现本模拟器的声音可以和VirtualNes媲美,而且核心用的是汇编,跑在f1c100s上真的是丝滑,赞 致谢 感谢原子哥,感谢ye781205大佬,感谢晕哥,感谢rtthread团队 惯例 如果喜欢本项目https://github.com/VeiLiang/BoloRTT欢迎start fork 测试提交issue如果觉得本项目对你有用解决了你的问题,欢迎点击我的个人网站用爱发电 以下由 @哇酷小管家 2021-06-03 加入-----------------------------------------不方便上github的朋友也可以通过本站下载: BoloRTT_git_full.7z 最近编辑记录 微凉VeiLiang (2021-01-30 23:48:56) |
CopyRight 2018-2019 办公设备维修网 版权所有 豫ICP备15022753号-3 |