About a week ago I got an Arduino board for some project ideas. Naturally, one of the things I looked for was a free, cross-platform emulator that could run AVR code on a desktop machine. I only found one on Sourceforge which was started a few months ago but development seems to have stalled. So I decided to write my own. How hard could it be?
The AVR CPU is a pretty simple 8-bit microcontroller. Instruction words are all 16 bits wide, and only a handful of instructions have an additional 16 bit data word following the instruction. Given the instruction set reference, I wrote a script to help create a big 64k table of function pointers, one for each possible instruction. The main loop looks something like this:
for (;;) { u16 instr = Program[PC++]; Instr[instr](instr); }
This loads the next instruction word into instr
. Then that value is used as an index into the Instr
function pointer table, and calls the function at that index with the instruction word as an argument. The instruction implementation function can then pull apart the instruction word if it needs to. For example, this is the implementation of the LDI instruction, which loads a constant value into a register:
static void do_LDI(u16 instr) { // ----KKKKddddKKKK u16 K = (instr & 0xf) | ((instr >> 4) & 0xf0); u16 d = 16 + ((instr >> 4) & 0xf); Data.Reg[d] = K; Cycle++; }
It turns out there are only 93 distinct instruction words that need to be implemented. I've got 80 of the important ones working, plus some basic peripherals like the USART for serial communications, EEPROM storage, and the simplest timer that could possibly work. With that, many of the sample programs that come with the Arduino IDE run perfectly, plus it can run simple Java code using NanoVM!
I have a long list of ideas to build around this emulator core, including:
I called the emulator emulino, which in addition to being a combination of emulator and Arduino, also happens to be an obscure conjugation (third person plural present subjunctive) of the Italian verb emulare, "to emulate".
You can find the current code on Github in the emulino project.
2009-05-16T05:55:27Z