yaze 0.2.2
Link to the Past ROM Editor
 
Loading...
Searching...
No Matches
instructions.cc
Go to the documentation of this file.
1#include "app/emu/cpu/cpu.h"
2
3namespace yaze {
4namespace emu {
5
6void Cpu::And(uint32_t low, uint32_t high) {
7 if (GetAccumulatorSize()) {
8 CheckInt();
9 uint8_t value = ReadByte(low);
10 A = (A & 0xff00) | ((A & value) & 0xff);
11 } else {
12 uint16_t value = ReadWord(low, high, true);
13 A &= value;
14 }
16}
17
18void Cpu::Eor(uint32_t low, uint32_t high) {
19 if (GetAccumulatorSize()) {
20 CheckInt();
21 uint8_t value = ReadByte(low);
22 A = (A & 0xff00) | ((A ^ value) & 0xff);
23 } else {
24 uint16_t value = ReadWord(low, high, true);
25 A ^= value;
26 }
28}
29
30void Cpu::Adc(uint32_t low, uint32_t high) {
31 if (GetAccumulatorSize()) {
32 CheckInt();
33 uint8_t value = ReadByte(low);
34 int result = 0;
35 if (GetDecimalFlag()) {
36 result = (A & 0xf) + (value & 0xf) + GetCarryFlag();
37 if (result > 0x9) result = ((result + 0x6) & 0xf) + 0x10;
38 result = (A & 0xf0) + (value & 0xf0) + result;
39 } else {
40 result = (A & 0xff) + value + GetCarryFlag();
41 }
42 SetOverflowFlag((A & 0x80) == (value & 0x80) &&
43 (value & 0x80) != (result & 0x80));
44 if (GetDecimalFlag() && result > 0x9f) result += 0x60;
45 SetCarryFlag(result > 0xff);
46 A = (A & 0xff00) | (result & 0xff);
47 } else {
48 uint16_t value = ReadWord(low, high, true);
49 int result = 0;
50 if (GetDecimalFlag()) {
51 result = (A & 0xf) + (value & 0xf) + GetCarryFlag();
52 if (result > 0x9) result = ((result + 0x6) & 0xf) + 0x10;
53 result = (A & 0xf0) + (value & 0xf0) + result;
54 if (result > 0x9f) result = ((result + 0x60) & 0xff) + 0x100;
55 result = (A & 0xf00) + (value & 0xf00) + result;
56 if (result > 0x9ff) result = ((result + 0x600) & 0xfff) + 0x1000;
57 result = (A & 0xf000) + (value & 0xf000) + result;
58 } else {
59 result = A + value + GetCarryFlag();
60 }
61 SetOverflowFlag((A & 0x8000) == (value & 0x8000) &&
62 (value & 0x8000) != (result & 0x8000));
63 if (GetDecimalFlag() && result > 0x9fff) result += 0x6000;
64 SetCarryFlag(result > 0xffff);
65 A = result;
66 }
68}
69
70void Cpu::Sbc(uint32_t low, uint32_t high) {
71 if (GetAccumulatorSize()) {
72 CheckInt();
73 uint8_t value = ReadByte(low) ^ 0xff;
74 int result = 0;
75 if (GetDecimalFlag()) {
76 result = (A & 0xf) + (value & 0xf) + GetCarryFlag();
77 if (result < 0x10)
78 result = (result - 0x6) & ((result - 0x6 < 0) ? 0xf : 0x1f);
79 result = (A & 0xf0) + (value & 0xf0) + result;
80 } else {
81 result = (A & 0xff) + value + GetCarryFlag();
82 }
83 SetOverflowFlag((A & 0x80) == (value & 0x80) &&
84 (value & 0x80) != (result & 0x80));
85 if (GetDecimalFlag() && result < 0x100) result -= 0x60;
86 SetCarryFlag(result > 0xff);
87 A = (A & 0xff00) | (result & 0xff);
88 } else {
89 uint16_t value = ReadWord(low, high, true) ^ 0xffff;
90 int result = 0;
91 if (GetDecimalFlag()) {
92 result = (A & 0xf) + (value & 0xf) + GetCarryFlag();
93 if (result < 0x10)
94 result = (result - 0x6) & ((result - 0x6 < 0) ? 0xf : 0x1f);
95 result = (A & 0xf0) + (value & 0xf0) + result;
96 if (result < 0x100)
97 result = (result - 0x60) & ((result - 0x60 < 0) ? 0xff : 0x1ff);
98 result = (A & 0xf00) + (value & 0xf00) + result;
99 if (result < 0x1000)
100 result = (result - 0x600) & ((result - 0x600 < 0) ? 0xfff : 0x1fff);
101 result = (A & 0xf000) + (value & 0xf000) + result;
102 } else {
103 result = A + value + GetCarryFlag();
104 }
105 SetOverflowFlag((A & 0x8000) == (value & 0x8000) &&
106 (value & 0x8000) != (result & 0x8000));
107 if (GetDecimalFlag() && result < 0x10000) result -= 0x6000;
108 SetCarryFlag(result > 0xffff);
109 A = result;
110 }
112}
113
114void Cpu::Cmp(uint32_t low, uint32_t high) {
115 int result = 0;
116 if (GetAccumulatorSize()) {
117 CheckInt();
118 uint8_t value = ReadByte(low) ^ 0xff;
119 result = (A & 0xff) + value + 1;
120 SetCarryFlag(result > 0xff);
121 } else {
122 uint16_t value = ReadWord(low, high, true) ^ 0xffff;
123 result = A + value + 1;
124 SetCarryFlag(result > 0xffff);
125 }
126 SetZN(result, GetAccumulatorSize());
127}
128
129void Cpu::Cpx(uint32_t low, uint32_t high) {
130 int result = 0;
131 if (GetIndexSize()) {
132 CheckInt();
133 uint8_t value = ReadByte(low) ^ 0xff;
134 result = (X & 0xff) + value + 1;
135 SetCarryFlag(result > 0xff);
136 } else {
137 uint16_t value = ReadWord(low, high, true) ^ 0xffff;
138 result = X + value + 1;
139 SetCarryFlag(result > 0xffff);
140 }
141 SetZN(result, GetIndexSize());
142}
143
144void Cpu::Cpy(uint32_t low, uint32_t high) {
145 int result = 0;
146 if (GetIndexSize()) {
147 CheckInt();
148 uint8_t value = ReadByte(low) ^ 0xff;
149 result = (Y & 0xff) + value + 1;
150 SetCarryFlag(result > 0xff);
151 } else {
152 uint16_t value = ReadWord(low, high, true) ^ 0xffff;
153 result = Y + value + 1;
154 SetCarryFlag(result > 0xffff);
155 }
156 SetZN(result, GetIndexSize());
157}
158
159void Cpu::Bit(uint32_t low, uint32_t high) {
160 if (GetAccumulatorSize()) {
161 CheckInt();
162 uint8_t value = ReadByte(low);
163 uint8_t result = (A & 0xff) & value;
164 SetZeroFlag(result == 0);
165 SetNegativeFlag(value & 0x80);
166 SetOverflowFlag(value & 0x40);
167 } else {
168 uint16_t value = ReadWord(low, high, true);
169 uint16_t result = A & value;
170 SetZeroFlag(result == 0);
171 SetNegativeFlag(value & 0x8000);
172 SetOverflowFlag(value & 0x4000);
173 }
174}
175
176void Cpu::Lda(uint32_t low, uint32_t high) {
177 if (GetAccumulatorSize()) {
178 CheckInt();
179 A = (A & 0xff00) | ReadByte(low);
180 } else {
181 A = ReadWord(low, high, true);
182 }
184}
185
186void Cpu::Ldx(uint32_t low, uint32_t high) {
187 if (GetIndexSize()) {
188 CheckInt();
189 X = ReadByte(low);
190 } else {
191 X = ReadWord(low, high, true);
192 }
193 SetZN(X, GetIndexSize());
194}
195
196void Cpu::Ldy(uint32_t low, uint32_t high) {
197 if (GetIndexSize()) {
198 CheckInt();
199 Y = ReadByte(low);
200 } else {
201 Y = ReadWord(low, high, true);
202 }
203 SetZN(Y, GetIndexSize());
204}
205
206void Cpu::Sta(uint32_t low, uint32_t high) {
207 if (GetAccumulatorSize()) {
208 CheckInt();
209 WriteByte(low, A);
210 } else {
211 WriteWord(low, high, A, false, true);
212 }
213}
214
215void Cpu::Stx(uint32_t low, uint32_t high) {
216 if (GetIndexSize()) {
217 CheckInt();
218 WriteByte(low, X);
219 } else {
220 WriteWord(low, high, X, false, true);
221 }
222}
223
224void Cpu::Sty(uint32_t low, uint32_t high) {
225 if (GetIndexSize()) {
226 CheckInt();
227 WriteByte(low, Y);
228 } else {
229 WriteWord(low, high, Y, false, true);
230 }
231}
232
233void Cpu::Stz(uint32_t low, uint32_t high) {
234 if (GetAccumulatorSize()) {
235 CheckInt();
236 WriteByte(low, 0);
237 } else {
238 WriteWord(low, high, 0, false, true);
239 }
240}
241
242void Cpu::Ror(uint32_t low, uint32_t high) {
243 bool carry = false;
244 int result = 0;
245 if (GetAccumulatorSize()) {
246 uint8_t value = ReadByte(low);
247 callbacks_.idle(false);
248 carry = value & 1;
249 result = (value >> 1) | (GetCarryFlag() << 7);
250 CheckInt();
251 WriteByte(low, result);
252 } else {
253 uint16_t value = ReadWord(low, high, false);
254 callbacks_.idle(false);
255 carry = value & 1;
256 result = (value >> 1) | (GetCarryFlag() << 15);
257 WriteWord(low, high, result, true, true);
258 }
259 SetZN(result, GetAccumulatorSize());
260 SetCarryFlag(carry);
261}
262
263void Cpu::Rol(uint32_t low, uint32_t high) {
264 int result = 0;
265 if (GetAccumulatorSize()) {
266 result = (ReadByte(low) << 1) | GetCarryFlag();
267 callbacks_.idle(false);
268 SetCarryFlag(result & 0x100);
269 CheckInt();
270 WriteByte(low, result);
271 } else {
272 result = (ReadWord(low, high, false) << 1) | GetCarryFlag();
273 callbacks_.idle(false);
274 SetCarryFlag(result & 0x10000);
275 WriteWord(low, high, result, true, true);
276 }
277 SetZN(result, GetAccumulatorSize());
278}
279
280void Cpu::Lsr(uint32_t low, uint32_t high) {
281 int result = 0;
282 if (GetAccumulatorSize()) {
283 uint8_t value = ReadByte(low);
284 callbacks_.idle(false);
285 SetCarryFlag(value & 1);
286 result = value >> 1;
287 CheckInt();
288 WriteByte(low, result);
289 } else {
290 uint16_t value = ReadWord(low, high, false);
291 callbacks_.idle(false);
292 SetCarryFlag(value & 1);
293 result = value >> 1;
294 WriteWord(low, high, result, true, true);
295 }
296 SetZN(result, GetAccumulatorSize());
297}
298
299void Cpu::Asl(uint32_t low, uint32_t high) {
300 int result = 0;
301 if (GetAccumulatorSize()) {
302 result = ReadByte(low) << 1;
303 callbacks_.idle(false);
304 SetCarryFlag(result & 0x100);
305 CheckInt();
306 WriteByte(low, result);
307 } else {
308 result = ReadWord(low, high, false) << 1;
309 callbacks_.idle(false);
310 SetCarryFlag(result & 0x10000);
311 WriteWord(low, high, result, true, true);
312 }
313 SetZN(result, GetAccumulatorSize());
314}
315
316void Cpu::Inc(uint32_t low, uint32_t high) {
317 int result = 0;
318 if (GetAccumulatorSize()) {
319 result = ReadByte(low) + 1;
320 callbacks_.idle(false);
321 CheckInt();
322 WriteByte(low, result);
323 } else {
324 result = ReadWord(low, high, false) + 1;
325 callbacks_.idle(false);
326 WriteWord(low, high, result, true, true);
327 }
328 SetZN(result, GetAccumulatorSize());
329}
330
331void Cpu::Dec(uint32_t low, uint32_t high) {
332 int result = 0;
333 if (GetAccumulatorSize()) {
334 result = ReadByte(low) - 1;
335 callbacks_.idle(false);
336 CheckInt();
337 WriteByte(low, result);
338 } else {
339 result = ReadWord(low, high, false) - 1;
340 callbacks_.idle(false);
341 WriteWord(low, high, result, true, true);
342 }
343 SetZN(result, GetAccumulatorSize());
344}
345
346void Cpu::Tsb(uint32_t low, uint32_t high) {
347 if (GetAccumulatorSize()) {
348 uint8_t value = ReadByte(low);
349 callbacks_.idle(false);
350 SetZeroFlag(((A & 0xff) & value) == 0);
351 CheckInt();
352 WriteByte(low, value | (A & 0xff));
353 } else {
354 uint16_t value = ReadWord(low, high, false);
355 callbacks_.idle(false);
356 SetZeroFlag((A & value) == 0);
357 WriteWord(low, high, value | A, true, true);
358 }
359}
360
361void Cpu::Trb(uint32_t low, uint32_t high) {
362 if (GetAccumulatorSize()) {
363 uint8_t value = ReadByte(low);
364 callbacks_.idle(false);
365 SetZeroFlag(((A & 0xff) & value) == 0);
366 CheckInt();
367 WriteByte(low, value & ~(A & 0xff));
368 } else {
369 uint16_t value = ReadWord(low, high, false);
370 callbacks_.idle(false);
371 SetZeroFlag((A & value) == 0);
372 WriteWord(low, high, value & ~A, true, true);
373 }
374}
375
376void Cpu::ORA(uint32_t low, uint32_t high) {
377 if (GetAccumulatorSize()) {
378 CheckInt();
379 uint8_t value = ReadByte(low);
380 A = (A & 0xFF00) | ((A | value) & 0xFF);
381 SetZeroFlag(A == 0);
382 SetNegativeFlag(A & 0x80);
383 } else {
384 uint16_t value = ReadWord(low, high, true);
385 A |= value;
386 SetZeroFlag(A == 0);
387 SetNegativeFlag(A & 0x8000);
388 }
389}
390
391} // namespace emu
392} // namespace yaze
void Stx(uint32_t low, uint32_t high)
void WriteWord(uint32_t address, uint32_t address_high, uint16_t value, bool reversed=false, bool int_check=false)
Definition cpu.h:166
void Asl(uint32_t low, uint32_t high)
void Inc(uint32_t low, uint32_t high)
void SetZN(uint16_t value, bool byte)
Definition cpu.h:100
void Ldy(uint32_t low, uint32_t high)
uint16_t X
Definition cpu.h:66
void Sta(uint32_t low, uint32_t high)
uint8_t ReadByte(uint32_t address)
Definition cpu.h:147
void Cpy(uint32_t low, uint32_t high)
uint16_t ReadWord(uint32_t address, uint32_t address_high, bool int_check=false)
Definition cpu.h:148
uint16_t Y
Definition cpu.h:67
void CheckInt()
Definition cpu.h:737
void Bit(uint32_t low, uint32_t high)
int GetIndexSize() const
Definition cpu.h:114
void And(uint32_t low, uint32_t high)
void SetZeroFlag(bool set)
Definition cpu.h:124
void WriteByte(uint32_t address, uint8_t value)
Definition cpu.h:162
void ORA(uint32_t low, uint32_t high)
uint16_t A
Definition cpu.h:65
void Sbc(uint32_t low, uint32_t high)
void Trb(uint32_t low, uint32_t high)
void Lda(uint32_t low, uint32_t high)
void Cpx(uint32_t low, uint32_t high)
void Rol(uint32_t low, uint32_t high)
void Tsb(uint32_t low, uint32_t high)
void Dec(uint32_t low, uint32_t high)
void Ldx(uint32_t low, uint32_t high)
int GetAccumulatorSize() const
Definition cpu.h:113
void SetOverflowFlag(bool set)
Definition cpu.h:120
void SetCarryFlag(bool set)
Definition cpu.h:125
bool GetCarryFlag() const
Definition cpu.h:134
CpuCallbacks callbacks_
Definition cpu.h:784
void Eor(uint32_t low, uint32_t high)
void Stz(uint32_t low, uint32_t high)
bool GetDecimalFlag() const
Definition cpu.h:131
void Cmp(uint32_t low, uint32_t high)
void Ror(uint32_t low, uint32_t high)
void SetNegativeFlag(bool set)
Definition cpu.h:119
void Sty(uint32_t low, uint32_t high)
void Lsr(uint32_t low, uint32_t high)
void Adc(uint32_t low, uint32_t high)
SNES Emulation and debugging tools.
Definition apu.cc:13
Main namespace for the application.
Definition controller.cc:18