GP32 Let's Flog A Dead Horse!


I'm a CS major as well, and my automata theory exams are in a couple of days. I have been thinking about the same material as you have. However, as a science major you should know that what you are proposing is not simply far fetched or even hard to execute. It's simply impossible since the code structure is so much degraded by the time a program turns binary that there's simply not enough information to decompile it into something remotely useful.

The main problem is that you can trace a stack when decompiling Java or Flash bytecode for instance, but it's much harder to trace a register set, because the sequence of instructions is pretty much lost. On top of that, functions are merely adresses in rom space, and are not named. Variables are also unnamed, and there's simply no way to retrieve information about structs and classes.

You don't need all of that information, you could simply convert each instruction of program A into a new instruction for program B. However, program B would need the data inside it's rom to be the same as in program A. Since you cannot see wich byte is code, and wich byte is data, you have to have both in memory. So you are essentially doubling the memory use for a given program.

Emulating I/O is also quite impossible since most gaming systems use memory mapped I/O. This means you have to recompile every memory access into a function or macro that checks wether that memory access is doing I/O. And you have to do this for EVERY memory access, making memory access so incredibly slow the program crawls.
 
The main problem is that you can trace a stack when decompiling Java or Flash bytecode for instance, but it's much harder to trace a register set, because the sequence of instructions is pretty much lost. On top of that, functions are merely adresses in rom space, and are not named. Variables are also unnamed, and there's simply no way to retrieve information about structs and classes.

Emulating I/O is also quite impossible since most gaming systems use memory mapped I/O. This means you have to recompile every memory access into a function or macro that checks wether that memory access is doing I/O. And you have to do this for EVERY memory access, making memory access so incredibly slow the program crawls.
It is fairly easy to get a stack trace in C... it has a well formed stack. (Never mind the fact that the ARM chip, in common with most CPU's, has instructions defined almost exclusively for calling functions & building the stack, so even if they are using lots of assembler, you'll still probably be able to do a stack trace).

Functions are only addresses, but you really don't need to know where the functions are. If you really want to, you can probably work out how many parameters each function takes, and some other info on the parameters, as C compilers have very regular function entry routines.

But all you really need to do in the GBA case is emulate the IO (which includes GPU and stuff). While you might have to do a macro for every memory IO, there are two reasons why this probably won't be as bad as you might expect:

1) A large number of read/writes will be absolutely specified addresses, so you will know if you need to do anything emulation wise. In addition, you'll probably be able to work out where most indirect accesses go at "conversion" stage too... this is what my friend does for a PhD. It is very hard, and doing it for GBA program would be a big leap above the state of the art (they have managed to do a similar thing with small PICs, with a few k of memory). However, you don't need to do it in every case, and you can leave little macro's in where you can't do this.

2) The CPU probably isn't doing that much data I/O... Large memory writes will probably be done through DMA, and ARM chips have lots of registers so they can do almost all their "working" without accessing memory.

Gone on about this subject a bit too much... however, would like to add my lot to the possible just improbable.

Also like to correct my statement about the Halting problem making it impossible... after some consultation, not really an issue.
There are problems with self modifying code, which could be an issue if any code is decompressed etc... However this is unlikely with the GBA architecture.
 
Last edited by a moderator:
Gaaah! Now you've done it! Why do you have to talk about such interesting things?!

I wanted to spend my spare time learning PalmOS and PPC. I don't really have time for other things, but now I want to write a GBA emu with a recompiler core. Damn you! ;)

Looking at it, seems the GP32 is the easiest platform to develope it for, until my PalmOS skills are better. No reason why I shouldn't run on both at the end (if it ever works at all).

As for the engine, well, I think the instructions are the least of our worries in regard to GBA. A lot of other memory locations should be able to be detected at compile time and handled accordingly, others will have to be handled whilst running. Thumb code could be recompiled to ARM, and SWIs changed to function calls.

self-modifying code and GBA *is* an issue - a lot of GBA code for example moves stuff from catridge ROM to WRAM, so it executes faster (as the ram requires fewer cycles), and this could be a problem.

To start with, I think something like the RotZoomer demo would be the first thing to emulate - mode 4 gfx, small asm code, no SWIs, etc.

Anyway, I'll have a go and see how it goes. I'll post my progress later on if I get anywhere. I know this will not be as fast as GPAdvance, as that is running completely native from the start, but hopefully this one will be more portable (if anything comes of it of course).
 
* Rico gives you an item: +4 Dr. Pepper of Deliciousness *

Now CODE!

Seriously you seem knowledgeable (and then some) so I really wish you luck with this ambitious project. If enf65 (a self-admitted coding n00b) and pump out something running homebrew, I think you can :)
 
Thanks :) I'm getting started writing the disassembler and 'decompiler'. I quote the last word because it just has an overall glance at the code and basically chops the code up into small pieces, guesses what it will be doing, calculates cycle timings etc. After that, I will try and write something that writes native code from this "knowledge base" that can be run by simply getting the processor to run it native.

Should be quite a fun project :)
 
self-modifying code and GBA *is* an issue - a lot of GBA code for example moves stuff from catridge ROM to WRAM, so it executes faster (as the ram requires fewer cycles), and this could be a problem.
May not be too bad... you should be able to "guess" jumps to WRAM in the same way as writes to video memory, then work backwards to work out the code that needs converting.

OK... that may be too bad. And doesn't solve the problem of, say, some code being held compressed on the rom before being decompressed to memory.... That would be extremely hard to do.

Is there any reason to convert Thumb code to ARM? Although it occurs to me that working out whether code is Thumb or ARM could be another difficulty... Don't know if they can be distinguished on a byte by byte basis.

Sorry, this is all stuff quite away in the future I imagine.
 
Last edited by a moderator:
Well, I've been playing with this and I don't think a pure compiler is that practical - it works with anything small, but falls over otherwise.

I'm going to a try an Interpretive+Compiler approach where parts are compiled, and the other parts are interpreted (with the emu breaking the roms into chunks of code and guessing which way to do the execution).

Remember, my goal here isn't to make the fastest emulator (I'd use the MMU like GPAdvance if I wanted that), but rather make a portable ARM-based emulator, so it should work on any ARM device 166mhz+
 
Back
Top