Friday, February 06, 2009

ARM emulation

Yesterday, I decided to implement my own ARM code emulator.

I think my problems with getting AWRender to work have been to do with self modifying ARM code in the AWRender module. I had a half-hearted go at finding a way to implement OS_SynchroniseCodeAreas with QEMU, then I decided to just implement my own.

The interface is very simple: global storage for the registers, and a routine that returns a pointer to some x86 code that implements whatever ARM code is pointed to by r15 on entry. The x86 code will return when it comes to an instruction it can't deal with by itself, such as a SWI or a floating point operation.

The idea is to keep the emulator as the core of an ARM system, and anything else that needs emulating (like an Operating System, or a co-processor) will be taken care of outside the core. That way, I think, I can create something that can be finished!

I'm moving away from QEMU for a couple of reasons. Firstly, because it does much more than I need and it's heading off in a direction of increased complexity. For example, when I found a bug in the (latest release) version I was using, I discovered that later versions (with that bug long since fixed) don't work the same way as the one I had been working with, and I was told that, surprisingly, I didn't really want to use it that way!

Another reason is that a stripped version of the QEMU library is a little under half a megabyte in size (478568 bytes, to be specific), whereas my replacement is about 8k, at the moment, with maybe half the instruction set dealt with (bearing in mind that floating point is a co-processor feature). Perhaps I could strip QEMU down, but not that far, and not that quickly.

QEMU has given me some good ideas about how to approach the problem, but it's too bloated for my liking, now.

Update: It's going quite well.

It took me a while to work out that the x86 uses the carry flag in the opposite way to the ARM when subtracting, that jb isn't quite the same as BHI, and a day and a half to realise that I'd implemented BIC as AND instead of AND NOT.

Anyway, I'm now at the point where I have to start looking at which SWIs to emulate in order to get AWRender to, well, render something. I've chosen to attempt to get the freely available ArtWorks renderer working as a proof of concept for the compatibility layer (the whole thing isn't free, but apparently very good). Unfortunately, the application doesn't work out of the box, because the BASIC uses inline assembler and Brandy ( doesn't include that. I'll ask on comp.sys.acorn.programmer if there's an alternative that does.


Post a Comment

Subscribe to Post Comments [Atom]

<< Home