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_z()) {
15 cpu.set_pc(
static_cast<u16
>(cpu.get_pc() + offset));
16 return totalMachineCycles(3);
19 return totalMachineCycles(2);
24 const u8 lo = mmu.read(cpu.inc_pc());
25 const u8 hi = mmu.read(cpu.inc_pc());
27 cpu.reg(ProcessingUnit::Register::H) = hi;
28 cpu.reg(ProcessingUnit::Register::L) = lo;
30 return totalMachineCycles(3);
35 const u16 hl = cpu.get_hl();
36 mmu.write(hl, cpu.reg(ProcessingUnit::Register::A));
38 const u16 newValue = hl + 1;
39 cpu.reg(ProcessingUnit::Register::H) =
static_cast<u8
>((newValue >> 8) & 0xFF);
40 cpu.reg(ProcessingUnit::Register::L) =
static_cast<u8
>(newValue & 0xFF);
42 return totalMachineCycles(2);
47 const u16 newValue = cpu.get_hl() + 1;
48 cpu.reg(ProcessingUnit::Register::H) =
static_cast<u8
>((newValue >> 8) & 0xFF);
49 cpu.reg(ProcessingUnit::Register::L) =
static_cast<u8
>(newValue & 0xFF);
51 return totalMachineCycles(2);
56 const u8 oldValue = cpu.reg(ProcessingUnit::Register::H);
57 const u8 newValue = oldValue + 1;
58 cpu.reg(ProcessingUnit::Register::H) = newValue;
60 cpu.setFlag(ProcessingUnit::Flag::Z, newValue == 0);
61 cpu.setFlag(ProcessingUnit::Flag::N,
false);
62 cpu.setFlag(ProcessingUnit::Flag::H, (oldValue & 0x0F) == 0x0F);
64 return totalMachineCycles(1);
69 const u8 oldValue = cpu.reg(ProcessingUnit::Register::H);
70 const u8 newValue = oldValue - 1;
71 cpu.reg(ProcessingUnit::Register::H) = newValue;
73 cpu.setFlag(ProcessingUnit::Flag::Z, newValue == 0);
74 cpu.setFlag(ProcessingUnit::Flag::N,
true);
75 cpu.setFlag(ProcessingUnit::Flag::H, (oldValue & 0x0F) == 0x00);
77 return totalMachineCycles(1);
82 cpu.reg(ProcessingUnit::Register::H) = mmu.read(cpu.inc_pc());
84 return totalMachineCycles(2);
89 u16 a = cpu.reg(ProcessingUnit::Register::A);
90 bool c = cpu.get_flag_c();
92 if (!cpu.get_flag_n()) {
93 if (cpu.get_flag_h() || (a & 0x0F) > 0x09) {
101 if (cpu.get_flag_h()) {
102 a = (a - 0x06) & 0xFF;
105 a = (a - 0x60) & 0xFF;
109 cpu.reg(ProcessingUnit::Register::A) =
static_cast<u8
>(a & 0xFF);
111 cpu.setFlag(ProcessingUnit::Flag::Z, cpu.reg(ProcessingUnit::Register::A) == 0);
112 cpu.setFlag(ProcessingUnit::Flag::H,
false);
113 cpu.setFlag(ProcessingUnit::Flag::C, c);
115 return totalMachineCycles(1);
120 const int8_t offset =
static_cast<int8_t
>(mmu.read(cpu.inc_pc()));
122 if (cpu.get_flag_z()) {
123 cpu.set_pc(
static_cast<u16
>(cpu.get_pc() + offset));
124 return totalMachineCycles(3);
127 return totalMachineCycles(2);
132 const u16 hl = cpu.get_hl();
133 const u32 sum =
static_cast<u32
>(hl) + hl;
135 cpu.reg(ProcessingUnit::Register::H) =
static_cast<u8
>((sum >> 8) & 0xFF);
136 cpu.reg(ProcessingUnit::Register::L) =
static_cast<u8
>(sum & 0xFF);
138 cpu.setFlag(ProcessingUnit::Flag::N,
false);
139 cpu.setFlag(ProcessingUnit::Flag::H, ((hl & 0x0FFF) + (hl & 0x0FFF)) > 0x0FFF);
140 cpu.setFlag(ProcessingUnit::Flag::C, sum > 0xFFFF);
142 return totalMachineCycles(2);
147 const u16 hl = cpu.get_hl();
148 cpu.reg(ProcessingUnit::Register::A) = mmu.read(hl);
150 const u16 newValue = hl + 1;
151 cpu.reg(ProcessingUnit::Register::H) =
static_cast<u8
>((newValue >> 8) & 0xFF);
152 cpu.reg(ProcessingUnit::Register::L) =
static_cast<u8
>(newValue & 0xFF);
154 return totalMachineCycles(2);
159 const u16 newValue = cpu.get_hl() - 1;
160 cpu.reg(ProcessingUnit::Register::H) =
static_cast<u8
>((newValue >> 8) & 0xFF);
161 cpu.reg(ProcessingUnit::Register::L) =
static_cast<u8
>(newValue & 0xFF);
163 return totalMachineCycles(2);
168 const u8 oldValue = cpu.reg(ProcessingUnit::Register::L);
169 const u8 newValue = oldValue + 1;
170 cpu.reg(ProcessingUnit::Register::L) = newValue;
172 cpu.setFlag(ProcessingUnit::Flag::Z, newValue == 0);
173 cpu.setFlag(ProcessingUnit::Flag::N,
false);
174 cpu.setFlag(ProcessingUnit::Flag::H, (oldValue & 0x0F) == 0x0F);
176 return totalMachineCycles(1);
181 const u8 oldValue = cpu.reg(ProcessingUnit::Register::L);
182 const u8 newValue = oldValue - 1;
183 cpu.reg(ProcessingUnit::Register::L) = newValue;
185 cpu.setFlag(ProcessingUnit::Flag::Z, newValue == 0);
186 cpu.setFlag(ProcessingUnit::Flag::N,
true);
187 cpu.setFlag(ProcessingUnit::Flag::H, (oldValue & 0x0F) == 0x00);
189 return totalMachineCycles(1);
194 cpu.reg(ProcessingUnit::Register::L) = mmu.read(cpu.inc_pc());
196 return totalMachineCycles(2);
201 cpu.reg(ProcessingUnit::Register::A) = ~cpu.reg(ProcessingUnit::Register::A);
203 cpu.setFlag(ProcessingUnit::Flag::N,
true);
204 cpu.setFlag(ProcessingUnit::Flag::H,
true);
206 return totalMachineCycles(1);