From 72803b155f67e61fd2bebf44d971d842c2f05951 Mon Sep 17 00:00:00 2001 From: Forest Belton Date: Thu, 22 Jul 2021 23:39:26 -0400 Subject: [PATCH] Finish adding non-branch instructions --- gbso/cpu.py | 6 ++ gbso/insn.py | 206 +++++++++++++++++++++++++++++++++++++++++++++++++++ 2 files changed, 212 insertions(+) diff --git a/gbso/cpu.py b/gbso/cpu.py index bb03729..ab071f5 100644 --- a/gbso/cpu.py +++ b/gbso/cpu.py @@ -30,3 +30,9 @@ class CPU: def set_mem16(self, nn: int, nn1: int) -> None: pass + + def deref_hl(self) -> int: + return self.get_mem8(self.get_reg16(R16.HL)) + + def deref_hl_set(self, n: int) -> None: + self.set_mem8(self.get_reg16(R16.HL), n) diff --git a/gbso/insn.py b/gbso/insn.py index 5cb4023..8b25aa9 100644 --- a/gbso/insn.py +++ b/gbso/insn.py @@ -35,6 +35,9 @@ class LD_R_N8(Insn): def exec(self, cpu: CPU) -> None: cpu.set_reg8(self.dst, self.imm) + def pretty(self) -> str: + return f"LD {self.dst}, {hex(self.imm)}" + @dataclass class LD_R_HL(Insn): @@ -43,6 +46,9 @@ class LD_R_HL(Insn): def exec(self, cpu: CPU) -> None: cpu.set_reg8(self.dst, cpu.get_mem8(cpu.get_reg16(R16.HL))) + def pretty(self) -> str: + return f"LD {self.dst}, (HL)" + @dataclass class LD_HL_R(Insn): @@ -51,6 +57,9 @@ class LD_HL_R(Insn): def exec(self, cpu: CPU) -> None: cpu.set_mem8(cpu.get_reg16(R16.HL), cpu.get_reg8(self.src)) + def pretty(self) -> str: + return f"LD (HL), {self.src}" + @dataclass class LD_HL_N(Insn): @@ -68,12 +77,18 @@ class LD_A_BC(Insn): def exec(self, cpu: CPU) -> None: cpu.set_reg8(R8.A, cpu.get_mem8(cpu.get_reg16(R16.BC))) + def pretty(self) -> str: + return "LD A, (BC)" + @dataclass class LD_A_DE(Insn): def exec(self, cpu: CPU) -> None: cpu.set_reg8(R8.A, cpu.get_mem8(cpu.get_reg16(R16.DE))) + def pretty(self) -> str: + return "LD A, (DE)" + @dataclass class LD_A_NN(Insn): @@ -82,6 +97,9 @@ class LD_A_NN(Insn): def exec(self, cpu: CPU) -> None: cpu.set_reg8(R8.A, cpu.get_mem8(self.nn)) + def pretty(self) -> str: + return f"LD A, ({hex(self.nn)})" + @dataclass class LD_BC_A(Insn): @@ -542,6 +560,194 @@ class RRA(Insn): return "RRA" +@dataclass +class RLC_R(Insn): + r: R8 + + 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) + + def pretty(self) -> str: + return f"RLC {self.r}" + + +@dataclass +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) + + def pretty(self) -> str: + return f"RLC (HL)" + + +@dataclass +class RL_R(Insn): + r: R8 + + 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 + + def pretty(self) -> str: + return f"RL {self.r}" + + +@dataclass +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 + + def pretty(self) -> str: + return "RL (HL)" + + +@dataclass +class RRC_R(Insn): + r: R8 + + 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)) + + def pretty(self) -> str: + return f"RRC {self.r}" + + +@dataclass +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)) + + def pretty(self) -> str: + return "RRC (HL)" + + +@dataclass +class RR_R(Insn): + r: R8 + + 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 + + def pretty(self) -> str: + return f"RR {self.r}" + + +@dataclass +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 + + def pretty(self) -> str: + return "RR (HL)" + + +@dataclass +class SLA_R(Insn): + r: R8 + + def exec(self, cpu: CPU) -> None: + r = cpu.get_reg8(self.r) + cpu.set_reg8(self.r, (r << 1) & 0xFF) + + def pretty(self) -> str: + return f"SLA {self.r}" + + +@dataclass +class SLA_HL(Insn): + def exec(self, cpu: CPU) -> None: + hl = cpu.deref_hl() + cpu.deref_hl_set((hl << 1) & 0xFF) + + def pretty(self) -> str: + return "SLA (HL)" + + +@dataclass +class SWAP_R(Insn): + r: R8 + + def exec(self, cpu: CPU) -> None: + r = cpu.get_reg8(self.r) + cpu.set_reg8(self.r, ((r << 4) & 0xFF) | (r >> 4)) + + def pretty(self) -> str: + return f"SWAP {self.r}" + + +@dataclass +class SWAP_HL(Insn): + def exec(self, cpu: CPU) -> None: + hl = cpu.deref_hl() + cpu.deref_hl_set(((hl << 4) & 0xFF) | (hl >> 4)) + + def pretty(self) -> str: + return "SWAP (HL)" + + +@dataclass +class SRA_R(Insn): + r: R8 + + def exec(self, cpu: CPU) -> None: + r = cpu.get_reg8(self.r) + cpu.set_reg8(self.r, (r >> 1) | (r & (1 << 7))) + + def pretty(self) -> str: + return f"SRA {self.r}" + + +@dataclass +class SRA_HL(Insn): + def exec(self, cpu: CPU) -> None: + hl = cpu.deref_hl() + cpu.deref_hl_set((hl >> 1) | (hl & (1 << 7))) + + def pretty(self) -> str: + return "SRA (HL)" + + +@dataclass +class SRL_R(Insn): + r: R8 + + def exec(self, cpu: CPU) -> None: + r = cpu.get_reg8(self.r) + cpu.set_reg8(self.r, r >> 1) + + def pretty(self) -> str: + return f"SRL {self.r}" + + +@dataclass +class SRL_HL(Insn): + def exec(self, cpu: CPU) -> None: + hl = cpu.deref_hl() + cpu.deref_hl_set(hl >> 1) + + def pretty(self) -> str: + return "SRL (HL)" + + # TODO: Remaining rotate and shift instructions