Browse Source

Move CPU cycle tracking into static method

master
Forest Belton 3 years ago
parent
commit
88db4070a8
11 changed files with 371 additions and 213 deletions
  1. +345
    -84
      gbso/cpu/insn.py
  2. +0
    -1
      gbso/cpu/state.py
  3. +4
    -6
      gbso/program/program.py
  4. +22
    -11
      gbso/program/test_case.py
  5. +0
    -10
      tests/insn/test_alu16.py
  6. +0
    -31
      tests/insn/test_alu8.py
  7. +0
    -4
      tests/insn/test_bit.py
  8. +0
    -3
      tests/insn/test_cpu.py
  9. +0
    -5
      tests/insn/test_loads16.py
  10. +0
    -20
      tests/insn/test_loads8.py
  11. +0
    -38
      tests/insn/test_shift.py

+ 345
- 84
gbso/cpu/insn.py
File diff suppressed because it is too large
View File


+ 0
- 1
gbso/cpu/state.py View File

@ -8,7 +8,6 @@ from gbso.cpu.regs import R8
@dataclass @dataclass
class CPUState: class CPUState:
carry: int = 0 carry: int = 0
cycles: int = 0
sp: int = 0 sp: int = 0
reg8: Dict[R8, int] = field(default_factory=lambda: defaultdict(lambda: 0)) reg8: Dict[R8, int] = field(default_factory=lambda: defaultdict(lambda: 0))
memory: Dict[int, int] = field(default_factory=lambda: defaultdict(lambda: 0)) memory: Dict[int, int] = field(default_factory=lambda: defaultdict(lambda: 0))

+ 4
- 6
gbso/program/program.py View File

@ -1,23 +1,21 @@
from dataclasses import dataclass from dataclasses import dataclass
from typing import List, Optional, Union
from typing import List, Optional
from gbso.cpu.cpu import CPU from gbso.cpu.cpu import CPU
from gbso.cpu.regs import R8
from gbso.cpu.state import CPUState from gbso.cpu.state import CPUState
from gbso.cpu.insn import Insn from gbso.cpu.insn import Insn
# TODO: Support 16-bit memory/register outputs
Output = Union[R8, int]
@dataclass @dataclass
class Program: class Program:
insns: List[Insn] insns: List[Insn]
outputs: List[Output]
def execute(self, init_state: Optional[CPUState] = None) -> CPU: def execute(self, init_state: Optional[CPUState] = None) -> CPU:
cpu = CPU(state=init_state) cpu = CPU(state=init_state)
for insn in self.insns: for insn in self.insns:
insn.exec(cpu) insn.exec(cpu)
return cpu return cpu
def perf(self) -> int:
return sum([insn.cycles() for insn in self.insns])

+ 22
- 11
gbso/program/test_case.py View File

@ -1,28 +1,39 @@
from dataclasses import dataclass from dataclasses import dataclass
from typing import List, Union
from gbso.cpu.cpu import CPU
from gbso.cpu.regs import R8 from gbso.cpu.regs import R8
from gbso.program.program import Program from gbso.program.program import Program
from gbso.cpu.state import CPUState from gbso.cpu.state import CPUState
# TODO: Support 16-bit memory/register outputs
Output = Union[R8, int]
@dataclass @dataclass
class TestCase: class TestCase:
__test__ = False __test__ = False
state: CPUState state: CPUState
def eq_on_testcase(p: Program, q: Program, case: TestCase) -> int:
# TODO: Allow p_cpu to be computed AOT
# TODO: Add penalty for undefined behavior (uninitialized register/memory reads)
def eq_on_testcase(
p: Program, q: Program, case: TestCase, outputs: List[Output]
) -> int:
p_cpu = p.execute(case.state) p_cpu = p.execute(case.state)
q_cpu = q.execute(case.state) q_cpu = q.execute(case.state)
delta = 0
for o in p.outputs:
if type(o) == R8:
delta += eq_8bit(p_cpu.state.reg8[o], q_cpu.state.reg8[o])
elif type(o) == int:
delta += eq_8bit(p_cpu.state.memory[o], q_cpu.state.memory[o])
else:
raise TypeError(f"unknown output type {type(o)}")
# TODO: Add penalty for undefined behavior (uninitialized register/memory reads)
return sum([eq_on_output(o, p_cpu, q_cpu) for o in outputs])
def eq_on_output(o: Output, p_cpu: CPU, q_cpu: CPU) -> int:
if type(o) == R8:
delta = eq_8bit(p_cpu.state.reg8[o], q_cpu.state.reg8[o])
elif type(o) == int:
delta = eq_8bit(p_cpu.state.memory[o], q_cpu.state.memory[o])
else:
raise TypeError(f"unknown output type {type(o)}")
return delta return delta

+ 0
- 10
tests/insn/test_alu16.py View File

@ -13,14 +13,12 @@ def test_add_hl_rr(rr):
assert cpu.get_reg16(R16.HL) == 0xBE01 assert cpu.get_reg16(R16.HL) == 0xBE01
assert cpu.state.carry == 0 assert cpu.state.carry == 0
assert cpu.state.cycles == 8
cpu.set_reg16(rr, 0xFFFF - 0xBE01 + 1) cpu.set_reg16(rr, 0xFFFF - 0xBE01 + 1)
ADD_HL_RR(rr).exec(cpu) ADD_HL_RR(rr).exec(cpu)
assert cpu.get_reg16(R16.HL) == 0 assert cpu.get_reg16(R16.HL) == 0
assert cpu.state.carry == 1 assert cpu.state.carry == 1
assert cpu.state.cycles == 16
@pytest.mark.parametrize("rr", set(R16) - {R16.AF}) @pytest.mark.parametrize("rr", set(R16) - {R16.AF})
@ -31,7 +29,6 @@ def test_inc_rr(rr):
INC_RR(rr).exec(cpu) INC_RR(rr).exec(cpu)
assert cpu.get_reg16(rr) == 0xABCE assert cpu.get_reg16(rr) == 0xABCE
assert cpu.state.cycles == 8
@pytest.mark.parametrize("rr", set(R16) - {R16.AF}) @pytest.mark.parametrize("rr", set(R16) - {R16.AF})
@ -42,7 +39,6 @@ def test_dec_rr(rr):
DEC_RR(rr).exec(cpu) DEC_RR(rr).exec(cpu)
assert cpu.get_reg16(rr) == 0xABCC assert cpu.get_reg16(rr) == 0xABCC
assert cpu.state.cycles == 8
def test_add_sp_dd(): def test_add_sp_dd():
@ -53,19 +49,16 @@ def test_add_sp_dd():
assert cpu.get_reg16(R16.SP) == 0xFFFE assert cpu.get_reg16(R16.SP) == 0xFFFE
assert cpu.state.carry == 0 assert cpu.state.carry == 0
assert cpu.state.cycles == 16
ADD_SP_DD(2).exec(cpu) ADD_SP_DD(2).exec(cpu)
assert cpu.get_reg16(R16.SP) == 0 assert cpu.get_reg16(R16.SP) == 0
assert cpu.state.carry == 1 assert cpu.state.carry == 1
assert cpu.state.cycles == 32
ADD_SP_DD(-1).exec(cpu) ADD_SP_DD(-1).exec(cpu)
assert cpu.get_reg16(R16.SP) == 0xFFFF assert cpu.get_reg16(R16.SP) == 0xFFFF
assert cpu.state.carry == 1 assert cpu.state.carry == 1
assert cpu.state.cycles == 48
def test_ld_hl_sp_dd(): def test_ld_hl_sp_dd():
@ -76,18 +69,15 @@ def test_ld_hl_sp_dd():
assert cpu.get_reg16(R16.HL) == 0 assert cpu.get_reg16(R16.HL) == 0
assert cpu.state.carry == 1 assert cpu.state.carry == 1
assert cpu.state.cycles == 12
cpu.set_reg16(R16.SP, 0) cpu.set_reg16(R16.SP, 0)
LD_HL_SP_DD(-1).exec(cpu) LD_HL_SP_DD(-1).exec(cpu)
assert cpu.get_reg16(R16.HL) == 0xFFFF assert cpu.get_reg16(R16.HL) == 0xFFFF
assert cpu.state.carry == 1 assert cpu.state.carry == 1
assert cpu.state.cycles == 24
cpu.set_reg16(R16.SP, 0xFFFF) cpu.set_reg16(R16.SP, 0xFFFF)
LD_HL_SP_DD(-2).exec(cpu) LD_HL_SP_DD(-2).exec(cpu)
assert cpu.get_reg16(R16.HL) == 0xFFFD assert cpu.get_reg16(R16.HL) == 0xFFFD
assert cpu.state.carry == 0 assert cpu.state.carry == 0
assert cpu.state.cycles == 36

+ 0
- 31
tests/insn/test_alu8.py View File

@ -12,14 +12,12 @@ def test_add_a_r(r):
assert cpu.get_reg8(R8.A) == 0x7F assert cpu.get_reg8(R8.A) == 0x7F
assert cpu.state.carry == 0 assert cpu.state.carry == 0
assert cpu.state.cycles == 4
cpu.set_reg8(r, 0x81) cpu.set_reg8(r, 0x81)
ADD_A_R(r).exec(cpu) ADD_A_R(r).exec(cpu)
assert cpu.get_reg8(R8.A) == 0x00 assert cpu.get_reg8(R8.A) == 0x00
assert cpu.state.carry == 1 assert cpu.state.carry == 1
assert cpu.state.cycles == 8
@pytest.mark.parametrize("n", n8()) @pytest.mark.parametrize("n", n8())
@ -31,7 +29,6 @@ def test_add_a_n(n):
assert cpu.get_reg8(R8.A) == (0x7F + n) & 0xFF assert cpu.get_reg8(R8.A) == (0x7F + n) & 0xFF
assert cpu.state.carry == (1 if n >= 0x81 else 0) assert cpu.state.carry == (1 if n >= 0x81 else 0)
assert cpu.state.cycles == 8
def test_add_a_hl(): def test_add_a_hl():
@ -43,14 +40,12 @@ def test_add_a_hl():
assert cpu.get_reg8(R8.A) == 0x7F assert cpu.get_reg8(R8.A) == 0x7F
assert cpu.state.carry == 0 assert cpu.state.carry == 0
assert cpu.state.cycles == 8
cpu.set_mem8(0x1234, 0x81) cpu.set_mem8(0x1234, 0x81)
ADD_A_HL().exec(cpu) ADD_A_HL().exec(cpu)
assert cpu.get_reg8(R8.A) == 0 assert cpu.get_reg8(R8.A) == 0
assert cpu.state.carry == 1 assert cpu.state.carry == 1
assert cpu.state.cycles == 16
@pytest.mark.parametrize("r", set(R8) - {R8.A}) @pytest.mark.parametrize("r", set(R8) - {R8.A})
@ -62,21 +57,18 @@ def test_adc_a_r(r):
assert cpu.get_reg8(R8.A) == 0x7F assert cpu.get_reg8(R8.A) == 0x7F
assert cpu.state.carry == 0 assert cpu.state.carry == 0
assert cpu.state.cycles == 4
cpu.set_reg8(r, 0x81) cpu.set_reg8(r, 0x81)
ADC_A_R(r).exec(cpu) ADC_A_R(r).exec(cpu)
assert cpu.get_reg8(R8.A) == 0x00 assert cpu.get_reg8(R8.A) == 0x00
assert cpu.state.carry == 1 assert cpu.state.carry == 1
assert cpu.state.cycles == 8
cpu.set_reg8(r, 0x00) cpu.set_reg8(r, 0x00)
ADC_A_R(r).exec(cpu) ADC_A_R(r).exec(cpu)
assert cpu.get_reg8(R8.A) == 0x01 assert cpu.get_reg8(R8.A) == 0x01
assert cpu.state.carry == 0 assert cpu.state.carry == 0
assert cpu.state.cycles == 12
@pytest.mark.parametrize("n", n8()) @pytest.mark.parametrize("n", n8())
@ -88,7 +80,6 @@ def test_adc_a_n(n):
assert cpu.get_reg8(R8.A) == (0x7F + n) & 0xFF assert cpu.get_reg8(R8.A) == (0x7F + n) & 0xFF
assert cpu.state.carry == (1 if n >= 0x81 else 0) assert cpu.state.carry == (1 if n >= 0x81 else 0)
assert cpu.state.cycles == 8
def test_adc_a_hl(): def test_adc_a_hl():
@ -100,21 +91,18 @@ def test_adc_a_hl():
assert cpu.get_reg8(R8.A) == 0x7F assert cpu.get_reg8(R8.A) == 0x7F
assert cpu.state.carry == 0 assert cpu.state.carry == 0
assert cpu.state.cycles == 8
cpu.hl = 0x81 cpu.hl = 0x81
ADC_A_HL().exec(cpu) ADC_A_HL().exec(cpu)
assert cpu.get_reg8(R8.A) == 0 assert cpu.get_reg8(R8.A) == 0
assert cpu.state.carry == 1 assert cpu.state.carry == 1
assert cpu.state.cycles == 16
cpu.hl = 0x00 cpu.hl = 0x00
ADC_A_HL().exec(cpu) ADC_A_HL().exec(cpu)
assert cpu.get_reg8(R8.A) == 1 assert cpu.get_reg8(R8.A) == 1
assert cpu.state.carry == 0 assert cpu.state.carry == 0
assert cpu.state.cycles == 24
# TODO: SUB_A_R, SUB_A_N, SUB_A_HL, SBC_A_R, SBC_A_N, SBC_A_HL # TODO: SUB_A_R, SUB_A_N, SUB_A_HL, SBC_A_R, SBC_A_N, SBC_A_HL
@ -130,7 +118,6 @@ def test_and_a_r(r):
assert cpu.get_reg8(R8.A) == 0x12 assert cpu.get_reg8(R8.A) == 0x12
assert cpu.state.carry == 0 assert cpu.state.carry == 0
assert cpu.state.cycles == 4
@pytest.mark.parametrize("n", n8()) @pytest.mark.parametrize("n", n8())
@ -142,7 +129,6 @@ def test_and_a_n(n):
assert cpu.get_reg8(R8.A) == 0x12 & n assert cpu.get_reg8(R8.A) == 0x12 & n
assert cpu.state.carry == 0 assert cpu.state.carry == 0
assert cpu.state.cycles == 8
def test_and_a_hl(): def test_and_a_hl():
@ -156,7 +142,6 @@ def test_and_a_hl():
assert cpu.get_reg8(R8.A) == 0x12 assert cpu.get_reg8(R8.A) == 0x12
assert cpu.state.carry == 0 assert cpu.state.carry == 0
assert cpu.state.cycles == 8
@pytest.mark.parametrize("r", set(R8) - {R8.A}) @pytest.mark.parametrize("r", set(R8) - {R8.A})
@ -169,7 +154,6 @@ def test_xor_a_r(r):
assert cpu.get_reg8(R8.A) == 0x6D assert cpu.get_reg8(R8.A) == 0x6D
assert cpu.state.carry == 0 assert cpu.state.carry == 0
assert cpu.state.cycles == 4
@pytest.mark.parametrize("n", n8()) @pytest.mark.parametrize("n", n8())
@ -181,7 +165,6 @@ def test_xor_a_n(n):
assert cpu.get_reg8(R8.A) == 0x12 ^ n assert cpu.get_reg8(R8.A) == 0x12 ^ n
assert cpu.state.carry == 0 assert cpu.state.carry == 0
assert cpu.state.cycles == 8
def test_xor_a_hl(): def test_xor_a_hl():
@ -195,7 +178,6 @@ def test_xor_a_hl():
assert cpu.get_reg8(R8.A) == 0x6D assert cpu.get_reg8(R8.A) == 0x6D
assert cpu.state.carry == 0 assert cpu.state.carry == 0
assert cpu.state.cycles == 8
@pytest.mark.parametrize("r", set(R8) - {R8.A}) @pytest.mark.parametrize("r", set(R8) - {R8.A})
@ -208,7 +190,6 @@ def test_or_a_r(r):
assert cpu.get_reg8(R8.A) == 0x7F assert cpu.get_reg8(R8.A) == 0x7F
assert cpu.state.carry == 0 assert cpu.state.carry == 0
assert cpu.state.cycles == 4
@pytest.mark.parametrize("n", n8()) @pytest.mark.parametrize("n", n8())
@ -220,7 +201,6 @@ def test_or_a_n(n):
assert cpu.get_reg8(R8.A) == 0x12 | n assert cpu.get_reg8(R8.A) == 0x12 | n
assert cpu.state.carry == 0 assert cpu.state.carry == 0
assert cpu.state.cycles == 8
def test_or_a_hl(): def test_or_a_hl():
@ -234,7 +214,6 @@ def test_or_a_hl():
assert cpu.get_reg8(R8.A) == 0x7F assert cpu.get_reg8(R8.A) == 0x7F
assert cpu.state.carry == 0 assert cpu.state.carry == 0
assert cpu.state.cycles == 8
@pytest.mark.parametrize("r", set(R8) - {R8.A}) @pytest.mark.parametrize("r", set(R8) - {R8.A})
@ -247,14 +226,12 @@ def test_cp_a_r(r):
assert cpu.get_reg8(R8.A) == 0x7F assert cpu.get_reg8(R8.A) == 0x7F
assert cpu.state.carry == 0 assert cpu.state.carry == 0
assert cpu.state.cycles == 4
cpu.set_reg8(r, 0x80) cpu.set_reg8(r, 0x80)
CP_A_R(r).exec(cpu) CP_A_R(r).exec(cpu)
assert cpu.get_reg8(R8.A) == 0x7F assert cpu.get_reg8(R8.A) == 0x7F
assert cpu.state.carry == 1 assert cpu.state.carry == 1
assert cpu.state.cycles == 8
@pytest.mark.parametrize("n", n8()) @pytest.mark.parametrize("n", n8())
@ -266,7 +243,6 @@ def test_cp_a_n(n):
assert cpu.get_reg8(R8.A) == 0x12 assert cpu.get_reg8(R8.A) == 0x12
assert cpu.state.carry == (1 if 0x12 < n else 0) assert cpu.state.carry == (1 if 0x12 < n else 0)
assert cpu.state.cycles == 8
def test_cp_a_hl(): def test_cp_a_hl():
@ -280,7 +256,6 @@ def test_cp_a_hl():
assert cpu.get_reg8(R8.A) == 0x7F assert cpu.get_reg8(R8.A) == 0x7F
assert cpu.state.carry == 0 assert cpu.state.carry == 0
assert cpu.state.cycles == 8
cpu.set_mem8(0x1234, 0x80) cpu.set_mem8(0x1234, 0x80)
@ -288,7 +263,6 @@ def test_cp_a_hl():
assert cpu.get_reg8(R8.A) == 0x7F assert cpu.get_reg8(R8.A) == 0x7F
assert cpu.state.carry == 1 assert cpu.state.carry == 1
assert cpu.state.cycles == 16
@pytest.mark.parametrize("r,n", [(r, n) for r in R8 for n in n8()]) @pytest.mark.parametrize("r,n", [(r, n) for r in R8 for n in n8()])
@ -299,7 +273,6 @@ def test_inc_r(r, n):
INC_R(r).exec(cpu) INC_R(r).exec(cpu)
assert cpu.get_reg8(r) == (n + 1) & 0xFF assert cpu.get_reg8(r) == (n + 1) & 0xFF
assert cpu.state.cycles == 4
@pytest.mark.parametrize("n", n8()) @pytest.mark.parametrize("n", n8())
@ -311,7 +284,6 @@ def test_inc_hl(n):
INC_HL(n).exec(cpu) INC_HL(n).exec(cpu)
assert cpu.hl == (n + 1) & 0xFF assert cpu.hl == (n + 1) & 0xFF
assert cpu.state.cycles == 12
@pytest.mark.parametrize("r,n", [(r, n) for r in R8 for n in n8()]) @pytest.mark.parametrize("r,n", [(r, n) for r in R8 for n in n8()])
@ -322,7 +294,6 @@ def test_dec_r(r, n):
DEC_R(r).exec(cpu) DEC_R(r).exec(cpu)
assert cpu.get_reg8(r) == (n - 1) & 0xFF assert cpu.get_reg8(r) == (n - 1) & 0xFF
assert cpu.state.cycles == 4
@pytest.mark.parametrize("n", n8()) @pytest.mark.parametrize("n", n8())
@ -334,7 +305,6 @@ def test_dec_hl(n):
DEC_HL(n).exec(cpu) DEC_HL(n).exec(cpu)
assert cpu.hl == (n - 1) & 0xFF assert cpu.hl == (n - 1) & 0xFF
assert cpu.state.cycles == 12
# TODO: Test DAA after implementing it # TODO: Test DAA after implementing it
@ -348,4 +318,3 @@ def test_cpl(n):
CPL().exec(cpu) CPL().exec(cpu)
assert cpu.get_reg8(R8.A) == n ^ 0xFF assert cpu.get_reg8(R8.A) == n ^ 0xFF
assert cpu.state.cycles == 4

+ 0
- 4
tests/insn/test_bit.py View File

@ -10,7 +10,6 @@ def test_set_n_r(n, r):
SET_N_R(n, r).exec(cpu) SET_N_R(n, r).exec(cpu)
assert cpu.get_reg8(r) == 1 << n assert cpu.get_reg8(r) == 1 << n
assert cpu.state.cycles == 8
@pytest.mark.parametrize("n", range(8)) @pytest.mark.parametrize("n", range(8))
@ -21,7 +20,6 @@ def test_set_n_hl(n):
SET_N_HL(n).exec(cpu) SET_N_HL(n).exec(cpu)
assert cpu.hl == 1 << n assert cpu.hl == 1 << n
assert cpu.state.cycles == 16
@pytest.mark.parametrize("n,r", [(n, r) for n in range(8) for r in R8]) @pytest.mark.parametrize("n,r", [(n, r) for n in range(8) for r in R8])
@ -32,7 +30,6 @@ def test_res_n_r(n, r):
RES_N_R(n, r).exec(cpu) RES_N_R(n, r).exec(cpu)
assert cpu.get_reg8(r) == 0xFF - (1 << n) assert cpu.get_reg8(r) == 0xFF - (1 << n)
assert cpu.state.cycles == 8
@pytest.mark.parametrize("n", range(8)) @pytest.mark.parametrize("n", range(8))
@ -44,4 +41,3 @@ def test_res_n_hl(n):
RES_N_HL(n).exec(cpu) RES_N_HL(n).exec(cpu)
assert cpu.hl == 0xFF - (1 << n) assert cpu.hl == 0xFF - (1 << n)
assert cpu.state.cycles == 16

+ 0
- 3
tests/insn/test_cpu.py View File

@ -7,12 +7,10 @@ def test_ccf():
CCF().exec(cpu) CCF().exec(cpu)
assert cpu.state.carry == 1 assert cpu.state.carry == 1
assert cpu.state.cycles == 4
CCF().exec(cpu) CCF().exec(cpu)
assert cpu.state.carry == 0 assert cpu.state.carry == 0
assert cpu.state.cycles == 8
def test_scf(): def test_scf():
@ -21,4 +19,3 @@ def test_scf():
SCF().exec(cpu) SCF().exec(cpu)
assert cpu.state.carry == 1 assert cpu.state.carry == 1
assert cpu.state.cycles == 4

+ 0
- 5
tests/insn/test_loads16.py View File

@ -10,7 +10,6 @@ def test_ld_rr_nn(rr):
LD_RR_NN(rr, 0x1234).exec(cpu) LD_RR_NN(rr, 0x1234).exec(cpu)
assert cpu.get_reg16(rr) == 0x1234 assert cpu.get_reg16(rr) == 0x1234
assert cpu.state.cycles == 12
def test_ld_nn_sp(): def test_ld_nn_sp():
@ -20,7 +19,6 @@ def test_ld_nn_sp():
LD_NN_SP(0x1234).exec(cpu) LD_NN_SP(0x1234).exec(cpu)
assert cpu.get_mem16(0x1234) == 0xABCD assert cpu.get_mem16(0x1234) == 0xABCD
assert cpu.state.cycles == 20
def test_ld_sp_hl(): def test_ld_sp_hl():
@ -30,7 +28,6 @@ def test_ld_sp_hl():
LD_SP_HL().exec(cpu) LD_SP_HL().exec(cpu)
assert cpu.get_reg16(R16.SP) == 0x1234 assert cpu.get_reg16(R16.SP) == 0x1234
assert cpu.state.cycles == 8
@pytest.mark.parametrize("rr", set(R16) - {R16.AF, R16.SP}) @pytest.mark.parametrize("rr", set(R16) - {R16.AF, R16.SP})
@ -43,7 +40,6 @@ def test_push_rr(rr):
assert cpu.get_reg16(R16.SP) == 0xFFFD assert cpu.get_reg16(R16.SP) == 0xFFFD
assert cpu.get_mem16(0xFFFD) == 0x1234 assert cpu.get_mem16(0xFFFD) == 0x1234
assert cpu.state.cycles == 16
@pytest.mark.parametrize("rr", set(R16) - {R16.AF, R16.SP}) @pytest.mark.parametrize("rr", set(R16) - {R16.AF, R16.SP})
@ -56,4 +52,3 @@ def test_pop_rr(rr):
assert cpu.get_reg16(R16.SP) == 0xFFFF assert cpu.get_reg16(R16.SP) == 0xFFFF
assert cpu.get_reg16(rr) == 0x1234 assert cpu.get_reg16(rr) == 0x1234
assert cpu.state.cycles == 12

+ 0
- 20
tests/insn/test_loads8.py View File

@ -10,7 +10,6 @@ def test_ld_r_r(dst, src):
LD_R_R(dst, src).exec(cpu) LD_R_R(dst, src).exec(cpu)
assert cpu.get_reg8(src) == 0x7F assert cpu.get_reg8(src) == 0x7F
assert cpu.state.cycles == 4
@pytest.mark.parametrize("r,imm", [(r, imm) for r in R8 for imm in n8()]) @pytest.mark.parametrize("r,imm", [(r, imm) for r in R8 for imm in n8()])
@ -19,7 +18,6 @@ def test_ld_r_n8(r, imm):
LD_R_N8(r, 0x7F).exec(cpu) LD_R_N8(r, 0x7F).exec(cpu)
assert cpu.get_reg8(r) == 0x7F assert cpu.get_reg8(r) == 0x7F
assert cpu.state.cycles == 8
@pytest.mark.parametrize("r", R8) @pytest.mark.parametrize("r", R8)
@ -30,7 +28,6 @@ def test_ld_r_hl(r):
LD_R_HL(r).exec(cpu) LD_R_HL(r).exec(cpu)
assert cpu.get_reg8(r) == 0x7F assert cpu.get_reg8(r) == 0x7F
assert cpu.state.cycles == 8
@pytest.mark.parametrize("r", R8) @pytest.mark.parametrize("r", R8)
@ -48,8 +45,6 @@ def test_ld_hl_r(r):
else: else:
assert cpu.hl == 0x7F assert cpu.hl == 0x7F
assert cpu.state.cycles == 8
@pytest.mark.parametrize("imm", n8()) @pytest.mark.parametrize("imm", n8())
def test_ld_hl_n8(imm): def test_ld_hl_n8(imm):
@ -59,7 +54,6 @@ def test_ld_hl_n8(imm):
LD_HL_N(imm).exec(cpu) LD_HL_N(imm).exec(cpu)
assert cpu.hl == imm assert cpu.hl == imm
assert cpu.state.cycles == 12
def test_ld_a_bc(): def test_ld_a_bc():
@ -70,7 +64,6 @@ def test_ld_a_bc():
LD_A_BC().exec(cpu) LD_A_BC().exec(cpu)
assert cpu.get_reg8(R8.A) == 0x7F assert cpu.get_reg8(R8.A) == 0x7F
assert cpu.state.cycles == 8
def test_ld_a_de(): def test_ld_a_de():
@ -81,7 +74,6 @@ def test_ld_a_de():
LD_A_DE().exec(cpu) LD_A_DE().exec(cpu)
assert cpu.get_reg8(R8.A) == 0x7F assert cpu.get_reg8(R8.A) == 0x7F
assert cpu.state.cycles == 8
# @pytest.mark.parametrize("nn", n16()) # @pytest.mark.parametrize("nn", n16())
@ -92,7 +84,6 @@ def test_ld_a_nn(nn=0x1234):
LD_A_NN(nn).exec(cpu) LD_A_NN(nn).exec(cpu)
assert cpu.get_reg8(R8.A) == 0x7F assert cpu.get_reg8(R8.A) == 0x7F
assert cpu.state.cycles == 16
def test_ld_bc_a(): def test_ld_bc_a():
@ -103,7 +94,6 @@ def test_ld_bc_a():
LD_BC_A().exec(cpu) LD_BC_A().exec(cpu)
assert cpu.get_mem8(0x1234) == 0x7F assert cpu.get_mem8(0x1234) == 0x7F
assert cpu.state.cycles == 8
def test_ld_de_a(): def test_ld_de_a():
@ -114,7 +104,6 @@ def test_ld_de_a():
LD_DE_A().exec(cpu) LD_DE_A().exec(cpu)
assert cpu.get_mem8(0x1234) == 0x7F assert cpu.get_mem8(0x1234) == 0x7F
assert cpu.state.cycles == 8
# @pytest.mark.parametrize("nn", n16()) # @pytest.mark.parametrize("nn", n16())
@ -125,7 +114,6 @@ def test_ld_nn_a(nn=0x1234):
LD_NN_A(nn).exec(cpu) LD_NN_A(nn).exec(cpu)
assert cpu.get_mem8(nn) == 0x7F assert cpu.get_mem8(nn) == 0x7F
assert cpu.state.cycles == 16
@pytest.mark.parametrize("n", n8()) @pytest.mark.parametrize("n", n8())
@ -136,7 +124,6 @@ def test_ld_a_ff_n(n):
LD_A_FF_N(n).exec(cpu) LD_A_FF_N(n).exec(cpu)
assert cpu.get_reg8(R8.A) == 0x7F assert cpu.get_reg8(R8.A) == 0x7F
assert cpu.state.cycles == 12
@pytest.mark.parametrize("n", n8()) @pytest.mark.parametrize("n", n8())
@ -147,7 +134,6 @@ def test_ld_ff_n_a(n):
LD_FF_N_A(n).exec(cpu) LD_FF_N_A(n).exec(cpu)
assert cpu.get_mem8(0xFF00 + n) == 0x7F assert cpu.get_mem8(0xFF00 + n) == 0x7F
assert cpu.state.cycles == 12
def test_ld_a_ff_c(): def test_ld_a_ff_c():
@ -158,7 +144,6 @@ def test_ld_a_ff_c():
LD_A_FF_C().exec(cpu) LD_A_FF_C().exec(cpu)
assert cpu.get_reg8(R8.A) == 0x7F assert cpu.get_reg8(R8.A) == 0x7F
assert cpu.state.cycles == 8
def test_ld_ff_c_a(): def test_ld_ff_c_a():
@ -169,7 +154,6 @@ def test_ld_ff_c_a():
LD_FF_C_A().exec(cpu) LD_FF_C_A().exec(cpu)
assert cpu.get_mem8(0xFF12) == 0x7F assert cpu.get_mem8(0xFF12) == 0x7F
assert cpu.state.cycles == 8
def test_ldi_hl_a(): def test_ldi_hl_a():
@ -181,7 +165,6 @@ def test_ldi_hl_a():
assert cpu.get_reg16(R16.HL) == 0x1235 assert cpu.get_reg16(R16.HL) == 0x1235
assert cpu.get_mem8(0x1234) == 0x7F assert cpu.get_mem8(0x1234) == 0x7F
assert cpu.state.cycles == 8
def test_ldi_a_hl(): def test_ldi_a_hl():
@ -193,7 +176,6 @@ def test_ldi_a_hl():
assert cpu.get_reg16(R16.HL) == 0x1235 assert cpu.get_reg16(R16.HL) == 0x1235
assert cpu.get_reg8(R8.A) == 0x7F assert cpu.get_reg8(R8.A) == 0x7F
assert cpu.state.cycles == 8
def test_ldd_hl_a(): def test_ldd_hl_a():
@ -205,7 +187,6 @@ def test_ldd_hl_a():
assert cpu.get_reg16(R16.HL) == 0x1233 assert cpu.get_reg16(R16.HL) == 0x1233
assert cpu.get_mem8(0x1234) == 0x7F assert cpu.get_mem8(0x1234) == 0x7F
assert cpu.state.cycles == 8
def test_ldd_a_hl(): def test_ldd_a_hl():
@ -217,4 +198,3 @@ def test_ldd_a_hl():
assert cpu.get_reg16(R16.HL) == 0x1233 assert cpu.get_reg16(R16.HL) == 0x1233
assert cpu.get_reg8(R8.A) == 0x7F assert cpu.get_reg8(R8.A) == 0x7F
assert cpu.state.cycles == 8

+ 0
- 38
tests/insn/test_shift.py View File

@ -11,13 +11,11 @@ def test_rlca():
assert cpu.get_reg8(R8.A) == 0x01 assert cpu.get_reg8(R8.A) == 0x01
assert cpu.state.carry == 1 assert cpu.state.carry == 1
assert cpu.state.cycles == 4
RLCA().exec(cpu) RLCA().exec(cpu)
assert cpu.get_reg8(R8.A) == 0x02 assert cpu.get_reg8(R8.A) == 0x02
assert cpu.state.carry == 0 assert cpu.state.carry == 0
assert cpu.state.cycles == 8
def test_rla(): def test_rla():
@ -28,13 +26,11 @@ def test_rla():
assert cpu.get_reg8(R8.A) == 0x00 assert cpu.get_reg8(R8.A) == 0x00
assert cpu.state.carry == 1 assert cpu.state.carry == 1
assert cpu.state.cycles == 4
RLA().exec(cpu) RLA().exec(cpu)
assert cpu.get_reg8(R8.A) == 0x01 assert cpu.get_reg8(R8.A) == 0x01
assert cpu.state.carry == 0 assert cpu.state.carry == 0
assert cpu.state.cycles == 8
def test_rrca(): def test_rrca():
@ -45,13 +41,11 @@ def test_rrca():
assert cpu.get_reg8(R8.A) == 0x80 assert cpu.get_reg8(R8.A) == 0x80
assert cpu.state.carry == 1 assert cpu.state.carry == 1
assert cpu.state.cycles == 4
RRCA().exec(cpu) RRCA().exec(cpu)
assert cpu.get_reg8(R8.A) == 0x40 assert cpu.get_reg8(R8.A) == 0x40
assert cpu.state.carry == 0 assert cpu.state.carry == 0
assert cpu.state.cycles == 8
def test_rra(): def test_rra():
@ -62,13 +56,11 @@ def test_rra():
assert cpu.get_reg8(R8.A) == 0x00 assert cpu.get_reg8(R8.A) == 0x00
assert cpu.state.carry == 1 assert cpu.state.carry == 1
assert cpu.state.cycles == 4
RRA().exec(cpu) RRA().exec(cpu)
assert cpu.get_reg8(R8.A) == 0x80 assert cpu.get_reg8(R8.A) == 0x80
assert cpu.state.carry == 0 assert cpu.state.carry == 0
assert cpu.state.cycles == 8
@pytest.mark.parametrize("r", R8) @pytest.mark.parametrize("r", R8)
@ -80,13 +72,11 @@ def test_rlc_r(r):
assert cpu.get_reg8(r) == 0x01 assert cpu.get_reg8(r) == 0x01
assert cpu.state.carry == 1 assert cpu.state.carry == 1
assert cpu.state.cycles == 8
RLC_R(r).exec(cpu) RLC_R(r).exec(cpu)
assert cpu.get_reg8(r) == 0x02 assert cpu.get_reg8(r) == 0x02
assert cpu.state.carry == 0 assert cpu.state.carry == 0
assert cpu.state.cycles == 16
def test_rlc_hl(): def test_rlc_hl():
@ -97,13 +87,11 @@ def test_rlc_hl():
assert cpu.hl == 0x01 assert cpu.hl == 0x01
assert cpu.state.carry == 1 assert cpu.state.carry == 1
assert cpu.state.cycles == 16
RLC_HL().exec(cpu) RLC_HL().exec(cpu)
assert cpu.hl == 0x02 assert cpu.hl == 0x02
assert cpu.state.carry == 0 assert cpu.state.carry == 0
assert cpu.state.cycles == 32
@pytest.mark.parametrize("r", R8) @pytest.mark.parametrize("r", R8)
@ -115,13 +103,11 @@ def test_rl_r(r):
assert cpu.get_reg8(r) == 0x00 assert cpu.get_reg8(r) == 0x00
assert cpu.state.carry == 1 assert cpu.state.carry == 1
assert cpu.state.cycles == 8
RL_R(r).exec(cpu) RL_R(r).exec(cpu)
assert cpu.get_reg8(r) == 0x01 assert cpu.get_reg8(r) == 0x01
assert cpu.state.carry == 0 assert cpu.state.carry == 0
assert cpu.state.cycles == 16
def test_rl_hl(): def test_rl_hl():
@ -132,13 +118,11 @@ def test_rl_hl():
assert cpu.hl == 0x00 assert cpu.hl == 0x00
assert cpu.state.carry == 1 assert cpu.state.carry == 1
assert cpu.state.cycles == 16
RL_HL().exec(cpu) RL_HL().exec(cpu)
assert cpu.hl == 0x01 assert cpu.hl == 0x01
assert cpu.state.carry == 0 assert cpu.state.carry == 0
assert cpu.state.cycles == 32
@pytest.mark.parametrize("r", R8) @pytest.mark.parametrize("r", R8)
@ -150,13 +134,11 @@ def test_rrc_r(r):
assert cpu.get_reg8(r) == 0x80 assert cpu.get_reg8(r) == 0x80
assert cpu.state.carry == 1 assert cpu.state.carry == 1
assert cpu.state.cycles == 8
RRC_R(r).exec(cpu) RRC_R(r).exec(cpu)
assert cpu.get_reg8(r) == 0x40 assert cpu.get_reg8(r) == 0x40
assert cpu.state.carry == 0 assert cpu.state.carry == 0
assert cpu.state.cycles == 16
def test_rrc_hl(): def test_rrc_hl():
@ -168,13 +150,11 @@ def test_rrc_hl():
assert cpu.hl == 0x80 assert cpu.hl == 0x80
assert cpu.state.carry == 1 assert cpu.state.carry == 1
assert cpu.state.cycles == 16
RRC_HL().exec(cpu) RRC_HL().exec(cpu)
assert cpu.hl == 0x40 assert cpu.hl == 0x40
assert cpu.state.carry == 0 assert cpu.state.carry == 0
assert cpu.state.cycles == 32
@pytest.mark.parametrize("r", R8) @pytest.mark.parametrize("r", R8)
@ -186,13 +166,11 @@ def test_rr_r(r):
assert cpu.get_reg8(r) == 0x00 assert cpu.get_reg8(r) == 0x00
assert cpu.state.carry == 1 assert cpu.state.carry == 1
assert cpu.state.cycles == 8
RR_R(r).exec(cpu) RR_R(r).exec(cpu)
assert cpu.get_reg8(r) == 0x80 assert cpu.get_reg8(r) == 0x80
assert cpu.state.carry == 0 assert cpu.state.carry == 0
assert cpu.state.cycles == 16
def test_rr_hl(): def test_rr_hl():
@ -204,13 +182,11 @@ def test_rr_hl():
assert cpu.hl == 0x00 assert cpu.hl == 0x00
assert cpu.state.carry == 1 assert cpu.state.carry == 1
assert cpu.state.cycles == 16
RR_HL().exec(cpu) RR_HL().exec(cpu)
assert cpu.hl == 0x80 assert cpu.hl == 0x80
assert cpu.state.carry == 0 assert cpu.state.carry == 0
assert cpu.state.cycles == 32
@pytest.mark.parametrize("r", R8) @pytest.mark.parametrize("r", R8)
@ -222,14 +198,12 @@ def test_sla_r(r):
assert cpu.get_reg8(r) == 0xFE assert cpu.get_reg8(r) == 0xFE
assert cpu.state.carry == 1 assert cpu.state.carry == 1
assert cpu.state.cycles == 8
cpu.set_reg8(r, 0x01) cpu.set_reg8(r, 0x01)
SLA_R(r).exec(cpu) SLA_R(r).exec(cpu)
assert cpu.get_reg8(r) == 0x02 assert cpu.get_reg8(r) == 0x02
assert cpu.state.carry == 0 assert cpu.state.carry == 0
assert cpu.state.cycles == 16
def test_sla_hl(): def test_sla_hl():
@ -241,14 +215,12 @@ def test_sla_hl():
assert cpu.hl == 0xFE assert cpu.hl == 0xFE
assert cpu.state.carry == 1 assert cpu.state.carry == 1
assert cpu.state.cycles == 16
cpu.hl = 0x01 cpu.hl = 0x01
SLA_HL().exec(cpu) SLA_HL().exec(cpu)
assert cpu.hl == 0x02 assert cpu.hl == 0x02
assert cpu.state.carry == 0 assert cpu.state.carry == 0
assert cpu.state.cycles == 32
@pytest.mark.parametrize("r", R8) @pytest.mark.parametrize("r", R8)
@ -260,7 +232,6 @@ def test_swap_r(r):
assert cpu.get_reg8(r) == 0xBA assert cpu.get_reg8(r) == 0xBA
assert cpu.state.carry == 0 assert cpu.state.carry == 0
assert cpu.state.cycles == 8
def test_swap_hl(): def test_swap_hl():
@ -272,7 +243,6 @@ def test_swap_hl():
assert cpu.hl == 0xBA assert cpu.hl == 0xBA
assert cpu.state.carry == 0 assert cpu.state.carry == 0
assert cpu.state.cycles == 16
@pytest.mark.parametrize("r", R8) @pytest.mark.parametrize("r", R8)
@ -284,14 +254,12 @@ def test_sra_r(r):
assert cpu.get_reg8(r) == 0xFF assert cpu.get_reg8(r) == 0xFF
assert cpu.state.carry == 1 assert cpu.state.carry == 1
assert cpu.state.cycles == 8
cpu.set_reg8(r, 0x02) cpu.set_reg8(r, 0x02)
SRA_R(r).exec(cpu) SRA_R(r).exec(cpu)
assert cpu.get_reg8(r) == 0x01 assert cpu.get_reg8(r) == 0x01
assert cpu.state.carry == 0 assert cpu.state.carry == 0
assert cpu.state.cycles == 16
def test_sra_hl(): def test_sra_hl():
@ -303,14 +271,12 @@ def test_sra_hl():
assert cpu.hl == 0xFF assert cpu.hl == 0xFF
assert cpu.state.carry == 1 assert cpu.state.carry == 1
assert cpu.state.cycles == 16
cpu.hl = 0x02 cpu.hl = 0x02
SRA_HL().exec(cpu) SRA_HL().exec(cpu)
assert cpu.hl == 0x01 assert cpu.hl == 0x01
assert cpu.state.carry == 0 assert cpu.state.carry == 0
assert cpu.state.cycles == 32
@pytest.mark.parametrize("r", R8) @pytest.mark.parametrize("r", R8)
@ -322,14 +288,12 @@ def test_srl_r(r):
assert cpu.get_reg8(r) == 0x7F assert cpu.get_reg8(r) == 0x7F
assert cpu.state.carry == 1 assert cpu.state.carry == 1
assert cpu.state.cycles == 8
cpu.set_reg8(r, 0x02) cpu.set_reg8(r, 0x02)
SRL_R(r).exec(cpu) SRL_R(r).exec(cpu)
assert cpu.get_reg8(r) == 0x01 assert cpu.get_reg8(r) == 0x01
assert cpu.state.carry == 0 assert cpu.state.carry == 0
assert cpu.state.cycles == 16
def test_srl_hl(): def test_srl_hl():
@ -341,11 +305,9 @@ def test_srl_hl():
assert cpu.hl == 0x7F assert cpu.hl == 0x7F
assert cpu.state.carry == 1 assert cpu.state.carry == 1
assert cpu.state.cycles == 16
cpu.hl = 0x02 cpu.hl = 0x02
SRL_HL().exec(cpu) SRL_HL().exec(cpu)
assert cpu.hl == 0x01 assert cpu.hl == 0x01
assert cpu.state.carry == 0 assert cpu.state.carry == 0
assert cpu.state.cycles == 32

Loading…
Cancel
Save