diff options
| author | Jan Tuomi <jans.tuomi@gmail.com> | 2024-02-25 20:08:32 +0200 |
|---|---|---|
| committer | Jan Tuomi <jans.tuomi@gmail.com> | 2024-02-25 20:08:32 +0200 |
| commit | 5776a07e6a3def343996c5ec83cd69242f7ea23a (patch) | |
| tree | dfe91cff071a60be9fd9fc674625b8b462e06f27 | |
| parent | 3ac72608e8fc708277137fde62193c8763268ff5 (diff) | |
Add tests, fix bugs
| -rw-r--r-- | atk16_asm/asm_ops.py | 8 | ||||
| -rw-r--r-- | atk16_emu/emu.py | 52 | ||||
| -rw-r--r-- | atk16_emu/test/test_alu.py | 344 | ||||
| -rw-r--r-- | atk16_emu/test/test_load.py | 32 | ||||
| -rw-r--r-- | atk16_emu/test/test_opcode_alr.py | 154 | ||||
| -rw-r--r-- | atk16_emu/test/test_store.py | 18 | ||||
| -rw-r--r-- | test/e2e/fibo/bootstrap.atk16 | 2 | ||||
| -rw-r--r-- | test/e2e/fibo/test_fibo.py | 2 | ||||
| -rw-r--r-- | test/e2e/just_hlt/test_just_hlt.py | 2 | ||||
| -rw-r--r-- | test/e2e/sum/test_sum.py | 2 |
10 files changed, 447 insertions, 169 deletions
diff --git a/atk16_asm/asm_ops.py b/atk16_asm/asm_ops.py index 293b1cc..6a08495 100644 --- a/atk16_asm/asm_ops.py +++ b/atk16_asm/asm_ops.py @@ -54,11 +54,11 @@ def make_ldr(meta: Meta, symbols: Symbols, addr_reg: str, to_reg: str) -> int: def make_str(meta: Meta, symbols: Symbols, from_reg: str, addr_reg: str) -> int: """STR 0011 XXXL LLRR RXXX""" - from_reg_e = eval_expr(symbols, from_reg, bits=3) - addr_reg_e = eval_expr(symbols, addr_reg, bits=3) + addr_reg_e = eval_expr(symbols, from_reg, bits=3) + from_reg_e = eval_expr(symbols, addr_reg, bits=3) word = (0b0011 << 12) + \ - (addr_reg_e << 6) + \ - (from_reg_e << 3) + (from_reg_e << 6) + \ + (addr_reg_e << 3) return word def make_ldi(meta: Meta, symbols: Symbols, imm: str, to_reg: str) -> int: diff --git a/atk16_emu/emu.py b/atk16_emu/emu.py index c87fff6..1d8fd1e 100644 --- a/atk16_emu/emu.py +++ b/atk16_emu/emu.py @@ -103,17 +103,54 @@ class ALU: sign = (result & 0x8000) != 0 )) case 2: # L and R - raise NotImplementedError() + result = L & R + return ALUResult(result, ALUFlags( + carry = False, + overflow = False, + zero = result == 0, + sign = (result & 0x8000) != 0 + )) case 3: # L or R - raise NotImplementedError() + result = L | R + return ALUResult(result, ALUFlags( + carry = False, + overflow = False, + zero = result == 0, + sign = (result & 0x8000) != 0 + )) case 4: # L xor R - raise NotImplementedError() + result = L ^ R + return ALUResult(result, ALUFlags( + carry = False, + overflow = False, + zero = result == 0, + sign = (result & 0x8000) != 0 + )) case 5: # L >> R logical - raise NotImplementedError() + result = L >> R + return ALUResult(result, ALUFlags( + carry = False, + overflow = False, + zero = result == 0, + sign = (result & 0x8000) != 0 + )) case 6: # L >>> R arithmetic - raise NotImplementedError() + # shift right but keep the sign bit (16-bit) + result = (L >> R) | (L & 0x8000) + return ALUResult(result, ALUFlags( + carry = False, + overflow = False, + zero = result == 0, + sign = (result & 0x8000) != 0 + )) case 7: # L << R - raise NotImplementedError() + result = (L << R) & 0xFFFF + return ALUResult(result, ALUFlags( + carry = False, + overflow = False, + zero = result == 0, + sign = (result & 0x8000) != 0 + )) raise ValueError(f"Invalid ALU S: {S}") @@ -200,7 +237,7 @@ class Machine: def mem_write(self, addr: int, value: int): if addr < 2 ** 15: - raise ValueError(f"Cannot write to ROM, addr: {addr:>04x}") + raise ValueError(f"Cannot write to ROM, addr: 0x{addr:>04x}") else: # TODO: Implement memory-mapped I/O self.ram.write(addr & 0x7FFF, value) @@ -295,6 +332,7 @@ class Machine: addr = self.get_nth_register(addr_reg).value value = self.get_nth_register(from_reg).value + print(f"==== addr: 0x{addr:>04x}, value: 0x{value:>04x}") self.mem_write(addr, value) case LDI(to_reg, imm): diff --git a/atk16_emu/test/test_alu.py b/atk16_emu/test/test_alu.py new file mode 100644 index 0000000..dfae609 --- /dev/null +++ b/atk16_emu/test/test_alu.py @@ -0,0 +1,344 @@ +from atk16_emu import Machine +from test.utils import make_rom + +def test_alr_add_small_unsigned(): + machine = Machine() + + rom_image = make_rom([0b0000_010_000_001_000]) # ALR target=RC left=RA right=RB alu_code=0 + machine.load_rom_image(rom_image) + machine.reset() + + machine.ra.value = 10 + machine.rb.value = 20 + + machine.run() + machine.step() + + assert machine.rc.value == 30 + assert machine.fr.carry == False + assert machine.fr.overflow == False + assert machine.fr.zero == False + assert machine.fr.sign == False + +def test_alr_add_large_unsigned(): + machine = Machine() + + rom_image = make_rom([0b0000_010_000_001_000]) # ALR target=RC left=RA right=RB alu_code=0 + machine.load_rom_image(rom_image) + machine.reset() + + machine.ra.value = 0xFFFF + machine.rb.value = 20 + + machine.run() + machine.step() + + assert machine.rc.value == 19 + assert machine.fr.carry == True + assert machine.fr.overflow == False + assert machine.fr.zero == False + assert machine.fr.sign == False + +def test_alr_add_small_signed(): + machine = Machine() + + rom_image = make_rom([0b0000_010_000_001_000]) # ALR target=RC left=RA right=RB alu_code=0 + machine.load_rom_image(rom_image) + machine.reset() + + machine.ra.value = 0xFFFF # -1 + machine.rb.value = 0x0001 # 1 + + machine.run() + machine.step() + + assert machine.rc.value == 0 + assert machine.fr.carry == True + assert machine.fr.overflow == False + assert machine.fr.zero == True + assert machine.fr.sign == False + +def test_alr_add_large_signed(): + machine = Machine() + + rom_image = make_rom([0b0000_010_000_001_000]) # ALR target=RC left=RA right=RB alu_code=0 + machine.load_rom_image(rom_image) + machine.reset() + + machine.ra.value = 0x7FFF # 32767 + machine.rb.value = 0x0001 # 1 + + machine.run() + machine.step() + + assert machine.rc.value == 0x8000 # -32768 + assert machine.fr.carry == False + assert machine.fr.overflow == True + assert machine.fr.zero == False + assert machine.fr.sign == True + +def test_alr_sub_small_unsigned(): + machine = Machine() + + rom_image = make_rom([0b0000_010_000_001_001]) # ALR target=RC left=RA right=RB alu_code=1 + machine.load_rom_image(rom_image) + machine.reset() + + machine.ra.value = 10 + machine.rb.value = 20 + + machine.run() + machine.step() + + assert machine.rc.value == 0xFFF6 # -10 + assert machine.fr.carry == True + assert machine.fr.overflow == False + assert machine.fr.zero == False + assert machine.fr.sign == True + +def test_alr_sub_large_unsigned(): + machine = Machine() + + rom_image = make_rom([0b0000_010_000_001_001]) # ALR target=RC left=RA right=RB alu_code=1 + machine.load_rom_image(rom_image) + machine.reset() + + machine.ra.value = 0xFFFF + machine.rb.value = 0xFFFF + + machine.run() + machine.step() + + assert machine.rc.value == 0x0000 + assert machine.fr.carry == False + assert machine.fr.overflow == False + assert machine.fr.zero == True + assert machine.fr.sign == False + +def test_alr_sub_small_signed(): + machine = Machine() + + rom_image = make_rom([0b0000_010_000_001_001]) # ALR target=RC left=RA right=RB alu_code=1 + machine.load_rom_image(rom_image) + machine.reset() + + machine.ra.value = 0x0001 # 1 + machine.rb.value = 0xFFFF # -1 + + machine.run() + machine.step() + + assert machine.rc.value == 0x0002 + assert machine.fr.carry == True + assert machine.fr.overflow == False + assert machine.fr.zero == False + assert machine.fr.sign == False + +def test_alr_sub_large_signed(): + machine = Machine() + + rom_image = make_rom([0b0000_010_000_001_001]) # ALR target=RC left=RA right=RB alu_code=1 + machine.load_rom_image(rom_image) + machine.reset() + + machine.ra.value = 0x7FFF # 32767 + machine.rb.value = 0xFFFF # -1 + + machine.run() + machine.step() + + assert machine.rc.value == 0x8000 # -32768 + assert machine.fr.carry == True + assert machine.fr.overflow == True + assert machine.fr.zero == False + assert machine.fr.sign == True + +def test_alr_and(): + machine = Machine() + + rom_image = make_rom([0b0000_010_000_001_010]) # ALR target=RC left=RA right=RB alu_code=2 + machine.load_rom_image(rom_image) + machine.reset() + + machine.ra.value = 0b1010 + machine.rb.value = 0b1100 + + machine.run() + machine.step() + + assert machine.rc.value == 0b1000 + assert machine.fr.carry == False + assert machine.fr.overflow == False + assert machine.fr.zero == False + assert machine.fr.sign == False + +def test_alr_or(): + machine = Machine() + + rom_image = make_rom([0b0000_010_000_001_011]) # ALR target=RC left=RA right=RB alu_code=3 + machine.load_rom_image(rom_image) + machine.reset() + + machine.ra.value = 0b1010 + machine.rb.value = 0b1100 + + machine.run() + machine.step() + + assert machine.rc.value == 0b1110 + assert machine.fr.carry == False + assert machine.fr.overflow == False + assert machine.fr.zero == False + assert machine.fr.sign == False + +def test_alr_xor(): + machine = Machine() + + rom_image = make_rom([0b0000_010_000_001_100]) # ALR target=RC left=RA right=RB alu_code=4 + machine.load_rom_image(rom_image) + machine.reset() + + machine.ra.value = 0b1010 + machine.rb.value = 0b1100 + + machine.run() + machine.step() + + assert machine.rc.value == 0b0110 + assert machine.fr.carry == False + assert machine.fr.overflow == False + assert machine.fr.zero == False + assert machine.fr.sign == False + +def test_alr_slr_small(): + machine = Machine() + + rom_image = make_rom([0b0000_010_000_001_101]) # ALR target=RC left=RA right=RB alu_code=5 + machine.load_rom_image(rom_image) + machine.reset() + + machine.ra.value = 0b1010 + machine.rb.value = 0b0001 + + machine.run() + machine.step() + + assert machine.rc.value == 0b0101 + assert machine.fr.carry == False + assert machine.fr.overflow == False + assert machine.fr.zero == False + assert machine.fr.sign == False + +def test_alr_slr_large(): + machine = Machine() + + rom_image = make_rom([0b0000_010_000_001_101]) # ALR target=RC left=RA right=RB alu_code=5 + machine.load_rom_image(rom_image) + machine.reset() + + machine.ra.value = 0xFFFF + machine.rb.value = 0x1 + + machine.run() + machine.step() + + assert machine.rc.value == 0x7FFF + assert machine.fr.carry == False + assert machine.fr.overflow == False + assert machine.fr.zero == False + assert machine.fr.sign == False + +def test_alr_sar_small(): + machine = Machine() + + rom_image = make_rom([0b0000_010_000_001_110]) # ALR target=RC left=RA right=RB alu_code=6 + machine.load_rom_image(rom_image) + machine.reset() + + machine.ra.value = 0b1010 + machine.rb.value = 0b0001 + + machine.run() + machine.step() + + assert machine.rc.value == 0b0101 + assert machine.fr.carry == False + assert machine.fr.overflow == False + assert machine.fr.zero == False + assert machine.fr.sign == False + +def test_alr_sar_large(): + machine = Machine() + + rom_image = make_rom([0b0000_010_000_001_110]) # ALR target=RC left=RA right=RB alu_code=6 + machine.load_rom_image(rom_image) + machine.reset() + + machine.ra.value = 0xFFFF + machine.rb.value = 0x1 + + machine.run() + machine.step() + + assert machine.rc.value == 0xFFFF + assert machine.fr.carry == False + assert machine.fr.overflow == False + assert machine.fr.zero == False + assert machine.fr.sign == True + + +def test_alr_sll_small(): + machine = Machine() + + rom_image = make_rom([0b0000_010_000_001_111]) # ALR target=RC left=RA right=RB alu_code=7 + machine.load_rom_image(rom_image) + machine.reset() + + machine.ra.value = 0b1010 + machine.rb.value = 0b0001 + + machine.run() + machine.step() + + assert machine.rc.value == 0b10100 + assert machine.fr.carry == False + assert machine.fr.overflow == False + assert machine.fr.zero == False + assert machine.fr.sign == False + +def test_alr_sll_large(): + machine = Machine() + + rom_image = make_rom([0b0000_010_000_001_111]) # ALR target=RC left=RA right=RB alu_code=7 + machine.load_rom_image(rom_image) + machine.reset() + + machine.ra.value = 0xFFFF + machine.rb.value = 0x1 + + machine.run() + machine.step() + + assert machine.rc.value == 0xFFFE + assert machine.fr.carry == False + assert machine.fr.overflow == False + assert machine.fr.zero == False + assert machine.fr.sign == True + +def test_ali_add_small_unsigned(): + machine = Machine() + + rom_image = make_rom([0b0001_010_000_001_000]) # ALI target=RC left=RA imm=0x000A alu_code=0 + machine.load_rom_image(rom_image) + machine.reset() + + machine.ra.value = 10 + + machine.run() + machine.step() + + assert machine.rc.value == 11 + assert machine.fr.carry == False + assert machine.fr.overflow == False + assert machine.fr.zero == False + assert machine.fr.sign == False diff --git a/atk16_emu/test/test_load.py b/atk16_emu/test/test_load.py new file mode 100644 index 0000000..c03fb8d --- /dev/null +++ b/atk16_emu/test/test_load.py @@ -0,0 +1,32 @@ +from atk16_emu import Machine +from test.utils import make_rom + +def test_ldr(): + machine = Machine() + + rom_image = make_rom([0b0010_010_000_000_000]) # ALR target=RC reg=RA + machine.load_rom_image(rom_image) + machine.reset() + + machine.mem_write(0x8000, 0x1234) + machine.ra.value = 0x8000 # mem address + machine.rc.value = 0x2345 + + machine.run() + machine.step() + + assert machine.rc.value == 0x1234 + +def test_ldi(): + machine = Machine() + + rom_image = make_rom([0b0100_010_111111111]) # LDI target=RC imm=511 + machine.load_rom_image(rom_image) + machine.reset() + + machine.rc.value = 0x123 + + machine.run() + machine.step() + + assert machine.rc.value == 511 diff --git a/atk16_emu/test/test_opcode_alr.py b/atk16_emu/test/test_opcode_alr.py deleted file mode 100644 index 9a34845..0000000 --- a/atk16_emu/test/test_opcode_alr.py +++ /dev/null @@ -1,154 +0,0 @@ -from atk16_emu import Machine -from test.utils import make_rom - -def test_alr_add_small_unsigned(): - machine = Machine() - - rom_image = make_rom([0b0000_010_000_001_000]) # ALR target=RC left=RA right=RB alu_code=0 - machine.load_rom_image(rom_image) - machine.reset() - - machine.ra.value = 10 - machine.rb.value = 20 - - machine.run() - machine.step() - - assert machine.rc.value == 30 - assert machine.fr.carry == 0 - assert machine.fr.overflow == 0 - assert machine.fr.zero == 0 - assert machine.fr.sign == 0 - -def test_alr_add_large_unsigned(): - machine = Machine() - - rom_image = make_rom([0b0000_010_000_001_000]) # ALR target=RC left=RA right=RB alu_code=0 - machine.load_rom_image(rom_image) - machine.reset() - - machine.ra.value = 0xFFFF - machine.rb.value = 20 - - machine.run() - machine.step() - - assert machine.rc.value == 19 - assert machine.fr.carry == 1 - assert machine.fr.overflow == 0 - assert machine.fr.zero == 0 - assert machine.fr.sign == 0 - -def test_alr_add_small_signed(): - machine = Machine() - - rom_image = make_rom([0b0000_010_000_001_000]) # ALR target=RC left=RA right=RB alu_code=0 - machine.load_rom_image(rom_image) - machine.reset() - - machine.ra.value = 0xFFFF # -1 - machine.rb.value = 0x0001 # 1 - - machine.run() - machine.step() - - assert machine.rc.value == 0 - assert machine.fr.carry == 1 - assert machine.fr.overflow == 0 - assert machine.fr.zero == 1 - assert machine.fr.sign == 0 - -def test_alr_add_large_signed(): - machine = Machine() - - rom_image = make_rom([0b0000_010_000_001_000]) # ALR target=RC left=RA right=RB alu_code=0 - machine.load_rom_image(rom_image) - machine.reset() - - machine.ra.value = 0x7FFF # 32767 - machine.rb.value = 0x0001 # 1 - - machine.run() - machine.step() - - assert machine.rc.value == 0x8000 # -32768 - assert machine.fr.carry == 0 - assert machine.fr.overflow == 1 - assert machine.fr.zero == 0 - assert machine.fr.sign == 1 - -def test_alr_sub_small_unsigned(): - machine = Machine() - - rom_image = make_rom([0b0000_010_000_001_001]) # ALR target=RC left=RA right=RB alu_code=1 - machine.load_rom_image(rom_image) - machine.reset() - - machine.ra.value = 10 - machine.rb.value = 20 - - machine.run() - machine.step() - - assert machine.rc.value == 0xFFF6 # -10 - assert machine.fr.carry == 1 - assert machine.fr.overflow == 0 - assert machine.fr.zero == 0 - assert machine.fr.sign == 1 - -def test_alr_sub_large_unsigned(): - machine = Machine() - - rom_image = make_rom([0b0000_010_000_001_001]) # ALR target=RC left=RA right=RB alu_code=1 - machine.load_rom_image(rom_image) - machine.reset() - - machine.ra.value = 0xFFFF - machine.rb.value = 0xFFFF - - machine.run() - machine.step() - - assert machine.rc.value == 0x0000 - assert machine.fr.carry == 0 - assert machine.fr.overflow == 0 - assert machine.fr.zero == 1 - assert machine.fr.sign == 0 - -def test_alr_sub_small_signed(): - machine = Machine() - - rom_image = make_rom([0b0000_010_000_001_001]) # ALR target=RC left=RA right=RB alu_code=1 - machine.load_rom_image(rom_image) - machine.reset() - - machine.ra.value = 0x0001 # 1 - machine.rb.value = 0xFFFF # -1 - - machine.run() - machine.step() - - assert machine.rc.value == 0x0002 - assert machine.fr.carry == 1 - assert machine.fr.overflow == 0 - assert machine.fr.zero == 0 - assert machine.fr.sign == 0 - -def test_alr_sub_large_signed(): - machine = Machine() - - rom_image = make_rom([0b0000_010_000_001_001]) # ALR target=RC left=RA right=RB alu_code=1 - machine.load_rom_image(rom_image) - machine.reset() - - machine.ra.value = 0x7FFF # 32767 - machine.rb.value = 0xFFFF # -1 - - machine.run() - machine.step() - - assert machine.rc.value == 0x8000 # -32768 - assert machine.fr.carry == 1 - assert machine.fr.overflow == 1 - assert machine.fr.zero == 0 - assert machine.fr.sign == 1 diff --git a/atk16_emu/test/test_store.py b/atk16_emu/test/test_store.py new file mode 100644 index 0000000..4b1b3df --- /dev/null +++ b/atk16_emu/test/test_store.py @@ -0,0 +1,18 @@ +from atk16_emu import Machine +from test.utils import make_rom + +def test_str(): + machine = Machine() + + rom_image = make_rom([0b0011_000_000_001_000]) # STR addr=RA data=RB + machine.load_rom_image(rom_image) + machine.reset() + + machine.mem_write(0x8000, 0x1234) + machine.ra.value = 0x8000 # mem address + machine.rb.value = 0x2345 + + machine.run() + machine.step() + + assert machine.mem_read(0x8000) == 0x2345 diff --git a/test/e2e/fibo/bootstrap.atk16 b/test/e2e/fibo/bootstrap.atk16 index 0fe2a9d..9b024e6 100644 --- a/test/e2e/fibo/bootstrap.atk16 +++ b/test/e2e/fibo/bootstrap.atk16 @@ -1,4 +1,4 @@ -@let sp RH +@let SP RH ; vector table fields @let vector_table 0x10 diff --git a/test/e2e/fibo/test_fibo.py b/test/e2e/fibo/test_fibo.py index 6dae09b..a7146fc 100644 --- a/test/e2e/fibo/test_fibo.py +++ b/test/e2e/fibo/test_fibo.py @@ -8,7 +8,7 @@ def test_fibo(): source = f.read() obj = assemble(source, filename) - rom_image = pad_bytearray(obj) + rom_image = pad_bytearray(obj.program) machine = Machine() machine.load_rom_image(rom_image) diff --git a/test/e2e/just_hlt/test_just_hlt.py b/test/e2e/just_hlt/test_just_hlt.py index 60c59b0..c037615 100644 --- a/test/e2e/just_hlt/test_just_hlt.py +++ b/test/e2e/just_hlt/test_just_hlt.py @@ -8,7 +8,7 @@ def test_just_hlt(): source = f.read() obj = assemble(source, filename) - rom_image = pad_bytearray(obj) + rom_image = pad_bytearray(obj.program) machine = Machine() machine.load_rom_image(rom_image) diff --git a/test/e2e/sum/test_sum.py b/test/e2e/sum/test_sum.py index 3484af5..3edc1aa 100644 --- a/test/e2e/sum/test_sum.py +++ b/test/e2e/sum/test_sum.py @@ -8,7 +8,7 @@ def test_sum(): source = f.read() obj = assemble(source, filename) - rom_image = pad_bytearray(obj) + rom_image = pad_bytearray(obj.program) machine = Machine() machine.load_rom_image(rom_image) |
