Made from 100% programmer art.

Support Me

Related Posts

How to Write Emulator - Fetch Decode Execute Cycle
The beating heart of any CPU is the fetch-decode-execute cycle. It is the same for our simulator
Read More…
How to Write Emulator - Opcodes Jumptables
How to efficiently store and execute many small functions, without using a single if statement or switch
Read More…
How to Write Emulator - Intro
A short series on how to write an emulator for the programming game Core War
Read More…

How to Write Emulator - Automating Tedious Programming with Excel

You’ll need a spreadsheet

It doesn’t matter which one, I wrote Excel because it’s the most popular and is more likely to appear in search results than Google Sheets, but that’s the one I really used in this example.

The problem

Imagine you have a lot of fairly similar code, for example this is the code for the “disassemble” function in my Redcode simulator

switch (ins.opcode) {
    case DAT:ret.opcode = "DAT"; break;
    case MOV:ret.opcode = "MOV"; break;
    case ADD:ret.opcode = "ADD"; break;
    case SUB:ret.opcode = "SUB"; break;
    case MUL:ret.opcode = "MUL"; break;
    case DIV:ret.opcode = "DIV"; break;
    case MOD:ret.opcode = "MOD"; break;
    case JMP:ret.opcode = "JMP"; break;
    case JMZ:ret.opcode = "JMZ"; break;
    case JMN:ret.opcode = "JMN"; break;
    case DJN:ret.opcode = "DJN"; break;
    case CMP:ret.opcode = "CMP"; break;
    case SEQ:ret.opcode = "SEQ"; break;
    case SNE:ret.opcode = "SNE"; break;
    case SLT:ret.opcode = "SLT"; break;
    case SPL:ret.opcode = "SPL"; break;
    case NOP:ret.opcode = "NOP"; break;
}

This painful looking code does the tedious thing of turning an enum value into a string representation of that enum value (yes, there are more automated ways of doing this, but they’re just plain weird) so it can be printed out. Boring, easy code. Just copy-paste-edit until they’re all done.

Except with a bit of spreadsheet magic you can do the same thing in a few seconds, which is really handy when you then have to type out code like this:

opcodeTable[DAT] = &opDAT;
opcodeTable[MOV] = &opMOV;
opcodeTable[ADD] = &opADD;
opcodeTable[SUB] = &opSUB;
opcodeTable[MUL] = &opMUL;
opcodeTable[DIV] = &opDIV;
opcodeTable[MOD] = &opMOD;
opcodeTable[JMP] = &opJMP;
opcodeTable[JMZ] = &opJMZ;
opcodeTable[JMN] = &opJMN;
opcodeTable[DJN] = &opDJN;
opcodeTable[CMP] = &opCMP;
opcodeTable[SEQ] = &opSEQ;
opcodeTable[SNE] = &opSNE;
opcodeTable[SLT] = &opSLT;
opcodeTable[SPL] = &opSPL;

Break out the spreadsheet!

Rather than seeing this as separate rows of text, see it as columns of text, most of which are identical. The only bit that changes is the “DAT”, “MOV”, “ADD” part.

So make your spreadsheet contain those columns…

Notice how there’s a formula in cell D1 to copy the contents of B1, to save re-typing the opcode out.

Next, type out all the opcodes into column B. This takes some effort, but it’s the only time you’ll need to do it

And now, make use of the amazing drag-fill feature built into every spreadsheet program since the mid 90s and watch the code write itself…

Now all you need to do is copy-paste the spreadsheet into your code editor

opcodeTable[	DAT	] = &op	DAT
opcodeTable[	MOV	] = &op	MOV
opcodeTable[	ADD	] = &op	ADD
opcodeTable[	SUB	] = &op	SUB
opcodeTable[	MUL	] = &op	MUL
opcodeTable[	DIV	] = &op	DIV

Now, the only thing to watch out for is that pasting the code will result in a tab character being put between each cell. This may or may not be what you want. If you don’t like it, just use your editor’s search-and-replace functionality to search for the tab character, and replace it with nothing. Can’t type in a tab character into the search-replace box? Just copy and paste one out the code.

Notice that if that code above was C++ it wouldn’t compile, due to the missing semi-colon? Well fixing that is just a case of adding one to the end of the spreadsheet and dragging it down.

Did you like this post?

if you did, it'd be really nice if you shared it, or left a comment below

Leave comments here!