aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorJan Tuomi <jan@jantuomi.fi>2024-04-19 09:55:30 +0300
committerJan Tuomi <jan@jantuomi.fi>2024-04-19 09:55:30 +0300
commitfad7d9ff1b7f1cc736d775e03096a398a7e9719a (patch)
tree58261f1ee8d421c21e7ea81abc397a4720482217
parent0a2b1cad27307fde058ce30d5cd8685c336e987a (diff)
WIP monitor
-rw-r--r--atk16_asm/asm_ops.py226
-rw-r--r--resources/asm/monitor.atk1686
-rw-r--r--resources/asm/monitor_macros.py29
3 files changed, 222 insertions, 119 deletions
diff --git a/atk16_asm/asm_ops.py b/atk16_asm/asm_ops.py
index d5da1c1..a7ef88f 100644
--- a/atk16_asm/asm_ops.py
+++ b/atk16_asm/asm_ops.py
@@ -4,6 +4,7 @@ from .asm_eval import *
ExpandResult = list[list[str]]
ExpandFn = Callable[..., ExpandResult]
+OpWordDict = dict[str, Callable[..., int]]
OpExpansionDict = dict[str, ExpandFn]
@dataclass
@@ -17,6 +18,20 @@ def generate_unique_label(prefix: str) -> str:
generate_unique_label_counter += 1
return label
+operations: OpWordDict = {}
+expansions: OpExpansionDict = {}
+
+def register_primitive(func):
+ ident: str = func.__name__.replace("make_", "")
+ operations[ident] = func
+ return func
+
+def register_macro(func):
+ ident: str = func.__name__.replace("expand_", "")
+ expansions[ident] = func
+ return func
+
+@register_primitive
def make_alr(meta: Meta, symbols: Symbols, alu_op: str, left: str, right: str, target: str) -> int:
"""ALR 0000 TTTL LLRR RSSS"""
target_e = eval_expr(symbols, target, bits=3)
@@ -30,11 +45,16 @@ def make_alr(meta: Meta, symbols: Symbols, alu_op: str, left: str, right: str, t
alu_op_e
return word
-def make_ali(meta: Meta, symbols: Symbols, alu_op: str, left: str, imm: str, target: str) -> int:
+@register_macro
+def expand_alr(alu_op: str, left: str, right: str, target: str) -> ExpandResult:
+ return [["alr", alu_op, left, right, target]]
+
+@register_primitive
+def make_ali(meta: Meta, symbols: Symbols, alu_op: str, left: str, imm: int | str, target: str) -> int:
"""ALI 0001 TTTL LLII ISSS"""
target_e = eval_expr(symbols, target, bits=3)
left_e = eval_expr(symbols, left, bits=3)
- imm_e = eval_expr(symbols, imm, bits=3)
+ imm_e = eval_expr(symbols, str(imm), bits=3)
alu_op_e = eval_expr(symbols, alu_op, bits=3)
word = (0b0001 << 12) + \
(target_e << 9) + \
@@ -43,6 +63,11 @@ def make_ali(meta: Meta, symbols: Symbols, alu_op: str, left: str, imm: str, tar
alu_op_e
return word
+@register_macro
+def expand_ali(alu_op: str, left: str, imm: int | str, target: str) -> ExpandResult:
+ return [["ali", alu_op, left, str(imm), target]]
+
+@register_primitive
def make_ldr(meta: Meta, symbols: Symbols, addr_reg: str, to_reg: str) -> int:
"""LDR 0010 TTTR RRXX XXXX"""
to_reg_e = eval_expr(symbols, to_reg, bits=3)
@@ -52,6 +77,11 @@ def make_ldr(meta: Meta, symbols: Symbols, addr_reg: str, to_reg: str) -> int:
(addr_reg_e << 6)
return word
+@register_macro
+def expand_ldr(addr_reg: str, to_reg: str) -> ExpandResult:
+ return [["ldr", addr_reg, to_reg]]
+
+@register_primitive
def make_str(meta: Meta, symbols: Symbols, from_reg: str, addr_reg: str) -> int:
"""STR 0011 XXXL LLRR RXXX"""
addr_reg_e = eval_expr(symbols, from_reg, bits=3)
@@ -61,15 +91,25 @@ def make_str(meta: Meta, symbols: Symbols, from_reg: str, addr_reg: str) -> int:
(addr_reg_e << 3)
return word
-def make_ldi(meta: Meta, symbols: Symbols, imm: str, to_reg: str) -> int:
+@register_macro
+def expand_str(from_reg: str, addr_reg: str) -> ExpandResult:
+ return [["str", from_reg, addr_reg]]
+
+@register_primitive
+def make_ldi(meta: Meta, symbols: Symbols, imm: int | str, to_reg: str) -> int:
"""LDI 0100 TTTI IIII IIII"""
to_reg_e = eval_expr(symbols, to_reg, bits=3)
- imm_e = eval_expr(symbols, imm, bits=9)
+ imm_e = eval_expr(symbols, str(imm), bits=9)
word = (0b0100 << 12) + \
(to_reg_e << 9) + \
imm_e
return word
+@register_macro
+def expand_ldi(imm: int | str, to_reg: str) -> ExpandResult:
+ return [["ldi", str(imm), to_reg]]
+
+@register_primitive
def make_jpr(meta: Meta, symbols: Symbols, addr_reg: str) -> int:
"""JPR 0101 XXXR RRXX XXXX"""
addr_reg_e = eval_expr(symbols, addr_reg, bits=3)
@@ -77,17 +117,25 @@ def make_jpr(meta: Meta, symbols: Symbols, addr_reg: str) -> int:
(addr_reg_e << 6)
return word
-def make_jpi(meta: Meta, symbols: Symbols, imm: str) -> int:
+@register_macro
+def expand_jpr(addr_reg: str) -> ExpandResult:
+ return [["jpr", addr_reg]]
+
+@register_primitive
+def make_jpi(meta: Meta, symbols: Symbols, imm: int | str) -> int:
"""JPI 0110 XXXI IIII IIII"""
- imm_e = eval_expr(symbols, imm, bits=9)
+ imm_e = eval_expr(symbols, str(imm), bits=9)
imm_e = imm_e - meta.address - 1
imm_e = imm_e & (0b111111111)
- #print("symbols:", symbols)
- #print(meta, imm, f"0x{imm_e:>0x}")
word = (0b0110 << 12) + \
imm_e
return word
+@register_macro
+def expand_jpi(imm: int | str) -> ExpandResult:
+ return [["jpi", str(imm)]]
+
+@register_primitive
def make_brr(meta: Meta, symbols: Symbols, flag_s: str, addr_reg: str) -> int:
"""brr 0111 XFFR RRXX XXXX"""
flag_s_e = eval_expr(symbols, flag_s, bits=2)
@@ -97,10 +145,15 @@ def make_brr(meta: Meta, symbols: Symbols, flag_s: str, addr_reg: str) -> int:
(addr_reg_e << 6)
return word
-def make_bri(meta: Meta, symbols: Symbols, flag_s: str, imm: str) -> int:
+@register_macro
+def expand_brr(flag_s: str, addr_reg: str) -> ExpandResult:
+ return [["brr", flag_s, addr_reg]]
+
+@register_primitive
+def make_bri(meta: Meta, symbols: Symbols, flag_s: str, imm: int | str) -> int:
"""BRI 1000 XFFI IIII IIII"""
flag_s_e = eval_expr(symbols, flag_s, bits=2)
- imm_e = eval_expr(symbols, imm, bits=9)
+ imm_e = eval_expr(symbols, str(imm), bits=9)
imm_e = imm_e - meta.address - 1
imm_e = imm_e & (0b111111111)
word = (0b1000 << 12) + \
@@ -108,6 +161,11 @@ def make_bri(meta: Meta, symbols: Symbols, flag_s: str, imm: str) -> int:
imm_e
return word
+@register_macro
+def expand_bri(flag_s: str, imm: int | str) -> ExpandResult:
+ return [["bri", flag_s, str(imm)]]
+
+@register_primitive
def make_lpc(meta: Meta, symbols: Symbols, target: str) -> int:
"""LPC 1001 TTTX XXXX XXXX"""
target_e = eval_expr(symbols, target, bits=3)
@@ -115,72 +173,81 @@ def make_lpc(meta: Meta, symbols: Symbols, target: str) -> int:
(target_e << 9)
return word
+@register_macro
+def expand_lpc(target: str) -> ExpandResult:
+ return [["lpc", target]]
+
+@register_primitive
def make_rti(meta: Meta, symbols: Symbols) -> int:
"""RTI 1110 XXXX XXXX XXXX"""
word = (0b1110 << 12)
return word
+@register_macro
+def expand_rti() -> ExpandResult:
+ return [["rti"]]
+
+@register_primitive
def make_hlt(meta: Meta, symbols: Symbols) -> int:
"""HLT 1111 XXXX XXXX XXXX"""
word = (0b1111 << 12)
return word
-OpWordDict = dict[str, Callable[..., int]]
-operations: OpWordDict = {
- "alr": make_alr,
- "ali": make_ali,
- "ldr": make_ldr,
- "str": make_str,
- "ldi": make_ldi,
- "jpr": make_jpr,
- "jpi": make_jpi,
- "brr": make_brr,
- "bri": make_bri,
- "lpc": make_lpc,
- "rti": make_rti,
- "hlt": make_hlt,
-}
+@register_macro
+def expand_hlt() -> ExpandResult:
+ return [["hlt"]]
def expand_id(*parts: str) -> ExpandResult:
return [list(parts)]
+@register_macro
def expand_add(left: str, right: str, target: str) -> ExpandResult:
return [["alr", "al_plus", left, right, target]]
+@register_macro
def expand_sub(left: str, right: str, target: str) -> ExpandResult:
return [["alr", "al_minus", left, right, target]]
-def expand_addi(left: str, imm: str, target: str) -> ExpandResult:
- return [["ali", "al_plus", left, imm, target]]
+@register_macro
+def expand_addi(left: str, imm: int | str, target: str) -> ExpandResult:
+ return [["ali", "al_plus", left, str(imm), target]]
-def expand_subi(left: str, imm: str, target: str) -> ExpandResult:
- return [["ali", "al_minus", left, imm, target]]
+@register_macro
+def expand_subi(left: str, imm: int | str, target: str) -> ExpandResult:
+ return [["ali", "al_minus", left, str(imm), target]]
# FIXME: 0xFFFF does not fit in 3 bits
# def expand_not(reg: str, target: str) -> ExpandResult:
# return [["alr", "al_xor", reg, "0xFFFF", target]]
-# def expand_noti(imm: str, target: str) -> ExpandResult:
+# def expand_noti(imm: int | str, target: str) -> ExpandResult:
# return [["ali", "al_xor", imm, "0xFFFF", target]]
+@register_macro
def expand_and(left: str, right: str, target: str) -> ExpandResult:
return [["alr", "al_and", left, right, target]]
-def expand_andi(left: str, imm: str, target: str) -> ExpandResult:
- return [["ali", "al_and", left, imm, target]]
+@register_macro
+def expand_andi(left: str, imm: int | str, target: str) -> ExpandResult:
+ return [["ali", "al_and", left, str(imm), target]]
+@register_macro
def expand_or(left: str, right: str, target: str) -> ExpandResult:
return [["alr", "al_or", left, right, target]]
-def expand_ori(left: str, imm: str, target: str) -> ExpandResult:
- return [["ali", "al_or", left, imm, target]]
+@register_macro
+def expand_ori(left: str, imm: int | str, target: str) -> ExpandResult:
+ return [["ali", "al_or", left, str(imm), target]]
-def expand_xor(left: str, imm: str, target: str) -> ExpandResult:
- return [["alr", "al_xor", left, imm, target]]
+@register_macro
+def expand_xor(left: str, imm: int | str, target: str) -> ExpandResult:
+ return [["alr", "al_xor", left, str(imm), target]]
+@register_macro
def expand_xori(left: str, right: str, target: str) -> ExpandResult:
return [["ali", "al_xor", left, right, target]]
+@register_macro
def expand_not(reg: str) -> ExpandResult:
tmp = "RA"
return [
@@ -191,48 +258,63 @@ def expand_not(reg: str) -> ExpandResult:
*expand_spo(tmp),
]
+@register_macro
def expand_sll(left: str, right: str, target: str) -> ExpandResult:
return [["alr", "al_sll", left, right, target]]
+@register_macro
def expand_slr(left: str, right: str, target: str) -> ExpandResult:
return [["alr", "al_slr", left, right, target]]
+@register_macro
def expand_sar(left: str, right: str, target: str) -> ExpandResult:
return [["alr", "al_sar", left, right, target]]
-def expand_slli(left: str, imm: str, target: str) -> ExpandResult:
- return [["ali", "al_sll", left, imm, target]]
+@register_macro
+def expand_slli(left: str, imm: int | str, target: str) -> ExpandResult:
+ return [["ali", "al_sll", left, str(imm), target]]
-def expand_slri(left: str, imm: str, target: str) -> ExpandResult:
- return [["ali", "al_slr", left, imm, target]]
+@register_macro
+def expand_slri(left: str, imm: int | str, target: str) -> ExpandResult:
+ return [["ali", "al_slr", left, str(imm), target]]
-def expand_sari(left: str, imm: str, target: str) -> ExpandResult:
- return [["ali", "al_sar", left, imm, target]]
+@register_macro
+def expand_sari(left: str, imm: int | str, target: str) -> ExpandResult:
+ return [["ali", "al_sar", left, str(imm), target]]
+@register_macro
def expand_inc(reg: str) -> ExpandResult:
return [["ali", "al_plus", reg, "1", reg]]
+@register_macro
def expand_dec(reg: str) -> ExpandResult:
return [["ali", "al_minus", reg, "1", reg]]
+@register_macro
def expand_mov(from_reg: str, to_reg: str) -> ExpandResult:
return [["ali", "al_plus", from_reg, "0", to_reg]]
+@register_macro
def expand_nop() -> ExpandResult:
return [["ali", "al_plus", "RA", "0", "RA"]]
+@register_macro
def expand_spu(reg: str) -> ExpandResult:
return [["str", reg, "SP"]] + expand_inc("SP")
+@register_macro
def expand_spo(reg: str) -> ExpandResult:
return expand_dec("SP") + [["ldr", "SP", reg]]
-def expand_sinc(imm: str) -> ExpandResult:
+@register_macro
+def expand_sinc(imm: int | str) -> ExpandResult:
return expand_addi("SP", imm, "SP")
-def expand_sdec(imm: str) -> ExpandResult:
+@register_macro
+def expand_sdec(imm: int | str) -> ExpandResult:
return expand_subi("SP", imm, "SP")
+@register_macro
def expand_callr(addr_reg: str) -> ExpandResult:
return [
["lpc", "RG"],
@@ -243,17 +325,19 @@ def expand_callr(addr_reg: str) -> ExpandResult:
*expand_dec("SP"),
]
-def expand_calli(addr_imm: str) -> ExpandResult:
+@register_macro
+def expand_calli(addr_imm: int | str) -> ExpandResult:
ret_label = generate_unique_label(prefix="calli_return")
return [
["ldi", ret_label, "RG"],
*expand_spu("RG"),
- ["jpi", addr_imm],
+ ["jpi", str(addr_imm)],
["@label", ret_label],
["ldr", "SP", "RG"], # return leaves SP pointing at return value, read to reg
*expand_dec("SP"), # decrement SP to fix stack
]
+@register_macro
def expand_return() -> ExpandResult:
return [
["str", "RG", "SP"], # store returned value on stack but don't increment SP
@@ -263,6 +347,7 @@ def expand_return() -> ExpandResult:
["jpr", "RG"] # jump back to call site
]
+@register_macro
def stack_stash(*rs: str) -> ExpandResult:
result: ExpandResult = []
for r in rs:
@@ -270,6 +355,7 @@ def stack_stash(*rs: str) -> ExpandResult:
return result
+@register_macro
def stack_restore(*rs: str) -> ExpandResult:
result: ExpandResult = []
for r in rs:
@@ -278,6 +364,7 @@ def stack_restore(*rs: str) -> ExpandResult:
return result
+@register_macro
def set_graphics_mode(mode: str) -> ExpandResult:
return [
["ldi", "vt_gr_mode_addr", "RF"],
@@ -285,50 +372,3 @@ def set_graphics_mode(mode: str) -> ExpandResult:
["ldi", mode, "RG"],
["str", "RG", "RF"],
]
-
-expansions: OpExpansionDict = {
- "alr": lambda *args: expand_id("alr", *args),
- "ali": lambda *args: expand_id("ali", *args),
- "ldr": lambda *args: expand_id("ldr", *args),
- "str": lambda *args: expand_id("str", *args),
- "ldi": lambda *args: expand_id("ldi", *args),
- "jpr": lambda *args: expand_id("jpr", *args),
- "jpi": lambda *args: expand_id("jpi", *args),
- "brr": lambda *args: expand_id("brr", *args),
- "bri": lambda *args: expand_id("bri", *args),
- "lpc": lambda *args: expand_id("lpc", *args),
- "rti": lambda *args: expand_id("rti", *args),
- "hlt": lambda *args: expand_id("hlt", *args),
-
- "add": expand_add,
- "sub": expand_sub,
- "addi": expand_addi,
- "subi": expand_subi,
- "not": expand_not,
- "and": expand_and,
- "andi": expand_andi,
- "or": expand_or,
- "ori": expand_ori,
- "xor": expand_xor,
- "xori": expand_xori,
- "sll": expand_sll,
- "slr": expand_slr,
- "sar": expand_sar,
- "slli": expand_slli,
- "slri": expand_slri,
- "sari": expand_sari,
- "inc": expand_inc,
- "dec": expand_dec,
- "mov": expand_mov,
- "nop": expand_nop,
- "spu": expand_spu,
- "spo": expand_spo,
- "sinc": expand_sinc,
- "sdec": expand_sdec,
- "callr": expand_callr,
- "calli": expand_calli,
- "return": expand_return,
- "stack_stash": stack_stash,
- "stack_restore": stack_restore,
- "set_graphics_mode": set_graphics_mode,
-}
diff --git a/resources/asm/monitor.atk16 b/resources/asm/monitor.atk16
index 5c48182..9a9484f 100644
--- a/resources/asm/monitor.atk16
+++ b/resources/asm/monitor.atk16
@@ -1,27 +1,44 @@
+@use monitor_macros:*
+
@include %bootstrap
@include %std_mem
@include %std_term
+@include %std_bump_alloc
; Constants
-@data text_buffer_size 2048
+@data text_buffer_size 2048
+@data input_buffer_size 64
; Global variable pointers
; 0xE800 - 0xEFFF: sprite buffer space that is unused in this program
-@data cursor_p 0xE800
+@data text_cursor_p 0xE800
+@data input_buffer_p 0xE801
+@data input_cursor_p 0xE802
@data title_string " »» ATK16 monitor v0.1 »»"
@data subtitle_string " Run [help] for a list of commands"
@label main
+ ; initialize heap allocator
+ calli bump_reset
+
; initialize global variables
- ; BEGIN cursor_p := text_mem
- ldi cursor_p RA
+ ; BEGIN text_cursor_p = text_mem
+ ldi text_cursor_p RA
ldr RA RA
ldi vt_text_mem RB
ldr RB RB
str RB RA
; END
+ ; BEGIN input_buffer_p = alloc(64)
+ ldi input_buffer_size RA
+ calli bump_alloc
+ ldi input_buffer_p RA
+ ldr RA RA
+ str RG RA
+ ; END
+
; use memset to clear the text buffer
; BEGIN memset(text_mem, 0, text_buffer_size)
ldi vt_text_mem RA ; RA := text buffer address pointer
@@ -34,14 +51,14 @@
set_graphics_mode gr_text_mode
- calli newline
+ m_newline RA RB
; BEGIN put_string(title_string)
ldi title_string RA
calli put_string
; END
- calli newline
+ m_newline RA RB
; BEGIN put_string(subtitle_string)
ldi subtitle_string RA
@@ -50,23 +67,27 @@
; loop forever
@label loop
+ calli wait_for_input_newline
+
+ ; BEGIN critical section
+ ; disable_interrupts
+ ; <work>
+ ; enable_interrupts
+ ; END
jpi loop
+;;; Subroutines
+
+; TODO: move the implementation body (between stack_stash and stack_restore) to
+; a macro so that it can be inlined without function call overhead when needed
+
@label newline
; move cursor to the beginning of the next line
; parameters: none
; returns: none
stack_stash RA RB
- ldi cursor_p RA
- ldr RA RA
- ldr RA RB
-
- slri RB 6 RB ; cursor = cursor / 64
- addi RB 1 RB ; cursor = cursor + 1
- slli RB 6 RB ; cursor = cursor * 64
-
- str RB RA
+ m_newline RA RB
stack_restore RA RB
return
@@ -76,14 +97,7 @@
; returns: none
stack_stash RB RC
- ldi cursor_p RB
- ldr RB RB
- ldr RB RC
-
- str RA RC
- inc RC
-
- str RC RB
+ m_put_char RA RB RC
stack_restore RB RC
return
@@ -92,7 +106,7 @@
; parameters: RA = string_p
; returns: none
- stack_stash RA RB RC
+ stack_stash RA RB RC RD RE
ldr RA RB ; RB := string length
addi RA 1 RC ; RC := pointer to first character
@label put_string_loop
@@ -100,11 +114,31 @@
bri zero put_string_done ; i.e. no more characters to put
ldr RC RA ; RA := character to put
- calli put_char
+ m_put_char RA RD RE ; inline the put_char subroutine to avoid function call overhead
inc RC
subi RB 1 RB
jpi put_string_loop
@label put_string_done
- stack_restore RA RB RC
+ stack_restore RA RB RC RD RE
return
+
+@label wait_for_input_newline
+ ; wait for a newline character in the input buffer
+ ; parameters: none
+ ; returns: RG = key code
+ stack_stash RA RB
+ ldi 10 RB ; RB := newline character
+@label wait_for_input_newline_loop
+ ldi input_cursor_p RA ; RA := data segment pointer
+ ldr RA RA ; RA := &&char
+ ldr RA RA ; RA := &char
+ ldr RA RA ; RA := char
+
+ sub RA RB RA ; if RA == newline, then stop waiting
+ bri zero wait_for_input_newline_done
+
+ jpi wait_for_input_newline_loop
+@label wait_for_input_newline_done
+ stack_restore RA RB
+ return \ No newline at end of file
diff --git a/resources/asm/monitor_macros.py b/resources/asm/monitor_macros.py
new file mode 100644
index 0000000..e753996
--- /dev/null
+++ b/resources/asm/monitor_macros.py
@@ -0,0 +1,29 @@
+from atk16_asm.asm_ops import *
+
+expansions: dict[str, Callable[..., ExpandResult]] = {}
+def register_macro(func):
+ expansions[func.__name__] = func
+ return func
+
+@register_macro
+def m_newline(r1: str, r2: str) -> ExpandResult:
+ return [
+ *expand_ldi("text_cursor_p", r1),
+ *expand_ldr(r1, r1),
+ *expand_ldr(r1, r2),
+ *expand_slri(r2, "6", r2), # cursor = cursor / 64
+ *expand_addi(r2, "1", r2), # cursor = cursor + 1
+ *expand_slli(r2, "6", r2), # cursor = cursor * 64
+ *expand_str(r2, r1),
+ ]
+
+@register_macro
+def m_put_char(char_r: str, r1: str, r2: str) -> ExpandResult:
+ return [
+ *expand_ldi("text_cursor_p", r1),
+ *expand_ldr(r1, r1),
+ *expand_ldr(r1, r2),
+ *expand_str(char_r, r2),
+ *expand_addi(r2, "1", r2),
+ *expand_str(r2, r1),
+ ]