GameBoy Emulator 1
Game Boy emulator core and tooling
Loading...
Searching...
No Matches
op_02.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_jr_nz(ProcessingUnit& cpu, MMU& mmu) // 0x20
11{
12 const int8_t offset = static_cast<int8_t>(mmu.read(cpu.inc_pc()));
13
14 if (!cpu.get_flag_z()) {
15 cpu.set_pc(static_cast<u16>(cpu.get_pc() + offset));
16 return totalMachineCycles(3);
17 }
18
19 return totalMachineCycles(2);
20}
21
22int op_ld_hl_d16(ProcessingUnit& cpu, MMU& mmu) // 0x21
23{
24 const u8 lo = mmu.read(cpu.inc_pc());
25 const u8 hi = mmu.read(cpu.inc_pc());
26
27 cpu.reg(ProcessingUnit::Register::H) = hi;
28 cpu.reg(ProcessingUnit::Register::L) = lo;
29
30 return totalMachineCycles(3);
31}
32
33int op_ld_hli_a(ProcessingUnit& cpu, MMU& mmu) // 0x22
34{
35 const u16 hl = cpu.get_hl();
36 mmu.write(hl, cpu.reg(ProcessingUnit::Register::A));
37
38 const u16 newValue = hl + 1;
39 cpu.reg(ProcessingUnit::Register::H) = static_cast<u8>((newValue >> 8) & 0xFF);
40 cpu.reg(ProcessingUnit::Register::L) = static_cast<u8>(newValue & 0xFF);
41
42 return totalMachineCycles(2);
43}
44
45int op_inc_hl(ProcessingUnit& cpu, MMU& mmu) // 0x23
46{
47 const u16 newValue = cpu.get_hl() + 1;
48 cpu.reg(ProcessingUnit::Register::H) = static_cast<u8>((newValue >> 8) & 0xFF);
49 cpu.reg(ProcessingUnit::Register::L) = static_cast<u8>(newValue & 0xFF);
50
51 return totalMachineCycles(2);
52}
53
54int op_inc_h(ProcessingUnit& cpu, MMU& mmu) // 0x24
55{
56 const u8 oldValue = cpu.reg(ProcessingUnit::Register::H);
57 const u8 newValue = oldValue + 1;
58 cpu.reg(ProcessingUnit::Register::H) = newValue;
59
60 cpu.setFlag(ProcessingUnit::Flag::Z, newValue == 0);
61 cpu.setFlag(ProcessingUnit::Flag::N, false);
62 cpu.setFlag(ProcessingUnit::Flag::H, (oldValue & 0x0F) == 0x0F);
63
64 return totalMachineCycles(1);
65}
66
67int op_dec_h(ProcessingUnit& cpu, MMU& mmu) // 0x25
68{
69 const u8 oldValue = cpu.reg(ProcessingUnit::Register::H);
70 const u8 newValue = oldValue - 1;
71 cpu.reg(ProcessingUnit::Register::H) = newValue;
72
73 cpu.setFlag(ProcessingUnit::Flag::Z, newValue == 0);
74 cpu.setFlag(ProcessingUnit::Flag::N, true);
75 cpu.setFlag(ProcessingUnit::Flag::H, (oldValue & 0x0F) == 0x00);
76
77 return totalMachineCycles(1);
78}
79
80int op_ld_h_d8(ProcessingUnit& cpu, MMU& mmu) // 0x26
81{
82 cpu.reg(ProcessingUnit::Register::H) = mmu.read(cpu.inc_pc());
83
84 return totalMachineCycles(2);
85}
86
87int op_daa(ProcessingUnit& cpu, MMU& mmu) // 0x27
88{
89 u16 a = cpu.reg(ProcessingUnit::Register::A);
90 bool c = cpu.get_flag_c();
91
92 if (!cpu.get_flag_n()) {
93 if (cpu.get_flag_h() || (a & 0x0F) > 0x09) {
94 a += 0x06;
95 }
96 if (c || a > 0x9F) {
97 a += 0x60;
98 c = true;
99 }
100 } else {
101 if (cpu.get_flag_h()) {
102 a = (a - 0x06) & 0xFF;
103 }
104 if (c) {
105 a = (a - 0x60) & 0xFF;
106 }
107 }
108
109 cpu.reg(ProcessingUnit::Register::A) = static_cast<u8>(a & 0xFF);
110
111 cpu.setFlag(ProcessingUnit::Flag::Z, cpu.reg(ProcessingUnit::Register::A) == 0);
112 cpu.setFlag(ProcessingUnit::Flag::H, false);
113 cpu.setFlag(ProcessingUnit::Flag::C, c);
114
115 return totalMachineCycles(1);
116}
117
118int op_jr_z(ProcessingUnit& cpu, MMU& mmu) // 0x28
119{
120 const int8_t offset = static_cast<int8_t>(mmu.read(cpu.inc_pc()));
121
122 if (cpu.get_flag_z()) {
123 cpu.set_pc(static_cast<u16>(cpu.get_pc() + offset));
124 return totalMachineCycles(3);
125 }
126
127 return totalMachineCycles(2);
128}
129
130int op_add_hl_hl(ProcessingUnit& cpu, MMU& mmu) // 0x29
131{
132 const u16 hl = cpu.get_hl();
133 const u32 sum = static_cast<u32>(hl) + hl;
134
135 cpu.reg(ProcessingUnit::Register::H) = static_cast<u8>((sum >> 8) & 0xFF);
136 cpu.reg(ProcessingUnit::Register::L) = static_cast<u8>(sum & 0xFF);
137
138 cpu.setFlag(ProcessingUnit::Flag::N, false);
139 cpu.setFlag(ProcessingUnit::Flag::H, ((hl & 0x0FFF) + (hl & 0x0FFF)) > 0x0FFF);
140 cpu.setFlag(ProcessingUnit::Flag::C, sum > 0xFFFF);
141
142 return totalMachineCycles(2);
143}
144
145int op_ld_a_hli(ProcessingUnit& cpu, MMU& mmu) // 0x2A
146{
147 const u16 hl = cpu.get_hl();
148 cpu.reg(ProcessingUnit::Register::A) = mmu.read(hl);
149
150 const u16 newValue = hl + 1;
151 cpu.reg(ProcessingUnit::Register::H) = static_cast<u8>((newValue >> 8) & 0xFF);
152 cpu.reg(ProcessingUnit::Register::L) = static_cast<u8>(newValue & 0xFF);
153
154 return totalMachineCycles(2);
155}
156
157int op_dec_hl(ProcessingUnit& cpu, MMU& mmu) // 0x2B
158{
159 const u16 newValue = cpu.get_hl() - 1;
160 cpu.reg(ProcessingUnit::Register::H) = static_cast<u8>((newValue >> 8) & 0xFF);
161 cpu.reg(ProcessingUnit::Register::L) = static_cast<u8>(newValue & 0xFF);
162
163 return totalMachineCycles(2);
164}
165
166int op_inc_l(ProcessingUnit& cpu, MMU& mmu) // 0x2C
167{
168 const u8 oldValue = cpu.reg(ProcessingUnit::Register::L);
169 const u8 newValue = oldValue + 1;
170 cpu.reg(ProcessingUnit::Register::L) = newValue;
171
172 cpu.setFlag(ProcessingUnit::Flag::Z, newValue == 0);
173 cpu.setFlag(ProcessingUnit::Flag::N, false);
174 cpu.setFlag(ProcessingUnit::Flag::H, (oldValue & 0x0F) == 0x0F);
175
176 return totalMachineCycles(1);
177}
178
179int op_dec_l(ProcessingUnit& cpu, MMU& mmu) // 0x2D
180{
181 const u8 oldValue = cpu.reg(ProcessingUnit::Register::L);
182 const u8 newValue = oldValue - 1;
183 cpu.reg(ProcessingUnit::Register::L) = newValue;
184
185 cpu.setFlag(ProcessingUnit::Flag::Z, newValue == 0);
186 cpu.setFlag(ProcessingUnit::Flag::N, true);
187 cpu.setFlag(ProcessingUnit::Flag::H, (oldValue & 0x0F) == 0x00);
188
189 return totalMachineCycles(1);
190}
191
192int op_ld_l_d8(ProcessingUnit& cpu, MMU& mmu) // 0x2E
193{
194 cpu.reg(ProcessingUnit::Register::L) = mmu.read(cpu.inc_pc());
195
196 return totalMachineCycles(2);
197}
198
199int op_cpl(ProcessingUnit& cpu, MMU& mmu) // 0x2F
200{
201 cpu.reg(ProcessingUnit::Register::A) = ~cpu.reg(ProcessingUnit::Register::A);
202
203 cpu.setFlag(ProcessingUnit::Flag::N, true);
204 cpu.setFlag(ProcessingUnit::Flag::H, true);
205
206 return totalMachineCycles(1);
207}
Definition mmu.hpp:12