From a36e5e001a4f17505c40b7f7a8f9c1f514f40de1 Mon Sep 17 00:00:00 2001 From: Jan Tuomi Date: Sat, 13 Apr 2024 22:27:54 +0300 Subject: Fix bugs, add tests --- atk16_asm/builtin_asm/std_mem.atk16 | 3 ++- atk16_emu/emu.py | 5 ++--- atk16_emu/peripherals.py | 10 ++++++++++ digital_diagrams/atk16_mem.dig | 38 +++++++++++++++++++------------------ resources/asm/text_mode.atk16 | 16 ++++++++++++++-- test/e2e/std_mem/run_memset.atk16 | 21 ++++++++++++++++++++ test/e2e/std_mem/test_memset.py | 22 +++++++++++++++++++++ 7 files changed, 91 insertions(+), 24 deletions(-) create mode 100644 test/e2e/std_mem/run_memset.atk16 create mode 100644 test/e2e/std_mem/test_memset.py diff --git a/atk16_asm/builtin_asm/std_mem.atk16 b/atk16_asm/builtin_asm/std_mem.atk16 index 4c6a455..7a7efab 100644 --- a/atk16_asm/builtin_asm/std_mem.atk16 +++ b/atk16_asm/builtin_asm/std_mem.atk16 @@ -7,13 +7,14 @@ stack_stash RD RE ldi 0 RD ; RD := i (counter), initially 0 @label memset_loop - subi RB RD RE ; RE := n – i (unused value) + sub RB RD RE ; RE := n – i (unused value) bri zero memset_done ; exit the loop add RA RD RE ; RE := RA + i (address of the word to set) str RC RE ; set the word at address RE to value in RC inc RD ; i := i + 1 + jpi memset_loop ; repeat the loop @label memset_done stack_restore RD RE return diff --git a/atk16_emu/emu.py b/atk16_emu/emu.py index d17b537..3f0fa41 100644 --- a/atk16_emu/emu.py +++ b/atk16_emu/emu.py @@ -200,17 +200,16 @@ class Machine: if addr < 2 ** 15: raise ValueError(f"Cannot write to ROM, addr: 0x{addr:>04x}") else: - # TODO: Implement memory-mapped I/O if addr == 0xE002 and value == 0b00: self.peripherals.graphics.deactivate() elif addr == 0xE002 and value == 0b01: self.peripherals.graphics.activate_tpu() elif addr == 0xE002 and value == 0b10: self.peripherals.graphics.activate_ppu() - elif 0xF800 < addr <= 0xFFFF: + elif 0xF800 <= addr <= 0xFFFF: self.peripherals.graphics.write(addr, value) elif addr == 0xE000: - self.terminal.write(value) + self.peripherals.terminal.write(value) else: self.ram.write(addr & 0x7FFF, value) diff --git a/atk16_emu/peripherals.py b/atk16_emu/peripherals.py index 0038a33..54020f4 100644 --- a/atk16_emu/peripherals.py +++ b/atk16_emu/peripherals.py @@ -8,6 +8,7 @@ class Peripherals: pygame.init() self.graphics = Graphics() self.keyboard = Keyboard() + self.terminal = Terminal() def step(self): for event in pygame.event.get(): @@ -23,6 +24,7 @@ class DummyPeripherals: def __init__(self): self.graphics = DummyGraphics() self.keyboard = DummyKeyboard() + self.terminal = Terminal() def step(self): pass @@ -127,3 +129,11 @@ class DummyKeyboard: def read(self) -> int: print("warning: reading from dummy keyboard") return 0xFFFF + +class Terminal: + def __init__(self): + pass + + def write(self, s: int): + print(chr(s), end="") + sys.stdout.flush() diff --git a/digital_diagrams/atk16_mem.dig b/digital_diagrams/atk16_mem.dig index 30579a7..5fa09fd 100644 --- a/digital_diagrams/atk16_mem.dig +++ b/digital_diagrams/atk16_mem.dig @@ -35,24 +35,26 @@ Data - 4014,2c00,6019,13*8000,c0,1a,1a,1a,8000,e000,e001,e002,e800,f800 -,4855,f000,4017,2000,4200,3008,6000,6001,f840,4422,2480,4220,3088 -,1488,4248,3088,1488,4245,3088,1488,424c,3088,1488,424c,3088,1488 -,424f,3088,1488,4220,3088,1488,4223,3088,1488,4276,3088,1488,4261 -,3088,1488,4269,3088,1488,426e,3088,1488,4263,3088,1488,426f,3088 -,1488,426f,3088,1488,4264,3088,1488,4269,3088,1488,426a,3088,1488 -,4275,3088,1488,4274,3088,1488,4275,3088,1488,4274,3088,1488,14b5 -,1488,14b7,4220,3088,1488,42bb,3088,1488,42bb,3088,1488,42bb,3088 -,1488,42bb,3088,1488,4220,3088,1488,4242,3088,1488,4259,3088,1488 -,4220,3088,1488,4240,3088,1488,426b,3088,1488,4261,3088,1488,426c -,3088,1488,425f,3088,1488,426a,3088,1488,4261,3088,1488,426e,3088 -,1488,4220,3088,1488,42bb,3088,1488,42bb,3088,1488,42bb,3088,1488 -,42bb,3088,1488,14b5,1488,14b7,14b5,1488,14b7,4220,3088,1488,423e -,3088,1488,4220,3088,1488,4017,2000,4201,3008,61ff,3140,1b48,3148 -,1b48,3158,1b48,4016,2000,2000,4215,2240,1600,16e9,16e9,8407,1600 -,16e9,16d9,8410,3080,1488,6012,14b5,1488,14b7,4220,3088,1488,423e -,3088,1488,4220,3088,1488,6005,1489,4220,3088,1488,1489,3158,1b48 -,3148,1b48,3140,1b48,e000 + 4014,2e00,6019,13*8000,e0,1a,1a,1a,8000,e000,e001,e002,e800,f800 +,4855,f000,4017,2000,4200,3008,6015,31d8,1fc8,31e0,1fc8,4600,859 +,8404,818,3110,16c8,61fa,1fc9,29c0,1fc9,27c0,31f0,1fc9,2dc0,1fc8 +,5180,800,4019,2000,4235,2240,4400,4c3f,31f0,1fc8,61e2,2dc0,1fc9 +,6001,f840,4442,2480,4220,3088,1488,4248,3088,1488,4245,3088,1488 +,424c,3088,1488,424c,3088,1488,424f,3088,1488,4220,3088,1488,4223 +,3088,1488,4276,3088,1488,4261,3088,1488,4269,3088,1488,426e,3088 +,1488,4263,3088,1488,426f,3088,1488,426f,3088,1488,4264,3088,1488 +,4269,3088,1488,426a,3088,1488,4275,3088,1488,4274,3088,1488,4275 +,3088,1488,4274,3088,1488,14b5,1488,14b7,4220,3088,1488,42bb,3088 +,1488,42bb,3088,1488,42bb,3088,1488,42bb,3088,1488,4220,3088,1488 +,4242,3088,1488,4259,3088,1488,4220,3088,1488,4240,3088,1488,426b +,3088,1488,4261,3088,1488,426c,3088,1488,425f,3088,1488,426a,3088 +,1488,4261,3088,1488,426e,3088,1488,4220,3088,1488,42bb,3088,1488 +,42bb,3088,1488,42bb,3088,1488,42bb,3088,1488,14b5,1488,14b7,14b5 +,1488,14b7,4220,3088,1488,423e,3088,1488,4220,3088,1488,4a17,2b40 +,4c01,3170,61ff,31c0,1fc8,31c8,1fc8,31d8,1fc8,4016,2000,2000,4215 +,2240,1600,16e9,16e9,8407,1600,16e9,16d9,8410,3080,1488,6012,14b5 +,1488,14b7,4220,3088,1488,423e,3088,1488,4220,3088,1488,6005,1489 +,4220,3088,1488,1489,1fc9,27c0,1fc9,23c0,1fc9,21c0,e000 diff --git a/resources/asm/text_mode.atk16 b/resources/asm/text_mode.atk16 index 3fc40d2..cab9562 100644 --- a/resources/asm/text_mode.atk16 +++ b/resources/asm/text_mode.atk16 @@ -1,8 +1,20 @@ @use ext_string_io:* @include %bootstrap +@include %std_mem + +@label text_buffer_size + 2048 @label main + ; use memset to clear the text buffer + ldi vt_text_mem RA ; RA := text buffer address pointer + ldr RA RA ; RA := text buffer address + ldi text_buffer_size RB ; RB := pointer to 1024 + ldr RB RB ; RB := 1024 + ldi 0 RC ; RC := 0 + calli memset + cursor_to_line RC 1 put_string RC RB " HELLO #vaincoodijutut" new_line RC @@ -16,7 +28,7 @@ @label loop jpi loop -@label my_keyboard_isr +@label keyboard_isr stack_stash RA RB RD ldi vt_kb_pp_addr RA ; RA := Keyboard peripheral address pointer ldr RA RA ; RA := Keyboard peripheral address deref @@ -54,5 +66,5 @@ @address vt_ISR0 @begin_override - my_keyboard_isr + keyboard_isr @end_override diff --git a/test/e2e/std_mem/run_memset.atk16 b/test/e2e/std_mem/run_memset.atk16 new file mode 100644 index 0000000..07e7666 --- /dev/null +++ b/test/e2e/std_mem/run_memset.atk16 @@ -0,0 +1,21 @@ +@include %bootstrap +@include %std_mem + +@label mem_offset + 0x9000 + +@label main + ; set 0x9005 to value 4 + ldi mem_offset RA + ldr RA RA + addi RA 5 RA + ldi 4 RB + str RB RA + + ; set values 0x0000..0x0004 to 3 + ldi mem_offset RA + ldr RA RA + ldi 5 RB + ldi 3 RC + calli memset + hlt diff --git a/test/e2e/std_mem/test_memset.py b/test/e2e/std_mem/test_memset.py new file mode 100644 index 0000000..0052ffe --- /dev/null +++ b/test/e2e/std_mem/test_memset.py @@ -0,0 +1,22 @@ +from atk16_asm import assemble +from atk16_emu import Machine +from test.utils import pad_bytearray + +def test_memset(): + filename = "test/e2e/std_mem/run_memset.atk16" + with open(filename, "r") as f: + source = f.read() + + obj = assemble(source, filename) + rom_image = pad_bytearray(obj.program) + + machine = Machine() + machine.load_rom_image(rom_image) + machine.reset() + machine.run_until_halted() + machine.print_state_summary() + + addr = 0x9000 - 0x8000 + expected_n = 5 + expected_value = 3 + assert all(map(lambda x: x == expected_value, machine.ram.memory[addr:addr+expected_n])) -- cgit v1.3