GameBoy Emulator 1
Game Boy emulator core and tooling
Loading...
Searching...
No Matches
op_03.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_nc(ProcessingUnit& cpu, MMU& mmu) // 0x30
11{
12 const int8_t offset = static_cast<int8_t>(mmu.read(cpu.inc_pc()));
13
14 if (!cpu.get_flag_c()) {
15 cpu.set_pc(static_cast<u16>(cpu.get_pc() + offset));
16 return totalMachineCycles(3);
17 }
18
19 return totalMachineCycles(2);
20}
21int op_ld_sp_d16(ProcessingUnit& cpu, MMU& mmu) // 0x31
22{
23 const u8 lo = mmu.read(cpu.inc_pc());
24 const u8 hi = mmu.read(cpu.inc_pc());
25 cpu.set_sp(static_cast<u16>((hi << 8) | lo));
26
27 return totalMachineCycles(3);
28}
29int op_ld_hld_a(ProcessingUnit& cpu, MMU& mmu) // 0x32
30{
31 const u16 hl = cpu.get_hl();
32 mmu.write(hl, cpu.reg(ProcessingUnit::Register::A));
33
34 const u16 newValue = hl - 1;
35 cpu.reg(ProcessingUnit::Register::H) = static_cast<u8>((newValue >> 8) & 0xFF);
36 cpu.reg(ProcessingUnit::Register::L) = static_cast<u8>(newValue & 0xFF);
37
38 return totalMachineCycles(2);
39}
40int op_inc_sp(ProcessingUnit& cpu, MMU& mmu) // 0x33
41{
42 cpu.set_sp(cpu.get_sp() + 1);
43
44 return totalMachineCycles(2);
45}
46int op_inc_hl_ptr(ProcessingUnit& cpu, MMU& mmu) // 0x34
47{
48 const u16 addr = cpu.get_hl();
49 const u8 oldValue = mmu.read(addr);
50 const u8 newValue = oldValue + 1;
51 mmu.write(addr, newValue);
52
53 cpu.setFlag(ProcessingUnit::Flag::Z, newValue == 0);
54 cpu.setFlag(ProcessingUnit::Flag::N, false);
55 cpu.setFlag(ProcessingUnit::Flag::H, (oldValue & 0x0F) == 0x0F);
56
57 return totalMachineCycles(3);
58}
59int op_dec_hl_ptr(ProcessingUnit& cpu, MMU& mmu) // 0x35
60{
61 const u16 addr = cpu.get_hl();
62 const u8 oldValue = mmu.read(addr);
63 const u8 newValue = oldValue - 1;
64 mmu.write(addr, newValue);
65
66 cpu.setFlag(ProcessingUnit::Flag::Z, newValue == 0);
67 cpu.setFlag(ProcessingUnit::Flag::N, true);
68 cpu.setFlag(ProcessingUnit::Flag::H, (oldValue & 0x0F) == 0x00);
69
70 return totalMachineCycles(3);
71}
72int op_ld_hl_d8(ProcessingUnit& cpu, MMU& mmu) // 0x36
73{
74 mmu.write(cpu.get_hl(), mmu.read(cpu.inc_pc()));
75
76 return totalMachineCycles(3);
77}
78int op_scf(ProcessingUnit& cpu, MMU& mmu) // 0x37
79{
80 cpu.setFlag(ProcessingUnit::Flag::N, false);
81 cpu.setFlag(ProcessingUnit::Flag::H, false);
82 cpu.setFlag(ProcessingUnit::Flag::C, true);
83
84 return totalMachineCycles(1);
85}
86int op_jr_c(ProcessingUnit& cpu, MMU& mmu) // 0x38
87{
88 const int8_t offset = static_cast<int8_t>(mmu.read(cpu.inc_pc()));
89
90 if (cpu.get_flag_c()) {
91 cpu.set_pc(static_cast<u16>(cpu.get_pc() + offset));
92 return totalMachineCycles(3);
93 }
94
95 return totalMachineCycles(2);
96}
97int op_add_hl_sp(ProcessingUnit& cpu, MMU& mmu) // 0x39
98{
99 const u16 hl = cpu.get_hl();
100 const u16 sp = cpu.get_sp();
101 const u32 sum = static_cast<u32>(hl) + sp;
102
103 cpu.reg(ProcessingUnit::Register::H) = static_cast<u8>((sum >> 8) & 0xFF);
104 cpu.reg(ProcessingUnit::Register::L) = static_cast<u8>(sum & 0xFF);
105
106 cpu.setFlag(ProcessingUnit::Flag::N, false);
107 cpu.setFlag(ProcessingUnit::Flag::H, ((hl & 0x0FFF) + (sp & 0x0FFF)) > 0x0FFF);
108 cpu.setFlag(ProcessingUnit::Flag::C, sum > 0xFFFF);
109
110 return totalMachineCycles(2);
111}
112int op_ld_a_hld(ProcessingUnit& cpu, MMU& mmu) // 0x3A
113{
114 const u16 hl = cpu.get_hl();
115 cpu.reg(ProcessingUnit::Register::A) = mmu.read(hl);
116
117 const u16 newValue = hl - 1;
118 cpu.reg(ProcessingUnit::Register::H) = static_cast<u8>((newValue >> 8) & 0xFF);
119 cpu.reg(ProcessingUnit::Register::L) = static_cast<u8>(newValue & 0xFF);
120
121 return totalMachineCycles(2);
122}
123int op_dec_sp(ProcessingUnit& cpu, MMU& mmu) // 0x3B
124{
125 cpu.set_sp(cpu.get_sp() - 1);
126
127 return totalMachineCycles(2);
128}
129int op_inc_a(ProcessingUnit& cpu, MMU& mmu) // 0x3C
130{
131 const u8 oldValue = cpu.reg(ProcessingUnit::Register::A);
132 const u8 newValue = oldValue + 1;
133 cpu.reg(ProcessingUnit::Register::A) = newValue;
134
135 cpu.setFlag(ProcessingUnit::Flag::Z, newValue == 0);
136 cpu.setFlag(ProcessingUnit::Flag::N, false);
137 cpu.setFlag(ProcessingUnit::Flag::H, (oldValue & 0x0F) == 0x0F);
138
139 return totalMachineCycles(1);
140}
141int op_dec_a(ProcessingUnit& cpu, MMU& mmu) // 0x3D
142{
143 const u8 oldValue = cpu.reg(ProcessingUnit::Register::A);
144 const u8 newValue = oldValue - 1;
145 cpu.reg(ProcessingUnit::Register::A) = newValue;
146
147 cpu.setFlag(ProcessingUnit::Flag::Z, newValue == 0);
148 cpu.setFlag(ProcessingUnit::Flag::N, true);
149 cpu.setFlag(ProcessingUnit::Flag::H, (oldValue & 0x0F) == 0x00);
150
151 return totalMachineCycles(1);
152}
153int op_ld_a_d8(ProcessingUnit& cpu, MMU& mmu) // 0x3E
154{
155 cpu.reg(ProcessingUnit::Register::A) = mmu.read(cpu.inc_pc());
156
157 return totalMachineCycles(2);
158}
159int op_ccf(ProcessingUnit& cpu, MMU& mmu) // 0x3F
160{
161 cpu.setFlag(ProcessingUnit::Flag::N, false);
162 cpu.setFlag(ProcessingUnit::Flag::H, false);
163 cpu.setFlag(ProcessingUnit::Flag::C, !cpu.get_flag_c());
164
165 return totalMachineCycles(1);
166}
Definition mmu.hpp:12