diff options
-rwxr-xr-x[-rw-r--r--] | asm.py | 12 | ||||
-rwxr-xr-x | disasm.py | 100 | ||||
-rw-r--r-- | test.r1 | 45 | ||||
-rw-r--r-- | test.r1b | bin | 0 -> 84 bytes | |||
-rw-r--r-- | testa.r1 | 63 |
5 files changed, 175 insertions, 45 deletions
@@ -1,3 +1,5 @@ +#!/usr/bin/env python3 + mnems = """ nop rot @@ -60,15 +62,17 @@ def assemble_line(args, lineno): emit_call(labels[label]) case ["c", label]: label_wants[label].add((pc,call_instr)) - emit(0) + emit(0x8000) case ['b', label] if label in local_labels: emit_obranch(local_labels[label]) case ['b', label]: local_label_wants[label].add((pc, obranch_instr)) + emit(0x5000) case ['j', label] if label in local_labels: emit_jump(local_labels[label]) case ['j', label]: local_label_wants[label].add((pc, jump_instr)) + emit(0x4000) case ["i", i1]: assemble_line(["i", i1, "nop"], lineno) @@ -78,6 +82,7 @@ def assemble_line(args, lineno): emit_instrs(opc1, opc2) case ["l", val]: emit_lit(int(val)) + case [':', label]: if label in labels: raise Wrong(lineno, "label defined twice "+label) @@ -117,12 +122,15 @@ def emit_jump(addr): emit(jump_instr(addr, origin=pc)) def emit(word): + oldlen = len(output) output.extend(word.to_bytes(2)) global pc pc += 2 + assert len(output) == 2 + oldlen, "beeite" def put_at(addr, word): - output[addr:addr+1] = word.to_bytes(2) + assert addr % 2 == 0, "ooeu" + output[addr:addr+2] = word.to_bytes(2) def lit_instr(val): return (val&0b1111111111111) | 0b0110000000000000 diff --git a/disasm.py b/disasm.py new file mode 100755 index 0000000..3ba5c2f --- /dev/null +++ b/disasm.py @@ -0,0 +1,100 @@ +#!/usr/bin/env python3 +import sys + +mnems = """ +nop +rot +nrt +dup +swp +ovr +drp +tck +nip +equ +neq +add +sub +mul +div +neg +slt +ult +sle +ule +lod +sto +psh +pop +""".split() +mnems.extend(['???']*(64-len(mnems))) +def opws(kw): + for k in range(16): + mnems.append(kw + str(k)) +opws("mark") # who is mark +opws("loc") +opws("ret") +opws("lit") + +def dpc(addr): + print(f"{addr:04x} | ",end='') + +def uuu(b): + u=bin(b)[2:].zfill(16) + for x in range(0,len(u),4): + yield u[x:x+4] + +def fbin(b): + return '_'.join(uuu(b)) + +pc = 0 + +MASK_CALL = 0b1000_0000_0000_0000 +MASK_LIT = 0b0110_0000_0000_0000 +MASK_JMP = 0b0100_0000_0000_0000 +def maskeq(x, m): + # must be called in the right order + return (x&m)==m + +def main(): + while True: + global pc + bys = sys.stdin.buffer.read(2) + if len(bys) < 2: break + word = int.from_bytes(bys, 'big') + dpc(pc) + dpc(word) + if maskeq(word, MASK_CALL): + disasm_call(word) + elif maskeq(word, MASK_LIT): + disasm_lit(word) + elif maskeq(word, MASK_JMP): + disasm_br(word, pc) + else: + disasm_i(word) + pc += 2 + +def disasm_call(word): + addr = word & 0b0111_1111_1111_1111 + addr = addr << 1 + print(f"c {addr:04x}") +def disasm_lit(word): + val = word & 0b0001_1111_1111_1111 + print(f"l {val:04x}") +def disasm_br(word, pc): + is_cond = (word & 0b0001_0000_0000_0000) != 0 + char = 'b' if is_cond else 'j' + rel = (word & 0b0000_1111_1111_1111) - 2048 + target = rel + pc + print(f"{char} {rel:+05x} ={target:04x}") +def disasm_i(word): + opc1 = (word&0b0011_1111_1000_0000)>>7 + opc2 = (word&0b0000_0000_0111_1111) + mnem1 = mnems[opc1] + mnem2 = mnems[opc2] + if mnem2 == "nop": mnem2 = "" + print(f"i {mnem1} {mnem2}") + + +if __name__ == "__main__": + main() @@ -1,4 +1,6 @@ : sqrt +i loc1 sto +i loc1 sto i mark2 dup i loc0 sto c /2 @@ -22,46 +24,3 @@ i add div c /2 i ret0 -: square -i dup mul -i ret0 -: tuck -i dup nrt -i ret0 - -: replace! -i dup lod -i nrt sto -i ret0 - -: close? -i nrt -c absdiff -i swp sle -i ret0 - -: /2 -i lit2 div -i ret0 - -: thresh -i lit4 ret0 - -: absdiff -i sub - -: abs -i lit0 slt -b f1 -i neg -% f1 -i ret0 - - -: hypot -c square -i swp -c square -i add -c sqrt -i ret0 diff --git a/test.r1b b/test.r1b Binary files differnew file mode 100644 index 0000000..a6b1600 --- /dev/null +++ b/test.r1b diff --git a/testa.r1 b/testa.r1 new file mode 100644 index 0000000..79e6352 --- /dev/null +++ b/testa.r1 @@ -0,0 +1,63 @@ +: sqrt +i mark2 dup +i loc0 sto +i lit2 div +i loc1 sto +% loop +i loc0 lod +i loc1 lod +c newton +i dup loc1 +c replace! +c thresh +c close? +b loop +i loc1 lod +i ret2 + +: newton +c tuck +c square +i add div +i lit2 div +i ret0 + +: square +i dup mul +i ret0 +: tuck +i dup nrt +i ret0 + +: replace! +i dup lod +i nrt sto +i ret0 + +: close? +i nrt +c absdiff +i swp sle +i ret0 + +: thresh +i lit4 ret0 + +: absdiff +i sub + +: abs +i lit0 slt +b f1 +i neg +% f1 +i ret0 + + +: hypot +c square +i swp +c square +i add +c sqrt +i ret0 |