GameBoy Emulator 1
Game Boy emulator core and tooling
Loading...
Searching...
No Matches
op_0D.cpp
1#include "../../../../../include/ProcessingUnit.hpp"
2#include "../../../../../include/opcodes.hpp"
3#include "../../../../../include/mmu.hpp"
4
5constexpr int machine_cycles = 4;
6#define totalMachineCycles(n) ((n) * machine_cycles)
7
8#define DUMMY(name) int name(ProcessingUnit&, MMU&) { return totalMachineCycles(1); }
9
10int op_ret_nc(ProcessingUnit& cpu, MMU& mmu) // 0xD0
11{
12 if (cpu.get_flag_c()) {
13 return totalMachineCycles(2);
14 }
15
16 const u16 sp = cpu.get_sp();
17 const u8 lo = mmu.read(sp);
18 const u8 hi = mmu.read(sp + 1);
19
20 cpu.set_sp(sp + 2);
21 cpu.set_pc(static_cast<u16>((hi << 8) | lo));
22
23 return totalMachineCycles(5);
24}
25
26int op_pop_de(ProcessingUnit& cpu, MMU& mmu) // 0xD1
27{
28 const u16 sp = cpu.get_sp();
29 const u8 lo = mmu.read(sp);
30 const u8 hi = mmu.read(sp + 1);
31
32 cpu.reg(ProcessingUnit::Register::E) = lo;
33 cpu.reg(ProcessingUnit::Register::D) = hi;
34 cpu.set_sp(sp + 2);
35
36 return totalMachineCycles(3);
37}
38
39int op_jp_nc(ProcessingUnit& cpu, MMU& mmu) // 0xD2
40{
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);
44
45 if (!cpu.get_flag_c())
46 {
47 cpu.set_pc(addr);
48 return totalMachineCycles(4);
49 }
50
51 return totalMachineCycles(3);
52}
53
54int op_illegal_d3(ProcessingUnit& cpu, MMU& mmu) // 0xD3
55{
56 throw std::runtime_error("Unimplemented opcode at PC: 0x" + std::to_string(cpu.last_pc));
57}
58
59int op_call_nc(ProcessingUnit& cpu, MMU& mmu) // 0xD4
60{
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);
64
65 if (!cpu.get_flag_c())
66 {
67 const u16 pc = cpu.get_pc();
68 const u16 sp = cpu.get_sp();
69
70 mmu.write(sp - 1, static_cast<u8>(pc >> 8));
71 mmu.write(sp - 2, static_cast<u8>(pc & 0xFF));
72 cpu.set_sp(sp - 2);
73 cpu.set_pc(addr);
74
75 return totalMachineCycles(6);
76 }
77
78 return totalMachineCycles(3);
79}
80
81int op_push_de(ProcessingUnit& cpu, MMU& mmu) // 0xD5
82{
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();
86
87 mmu.write(sp - 1, d);
88 mmu.write(sp - 2, e);
89 cpu.set_sp(sp - 2);
90
91 return totalMachineCycles(4);
92}
93
94int op_sub_d8(ProcessingUnit& cpu, MMU& mmu) // 0xD6
95{
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);
100
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);
105
106 cpu.reg(ProcessingUnit::Register::A) = static_cast<u8>(result);
107
108 return totalMachineCycles(2);
109}
110
111int op_rst_10(ProcessingUnit& cpu, MMU& mmu) // 0xD7
112{
113 const u16 pc = cpu.get_pc();
114
115 cpu.set_sp(cpu.get_sp() - 1);
116 mmu.write(cpu.get_sp(), (pc >> 8) & 0xFF);
117
118 cpu.set_sp(cpu.get_sp() - 1);
119 mmu.write(cpu.get_sp(), pc & 0xFF);
120
121 cpu.set_pc(0x10);
122
123 return totalMachineCycles(4);
124}
125
126int op_ret_c(ProcessingUnit& cpu, MMU& mmu) // 0xD8
127{
128 if (!cpu.get_flag_c()) {
129 return totalMachineCycles(2);
130 }
131
132 const u16 sp = cpu.get_sp();
133 const u8 lo = mmu.read(sp);
134 const u8 hi = mmu.read(sp + 1);
135
136 cpu.set_sp(sp + 2);
137 cpu.set_pc(static_cast<u16>((hi << 8) | lo));
138
139 return totalMachineCycles(5);
140}
141
142int op_reti(ProcessingUnit& cpu, MMU& mmu) // 0xD9
143{
144 const u16 sp = cpu.get_sp();
145 const u8 lo = mmu.read(sp);
146 const u8 hi = mmu.read(sp + 1);
147
148 cpu.set_sp(sp + 2);
149 cpu.set_pc(static_cast<u16>((hi << 8) | lo));
150 cpu.setIME(true);
151
152 return totalMachineCycles(4);
153}
154
155int op_jp_c(ProcessingUnit& cpu, MMU& mmu) // 0xDA
156{
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);
160
161 if (cpu.get_flag_c())
162 {
163 cpu.set_pc(addr);
164 return totalMachineCycles(4);
165 }
166
167 return totalMachineCycles(3);
168}
169
170int op_illegal_db(ProcessingUnit& cpu, MMU& mmu) // 0xDB
171{
172 throw std::runtime_error("Unimplemented opcode at PC: 0x" + std::to_string(cpu.last_pc));
173}
174
175int op_call_c(ProcessingUnit& cpu, MMU& mmu) // 0xDC
176{
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);
180
181 if (cpu.get_flag_c())
182 {
183 const u16 pc = cpu.get_pc();
184 const u16 sp = cpu.get_sp();
185
186 mmu.write(sp - 1, static_cast<u8>(pc >> 8));
187 mmu.write(sp - 2, static_cast<u8>(pc & 0xFF));
188 cpu.set_sp(sp - 2);
189 cpu.set_pc(addr);
190
191 return totalMachineCycles(6);
192 }
193
194 return totalMachineCycles(3);
195}
196
197int op_illegal_dd(ProcessingUnit& cpu, MMU& mmu) // 0xDD
198{
199 throw std::runtime_error("Unimplemented opcode at PC: 0x" + std::to_string(cpu.last_pc));
200}
201
202int op_sbc_a_d8(ProcessingUnit& cpu, MMU& mmu) // 0xDE
203{
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;
209
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);
214
215 cpu.reg(ProcessingUnit::Register::A) = static_cast<u8>(result);
216
217 return totalMachineCycles(2);
218}
219
220int op_rst_18(ProcessingUnit& cpu, MMU& mmu) // 0xDF
221{
222 const u16 pc = cpu.get_pc();
223
224 cpu.set_sp(cpu.get_sp() - 1);
225 mmu.write(cpu.get_sp(), (pc >> 8) & 0xFF);
226
227 cpu.set_sp(cpu.get_sp() - 1);
228 mmu.write(cpu.get_sp(), pc & 0xFF);
229
230 cpu.set_pc(0x18);
231
232 return totalMachineCycles(4);
233}
Definition mmu.hpp:12