summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rwxr-xr-x[-rw-r--r--]asm.py12
-rwxr-xr-xdisasm.py100
-rw-r--r--test.r145
-rw-r--r--test.r1bbin0 -> 84 bytes
-rw-r--r--testa.r163
5 files changed, 175 insertions, 45 deletions
diff --git a/asm.py b/asm.py
index 7a20f8b..26eaf8f 100644..100755
--- a/asm.py
+++ b/asm.py
@@ -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()
diff --git a/test.r1 b/test.r1
index 8a51d81..557932d 100644
--- a/test.r1
+++ b/test.r1
@@ -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
new file mode 100644
index 0000000..a6b1600
--- /dev/null
+++ b/test.r1b
Binary files differ
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