您尚未登录。

楼主 #1 2021-01-30 22:43:40

微凉VeiLiang
会员
所在地: 深圳
注册时间: 2018-10-28
已发帖子: 595
积分: 525
个人网站

F1C100S玩游戏系列-FC红白机Nes模拟器(二)-移植正点原子的nes模拟器(ye781205的汇编核心),带声音,ARM转GNU汇编

接上篇: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 改成 .text
AREA wram_globals0, DATA, READWRITE 需要改成 .data

6. RN需要改成.req

globalptr	RN r10
globalptr .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)

离线

楼主 #2 2021-01-30 22:44:48

微凉VeiLiang
会员
所在地: 深圳
注册时间: 2018-10-28
已发帖子: 595
积分: 525
个人网站

Re: F1C100S玩游戏系列-FC红白机Nes模拟器(二)-移植正点原子的nes模拟器(ye781205的汇编核心),带声音,ARM转GNU汇编

本模拟器在项目的目录路径:BoloRTT/bsp/f1c/package/vnes/

离线

楼主 #3 2021-01-30 22:49:06

微凉VeiLiang
会员
所在地: 深圳
注册时间: 2018-10-28
已发帖子: 595
积分: 525
个人网站

Re: F1C100S玩游戏系列-FC红白机Nes模拟器(二)-移植正点原子的nes模拟器(ye781205的汇编核心),带声音,ARM转GNU汇编

如果只想下载模拟器代码,可以本站链接下来 vnes.rar
关于文件夹命名,原版文件夹就是叫做NES的,加了个v区分下其它移植的模拟器,所以命名就变成vnes了,谅解

离线

楼主 #10 2021-02-02 17:36:39

微凉VeiLiang
会员
所在地: 深圳
注册时间: 2018-10-28
已发帖子: 595
积分: 525
个人网站

Re: F1C100S玩游戏系列-FC红白机Nes模拟器(二)-移植正点原子的nes模拟器(ye781205的汇编核心),带声音,ARM转GNU汇编

视觉℡ 说:

为啥编译不过呢
scons: Reading SConscript files ...
scons: done reading SConscript files.
scons: Building targets ...
scons: building associated VariantDir targets: build
CC build\applications\Apps\demo.o
Error in calling:
arm-eabi-gcc -o "build\applications\Apps\demo.o" -c -mcpu=arm926ej-s -ffunction-sections -fdata-sections -Wall -O2 -DHAVE_CCONFIG_H -DRT_USING_NEWLIB -I. -Iapplications -Iapplications\Apps -Ibootloader -Idrivers -Ilibcpu -Ipackage -Ipackage\infones -Ipackage\jpgdec -Ipackage\lvgl -Ipackage\lvgl\porting -Ipackage\lvgl\src -Ipackage\lvgl\src\lv_core -Ipackage\lvgl\src\lv_draw -Ipackage\lvgl\src\lv_font -Ipackage\lvgl\src\lv_hal -Ipackage\lvgl\src\lv_misc -Ipackage\lvgl\src\lv_objx -Ipackage\lvgl\src\lv_themes -Ipackage\vnes -ID:\RTT\BoloRTT-master\include -ID:\RTT\BoloRTT-master\components\dfs\include -ID:\RTT\BoloRTT-master\components\dfs\filesystems\devfs -ID:\RTT\BoloRTT-master\components\dfs\filesystems\elmfat -ID:\RTT\BoloRTT-master\components\dfs\filesystems\romfs -ID:\RTT\BoloRTT-master\components\drivers\include -ID:\RTT\BoloRTT-master\components\drivers\include -ID:\RTT\BoloRTT-master\components\drivers\include -ID:\RTT\BoloRTT-master\components\drivers\spi -ID:\RTT\BoloRTT-master\components\drivers\include -ID:\RTT\BoloRTT-master\components\drivers\spi\sfud\inc -ID:\RTT\BoloRTT-master\components\drivers\include -ID:\RTT\BoloRTT-master\components\drivers\usb\usbhost -ID:\RTT\BoloRTT-master\components\drivers\usb\usbhost\class -ID:\RTT\BoloRTT-master\components\drivers\usb\usbhost\core -ID:\RTT\BoloRTT-master\components\drivers\usb\usbhost\include -ID:\RTT\BoloRTT-master\components\drivers\include -ID:\RTT\BoloRTT-master\components\finsh -ID:\RTT\BoloRTT-master\components\libc\compilers\newlib -ID:\RTT\BoloRTT-master\components\libc\pthreads -ID:\RTT\BoloRTT-master\components\libc\time "applications\Apps\demo.c"
Exception: [Error 2] : No such file or directory
scons: *** [build\applications\Apps\demo.o] Error 2
scons: building terminated because of errors.

是在bsp/f1c目录下运行scons么

离线

楼主 #15 2021-02-02 21:57:27

微凉VeiLiang
会员
所在地: 深圳
注册时间: 2018-10-28
已发帖子: 595
积分: 525
个人网站

Re: F1C100S玩游戏系列-FC红白机Nes模拟器(二)-移植正点原子的nes模拟器(ye781205的汇编核心),带声音,ARM转GNU汇编

视觉℡ 说:

修改了两个地方可以编译了,
第一、rtconfig.py文件中的第32行
PREFIX  = 'arm-eabi-'  修改为  PREFIX  = 'arm-none-eabi-'

第二、libc_errno.h文件中的第32行
#include <asm-generic/errno.h>   修改为  #include <errno.h>



编译成功
LINK rtthread.elf
arm-none-eabi-objcopy -O binary rtthread.elf rtthread.bin
arm-none-eabi-size rtthread.elf
   text    data     bss     dec     hex filename
1717783   56628 6469356 8243767  7dca37 rtthread.elf
tools/mksunxi.exe rtthread.bin
bootloader size= 2200
The bootloader head has been fixed
scons: done building targets.

感谢分享 arm-none-eabi编译器的编译经验
工程是带sd卡读写的,有sd卡的话会挂载文件系统到/mmc目录,命令行下测试就好

离线

楼主 #17 2021-02-03 09:17:48

微凉VeiLiang
会员
所在地: 深圳
注册时间: 2018-10-28
已发帖子: 595
积分: 525
个人网站

Re: F1C100S玩游戏系列-FC红白机Nes模拟器(二)-移植正点原子的nes模拟器(ye781205的汇编核心),带声音,ARM转GNU汇编

myxiaonia 说:

大佬,我在你的菠萝派基础上制作了板子,现在发现运行一会儿就出现死机情况,而且pmic部分碰一下也会造成花屏死机问题,请问有什么经验指示吗

用的是之前的V1 V2版本么。5V处要加电容,不知道是不是这个原因,你可以加一个试下

离线

页脚

工信部备案:粤ICP备20025096号 Powered by FluxBB

感谢为中文互联网持续输出优质内容的各位老铁们。 QQ: 516333132, 微信(wechat): whycan_cn (哇酷网/挖坑网/填坑网) service@whycan.cn