Hacker News new | ask | show | jobs
by nanochess 817 days ago
The simplest emulator in the world would be like this one:

unsigned char memory[65536];

int reg[8];

int main(void)

{

    int pc = 0;

    /* In this point you read something into memory */    

    while (1) {
        
        instruction = memory[pc];

        if (instruction == 0x76)  break;  /* HLT */

        pc = (pc + 1) & 0xffff; 

        if ((instruction & 0xc0) == 0x40)    /* Handle MOV r,r (opcodes 0x40-0x7f) */

            reg[(instruction >> 3) & 7] = reg[instruction & 7];

    }

    return 0;
}

What it does? It simply reads each instruction from memory (PC is the Program Counter), and increments PC continuously limiting it to 16-bit.

It does a comparison for each possible instruction, for this example I only handled the most basic one of 8080 (MOV r,r) and HLT, but this is already 64 cases of the 256 possible!

Then I added iteratively chunks of opcodes to emulate and used language C macros to reduce the code size. For example, there is #define d(e) to join two 8-bit registers into a 16-bit value, and #define Q to read the accumulator.

In the end, to stay inside the size limit of the IOCCC, I removed the tree of 'if' statements and replaced it with a tree of trinary operators ?: (a way of doing 'if' inside an expression) and this is what the macros C and S does.