GameBoy Emulator 1
Game Boy emulator core and tooling
Loading...
Searching...
No Matches
op_0C.cpp
1#include "../../../../../include/ProcessingUnit.hpp"
2#include "../../../../../include/opcodes.hpp"
3#include "../../../../../include/mmu.hpp"
4#include "../../../../../include/opcode_table.hpp"
5
6constexpr int machine_cycles = 4;
7#define totalMachineCycles(n) ((n) * machine_cycles)
8
9#define DUMMY(name) int name(ProcessingUnit&, MMU&) { return totalMachineCycles(1); }
10
11int op_ret_nz(ProcessingUnit& cpu, MMU& mmu) // 0xC0
12{
13 if (cpu.get_flag_z()) {
14 return totalMachineCycles(2);
15 }
16
17 const u16 sp = cpu.get_sp();
18 const u8 lo = mmu.read(sp);
19 const u8 hi = mmu.read(sp + 1);
20
21 cpu.set_sp(sp + 2);
22 cpu.set_pc(static_cast<u16>((hi << 8) | lo));
23
24 return totalMachineCycles(5);
25}
26
27int op_pop_bc(ProcessingUnit& cpu, MMU& mmu) // 0xC1
28{
29 const u16 sp = cpu.get_sp();
30 const u8 lo = mmu.read(sp);
31 const u8 hi = mmu.read(sp + 1);
32
33 cpu.reg(ProcessingUnit::Register::C) = lo;
34 cpu.reg(ProcessingUnit::Register::B) = hi;
35
36 cpu.set_sp(sp + 2);
37
38 return totalMachineCycles(3);
39}
40
41int op_jp_nz(ProcessingUnit& cpu, MMU& mmu) // 0xC2
42{
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);
46
47 if (!cpu.get_flag_z())
48 {
49 cpu.set_pc(addr);
50 return totalMachineCycles(4);
51 }
52
53 return totalMachineCycles(3);
54}
55
56int op_jp(ProcessingUnit& cpu, MMU& mmu) // 0xC3
57{
58 const u8 lo = mmu.read(cpu.inc_pc());
59 const u8 hi = mmu.read(cpu.inc_pc());
60
61 cpu.set_pc(static_cast<u16>((hi << 8) | lo));
62
63 return totalMachineCycles(4);
64}
65
66int op_call_nz(ProcessingUnit& cpu, MMU& mmu) // 0xC4
67{
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);
71
72 if (!cpu.get_flag_z())
73 {
74 const u16 pc = cpu.get_pc();
75 const u16 sp = cpu.get_sp();
76
77 mmu.write(sp - 1, static_cast<u8>(pc >> 8));
78 mmu.write(sp - 2, static_cast<u8>(pc & 0xFF));
79 cpu.set_sp(sp - 2);
80 cpu.set_pc(addr);
81
82 return totalMachineCycles(6);
83 }
84 return totalMachineCycles(3);
85}
86
87int op_push_bc(ProcessingUnit& cpu, MMU& mmu) // 0xC5
88{
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();
92
93 mmu.write(sp - 1, b);
94 mmu.write(sp - 2, c);
95 cpu.set_sp(sp - 2);
96
97 return totalMachineCycles(4);
98}
99
100int op_add_a_d8(ProcessingUnit& cpu, MMU& mmu) // 0xC6
101{
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);
105
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);
110
111 cpu.reg(ProcessingUnit::Register::A) = static_cast<u8>(result);
112
113 return totalMachineCycles(2);
114}
115
116int op_rst_00(ProcessingUnit& cpu, MMU& mmu) // 0xC7
117{
118 const u16 pc = cpu.get_pc();
119 const u16 sp = cpu.get_sp();
120
121 mmu.write(sp - 1, static_cast<u8>(pc >> 8));
122 mmu.write(sp - 2, static_cast<u8>(pc & 0xFF));
123 cpu.set_sp(sp - 2);
124 cpu.set_pc(0x0000);
125
126 return totalMachineCycles(4);
127}
128
129int op_ret_z(ProcessingUnit& cpu, MMU& mmu) // 0xC8
130{
131 if (!cpu.get_flag_z()) {
132 return totalMachineCycles(2);
133 }
134
135 const u16 sp = cpu.get_sp();
136 const u8 lo = mmu.read(sp);
137 const u8 hi = mmu.read(sp + 1);
138
139 cpu.set_sp(sp + 2);
140 cpu.set_pc(static_cast<u16>((hi << 8) | lo));
141
142 return totalMachineCycles(5);
143}
144
145int op_ret(ProcessingUnit& cpu, MMU& mmu) // 0xC9
146{
147 const u16 sp = cpu.get_sp();
148 const u8 lo = mmu.read(sp);
149 const u8 hi = mmu.read(sp + 1);
150
151 cpu.set_sp(sp + 2);
152 cpu.set_pc(static_cast<u16>((hi << 8) | lo));
153
154 return totalMachineCycles(4);
155}
156
157int op_jp_z(ProcessingUnit& cpu, MMU& mmu) // 0xCA
158{
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);
162
163 if (cpu.get_flag_z())
164 {
165 cpu.set_pc(addr);
166 return totalMachineCycles(4);
167 }
168
169 return totalMachineCycles(3);
170}
171
172int op_cb_prefix(ProcessingUnit& cpu , MMU& mmu) // 0xCB
173{
174 const u8 cb_opcode = mmu.read(cpu.inc_pc());
175
176 return cbInstructionTable[cb_opcode](cpu, mmu);
177}
178
179int op_call_z(ProcessingUnit& cpu, MMU& mmu) // 0xCC
180{
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);
184
185 if (cpu.get_flag_z())
186 {
187 const u16 pc = cpu.get_pc();
188 const u16 sp = cpu.get_sp();
189
190 mmu.write(sp - 1, static_cast<u8>(pc >> 8));
191 mmu.write(sp - 2, static_cast<u8>(pc & 0xFF));
192 cpu.set_sp(sp - 2);
193 cpu.set_pc(addr);
194
195 return totalMachineCycles(6);
196 }
197 return totalMachineCycles(3);
198}
199
200int op_call(ProcessingUnit& cpu, MMU& mmu) // 0xCD
201{
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);
205
206 const u16 pc = cpu.get_pc();
207 const u16 sp = cpu.get_sp();
208
209 mmu.write(sp - 1, static_cast<u8>(pc >> 8));
210 mmu.write(sp - 2, static_cast<u8>(pc & 0xFF));
211
212 cpu.set_sp(sp - 2);
213 cpu.set_pc(addr);
214
215 return totalMachineCycles(6);
216}
217
218int op_adc_a_d8(ProcessingUnit& cpu, MMU& mmu) // 0xCE
219{
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;
224
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);
229
230 cpu.reg(ProcessingUnit::Register::A) = static_cast<u8>(result);
231 return totalMachineCycles(2);
232}
233
234int op_rst_08(ProcessingUnit& cpu, MMU& mmu) // 0xCF
235{
236 const u16 pc = cpu.get_pc();
237 const u16 sp = cpu.get_sp();
238
239 mmu.write(sp - 1, static_cast<u8>(pc >> 8));
240 mmu.write(sp - 2, static_cast<u8>(pc & 0xFF));
241 cpu.set_sp(sp - 2);
242
243 cpu.set_pc(0x0008);
244
245 return totalMachineCycles(4);
246}
Definition mmu.hpp:12