1#include "../../../../../include/ProcessingUnit.hpp"
2#include "../../../../../include/opcodes.hpp"
3#include "../../../../../include/mmu.hpp"
5constexpr int machine_cycles = 4;
6#define totalMachineCycles(n) ((n) * machine_cycles)
8#define DUMMY(name) int name(ProcessingUnit&, MMU&) { return totalMachineCycles(1); }
12 const int8_t offset =
static_cast<int8_t
>(mmu.read(cpu.inc_pc()));
14 if (!cpu.get_flag_c()) {
15 cpu.set_pc(
static_cast<u16
>(cpu.get_pc() + offset));
16 return totalMachineCycles(3);
19 return totalMachineCycles(2);
23 const u8 lo = mmu.read(cpu.inc_pc());
24 const u8 hi = mmu.read(cpu.inc_pc());
25 cpu.set_sp(
static_cast<u16
>((hi << 8) | lo));
27 return totalMachineCycles(3);
31 const u16 hl = cpu.get_hl();
32 mmu.write(hl, cpu.reg(ProcessingUnit::Register::A));
34 const u16 newValue = hl - 1;
35 cpu.reg(ProcessingUnit::Register::H) =
static_cast<u8
>((newValue >> 8) & 0xFF);
36 cpu.reg(ProcessingUnit::Register::L) =
static_cast<u8
>(newValue & 0xFF);
38 return totalMachineCycles(2);
42 cpu.set_sp(cpu.get_sp() + 1);
44 return totalMachineCycles(2);
48 const u16 addr = cpu.get_hl();
49 const u8 oldValue = mmu.read(addr);
50 const u8 newValue = oldValue + 1;
51 mmu.write(addr, newValue);
53 cpu.setFlag(ProcessingUnit::Flag::Z, newValue == 0);
54 cpu.setFlag(ProcessingUnit::Flag::N,
false);
55 cpu.setFlag(ProcessingUnit::Flag::H, (oldValue & 0x0F) == 0x0F);
57 return totalMachineCycles(3);
61 const u16 addr = cpu.get_hl();
62 const u8 oldValue = mmu.read(addr);
63 const u8 newValue = oldValue - 1;
64 mmu.write(addr, newValue);
66 cpu.setFlag(ProcessingUnit::Flag::Z, newValue == 0);
67 cpu.setFlag(ProcessingUnit::Flag::N,
true);
68 cpu.setFlag(ProcessingUnit::Flag::H, (oldValue & 0x0F) == 0x00);
70 return totalMachineCycles(3);
74 mmu.write(cpu.get_hl(), mmu.read(cpu.inc_pc()));
76 return totalMachineCycles(3);
80 cpu.setFlag(ProcessingUnit::Flag::N,
false);
81 cpu.setFlag(ProcessingUnit::Flag::H,
false);
82 cpu.setFlag(ProcessingUnit::Flag::C,
true);
84 return totalMachineCycles(1);
88 const int8_t offset =
static_cast<int8_t
>(mmu.read(cpu.inc_pc()));
90 if (cpu.get_flag_c()) {
91 cpu.set_pc(
static_cast<u16
>(cpu.get_pc() + offset));
92 return totalMachineCycles(3);
95 return totalMachineCycles(2);
99 const u16 hl = cpu.get_hl();
100 const u16 sp = cpu.get_sp();
101 const u32 sum =
static_cast<u32
>(hl) + sp;
103 cpu.reg(ProcessingUnit::Register::H) =
static_cast<u8
>((sum >> 8) & 0xFF);
104 cpu.reg(ProcessingUnit::Register::L) =
static_cast<u8
>(sum & 0xFF);
106 cpu.setFlag(ProcessingUnit::Flag::N,
false);
107 cpu.setFlag(ProcessingUnit::Flag::H, ((hl & 0x0FFF) + (sp & 0x0FFF)) > 0x0FFF);
108 cpu.setFlag(ProcessingUnit::Flag::C, sum > 0xFFFF);
110 return totalMachineCycles(2);
114 const u16 hl = cpu.get_hl();
115 cpu.reg(ProcessingUnit::Register::A) = mmu.read(hl);
117 const u16 newValue = hl - 1;
118 cpu.reg(ProcessingUnit::Register::H) =
static_cast<u8
>((newValue >> 8) & 0xFF);
119 cpu.reg(ProcessingUnit::Register::L) =
static_cast<u8
>(newValue & 0xFF);
121 return totalMachineCycles(2);
125 cpu.set_sp(cpu.get_sp() - 1);
127 return totalMachineCycles(2);
131 const u8 oldValue = cpu.reg(ProcessingUnit::Register::A);
132 const u8 newValue = oldValue + 1;
133 cpu.reg(ProcessingUnit::Register::A) = newValue;
135 cpu.setFlag(ProcessingUnit::Flag::Z, newValue == 0);
136 cpu.setFlag(ProcessingUnit::Flag::N,
false);
137 cpu.setFlag(ProcessingUnit::Flag::H, (oldValue & 0x0F) == 0x0F);
139 return totalMachineCycles(1);
143 const u8 oldValue = cpu.reg(ProcessingUnit::Register::A);
144 const u8 newValue = oldValue - 1;
145 cpu.reg(ProcessingUnit::Register::A) = newValue;
147 cpu.setFlag(ProcessingUnit::Flag::Z, newValue == 0);
148 cpu.setFlag(ProcessingUnit::Flag::N,
true);
149 cpu.setFlag(ProcessingUnit::Flag::H, (oldValue & 0x0F) == 0x00);
151 return totalMachineCycles(1);
155 cpu.reg(ProcessingUnit::Register::A) = mmu.read(cpu.inc_pc());
157 return totalMachineCycles(2);
161 cpu.setFlag(ProcessingUnit::Flag::N,
false);
162 cpu.setFlag(ProcessingUnit::Flag::H,
false);
163 cpu.setFlag(ProcessingUnit::Flag::C, !cpu.get_flag_c());
165 return totalMachineCycles(1);