F1C100S玩游戏系列

您所在的位置:网站首页 NES模拟器GG码 F1C100S玩游戏系列

F1C100S玩游戏系列

2024-01-19 21:34| 来源: 网络整理| 查看: 265

接上篇: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 .endm

2.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 , 0x80

3.SETA需要改成.equ对于SETA 可以认为是编译时候要用到的宏变量,一样可以用.equ代替.通常是用于宏搭配着用

_type SETA _ABS

可以改成

.equ _type , _ABS

4.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 r10

7.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 VeiLiang

12.注释不一样,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; // } }

演示

_20210130224030.jpg

----------------------------------------------------------

----------------------------------------------------------

总结

总的移植下来,感觉学习到东西也蛮多。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