ViewVC Help
View File | Revision Log | Show Annotations | Revision Graph | Root Listing
root/cebix/Frodo4/Src/CPU_emulcycle.h
Revision: 1.7
Committed: 2010-04-22T15:08:18Z (13 years, 11 months ago) by cebix
Content type: text/plain
Branch: MAIN
CVS Tags: HEAD
Changes since 1.6: +15 -9 lines
Log Message:
better interrupt timing

File Contents

# Content
1 /*
2 * CPU_emulcycle.h - SC 6510/6502 emulation core (body of
3 * EmulateCycle() 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 * Stack macros
26 */
27
28 // Pop processor flags from the stack
29 #define pop_flags() \
30 read_to(sp | 0x100, data); \
31 n_flag = data; \
32 v_flag = data & 0x40; \
33 d_flag = data & 0x08; \
34 i_flag = data & 0x04; \
35 z_flag = !(data & 0x02); \
36 c_flag = data & 0x01;
37
38 // Push processor flags onto the stack
39 #define push_flags(b_flag) \
40 data = 0x20 | (n_flag & 0x80); \
41 if (v_flag) data |= 0x40; \
42 if (b_flag) data |= 0x10; \
43 if (d_flag) data |= 0x08; \
44 if (i_flag) data |= 0x04; \
45 if (!z_flag) data |= 0x02; \
46 if (c_flag) data |= 0x01; \
47 write_byte(sp-- | 0x100, data);
48
49
50 /*
51 * Other macros
52 */
53
54 // Branch (cycle 1)
55 #define Branch(flag) \
56 read_to(pc++, data); \
57 if (flag) { \
58 ar = pc + (int8)data; \
59 if ((ar >> 8) != (pc >> 8)) { \
60 if (data & 0x80) \
61 state = O_BRANCH_BP; \
62 else \
63 state = O_BRANCH_FP; \
64 } else \
65 state = O_BRANCH_NP; \
66 } else \
67 state = 0; \
68 break;
69
70 // Set N and Z flags according to byte
71 #define set_nz(x) (z_flag = n_flag = (x))
72
73 // Address fetch of RMW instruction done, now read and write operand
74 #define DoRMW state = RMW_DO_IT; break;
75
76 // Operand fetch done, now execute opcode
77 #define Execute state = OpTab[op]; break;
78
79 // Last cycle of opcode
80 #define Last state = 0; break;
81
82
83 /*
84 * EmulCycle() function
85 */
86
87 switch (state) {
88
89
90 // Opcode fetch (cycle 0)
91 case 0:
92 read_to(pc++, op);
93 state = ModeTab[op];
94 opflags = 0;
95 break;
96
97
98 // IRQ
99 case 0x0008:
100 read_idle(pc);
101 state = 0x0009;
102 break;
103 case 0x0009:
104 read_idle(pc);
105 state = 0x000a;
106 break;
107 case 0x000a:
108 write_byte(sp-- | 0x100, pc >> 8);
109 state = 0x000b;
110 break;
111 case 0x000b:
112 write_byte(sp-- | 0x100, pc);
113 state = 0x000c;
114 break;
115 case 0x000c:
116 push_flags(false);
117 i_flag = true;
118 state = 0x000d;
119 break;
120 case 0x000d:
121 read_to(0xfffe, pc);
122 state = 0x000e;
123 break;
124 case 0x000e:
125 read_to(0xffff, data);
126 pc |= data << 8;
127 Last;
128
129
130 // NMI
131 case 0x0010:
132 read_idle(pc);
133 state = 0x0011;
134 break;
135 case 0x0011:
136 read_idle(pc);
137 state = 0x0012;
138 break;
139 case 0x0012:
140 write_byte(sp-- | 0x100, pc >> 8);
141 state = 0x0013;
142 break;
143 case 0x0013:
144 write_byte(sp-- | 0x100, pc);
145 state = 0x0014;
146 break;
147 case 0x0014:
148 push_flags(false);
149 i_flag = true;
150 state = 0x0015;
151 break;
152 case 0x0015:
153 read_to(0xfffa, pc);
154 state = 0x0016;
155 break;
156 case 0x0016:
157 read_to(0xfffb, data);
158 pc |= data << 8;
159 Last;
160
161
162 // Addressing modes: Fetch effective address, no extra cycles (-> ar)
163 case A_ZERO:
164 read_to(pc++, ar);
165 Execute;
166
167 case A_ZEROX:
168 read_to(pc++, ar);
169 state = A_ZEROX1;
170 break;
171 case A_ZEROX1:
172 read_idle(ar);
173 ar = (ar + x) & 0xff;
174 Execute;
175
176 case A_ZEROY:
177 read_to(pc++, ar);
178 state = A_ZEROY1;
179 break;
180 case A_ZEROY1:
181 read_idle(ar);
182 ar = (ar + y) & 0xff;
183 Execute;
184
185 case A_ABS:
186 read_to(pc++, ar);
187 state = A_ABS1;
188 break;
189 case A_ABS1:
190 read_to(pc++, data);
191 ar = ar | (data << 8);
192 Execute;
193
194 case A_ABSX:
195 read_to(pc++, ar);
196 state = A_ABSX1;
197 break;
198 case A_ABSX1:
199 read_to(pc++, ar2); // Note: Some undocumented opcodes rely on the value of ar2
200 if (ar+x < 0x100)
201 state = A_ABSX2;
202 else
203 state = A_ABSX3;
204 ar = (ar + x) & 0xff | (ar2 << 8);
205 break;
206 case A_ABSX2: // No page crossed
207 read_idle(ar);
208 Execute;
209 case A_ABSX3: // Page crossed
210 read_idle(ar);
211 ar += 0x100;
212 Execute;
213
214 case A_ABSY:
215 read_to(pc++, ar);
216 state = A_ABSY1;
217 break;
218 case A_ABSY1:
219 read_to(pc++, ar2); // Note: Some undocumented opcodes rely on the value of ar2
220 if (ar+y < 0x100)
221 state = A_ABSY2;
222 else
223 state = A_ABSY3;
224 ar = (ar + y) & 0xff | (ar2 << 8);
225 break;
226 case A_ABSY2: // No page crossed
227 read_idle(ar);
228 Execute;
229 case A_ABSY3: // Page crossed
230 read_idle(ar);
231 ar += 0x100;
232 Execute;
233
234 case A_INDX:
235 read_to(pc++, ar2);
236 state = A_INDX1;
237 break;
238 case A_INDX1:
239 read_idle(ar2);
240 ar2 = (ar2 + x) & 0xff;
241 state = A_INDX2;
242 break;
243 case A_INDX2:
244 read_to(ar2, ar);
245 state = A_INDX3;
246 break;
247 case A_INDX3:
248 read_to((ar2 + 1) & 0xff, data);
249 ar = ar | (data << 8);
250 Execute;
251
252 case A_INDY:
253 read_to(pc++, ar2);
254 state = A_INDY1;
255 break;
256 case A_INDY1:
257 read_to(ar2, ar);
258 state = A_INDY2;
259 break;
260 case A_INDY2:
261 read_to((ar2 + 1) & 0xff, ar2); // Note: Some undocumented opcodes rely on the value of ar2
262 if (ar+y < 0x100)
263 state = A_INDY3;
264 else
265 state = A_INDY4;
266 ar = (ar + y) & 0xff | (ar2 << 8);
267 break;
268 case A_INDY3: // No page crossed
269 read_idle(ar);
270 Execute;
271 case A_INDY4: // Page crossed
272 read_idle(ar);
273 ar += 0x100;
274 Execute;
275
276
277 // Addressing modes: Fetch effective address, extra cycle on page crossing (-> ar)
278 case AE_ABSX:
279 read_to(pc++, ar);
280 state = AE_ABSX1;
281 break;
282 case AE_ABSX1:
283 read_to(pc++, data);
284 if (ar+x < 0x100) {
285 ar = (ar + x) & 0xff | (data << 8);
286 Execute;
287 } else {
288 ar = (ar + x) & 0xff | (data << 8);
289 state = AE_ABSX2;
290 }
291 break;
292 case AE_ABSX2: // Page crossed
293 read_idle(ar);
294 ar += 0x100;
295 Execute;
296
297 case AE_ABSY:
298 read_to(pc++, ar);
299 state = AE_ABSY1;
300 break;
301 case AE_ABSY1:
302 read_to(pc++, data);
303 if (ar+y < 0x100) {
304 ar = (ar + y) & 0xff | (data << 8);
305 Execute;
306 } else {
307 ar = (ar + y) & 0xff | (data << 8);
308 state = AE_ABSY2;
309 }
310 break;
311 case AE_ABSY2: // Page crossed
312 read_idle(ar);
313 ar += 0x100;
314 Execute;
315
316 case AE_INDY:
317 read_to(pc++, ar2);
318 state = AE_INDY1;
319 break;
320 case AE_INDY1:
321 read_to(ar2, ar);
322 state = AE_INDY2;
323 break;
324 case AE_INDY2:
325 read_to((ar2 + 1) & 0xff, data);
326 if (ar+y < 0x100) {
327 ar = (ar + y) & 0xff | (data << 8);
328 Execute;
329 } else {
330 ar = (ar + y) & 0xff | (data << 8);
331 state = AE_INDY3;
332 }
333 break;
334 case AE_INDY3: // Page crossed
335 read_idle(ar);
336 ar += 0x100;
337 Execute;
338
339
340 // Addressing modes: Read operand, write it back, no extra cycles (-> ar, rdbuf)
341 case M_ZERO:
342 read_to(pc++, ar);
343 DoRMW;
344
345 case M_ZEROX:
346 read_to(pc++, ar);
347 state = M_ZEROX1;
348 break;
349 case M_ZEROX1:
350 read_idle(ar);
351 ar = (ar + x) & 0xff;
352 DoRMW;
353
354 case M_ZEROY:
355 read_to(pc++, ar);
356 state = M_ZEROY1;
357 break;
358 case M_ZEROY1:
359 read_idle(ar);
360 ar = (ar + y) & 0xff;
361 DoRMW;
362
363 case M_ABS:
364 read_to(pc++, ar);
365 state = M_ABS1;
366 break;
367 case M_ABS1:
368 read_to(pc++, data);
369 ar = ar | (data << 8);
370 DoRMW;
371
372 case M_ABSX:
373 read_to(pc++, ar);
374 state = M_ABSX1;
375 break;
376 case M_ABSX1:
377 read_to(pc++, data);
378 if (ar+x < 0x100)
379 state = M_ABSX2;
380 else
381 state = M_ABSX3;
382 ar = (ar + x) & 0xff | (data << 8);
383 break;
384 case M_ABSX2: // No page crossed
385 read_idle(ar);
386 DoRMW;
387 case M_ABSX3: // Page crossed
388 read_idle(ar);
389 ar += 0x100;
390 DoRMW;
391
392 case M_ABSY:
393 read_to(pc++, ar);
394 state = M_ABSY1;
395 break;
396 case M_ABSY1:
397 read_to(pc++, data);
398 if (ar+y < 0x100)
399 state = M_ABSY2;
400 else
401 state = M_ABSY3;
402 ar = (ar + y) & 0xff | (data << 8);
403 break;
404 case M_ABSY2: // No page crossed
405 read_idle(ar);
406 DoRMW;
407 case M_ABSY3: // Page crossed
408 read_idle(ar);
409 ar += 0x100;
410 DoRMW;
411
412 case M_INDX:
413 read_to(pc++, ar2);
414 state = M_INDX1;
415 break;
416 case M_INDX1:
417 read_idle(ar2);
418 ar2 = (ar2 + x) & 0xff;
419 state = M_INDX2;
420 break;
421 case M_INDX2:
422 read_to(ar2, ar);
423 state = M_INDX3;
424 break;
425 case M_INDX3:
426 read_to((ar2 + 1) & 0xff, data);
427 ar = ar | (data << 8);
428 DoRMW;
429
430 case M_INDY:
431 read_to(pc++, ar2);
432 state = M_INDY1;
433 break;
434 case M_INDY1:
435 read_to(ar2, ar);
436 state = M_INDY2;
437 break;
438 case M_INDY2:
439 read_to((ar2 + 1) & 0xff, data);
440 if (ar+y < 0x100)
441 state = M_INDY3;
442 else
443 state = M_INDY4;
444 ar = (ar + y) & 0xff | (data << 8);
445 break;
446 case M_INDY3: // No page crossed
447 read_idle(ar);
448 DoRMW;
449 case M_INDY4: // Page crossed
450 read_idle(ar);
451 ar += 0x100;
452 DoRMW;
453
454 case RMW_DO_IT:
455 read_to(ar, rdbuf);
456 state = RMW_DO_IT1;
457 break;
458 case RMW_DO_IT1:
459 write_byte(ar, rdbuf);
460 Execute;
461
462
463 // Load group
464 case O_LDA:
465 read_to(ar, data);
466 set_nz(a = data);
467 Last;
468 case O_LDA_I:
469 read_to(pc++, data);
470 set_nz(a = data);
471 Last;
472
473 case O_LDX:
474 read_to(ar, data);
475 set_nz(x = data);
476 Last;
477 case O_LDX_I:
478 read_to(pc++, data);
479 set_nz(x = data);
480 Last;
481
482 case O_LDY:
483 read_to(ar, data);
484 set_nz(y = data);
485 Last;
486 case O_LDY_I:
487 read_to(pc++, data);
488 set_nz(y = data);
489 Last;
490
491
492 // Store group
493 case O_STA:
494 write_byte(ar, a);
495 Last;
496
497 case O_STX:
498 write_byte(ar, x);
499 Last;
500
501 case O_STY:
502 write_byte(ar, y);
503 Last;
504
505
506 // Transfer group
507 case O_TAX:
508 read_idle(pc);
509 set_nz(x = a);
510 Last;
511
512 case O_TXA:
513 read_idle(pc);
514 set_nz(a = x);
515 Last;
516
517 case O_TAY:
518 read_idle(pc);
519 set_nz(y = a);
520 Last;
521
522 case O_TYA:
523 read_idle(pc);
524 set_nz(a = y);
525 Last;
526
527 case O_TSX:
528 read_idle(pc);
529 set_nz(x = sp);
530 Last;
531
532 case O_TXS:
533 read_idle(pc);
534 sp = x;
535 Last;
536
537
538 // Arithmetic group
539 case O_ADC:
540 read_to(ar, data);
541 do_adc(data);
542 Last;
543 case O_ADC_I:
544 read_to(pc++, data);
545 do_adc(data);
546 Last;
547
548 case O_SBC:
549 read_to(ar, data);
550 do_sbc(data);
551 Last;
552 case O_SBC_I:
553 read_to(pc++, data);
554 do_sbc(data);
555 Last;
556
557
558 // Increment/decrement group
559 case O_INX:
560 read_idle(pc);
561 set_nz(++x);
562 Last;
563
564 case O_DEX:
565 read_idle(pc);
566 set_nz(--x);
567 Last;
568
569 case O_INY:
570 read_idle(pc);
571 set_nz(++y);
572 Last;
573
574 case O_DEY:
575 read_idle(pc);
576 set_nz(--y);
577 Last;
578
579 case O_INC:
580 write_byte(ar, set_nz(rdbuf + 1));
581 Last;
582
583 case O_DEC:
584 write_byte(ar, set_nz(rdbuf - 1));
585 Last;
586
587
588 // Logic group
589 case O_AND:
590 read_to(ar, data);
591 set_nz(a &= data);
592 Last;
593 case O_AND_I:
594 read_to(pc++, data);
595 set_nz(a &= data);
596 Last;
597
598 case O_ORA:
599 read_to(ar, data);
600 set_nz(a |= data);
601 Last;
602 case O_ORA_I:
603 read_to(pc++, data);
604 set_nz(a |= data);
605 Last;
606
607 case O_EOR:
608 read_to(ar, data);
609 set_nz(a ^= data);
610 Last;
611 case O_EOR_I:
612 read_to(pc++, data);
613 set_nz(a ^= data);
614 Last;
615
616 // Compare group
617 case O_CMP:
618 read_to(ar, data);
619 set_nz(ar = a - data);
620 c_flag = ar < 0x100;
621 Last;
622 case O_CMP_I:
623 read_to(pc++, data);
624 set_nz(ar = a - data);
625 c_flag = ar < 0x100;
626 Last;
627
628 case O_CPX:
629 read_to(ar, data);
630 set_nz(ar = x - data);
631 c_flag = ar < 0x100;
632 Last;
633 case O_CPX_I:
634 read_to(pc++, data);
635 set_nz(ar = x - data);
636 c_flag = ar < 0x100;
637 Last;
638
639 case O_CPY:
640 read_to(ar, data);
641 set_nz(ar = y - data);
642 c_flag = ar < 0x100;
643 Last;
644 case O_CPY_I:
645 read_to(pc++, data);
646 set_nz(ar = y - data);
647 c_flag = ar < 0x100;
648 Last;
649
650
651 // Bit-test group
652 case O_BIT:
653 read_to(ar, data);
654 z_flag = a & data;
655 n_flag = data;
656 v_flag = data & 0x40;
657 Last;
658
659
660 // Shift/rotate group
661 case O_ASL:
662 c_flag = rdbuf & 0x80;
663 write_byte(ar, set_nz(rdbuf << 1));
664 Last;
665 case O_ASL_A:
666 read_idle(pc);
667 c_flag = a & 0x80;
668 set_nz(a <<= 1);
669 Last;
670
671 case O_LSR:
672 c_flag = rdbuf & 0x01;
673 write_byte(ar, set_nz(rdbuf >> 1));
674 Last;
675 case O_LSR_A:
676 read_idle(pc);
677 c_flag = a & 0x01;
678 set_nz(a >>= 1);
679 Last;
680
681 case O_ROL:
682 write_byte(ar, set_nz(c_flag ? (rdbuf << 1) | 0x01 : rdbuf << 1));
683 c_flag = rdbuf & 0x80;
684 Last;
685 case O_ROL_A:
686 read_idle(pc);
687 data = a & 0x80;
688 set_nz(a = c_flag ? (a << 1) | 0x01 : a << 1);
689 c_flag = data;
690 Last;
691
692 case O_ROR:
693 write_byte(ar, set_nz(c_flag ? (rdbuf >> 1) | 0x80 : rdbuf >> 1));
694 c_flag = rdbuf & 0x01;
695 Last;
696 case O_ROR_A:
697 read_idle(pc);
698 data = a & 0x01;
699 set_nz(a = (c_flag ? (a >> 1) | 0x80 : a >> 1));
700 c_flag = data;
701 Last;
702
703
704 // Stack group
705 case O_PHA:
706 read_idle(pc);
707 state = O_PHA1;
708 break;
709 case O_PHA1:
710 write_byte(sp-- | 0x100, a);
711 Last;
712
713 case O_PLA:
714 read_idle(pc);
715 state = O_PLA1;
716 break;
717 case O_PLA1:
718 read_idle(sp++ | 0x100);
719 state = O_PLA2;
720 break;
721 case O_PLA2:
722 read_to(sp | 0x100, data);
723 set_nz(a = data);
724 Last;
725
726 case O_PHP:
727 read_idle(pc);
728 state = O_PHP1;
729 break;
730 case O_PHP1:
731 push_flags(true);
732 Last;
733
734 case O_PLP:
735 read_idle(pc);
736 state = O_PLP1;
737 break;
738 case O_PLP1:
739 read_idle(sp++ | 0x100);
740 state = O_PLP2;
741 break;
742 case O_PLP2: {
743 bool old_i_flag = i_flag;
744 pop_flags();
745 if (!old_i_flag && i_flag) {
746 opflags |= OPFLAG_IRQ_DISABLED;
747 } else if (old_i_flag && !i_flag) {
748 opflags |= OPFLAG_IRQ_ENABLED;
749 }
750 Last;
751 }
752
753
754 // Jump/branch group
755 case O_JMP:
756 read_to(pc++, ar);
757 state = O_JMP1;
758 break;
759 case O_JMP1:
760 read_to(pc, data);
761 pc = (data << 8) | ar;
762 Last;
763
764 case O_JMP_I:
765 read_to(ar, pc);
766 state = O_JMP_I1;
767 break;
768 case O_JMP_I1:
769 read_to((ar + 1) & 0xff | ar & 0xff00, data);
770 pc |= data << 8;
771 Last;
772
773 case O_JSR:
774 read_to(pc++, ar);
775 state = O_JSR1;
776 break;
777 case O_JSR1:
778 read_idle(sp | 0x100);
779 state = O_JSR2;
780 break;
781 case O_JSR2:
782 write_byte(sp-- | 0x100, pc >> 8);
783 state = O_JSR3;
784 break;
785 case O_JSR3:
786 write_byte(sp-- | 0x100, pc);
787 state = O_JSR4;
788 break;
789 case O_JSR4:
790 read_to(pc++, data);
791 pc = ar | (data << 8);
792 Last;
793
794 case O_RTS:
795 read_idle(pc);
796 state = O_RTS1;
797 break;
798 case O_RTS1:
799 read_idle(sp++ | 0x100);
800 state = O_RTS2;
801 break;
802 case O_RTS2:
803 read_to(sp++ | 0x100, pc);
804 state = O_RTS3;
805 break;
806 case O_RTS3:
807 read_to(sp | 0x100, data);
808 pc |= data << 8;
809 state = O_RTS4;
810 break;
811 case O_RTS4:
812 read_idle(pc++);
813 Last;
814
815 case O_RTI:
816 read_idle(pc);
817 state = O_RTI1;
818 break;
819 case O_RTI1:
820 read_idle(sp++ | 0x100);
821 state = O_RTI2;
822 break;
823 case O_RTI2:
824 pop_flags();
825 sp++;
826 state = O_RTI3;
827 break;
828 case O_RTI3:
829 read_to(sp++ | 0x100, pc);
830 state = O_RTI4;
831 break;
832 case O_RTI4:
833 read_to(sp | 0x100, data);
834 pc |= data << 8;
835 Last;
836
837 case O_BRK:
838 read_idle(pc++);
839 state = O_BRK1;
840 break;
841 case O_BRK1:
842 write_byte(sp-- | 0x100, pc >> 8);
843 state = O_BRK2;
844 break;
845 case O_BRK2:
846 write_byte(sp-- | 0x100, pc);
847 state = O_BRK3;
848 break;
849 case O_BRK3:
850 push_flags(true);
851 i_flag = true;
852 #ifndef IS_CPU_1541
853 if (interrupt.intr[INT_NMI]) { // BRK interrupted by NMI?
854 interrupt.intr[INT_NMI] = false; // Simulate an edge-triggered input
855 state = 0x0015; // Jump to NMI sequence
856 break;
857 }
858 #endif
859 state = O_BRK4;
860 break;
861 case O_BRK4:
862 read_to(0xfffe, pc);
863 state = O_BRK5;
864 break;
865 case O_BRK5:
866 read_to(0xffff, data);
867 pc |= data << 8;
868 Last;
869
870 case O_BCS:
871 Branch(c_flag);
872
873 case O_BCC:
874 Branch(!c_flag);
875
876 case O_BEQ:
877 Branch(!z_flag);
878
879 case O_BNE:
880 Branch(z_flag);
881
882 case O_BVS:
883 #ifndef IS_CPU_1541
884 Branch(v_flag);
885 #else
886 Branch((via2_pcr & 0x0e) == 0x0e ? 1 : v_flag); // GCR byte ready flag
887 #endif
888
889 case O_BVC:
890 #ifndef IS_CPU_1541
891 Branch(!v_flag);
892 #else
893 Branch(!((via2_pcr & 0x0e) == 0x0e) ? 0 : v_flag); // GCR byte ready flag
894 #endif
895
896 case O_BMI:
897 Branch(n_flag & 0x80);
898
899 case O_BPL:
900 Branch(!(n_flag & 0x80));
901
902 case O_BRANCH_NP: // No page crossed
903 opflags |= OPFLAG_INT_DELAYED;
904 read_idle(pc);
905 pc = ar;
906 Last;
907 case O_BRANCH_BP: // Page crossed, branch backwards
908 read_idle(pc);
909 pc = ar;
910 state = O_BRANCH_BP1;
911 break;
912 case O_BRANCH_BP1:
913 read_idle(pc + 0x100);
914 Last;
915 case O_BRANCH_FP: // Page crossed, branch forwards
916 read_idle(pc);
917 pc = ar;
918 state = O_BRANCH_FP1;
919 break;
920 case O_BRANCH_FP1:
921 read_idle(pc - 0x100);
922 Last;
923
924
925 // Flag group
926 case O_SEC:
927 read_idle(pc);
928 c_flag = true;
929 Last;
930
931 case O_CLC:
932 read_idle(pc);
933 c_flag = false;
934 Last;
935
936 case O_SED:
937 read_idle(pc);
938 d_flag = true;
939 Last;
940
941 case O_CLD:
942 read_idle(pc);
943 d_flag = false;
944 Last;
945
946 case O_SEI:
947 read_idle(pc);
948 if (!i_flag)
949 opflags |= OPFLAG_IRQ_DISABLED;
950 i_flag = true;
951 Last;
952
953 case O_CLI:
954 read_idle(pc);
955 if (i_flag)
956 opflags |= OPFLAG_IRQ_ENABLED;
957 i_flag = false;
958 Last;
959
960 case O_CLV:
961 read_idle(pc);
962 v_flag = false;
963 Last;
964
965
966 // NOP group
967 case O_NOP:
968 read_idle(pc);
969 Last;
970
971
972 /*
973 * Undocumented opcodes start here
974 */
975
976 // NOP group
977 case O_NOP_I:
978 read_idle(pc++);
979 Last;
980
981 case O_NOP_A:
982 read_idle(ar);
983 Last;
984
985
986 // Load A/X group
987 case O_LAX:
988 read_to(ar, data);
989 set_nz(a = x = data);
990 Last;
991
992
993 // Store A/X group
994 case O_SAX:
995 write_byte(ar, a & x);
996 Last;
997
998
999 // ASL/ORA group
1000 case O_SLO:
1001 c_flag = rdbuf & 0x80;
1002 rdbuf <<= 1;
1003 write_byte(ar, rdbuf);
1004 set_nz(a |= rdbuf);
1005 Last;
1006
1007
1008 // ROL/AND group
1009 case O_RLA:
1010 tmp = rdbuf & 0x80;
1011 rdbuf = c_flag ? (rdbuf << 1) | 0x01 : rdbuf << 1;
1012 c_flag = tmp;
1013 write_byte(ar, rdbuf);
1014 set_nz(a &= rdbuf);
1015 Last;
1016
1017
1018 // LSR/EOR group
1019 case O_SRE:
1020 c_flag = rdbuf & 0x01;
1021 rdbuf >>= 1;
1022 write_byte(ar, rdbuf);
1023 set_nz(a ^= rdbuf);
1024 Last;
1025
1026
1027 // ROR/ADC group
1028 case O_RRA:
1029 tmp = rdbuf & 0x01;
1030 rdbuf = c_flag ? (rdbuf >> 1) | 0x80 : rdbuf >> 1;
1031 c_flag = tmp;
1032 write_byte(ar, rdbuf);
1033 do_adc(rdbuf);
1034 Last;
1035
1036
1037 // DEC/CMP group
1038 case O_DCP:
1039 write_byte(ar, --rdbuf);
1040 set_nz(ar = a - rdbuf);
1041 c_flag = ar < 0x100;
1042 Last;
1043
1044
1045 // INC/SBC group
1046 case O_ISB:
1047 write_byte(ar, ++rdbuf);
1048 do_sbc(rdbuf);
1049 Last;
1050
1051
1052 // Complex functions
1053 case O_ANC_I:
1054 read_to(pc++, data);
1055 set_nz(a &= data);
1056 c_flag = n_flag & 0x80;
1057 Last;
1058
1059 case O_ASR_I:
1060 read_to(pc++, data);
1061 a &= data;
1062 c_flag = a & 0x01;
1063 set_nz(a >>= 1);
1064 Last;
1065
1066 case O_ARR_I:
1067 read_to(pc++, data);
1068 data &= a;
1069 a = (c_flag ? (data >> 1) | 0x80 : data >> 1);
1070 if (!d_flag) {
1071 set_nz(a);
1072 c_flag = a & 0x40;
1073 v_flag = (a & 0x40) ^ ((a & 0x20) << 1);
1074 } else {
1075 n_flag = c_flag ? 0x80 : 0;
1076 z_flag = a;
1077 v_flag = (data ^ a) & 0x40;
1078 if ((data & 0x0f) + (data & 0x01) > 5)
1079 a = a & 0xf0 | (a + 6) & 0x0f;
1080 if ((c_flag = ((data + (data & 0x10)) & 0x1f0) > 0x50) != 0)
1081 a += 0x60;
1082 }
1083 Last;
1084
1085 case O_ANE_I:
1086 read_to(pc++, data);
1087 set_nz(a = (a | 0xee) & x & data);
1088 Last;
1089
1090 case O_LXA_I:
1091 read_to(pc++, data);
1092 set_nz(a = x = (a | 0xee) & data);
1093 Last;
1094
1095 case O_SBX_I:
1096 read_to(pc++, data);
1097 set_nz(x = ar = (x & a) - data);
1098 c_flag = ar < 0x100;
1099 Last;
1100
1101 case O_LAS:
1102 read_to(ar, data);
1103 set_nz(a = x = sp = data & sp);
1104 Last;
1105
1106 case O_SHS: // ar2 contains the high byte of the operand address
1107 write_byte(ar, (ar2+1) & (sp = a & x));
1108 Last;
1109
1110 case O_SHY: // ar2 contains the high byte of the operand address
1111 write_byte(ar, y & (ar2+1));
1112 Last;
1113
1114 case O_SHX: // ar2 contains the high byte of the operand address
1115 write_byte(ar, x & (ar2+1));
1116 Last;
1117
1118 case O_SHA: // ar2 contains the high byte of the operand address
1119 write_byte(ar, a & x & (ar2+1));
1120 Last;