From 492cc14054b243bfcc02b0c4a2289060aa4adb4f Mon Sep 17 00:00:00 2001 From: Jan Tuomi Date: Sun, 14 Apr 2024 13:34:10 +0300 Subject: Change MMIO segment address space --- atk16_asm/builtin_asm/bootstrap.atk16 | 8 +-- atk16_asm/builtin_asm/std_alloc.atk16 | 0 atk16_asm/builtin_asm/std_math.atk16 | 92 ++++++++++++++++++++++++++++++ atk16_emu/emu.py | 10 ++-- resources/asm/ast_compiler_bootstrap.atk16 | 8 +-- resources/asm/test_py_src.atk16 | 8 +-- 6 files changed, 109 insertions(+), 17 deletions(-) create mode 100644 atk16_asm/builtin_asm/std_alloc.atk16 create mode 100644 atk16_asm/builtin_asm/std_math.atk16 diff --git a/atk16_asm/builtin_asm/bootstrap.atk16 b/atk16_asm/builtin_asm/bootstrap.atk16 index 94eed4c..e0fddfa 100644 --- a/atk16_asm/builtin_asm/bootstrap.atk16 +++ b/atk16_asm/builtin_asm/bootstrap.atk16 @@ -2,10 +2,10 @@ ; memory segments @let stack_segment 0x8000 -@let mmio_segment 0xE000 -@let terminal_addr 0xE000 -@let keyboard_addr 0xE001 -@let gr_mode_addr 0xE002 +@let mmio_segment 0xE7F0 +@let terminal_addr 0xE7F0 +@let keyboard_addr 0xE7F1 +@let gr_mode_addr 0xE7F2 @let sprite_mem 0xE800 @let text_mem 0xF800 ; to 0xFFFF ; note: sprite memory & text memory can use the same space diff --git a/atk16_asm/builtin_asm/std_alloc.atk16 b/atk16_asm/builtin_asm/std_alloc.atk16 new file mode 100644 index 0000000..e69de29 diff --git a/atk16_asm/builtin_asm/std_math.atk16 b/atk16_asm/builtin_asm/std_math.atk16 new file mode 100644 index 0000000..58b9cdb --- /dev/null +++ b/atk16_asm/builtin_asm/std_math.atk16 @@ -0,0 +1,92 @@ +@label mul_sign_mask + ${2 ** 15} +@label mul_not_mask + 0xFFFF + +@label mul + ; multiply a signed (a) and a signed (b) + ; parameters RA = a + ; RB = b + ; return RG = a * b + + stack_stash RA RB RC RD + ldi 0 RG ; initialize return value in RG to 0 + + ldi mul_sign_mask RD + ldr RD RD ; RD := 2 ** 16 + and RA RD RC ; RC := 2 ** 16 if a is negative, 0 otherwise + and RB RD RD ; RD := 2 ** 16 if b is negative, 0 otherwise + xor RC RD RC ; RC := 2 ** 16 if exactly one of a or b is negative, 0 otherwise + + ldi mul_not_mask RD + ldr RD RD ; RD := 0xFFFF + + ; RA := abs(a) + subi RA 0 RA + bri sign mul_a_negative + jpi mul_a_negative_done +@label mul_a_negative + xor RA RD RA ; RA := ~a + inc RA ; negate twos complement a +@label mul_a_negative_done + + ; RB := abs(b) + subi RB 0 RB + bri sign mul_b_negative + jpi mul_b_negative_done +@label mul_b_negative + xor RB RD RB ; RB := ~b + inc RB ; negate twos complement b +@label mul_b_negative_done + + ; the algorithms iterates b times, adding a to RG each time + ; so b should be as small as possible + sub RB RA RD ; if a <= b, swap a and b + bri sign mul_loop + + mov RA RD + mov RB RA + mov RD RB +@label mul_loop + ; if b == 0, we are done + subi RB 0 RB + bri zero mul_done + ; RG += RA + add RA RG RG + dec RB + jpi mul_loop +@label mul_done + ; set the most significant bit to the precomputed sign + subi RC 0 RC + bri sign mul_negate_result + jpi mul_return +@label mul_negate_result + ldi mul_not_mask RD + ldr RD RD ; RD := 0xFFFF + xor RG RD RG + inc RG +@label mul_return + stack_restore RA RB RC RD + return + +; Recursive impl of the factorial +; Calling convention is that arguments are in registers RA..RG (max 7 arguments since RH = SP) +; and the return value is in RG (note: overwriting arg in RG) + +@label fact + ; parameters RA = n + ; return RG = factorial(n) + subi RA 0 RA + bri zero fact_basecase +@label fact_reccase + stack_stash RA RB + mov RA RB ; RB := n + subi RA 1 RA ; RA := n - 1 + calli fact ; RG := fact(n - 1) + mov RG RA ; RA := fact(n - 1) + calli mul ; RG := n * fact(n - 1) + stack_restore RA RB + return +@label fact_basecase + ldi 1 RG + return diff --git a/atk16_emu/emu.py b/atk16_emu/emu.py index 43dfdf1..0b4e675 100644 --- a/atk16_emu/emu.py +++ b/atk16_emu/emu.py @@ -196,7 +196,7 @@ class Machine: if addr < 2 ** 15: return self.rom.read(addr & 0x7FFF) else: - if addr == 0xE001: + if addr == 0xE7F1: return self.peripherals.keyboard.read() else: return self.ram.read(addr & 0x7FFF) @@ -205,15 +205,15 @@ class Machine: if addr < 2 ** 15: raise ValueError(f"Cannot write to ROM, addr: 0x{addr:>04x}") else: - if addr == 0xE002 and value == 0b00: + if addr == 0xE7F2 and value == 0b00: self.peripherals.graphics.deactivate() - elif addr == 0xE002 and value == 0b01: + elif addr == 0xE7F2 and value == 0b01: self.peripherals.graphics.activate_tpu() - elif addr == 0xE002 and value == 0b10: + elif addr == 0xE7F2 and value == 0b10: self.peripherals.graphics.activate_ppu() elif 0xF800 <= addr <= 0xFFFF: self.peripherals.graphics.write(addr, value) - elif addr == 0xE000: + elif addr == 0xE7F0: self.peripherals.terminal.write(value) else: self.ram.write(addr & 0x7FFF, value) diff --git a/resources/asm/ast_compiler_bootstrap.atk16 b/resources/asm/ast_compiler_bootstrap.atk16 index 2e112eb..b38e5f5 100644 --- a/resources/asm/ast_compiler_bootstrap.atk16 +++ b/resources/asm/ast_compiler_bootstrap.atk16 @@ -18,10 +18,10 @@ @let vt_text_mem 0x19 ; Text memory buffer address @let stack_segment 0x8000 -@let mmio_segment 0xE000 -@let terminal_addr 0xE000 -@let keyboard_addr 0xE001 -@let gr_mode_addr 0xE002 +@let mmio_segment 0xE7F0 +@let terminal_addr 0xE7F0 +@let keyboard_addr 0xE7F1 +@let gr_mode_addr 0xE7F2 @let sprite_mem 0xE800 @let text_mem 0xF800 diff --git a/resources/asm/test_py_src.atk16 b/resources/asm/test_py_src.atk16 index c38d1ca..bd1d93f 100644 --- a/resources/asm/test_py_src.atk16 +++ b/resources/asm/test_py_src.atk16 @@ -18,10 +18,10 @@ @let vt_text_mem 0x19 ; Text memory buffer address @let stack_segment 0x8000 -@let mmio_segment 0xE000 -@let terminal_addr 0xE000 -@let keyboard_addr 0xE001 -@let gr_mode_addr 0xE002 +@let mmio_segment 0xE7F0 +@let terminal_addr 0xE7F0 +@let keyboard_addr 0xE7F1 +@let gr_mode_addr 0xE7F2 @let sprite_mem 0xE800 @let text_mem 0xF800 -- cgit v1.3