GameBoy Emulator 1
Game Boy emulator core and tooling
Loading...
Searching...
No Matches
op_00.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_nop(ProcessingUnit &cpu, MMU &mmu) // 0x00
11{
12 return totalMachineCycles(1);
13}
14
15int op_ld_bc_d16(ProcessingUnit &cpu, MMU &mmu) // 0x01
16{
17 const u8 lo = mmu.read(cpu.inc_pc());
18 const u8 hi = mmu.read(cpu.inc_pc());
19
20 cpu.reg(ProcessingUnit::Register::B) = hi;
21 cpu.reg(ProcessingUnit::Register::C) = lo;
22
23 return totalMachineCycles(3);
24}
25
26int op_ld_bc_a(ProcessingUnit &cpu, MMU &mmu) // 0x02
27{
28 const u16 addr = cpu.get_bc(); // BC contains the target address
29 const u8 value = cpu.reg(ProcessingUnit::Register::A);
30
31 mmu.write(addr, value);
32
33 return totalMachineCycles(2);
34}
35
36int op_inc_bc(ProcessingUnit& cpu, MMU& mmu) // 0x03
37{
38 const u16 newValue = cpu.get_bc() + 1;
39
40 cpu.reg(ProcessingUnit::Register::B) = (newValue >> 8) & 0xFF;
41 cpu.reg(ProcessingUnit::Register::C) = newValue & 0xFF;
42
43 return totalMachineCycles(2);
44}
45
46int op_inc_b(ProcessingUnit& cpu, MMU& mmu) // 0x04
47{
48 const u8 oldValue = cpu.reg(ProcessingUnit::Register::B);
49 const u8 newValue = oldValue + 1;
50 cpu.reg(ProcessingUnit::Register::B) = newValue;
51 cpu.setFlag(ProcessingUnit::Flag::Z, newValue == 0);
52 cpu.setFlag(ProcessingUnit::Flag::N, false);
53 cpu.setFlag(ProcessingUnit::Flag::H, (oldValue & 0x0F) == 0x0F);
54 return totalMachineCycles(1);
55}
56
57int op_dec_b(ProcessingUnit& cpu, MMU& mmu) // 0x05
58{
59 const u8 oldValue = cpu.reg(ProcessingUnit::Register::B);
60 const u8 newValue = oldValue - 1;
61 cpu.reg(ProcessingUnit::Register::B) = newValue;
62 cpu.setFlag(ProcessingUnit::Flag::Z, newValue == 0);
63 cpu.setFlag(ProcessingUnit::Flag::N, true);
64 cpu.setFlag(ProcessingUnit::Flag::H, (oldValue & 0x0F) == 0x00);
65 return totalMachineCycles(1);
66}
67
68int op_ld_b_d8(ProcessingUnit& cpu, MMU& mmu) // 0x06
69{
70 const u8 newValue = mmu.read(cpu.inc_pc());
71
72 cpu.reg(ProcessingUnit::Register::B) = newValue;
73
74 return totalMachineCycles(2);
75}
76
77int op_rlca(ProcessingUnit& cpu, MMU& mmu) // 0x07
78{
79 const u8 a = cpu.reg(ProcessingUnit::Register::A);
80
81 const u8 carry = (a >> 7) & 1;
82 const u8 result = (a << 1) | carry;
83
84 cpu.reg(ProcessingUnit::Register::A) = result;
85
86 cpu.setFlag(ProcessingUnit::Flag::Z, false);
87 cpu.setFlag(ProcessingUnit::Flag::N, false);
88 cpu.setFlag(ProcessingUnit::Flag::H, false);
89 cpu.setFlag(ProcessingUnit::Flag::C, carry);
90
91 return totalMachineCycles(1);
92}
93
94int op_ld_a16_sp(ProcessingUnit& cpu, MMU& mmu) // 0x08
95{
96 const u8 lo = mmu.read(cpu.inc_pc());
97 const u8 hi = mmu.read(cpu.inc_pc());
98
99 const u16 addr = (hi << 8) | lo;
100
101 mmu.write(addr, cpu.get_sp() & 0xFF);
102 mmu.write(addr + 1, cpu.get_sp() >> 8);
103
104 return totalMachineCycles(5);
105}
106
107int op_add_hl_bc(ProcessingUnit& cpu, MMU& mmu) // 0x09
108{
109 const u16 hl = cpu.get_hl();
110 const u16 bc = cpu.get_bc();
111 const u32 sum = static_cast<u32>(hl) + bc;
112
113 cpu.reg(ProcessingUnit::Register::H) = static_cast<u8>((sum >> 8) & 0xFF);
114 cpu.reg(ProcessingUnit::Register::L) = static_cast<u8>(sum & 0xFF);
115
116 cpu.setFlag(ProcessingUnit::Flag::N, false);
117 cpu.setFlag(ProcessingUnit::Flag::H, ((hl & 0x0FFF) + (bc & 0x0FFF)) > 0x0FFF);
118 cpu.setFlag(ProcessingUnit::Flag::C, sum > 0xFFFF);
119
120 return totalMachineCycles(2);
121}
122
123int op_ld_a_bc(ProcessingUnit& cpu, MMU& mmu) // 0x0A
124{
125 const u16 addr = cpu.get_bc();
126 cpu.reg(ProcessingUnit::Register::A) = mmu.read(addr);
127
128 return totalMachineCycles(2);
129}
130
131int op_dec_bc(ProcessingUnit& cpu, MMU& mmu) // 0x0B
132{
133 u16 bc = cpu.get_bc();
134 bc--;
135
136 cpu.reg(ProcessingUnit::Register::B) = bc >> 8;
137 cpu.reg(ProcessingUnit::Register::C) = bc & 0xFF;
138
139 return totalMachineCycles(2);
140}
141
142int op_inc_c(ProcessingUnit& cpu, MMU& mmu) // 0x0C
143{
144 const u8 oldValue = cpu.reg(ProcessingUnit::Register::C);
145 const u8 newValue = oldValue + 1;
146 cpu.reg(ProcessingUnit::Register::C) = newValue;
147 cpu.setFlag(ProcessingUnit::Flag::Z, newValue == 0);
148 cpu.setFlag(ProcessingUnit::Flag::N, false);
149 cpu.setFlag(ProcessingUnit::Flag::H, (oldValue & 0x0F) == 0x0F);
150 return totalMachineCycles(1);
151}
152
153int op_dec_c(ProcessingUnit& cpu, MMU& mmu) // 0x0D
154{
155 const u8 oldValue = cpu.reg(ProcessingUnit::Register::C);
156 const u8 newValue = oldValue - 1;
157 cpu.reg(ProcessingUnit::Register::C) = 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);
161 return totalMachineCycles(1);
162}
163int op_ld_c_d8(ProcessingUnit& cpu, MMU& mmu) // 0x0E
164{
165 const u8 newValue = mmu.read(cpu.inc_pc());
166 cpu.reg(ProcessingUnit::Register::C) = newValue;
167
168 return totalMachineCycles(2);
169}
170
171int op_rrca(ProcessingUnit& cpu, MMU& mmu) // 0x0F
172{
173 const u8 a = cpu.reg(ProcessingUnit::Register::A);
174
175 const u8 carry = a & 1;
176 const u8 result = (a >> 1) | (carry << 7);
177
178 cpu.reg(ProcessingUnit::Register::A) = result;
179
180 cpu.setFlag(ProcessingUnit::Flag::Z, false);
181 cpu.setFlag(ProcessingUnit::Flag::N, false);
182 cpu.setFlag(ProcessingUnit::Flag::H, false);
183 cpu.setFlag(ProcessingUnit::Flag::C, carry);
184
185 return totalMachineCycles(1);
186}
187
188
189
190
191
192
193
194
Definition mmu.hpp:12