In previous post I wrote that I'm taking a break from USB on RasPi for a while. I need some fresh air in order to keep myself concentrated on the work. If I would just stick at USB for longer it would develop at much slower pace. So, taking a break but staying with AROS, or with ARM.

I wrote you once that in the future there will be a possibility to use m68k binaries with AROS on RasPi, and I really mean it. So, few months ago I've started to look around for any available m68k emulators. And you know what? There are plenty of them. Hurray? No. They are either slow interpreters written eons ago as a proof of concept, or GPL licensed. Even though I find GPL ok and use it myself from time to time, I find it too restrictive in this case. Besides I wanted to try something new :)

So, here it goes, my new project on github - Emu68. The project is in very early stage and there is almost no code inside but hey, it's 4 days old, only.

What is Emu68? It is going to be a JIT emulator for 680x0 processors. It is not going to be a pure m68k emulation with all bells and whistles (maybe it will get the completeness later on), only the parts necessary to run the code.

Emu68 provides a large instruction cache, where blocks of up to 32 m68k instructions (this is a configurable parameter) are translated into blocks of ARM instructions. Each translation unit stored in the cache has two nodes - one is used to link the translation within a hash table (for quick fetches), another node is used to keep track of usage frequency. Here I am using simplest LRU strategy - newly added units are stored in front of the LRU, units which were in the cache and are fetched for execution are moved in front of LRU too, the units which are going to be flushed are removed form the end of the LRU queue. Please note that all this operations are O(1).

Within each block the JIT translator has 10 free ARM registers for its own use - as intermediate calculation results or as a cache for up to 8 m68k registers. Additionally, one ARM register is used as program counter for m68k and another one keeps the status flags. In order to reduce number of ARM instructions, the status flags are updated only if really necessary. If subsequent instruction is known to change some flags, these will be not updated by the current instruction. It saves a lot since nearly every single m68k opcode does affect the flags in some way.

What do I have already? Not much, but the bits and pieces work as expected:

Calculation of effective address combined with optional fetch or store from/to EA (combining it spares eventually one ARM instruction)

Nothing special, but I wanted to see if move.w works as expected (i.e. does not trash upper 16 bits) and if addi.b sets the CPU flags properly. Letting my JIT execute it generates following debug output:

Why 24 bit shifting? Because I do not want to calculate the status flags by myself. I prefer ARM cpu doing that for me. As you can see in the code, first two instructions load PC and SR (most frequently used, therefore always cached), then the m68k code begins. At the end of translation unit, all modified (dirty) registers are stored back in the m68k context. Finally, PC and SR are stored too and the code returns to JIT. Once the code returns I wrote back m68k context: