+.data
+.org 0x10
+inputdata:
+.fill
+stack:
+.fill 256, 0
+jumptable:
+;0
+.fill 0, vm_eof
+.fill 40, vm_default
+;42
+.fill 1, vm_mul
+;43
+.fill 1, vm_add
+;44
+.fill 1, vm_default
+;45
+.fill 1, vm_sub
+;46-47
+.fill 2, vm_default
+;48-57
+.fill 10, vm_consts
+;58-59
+.fill 2, vm_default
+;60
+.fill 1, vm_lessthan
+;61-67
+.fill 7, vm_default
+;68
+.fill 1, vm_dup
+;69-72
+.fill 4, vm_default
+;73
+.fill 1, vm_imm
+;74
+.fill 1, vm_jmp
+;75-79
+.fill 5, vm_default
+;80
+.fill 1, vm_pop
+;81-87
+.fill 7, vm_default
+;88
+.fill 1, vm_xch
+;88-125
+.fill 40, vm_default
+;126
+.fill 1, vm_not
+;127-255
+.fill 129, vm_default
+
+.text
+main:
+ ldi r1, inputdata
+ call+ vm
+ br+ main
+
+vm:
+ ;r1 ... addr to input
+ ;r2 ... pc
+ ;r3 ... effective stack address
+ ;r4 ... effective input addr
+ ;r5 ... input
+
+ ;set pc to -4
+ ldis r2, 0xFFFF
+ ;load base address of stack
+ ldi r3, stack
+
+vm_default:
+vm_loop:
+ ;increment pc
+ addi r2, r2, 1
+ ;generate effective input addr
+ add r4, r1, r2
+ ;load input
+ ldw r5, 0(r4)
+ ;jump to instr
+ brr r5
+
+vm_eof:
+ ;load stack[sp-1]
+ ldw r0, 0-4(r3);
+ ret+;
+
+;case *
+;42
+vm_mul:
+ br+ vm_loop
+
+;case +
+;43
+vm_add:
+ ;decrement sp
+ subi r3, r3, 4
+ ;load sp
+ ldw r6, 0(r3)
+ ;load sp-1
+ ldw r7, 0-4(r3)
+ ;sp-1 = sp-1 + sp
+ add r7, r7, r6
+ ;store sp-1
+ stw r7, 0-4(r3)
+ br+ vm_loop
+
+;case -
+;45
+vm_sub:
+ ;decrement sp
+ subi r3, r3, 4
+ ;load sp
+ ldw r6, 0(r3)
+ ;load sp-1
+ ldw r7, 0-4(r3)
+ ;sp-1 = sp-1 - sp
+ sub r7, r7, r6
+ ;store sp-1
+ stw r7, 0-4(r3)
+ br+ vm_loop
+
+;case 0 1 2 3 4 5 6 7 8 9
+;48-57
+vm_consts:
+ ;input minus offset
+ subi r6, r5, 48
+ ;store onto stack
+ stw r6, 0(r3)
+ ;increment stack addr
+ addi r3, r3, 4
+ br+ vm_loop
+
+;case <
+;60
+vm_lessthan:
+ ;decrement sp
+ subi r3, r3, 4
+ ;load sp
+ ldw r6, 0(r3)
+ ;load sp-1
+ ldw r7, 0-4(r3)
+ ;load r8 with 0
+ ldi r8, 0
+ ;compare sp-1 with sp
+ cmp r7, r6
+ ;set r8 to -1 if less than
+ ldilt r8, 1
+ ;store r8 to sp-1
+ stw r8, 0-4(r3)
+ br+ vm_loop
+
+
+;case D
+;68
+vm_dup:
+ ;load sp-1
+ ldw r6, 0-4(r3)
+ ;store to sp
+ stw r6, 0(r3)
+ ;increment stack addr
+ addi r3, r3, 4
+ br+ vm_loop
+
+;case I
+;73
+vm_imm:
+ ;load new high byte
+ ldb r6, 4(pc)
+ ;shift high byte
+ lls r6, r6, 8
+ ;load 2nd byte
+ ldb r7, 3(pc)
+ ;add to high byte
+ add r6, r6, r7
+ ;shift
+ lls r6, r6, 8
+ ;load
+ ldb r7, 2(pc)
+ ;add
+ add r6, r6, r7
+ ;shift
+ lls r6, r6, 8
+ ;load
+ ldb r7, 1(pc)
+ ;add
+ add r6, r6, r7
+ ;store result to stack
+ stw r6, 0(r3)
+ ;pc+4
+ addi r2, r2, 4
+ br+ vm_loop
+
+;case J
+;74
+vm_jmp:
+ ;decrement sp
+ sub r3, r3, 4
+ ;load sp
+ ldw r6, 0(r3)
+ ;compare to 0
+ cmpi r6,0
+ ;increment pc if == 0
+ addieqD r2, r2, 4
+ brnq+ vm_loop
+ ;if != 0
+ ;load pc+1 input
+ ldb r6, 1(r4)
+ ;pc += data
+ add r2, r2, r6
+ br+ vm_loop
+
+;case P
+;80
+vm_pop:
+ ;decrement stack addr
+ subi r3, r3, 4
+ br+ vm_loop
+
+;case X
+;88
+vm_xch:
+ ;load sp-1
+ ldw r6, 0-4(r3)
+ ;load sp-2
+ ldw r7, 0-8(r3)
+ ;store sp-1 to sp-2
+ stw r6, 0-8(r3)
+ ;store sp-2 to sp-1
+ stw r7, 0-4(r3)
+ br+ vm_loop
+
+;case ~
+;126
+vm_not:
+ ldw r6, 0-4(r3)
+ not r6
+ stw r6, 0-4(r3)
+ br+ vm_loop
+