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