ViewVC Help
View File | Revision Log | Show Annotations | Revision Graph | Root Listing
root/cebix/Frodo4/Src/CPU_emulline.h
Revision: 1.6
Committed: 2005-06-27T19:55:48Z (17 years, 5 months ago) by cebix
Content type: text/plain
Branch: MAIN
CVS Tags: VERSION_4_2, HEAD
Changes since 1.5: +1 -1 lines
Log Message:
updated copyright dates

File Contents

# Content
1 /*
2 * CPU_emulline.h - 6510/6502 emulation core (body of
3 * EmulateLine() function, the same for
4 * both 6510 and 6502)
5 *
6 * Frodo (C) 1994-1997,2002-2005 Christian Bauer
7 *
8 * This program is free software; you can redistribute it and/or modify
9 * it under the terms of the GNU General Public License as published by
10 * the Free Software Foundation; either version 2 of the License, or
11 * (at your option) any later version.
12 *
13 * This program is distributed in the hope that it will be useful,
14 * but WITHOUT ANY WARRANTY; without even the implied warranty of
15 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
16 * GNU General Public License for more details.
17 *
18 * You should have received a copy of the GNU General Public License
19 * along with this program; if not, write to the Free Software
20 * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
21 */
22
23
24 /*
25 * Addressing mode macros
26 */
27
28 // Read immediate operand
29 #if PC_IS_POINTER
30 #define read_byte_imm() (*pc++)
31 #else
32 #define read_byte_imm() read_byte(pc++)
33 #endif
34
35 // Read zeropage operand address
36 #define read_adr_zero() ((uint16)read_byte_imm())
37
38 // Read zeropage x-indexed operand address
39 #define read_adr_zero_x() ((read_byte_imm() + x) & 0xff)
40
41 // Read zeropage y-indexed operand address
42 #define read_adr_zero_y() ((read_byte_imm() + y) & 0xff)
43
44 // Read absolute operand address (uses adr!)
45 #if PC_IS_POINTER
46 #if LITTLE_ENDIAN_UNALIGNED
47 #define read_adr_abs() (adr = *(UWORD *)pc, pc+=2, adr)
48 #else
49 #define read_adr_abs() (adr = ((*(pc+1)) << 8) | *pc, pc+=2, adr)
50 #endif
51 #else
52 #define read_adr_abs() (adr = read_word(pc), pc+=2, adr)
53 #endif
54
55 // Read absolute x-indexed operand address
56 #define read_adr_abs_x() (read_adr_abs() + x)
57
58 // Read absolute y-indexed operand address
59 #define read_adr_abs_y() (read_adr_abs() + y)
60
61 // Read indexed indirect operand address
62 #define read_adr_ind_x() (read_zp_word(read_byte_imm() + x))
63
64 // Read indirect indexed operand address
65 #define read_adr_ind_y() (read_zp_word(read_byte_imm()) + y)
66
67 // Read zeropage operand
68 #define read_byte_zero() read_zp(read_adr_zero())
69
70 // Read zeropage x-indexed operand
71 #define read_byte_zero_x() read_zp(read_adr_zero_x())
72
73 // Read zeropage y-indexed operand
74 #define read_byte_zero_y() read_zp(read_adr_zero_y())
75
76 // Read absolute operand
77 #define read_byte_abs() read_byte(read_adr_abs())
78
79 #if PRECISE_CPU_CYCLES
80 // Acount for cyles due to crossing page boundaries
81 #define page_plus(exp, reg) \
82 (adr = exp, page_cycles = (adr & 0xff) + reg >= 0x100, adr + reg)
83
84 // Read absolute x-indexed operand
85 #define read_byte_abs_x() read_byte(page_plus(read_adr_abs(), x))
86
87 // Read absolute x-indexed operand
88 #define read_byte_abs_y() read_byte(page_plus(read_adr_abs(), y))
89
90 // Read indirect y-indexed operand
91 #define read_byte_ind_y() read_byte(page_plus(read_zp_word(read_byte_imm()), y))
92
93 #else
94
95 // Read absolute x-indexed operand
96 #define read_byte_abs_x() read_byte(read_adr_abs_x())
97
98 // Read absolute x-indexed operand
99 #define read_byte_abs_y() read_byte(read_adr_abs_y())
100
101 // Read indirect y-indexed operand
102 #define read_byte_ind_y() read_byte(read_adr_ind_y())
103 #endif
104
105 // Read indexed indirect operand
106 #define read_byte_ind_x() read_byte(read_adr_ind_x())
107
108
109 /*
110 * Set N and Z flags according to byte
111 */
112
113 #define set_nz(x) (z_flag = n_flag = (x))
114
115
116 /*
117 * End of opcode, decrement cycles left
118 */
119
120 #define ENDOP(cyc) last_cycles = cyc; break;
121
122
123 // Main opcode fetch/execute loop
124 #if PRECISE_CPU_CYCLES
125 if (cycles_left != 1)
126 cycles_left -= borrowed_cycles;
127 int page_cycles = 0;
128 for (;;) {
129 if (last_cycles) {
130 last_cycles += page_cycles;
131 page_cycles = 0;
132 #if PRECISE_CIA_CYCLES && !defined(IS_CPU_1541)
133 TheCIA1->EmulateLine(last_cycles);
134 TheCIA2->EmulateLine(last_cycles);
135 #endif
136 }
137 if ((cycles_left -= last_cycles) < 0) {
138 borrowed_cycles = -cycles_left;
139 break;
140 }
141 #else
142 while ((cycles_left -= last_cycles) >= 0) {
143 #endif
144
145 switch (read_byte_imm()) {
146
147
148 // Load group
149 case 0xa9: // LDA #imm
150 set_nz(a = read_byte_imm());
151 ENDOP(2);
152
153 case 0xa5: // LDA zero
154 set_nz(a = read_byte_zero());
155 ENDOP(3);
156
157 case 0xb5: // LDA zero,X
158 set_nz(a = read_byte_zero_x());
159 ENDOP(4);
160
161 case 0xad: // LDA abs
162 set_nz(a = read_byte_abs());
163 ENDOP(4);
164
165 case 0xbd: // LDA abs,X
166 set_nz(a = read_byte_abs_x());
167 ENDOP(4);
168
169 case 0xb9: // LDA abs,Y
170 set_nz(a = read_byte_abs_y());
171 ENDOP(4);
172
173 case 0xa1: // LDA (ind,X)
174 set_nz(a = read_byte_ind_x());
175 ENDOP(6);
176
177 case 0xb1: // LDA (ind),Y
178 set_nz(a = read_byte_ind_y());
179 ENDOP(5);
180
181 case 0xa2: // LDX #imm
182 set_nz(x = read_byte_imm());
183 ENDOP(2);
184
185 case 0xa6: // LDX zero
186 set_nz(x = read_byte_zero());
187 ENDOP(3);
188
189 case 0xb6: // LDX zero,Y
190 set_nz(x = read_byte_zero_y());
191 ENDOP(4);
192
193 case 0xae: // LDX abs
194 set_nz(x = read_byte_abs());
195 ENDOP(4);
196
197 case 0xbe: // LDX abs,Y
198 set_nz(x = read_byte_abs_y());
199 ENDOP(4);
200
201 case 0xa0: // LDY #imm
202 set_nz(y = read_byte_imm());
203 ENDOP(2);
204
205 case 0xa4: // LDY zero
206 set_nz(y = read_byte_zero());
207 ENDOP(3);
208
209 case 0xb4: // LDY zero,X
210 set_nz(y = read_byte_zero_x());
211 ENDOP(4);
212
213 case 0xac: // LDY abs
214 set_nz(y = read_byte_abs());
215 ENDOP(4);
216
217 case 0xbc: // LDY abs,X
218 set_nz(y = read_byte_abs_x());
219 ENDOP(4);
220
221
222 // Store group
223 case 0x85: // STA zero
224 write_byte(read_adr_zero(), a);
225 ENDOP(3);
226
227 case 0x95: // STA zero,X
228 write_byte(read_adr_zero_x(), a);
229 ENDOP(4);
230
231 case 0x8d: // STA abs
232 write_byte(read_adr_abs(), a);
233 ENDOP(4);
234
235 case 0x9d: // STA abs,X
236 write_byte(read_adr_abs_x(), a);
237 ENDOP(5);
238
239 case 0x99: // STA abs,Y
240 write_byte(read_adr_abs_y(), a);
241 ENDOP(5);
242
243 case 0x81: // STA (ind,X)
244 write_byte(read_adr_ind_x(), a);
245 ENDOP(6);
246
247 case 0x91: // STA (ind),Y
248 write_byte(read_adr_ind_y(), a);
249 ENDOP(6);
250
251 case 0x86: // STX zero
252 write_byte(read_adr_zero(), x);
253 ENDOP(3);
254
255 case 0x96: // STX zero,Y
256 write_byte(read_adr_zero_y(), x);
257 ENDOP(4);
258
259 case 0x8e: // STX abs
260 write_byte(read_adr_abs(), x);
261 ENDOP(4);
262
263 case 0x84: // STY zero
264 write_byte(read_adr_zero(), y);
265 ENDOP(3);
266
267 case 0x94: // STY zero,X
268 write_byte(read_adr_zero_x(), y);
269 ENDOP(4);
270
271 case 0x8c: // STY abs
272 write_byte(read_adr_abs(), y);
273 ENDOP(4);
274
275
276 // Transfer group
277 case 0xaa: // TAX
278 set_nz(x = a);
279 ENDOP(2);
280
281 case 0x8a: // TXA
282 set_nz(a = x);
283 ENDOP(2);
284
285 case 0xa8: // TAY
286 set_nz(y = a);
287 ENDOP(2);
288
289 case 0x98: // TYA
290 set_nz(a = y);
291 ENDOP(2);
292
293 case 0xba: // TSX
294 set_nz(x = sp);
295 ENDOP(2);
296
297 case 0x9a: // TXS
298 sp = x;
299 ENDOP(2);
300
301
302 // Arithmetic group
303 case 0x69: // ADC #imm
304 do_adc(read_byte_imm());
305 ENDOP(2);
306
307 case 0x65: // ADC zero
308 do_adc(read_byte_zero());
309 ENDOP(3);
310
311 case 0x75: // ADC zero,X
312 do_adc(read_byte_zero_x());
313 ENDOP(4);
314
315 case 0x6d: // ADC abs
316 do_adc(read_byte_abs());
317 ENDOP(4);
318
319 case 0x7d: // ADC abs,X
320 do_adc(read_byte_abs_x());
321 ENDOP(4);
322
323 case 0x79: // ADC abs,Y
324 do_adc(read_byte_abs_y());
325 ENDOP(4);
326
327 case 0x61: // ADC (ind,X)
328 do_adc(read_byte_ind_x());
329 ENDOP(6);
330
331 case 0x71: // ADC (ind),Y
332 do_adc(read_byte_ind_y());
333 ENDOP(5);
334
335 case 0xe9: // SBC #imm
336 case 0xeb: // Undocumented opcode
337 do_sbc(read_byte_imm());
338 ENDOP(2);
339
340 case 0xe5: // SBC zero
341 do_sbc(read_byte_zero());
342 ENDOP(3);
343
344 case 0xf5: // SBC zero,X
345 do_sbc(read_byte_zero_x());
346 ENDOP(4);
347
348 case 0xed: // SBC abs
349 do_sbc(read_byte_abs());
350 ENDOP(4);
351
352 case 0xfd: // SBC abs,X
353 do_sbc(read_byte_abs_x());
354 ENDOP(4);
355
356 case 0xf9: // SBC abs,Y
357 do_sbc(read_byte_abs_y());
358 ENDOP(4);
359
360 case 0xe1: // SBC (ind,X)
361 do_sbc(read_byte_ind_x());
362 ENDOP(6);
363
364 case 0xf1: // SBC (ind),Y
365 do_sbc(read_byte_ind_y());
366 ENDOP(5);
367
368
369 // Increment/decrement group
370 case 0xe8: // INX
371 set_nz(++x);
372 ENDOP(2);
373
374 case 0xca: // DEX
375 set_nz(--x);
376 ENDOP(2);
377
378 case 0xc8: // INY
379 set_nz(++y);
380 ENDOP(2);
381
382 case 0x88: // DEY
383 set_nz(--y);
384 ENDOP(2);
385
386 case 0xe6: // INC zero
387 adr = read_adr_zero();
388 write_zp(adr, set_nz(read_zp(adr) + 1));
389 ENDOP(5);
390
391 case 0xf6: // INC zero,X
392 adr = read_adr_zero_x();
393 write_zp(adr, set_nz(read_zp(adr) + 1));
394 ENDOP(6);
395
396 case 0xee: // INC abs
397 adr = read_adr_abs();
398 write_byte(adr, set_nz(read_byte(adr) + 1));
399 ENDOP(6);
400
401 case 0xfe: // INC abs,X
402 adr = read_adr_abs_x();
403 write_byte(adr, set_nz(read_byte(adr) + 1));
404 ENDOP(7);
405
406 case 0xc6: // DEC zero
407 adr = read_adr_zero();
408 write_zp(adr, set_nz(read_zp(adr) - 1));
409 ENDOP(5);
410
411 case 0xd6: // DEC zero,X
412 adr = read_adr_zero_x();
413 write_zp(adr, set_nz(read_zp(adr) - 1));
414 ENDOP(6);
415
416 case 0xce: // DEC abs
417 adr = read_adr_abs();
418 write_byte(adr, set_nz(read_byte(adr) - 1));
419 ENDOP(6);
420
421 case 0xde: // DEC abs,X
422 adr = read_adr_abs_x();
423 write_byte(adr, set_nz(read_byte(adr) - 1));
424 ENDOP(7);
425
426
427 // Logic group
428 case 0x29: // AND #imm
429 set_nz(a &= read_byte_imm());
430 ENDOP(2);
431
432 case 0x25: // AND zero
433 set_nz(a &= read_byte_zero());
434 ENDOP(3);
435
436 case 0x35: // AND zero,X
437 set_nz(a &= read_byte_zero_x());
438 ENDOP(4);
439
440 case 0x2d: // AND abs
441 set_nz(a &= read_byte_abs());
442 ENDOP(4);
443
444 case 0x3d: // AND abs,X
445 set_nz(a &= read_byte_abs_x());
446 ENDOP(4);
447
448 case 0x39: // AND abs,Y
449 set_nz(a &= read_byte_abs_y());
450 ENDOP(4);
451
452 case 0x21: // AND (ind,X)
453 set_nz(a &= read_byte_ind_x());
454 ENDOP(6);
455
456 case 0x31: // AND (ind),Y
457 set_nz(a &= read_byte_ind_y());
458 ENDOP(5);
459
460 case 0x09: // ORA #imm
461 set_nz(a |= read_byte_imm());
462 ENDOP(2);
463
464 case 0x05: // ORA zero
465 set_nz(a |= read_byte_zero());
466 ENDOP(3);
467
468 case 0x15: // ORA zero,X
469 set_nz(a |= read_byte_zero_x());
470 ENDOP(4);
471
472 case 0x0d: // ORA abs
473 set_nz(a |= read_byte_abs());
474 ENDOP(4);
475
476 case 0x1d: // ORA abs,X
477 set_nz(a |= read_byte_abs_x());
478 ENDOP(4);
479
480 case 0x19: // ORA abs,Y
481 set_nz(a |= read_byte_abs_y());
482 ENDOP(4);
483
484 case 0x01: // ORA (ind,X)
485 set_nz(a |= read_byte_ind_x());
486 ENDOP(6);
487
488 case 0x11: // ORA (ind),Y
489 set_nz(a |= read_byte_ind_y());
490 ENDOP(5);
491
492 case 0x49: // EOR #imm
493 set_nz(a ^= read_byte_imm());
494 ENDOP(2);
495
496 case 0x45: // EOR zero
497 set_nz(a ^= read_byte_zero());
498 ENDOP(3);
499
500 case 0x55: // EOR zero,X
501 set_nz(a ^= read_byte_zero_x());
502 ENDOP(4);
503
504 case 0x4d: // EOR abs
505 set_nz(a ^= read_byte_abs());
506 ENDOP(4);
507
508 case 0x5d: // EOR abs,X
509 set_nz(a ^= read_byte_abs_x());
510 ENDOP(4);
511
512 case 0x59: // EOR abs,Y
513 set_nz(a ^= read_byte_abs_y());
514 ENDOP(4);
515
516 case 0x41: // EOR (ind,X)
517 set_nz(a ^= read_byte_ind_x());
518 ENDOP(6);
519
520 case 0x51: // EOR (ind),Y
521 set_nz(a ^= read_byte_ind_y());
522 ENDOP(5);
523
524
525 // Compare group
526 case 0xc9: // CMP #imm
527 set_nz(adr = a - read_byte_imm());
528 c_flag = adr < 0x100;
529 ENDOP(2);
530
531 case 0xc5: // CMP zero
532 set_nz(adr = a - read_byte_zero());
533 c_flag = adr < 0x100;
534 ENDOP(3);
535
536 case 0xd5: // CMP zero,X
537 set_nz(adr = a - read_byte_zero_x());
538 c_flag = adr < 0x100;
539 ENDOP(4);
540
541 case 0xcd: // CMP abs
542 set_nz(adr = a - read_byte_abs());
543 c_flag = adr < 0x100;
544 ENDOP(4);
545
546 case 0xdd: // CMP abs,X
547 set_nz(adr = a - read_byte_abs_x());
548 c_flag = adr < 0x100;
549 ENDOP(4);
550
551 case 0xd9: // CMP abs,Y
552 set_nz(adr = a - read_byte_abs_y());
553 c_flag = adr < 0x100;
554 ENDOP(4);
555
556 case 0xc1: // CMP (ind,X)
557 set_nz(adr = a - read_byte_ind_x());
558 c_flag = adr < 0x100;
559 ENDOP(6);
560
561 case 0xd1: // CMP (ind),Y
562 set_nz(adr = a - read_byte_ind_y());
563 c_flag = adr < 0x100;
564 ENDOP(5);
565
566 case 0xe0: // CPX #imm
567 set_nz(adr = x - read_byte_imm());
568 c_flag = adr < 0x100;
569 ENDOP(2);
570
571 case 0xe4: // CPX zero
572 set_nz(adr = x - read_byte_zero());
573 c_flag = adr < 0x100;
574 ENDOP(3);
575
576 case 0xec: // CPX abs
577 set_nz(adr = x - read_byte_abs());
578 c_flag = adr < 0x100;
579 ENDOP(4);
580
581 case 0xc0: // CPY #imm
582 set_nz(adr = y - read_byte_imm());
583 c_flag = adr < 0x100;
584 ENDOP(2);
585
586 case 0xc4: // CPY zero
587 set_nz(adr = y - read_byte_zero());
588 c_flag = adr < 0x100;
589 ENDOP(3);
590
591 case 0xcc: // CPY abs
592 set_nz(adr = y - read_byte_abs());
593 c_flag = adr < 0x100;
594 ENDOP(4);
595
596
597 // Bit-test group
598 case 0x24: // BIT zero
599 z_flag = a & (tmp = read_byte_zero());
600 n_flag = tmp;
601 v_flag = tmp & 0x40;
602 ENDOP(3);
603
604 case 0x2c: // BIT abs
605 z_flag = a & (tmp = read_byte_abs());
606 n_flag = tmp;
607 v_flag = tmp & 0x40;
608 ENDOP(4);
609
610
611 // Shift/rotate group
612 case 0x0a: // ASL A
613 c_flag = a & 0x80;
614 set_nz(a <<= 1);
615 ENDOP(2);
616
617 case 0x06: // ASL zero
618 tmp = read_zp(adr = read_adr_zero());
619 c_flag = tmp & 0x80;
620 write_zp(adr, set_nz(tmp << 1));
621 ENDOP(5);
622
623 case 0x16: // ASL zero,X
624 tmp = read_zp(adr = read_adr_zero_x());
625 c_flag = tmp & 0x80;
626 write_zp(adr, set_nz(tmp << 1));
627 ENDOP(6);
628
629 case 0x0e: // ASL abs
630 tmp = read_byte(adr = read_adr_abs());
631 c_flag = tmp & 0x80;
632 write_byte(adr, set_nz(tmp << 1));
633 ENDOP(6);
634
635 case 0x1e: // ASL abs,X
636 tmp = read_byte(adr = read_adr_abs_x());
637 c_flag = tmp & 0x80;
638 write_byte(adr, set_nz(tmp << 1));
639 ENDOP(7);
640
641 case 0x4a: // LSR A
642 c_flag = a & 0x01;
643 set_nz(a >>= 1);
644 ENDOP(2);
645
646 case 0x46: // LSR zero
647 tmp = read_zp(adr = read_adr_zero());
648 c_flag = tmp & 0x01;
649 write_zp(adr, set_nz(tmp >> 1));
650 ENDOP(5);
651
652 case 0x56: // LSR zero,X
653 tmp = read_zp(adr = read_adr_zero_x());
654 c_flag = tmp & 0x01;
655 write_zp(adr, set_nz(tmp >> 1));
656 ENDOP(6);
657
658 case 0x4e: // LSR abs
659 tmp = read_byte(adr = read_adr_abs());
660 c_flag = tmp & 0x01;
661 write_byte(adr, set_nz(tmp >> 1));
662 ENDOP(6);
663
664 case 0x5e: // LSR abs,X
665 tmp = read_byte(adr = read_adr_abs_x());
666 c_flag = tmp & 0x01;
667 write_byte(adr, set_nz(tmp >> 1));
668 ENDOP(7);
669
670 case 0x2a: // ROL A
671 tmp2 = a & 0x80;
672 set_nz(a = c_flag ? (a << 1) | 0x01 : a << 1);
673 c_flag = tmp2;
674 ENDOP(2);
675
676 case 0x26: // ROL zero
677 tmp = read_zp(adr = read_adr_zero());
678 tmp2 = tmp & 0x80;
679 write_zp(adr, set_nz(c_flag ? (tmp << 1) | 0x01 : tmp << 1));
680 c_flag = tmp2;
681 ENDOP(5);
682
683 case 0x36: // ROL zero,X
684 tmp = read_zp(adr = read_adr_zero_x());
685 tmp2 = tmp & 0x80;
686 write_zp(adr, set_nz(c_flag ? (tmp << 1) | 0x01 : tmp << 1));
687 c_flag = tmp2;
688 ENDOP(6);
689
690 case 0x2e: // ROL abs
691 tmp = read_byte(adr = read_adr_abs());
692 tmp2 = tmp & 0x80;
693 write_byte(adr, set_nz(c_flag ? (tmp << 1) | 0x01 : tmp << 1));
694 c_flag = tmp2;
695 ENDOP(6);
696
697 case 0x3e: // ROL abs,X
698 tmp = read_byte(adr = read_adr_abs_x());
699 tmp2 = tmp & 0x80;
700 write_byte(adr, set_nz(c_flag ? (tmp << 1) | 0x01 : tmp << 1));
701 c_flag = tmp2;
702 ENDOP(7);
703
704 case 0x6a: // ROR A
705 tmp2 = a & 0x01;
706 set_nz(a = (c_flag ? (a >> 1) | 0x80 : a >> 1));
707 c_flag = tmp2;
708 ENDOP(2);
709
710 case 0x66: // ROR zero
711 tmp = read_zp(adr = read_adr_zero());
712 tmp2 = tmp & 0x01;
713 write_zp(adr, set_nz(c_flag ? (tmp >> 1) | 0x80 : tmp >> 1));
714 c_flag = tmp2;
715 ENDOP(5);
716
717 case 0x76: // ROR zero,X
718 tmp = read_zp(adr = read_adr_zero_x());
719 tmp2 = tmp & 0x01;
720 write_zp(adr, set_nz(c_flag ? (tmp >> 1) | 0x80 : tmp >> 1));
721 c_flag = tmp2;
722 ENDOP(6);
723
724 case 0x6e: // ROR abs
725 tmp = read_byte(adr = read_adr_abs());
726 tmp2 = tmp & 0x01;
727 write_byte(adr, set_nz(c_flag ? (tmp >> 1) | 0x80 : tmp >> 1));
728 c_flag = tmp2;
729 ENDOP(6);
730
731 case 0x7e: // ROR abs,X
732 tmp = read_byte(adr = read_adr_abs_x());
733 tmp2 = tmp & 0x01;
734 write_byte(adr, set_nz(c_flag ? (tmp >> 1) | 0x80 : tmp >> 1));
735 c_flag = tmp2;
736 ENDOP(7);
737
738
739 // Stack group
740 case 0x48: // PHA
741 push_byte(a);
742 ENDOP(3);
743
744 case 0x68: // PLA
745 set_nz(a = pop_byte());
746 ENDOP(4);
747
748 case 0x08: // PHP
749 push_flags(true);
750 ENDOP(3);
751
752 case 0x28: // PLP
753 pop_flags();
754 if (interrupt.intr_any && !i_flag)
755 goto handle_int;
756 ENDOP(4);
757
758
759 // Jump/branch group
760 case 0x4c: // JMP abs
761 adr = read_adr_abs();
762 jump(adr);
763 ENDOP(3);
764
765 case 0x6c: // JMP (ind)
766 adr = read_adr_abs();
767 adr = read_byte(adr) | (read_byte((adr + 1) & 0xff | adr & 0xff00) << 8);
768 jump(adr);
769 ENDOP(5);
770
771 case 0x20: // JSR abs
772 #if PC_IS_POINTER
773 push_byte((pc-pc_base+1) >> 8); push_byte(pc-pc_base+1);
774 #else
775 push_byte(pc+1 >> 8); push_byte(pc+1);
776 #endif
777 adr = read_adr_abs();
778 jump(adr);
779 ENDOP(6);
780
781 case 0x60: // RTS
782 adr = pop_byte(); // Split because of pop_byte ++sp side-effect
783 adr = (adr | pop_byte() << 8) + 1;
784 jump(adr);
785 ENDOP(6);
786
787 case 0x40: // RTI
788 pop_flags();
789 adr = pop_byte(); // Split because of pop_byte ++sp side-effect
790 adr = adr | pop_byte() << 8;
791 jump(adr);
792 if (interrupt.intr_any && !i_flag)
793 goto handle_int;
794 ENDOP(6);
795
796 case 0x00: // BRK
797 #if PC_IS_POINTER
798 push_byte((pc+1-pc_base) >> 8); push_byte(pc+1-pc_base);
799 #else
800 push_byte((pc+1) >> 8); push_byte(pc+1);
801 #endif
802 push_flags(true);
803 i_flag = true;
804 adr = read_word(0xfffe);
805 jump(adr);
806 ENDOP(7);
807
808 #if PC_IS_POINTER
809 #if PRECISE_CPU_CYCLES
810 #define Branch(flag) \
811 if (flag) { \
812 pc += (int8)*pc + 1; \
813 if (((pc-pc_base) ^ (old_pc - pc_base)) & 0xff00) { \
814 ENDOP(4); \
815 } else { \
816 ENDOP(3); \
817 } \
818 } else { \
819 pc++; \
820 ENDOP(2); \
821 }
822 #else
823 #define Branch(flag) \
824 if (flag) { \
825 pc += (int8)*pc + 1; \
826 ENDOP(3); \
827 } else { \
828 pc++; \
829 ENDOP(2); \
830 }
831 #endif
832 #else
833 #define Branch(flag) \
834 if (flag) { \
835 uint16 old_pc = pc; \
836 pc += (int8)read_byte(pc) + 1; \
837 if ((pc ^ old_pc) & 0xff00) { \
838 ENDOP(4); \
839 } else { \
840 ENDOP(3); \
841 } \
842 } else { \
843 pc++; \
844 ENDOP(2); \
845 }
846 #endif
847
848 case 0xb0: // BCS rel
849 Branch(c_flag);
850
851 case 0x90: // BCC rel
852 Branch(!c_flag);
853
854 case 0xf0: // BEQ rel
855 Branch(!z_flag);
856
857 case 0xd0: // BNE rel
858 Branch(z_flag);
859
860 case 0x70: // BVS rel
861 #ifndef IS_CPU_1541
862 Branch(v_flag);
863 #else
864 Branch((via2_pcr & 0x0e) == 0x0e ? 1 : v_flag); // GCR byte ready flag
865 #endif
866
867 case 0x50: // BVC rel
868 #ifndef IS_CPU_1541
869 Branch(!v_flag);
870 #else
871 Branch(!((via2_pcr & 0x0e) == 0x0e) ? 0 : v_flag); // GCR byte ready flag
872 #endif
873
874 case 0x30: // BMI rel
875 Branch(n_flag & 0x80);
876
877 case 0x10: // BPL rel
878 Branch(!(n_flag & 0x80));
879
880
881 // Flags group
882 case 0x38: // SEC
883 c_flag = true;
884 ENDOP(2);
885
886 case 0x18: // CLC
887 c_flag = false;
888 ENDOP(2);
889
890 case 0xf8: // SED
891 d_flag = true;
892 ENDOP(2);
893
894 case 0xd8: // CLD
895 d_flag = false;
896 ENDOP(2);
897
898 case 0x78: // SEI
899 i_flag = true;
900 ENDOP(2);
901
902 case 0x58: // CLI
903 i_flag = false;
904 if (interrupt.intr_any)
905 goto handle_int;
906 ENDOP(2);
907
908 case 0xb8: // CLV
909 v_flag = false;
910 ENDOP(2);
911
912
913 // NOP group
914 case 0xea: // NOP
915 ENDOP(2);
916
917
918 /*
919 * Undocumented opcodes start here
920 */
921
922 // NOP group
923 case 0x1a: // NOP
924 case 0x3a:
925 case 0x5a:
926 case 0x7a:
927 case 0xda:
928 case 0xfa:
929 ENDOP(2);
930
931 case 0x80: // NOP #imm
932 case 0x82:
933 case 0x89:
934 case 0xc2:
935 case 0xe2:
936 pc++;
937 ENDOP(2);
938
939 case 0x04: // NOP zero
940 case 0x44:
941 case 0x64:
942 pc++;
943 ENDOP(3);
944
945 case 0x14: // NOP zero,X
946 case 0x34:
947 case 0x54:
948 case 0x74:
949 case 0xd4:
950 case 0xf4:
951 pc++;
952 ENDOP(4);
953
954 case 0x0c: // NOP abs
955 pc+=2;
956 ENDOP(4);
957
958 case 0x1c: // NOP abs,X
959 case 0x3c:
960 case 0x5c:
961 case 0x7c:
962 case 0xdc:
963 case 0xfc:
964 #if PRECISE_CPU_CYCLES
965 read_byte_abs_x();
966 #else
967 pc+=2;
968 #endif
969 ENDOP(4);
970
971
972 // Load A/X group
973 case 0xa7: // LAX zero
974 set_nz(a = x = read_byte_zero());
975 ENDOP(3);
976
977 case 0xb7: // LAX zero,Y
978 set_nz(a = x = read_byte_zero_y());
979 ENDOP(4);
980
981 case 0xaf: // LAX abs
982 set_nz(a = x = read_byte_abs());
983 ENDOP(4);
984
985 case 0xbf: // LAX abs,Y
986 set_nz(a = x = read_byte_abs_y());
987 ENDOP(4);
988
989 case 0xa3: // LAX (ind,X)
990 set_nz(a = x = read_byte_ind_x());
991 ENDOP(6);
992
993 case 0xb3: // LAX (ind),Y
994 set_nz(a = x = read_byte_ind_y());
995 ENDOP(5);
996
997
998 // Store A/X group
999 case 0x87: // SAX zero
1000 write_byte(read_adr_zero(), a & x);
1001 ENDOP(3);
1002
1003 case 0x97: // SAX zero,Y
1004 write_byte(read_adr_zero_y(), a & x);
1005 ENDOP(4);
1006
1007 case 0x8f: // SAX abs
1008 write_byte(read_adr_abs(), a & x);
1009 ENDOP(4);
1010
1011 case 0x83: // SAX (ind,X)
1012 write_byte(read_adr_ind_x(), a & x);
1013 ENDOP(6);
1014
1015
1016 // ASL/ORA group
1017 #define ShiftLeftOr \
1018 c_flag = tmp & 0x80; \
1019 tmp <<= 1; \
1020 set_nz(a |= tmp);
1021
1022 case 0x07: // SLO zero
1023 tmp = read_zp(adr = read_adr_zero());
1024 ShiftLeftOr;
1025 write_zp(adr, tmp);
1026 ENDOP(5);
1027
1028 case 0x17: // SLO zero,X
1029 tmp = read_zp(adr = read_adr_zero_x());
1030 ShiftLeftOr;
1031 write_zp(adr, tmp);
1032 ENDOP(6);
1033
1034 case 0x0f: // SLO abs
1035 tmp = read_byte(adr = read_adr_abs());
1036 ShiftLeftOr;
1037 write_byte(adr, tmp);
1038 ENDOP(6);
1039
1040 case 0x1f: // SLO abs,X
1041 tmp = read_byte(adr = read_adr_abs_x());
1042 ShiftLeftOr;
1043 write_byte(adr, tmp);
1044 ENDOP(7);
1045
1046 case 0x1b: // SLO abs,Y
1047 tmp = read_byte(adr = read_adr_abs_y());
1048 ShiftLeftOr;
1049 write_byte(adr, tmp);
1050 ENDOP(7);
1051
1052 case 0x03: // SLO (ind,X)
1053 tmp = read_byte(adr = read_adr_ind_x());
1054 ShiftLeftOr;
1055 write_byte(adr, tmp);
1056 ENDOP(8);
1057
1058 case 0x13: // SLO (ind),Y
1059 tmp = read_byte(adr = read_adr_ind_y());
1060 ShiftLeftOr;
1061 write_byte(adr, tmp);
1062 ENDOP(8);
1063
1064
1065 // ROL/AND group
1066 #define RoLeftAnd \
1067 tmp2 = tmp & 0x80; \
1068 tmp = c_flag ? (tmp << 1) | 0x01 : tmp << 1; \
1069 set_nz(a &= tmp); \
1070 c_flag = tmp2;
1071
1072 case 0x27: // RLA zero
1073 tmp = read_zp(adr = read_adr_zero());
1074 RoLeftAnd;
1075 write_zp(adr, tmp);
1076 ENDOP(5);
1077
1078 case 0x37: // RLA zero,X
1079 tmp = read_zp(adr = read_adr_zero_x());
1080 RoLeftAnd;
1081 write_zp(adr, tmp);
1082 ENDOP(6);
1083
1084 case 0x2f: // RLA abs
1085 tmp = read_byte(adr = read_adr_abs());
1086 RoLeftAnd;
1087 write_byte(adr, tmp);
1088 ENDOP(6);
1089
1090 case 0x3f: // RLA abs,X
1091 tmp = read_byte(adr = read_adr_abs_x());
1092 RoLeftAnd;
1093 write_byte(adr, tmp);
1094 ENDOP(7);
1095
1096 case 0x3b: // RLA abs,Y
1097 tmp = read_byte(adr = read_adr_abs_y());
1098 RoLeftAnd;
1099 write_byte(adr, tmp);
1100 ENDOP(7);
1101
1102 case 0x23: // RLA (ind,X)
1103 tmp = read_byte(adr = read_adr_ind_x());
1104 RoLeftAnd;
1105 write_byte(adr, tmp);
1106 ENDOP(8);
1107
1108 case 0x33: // RLA (ind),Y
1109 tmp = read_byte(adr = read_adr_ind_y());
1110 RoLeftAnd;
1111 write_byte(adr, tmp);
1112 ENDOP(8);
1113
1114
1115 // LSR/EOR group
1116 #define ShiftRightEor \
1117 c_flag = tmp & 0x01; \
1118 tmp >>= 1; \
1119 set_nz(a ^= tmp);
1120
1121 case 0x47: // SRE zero
1122 tmp = read_zp(adr = read_adr_zero());
1123 ShiftRightEor;
1124 write_zp(adr, tmp);
1125 ENDOP(5);
1126
1127 case 0x57: // SRE zero,X
1128 tmp = read_zp(adr = read_adr_zero_x());
1129 ShiftRightEor;
1130 write_zp(adr, tmp);
1131 ENDOP(6);
1132
1133 case 0x4f: // SRE abs
1134 tmp = read_byte(adr = read_adr_abs());
1135 ShiftRightEor;
1136 write_byte(adr, tmp);
1137 ENDOP(6);
1138
1139 case 0x5f: // SRE abs,X
1140 tmp = read_byte(adr = read_adr_abs_x());
1141 ShiftRightEor;
1142 write_byte(adr, tmp);
1143 ENDOP(7);
1144
1145 case 0x5b: // SRE abs,Y
1146 tmp = read_byte(adr = read_adr_abs_y());
1147 ShiftRightEor;
1148 write_byte(adr, tmp);
1149 ENDOP(7);
1150
1151 case 0x43: // SRE (ind,X)
1152 tmp = read_byte(adr = read_adr_ind_x());
1153 ShiftRightEor;
1154 write_byte(adr, tmp);
1155 ENDOP(8);
1156
1157 case 0x53: // SRE (ind),Y
1158 tmp = read_byte(adr = read_adr_ind_y());
1159 ShiftRightEor;
1160 write_byte(adr, tmp);
1161 ENDOP(8);
1162
1163
1164 // ROR/ADC group
1165 #define RoRightAdc \
1166 tmp2 = tmp & 0x01; \
1167 tmp = c_flag ? (tmp >> 1) | 0x80 : tmp >> 1; \
1168 c_flag = tmp2; \
1169 do_adc(tmp);
1170
1171 case 0x67: // RRA zero
1172 tmp = read_zp(adr = read_adr_zero());
1173 RoRightAdc;
1174 write_zp(adr, tmp);
1175 ENDOP(5);
1176
1177 case 0x77: // RRA zero,X
1178 tmp = read_zp(adr = read_adr_zero_x());
1179 RoRightAdc;
1180 write_zp(adr, tmp);
1181 ENDOP(6);
1182
1183 case 0x6f: // RRA abs
1184 tmp = read_byte(adr = read_adr_abs());
1185 RoRightAdc;
1186 write_byte(adr, tmp);
1187 ENDOP(6);
1188
1189 case 0x7f: // RRA abs,X
1190 tmp = read_byte(adr = read_adr_abs_x());
1191 RoRightAdc;
1192 write_byte(adr, tmp);
1193 ENDOP(7);
1194
1195 case 0x7b: // RRA abs,Y
1196 tmp = read_byte(adr = read_adr_abs_y());
1197 RoRightAdc;
1198 write_byte(adr, tmp);
1199 ENDOP(7);
1200
1201 case 0x63: // RRA (ind,X)
1202 tmp = read_byte(adr = read_adr_ind_x());
1203 RoRightAdc;
1204 write_byte(adr, tmp);
1205 ENDOP(8);
1206
1207 case 0x73: // RRA (ind),Y
1208 tmp = read_byte(adr = read_adr_ind_y());
1209 RoRightAdc;
1210 write_byte(adr, tmp);
1211 ENDOP(8);
1212
1213
1214 // DEC/CMP group
1215 #define DecCompare \
1216 set_nz(adr = a - tmp); \
1217 c_flag = adr < 0x100;
1218
1219 case 0xc7: // DCP zero
1220 tmp = read_zp(adr = read_adr_zero()) - 1;
1221 write_zp(adr, tmp);
1222 DecCompare;
1223 ENDOP(5);
1224
1225 case 0xd7: // DCP zero,X
1226 tmp = read_zp(adr = read_adr_zero_x()) - 1;
1227 write_zp(adr, tmp);
1228 DecCompare;
1229 ENDOP(6);
1230
1231 case 0xcf: // DCP abs
1232 tmp = read_byte(adr = read_adr_abs()) - 1;
1233 write_byte(adr, tmp);
1234 DecCompare;
1235 ENDOP(6);
1236
1237 case 0xdf: // DCP abs,X
1238 tmp = read_byte(adr = read_adr_abs_x()) - 1;
1239 write_byte(adr, tmp);
1240 DecCompare;
1241 ENDOP(7);
1242
1243 case 0xdb: // DCP abs,Y
1244 tmp = read_byte(adr = read_adr_abs_y()) - 1;
1245 write_byte(adr, tmp);
1246 DecCompare;
1247 ENDOP(7);
1248
1249 case 0xc3: // DCP (ind,X)
1250 tmp = read_byte(adr = read_adr_ind_x()) - 1;
1251 write_byte(adr, tmp);
1252 DecCompare;
1253 ENDOP(8);
1254
1255 case 0xd3: // DCP (ind),Y
1256 tmp = read_byte(adr = read_adr_ind_y()) - 1;
1257 write_byte(adr, tmp);
1258 DecCompare;
1259 ENDOP(8);
1260
1261
1262 // INC/SBC group
1263 case 0xe7: // ISB zero
1264 tmp = read_zp(adr = read_adr_zero()) + 1;
1265 do_sbc(tmp);
1266 write_zp(adr, tmp);
1267 ENDOP(5);
1268
1269 case 0xf7: // ISB zero,X
1270 tmp = read_zp(adr = read_adr_zero_x()) + 1;
1271 do_sbc(tmp);
1272 write_zp(adr, tmp);
1273 ENDOP(6);
1274
1275 case 0xef: // ISB abs
1276 tmp = read_byte(adr = read_adr_abs()) + 1;
1277 do_sbc(tmp);
1278 write_byte(adr, tmp);
1279 ENDOP(6);
1280
1281 case 0xff: // ISB abs,X
1282 tmp = read_byte(adr = read_adr_abs_x()) + 1;
1283 do_sbc(tmp);
1284 write_byte(adr, tmp);
1285 ENDOP(7);
1286
1287 case 0xfb: // ISB abs,Y
1288 tmp = read_byte(adr = read_adr_abs_y()) + 1;
1289 do_sbc(tmp);
1290 write_byte(adr, tmp);
1291 ENDOP(7);
1292
1293 case 0xe3: // ISB (ind,X)
1294 tmp = read_byte(adr = read_adr_ind_x()) + 1;
1295 do_sbc(tmp);
1296 write_byte(adr, tmp);
1297 ENDOP(8);
1298
1299 case 0xf3: // ISB (ind),Y
1300 tmp = read_byte(adr = read_adr_ind_y()) + 1;
1301 do_sbc(tmp);
1302 write_byte(adr, tmp);
1303 ENDOP(8);
1304
1305
1306 // Complex functions
1307 case 0x0b: // ANC #imm
1308 case 0x2b:
1309 set_nz(a &= read_byte_imm());
1310 c_flag = n_flag & 0x80;
1311 ENDOP(2);
1312
1313 case 0x4b: // ASR #imm
1314 a &= read_byte_imm();
1315 c_flag = a & 0x01;
1316 set_nz(a >>= 1);
1317 ENDOP(2);
1318
1319 case 0x6b: // ARR #imm
1320 tmp2 = read_byte_imm() & a;
1321 a = (c_flag ? (tmp2 >> 1) | 0x80 : tmp2 >> 1);
1322 if (!d_flag) {
1323 set_nz(a);
1324 c_flag = a & 0x40;
1325 v_flag = (a & 0x40) ^ ((a & 0x20) << 1);
1326 } else {
1327 n_flag = c_flag ? 0x80 : 0;
1328 z_flag = a;
1329 v_flag = (tmp2 ^ a) & 0x40;
1330 if ((tmp2 & 0x0f) + (tmp2 & 0x01) > 5)
1331 a = a & 0xf0 | (a + 6) & 0x0f;
1332 if ((c_flag = ((tmp2 + (tmp2 & 0x10)) & 0x1f0) > 0x50) != 0)
1333 a += 0x60;
1334 }
1335 ENDOP(2);
1336
1337 case 0x8b: // ANE #imm
1338 set_nz(a = read_byte_imm() & x & (a | 0xee));
1339 ENDOP(2);
1340
1341 case 0x93: // SHA (ind),Y
1342 #if PC_IS_POINTER
1343 tmp2 = read_zp(pc[0] + 1);
1344 #else
1345 tmp2 = read_zp(read_byte(pc) + 1);
1346 #endif
1347 write_byte(read_adr_ind_y(), a & x & (tmp2+1));
1348 ENDOP(6);
1349
1350 case 0x9b: // SHS abs,Y
1351 #if PC_IS_POINTER
1352 tmp2 = pc[1];
1353 #else
1354 tmp2 = read_byte(pc+1);
1355 #endif
1356 write_byte(read_adr_abs_y(), a & x & (tmp2+1));
1357 sp = a & x;
1358 ENDOP(5);
1359
1360 case 0x9c: // SHY abs,X
1361 #if PC_IS_POINTER
1362 tmp2 = pc[1];
1363 #else
1364 tmp2 = read_byte(pc+1);
1365 #endif
1366 write_byte(read_adr_abs_x(), y & (tmp2+1));
1367 ENDOP(5);
1368
1369 case 0x9e: // SHX abs,Y
1370 #if PC_IS_POINTER
1371 tmp2 = pc[1];
1372 #else
1373 tmp2 = read_byte(pc+1);
1374 #endif
1375 write_byte(read_adr_abs_y(), x & (tmp2+1));
1376 ENDOP(5);
1377
1378 case 0x9f: // SHA abs,Y
1379 #if PC_IS_POINTER
1380 tmp2 = pc[1];
1381 #else
1382 tmp2 = read_byte(pc+1);
1383 #endif
1384 write_byte(read_adr_abs_y(), a & x & (tmp2+1));
1385 ENDOP(5);
1386
1387 case 0xab: // LXA #imm
1388 set_nz(a = x = (a | 0xee) & read_byte_imm());
1389 ENDOP(2);
1390
1391 case 0xbb: // LAS abs,Y
1392 set_nz(a = x = sp = read_byte_abs_y() & sp);
1393 ENDOP(4);
1394
1395 case 0xcb: // SBX #imm
1396 x &= a;
1397 adr = x - read_byte_imm();
1398 c_flag = adr < 0x100;
1399 set_nz(x = adr);
1400 ENDOP(2);
1401
1402 case 0x02:
1403 case 0x12:
1404 case 0x22:
1405 case 0x32:
1406 case 0x42:
1407 case 0x52:
1408 case 0x62:
1409 case 0x72:
1410 case 0x92:
1411 case 0xb2:
1412 case 0xd2:
1413 #if PC_IS_POINTER
1414 illegal_op(*(pc-1), pc-pc_base-1);
1415 #else
1416 illegal_op(read_byte(pc-1), pc-1);
1417 #endif
1418 break;