I’ve been working on a virtual machine under 9front implementing the LC3 educational ISA. This has been a lot of fun, and I realise that probably sounds weird to a bunch of people who did CompSci at university and were made to do this sort of thing. In that sense I’m like a mature student - I’m actually doing it because I care.
Initially I started out when I was on a 7 week trip through Asia (I know, I never update this thing, but then nobody reads it either). I was in Kuala Lumpur and taking a much needed rest, and for some reason that I can’t quite remember I just decided to search “how to write a virtual machine” and a blog post came up which essentially lined up the problem of how you’d go about implementing LC3. So I just started.
And I continued in Nepal, where I finished off the majority of the VM and a
rudimentary assembler and patched
vexed hex editor for binary input to help
with my hand-hacked test machine code.
And I continued on a beach in Thailand, where I wrote the beginnings of an assembler.
Yesterday I reached an important milestone - I was able to assemble and run the following program:
.ORIG x3000 NOP ADD R2,R2,x6 ; we need 6 loops to get to 'h' NOT R2,R2 ; we want to be able to subtract this number so we'll 2's complements it ADD R2,R2,x1 LOOPH ADD R0,R0,xf ADD R1,R1,x1 ADD R3,R1,R2 ; compare if we're at 6 loops yet BRn LOOPH ADD R0,R0,xe OUT E .FILL x65 L .FILL x6c O .FILL x6f LD R0,E OUT LD R0,L OUT OUT LD R0,O OUT .BLKW x5 LEA R0,WRLD PUTSP HALT WRLD .STRINGZ x20776f726c64210a .END
Which runs thusly:
cpu% lc3/lc3 -f out.hex hello world! Program complete, exiting
I think it’s quite a fun “hello world” because I wrote it as I was implementing features of the assembler…
Up until the first
OUT (which was a
at the time) I only just had assembling into a binary format working, with none
of the raw data loading directives so I had to
ADD the largest positive value
ADD’s immediate mode (which only supports a 5 bit signed
operand) 6 times and then add the remainder to get to
To get the rest of
ello I then implemented
.FILL and (now that I think
about it) just let the machine blast through trying to interpret those
instructions (I should probalby fix that hahah), but this means that we’re then
LD those memory locations into
R0 which then means we can use the
OUT trap to print each one in turn.
Then we have
.BLKW which I didn’t have much use for in this program but it
was easy to implement after
.FILL so my implementation also initializes to
0x0 which maps to
NOP (or more strictly, unconditional branch to
.STRINGZ. As you can see, I’ve not implemented any data literals
other than hex yet, so I still have string literals and decimal to implement
but I don’t need those to demo that my VM is working.
I have some plans for this VM which I’m not going to talk about, because I’ve found in my life that talking about an idea to people often exhausts the need to actually follow through on it - needless to say it’s weird dumb bullshit like you’d expect from me.
The plans which I am going to talk about here are the 9p debugging features I’d like to implement.
Essentially, I’d like to write a filesystem which has something like the following layout:
reg/ pc cond r0 r1 r2 r3 r4 r5 r6 mem/ full 0/ 0/ 0/ 0 1 ... 1/ ... 1/ 2/ 3/ ... clk cons
The idea here is that you can read and update the state of any given memory
address or register at any point, and you can step the clock simply by reading
clk. You can follow the program along by reading
reg/pc and then reading
the corresponding address.
In fact, beyond that I doubt it would be that hard to also have a
tree as well which will allow you to follow along with a disassembled version
of the program.
This then means that your debugger is a simple filesystem API which you can
then instrument and script around using
awk, whatever. In that sense,
I’m kind of surprised that
acid was never designed in this way, because I’d
say one of the huge advantages of Plan 9 is that you don’t have to learn
someone’s implementation of a given API or language when you can simply explore
a filesystem and write tools to manipulate it.
Anyway, that’s what I’ve been up to.