Porting zsnes to arm-based machines *not a request*

Strictly for discussing ZSNES development and for submitting code. You can also join us on IRC at irc.libera.chat in #zsnes.
Please, no requests here.

Moderator: ZSNES Mods

Post Reply
Lint
New Member
Posts: 6
Joined: Tue Dec 05, 2006 9:58 pm
Contact:

Porting zsnes to arm-based machines *not a request*

Post by Lint »

Hi

I used to program assembly a long time ago (i386/i486 era, not a clue about mmx instructions indeed) and I already cared to search that the main problem of porting zsnes is that it's based in x86 assembly (so let no one flame me by this)

I'm no arm assembly programmer indeed (there are almost no asm programmers for arm that I know, but I'm starting to learn that) but I'm thinking about porting that x86 asm code to arm asm code, since arm have 15 general-purpose registers we could have a direct replacement for eax = r4, ebx = r5 and so on, right? and still have some registers to deal with in a pinch...

does anyone knows if that has been already tried? (yes, I already searched and found nothing about it)
would the latest zsnes be the best choice to try porting? (I think earlier versions would have support for less things and so less work to do, and the arm processor is not going to have enough power to emulate starfox and things like that anyway)

Any help would be appreaciated, even better if it's something regarding zsnes source that could save me from having trouble...
As the main target is a GP2X console, the desired binary would be a sdl based arm linux (running windows at this time is not doable because I don't have any windows installed on my computer)
mog123
Hazed
Posts: 62
Joined: Sat Apr 01, 2006 11:33 pm

Post by mog123 »

first of all there are many ARM ASM programmers. flubba is one of them.

NDS and GBA use ARM processors, also new nokia N series use the ARM processors.

Go to pocketheaven.com/boards/index.php
My general dev blog:
http://mog123x.blogspot.com
Deathlike2
ZSNES Developer
ZSNES Developer
Posts: 6747
Joined: Tue Dec 28, 2004 6:47 am

Re: Porting zsnes to arm-based machines *not a request*

Post by Deathlike2 »

Lint wrote:Hi

I used to program assembly a long time ago (i386/i486 era, not a clue about mmx instructions indeed) and I already cared to search that the main problem of porting zsnes is that it's based in x86 assembly (so let no one flame me by this)

I'm no arm assembly programmer indeed (there are almost no asm programmers for arm that I know, but I'm starting to learn that) but I'm thinking about porting that x86 asm code to arm asm code, since arm have 15 general-purpose registers we could have a direct replacement for eax = r4, ebx = r5 and so on, right? and still have some registers to deal with in a pinch...

does anyone knows if that has been already tried? (yes, I already searched and found nothing about it)
would the latest zsnes be the best choice to try porting? (I think earlier versions would have support for less things and so less work to do, and the arm processor is not going to have enough power to emulate starfox and things like that anyway)

Any help would be appreaciated, even better if it's something regarding zsnes source that could save me from having trouble...
As the main target is a GP2X console, the desired binary would be a sdl based arm linux (running windows at this time is not doable because I don't have any windows installed on my computer)
It's rather unrealistic. If you think you can deal with the source code where it is still approximately 75% ASM, then go for it. I don't think anyone else has attempted simply because of this mere fact.
Continuing [url=http://slickproductions.org/forum/index.php?board=13.0]FF4[/url] Research...
BRPXQZME
Hazed
Posts: 54
Joined: Tue May 30, 2006 3:47 am
Location: Centreville, VA
Contact:

Post by BRPXQZME »

You'd have my eternal respect if you could actually pull it off. It's nigh impossible because of the sheer volume of code in assembly, (and to be efficient, you wouldn't just map one register to another, you'd have to refactor them all to get the best use out of your ARM... because otherwise what you're doing is emulating an x86 on an ARM. The hard way.)

There are a couple of options, though.

You can just use the ~25% C code and re-write ALL missing parts as necessary (probably best done writing in C and converting it to assembly where you need the extra efficiency). Chief problem is that you still have a lot to re-write. You will probably end up with something that looks nothing like ZSNES on the inside, but on the outside you'd have something that looks like ZSNES to a cursory glance (at that point, you'd have an entirely differnt emulator in fact, since the code that runs things is entirely different, though it may work in a fashion much inspired by the original). By my estimate you'd have to translate about 165000 lines of code (you can cut quite a few more corners than what I'm considering, but only so much!).

You could give up on trying ZSNES to ARM (I know I would, I don't have that kind of dedication) and direct your efforts at improving a C-based or GP2X/ARM-centric emulator. GP2X has a few SNES emus as it is, I believe. You could show another system some love, or perhaps do something daring and ambitious (I've seen emulation of PSX done on an three-year old Dell Axim... now GP2X isn't as fast as that, but with a bit of work you could probably get something like FFT going... of course, you don't have a lot of space!).

A few people have tried to port it to PowerPC, but I ain't seen any such effort become fruitful. Or even produce any code.
Jipcy
Veteran
Posts: 768
Joined: Thu Feb 03, 2005 8:18 pm
Contact:

Post by Jipcy »

The primary reason that ZSNES is very fast is that it has a lot of x86 ASM, right? Could bsnes be comparatively as fast if someone ported as much as possible of that code to ARM ASM? I'm not intimately familiar with bsnes' code, but I think I recall that there was a (relatively) easy way to compile that emulator so that it has opcode-level accuracy, rather than the cycle (or whatever) accuracy it has usually. And I know byuu has made a strong effort to keep his code simple and clean. It *might* be easier to just port his C++ code to ARM ASM instead of ZSNES' x86 ASM to ARM ASM.

This is all just an uneducated opinion from a non-programmer, however.
[url=http://zsnes-docs.sf.net]Official ZSNES Docs[/url] | [url=http://zsnes-docs.sf.net/nsrt]NSRT Guide[/url] | [url=http://endoftransmission.net/phpBB3/viewtopic.php?t=394]Using a Wiimote w/ emulators[/url]
Nach
ZSNES Developer
ZSNES Developer
Posts: 3904
Joined: Tue Jul 27, 2004 10:54 pm
Location: Solar powered park bench
Contact:

Post by Nach »

Jipcy wrote:The primary reason that ZSNES is very fast is that it has a lot of x86 ASM, right?
Probably not. The primary reason ZSNES is so fast is that it emulates in a manner to make the process almost native with little overhead. The SNES code in some sense is ran as opposed to interpreted and acted upon. It's possible to do this in C, but easier for some stuff to be done in assembly. If other emulators used some of the methods ZSNES did, they would be much faster.
May 9 2007 - NSRT 3.4, now with lots of hashing and even more accurate information! Go download it.
_____________
Insane Coding
Lint
New Member
Posts: 6
Joined: Tue Dec 05, 2006 9:58 pm
Contact:

Post by Lint »

@Mog123:
Yep, I know there are some persons over the world who do program arm assembly, but I (personally) don't know any, even x86 assembly programmers are very hard to find nowadays, and the code is to be ran on a GP2X (I had one, so I could try on it) but anyone can port that code to GBA, Nokia N, i-MX21 or any other arm machine

@BRPXQZME:
This idea of register-mapping is the cornerstone of my idea, we all know for sure that it would not be as fast as a natively written emulator in arm asm, but writing a whole emulator for a system that I have almost no knowledge about is way more harder than trying this, don't you agree? That also the reason why I don't try to port zsnes asm->C, because I would have to understand all the functionalities of the program, while porting this way I will try to keep things away from upper logic

SNES emulators for gp2x are C++ based, that sucks, and that's one of the reasons why I do believe that even using x86 assembly disguised as arm, still it could be faster than with C++

@All:Zsnes is knew to be the fastest SNES emulator (at least afaik, there's a long time since I played any snes emulator on PC indeed...), so if I'm going to try, I should try with the fastest, even why there's the possibility that I finish it but it ran slow because of the poorly-written asm usage, if I ever come to that point I'll be already much proud of myself

Last but not least, don't expect that to be completed any month soon if ever completed, I have the sure feeling that even compiling everything into arm-asm, the resulting code will be somehow bugged and will not run anything, but at least I'll have learned a lot of arm assembly, so having a emulator that just segfaults would worth for me as fun, knowledge and mainly a proof of time wasted :(
Nach
ZSNES Developer
ZSNES Developer
Posts: 3904
Joined: Tue Jul 27, 2004 10:54 pm
Location: Solar powered park bench
Contact:

Post by Nach »

Lint wrote:even x86 assembly programmers are very hard to find nowadays
I wouldn't say that. Half the people who post in this section of the forum know x86 assembly. I can name at least a dozen right off the bat.
May 9 2007 - NSRT 3.4, now with lots of hashing and even more accurate information! Go download it.
_____________
Insane Coding
FitzRoy
Veteran
Posts: 861
Joined: Wed Aug 04, 2004 5:43 pm
Location: Sloop

Post by FitzRoy »

Lint wrote: @All:Zsnes is knew to be the fastest SNES emulator (at least afaik, there's a long time since I played any snes emulator on PC indeed...), so if I'm going to try, I should try with the fastest, even why there's the possibility that I finish it but it ran slow because of the poorly-written asm usage, if I ever come to that point I'll be already much proud of myself

Last but not least, don't expect that to be completed any month soon if ever completed, I have the sure feeling that even compiling everything into arm-asm, the resulting code will be somehow bugged and will not run anything, but at least I'll have learned a lot of arm assembly, so having a emulator that just segfaults would worth for me as fun, knowledge and mainly a proof of time wasted :(
Why go through the trouble of converting all that code? If you did bsnes, by the time you finished, the GP3X would be out to run it at 60fps. It doesn't matter if zsnes could run it at 2000fps. The future dissolves the speed issue and it saves future programmers from spending countless more hours doing another port to improve upon the accuracy of the old one. And even that isn't assured to happen since the snes is getting older and less interest from new talent every day. And even if there was interest, the existence of a port that is complacently close to accurate could deter them from doing anything for that system.
www.zapatabase.com
gladius
Rookie
Posts: 16
Joined: Wed Nov 30, 2005 8:10 am
Contact:

Post by gladius »

There already are cpu cores written for the DS/GBA in arm assembly. You'd have to rewrite the graphics routines as they make use of the tile hardware, but a huge chunk of your work is done.

Check out http://snezzids.bountysource.com.

Oh, and ARM assembly programmers aren't as rare a species as you might think :). Most game developers on GBA/DS are pretty experienced in it.
Deathlike2
ZSNES Developer
ZSNES Developer
Posts: 6747
Joined: Tue Dec 28, 2004 6:47 am

Post by Deathlike2 »

FitzRoy wrote:
Lint wrote: @All:Zsnes is knew to be the fastest SNES emulator (at least afaik, there's a long time since I played any snes emulator on PC indeed...), so if I'm going to try, I should try with the fastest, even why there's the possibility that I finish it but it ran slow because of the poorly-written asm usage, if I ever come to that point I'll be already much proud of myself

Last but not least, don't expect that to be completed any month soon if ever completed, I have the sure feeling that even compiling everything into arm-asm, the resulting code will be somehow bugged and will not run anything, but at least I'll have learned a lot of arm assembly, so having a emulator that just segfaults would worth for me as fun, knowledge and mainly a proof of time wasted :(
Why go through the trouble of converting all that code? If you did bsnes, by the time you finished, the GP3X would be out to run it at 60fps. It doesn't matter if zsnes could run it at 2000fps. The future dissolves the speed issue and it saves future programmers from spending countless more hours doing another port to improve upon the accuracy of the old one. And even that isn't assured to happen since the snes is getting older and less interest from new talent every day. And even if there was interest, the existence of a port that is complacently close to accurate could deter them from doing anything for that system.
I think you're forgetting to factor in the CPU that is being ported to. Very likely it is not as fast as even the more commonly found CPUs in today's PCs. BSNES would not be ideal for this purpose.
Continuing [url=http://slickproductions.org/forum/index.php?board=13.0]FF4[/url] Research...
FitzRoy
Veteran
Posts: 861
Joined: Wed Aug 04, 2004 5:43 pm
Location: Sloop

Post by FitzRoy »

The GP3X is still a few years off. I would give it a chance to pull it off. If not, a frameskip of 1 is not a bad consolation until GP4x. I disagree with continuous development strategies for immediate satisfaction.
www.zapatabase.com
Lint
New Member
Posts: 6
Joined: Tue Dec 05, 2006 9:58 pm
Contact:

Post by Lint »

You see, I said that about assembly programmers in comparsion against other languages, at least over here, I know like a hundread java programmers, a dozen C programmers and a couple of asm programmers in a best case scenario (in real life, of course I know there still are asm programmers at linuxassembly.org, zsnes.com and some other sites, and I salute everyone of them/us) and game developers too!

anyway, nevermind :P

@Fritzboy: as I've said, I don't know anything about SNES, all I know is that it have a gamepad with 7 buttons and a directional..... I could help an on-going project, but somebody gonna have to teach me everything about it or wait for me to learn before I can develop something, right? and I don't know if I'm on that mood to go all this way, really..

The reasons for me to make this topic are: I know x86 assembly and I want to learn arm asm, as I work part of the time with arm machines, I have a gp2x and want it to play snes decently, other platforms I would have to send the emu to someone else every time I would try/test out something... So it may be not a good deal, I may probably giving up with nothing but strange arm-asm code, but I'm definitely good rated for this particular job...

@gladius: thanks man, I really appreciate that, if I ever finish half of this someday, I'll try to merge that with zsnes' code to see if it play something.. or perhaps try to contribute with some other hardware code, I know that sooner or later I'll be understanding much, much more about snes than ever before
PHoNyMiKe
Retrosexual
Posts: 1011
Joined: Wed Jul 28, 2004 2:09 am
Location: Rapture

Post by PHoNyMiKe »

I know arm asm, it's easy as hell and 32bit baby. nobody wants to go through however many megabytes of zsnes code and convert it line by line to any language. and no you can't use notepad and just have it replace a few occurances of shit. this would take months of intense work.
[url=http://www.alexchiu.com/affiliates/clickthru.cgi?id=phonymike]ultimate immortality[/url]
[url=http://www.sloganizer.net/en/][img]http://www.sloganizer.net/en/image,zsnes,white,purple.png[/img][/url]
FitzRoy
Veteran
Posts: 861
Joined: Wed Aug 04, 2004 5:43 pm
Location: Sloop

Post by FitzRoy »

lol, Fritzboy.

So what's wrong with the snes9x port to gp2x that a zsnes port would solve?
www.zapatabase.com
BRPXQZME
Hazed
Posts: 54
Joined: Tue May 30, 2006 3:47 am
Location: Centreville, VA
Contact:

Post by BRPXQZME »

Lint wrote:@BRPXQZME:
This idea of register-mapping is the cornerstone of my idea, we all know for sure that it would not be as fast as a natively written emulator in arm asm, but writing a whole emulator for a system that I have almost no knowledge about is way more harder than trying this, don't you agree? That also the reason why I don't try to port zsnes asm->C, because I would have to understand all the functionalities of the program, while porting this way I will try to keep things away from upper logic

SNES emulators for gp2x are C++ based, that sucks, and that's one of the reasons why I do believe that even using x86 assembly disguised as arm, still it could be faster than with C++
I find it doubtful that all the SNES emulators for GP2X are 100% C/C++, because if they are, then they're either not trying or they're trying too hard. GP2X isn't that fast of a system. However, its processor has some advantages over, say, a Pentium with the same clock rate. I'd take issue with not using those advantages, one of which is more registers. More registers means less swapping them out in certain situations, among other things.

Also, more important than knowing x86 or ARM assembly, would be knowing the SNES internals, even if you only know a little. It's more important to understand why an emulator does something a certain way than to copy exactly what it does (just an example: When they wrote the floating-point code for PCSX2, first they thought, "okay, so we lose a little precision by using native x86 floating point, but that should be okay, right? We won't really need all that many digits....". This thought was incorrect, as they quickly ascertained. In the end, they had to use SSE to manage these floating point numbers with any kind of speed at all. Now imagine you were to make a PS2 emulator for, say, some futuristic MIPS platform, and you were looking over this floating point code. If you didn't know why they did the SSE code that way, you'd either be porting in some serious performance issues, or wondering why those idiots didn't just use normal floating-point... or you'd figure out why they did it, and you'd have to concede that it was the only good way.). You simply WILL NOT get away with not knowing this if you are changing that much code.

NOTE: but don't think that 'impossible' is a word that is in my dictionary, because it isn't. I'm just telling you you're probably better off taking a more traditional approach even if you take a lot of inspiration and guidance from the ZSNES code.
Lint
New Member
Posts: 6
Joined: Tue Dec 05, 2006 9:58 pm
Contact:

Post by Lint »

@phOnYmIkE: Hey, that's good to hear, so you're going to help or your going just to complain that it's too much work?
I mean, if it's too much work for one person, then I'm assuming that you wanna join in, right? there are plenty of source for everybody to spend some time.... even why, that's not just x86 to arm translation, there's also NASM (intel) to GAS (at&t) syntax translation, which I know that sooner or later will lead to some mistakes, besides that limited macro capatibilities of gas......

And hey, thanks for letting me know that I can't use notepad, for an instance I thought that all I needed to do was to compile zsnes with the --please-produce-arm9-output command line switch on nasm, you know?
(that means you should read when I say that I don't care if it come to nothing, as it costs to me pretty much the same)

FitzRoy: Oh, sorry man.. What's wrong: they don't have enough speed.

BRPXQZME:(and perhaps anybody else) Most of the code of that emus are C++ based on snes9x's code, there is some very, very little C code and even less arm assembly code, still falls into the problem that I have to understand much about the system.. I guess if someone rewrite just cpu or video emulation we could reach reasonable speed emulation overclocking these devices and the job is done, but I would not learn arm assembly (at least not as much), so everybody's happy but me :( And also I'd liked this (insane) idea of doing asm-asm translation, it's like human-aided static recompilation of an emulator...

Besides, after doing that I'll be free, willing to and capable of optimizing some of the code that had been translated, on a experimental basis, even if speed is already enough, or to implement a lot of gp2x specific changes that will be made necessary...

I thougt that based on the simplicity of the idea, more people would be attracted to help, as the only limitating factor is not to fear the size of the job, I even think that most of the people who took time to answer this is actually capable of helping if willing to, so from 8 people here, let's say 5 started to help me, we would have translate 25k lines each leaving just 40k lines to me (if that 165k lines is true), that's much easier now, and in that 25k lines, 15k at least will be just replaced by search/replace functions, like jmp -> bx, call -> bl + st lr, mov eax, -> mov r0,, etc...

I agree I'll not get away with a good version, but if I start to read a lot about snes and try to optimize everything so the code would be best, it will be even more probable that I give up in the middle of the way, so finishing a lame version and having some optimizations later would give better results than trying to do it right already in the first run and facing some (much) created bugs during optimization ending with a very fast and very useless code

Calling conventions are different in x86 and in arm, so I know that there is some code that have to be completely rewritten, that's part of the job (and that's just to name one of the changes), any routine that took use of mmx will have to be rewritten too and so on..

I already started to write things, but so far I'm only degladiating these nasm/intel to gas/at&t macro differences found on macros.mac
funkyass
"God"
Posts: 1128
Joined: Tue Jul 27, 2004 11:24 pm

Post by funkyass »

techincally, most of snes9x is C.

you are facing one issue, and its a big one.

ARM is RISC based, x86 is CISC

so it has the same number of registers, you still have to rewrite every line of ASM, and it being RISC, you might be more flexible in running more SNES instructions natively than what ZSNES is currently doing.
Does [Kevin] Smith masturbate with steel wool too?

- Yes, but don’t change the subject.
blargg
Regular
Posts: 327
Joined: Thu Jun 30, 2005 1:54 pm
Location: USA
Contact:

Post by blargg »

The nice thing about modern RISC processors is that you can code in C or C++ and still get good performance, because things map so closely. This especially applies to architectures that use a three-operand instruction format (i.e. ADD r0,r1,r2 that does r0 = r1 + r2 instead of ADD r0,r1 that does r0 = r0 + r1). Use plenty of local variables and mind your loads and stores and you don't have to drop into assembly language unless you're doing truly low-level things. GCC's got some nifty options to keep global variables in a register at all times, which can help avoid extra parameter passing.
Deathlike2
ZSNES Developer
ZSNES Developer
Posts: 6747
Joined: Tue Dec 28, 2004 6:47 am

Post by Deathlike2 »

funkyass wrote:techincally, most of snes9x is C.

you are facing one issue, and its a big one.

ARM is RISC based, x86 is CISC

so it has the same number of registers, you still have to rewrite every line of ASM, and it being RISC, you might be more flexible in running more SNES instructions natively than what ZSNES is currently doing.
Well, x86 processors nowadays are becoming more RISC-like. They aren't RISC of course, but meh.
Continuing [url=http://slickproductions.org/forum/index.php?board=13.0]FF4[/url] Research...
Lint
New Member
Posts: 6
Joined: Tue Dec 05, 2006 9:58 pm
Contact:

Post by Lint »

now we're talking :)

that's a fact: some instructions on a cisc CPU have to be translated into many risc CPU instructions, let's take an example:

in init.asm to inir-arm.s, at line 179 you'd have:
shl word[SnowData+edx*2],8
: shift left the word at SnowData(imediate) + edx times 2 by 8

definitely you'll not have one single risc instruction to to that, and it's even worse that arm is capable of manipulating 8bit or 32bit elements, but it has no support for 16 bits, right now I'm in doubt if it's better to rewrite all the procedure or keep on strict emulation on a per-opcode basis, performance is no concern at the moment, but I'm wondering about coding ease and compatibility.. probably I'll stick on per-opcode basis for compatibility unless it come to something slow as 16-bit processing

anyway there are many x86 opcodes translated into a single arm opcode, so I should call it almost even:
still, arm is dword aligned in it's code and have a better mips/mhz ratio than x86, so I think that still the code is going to be at least as fast as x86 version... how does zsnes run on a 233mhz pentium machine?

and yes, sometimes C compilers do a very clean job thanks to the bunch of registers that it can use, indeed I'm still afraid about what takes so long for SNES emulation to take off on gp2x/arm devices... and wonder why Squidgesnes, GP2X's fastest snes emulator have so much C++ code, perhaps I should take a look again, but I'm sure that it have plenty of C++ code and very little arm assembly code...
sephiroth111

Post by sephiroth111 »

Lint wrote:now we're talking :)
definitely you'll not have one single risc instruction to to that, and it's even worse that arm is capable of manipulating 8bit or 32bit elements, but it has no support for 16 bits, right now I'm in doubt if it's better to rewrite all the procedure or keep on strict emulation on a per-opcode basis, performance is no concern at the moment, but I'm wondering about coding ease and compatibility.. probably I'll stick on per-opcode basis for compatibility unless it come to something slow as 16-bit processing
you DO know you can use the THUMB present in the GP2X unit to process 16 bit instructions right? its also built into the GBA. The arm9 main cpu has a thumb unit, just like the GBA, that means you can process 16bit thumb instructions. THUMB asm is different, though I haven't done enough asm coding to know how though.

I'm familiar with the inner workings of the GP2x, though i can only program in C.
Lint
New Member
Posts: 6
Joined: Tue Dec 05, 2006 9:58 pm
Contact:

Post by Lint »

Yeap, the processor runs arm9tdmi, which is capable of running thumb instructions, but I've found that LDRH/STRH do what I've wanted to do (and that is to load/store 16-bit data), and so far I haven't tried that out (no time) but I'm quite confident with that

Also, thumb instructions are more like "compressed code", definitely not aiming those who want to take best performance out of an arm processor, and in thumb mode I'll not have access to registers r8-above, that lacks esi, edi and ebp for now (esp and eip can be handled), so there should be very little usage of thumb mode on this one, I think...

I started to port that and came to the conclusion that's an enormous job (we all already knew it) but I still think that's human-makeable, altough I've started to write a simple source-converter in C to see how much can it help me
Post Reply