diff options
| author | Jan Tuomi <jan@jantuomi.fi> | 2024-05-16 17:09:45 +0300 |
|---|---|---|
| committer | Jan Tuomi <jan@jantuomi.fi> | 2024-05-16 17:09:45 +0300 |
| commit | 1045229da08fc1c8168b5ae58d54a1566eefaaac (patch) | |
| tree | ab8288897c8d66dda9f60332c02022fdbccb7c2e | |
| parent | 230e573b26c6a59828cda7b83d3574080d887cfe (diff) | |
Fix bug in assembler where long jumps with jpi got aliased
| -rw-r--r-- | atk16_asm/asm_ops.py | 4 | ||||
| -rw-r--r-- | atk16_emu/emu.py | 9 | ||||
| -rw-r--r-- | atk16_projects/monitor/monitor.atk16 | 54 |
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 |
