Browse Source

Update tests and instructions to use CPU state

master
Forest Belton 2 years ago
parent
commit
f0e46646b4
9 changed files with 339 additions and 337 deletions
  1. +153
    -151
      gbso/insn.py
  2. +1
    -1
      gbso/program.py
  3. +18
    -18
      tests/insn/test_alu16.py
  4. +57
    -57
      tests/insn/test_alu8.py
  5. +4
    -4
      tests/insn/test_bit.py
  6. +6
    -6
      tests/insn/test_cpu.py
  7. +5
    -5
      tests/insn/test_loads16.py
  8. +19
    -19
      tests/insn/test_loads8.py
  9. +76
    -76
      tests/insn/test_shift.py

+ 153
- 151
gbso/insn.py View File

@ -22,7 +22,7 @@ class LD_R_R(Insn):
def exec(self, cpu: CPU) -> None:
cpu.set_reg8(self.dst, cpu.get_reg8(self.src))
cpu.cycles += 4
cpu.state.cycles += 4
def pretty(self) -> str:
return f"LD {self.dst.value}, {self.src.value}"
@ -35,7 +35,7 @@ class LD_R_N8(Insn):
def exec(self, cpu: CPU) -> None:
cpu.set_reg8(self.dst, self.imm)
cpu.cycles += 8
cpu.state.cycles += 8
def pretty(self) -> str:
return f"LD {self.dst.value}, {hex(self.imm)}"
@ -47,7 +47,7 @@ class LD_R_HL(Insn):
def exec(self, cpu: CPU) -> None:
cpu.set_reg8(self.dst, cpu.get_mem8(cpu.get_reg16(R16.HL)))
cpu.cycles += 8
cpu.state.cycles += 8
def pretty(self) -> str:
return f"LD {self.dst.value}, (HL)"
@ -59,7 +59,7 @@ class LD_HL_R(Insn):
def exec(self, cpu: CPU) -> None:
cpu.deref_hl_set(cpu.get_reg8(self.src))
cpu.cycles += 8
cpu.state.cycles += 8
def pretty(self) -> str:
return f"LD (HL), {self.src.value}"
@ -71,7 +71,7 @@ class LD_HL_N(Insn):
def exec(self, cpu: CPU) -> None:
cpu.set_mem8(cpu.get_reg16(R16.HL), self.imm)
cpu.cycles += 12
cpu.state.cycles += 12
def pretty(self) -> str:
return f"LD (HL), {hex(self.imm & 0xff)}"
@ -81,7 +81,7 @@ class LD_HL_N(Insn):
class LD_A_BC(Insn):
def exec(self, cpu: CPU) -> None:
cpu.set_reg8(R8.A, cpu.get_mem8(cpu.get_reg16(R16.BC)))
cpu.cycles += 8
cpu.state.cycles += 8
def pretty(self) -> str:
return "LD A, (BC)"
@ -91,7 +91,7 @@ class LD_A_BC(Insn):
class LD_A_DE(Insn):
def exec(self, cpu: CPU) -> None:
cpu.set_reg8(R8.A, cpu.get_mem8(cpu.get_reg16(R16.DE)))
cpu.cycles += 8
cpu.state.cycles += 8
def pretty(self) -> str:
return "LD A, (DE)"
@ -103,7 +103,7 @@ class LD_A_NN(Insn):
def exec(self, cpu: CPU) -> None:
cpu.set_reg8(R8.A, cpu.get_mem8(self.nn))
cpu.cycles += 16
cpu.state.cycles += 16
def pretty(self) -> str:
return f"LD A, ({hex(self.nn)})"
@ -113,7 +113,7 @@ class LD_A_NN(Insn):
class LD_BC_A(Insn):
def exec(self, cpu: CPU) -> None:
cpu.set_mem8(cpu.get_reg16(R16.BC), cpu.get_reg8(R8.A))
cpu.cycles += 8
cpu.state.cycles += 8
def pretty(self) -> str:
return "LD (BC), A"
@ -123,7 +123,7 @@ class LD_BC_A(Insn):
class LD_DE_A(Insn):
def exec(self, cpu: CPU) -> None:
cpu.set_mem8(cpu.get_reg16(R16.DE), cpu.get_reg8(R8.A))
cpu.cycles += 8
cpu.state.cycles += 8
def pretty(self) -> str:
return "LD (DE), A"
@ -135,7 +135,7 @@ class LD_NN_A(Insn):
def exec(self, cpu: CPU) -> None:
cpu.set_mem8(self.nn, cpu.get_reg8(R8.A))
cpu.cycles += 16
cpu.state.cycles += 16
def pretty(self) -> str:
return f"LD ({hex(self.nn)}), A"
@ -147,7 +147,7 @@ class LD_A_FF_N(Insn):
def exec(self, cpu: CPU) -> None:
cpu.set_reg8(R8.A, cpu.get_mem8(0xFF00 + self.n))
cpu.cycles += 12
cpu.state.cycles += 12
def pretty(self) -> str:
return f"LD A, (0xFF00 + {hex(self.n)})"
@ -159,7 +159,7 @@ class LD_FF_N_A(Insn):
def exec(self, cpu: CPU) -> None:
cpu.set_mem8(0xFF00 + self.n, cpu.get_reg8(R8.A))
cpu.cycles += 12
cpu.state.cycles += 12
def pretty(self) -> str:
return f"LD (0xFF00 + {hex(self.n)}), A"
@ -169,7 +169,7 @@ class LD_FF_N_A(Insn):
class LD_A_FF_C(Insn):
def exec(self, cpu: CPU) -> None:
cpu.set_reg8(R8.A, cpu.get_mem8(0xFF00 + cpu.get_reg8(R8.C)))
cpu.cycles += 8
cpu.state.cycles += 8
def pretty(self) -> str:
return "LD A, (0xFF00 + C)"
@ -179,7 +179,7 @@ class LD_A_FF_C(Insn):
class LD_FF_C_A(Insn):
def exec(self, cpu: CPU) -> None:
cpu.set_mem8(0xFF00 + cpu.get_reg8(R8.C), cpu.get_reg8(R8.A))
cpu.cycles += 8
cpu.state.cycles += 8
def pretty(self) -> str:
return "LD (0xFF00 + C), A"
@ -191,7 +191,7 @@ class LDI_HL_A(Insn):
hl = cpu.get_reg16(R16.HL)
cpu.set_mem8(hl, cpu.get_reg8(R8.A))
cpu.set_reg16(R16.HL, hl + 1)
cpu.cycles += 8
cpu.state.cycles += 8
def pretty(self) -> str:
return "LDI (HL), A"
@ -203,7 +203,7 @@ class LDI_A_HL(Insn):
hl = cpu.get_reg16(R16.HL)
cpu.set_reg8(R8.A, cpu.get_mem8(hl))
cpu.set_reg16(R16.HL, hl + 1)
cpu.cycles += 8
cpu.state.cycles += 8
def pretty(self) -> str:
return "LDI A, (HL)"
@ -215,7 +215,7 @@ class LDD_HL_A(Insn):
hl = cpu.get_reg16(R16.HL)
cpu.set_mem8(hl, cpu.get_reg8(R8.A))
cpu.set_reg16(R16.HL, hl - 1)
cpu.cycles += 8
cpu.state.cycles += 8
def pretty(self) -> str:
return "LDD (HL), A"
@ -227,7 +227,7 @@ class LDD_A_HL(Insn):
hl = cpu.get_reg16(R16.HL)
cpu.set_reg8(R8.A, cpu.get_mem8(hl))
cpu.set_reg16(R16.HL, hl - 1)
cpu.cycles += 8
cpu.state.cycles += 8
def pretty(self) -> str:
return "LDD A, (HL)"
@ -240,7 +240,7 @@ class LD_RR_NN(Insn):
def exec(self, cpu: CPU) -> None:
cpu.set_reg16(self.rr, self.nn)
cpu.cycles += 12
cpu.state.cycles += 12
def pretty(self) -> str:
return f"LD {self.rr.value}, {hex(self.nn)}"
@ -252,7 +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
cpu.state.cycles += 20
def pretty(self) -> str:
return f"LD ({hex(self.nn)}), SP"
@ -262,7 +262,7 @@ 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
cpu.state.cycles += 8
def pretty(self) -> str:
return "LD SP, HL"
@ -278,7 +278,7 @@ class PUSH_RR(Insn):
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
cpu.state.cycles += 16
def pretty(self) -> str:
return f"PUSH {self.rr.value}"
@ -292,7 +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
cpu.state.cycles += 12
def pretty(self) -> str:
return f"POP {self.rr.value}"
@ -304,9 +304,9 @@ class ADD_A_R(Insn):
def exec(self, cpu: CPU) -> None:
a = cpu.get_reg8(R8.A) + cpu.get_reg8(self.r)
cpu.carry = 1 if a > 0xFF else 0
cpu.state.carry = 1 if a > 0xFF else 0
cpu.set_reg8(R8.A, a)
cpu.cycles += 4
cpu.state.cycles += 4
def pretty(self) -> str:
return f"ADD A, {self.r.value}"
@ -318,9 +318,9 @@ class ADD_A_N(Insn):
def exec(self, cpu: CPU) -> None:
a = cpu.get_reg8(R8.A) + self.n
cpu.carry = 1 if a > 0xFF else 0
cpu.state.carry = 1 if a > 0xFF else 0
cpu.set_reg8(R8.A, a)
cpu.cycles += 8
cpu.state.cycles += 8
def pretty(self) -> str:
return f"ADD A, {hex(self.n)}"
@ -330,9 +330,9 @@ class ADD_A_N(Insn):
class ADD_A_HL(Insn):
def exec(self, cpu: CPU) -> None:
a = cpu.get_reg8(R8.A) + cpu.get_mem8(cpu.get_reg16(R16.HL))
cpu.carry = 1 if a > 0xFF else 0
cpu.state.carry = 1 if a > 0xFF else 0
cpu.set_reg8(R8.A, a)
cpu.cycles += 8
cpu.state.cycles += 8
def pretty(self) -> str:
return f"ADD A, (HL)"
@ -343,10 +343,10 @@ class ADC_A_R(Insn):
r: R8
def exec(self, cpu: CPU) -> None:
a = cpu.get_reg8(R8.A) + cpu.get_reg8(self.r) + cpu.carry
cpu.carry = 1 if a > 0xFF else 0
a = cpu.get_reg8(R8.A) + cpu.get_reg8(self.r) + cpu.state.carry
cpu.state.carry = 1 if a > 0xFF else 0
cpu.set_reg8(R8.A, a)
cpu.cycles += 4
cpu.state.cycles += 4
def pretty(self) -> str:
return f"ADC A, {self.r.value}"
@ -357,10 +357,10 @@ class ADC_A_N(Insn):
n: int
def exec(self, cpu: CPU) -> None:
a = cpu.get_reg8(R8.A) + self.n + cpu.carry
cpu.carry = 1 if a > 0xFF else 0
a = cpu.get_reg8(R8.A) + self.n + cpu.state.carry
cpu.state.carry = 1 if a > 0xFF else 0
cpu.set_reg8(R8.A, a)
cpu.cycles += 8
cpu.state.cycles += 8
def pretty(self) -> str:
return f"ADC A, {hex(self.n)}"
@ -369,10 +369,10 @@ class ADC_A_N(Insn):
@dataclass
class ADC_A_HL(Insn):
def exec(self, cpu: CPU) -> None:
a = cpu.get_reg8(R8.A) + cpu.get_mem8(cpu.get_reg16(R16.HL)) + cpu.carry
cpu.carry = 1 if a > 0xFF else 0
a = cpu.get_reg8(R8.A) + cpu.get_mem8(cpu.get_reg16(R16.HL)) + cpu.state.carry
cpu.state.carry = 1 if a > 0xFF else 0
cpu.set_reg8(R8.A, a)
cpu.cycles += 8
cpu.state.cycles += 8
def pretty(self) -> str:
return f"ADC A, (HL)"
@ -384,9 +384,9 @@ class SUB_A_R(Insn):
def exec(self, cpu: CPU) -> None:
a = cpu.get_reg8(R8.A) - cpu.get_reg8(self.r)
cpu.carry = 1 if a < 0 else 0
cpu.state.carry = 1 if a < 0 else 0
cpu.set_reg8(R8.A, a)
cpu.cycles += 4
cpu.state.cycles += 4
def pretty(self) -> str:
return f"SUB A, {self.r.value}"
@ -398,9 +398,9 @@ class SUB_A_N(Insn):
def exec(self, cpu: CPU) -> None:
a = cpu.get_reg8(R8.A) - self.n
cpu.carry = 1 if a < 0 else 0
cpu.state.carry = 1 if a < 0 else 0
cpu.set_reg8(R8.A, a)
cpu.cycles += 8
cpu.state.cycles += 8
def pretty(self) -> str:
return f"SUB A, {hex(self.n)}"
@ -410,9 +410,9 @@ class SUB_A_N(Insn):
class SUB_A_HL(Insn):
def exec(self, cpu: CPU) -> None:
a = cpu.get_reg8(R8.A) - cpu.get_mem8(cpu.get_reg16(R16.HL))
cpu.carry = 1 if a < 0 else 0
cpu.state.carry = 1 if a < 0 else 0
cpu.set_reg8(R8.A, a)
cpu.cycles += 8
cpu.state.cycles += 8
def pretty(self) -> str:
return "SUB A, (HL)"
@ -423,10 +423,10 @@ class SBC_A_R(Insn):
r: R8
def exec(self, cpu: CPU) -> None:
a = cpu.get_reg8(R8.A) - cpu.get_reg8(self.r) - cpu.carry
cpu.carry = 1 if a < 0 else 0
a = cpu.get_reg8(R8.A) - cpu.get_reg8(self.r) - cpu.state.carry
cpu.state.carry = 1 if a < 0 else 0
cpu.set_reg8(R8.A, a)
cpu.cycles += 4
cpu.state.cycles += 4
def pretty(self) -> str:
return f"SBC A, {self.r.value}"
@ -437,10 +437,10 @@ class SBC_A_N(Insn):
n: int
def exec(self, cpu: CPU) -> None:
a = cpu.get_reg8(R8.A) - self.n - cpu.carry
cpu.carry = 1 if a < 0 else 0
a = cpu.get_reg8(R8.A) - self.n - cpu.state.carry
cpu.state.carry = 1 if a < 0 else 0
cpu.set_reg8(R8.A, a)
cpu.cycles += 8
cpu.state.cycles += 8
def pretty(self) -> str:
return f"SBC A, {hex(self.n)}"
@ -449,10 +449,10 @@ class SBC_A_N(Insn):
@dataclass
class SBC_A_HL(Insn):
def exec(self, cpu: CPU) -> None:
a = cpu.get_reg8(R8.A) - cpu.get_mem8(cpu.get_reg16(R16.HL)) - cpu.carry
cpu.carry = 1 if a < 0 else 0
a = cpu.get_reg8(R8.A) - cpu.get_mem8(cpu.get_reg16(R16.HL)) - cpu.state.carry
cpu.state.carry = 1 if a < 0 else 0
cpu.set_reg8(R8.A, a)
cpu.cycles += 8
cpu.state.cycles += 8
def pretty(self) -> str:
return "SBC A, (HL)"
@ -465,8 +465,8 @@ class AND_A_R(Insn):
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
cpu.state.carry = 0
cpu.state.cycles += 4
def pretty(self) -> str:
return f"AND A, {self.r.value}"
@ -479,8 +479,8 @@ class AND_A_N(Insn):
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
cpu.state.carry = 0
cpu.state.cycles += 8
def pretty(self) -> str:
return f"AND A, {hex(self.n)}"
@ -491,8 +491,8 @@ class AND_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
cpu.state.carry = 0
cpu.state.cycles += 8
def pretty(self) -> str:
return "AND A, (HL)"
@ -505,8 +505,8 @@ class XOR_A_R(Insn):
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
cpu.state.carry = 0
cpu.state.cycles += 4
def pretty(self) -> str:
return f"XOR A, {self.r.value}"
@ -519,8 +519,8 @@ class XOR_A_N(Insn):
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
cpu.state.carry = 0
cpu.state.cycles += 8
def pretty(self) -> str:
return f"XOR A, {hex(self.n)}"
@ -531,8 +531,8 @@ 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
cpu.state.carry = 0
cpu.state.cycles += 8
def pretty(self) -> str:
return "XOR A, (HL)"
@ -545,8 +545,8 @@ class OR_A_R(Insn):
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
cpu.state.carry = 0
cpu.state.cycles += 4
def pretty(self) -> str:
return f"OR A, {self.r.value}"
@ -559,8 +559,8 @@ class OR_A_N(Insn):
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
cpu.state.carry = 0
cpu.state.cycles += 8
def pretty(self) -> str:
return f"OR A, {hex(self.n)}"
@ -571,8 +571,8 @@ 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
cpu.state.carry = 0
cpu.state.cycles += 8
def pretty(self) -> str:
return "OR A, (HL)"
@ -583,8 +583,8 @@ 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
cpu.state.carry = 1 if cpu.get_reg8(R8.A) < cpu.get_reg8(self.r) else 0
cpu.state.cycles += 4
def pretty(self) -> str:
return f"CP A, {self.r.value}"
@ -595,8 +595,8 @@ class CP_A_N(Insn):
n: int
def exec(self, cpu: CPU) -> None:
cpu.carry = 1 if cpu.get_reg8(R8.A) < self.n else 0
cpu.cycles += 8
cpu.state.carry = 1 if cpu.get_reg8(R8.A) < self.n else 0
cpu.state.cycles += 8
def pretty(self) -> str:
return f"CP A, {hex(self.n)}"
@ -605,8 +605,10 @@ class CP_A_N(Insn):
@dataclass
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
cpu.state.carry = (
1 if cpu.get_reg8(R8.A) < cpu.get_mem8(cpu.get_reg16(R16.HL)) else 0
)
cpu.state.cycles += 8
def pretty(self) -> str:
return "CP A, (HL)"
@ -618,7 +620,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
cpu.state.cycles += 4
def pretty(self) -> str:
return f"INC {self.r.value}"
@ -631,7 +633,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
cpu.state.cycles += 12
def pretty(self) -> str:
return "INC (HL)"
@ -643,7 +645,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
cpu.state.cycles += 4
def pretty(self) -> str:
return f"DEC {self.r.value}"
@ -656,7 +658,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
cpu.state.cycles += 12
def pretty(self) -> str:
return "DEC (HL)"
@ -666,7 +668,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
cpu.state.cycles += 4
def pretty(self) -> str:
return "CPL"
@ -678,9 +680,9 @@ class ADD_HL_RR(Insn):
def exec(self, cpu: CPU) -> None:
hl = cpu.get_reg16(R16.HL) + cpu.get_reg16(self.rr)
cpu.carry = 1 if hl > 0xFFFF else 0
cpu.state.carry = 1 if hl > 0xFFFF else 0
cpu.set_reg16(R16.HL, hl)
cpu.cycles += 8
cpu.state.cycles += 8
def pretty(self) -> str:
return f"ADD HL, {self.rr.value}"
@ -692,7 +694,7 @@ class INC_RR(Insn):
def exec(self, cpu: CPU) -> None:
cpu.set_reg16(self.rr, cpu.get_reg16(self.rr) + 1)
cpu.cycles += 8
cpu.state.cycles += 8
def pretty(self) -> str:
return f"INC {self.rr.value}"
@ -704,7 +706,7 @@ class DEC_RR(Insn):
def exec(self, cpu: CPU) -> None:
cpu.set_reg16(self.rr, cpu.get_reg16(self.rr) - 1)
cpu.cycles += 8
cpu.state.cycles += 8
def pretty(self) -> str:
return f"DEC {self.rr.value}"
@ -716,9 +718,9 @@ class ADD_SP_DD(Insn):
def exec(self, cpu: CPU) -> None:
sp = cpu.get_reg16(R16.SP) + self.dd
cpu.carry = 1 if sp > 0xFFFF or sp < 0 else 0
cpu.state.carry = 1 if sp > 0xFFFF or sp < 0 else 0
cpu.set_reg16(R16.SP, sp & 0xFFFF)
cpu.cycles += 16
cpu.state.cycles += 16
def pretty(self) -> str:
return f"ADD SP, {self.dd}"
@ -730,9 +732,9 @@ class LD_HL_SP_DD(Insn):
def exec(self, cpu: CPU) -> None:
sp = cpu.get_reg16(R16.SP) + self.dd
cpu.carry = 1 if sp > 0xFFFF or sp < 0 else 0
cpu.state.carry = 1 if sp > 0xFFFF or sp < 0 else 0
cpu.set_reg16(R16.HL, sp & 0xFFFF)
cpu.cycles += 12
cpu.state.cycles += 12
def pretty(self) -> str:
return f"LD HL, SP + {self.dd}"
@ -742,9 +744,9 @@ class LD_HL_SP_DD(Insn):
class RLCA(Insn):
def exec(self, cpu: CPU) -> None:
a = cpu.get_reg8(R8.A)
cpu.carry = (a >> 7) & 1
cpu.set_reg8(R8.A, ((a << 1) & 0xFF) | cpu.carry)
cpu.cycles += 4
cpu.state.carry = (a >> 7) & 1
cpu.set_reg8(R8.A, ((a << 1) & 0xFF) | cpu.state.carry)
cpu.state.cycles += 4
def pretty(self) -> str:
return "RLCA"
@ -755,9 +757,9 @@ class RLA(Insn):
def exec(self, cpu: CPU) -> None:
a = cpu.get_reg8(R8.A)
next_carry = (a >> 7) & 1
cpu.set_reg8(R8.A, ((a << 1) & 0xFF) | cpu.carry)
cpu.carry = next_carry
cpu.cycles += 4
cpu.set_reg8(R8.A, ((a << 1) & 0xFF) | cpu.state.carry)
cpu.state.carry = next_carry
cpu.state.cycles += 4
def pretty(self) -> str:
return "RLA"
@ -767,9 +769,9 @@ class RLA(Insn):
class RRCA(Insn):
def exec(self, cpu: CPU) -> None:
a = cpu.get_reg8(R8.A)
cpu.carry = a & 1
cpu.set_reg8(R8.A, (a >> 1) | (cpu.carry << 7))
cpu.cycles += 4
cpu.state.carry = a & 1
cpu.set_reg8(R8.A, (a >> 1) | (cpu.state.carry << 7))
cpu.state.cycles += 4
def pretty(self) -> str:
return "RRCA"
@ -780,9 +782,9 @@ class RRA(Insn):
def exec(self, cpu: CPU) -> None:
a = cpu.get_reg8(R8.A)
next_carry = a & 1
cpu.set_reg8(R8.A, (a >> 1) | (cpu.carry << 7))
cpu.carry = next_carry
cpu.cycles += 4
cpu.set_reg8(R8.A, (a >> 1) | (cpu.state.carry << 7))
cpu.state.carry = next_carry
cpu.state.cycles += 4
def pretty(self) -> str:
return "RRA"
@ -794,9 +796,9 @@ class RLC_R(Insn):
def exec(self, cpu: CPU) -> None:
r = cpu.get_reg8(self.r)
cpu.carry = (r >> 7) & 1
cpu.set_reg8(self.r, ((r << 1) & 0xFF) | cpu.carry)
cpu.cycles += 8
cpu.state.carry = (r >> 7) & 1
cpu.set_reg8(self.r, ((r << 1) & 0xFF) | cpu.state.carry)
cpu.state.cycles += 8
def pretty(self) -> str:
return f"RLC {self.r.value}"
@ -806,9 +808,9 @@ class RLC_R(Insn):
class RLC_HL(Insn):
def exec(self, cpu: CPU) -> None:
hl = cpu.deref_hl()
cpu.carry = (hl >> 7) & 1
cpu.deref_hl_set(((hl << 1) & 0xFF) | cpu.carry)
cpu.cycles += 16
cpu.state.carry = (hl >> 7) & 1
cpu.deref_hl_set(((hl << 1) & 0xFF) | cpu.state.carry)
cpu.state.cycles += 16
def pretty(self) -> str:
return f"RLC (HL)"
@ -821,9 +823,9 @@ class RL_R(Insn):
def exec(self, cpu: CPU) -> None:
r = cpu.get_reg8(self.r)
next_carry = (r >> 7) & 1
cpu.set_reg8(self.r, ((r << 1) & 0xFF) | cpu.carry)
cpu.carry = next_carry
cpu.cycles += 8
cpu.set_reg8(self.r, ((r << 1) & 0xFF) | cpu.state.carry)
cpu.state.carry = next_carry
cpu.state.cycles += 8
def pretty(self) -> str:
return f"RL {self.r.value}"
@ -834,9 +836,9 @@ class RL_HL(Insn):
def exec(self, cpu: CPU) -> None:
hl = cpu.deref_hl()
next_carry = (hl >> 7) & 1
cpu.deref_hl_set(((hl << 1) & 0xFF) | cpu.carry)
cpu.carry = next_carry
cpu.cycles += 16
cpu.deref_hl_set(((hl << 1) & 0xFF) | cpu.state.carry)
cpu.state.carry = next_carry
cpu.state.cycles += 16
def pretty(self) -> str:
return "RL (HL)"
@ -848,9 +850,9 @@ class RRC_R(Insn):
def exec(self, cpu: CPU) -> None:
r = cpu.get_reg8(self.r)
cpu.carry = r & 1
cpu.set_reg8(self.r, (r >> 1) | (cpu.carry << 7))
cpu.cycles += 8
cpu.state.carry = r & 1
cpu.set_reg8(self.r, (r >> 1) | (cpu.state.carry << 7))
cpu.state.cycles += 8
def pretty(self) -> str:
return f"RRC {self.r.value}"
@ -860,9 +862,9 @@ class RRC_R(Insn):
class RRC_HL(Insn):
def exec(self, cpu: CPU) -> None:
hl = cpu.deref_hl()
cpu.carry = hl & 1
cpu.deref_hl_set((hl >> 1) | (cpu.carry << 7))
cpu.cycles += 16
cpu.state.carry = hl & 1
cpu.deref_hl_set((hl >> 1) | (cpu.state.carry << 7))
cpu.state.cycles += 16
def pretty(self) -> str:
return "RRC (HL)"
@ -875,9 +877,9 @@ class RR_R(Insn):
def exec(self, cpu: CPU) -> None:
r = cpu.get_reg8(self.r)
next_carry = r & 1
cpu.set_reg8(self.r, (r >> 1) | (cpu.carry << 7))
cpu.carry = next_carry
cpu.cycles += 8
cpu.set_reg8(self.r, (r >> 1) | (cpu.state.carry << 7))
cpu.state.carry = next_carry
cpu.state.cycles += 8
def pretty(self) -> str:
return f"RR {self.r.value}"
@ -888,9 +890,9 @@ class RR_HL(Insn):
def exec(self, cpu: CPU) -> None:
hl = cpu.deref_hl()
next_carry = hl & 1
cpu.deref_hl_set((hl >> 1) | (cpu.carry << 7))
cpu.carry = next_carry
cpu.cycles += 16
cpu.deref_hl_set((hl >> 1) | (cpu.state.carry << 7))
cpu.state.carry = next_carry
cpu.state.cycles += 16
def pretty(self) -> str:
return "RR (HL)"
@ -902,9 +904,9 @@ class SLA_R(Insn):
def exec(self, cpu: CPU) -> None:
r = cpu.get_reg8(self.r)
cpu.carry = 1 if r & (1 << 7) else 0
cpu.state.carry = 1 if r & (1 << 7) else 0
cpu.set_reg8(self.r, (r << 1) & 0xFF)
cpu.cycles += 8
cpu.state.cycles += 8
def pretty(self) -> str:
return f"SLA {self.r.value}"
@ -914,9 +916,9 @@ class SLA_R(Insn):
class SLA_HL(Insn):
def exec(self, cpu: CPU) -> None:
hl = cpu.deref_hl()
cpu.carry = 1 if hl & (1 << 7) else 0
cpu.state.carry = 1 if hl & (1 << 7) else 0
cpu.deref_hl_set((hl << 1) & 0xFF)
cpu.cycles += 16
cpu.state.cycles += 16
def pretty(self) -> str:
return "SLA (HL)"
@ -929,8 +931,8 @@ class SWAP_R(Insn):
def exec(self, cpu: CPU) -> None:
r = cpu.get_reg8(self.r)
cpu.set_reg8(self.r, ((r << 4) & 0xFF) | (r >> 4))
cpu.carry = 0
cpu.cycles += 8
cpu.state.carry = 0
cpu.state.cycles += 8
def pretty(self) -> str:
return f"SWAP {self.r.value}"
@ -941,8 +943,8 @@ class SWAP_HL(Insn):
def exec(self, cpu: CPU) -> None:
hl = cpu.deref_hl()
cpu.deref_hl_set(((hl << 4) & 0xFF) | (hl >> 4))
cpu.carry = 0
cpu.cycles += 16
cpu.state.carry = 0
cpu.state.cycles += 16
def pretty(self) -> str:
return "SWAP (HL)"
@ -954,9 +956,9 @@ class SRA_R(Insn):
def exec(self, cpu: CPU) -> None:
r = cpu.get_reg8(self.r)
cpu.carry = 1 if r & (1 << 0) else 0
cpu.state.carry = 1 if r & (1 << 0) else 0
cpu.set_reg8(self.r, (r >> 1) | (r & (1 << 7)))
cpu.cycles += 8
cpu.state.cycles += 8
def pretty(self) -> str:
return f"SRA {self.r.value}"
@ -966,9 +968,9 @@ class SRA_R(Insn):
class SRA_HL(Insn):
def exec(self, cpu: CPU) -> None:
hl = cpu.deref_hl()
cpu.carry = 1 if hl & (1 << 0) else 0
cpu.state.carry = 1 if hl & (1 << 0) else 0
cpu.deref_hl_set((hl >> 1) | (hl & (1 << 7)))
cpu.cycles += 16
cpu.state.cycles += 16
def pretty(self) -> str:
return "SRA (HL)"
@ -980,9 +982,9 @@ class SRL_R(Insn):
def exec(self, cpu: CPU) -> None:
r = cpu.get_reg8(self.r)
cpu.carry = 1 if r & (1 << 0) else 0
cpu.state.carry = 1 if r & (1 << 0) else 0
cpu.set_reg8(self.r, r >> 1)
cpu.cycles += 8
cpu.state.cycles += 8
def pretty(self) -> str:
return f"SRL {self.r.value}"
@ -992,9 +994,9 @@ class SRL_R(Insn):
class SRL_HL(Insn):
def exec(self, cpu: CPU) -> None:
hl = cpu.deref_hl()
cpu.carry = 1 if hl & (1 << 0) else 0
cpu.state.carry = 1 if hl & (1 << 0) else 0
cpu.deref_hl_set(hl >> 1)
cpu.cycles += 16
cpu.state.cycles += 16
def pretty(self) -> str:
return "SRL (HL)"
@ -1007,7 +1009,7 @@ class SET_N_R(Insn):
def exec(self, cpu: CPU) -> None:
cpu.set_reg8(self.r, cpu.get_reg8(self.r) | (1 << self.n))
cpu.cycles += 8
cpu.state.cycles += 8
def pretty(self) -> str:
return f"SET {self.n}, {self.r.value}"
@ -1020,7 +1022,7 @@ class SET_N_HL(Insn):
def exec(self, cpu: CPU) -> None:
hl = cpu.get_reg16(R16.HL)
cpu.set_mem8(hl, cpu.get_mem8(hl) | (1 << self.n))
cpu.cycles += 16
cpu.state.cycles += 16
def pretty(self) -> str:
return f"SET {self.n}, (HL)"
@ -1033,7 +1035,7 @@ class RES_N_R(Insn):
def exec(self, cpu: CPU) -> None:
cpu.set_reg8(self.r, cpu.get_reg8(self.r) & ~(1 << self.n))
cpu.cycles += 8
cpu.state.cycles += 8
def pretty(self) -> str:
return f"RES {self.n}, (HL)"
@ -1046,7 +1048,7 @@ class RES_N_HL(Insn):
def exec(self, cpu: CPU) -> None:
hl = cpu.get_reg16(R16.HL)
cpu.set_mem8(hl, cpu.get_mem8(hl) & ~(1 << self.n))
cpu.cycles += 16
cpu.state.cycles += 16
def pretty(self) -> str:
return f"RES {self.n}, (HL)"
@ -1055,8 +1057,8 @@ class RES_N_HL(Insn):
@dataclass
class CCF(Insn):
def exec(self, cpu: CPU) -> None:
cpu.carry = cpu.carry ^ 1
cpu.cycles += 4
cpu.state.carry = cpu.state.carry ^ 1
cpu.state.cycles += 4
def pretty(self) -> str:
return "CCF"
@ -1065,8 +1067,8 @@ class CCF(Insn):
@dataclass
class SCF(Insn):
def exec(self, cpu: CPU) -> None:
cpu.carry = 1
cpu.cycles += 4
cpu.state.carry = 1
cpu.state.cycles += 4
def pretty(self) -> str:
return "SCF"

+ 1
- 1
gbso/program.py View File

@ -1,5 +1,5 @@
from dataclasses import dataclass
from typing import Dict, List, Optional, Set, Union
from typing import List, Optional, Set, Union
from gbso.cpu import CPU, CPUState
from gbso.insn import Insn

+ 18
- 18
tests/insn/test_alu16.py View File

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

+ 57
- 57
tests/insn/test_alu8.py View File

@ -11,15 +11,15 @@ def test_add_a_r(r):
ADD_A_R(r).exec(cpu)
assert cpu.get_reg8(R8.A) == 0x7F
assert cpu.carry == 0
assert cpu.cycles == 4
assert cpu.state.carry == 0
assert cpu.state.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
assert cpu.state.carry == 1
assert cpu.state.cycles == 8
@pytest.mark.parametrize("n", n8())
@ -30,8 +30,8 @@ def test_add_a_n(n):
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
assert cpu.state.carry == (1 if n >= 0x81 else 0)
assert cpu.state.cycles == 8
def test_add_a_hl():
@ -42,15 +42,15 @@ def test_add_a_hl():
ADD_A_HL().exec(cpu)
assert cpu.get_reg8(R8.A) == 0x7F
assert cpu.carry == 0
assert cpu.cycles == 8
assert cpu.state.carry == 0
assert cpu.state.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
assert cpu.state.carry == 1
assert cpu.state.cycles == 16
@pytest.mark.parametrize("r", set(R8) - {R8.A})
@ -61,22 +61,22 @@ def test_adc_a_r(r):
ADC_A_R(r).exec(cpu)
assert cpu.get_reg8(R8.A) == 0x7F
assert cpu.carry == 0
assert cpu.cycles == 4
assert cpu.state.carry == 0
assert cpu.state.cycles == 4
cpu.set_reg8(r, 0x81)
ADC_A_R(r).exec(cpu)
assert cpu.get_reg8(R8.A) == 0x00
assert cpu.carry == 1
assert cpu.cycles == 8
assert cpu.state.carry == 1
assert cpu.state.cycles == 8
cpu.set_reg8(r, 0x00)
ADC_A_R(r).exec(cpu)
assert cpu.get_reg8(R8.A) == 0x01
assert cpu.carry == 0
assert cpu.cycles == 12
assert cpu.state.carry == 0
assert cpu.state.cycles == 12
@pytest.mark.parametrize("n", n8())
@ -87,8 +87,8 @@ def test_adc_a_n(n):
ADC_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
assert cpu.state.carry == (1 if n >= 0x81 else 0)
assert cpu.state.cycles == 8
def test_adc_a_hl():
@ -99,22 +99,22 @@ def test_adc_a_hl():
ADC_A_HL().exec(cpu)
assert cpu.get_reg8(R8.A) == 0x7F
assert cpu.carry == 0
assert cpu.cycles == 8
assert cpu.state.carry == 0
assert cpu.state.cycles == 8
cpu.deref_hl_set(0x81)
ADC_A_HL().exec(cpu)
assert cpu.get_reg8(R8.A) == 0
assert cpu.carry == 1
assert cpu.cycles == 16
assert cpu.state.carry == 1
assert cpu.state.cycles == 16
cpu.deref_hl_set(0x00)
ADC_A_HL().exec(cpu)
assert cpu.get_reg8(R8.A) == 1
assert cpu.carry == 0
assert cpu.cycles == 24
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
@ -129,8 +129,8 @@ def test_and_a_r(r):
AND_A_R(r).exec(cpu)
assert cpu.get_reg8(R8.A) == 0x12
assert cpu.carry == 0
assert cpu.cycles == 4
assert cpu.state.carry == 0
assert cpu.state.cycles == 4
@pytest.mark.parametrize("n", n8())
@ -141,8 +141,8 @@ def test_and_a_n(n):
AND_A_N(n).exec(cpu)
assert cpu.get_reg8(R8.A) == 0x12 & n
assert cpu.carry == 0
assert cpu.cycles == 8
assert cpu.state.carry == 0
assert cpu.state.cycles == 8
def test_and_a_hl():
@ -155,8 +155,8 @@ def test_and_a_hl():
AND_A_HL().exec(cpu)
assert cpu.get_reg8(R8.A) == 0x12
assert cpu.carry == 0
assert cpu.cycles == 8
assert cpu.state.carry == 0
assert cpu.state.cycles == 8
@pytest.mark.parametrize("r", set(R8) - {R8.A})
@ -168,8 +168,8 @@ def test_xor_a_r(r):
XOR_A_R(r).exec(cpu)
assert cpu.get_reg8(R8.A) == 0x6D
assert cpu.carry == 0
assert cpu.cycles == 4
assert cpu.state.carry == 0
assert cpu.state.cycles == 4
@pytest.mark.parametrize("n", n8())
@ -180,8 +180,8 @@ def test_xor_a_n(n):
XOR_A_N(n).exec(cpu)
assert cpu.get_reg8(R8.A) == 0x12 ^ n
assert cpu.carry == 0
assert cpu.cycles == 8
assert cpu.state.carry == 0
assert cpu.state.cycles == 8
def test_xor_a_hl():
@ -194,8 +194,8 @@ def test_xor_a_hl():
XOR_A_HL().exec(cpu)
assert cpu.get_reg8(R8.A) == 0x6D
assert cpu.carry == 0
assert cpu.cycles == 8
assert cpu.state.carry == 0
assert cpu.state.cycles == 8
@pytest.mark.parametrize("r", set(R8) - {R8.A})
@ -207,8 +207,8 @@ def test_or_a_r(r):
OR_A_R(r).exec(cpu)
assert cpu.get_reg8(R8.A) == 0x7F
assert cpu.carry == 0
assert cpu.cycles == 4
assert cpu.state.carry == 0
assert cpu.state.cycles == 4
@pytest.mark.parametrize("n", n8())
@ -219,8 +219,8 @@ def test_or_a_n(n):
OR_A_N(n).exec(cpu)
assert cpu.get_reg8(R8.A) == 0x12 | n
assert cpu.carry == 0
assert cpu.cycles == 8
assert cpu.state.carry == 0
assert cpu.state.cycles == 8
def test_or_a_hl():
@ -233,8 +233,8 @@ def test_or_a_hl():
OR_A_HL().exec(cpu)
assert cpu.get_reg8(R8.A) == 0x7F
assert cpu.carry == 0
assert cpu.cycles == 8
assert cpu.state.carry == 0
assert cpu.state.cycles == 8
@pytest.mark.parametrize("r", set(R8) - {R8.A})
@ -246,15 +246,15 @@ def test_cp_a_r(r):
CP_A_R(r).exec(cpu)
assert cpu.get_reg8(R8.A) == 0x7F
assert cpu.carry == 0
assert cpu.cycles == 4
assert cpu.state.carry == 0
assert cpu.state.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
assert cpu.state.carry == 1
assert cpu.state.cycles == 8
@pytest.mark.parametrize("n", n8())
@ -265,8 +265,8 @@ def test_cp_a_n(n):
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
assert cpu.state.carry == (1 if 0x12 < n else 0)
assert cpu.state.cycles == 8
def test_cp_a_hl():
@ -279,16 +279,16 @@ def test_cp_a_hl():
CP_A_HL().exec(cpu)
assert cpu.get_reg8(R8.A) == 0x7F
assert cpu.carry == 0
assert cpu.cycles == 8
assert cpu.state.carry == 0
assert cpu.state.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
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()])
@ -299,7 +299,7 @@ def test_inc_r(r, n):
INC_R(r).exec(cpu)
assert cpu.get_reg8(r) == (n + 1) & 0xFF
assert cpu.cycles == 4
assert cpu.state.cycles == 4
@pytest.mark.parametrize("n", n8())
@ -311,7 +311,7 @@ def test_inc_hl(n):
INC_HL(n).exec(cpu)
assert cpu.deref_hl() == (n + 1) & 0xFF
assert cpu.cycles == 12
assert cpu.state.cycles == 12
@pytest.mark.parametrize("r,n", [(r, n) for r in R8 for n in n8()])
@ -322,7 +322,7 @@ def test_dec_r(r, n):
DEC_R(r).exec(cpu)
assert cpu.get_reg8(r) == (n - 1) & 0xFF
assert cpu.cycles == 4
assert cpu.state.cycles == 4
@pytest.mark.parametrize("n", n8())
@ -334,7 +334,7 @@ def test_dec_hl(n):
DEC_HL(n).exec(cpu)
assert cpu.deref_hl() == (n - 1) & 0xFF
assert cpu.cycles == 12
assert cpu.state.cycles == 12
# TODO: Test DAA after implementing it
@ -348,4 +348,4 @@ def test_cpl(n):
CPL().exec(cpu)
assert cpu.get_reg8(R8.A) == n ^ 0xFF
assert cpu.cycles == 4
assert cpu.state.cycles == 4

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

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

+ 6
- 6
tests/insn/test_cpu.py View File

@ -6,13 +6,13 @@ def test_ccf():
CCF().exec(cpu)
assert cpu.carry == 1
assert cpu.cycles == 4
assert cpu.state.carry == 1
assert cpu.state.cycles == 4
CCF().exec(cpu)
assert cpu.carry == 0
assert cpu.cycles == 8
assert cpu.state.carry == 0
assert cpu.state.cycles == 8
def test_scf():
@ -20,5 +20,5 @@ def test_scf():
SCF().exec(cpu)
assert cpu.carry == 1
assert cpu.cycles == 4
assert cpu.state.carry == 1
assert cpu.state.cycles == 4

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

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

+ 19
- 19
tests/insn/test_loads8.py View File

@ -10,7 +10,7 @@ def test_ld_r_r(dst, src):
LD_R_R(dst, src).exec(cpu)
assert cpu.get_reg8(src) == 0x7F
assert cpu.cycles == 4
assert cpu.state.cycles == 4
@pytest.mark.parametrize("r,imm", [(r, imm) for r in R8 for imm in n8()])
@ -19,7 +19,7 @@ def test_ld_r_n8(r, imm):
LD_R_N8(r, 0x7F).exec(cpu)
assert cpu.get_reg8(r) == 0x7F
assert cpu.cycles == 8
assert cpu.state.cycles == 8
@pytest.mark.parametrize("r", R8)
@ -30,7 +30,7 @@ def test_ld_r_hl(r):
LD_R_HL(r).exec(cpu)
assert cpu.get_reg8(r) == 0x7F
assert cpu.cycles == 8
assert cpu.state.cycles == 8
@pytest.mark.parametrize("r", R8)
@ -49,7 +49,7 @@ def test_ld_hl_r(r):
else:
assert hl == 0x7F
assert cpu.cycles == 8
assert cpu.state.cycles == 8
@pytest.mark.parametrize("imm", n8())
@ -60,7 +60,7 @@ def test_ld_hl_n8(imm):
LD_HL_N(imm).exec(cpu)
assert cpu.deref_hl() == imm
assert cpu.cycles == 12
assert cpu.state.cycles == 12
def test_ld_a_bc():
@ -71,7 +71,7 @@ def test_ld_a_bc():
LD_A_BC().exec(cpu)
assert cpu.get_reg8(R8.A) == 0x7F
assert cpu.cycles == 8
assert cpu.state.cycles == 8
def test_ld_a_de():
@ -82,7 +82,7 @@ def test_ld_a_de():
LD_A_DE().exec(cpu)
assert cpu.get_reg8(R8.A) == 0x7F
assert cpu.cycles == 8
assert cpu.state.cycles == 8
# @pytest.mark.parametrize("nn", n16())
@ -93,7 +93,7 @@ def test_ld_a_nn(nn=0x1234):
LD_A_NN(nn).exec(cpu)
assert cpu.get_reg8(R8.A) == 0x7F
assert cpu.cycles == 16
assert cpu.state.cycles == 16
def test_ld_bc_a():
@ -104,7 +104,7 @@ def test_ld_bc_a():
LD_BC_A().exec(cpu)
assert cpu.get_mem8(0x1234) == 0x7F
assert cpu.cycles == 8
assert cpu.state.cycles == 8
def test_ld_de_a():
@ -115,7 +115,7 @@ def test_ld_de_a():
LD_DE_A().exec(cpu)
assert cpu.get_mem8(0x1234) == 0x7F
assert cpu.cycles == 8
assert cpu.state.cycles == 8
# @pytest.mark.parametrize("nn", n16())
@ -126,7 +126,7 @@ def test_ld_nn_a(nn=0x1234):
LD_NN_A(nn).exec(cpu)
assert cpu.get_mem8(nn) == 0x7F
assert cpu.cycles == 16
assert cpu.state.cycles == 16
@pytest.mark.parametrize("n", n8())
@ -137,7 +137,7 @@ def test_ld_a_ff_n(n):
LD_A_FF_N(n).exec(cpu)
assert cpu.get_reg8(R8.A) == 0x7F
assert cpu.cycles == 12
assert cpu.state.cycles == 12
@pytest.mark.parametrize("n", n8())
@ -148,7 +148,7 @@ def test_ld_ff_n_a(n):
LD_FF_N_A(n).exec(cpu)
assert cpu.get_mem8(0xFF00 + n) == 0x7F
assert cpu.cycles == 12
assert cpu.state.cycles == 12
def test_ld_a_ff_c():
@ -159,7 +159,7 @@ def test_ld_a_ff_c():
LD_A_FF_C().exec(cpu)
assert cpu.get_reg8(R8.A) == 0x7F
assert cpu.cycles == 8
assert cpu.state.cycles == 8
def test_ld_ff_c_a():
@ -170,7 +170,7 @@ def test_ld_ff_c_a():
LD_FF_C_A().exec(cpu)
assert cpu.get_mem8(0xFF12) == 0x7F
assert cpu.cycles == 8
assert cpu.state.cycles == 8
def test_ldi_hl_a():
@ -182,7 +182,7 @@ def test_ldi_hl_a():
assert cpu.get_reg16(R16.HL) == 0x1235
assert cpu.get_mem8(0x1234) == 0x7F
assert cpu.cycles == 8
assert cpu.state.cycles == 8
def test_ldi_a_hl():
@ -194,7 +194,7 @@ def test_ldi_a_hl():
assert cpu.get_reg16(R16.HL) == 0x1235
assert cpu.get_reg8(R8.A) == 0x7F
assert cpu.cycles == 8
assert cpu.state.cycles == 8
def test_ldd_hl_a():
@ -206,7 +206,7 @@ def test_ldd_hl_a():
assert cpu.get_reg16(R16.HL) == 0x1233
assert cpu.get_mem8(0x1234) == 0x7F
assert cpu.cycles == 8
assert cpu.state.cycles == 8
def test_ldd_a_hl():
@ -218,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.state.cycles == 8

+ 76
- 76
tests/insn/test_shift.py View File

@ -10,14 +10,14 @@ def test_rlca():
RLCA().exec(cpu)
assert cpu.get_reg8(R8.A) == 0x01
assert cpu.carry == 1
assert cpu.cycles == 4
assert cpu.state.carry == 1
assert cpu.state.cycles == 4
RLCA().exec(cpu)
assert cpu.get_reg8(R8.A) == 0x02
assert cpu.carry == 0
assert cpu.cycles == 8
assert cpu.state.carry == 0
assert cpu.state.cycles == 8
def test_rla():
@ -27,14 +27,14 @@ def test_rla():
RLA().exec(cpu)
assert cpu.get_reg8(R8.A) == 0x00
assert cpu.carry == 1
assert cpu.cycles == 4
assert cpu.state.carry == 1
assert cpu.state.cycles == 4
RLA().exec(cpu)
assert cpu.get_reg8(R8.A) == 0x01
assert cpu.carry == 0
assert cpu.cycles == 8
assert cpu.state.carry == 0
assert cpu.state.cycles == 8
def test_rrca():
@ -44,14 +44,14 @@ def test_rrca():
RRCA().exec(cpu)
assert cpu.get_reg8(R8.A) == 0x80
assert cpu.carry == 1
assert cpu.cycles == 4
assert cpu.state.carry == 1
assert cpu.state.cycles == 4
RRCA().exec(cpu)
assert cpu.get_reg8(R8.A) == 0x40
assert cpu.carry == 0
assert cpu.cycles == 8
assert cpu.state.carry == 0
assert cpu.state.cycles == 8
def test_rra():
@ -61,14 +61,14 @@ def test_rra():
RRA().exec(cpu)
assert cpu.get_reg8(R8.A) == 0x00
assert cpu.carry == 1
assert cpu.cycles == 4
assert cpu.state.carry == 1
assert cpu.state.cycles == 4
RRA().exec(cpu)
assert cpu.get_reg8(R8.A) == 0x80
assert cpu.carry == 0
assert cpu.cycles == 8
assert cpu.state.carry == 0
assert cpu.state.cycles == 8
@pytest.mark.parametrize("r", R8)
@ -79,14 +79,14 @@ def test_rlc_r(r):
RLC_R(r).exec(cpu)
assert cpu.get_reg8(r) == 0x01
assert cpu.carry == 1
assert cpu.cycles == 8
assert cpu.state.carry == 1
assert cpu.state.cycles == 8
RLC_R(r).exec(cpu)
assert cpu.get_reg8(r) == 0x02
assert cpu.carry == 0
assert cpu.cycles == 16
assert cpu.state.carry == 0
assert cpu.state.cycles == 16
def test_rlc_hl():
@ -96,14 +96,14 @@ def test_rlc_hl():
RLC_HL().exec(cpu)
assert cpu.deref_hl() == 0x01
assert cpu.carry == 1
assert cpu.cycles == 16
assert cpu.state.carry == 1
assert cpu.state.cycles == 16
RLC_HL().exec(cpu)
assert cpu.deref_hl() == 0x02
assert cpu.carry == 0
assert cpu.cycles == 32
assert cpu.state.carry == 0
assert cpu.state.cycles == 32
@pytest.mark.parametrize("r", R8)
@ -114,14 +114,14 @@ def test_rl_r(r):
RL_R(r).exec(cpu)
assert cpu.get_reg8(r) == 0x00
assert cpu.carry == 1
assert cpu.cycles == 8
assert cpu.state.carry == 1
assert cpu.state.cycles == 8
RL_R(r).exec(cpu)
assert cpu.get_reg8(r) == 0x01
assert cpu.carry == 0
assert cpu.cycles == 16
assert cpu.state.carry == 0
assert cpu.state.cycles == 16
def test_rl_hl():
@ -131,14 +131,14 @@ def test_rl_hl():
RL_HL().exec(cpu)
assert cpu.deref_hl() == 0x00
assert cpu.carry == 1
assert cpu.cycles == 16
assert cpu.state.carry == 1
assert cpu.state.cycles == 16
RL_HL().exec(cpu)
assert cpu.deref_hl() == 0x01
assert cpu.carry == 0
assert cpu.cycles == 32
assert cpu.state.carry == 0
assert cpu.state.cycles == 32
@pytest.mark.parametrize("r", R8)
@ -149,14 +149,14 @@ def test_rrc_r(r):
RRC_R(r).exec(cpu)
assert cpu.get_reg8(r) == 0x80
assert cpu.carry == 1
assert cpu.cycles == 8
assert cpu.state.carry == 1
assert cpu.state.cycles == 8
RRC_R(r).exec(cpu)
assert cpu.get_reg8(r) == 0x40
assert cpu.carry == 0
assert cpu.cycles == 16
assert cpu.state.carry == 0
assert cpu.state.cycles == 16
def test_rrc_hl():
@ -167,14 +167,14 @@ def test_rrc_hl():
RRC_HL().exec(cpu)
assert cpu.deref_hl() == 0x80
assert cpu.carry == 1
assert cpu.cycles == 16
assert cpu.state.carry == 1
assert cpu.state.cycles == 16
RRC_HL().exec(cpu)
assert cpu.deref_hl() == 0x40
assert cpu.carry == 0
assert cpu.cycles == 32
assert cpu.state.carry == 0
assert cpu.state.cycles == 32
@pytest.mark.parametrize("r", R8)
@ -185,14 +185,14 @@ def test_rr_r(r):
RR_R(r).exec(cpu)
assert cpu.get_reg8(r) == 0x00
assert cpu.carry == 1
assert cpu.cycles == 8
assert cpu.state.carry == 1
assert cpu.state.cycles == 8
RR_R(r).exec(cpu)
assert cpu.get_reg8(r) == 0x80
assert cpu.carry == 0
assert cpu.cycles == 16
assert cpu.state.carry == 0
assert cpu.state.cycles == 16
def test_rr_hl():
@ -203,14 +203,14 @@ def test_rr_hl():
RR_HL().exec(cpu)
assert cpu.deref_hl() == 0x00
assert cpu.carry == 1
assert cpu.cycles == 16
assert cpu.state.carry == 1
assert cpu.state.cycles == 16
RR_HL().exec(cpu)
assert cpu.deref_hl() == 0x80
assert cpu.carry == 0
assert cpu.cycles == 32
assert cpu.state.carry == 0
assert cpu.state.cycles == 32
@pytest.mark.parametrize("r", R8)
@ -221,15 +221,15 @@ def test_sla_r(r):
SLA_R(r).exec(cpu)
assert cpu.get_reg8(r) == 0xFE
assert cpu.carry == 1
assert cpu.cycles == 8
assert cpu.state.carry == 1
assert cpu.state.cycles == 8
cpu.set_reg8(r, 0x01)
SLA_R(r).exec(cpu)
assert cpu.get_reg8(r) == 0x02
assert cpu.carry == 0
assert cpu.cycles == 16
assert cpu.state.carry == 0
assert cpu.state.cycles == 16
def test_sla_hl():
@ -240,15 +240,15 @@ def test_sla_hl():
SLA_HL().exec(cpu)
assert cpu.deref_hl() == 0xFE
assert cpu.carry == 1
assert cpu.cycles == 16
assert cpu.state.carry == 1
assert cpu.state.cycles == 16
cpu.deref_hl_set(0x01)
SLA_HL().exec(cpu)
assert cpu.deref_hl() == 0x02
assert cpu.carry == 0
assert cpu.cycles == 32
assert cpu.state.carry == 0
assert cpu.state.cycles == 32
@pytest.mark.parametrize("r", R8)
@ -259,8 +259,8 @@ def test_swap_r(r):
SWAP_R(r).exec(cpu)
assert cpu.get_reg8(r) == 0xBA
assert cpu.carry == 0
assert cpu.cycles == 8
assert cpu.state.carry == 0
assert cpu.state.cycles == 8
def test_swap_hl():
@ -271,8 +271,8 @@ def test_swap_hl():
SWAP_HL().exec(cpu)
assert cpu.deref_hl() == 0xBA
assert cpu.carry == 0
assert cpu.cycles == 16
assert cpu.state.carry == 0
assert cpu.state.cycles == 16
@pytest.mark.parametrize("r", R8)
@ -283,15 +283,15 @@ def test_sra_r(r):
SRA_R(r).exec(cpu)
assert cpu.get_reg8(r) == 0xFF
assert cpu.carry == 1
assert cpu.cycles == 8
assert cpu.state.carry == 1
assert cpu.state.cycles == 8
cpu.set_reg8(r, 0x02)
SRA_R(r).exec(cpu)
assert cpu.get_reg8(r) == 0x01
assert cpu.carry == 0
assert cpu.cycles == 16
assert cpu.state.carry == 0
assert cpu.state.cycles == 16
def test_sra_hl():
@ -302,15 +302,15 @@ def test_sra_hl():
SRA_HL().exec(cpu)
assert cpu.deref_hl() == 0xFF
assert cpu.carry == 1
assert cpu.cycles == 16
assert cpu.state.carry == 1
assert cpu.state.cycles == 16
cpu.deref_hl_set(0x02)
SRA_HL().exec(cpu)
assert cpu.deref_hl() == 0x01
assert cpu.carry == 0
assert cpu.cycles == 32
assert cpu.state.carry == 0
assert cpu.state.cycles == 32
@pytest.mark.parametrize("r", R8)
@ -321,15 +321,15 @@ def test_srl_r(r):
SRL_R(r).exec(cpu)
assert cpu.get_reg8(r) == 0x7F
assert cpu.carry == 1
assert cpu.cycles == 8
assert cpu.state.carry == 1
assert cpu.state.cycles == 8
cpu.set_reg8(r, 0x02)
SRL_R(r).exec(cpu)
assert cpu.get_reg8(r) == 0x01
assert cpu.carry == 0
assert cpu.cycles == 16
assert cpu.state.carry == 0
assert cpu.state.cycles == 16
def test_srl_hl():
@ -340,12 +340,12 @@ def test_srl_hl():
SRL_HL().exec(cpu)
assert cpu.deref_hl() == 0x7F
assert cpu.carry == 1
assert cpu.cycles == 16
assert cpu.state.carry == 1
assert cpu.state.cycles == 16
cpu.deref_hl_set(0x02)
SRL_HL().exec(cpu)
assert cpu.deref_hl() == 0x01
assert cpu.carry == 0
assert cpu.cycles == 32
assert cpu.state.carry == 0
assert cpu.state.cycles == 32

Loading…
Cancel
Save