GameBoy Emulator 1
Game Boy emulator core and tooling
Loading...
Searching...
No Matches
op_0E.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_ldh_a8_a(ProcessingUnit& cpu, MMU& mmu) // 0xE0
11{
12 const u8 a8 = mmu.read(cpu.inc_pc());
13 const u16 target = 0xFF00 | a8;
14
15 mmu.write(target, cpu.reg(ProcessingUnit::Register::A));
16
17 return totalMachineCycles(3);
18}
19
20int op_pop_hl(ProcessingUnit& cpu, MMU& mmu) // 0xE1
21{
22 const u16 sp = cpu.get_sp();
23 const u8 lo = mmu.read(sp);
24 const u8 hi = mmu.read(sp + 1);
25
26 cpu.reg(ProcessingUnit::Register::L) = lo;
27 cpu.reg(ProcessingUnit::Register::H) = hi;
28 cpu.set_sp(sp + 2);
29
30 return totalMachineCycles(3);
31}
32
33int op_ld_c_a_e2(ProcessingUnit& cpu, MMU& mmu) // 0xE2
34{
35 const u16 target = 0xFF00 | cpu.reg(ProcessingUnit::Register::C);
36 mmu.write(target, cpu.reg(ProcessingUnit::Register::A));
37
38 return totalMachineCycles(2);
39}
40
41int op_illegal_e3(ProcessingUnit& cpu, MMU& mmu) // 0xE3
42{
43 throw std::runtime_error("Unimplemented opcode at PC: 0x" + std::to_string(cpu.last_pc));
44}
45
46int op_illegal_e4(ProcessingUnit& cpu, MMU& mmu) // 0xE4
47{
48 throw std::runtime_error("Unimplemented opcode at PC: 0x" + std::to_string(cpu.last_pc));
49}
50
51int op_push_hl(ProcessingUnit& cpu, MMU& mmu) // 0xE5
52{
53 const u8 h = cpu.reg(ProcessingUnit::Register::H);
54 const u8 l = cpu.reg(ProcessingUnit::Register::L);
55 const u16 sp = cpu.get_sp();
56
57 mmu.write(sp - 1, h);
58 mmu.write(sp - 2, l);
59 cpu.set_sp(sp - 2);
60
61 return totalMachineCycles(4);
62}
63
64int op_and_d8(ProcessingUnit& cpu, MMU& mmu) // 0xE6
65{
66 const u8 d8 = mmu.read(cpu.inc_pc());
67 const u8 result = cpu.reg(ProcessingUnit::Register::A) & d8;
68 cpu.reg(ProcessingUnit::Register::A) = result;
69
70 cpu.setFlag(ProcessingUnit::Flag::Z, result == 0);
71 cpu.setFlag(ProcessingUnit::Flag::N, false);
72 cpu.setFlag(ProcessingUnit::Flag::H, true);
73 cpu.setFlag(ProcessingUnit::Flag::C, false);
74
75 return totalMachineCycles(2);
76}
77
78int op_rst_20(ProcessingUnit& cpu, MMU& mmu) // 0xE7
79{
80 const u16 pc = cpu.get_pc();
81
82 cpu.set_sp(cpu.get_sp() - 1);
83 mmu.write(cpu.get_sp(), (pc >> 8) & 0xFF);
84
85 cpu.set_sp(cpu.get_sp() - 1);
86 mmu.write(cpu.get_sp(), pc & 0xFF);
87
88 cpu.set_pc(0x20);
89
90 return totalMachineCycles(4);
91}
92
93int op_add_sp_e8(ProcessingUnit& cpu, MMU& mmu) // 0xE8
94{
95 const u16 sp = cpu.get_sp();
96 const u8 offset_raw = mmu.read(cpu.inc_pc());
97 const auto offset = static_cast<int8_t>(offset_raw);
98 const u16 result = static_cast<u16>(sp + offset);
99
100 cpu.set_sp(result);
101
102 cpu.setFlag(ProcessingUnit::Flag::Z, false);
103 cpu.setFlag(ProcessingUnit::Flag::N, false);
104 cpu.setFlag(ProcessingUnit::Flag::H, ((sp & 0x0F) + (offset_raw & 0x0F)) > 0x0F);
105 cpu.setFlag(ProcessingUnit::Flag::C, ((sp & 0xFF) + (offset_raw & 0xFF)) > 0xFF);
106
107 return totalMachineCycles(4);
108}
109
110int op_jp_hl(ProcessingUnit& cpu, MMU& mmu) // 0xE9
111{
112 cpu.set_pc(cpu.get_hl());
113 return totalMachineCycles(1);
114}
115
116int op_ld_a16_a(ProcessingUnit& cpu, MMU& mmu) // 0xEA
117{
118 const u8 lo = mmu.read(cpu.inc_pc());
119 const u8 hi = mmu.read(cpu.inc_pc());
120 const u16 addr = static_cast<u16>((hi << 8) | lo);
121
122 mmu.write(addr, cpu.reg(ProcessingUnit::Register::A));
123
124 return totalMachineCycles(4);
125}
126
127int op_illegal_eb(ProcessingUnit& cpu, MMU& mmu) // 0xEB
128{
129 throw std::runtime_error("Unimplemented opcode at PC: 0x" + std::to_string(cpu.last_pc));
130}
131
132int op_illegal_ec(ProcessingUnit& cpu, MMU& mmu) // 0xEC
133{
134 throw std::runtime_error("Unimplemented opcode at PC: 0x" + std::to_string(cpu.last_pc));
135}
136
137int op_illegal_ed(ProcessingUnit& cpu, MMU& mmu) // 0xED
138{
139 throw std::runtime_error("Unimplemented opcode at PC: 0x" + std::to_string(cpu.last_pc));
140}
141
142int op_xor_d8(ProcessingUnit& cpu, MMU& mmu) // 0xEE
143{
144 const u8 d8 = mmu.read(cpu.inc_pc());
145 const u8 result = cpu.reg(ProcessingUnit::Register::A) ^ d8;
146 cpu.reg(ProcessingUnit::Register::A) = result;
147
148 cpu.setFlag(ProcessingUnit::Flag::Z, result == 0);
149 cpu.setFlag(ProcessingUnit::Flag::N, false);
150 cpu.setFlag(ProcessingUnit::Flag::H, false);
151 cpu.setFlag(ProcessingUnit::Flag::C, false);
152
153 return totalMachineCycles(2);
154}
155
156int op_rst_28(ProcessingUnit& cpu, MMU& mmu) // 0xEF
157{
158 const u16 pc = cpu.get_pc();
159
160 cpu.set_sp(cpu.get_sp() - 1);
161 mmu.write(cpu.get_sp(), (pc >> 8) & 0xFF);
162
163 cpu.set_sp(cpu.get_sp() - 1);
164 mmu.write(cpu.get_sp(), pc & 0xFF);
165
166 cpu.set_pc(0x28);
167
168 return totalMachineCycles(4);
169}
Definition mmu.hpp:12