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); }
13 return totalMachineCycles(1);
18 const u8 lo = mmu.read(cpu.inc_pc());
19 const u8 hi = mmu.read(cpu.inc_pc());
21 cpu.reg(ProcessingUnit::Register::D) = hi;
22 cpu.reg(ProcessingUnit::Register::E) = lo;
24 return totalMachineCycles(3);
29 const u16 addr = cpu.get_de();
30 const u8 value = cpu.reg(ProcessingUnit::Register::A);
32 mmu.write(addr, value);
34 return totalMachineCycles(2);
39 const u16 newValue = cpu.get_de() + 1;
41 cpu.reg(ProcessingUnit::Register::D) = (newValue >> 8) & 0xFF;
42 cpu.reg(ProcessingUnit::Register::E) = newValue & 0xFF;
44 return totalMachineCycles(2);
49 const u8 oldValue = cpu.reg(ProcessingUnit::Register::D);
50 const u8 newValue = oldValue + 1;
51 cpu.reg(ProcessingUnit::Register::D) = newValue;
52 cpu.setFlag(ProcessingUnit::Flag::Z, newValue == 0);
53 cpu.setFlag(ProcessingUnit::Flag::N,
false);
54 cpu.setFlag(ProcessingUnit::Flag::H, (oldValue & 0x0F) == 0x0F);
55 return totalMachineCycles(1);
60 const u8 oldValue = cpu.reg(ProcessingUnit::Register::D);
61 const u8 newValue = oldValue - 1;
62 cpu.reg(ProcessingUnit::Register::D) = newValue;
63 cpu.setFlag(ProcessingUnit::Flag::Z, newValue == 0);
64 cpu.setFlag(ProcessingUnit::Flag::N,
true);
65 cpu.setFlag(ProcessingUnit::Flag::H, (oldValue & 0x0F) == 0x00);
66 return totalMachineCycles(1);
71 const u8 newValue = mmu.read(cpu.inc_pc());
73 cpu.reg(ProcessingUnit::Register::D) = newValue;
75 return totalMachineCycles(2);
80 const u8 a = cpu.reg(ProcessingUnit::Register::A);
81 const bool carryIn = cpu.get_flag_c();
83 const u8 carryOut = (a >> 7) & 1;
84 const u8 result =
static_cast<u8
>((a << 1) | (carryIn ? 1 : 0));
86 cpu.reg(ProcessingUnit::Register::A) = result;
88 cpu.setFlag(ProcessingUnit::Flag::Z,
false);
89 cpu.setFlag(ProcessingUnit::Flag::N,
false);
90 cpu.setFlag(ProcessingUnit::Flag::H,
false);
91 cpu.setFlag(ProcessingUnit::Flag::C, carryOut);
93 return totalMachineCycles(1);
98 const int8_t offset =
static_cast<int8_t
>(mmu.read(cpu.inc_pc()));
99 const u16 target =
static_cast<u16
>(cpu.get_pc() + offset);
103 return totalMachineCycles(3);
108 const u16 hl = cpu.get_hl();
109 const u16 de = cpu.get_de();
110 const u32 sum =
static_cast<u32
>(hl) + de;
112 cpu.reg(ProcessingUnit::Register::H) =
static_cast<u8
>((sum >> 8) & 0xFF);
113 cpu.reg(ProcessingUnit::Register::L) =
static_cast<u8
>(sum & 0xFF);
115 cpu.setFlag(ProcessingUnit::Flag::N,
false);
116 cpu.setFlag(ProcessingUnit::Flag::H, ((hl & 0x0FFF) + (de & 0x0FFF)) > 0x0FFF);
117 cpu.setFlag(ProcessingUnit::Flag::C, sum > 0xFFFF);
119 return totalMachineCycles(2);
124 cpu.reg(ProcessingUnit::Register::A) = mmu.read(cpu.get_de());
126 return totalMachineCycles(2);
131 const u16 newValue = cpu.get_de() - 1;
133 cpu.reg(ProcessingUnit::Register::D) =
static_cast<u8
>((newValue >> 8) & 0xFF);
134 cpu.reg(ProcessingUnit::Register::E) =
static_cast<u8
>(newValue & 0xFF);
136 return totalMachineCycles(2);
141 const u8 oldValue = cpu.reg(ProcessingUnit::Register::E);
142 const u8 newValue = oldValue + 1;
143 cpu.reg(ProcessingUnit::Register::E) = newValue;
145 cpu.setFlag(ProcessingUnit::Flag::Z, newValue == 0);
146 cpu.setFlag(ProcessingUnit::Flag::N,
false);
147 cpu.setFlag(ProcessingUnit::Flag::H, (oldValue & 0x0F) == 0x0F);
149 return totalMachineCycles(1);
154 const u8 oldValue = cpu.reg(ProcessingUnit::Register::E);
155 const u8 newValue = oldValue - 1;
156 cpu.reg(ProcessingUnit::Register::E) = newValue;
158 cpu.setFlag(ProcessingUnit::Flag::Z, newValue == 0);
159 cpu.setFlag(ProcessingUnit::Flag::N,
true);
160 cpu.setFlag(ProcessingUnit::Flag::H, (oldValue & 0x0F) == 0x00);
162 return totalMachineCycles(1);
167 cpu.reg(ProcessingUnit::Register::E) = mmu.read(cpu.inc_pc());
169 return totalMachineCycles(2);
174 const u8 a = cpu.reg(ProcessingUnit::Register::A);
175 const bool carryIn = cpu.get_flag_c();
177 const u8 carryOut = a & 1;
178 const u8 result =
static_cast<u8
>((a >> 1) | (carryIn ? 0x80 : 0x00));
180 cpu.reg(ProcessingUnit::Register::A) = result;
182 cpu.setFlag(ProcessingUnit::Flag::Z,
false);
183 cpu.setFlag(ProcessingUnit::Flag::N,
false);
184 cpu.setFlag(ProcessingUnit::Flag::H,
false);
185 cpu.setFlag(ProcessingUnit::Flag::C, carryOut);
187 return totalMachineCycles(1);