diff --git a/gbso/cpu.py b/gbso/cpu.py index d5e0948..3f9b39d 100644 --- a/gbso/cpu.py +++ b/gbso/cpu.py @@ -8,6 +8,7 @@ class CPU: carry: int cycles: int reg8: Dict[R8, int] + sp: int memory: bytearray def __init__(self) -> None: @@ -20,12 +21,19 @@ class CPU: return self.reg8[r] def get_reg16(self, rr: R16) -> int: + if rr == R16.SP: + return self.sp + return (self.reg8[R16_HI[rr]] << 8) | self.reg8[R16_LO[rr]] def set_reg8(self, r: R8, n: int) -> None: self.reg8[r] = n & 0xFF def set_reg16(self, rr: R16, nn: int) -> None: + if rr == R16.SP: + self.sp = nn & 0xFFFF + return + self.reg8[R16_HI[rr]] = (nn >> 8) & 0xFF self.reg8[R16_LO[rr]] = nn & 0xFF @@ -33,14 +41,14 @@ class CPU: return self.memory[nn & 0xFFFF] def get_mem16(self, nn: int) -> int: - return (self.memory[(nn + 1) & 0xFF] << 8) | self.memory[nn & 0xFFFF] + return (self.memory[nn & 0xFFFF] << 8) | self.memory[(nn + 1) & 0xFFFF] def set_mem8(self, nn: int, n: int) -> None: self.memory[nn & 0xFFFF] = n & 0xFF def set_mem16(self, nn: int, nn1: int) -> None: - self.memory[nn & 0xFFFF] = nn1 & 0xFF - self.memory[(nn + 1) & 0xFFFF] = (nn1 >> 8) & 0xFF + self.memory[nn & 0xFFFF] = (nn1 >> 8) & 0xFF + self.memory[(nn + 1) & 0xFFFF] = nn1 & 0xFF def deref_hl(self) -> int: return self.get_mem8(self.get_reg16(R16.HL)) diff --git a/gbso/insn.py b/gbso/insn.py index 026160c..31e75c4 100644 --- a/gbso/insn.py +++ b/gbso/insn.py @@ -240,6 +240,7 @@ class LD_RR_NN(Insn): def exec(self, cpu: CPU) -> None: cpu.set_reg16(self.rr, self.nn) + cpu.cycles += 12 def pretty(self) -> str: return f"LD {self.rr.value}, {hex(self.nn)}" @@ -251,6 +252,7 @@ class LD_NN_SP(Insn): def exec(self, cpu: CPU) -> None: cpu.set_mem16(self.nn, cpu.get_reg16(R16.SP)) + cpu.cycles += 20 def pretty(self) -> str: return f"LD ({hex(self.nn)}), SP" @@ -260,19 +262,23 @@ class LD_NN_SP(Insn): class LD_SP_HL(Insn): def exec(self, cpu: CPU) -> None: cpu.set_reg16(R16.SP, cpu.get_reg16(R16.HL)) + cpu.cycles += 8 def pretty(self) -> str: return "LD SP, HL" +# NOTE: Normally we would support PUSH AF, but then non-carry flags could impact +# the program (by popping or inspecting where F was stored) @dataclass class PUSH_RR(Insn): rr: R16 def exec(self, cpu: CPU) -> None: - sp = cpu.get_reg16(R16.SP) - cpu.set_reg16(R16.SP, sp - 2) - cpu.set_mem16(sp - 2, cpu.get_reg16(self.rr)) + sp = cpu.get_reg16(R16.SP) - 2 + cpu.set_reg16(R16.SP, sp) + cpu.set_mem16(sp, cpu.get_reg16(self.rr)) + cpu.cycles += 16 def pretty(self) -> str: return f"PUSH {self.rr.value}" @@ -286,6 +292,7 @@ class POP_RR(Insn): sp = cpu.get_reg16(R16.SP) cpu.set_reg16(self.rr, cpu.get_mem16(sp)) cpu.set_reg16(R16.SP, sp + 2) + cpu.cycles += 12 def pretty(self) -> str: return f"POP {self.rr.value}" @@ -299,6 +306,7 @@ class ADD_A_R(Insn): a = cpu.get_reg8(R8.A) + cpu.get_reg8(self.r) cpu.carry = 1 if a > 0xFF else 0 cpu.set_reg8(R8.A, a) + cpu.cycles += 4 def pretty(self) -> str: return f"ADD A, {self.r.value}" @@ -312,6 +320,7 @@ class ADD_A_N(Insn): a = cpu.get_reg8(R8.A) + self.n cpu.carry = 1 if a > 0xFF else 0 cpu.set_reg8(R8.A, a) + cpu.cycles += 8 def pretty(self) -> str: return f"ADD A, {hex(self.n)}" @@ -323,6 +332,7 @@ class ADD_A_HL(Insn): a = cpu.get_reg8(R8.A) + cpu.get_mem8(cpu.get_reg16(R16.HL)) cpu.carry = 1 if a > 0xFF else 0 cpu.set_reg8(R8.A, a) + cpu.cycles += 8 def pretty(self) -> str: return f"ADD A, (HL)" @@ -336,6 +346,7 @@ class ADC_A_R(Insn): a = cpu.get_reg8(R8.A) + cpu.get_reg8(self.r) + cpu.carry cpu.carry = 1 if a > 0xFF else 0 cpu.set_reg8(R8.A, a) + cpu.cycles += 4 def pretty(self) -> str: return f"ADC A, {self.r.value}" @@ -349,6 +360,7 @@ class ADC_A_N(Insn): a = cpu.get_reg8(R8.A) + self.n + cpu.carry cpu.carry = 1 if a > 0xFF else 0 cpu.set_reg8(R8.A, a) + cpu.cycles += 8 def pretty(self) -> str: return f"ADC A, {hex(self.n)}" @@ -360,6 +372,7 @@ class ADC_A_HL(Insn): a = cpu.get_reg8(R8.A) + cpu.get_mem8(cpu.get_reg16(R16.HL)) + cpu.carry cpu.carry = 1 if a > 0xFF else 0 cpu.set_reg8(R8.A, a) + cpu.cycles += 8 def pretty(self) -> str: return f"ADC A, (HL)" @@ -373,6 +386,7 @@ class SUB_A_R(Insn): a = cpu.get_reg8(R8.A) - cpu.get_reg8(self.r) cpu.carry = 1 if a < 0 else 0 cpu.set_reg8(R8.A, a) + cpu.cycles += 4 def pretty(self) -> str: return f"SUB A, {self.r.value}" @@ -386,6 +400,7 @@ class SUB_A_N(Insn): a = cpu.get_reg8(R8.A) - self.n cpu.carry = 1 if a < 0 else 0 cpu.set_reg8(R8.A, a) + cpu.cycles += 8 def pretty(self) -> str: return f"SUB A, {hex(self.n)}" @@ -397,6 +412,7 @@ class SUB_A_HL(Insn): a = cpu.get_reg8(R8.A) - cpu.get_mem8(cpu.get_reg16(R16.HL)) cpu.carry = 1 if a < 0 else 0 cpu.set_reg8(R8.A, a) + cpu.cycles += 8 def pretty(self) -> str: return "SUB A, (HL)" @@ -410,6 +426,7 @@ class SBC_A_R(Insn): a = cpu.get_reg8(R8.A) - cpu.get_reg8(self.r) - cpu.carry cpu.carry = 1 if a < 0 else 0 cpu.set_reg8(R8.A, a) + cpu.cycles += 4 def pretty(self) -> str: return f"SBC A, {self.r.value}" @@ -423,6 +440,7 @@ class SBC_A_N(Insn): a = cpu.get_reg8(R8.A) - self.n - cpu.carry cpu.carry = 1 if a < 0 else 0 cpu.set_reg8(R8.A, a) + cpu.cycles += 8 def pretty(self) -> str: return f"SBC A, {hex(self.n)}" @@ -434,6 +452,7 @@ class SBC_A_HL(Insn): a = cpu.get_reg8(R8.A) - cpu.get_mem8(cpu.get_reg16(R16.HL)) - cpu.carry cpu.carry = 1 if a < 0 else 0 cpu.set_reg8(R8.A, a) + cpu.cycles += 8 def pretty(self) -> str: return "SBC A, (HL)" @@ -447,6 +466,7 @@ class AND_A_R(Insn): a = cpu.get_reg8(R8.A) & cpu.get_reg8(self.r) cpu.set_reg8(R8.A, a) cpu.carry = 0 + cpu.cycles += 4 def pretty(self) -> str: return f"AND A, {self.r.value}" @@ -460,6 +480,7 @@ class AND_A_N(Insn): a = cpu.get_reg8(R8.A) & self.n cpu.set_reg8(R8.A, a) cpu.carry = 0 + cpu.cycles += 8 def pretty(self) -> str: return f"AND A, {hex(self.n)}" @@ -471,17 +492,99 @@ class AND_A_HL(Insn): a = cpu.get_reg8(R8.A) & cpu.get_mem8(cpu.get_reg16(R16.HL)) cpu.set_reg8(R8.A, a) cpu.carry = 0 + cpu.cycles += 8 def pretty(self) -> str: return "AND A, (HL)" +@dataclass +class XOR_A_R(Insn): + r: R8 + + def exec(self, cpu: CPU) -> None: + a = cpu.get_reg8(R8.A) ^ cpu.get_reg8(self.r) + cpu.set_reg8(R8.A, a) + cpu.carry = 0 + cpu.cycles += 4 + + def pretty(self) -> str: + return f"XOR A, {self.r.value}" + + +@dataclass +class XOR_A_N(Insn): + n: int + + def exec(self, cpu: CPU) -> None: + a = cpu.get_reg8(R8.A) ^ self.n + cpu.set_reg8(R8.A, a) + cpu.carry = 0 + cpu.cycles += 8 + + def pretty(self) -> str: + return f"XOR A, {hex(self.n)}" + + +@dataclass +class XOR_A_HL(Insn): + def exec(self, cpu: CPU) -> None: + a = cpu.get_reg8(R8.A) ^ cpu.get_mem8(cpu.get_reg16(R16.HL)) + cpu.set_reg8(R8.A, a) + cpu.carry = 0 + cpu.cycles += 8 + + def pretty(self) -> str: + return "XOR A, (HL)" + + +@dataclass +class OR_A_R(Insn): + r: R8 + + def exec(self, cpu: CPU) -> None: + a = cpu.get_reg8(R8.A) | cpu.get_reg8(self.r) + cpu.set_reg8(R8.A, a) + cpu.carry = 0 + cpu.cycles += 4 + + def pretty(self) -> str: + return f"OR A, {self.r.value}" + + +@dataclass +class OR_A_N(Insn): + n: int + + def exec(self, cpu: CPU) -> None: + a = cpu.get_reg8(R8.A) | self.n + cpu.set_reg8(R8.A, a) + cpu.carry = 0 + cpu.cycles += 8 + + def pretty(self) -> str: + return f"OR A, {hex(self.n)}" + + +@dataclass +class OR_A_HL(Insn): + def exec(self, cpu: CPU) -> None: + a = cpu.get_reg8(R8.A) | cpu.get_mem8(cpu.get_reg16(R16.HL)) + cpu.set_reg8(R8.A, a) + cpu.carry = 0 + cpu.cycles += 8 + + def pretty(self) -> str: + return "OR A, (HL)" + + @dataclass class CP_A_R(Insn): r: R8 def exec(self, cpu: CPU) -> None: cpu.carry = 1 if cpu.get_reg8(R8.A) < cpu.get_reg8(self.r) else 0 + cpu.cycles += 4 def pretty(self) -> str: return f"CP A, {self.r.value}" @@ -493,6 +596,7 @@ class CP_A_N(Insn): def exec(self, cpu: CPU) -> None: cpu.carry = 1 if cpu.get_reg8(R8.A) < self.n else 0 + cpu.cycles += 8 def pretty(self) -> str: return f"CP A, {hex(self.n)}" @@ -502,6 +606,7 @@ class CP_A_N(Insn): class CP_A_HL(Insn): def exec(self, cpu: CPU) -> None: cpu.carry = 1 if cpu.get_reg8(R8.A) < cpu.get_mem8(cpu.get_reg16(R16.HL)) else 0 + cpu.cycles += 8 def pretty(self) -> str: return "CP A, (HL)" @@ -513,6 +618,7 @@ class INC_R(Insn): def exec(self, cpu: CPU) -> None: cpu.set_reg8(self.r, cpu.get_reg8(self.r) + 1) + cpu.cycles += 4 def pretty(self) -> str: return f"INC {self.r.value}" @@ -525,6 +631,7 @@ class INC_HL(Insn): def exec(self, cpu: CPU) -> None: hl = cpu.get_reg16(R16.HL) cpu.set_mem8(hl, cpu.get_mem8(hl) + 1) + cpu.cycles += 12 def pretty(self) -> str: return "INC (HL)" @@ -536,6 +643,7 @@ class DEC_R(Insn): def exec(self, cpu: CPU) -> None: cpu.set_reg8(self.r, cpu.get_reg8(self.r) - 1) + cpu.cycles += 4 def pretty(self) -> str: return f"DEC {self.r.value}" @@ -548,6 +656,7 @@ class DEC_HL(Insn): def exec(self, cpu: CPU) -> None: hl = cpu.get_reg16(R16.HL) cpu.set_mem8(hl, cpu.get_mem8(hl) - 1) + cpu.cycles += 12 def pretty(self) -> str: return "DEC (HL)" @@ -557,6 +666,7 @@ class DEC_HL(Insn): class CPL(Insn): def exec(self, cpu: CPU) -> None: cpu.set_reg8(R8.A, cpu.get_reg8(R8.A) ^ 0xFF) + cpu.cycles += 4 def pretty(self) -> str: return "CPL" diff --git a/tests/insn/__init__.py b/tests/insn/__init__.py new file mode 100644 index 0000000..e69de29 diff --git a/tests/insn/helpers.py b/tests/insn/helpers.py new file mode 100644 index 0000000..a83c56f --- /dev/null +++ b/tests/insn/helpers.py @@ -0,0 +1,12 @@ +from gbso.insn import * +from gbso.regs import * + + +def n8(): + for i in range(0xFF + 1): + yield i + + +def n16(): + for i in range(0xFFFF + 1): + yield i diff --git a/tests/insn/test_alu8.py b/tests/insn/test_alu8.py new file mode 100644 index 0000000..eadb2d7 --- /dev/null +++ b/tests/insn/test_alu8.py @@ -0,0 +1,288 @@ +import pytest + +from tests.insn.helpers import * + + +@pytest.mark.parametrize("r", set(R8) - {R8.A}) +def test_add_a_r(r): + cpu = CPU() + cpu.set_reg8(r, 0x7F) + + ADD_A_R(r).exec(cpu) + + assert cpu.get_reg8(R8.A) == 0x7F + assert cpu.carry == 0 + assert cpu.cycles == 4 + + cpu.set_reg8(r, 0x81) + ADD_A_R(r).exec(cpu) + + assert cpu.get_reg8(R8.A) == 0x00 + assert cpu.carry == 1 + assert cpu.cycles == 8 + + +@pytest.mark.parametrize("n", n8()) +def test_add_a_n(n): + cpu = CPU() + cpu.set_reg8(R8.A, 0x7F) + + ADD_A_N(n).exec(cpu) + + assert cpu.get_reg8(R8.A) == (0x7F + n) & 0xFF + assert cpu.carry == (1 if n >= 0x81 else 0) + assert cpu.cycles == 8 + + +def test_add_a_hl(): + cpu = CPU() + cpu.set_reg16(R16.HL, 0x1234) + cpu.set_mem8(0x1234, 0x7F) + + ADD_A_HL().exec(cpu) + + assert cpu.get_reg8(R8.A) == 0x7F + assert cpu.carry == 0 + assert cpu.cycles == 8 + + cpu.set_mem8(0x1234, 0x81) + ADD_A_HL().exec(cpu) + + assert cpu.get_reg8(R8.A) == 0 + assert cpu.carry == 1 + assert cpu.cycles == 16 + + +# TODO: ADC_A_R, ADC_A_N, ADC_A_HL, SUB_A_R, SUB_A_N, SUB_A_HL, SBC_A_R, +# SBC_A_N, SBC_A_HL + + +@pytest.mark.parametrize("r", set(R8) - {R8.A}) +def test_and_a_r(r): + cpu = CPU() + cpu.set_reg8(R8.A, 0x12) + cpu.set_reg8(r, 0x7F) + + AND_A_R(r).exec(cpu) + + assert cpu.get_reg8(R8.A) == 0x12 + assert cpu.carry == 0 + assert cpu.cycles == 4 + + +@pytest.mark.parametrize("n", n8()) +def test_and_a_n(n): + cpu = CPU() + cpu.set_reg8(R8.A, 0x12) + + AND_A_N(n).exec(cpu) + + assert cpu.get_reg8(R8.A) == 0x12 & n + assert cpu.carry == 0 + assert cpu.cycles == 8 + + +def test_and_a_hl(): + cpu = CPU() + + cpu.set_reg8(R8.A, 0x12) + cpu.set_reg16(R16.HL, 0x1234) + cpu.set_mem8(0x1234, 0x7F) + + AND_A_HL().exec(cpu) + + assert cpu.get_reg8(R8.A) == 0x12 + assert cpu.carry == 0 + assert cpu.cycles == 8 + + +@pytest.mark.parametrize("r", set(R8) - {R8.A}) +def test_xor_a_r(r): + cpu = CPU() + cpu.set_reg8(R8.A, 0x12) + cpu.set_reg8(r, 0x7F) + + XOR_A_R(r).exec(cpu) + + assert cpu.get_reg8(R8.A) == 0x6D + assert cpu.carry == 0 + assert cpu.cycles == 4 + + +@pytest.mark.parametrize("n", n8()) +def test_xor_a_n(n): + cpu = CPU() + cpu.set_reg8(R8.A, 0x12) + + XOR_A_N(n).exec(cpu) + + assert cpu.get_reg8(R8.A) == 0x12 ^ n + assert cpu.carry == 0 + assert cpu.cycles == 8 + + +def test_xor_a_hl(): + cpu = CPU() + + cpu.set_reg8(R8.A, 0x12) + cpu.set_reg16(R16.HL, 0x1234) + cpu.set_mem8(0x1234, 0x7F) + + XOR_A_HL().exec(cpu) + + assert cpu.get_reg8(R8.A) == 0x6D + assert cpu.carry == 0 + assert cpu.cycles == 8 + + +@pytest.mark.parametrize("r", set(R8) - {R8.A}) +def test_or_a_r(r): + cpu = CPU() + cpu.set_reg8(R8.A, 0x12) + cpu.set_reg8(r, 0x7F) + + OR_A_R(r).exec(cpu) + + assert cpu.get_reg8(R8.A) == 0x7F + assert cpu.carry == 0 + assert cpu.cycles == 4 + + +@pytest.mark.parametrize("n", n8()) +def test_or_a_n(n): + cpu = CPU() + cpu.set_reg8(R8.A, 0x12) + + OR_A_N(n).exec(cpu) + + assert cpu.get_reg8(R8.A) == 0x12 | n + assert cpu.carry == 0 + assert cpu.cycles == 8 + + +def test_or_a_hl(): + cpu = CPU() + + cpu.set_reg8(R8.A, 0x12) + cpu.set_reg16(R16.HL, 0x1234) + cpu.set_mem8(0x1234, 0x7F) + + OR_A_HL().exec(cpu) + + assert cpu.get_reg8(R8.A) == 0x7F + assert cpu.carry == 0 + assert cpu.cycles == 8 + + +@pytest.mark.parametrize("r", set(R8) - {R8.A}) +def test_cp_a_r(r): + cpu = CPU() + cpu.set_reg8(R8.A, 0x7F) + cpu.set_reg8(r, 0x12) + + CP_A_R(r).exec(cpu) + + assert cpu.get_reg8(R8.A) == 0x7F + assert cpu.carry == 0 + assert cpu.cycles == 4 + + cpu.set_reg8(r, 0x80) + CP_A_R(r).exec(cpu) + + assert cpu.get_reg8(R8.A) == 0x7F + assert cpu.carry == 1 + assert cpu.cycles == 8 + + +@pytest.mark.parametrize("n", n8()) +def test_cp_a_n(n): + cpu = CPU() + cpu.set_reg8(R8.A, 0x12) + + CP_A_N(n).exec(cpu) + + assert cpu.get_reg8(R8.A) == 0x12 + assert cpu.carry == (1 if 0x12 < n else 0) + assert cpu.cycles == 8 + + +def test_cp_a_hl(): + cpu = CPU() + + cpu.set_reg8(R8.A, 0x7F) + cpu.set_reg16(R16.HL, 0x1234) + cpu.set_mem8(0x1234, 0x12) + + CP_A_HL().exec(cpu) + + assert cpu.get_reg8(R8.A) == 0x7F + assert cpu.carry == 0 + assert cpu.cycles == 8 + + cpu.set_mem8(0x1234, 0x80) + + CP_A_HL().exec(cpu) + + assert cpu.get_reg8(R8.A) == 0x7F + assert cpu.carry == 1 + assert cpu.cycles == 16 + + +@pytest.mark.parametrize("r,n", [(r, n) for r in R8 for n in n8()]) +def test_inc_r(r, n): + cpu = CPU() + cpu.set_reg8(r, n) + + INC_R(r).exec(cpu) + + assert cpu.get_reg8(r) == (n + 1) & 0xFF + assert cpu.cycles == 4 + + +@pytest.mark.parametrize("n", n8()) +def test_inc_hl(n): + cpu = CPU() + cpu.set_reg16(R16.HL, 0x1234) + cpu.set_mem8(0x1234, n) + + INC_HL(n).exec(cpu) + + assert cpu.deref_hl() == (n + 1) & 0xFF + assert cpu.cycles == 12 + + +@pytest.mark.parametrize("r,n", [(r, n) for r in R8 for n in n8()]) +def test_dec_r(r, n): + cpu = CPU() + cpu.set_reg8(r, n) + + DEC_R(r).exec(cpu) + + assert cpu.get_reg8(r) == (n - 1) & 0xFF + assert cpu.cycles == 4 + + +@pytest.mark.parametrize("n", n8()) +def test_dec_hl(n): + cpu = CPU() + cpu.set_reg16(R16.HL, 0x1234) + cpu.set_mem8(0x1234, n) + + DEC_HL(n).exec(cpu) + + assert cpu.deref_hl() == (n - 1) & 0xFF + assert cpu.cycles == 12 + + +# TODO: Test DAA after implementing it + + +@pytest.mark.parametrize("n", n8()) +def test_cpl(n): + cpu = CPU() + cpu.set_reg8(R8.A, n) + + CPL().exec(cpu) + + assert cpu.get_reg8(R8.A) == n ^ 0xFF + assert cpu.cycles == 4 diff --git a/tests/insn/test_loads16.py b/tests/insn/test_loads16.py new file mode 100644 index 0000000..0682571 --- /dev/null +++ b/tests/insn/test_loads16.py @@ -0,0 +1,59 @@ +import pytest + +from tests.insn.helpers import * + + +@pytest.mark.parametrize("rr", set(R16) - {R16.AF}) +def test_ld_rr_nn(rr): + cpu = CPU() + + LD_RR_NN(rr, 0x1234).exec(cpu) + + assert cpu.get_reg16(rr) == 0x1234 + assert cpu.cycles == 12 + + +def test_ld_nn_sp(): + cpu = CPU() + cpu.set_reg16(R16.SP, 0xABCD) + + LD_NN_SP(0x1234).exec(cpu) + + assert cpu.get_mem16(0x1234) == 0xABCD + assert cpu.cycles == 20 + + +def test_ld_sp_hl(): + cpu = CPU() + cpu.set_reg16(R16.HL, 0x1234) + + LD_SP_HL().exec(cpu) + + assert cpu.get_reg16(R16.SP) == 0x1234 + assert cpu.cycles == 8 + + +@pytest.mark.parametrize("rr", set(R16) - {R16.AF, R16.SP}) +def test_push_rr(rr): + cpu = CPU() + cpu.set_reg16(R16.SP, 0xFFFF) + cpu.set_reg16(rr, 0x1234) + + PUSH_RR(rr).exec(cpu) + + assert cpu.get_reg16(R16.SP) == 0xFFFD + assert cpu.get_mem16(0xFFFD) == 0x1234 + assert cpu.cycles == 16 + + +@pytest.mark.parametrize("rr", set(R16) - {R16.AF, R16.SP}) +def test_pop_rr(rr): + cpu = CPU() + cpu.set_reg16(R16.SP, 0xFFFD) + cpu.set_mem16(0xFFFD, 0x1234) + + POP_RR(rr).exec(cpu) + + assert cpu.get_reg16(R16.SP) == 0xFFFF + assert cpu.get_reg16(rr) == 0x1234 + assert cpu.cycles == 12 diff --git a/tests/test_insn.py b/tests/insn/test_loads8.py similarity index 95% rename from tests/test_insn.py rename to tests/insn/test_loads8.py index 244016e..24136bc 100644 --- a/tests/test_insn.py +++ b/tests/insn/test_loads8.py @@ -1,17 +1,6 @@ import pytest -from gbso.insn import * -from gbso.regs import * - - -def n8(): - for i in range(0xFF + 1): - yield i - - -def n16(): - for i in range(0xFFFF + 1): - yield i +from tests.insn.helpers import * @pytest.mark.parametrize("dst,src", [(x, y) for x in R8 for y in R8]) @@ -229,4 +218,4 @@ def test_ldd_a_hl(): assert cpu.get_reg16(R16.HL) == 0x1233 assert cpu.get_reg8(R8.A) == 0x7F - assert cpu.cycles == 8 + assert cpu.cycles == 8 \ No newline at end of file