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