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 if (cpu.get_flag_c()) {
13 return totalMachineCycles(2);
16 const u16 sp = cpu.get_sp();
17 const u8 lo = mmu.read(sp);
18 const u8 hi = mmu.read(sp + 1);
21 cpu.set_pc(
static_cast<u16
>((hi << 8) | lo));
23 return totalMachineCycles(5);
28 const u16 sp = cpu.get_sp();
29 const u8 lo = mmu.read(sp);
30 const u8 hi = mmu.read(sp + 1);
32 cpu.reg(ProcessingUnit::Register::E) = lo;
33 cpu.reg(ProcessingUnit::Register::D) = hi;
36 return totalMachineCycles(3);
41 const u8 lo = mmu.read(cpu.inc_pc());
42 const u8 hi = mmu.read(cpu.inc_pc());
43 const u16 addr =
static_cast<u16
>((hi << 8) | lo);
45 if (!cpu.get_flag_c())
48 return totalMachineCycles(4);
51 return totalMachineCycles(3);
56 throw std::runtime_error(
"Unimplemented opcode at PC: 0x" + std::to_string(cpu.last_pc));
61 const u8 lo = mmu.read(cpu.inc_pc());
62 const u8 hi = mmu.read(cpu.inc_pc());
63 const u16 addr =
static_cast<u16
>((hi << 8) | lo);
65 if (!cpu.get_flag_c())
67 const u16 pc = cpu.get_pc();
68 const u16 sp = cpu.get_sp();
70 mmu.write(sp - 1,
static_cast<u8
>(pc >> 8));
71 mmu.write(sp - 2,
static_cast<u8
>(pc & 0xFF));
75 return totalMachineCycles(6);
78 return totalMachineCycles(3);
83 const u8 d = cpu.reg(ProcessingUnit::Register::D);
84 const u8 e = cpu.reg(ProcessingUnit::Register::E);
85 const u16 sp = cpu.get_sp();
91 return totalMachineCycles(4);
96 const u8 a = cpu.reg(ProcessingUnit::Register::A);
97 const u8 d8 = mmu.read(cpu.inc_pc());
98 const int result = a - d8;
99 const int half_carry = (a & 0x0F) - (d8 & 0x0F);
101 cpu.setFlag(ProcessingUnit::Flag::Z, (result & 0xFF) == 0);
102 cpu.setFlag(ProcessingUnit::Flag::N,
true);
103 cpu.setFlag(ProcessingUnit::Flag::H, half_carry < 0);
104 cpu.setFlag(ProcessingUnit::Flag::C, result < 0);
106 cpu.reg(ProcessingUnit::Register::A) =
static_cast<u8
>(result);
108 return totalMachineCycles(2);
113 const u16 pc = cpu.get_pc();
115 cpu.set_sp(cpu.get_sp() - 1);
116 mmu.write(cpu.get_sp(), (pc >> 8) & 0xFF);
118 cpu.set_sp(cpu.get_sp() - 1);
119 mmu.write(cpu.get_sp(), pc & 0xFF);
123 return totalMachineCycles(4);
128 if (!cpu.get_flag_c()) {
129 return totalMachineCycles(2);
132 const u16 sp = cpu.get_sp();
133 const u8 lo = mmu.read(sp);
134 const u8 hi = mmu.read(sp + 1);
137 cpu.set_pc(
static_cast<u16
>((hi << 8) | lo));
139 return totalMachineCycles(5);
144 const u16 sp = cpu.get_sp();
145 const u8 lo = mmu.read(sp);
146 const u8 hi = mmu.read(sp + 1);
149 cpu.set_pc(
static_cast<u16
>((hi << 8) | lo));
152 return totalMachineCycles(4);
157 const u8 lo = mmu.read(cpu.inc_pc());
158 const u8 hi = mmu.read(cpu.inc_pc());
159 const u16 addr =
static_cast<u16
>((hi << 8) | lo);
161 if (cpu.get_flag_c())
164 return totalMachineCycles(4);
167 return totalMachineCycles(3);
172 throw std::runtime_error(
"Unimplemented opcode at PC: 0x" + std::to_string(cpu.last_pc));
177 const u8 lo = mmu.read(cpu.inc_pc());
178 const u8 hi = mmu.read(cpu.inc_pc());
179 const u16 addr =
static_cast<u16
>((hi << 8) | lo);
181 if (cpu.get_flag_c())
183 const u16 pc = cpu.get_pc();
184 const u16 sp = cpu.get_sp();
186 mmu.write(sp - 1,
static_cast<u8
>(pc >> 8));
187 mmu.write(sp - 2,
static_cast<u8
>(pc & 0xFF));
191 return totalMachineCycles(6);
194 return totalMachineCycles(3);
199 throw std::runtime_error(
"Unimplemented opcode at PC: 0x" + std::to_string(cpu.last_pc));
204 const u8 a = cpu.reg(ProcessingUnit::Register::A);
205 const u8 d8 = mmu.read(cpu.inc_pc());
206 const u8 carry = cpu.get_flag_c() ? 1 : 0;
207 const int result = a - d8 - carry;
208 const int half_carry = (a & 0x0F) - (d8 & 0x0F) - carry;
210 cpu.setFlag(ProcessingUnit::Flag::Z, (result & 0xFF) == 0);
211 cpu.setFlag(ProcessingUnit::Flag::N,
true);
212 cpu.setFlag(ProcessingUnit::Flag::H, half_carry < 0);
213 cpu.setFlag(ProcessingUnit::Flag::C, result < 0);
215 cpu.reg(ProcessingUnit::Register::A) =
static_cast<u8
>(result);
217 return totalMachineCycles(2);
222 const u16 pc = cpu.get_pc();
224 cpu.set_sp(cpu.get_sp() - 1);
225 mmu.write(cpu.get_sp(), (pc >> 8) & 0xFF);
227 cpu.set_sp(cpu.get_sp() - 1);
228 mmu.write(cpu.get_sp(), pc & 0xFF);
232 return totalMachineCycles(4);