aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorJan Tuomi <jan@jantuomi.fi>2024-05-16 17:09:45 +0300
committerJan Tuomi <jan@jantuomi.fi>2024-05-16 17:09:45 +0300
commit1045229da08fc1c8168b5ae58d54a1566eefaaac (patch)
treeab8288897c8d66dda9f60332c02022fdbccb7c2e
parent230e573b26c6a59828cda7b83d3574080d887cfe (diff)
Fix bug in assembler where long jumps with jpi got aliased
-rw-r--r--atk16_asm/asm_ops.py4
-rw-r--r--atk16_emu/emu.py9
-rw-r--r--atk16_projects/monitor/monitor.atk1654
3 files changed, 37 insertions, 30 deletions
diff --git a/atk16_asm/asm_ops.py b/atk16_asm/asm_ops.py
index a7ef88f..3198d4c 100644
--- a/atk16_asm/asm_ops.py
+++ b/atk16_asm/asm_ops.py
@@ -126,6 +126,10 @@ def make_jpi(meta: Meta, symbols: Symbols, imm: int | str) -> int:
"""JPI 0110 XXXI IIII IIII"""
imm_e = eval_expr(symbols, str(imm), bits=9)
imm_e = imm_e - meta.address - 1
+
+ if imm_e < -(2 ** 8) or imm_e >= 2 ** 8:
+ raise Exception(f"jpi imm value is not representable in 9 bits: {imm_e}")
+
imm_e = imm_e & (0b111111111)
word = (0b0110 << 12) + \
imm_e
diff --git a/atk16_emu/emu.py b/atk16_emu/emu.py
index d519e5f..67f63f1 100644
--- a/atk16_emu/emu.py
+++ b/atk16_emu/emu.py
@@ -355,9 +355,13 @@ class Machine:
self.pc.value = addr
case JPI(imm):
+ # check that imm fits in 9 bits
+ if imm >= 2 ** 9:
+ raise Exception(f"JPI immediate value does not fit in 9 bits: {imm:>04x}" )
+
# convert imm from signed (twos complement) 9-bit to a python int
- imm = (imm & (0b011111111)) - (imm & 0b100000000)
- self.pc.value = (self.pc.value + imm) & 0xFFFF
+ py_imm = (imm & (0b011111111)) - (imm & 0b100000000)
+ self.pc.value = (self.pc.value + py_imm) & 0xFFFF
case BRR(flag, addr_reg):
if self.check_nth_flag(flag):
@@ -407,6 +411,7 @@ class Machine:
def decode(self, instr: int):
opcode = (instr & 0xF000) >> 12
opdata = instr & 0x0FFF
+
match opcode:
case 0b0000: return ALR(target=(opdata & 0b111000000000) >> 9,
left=(opdata & 0b000111000000) >> 6,
diff --git a/atk16_projects/monitor/monitor.atk16 b/atk16_projects/monitor/monitor.atk16
index 57db870..4580d5f 100644
--- a/atk16_projects/monitor/monitor.atk16
+++ b/atk16_projects/monitor/monitor.atk16
@@ -83,9 +83,10 @@
; BEGIN critical section
m_set_critical RA RB
- calli is_newline_pressed
- subi RG 1 RG ; if is_newline_pressed() == 1, then loop_newline_pressed
- bri zero loop_newline_pressed
+ ; TODO evaluate input_buffer if newline was just pressed
+ ;calli is_newline_pressed
+ ;subi RG 1 RG ; if is_newline_pressed() == 1, then loop_newline_pressed
+ ;bri zero loop_newline_pressed
jpi loop_finally
@label loop_newline_pressed
@@ -141,27 +142,6 @@
stack_restore RA RB RC RD RE
return
-
-@label is_newline_pressed
- ; check if the last character in the input buffer is a newline
- ; parameters: none
- ; returns: RG = 1 if newline is pressed, 0 otherwise
- stack_stash RA RB
- ldi 10 RB ; RB := newline character
-
- ldi input_cursor_p RA ; RA := data segment pointer
- ldr RA RA ; RA := 0xE802
- ldr RA RA ; RA := &char
- ldr RA RA ; RA := char
-
- ldi 1 RG ; RG := 1
- sub RA RB RA ; if RA == newline, then return RG = 1
- bri zero is_newline_pressed_done
- ldi 0 RG ; else return RG = 0
-@label is_newline_pressed_done
- stack_restore RA RB
- return
-
@data row_index_mask ${64 - 1}
@label keyboard_isr
@@ -170,15 +150,15 @@
ldr RA RA ; RA := Keyboard peripheral address deref
ldr RA RA ; RA := <16-bit keyboard character code> from MMIO register
+ ldi text_cursor_p RC
+ ldr RC RC
+ ldr RC RC ; RC := text_cursor_p
+
mov RA RB ; RB := character code
subi RB 5 RB ; if code == 10 (enter key), then run newline handler
subi RB 5 RB
bri zero keyboard_isr_newline
- ldi text_cursor_p RC
- ldr RC RC
- ldr RC RC ; RC := text_cursor_p
-
mov RA RB ; if code == 8 (backspace key), then run backspace handler
subi RB 5 RB
subi RB 3 RB
@@ -203,6 +183,24 @@
@label keyboard_isr_newline
m_newline RA RB
+ ; note: RC = text_cursor_p, set in the beginning of the ISR
+
+ ; BEGIN memcopy(last_line_p, input_buffer_p, input_buffer_size)
+ slri RC 6 RC ; RC := RC >> 6, i.e. the row index
+ slli RC 6 RC ; RC := RC << 6, i.e. index to the first character of the row
+ addi RC 3 RA ; RA := RC + 3, i.e. index to the first character of the input string
+
+ ldi input_buffer_p RB
+ ldr RB RB ; RB := &input_buffer_p
+ ldr RB RB ; RB := input_buffer_p
+
+ ldi input_buffer_size RC
+ ldr RC RC ; RC := input_buffer_size
+
+ ldi memcopy RD
+ callr RD
+ ; END
+
ldi prompt_string RA
calli put_string