Assembler and emulator for Octornado, an 8-bit CPU

I haven’t started making the CPU yet, but I’ve written an assembler and emulator and made a git repo for it.

The file assembler.py is the assembler, while emulator.py is the emulator.

Here’s the two working together to run an assembly program:

martin@magni ~/cloud/dev/octornado-cpu main* $ cat test.s
mov r7 stack_start
st retaddr
mov r1 data
jmp strlen
retaddr:
        halt

strlen:
        mov r0 0
        mov r2 r7
        mov r7 r1

strlen_loop:
        ld r1
        cmp r1 0
        jeq strlen_exit
        add r0 r0 1
        add r7 r7 1
        jmp strlen_loop

strlen_exit:
        mov r7 r2
        ld r1
        jmp r1

data:
        byte 'H'
        byte 'e'
        byte 'l'
        byte 'l'
        byte 'o'
        byte ' '
        byte 'w'
        byte 'o'
        byte 'r'
        byte 'l'
        byte 'd'
        byte '\0'

stack_start:
martin@magni ~/cloud/dev/octornado-cpu main* $ ./assembler.py test.s test.bin
martin@magni ~/cloud/dev/octornado-cpu main* $ ./emulator.py test.bin
Registers after execution:
[11, 8, 46, 0, 0, 0, 0, 46]

With my calling convention, register 0 is the return register, so strlen(data) correctly returns 11. (Registers 1, 2 and 3 are arguments and caller-saved, register 7 is the RAM address register and used by the calling convention as a stack pointer.)

3 Likes

That’s pretty cool

NIce!