1#include "../../../../../include/ProcessingUnit.hpp"
2#include "../../../../../include/opcodes.hpp"
3#include "../../../../../include/mmu.hpp"
4#include "../../../../../include/opcode_table.hpp"
6constexpr int machine_cycles = 4;
7#define totalMachineCycles(n) ((n) * machine_cycles)
9#define DUMMY(name) int name(ProcessingUnit&, MMU&) { return totalMachineCycles(1); }
13 if (cpu.get_flag_z()) {
14 return totalMachineCycles(2);
17 const u16 sp = cpu.get_sp();
18 const u8 lo = mmu.read(sp);
19 const u8 hi = mmu.read(sp + 1);
22 cpu.set_pc(
static_cast<u16
>((hi << 8) | lo));
24 return totalMachineCycles(5);
29 const u16 sp = cpu.get_sp();
30 const u8 lo = mmu.read(sp);
31 const u8 hi = mmu.read(sp + 1);
33 cpu.reg(ProcessingUnit::Register::C) = lo;
34 cpu.reg(ProcessingUnit::Register::B) = hi;
38 return totalMachineCycles(3);
43 const u8 lo = mmu.read(cpu.inc_pc());
44 const u8 hi = mmu.read(cpu.inc_pc());
45 const u16 addr =
static_cast<u16
>((hi << 8) | lo);
47 if (!cpu.get_flag_z())
50 return totalMachineCycles(4);
53 return totalMachineCycles(3);
58 const u8 lo = mmu.read(cpu.inc_pc());
59 const u8 hi = mmu.read(cpu.inc_pc());
61 cpu.set_pc(
static_cast<u16
>((hi << 8) | lo));
63 return totalMachineCycles(4);
68 const u8 lo = mmu.read(cpu.inc_pc());
69 const u8 hi = mmu.read(cpu.inc_pc());
70 const u16 addr =
static_cast<u16
>((hi << 8) | lo);
72 if (!cpu.get_flag_z())
74 const u16 pc = cpu.get_pc();
75 const u16 sp = cpu.get_sp();
77 mmu.write(sp - 1,
static_cast<u8
>(pc >> 8));
78 mmu.write(sp - 2,
static_cast<u8
>(pc & 0xFF));
82 return totalMachineCycles(6);
84 return totalMachineCycles(3);
89 const u8 b = cpu.reg(ProcessingUnit::Register::B);
90 const u8 c = cpu.reg(ProcessingUnit::Register::C);
91 const u16 sp = cpu.get_sp();
97 return totalMachineCycles(4);
102 const u8 a = cpu.reg(ProcessingUnit::Register::A);
103 const u8 d8 = mmu.read(cpu.inc_pc());
104 const u16 result =
static_cast<u16
>(a) +
static_cast<u16
>(d8);
106 cpu.setFlag(ProcessingUnit::Flag::Z, (result & 0xFF) == 0);
107 cpu.setFlag(ProcessingUnit::Flag::N,
false);
108 cpu.setFlag(ProcessingUnit::Flag::H, ((a & 0x0F) + (d8 & 0x0F)) > 0x0F);
109 cpu.setFlag(ProcessingUnit::Flag::C, result > 0xFF);
111 cpu.reg(ProcessingUnit::Register::A) =
static_cast<u8
>(result);
113 return totalMachineCycles(2);
118 const u16 pc = cpu.get_pc();
119 const u16 sp = cpu.get_sp();
121 mmu.write(sp - 1,
static_cast<u8
>(pc >> 8));
122 mmu.write(sp - 2,
static_cast<u8
>(pc & 0xFF));
126 return totalMachineCycles(4);
131 if (!cpu.get_flag_z()) {
132 return totalMachineCycles(2);
135 const u16 sp = cpu.get_sp();
136 const u8 lo = mmu.read(sp);
137 const u8 hi = mmu.read(sp + 1);
140 cpu.set_pc(
static_cast<u16
>((hi << 8) | lo));
142 return totalMachineCycles(5);
147 const u16 sp = cpu.get_sp();
148 const u8 lo = mmu.read(sp);
149 const u8 hi = mmu.read(sp + 1);
152 cpu.set_pc(
static_cast<u16
>((hi << 8) | lo));
154 return totalMachineCycles(4);
159 const u8 lo = mmu.read(cpu.inc_pc());
160 const u8 hi = mmu.read(cpu.inc_pc());
161 const u16 addr =
static_cast<u16
>((hi << 8) | lo);
163 if (cpu.get_flag_z())
166 return totalMachineCycles(4);
169 return totalMachineCycles(3);
174 const u8 cb_opcode = mmu.read(cpu.inc_pc());
176 return cbInstructionTable[cb_opcode](cpu, mmu);
181 const u8 lo = mmu.read(cpu.inc_pc());
182 const u8 hi = mmu.read(cpu.inc_pc());
183 const u16 addr =
static_cast<u16
>((hi << 8) | lo);
185 if (cpu.get_flag_z())
187 const u16 pc = cpu.get_pc();
188 const u16 sp = cpu.get_sp();
190 mmu.write(sp - 1,
static_cast<u8
>(pc >> 8));
191 mmu.write(sp - 2,
static_cast<u8
>(pc & 0xFF));
195 return totalMachineCycles(6);
197 return totalMachineCycles(3);
202 const u8 lo = mmu.read(cpu.inc_pc());
203 const u8 hi = mmu.read(cpu.inc_pc());
204 const u16 addr =
static_cast<u16
>((hi << 8) | lo);
206 const u16 pc = cpu.get_pc();
207 const u16 sp = cpu.get_sp();
209 mmu.write(sp - 1,
static_cast<u8
>(pc >> 8));
210 mmu.write(sp - 2,
static_cast<u8
>(pc & 0xFF));
215 return totalMachineCycles(6);
220 const u8 d8 = mmu.read(cpu.inc_pc());
221 const u8 a = cpu.reg(ProcessingUnit::Register::A);
222 const u8 c = cpu.get_flag_c() ? 1 : 0;
223 const u16 result = a + d8 + c;
225 cpu.setFlag(ProcessingUnit::Flag::Z, (result & 0xFF) == 0);
226 cpu.setFlag(ProcessingUnit::Flag::N,
false);
227 cpu.setFlag(ProcessingUnit::Flag::H, ((a & 0xF) + (d8 & 0xF) + c) > 0xF);
228 cpu.setFlag(ProcessingUnit::Flag::C, result > 0xFF);
230 cpu.reg(ProcessingUnit::Register::A) =
static_cast<u8
>(result);
231 return totalMachineCycles(2);
236 const u16 pc = cpu.get_pc();
237 const u16 sp = cpu.get_sp();
239 mmu.write(sp - 1,
static_cast<u8
>(pc >> 8));
240 mmu.write(sp - 2,
static_cast<u8
>(pc & 0xFF));
245 return totalMachineCycles(4);