]> git.sur5r.net Git - cc65/blob - src/sim65/cpucore.c
First import
[cc65] / src / sim65 / cpucore.c
1 /*****************************************************************************/
2 /*                                                                           */
3 /*                                   cpucore.c                               */
4 /*                                                                           */
5 /*                        CPU core for the 6502 simulator                    */
6 /*                                                                           */
7 /*                                                                           */
8 /*                                                                           */
9 /* (C) 2002      Ullrich von Bassewitz                                       */
10 /*               Wacholderweg 14                                             */
11 /*               D-70597 Stuttgart                                           */
12 /* EMail:        uz@cc65.org                                                 */
13 /*                                                                           */
14 /*                                                                           */
15 /* This software is provided 'as-is', without any expressed or implied       */
16 /* warranty.  In no event will the authors be held liable for any damages    */
17 /* arising from the use of this software.                                    */
18 /*                                                                           */
19 /* Permission is granted to anyone to use this software for any purpose,     */
20 /* including commercial applications, and to alter it and redistribute it    */
21 /* freely, subject to the following restrictions:                            */
22 /*                                                                           */
23 /* 1. The origin of this software must not be misrepresented; you must not   */
24 /*    claim that you wrote the original software. If you use this software   */
25 /*    in a product, an acknowledgment in the product documentation would be  */
26 /*    appreciated but is not required.                                       */
27 /* 2. Altered source versions must be plainly marked as such, and must not   */
28 /*    be misrepresented as being the original software.                      */
29 /* 3. This notice may not be removed or altered from any source              */
30 /*    distribution.                                                          */
31 /*                                                                           */
32 /*****************************************************************************/
33
34
35
36 #include <stdlib.h>
37
38 /* common */
39 #include "abend.h"
40 #include "print.h"
41
42 /* sim65 */
43 #include "cputype.h"
44 #include "global.h"
45 #include "memory.h"
46 #include "cpucore.h"
47
48
49
50 /*****************************************************************************/
51 /*                                   Data                                    */
52 /*****************************************************************************/
53
54
55
56 /* Registers */
57 unsigned char   AC;             /* Accumulator */
58 unsigned char   XR;             /* X register */
59 unsigned char   YR;             /* Y register */
60 unsigned char   SR;             /* Status register */
61 unsigned char   SP;             /* Stackpointer */
62 unsigned        PC;             /* Program counter */
63
64 /* Count the total number of cylcles */
65 unsigned        Cycles;         /* Cycles per insn */
66 unsigned long   TotalCycles;    /* Total cycles */
67
68 /* Allow the stack page to be changed */
69 static unsigned StackPage = 0x100;
70
71 /* Status register bits */
72 #define CF      0x01            /* Carry flag */
73 #define ZF      0x02            /* Zero flag */
74 #define IF      0x04            /* Interrupt flag */
75 #define DF      0x08            /* Decimal flag */
76 #define BF      0x10            /* Break flag */
77 #define OF      0x40            /* Overflow flag */
78 #define SF      0x80            /* Sign flag */
79
80 /* */
81 int CPUHalted;
82
83
84
85 /*****************************************************************************/
86 /*                        Helper functions and macros                        */
87 /*****************************************************************************/
88
89
90
91 /* Set flags */
92 #define SET_CF()        (SR |= CF)
93 #define SET_ZF()        (SR |= ZF)
94 #define SET_IF()        (SR |= IF)
95 #define SET_DF()        (SR |= DF)
96 #define SET_BF()        (SR |= BF)
97 #define SET_OF()        (SR |= OF)
98 #define SET_SF()        (SR |= SF)
99
100 /* Reset flags */
101 #define CLR_CF()        (SR &= ~CF)
102 #define CLR_ZF()        (SR &= ~ZF)
103 #define CLR_IF()        (SR &= ~IF)
104 #define CLR_DF()        (SR &= ~DF)
105 #define CLR_BF()        (SR &= ~BF)
106 #define CLR_OF()        (SR &= ~OF)
107 #define CLR_SF()        (SR &= ~SF)
108
109 /* Test for the flags */
110 #define CF_IS_SET()     (SR & CF)
111 #define ZF_IS_SET()     (SR & ZF)
112 #define IF_IS_SET()     (SR & IF)
113 #define DF_IS_SET()     (SR & DF)
114 #define BF_IS_SET()     (SR & BF)
115 #define OF_IS_SET()     (SR & OF)
116 #define SF_IS_SET()     (SR & SF)
117
118 /* Set the flags according to a given value */
119 #define TEST_ZF(v)      do { if ((v) == 0) { SET_ZF(); } else { CLR_ZF(); } } while (0)
120 #define TEST_SF(v)      do { if ((v) & 0x80) { SET_SF(); } else { CLR_SF(); } } while (0)
121 #define TEST_CF(v)      do { if (v) { SET_CF (); } else { CLR_CF (); } } while (0)
122
123 /* Program counter halves */
124 #define PCL             (PC & 0xFF)
125 #define PCH             ((PC >> 8) & 0xFF)
126
127 /* Stack operations */
128 #define PUSH(Val)       WriteMem (StackPage + SP--, Val)
129 #define POP()           ReadMem (StackPage + ++SP)
130
131 /* Test for page cross */
132 #define PAGE_CROSS(addr,offs)   ((((addr) & 0xFF) + offs) >= 0x100)
133
134 /* #imm */
135 #define AC_OP_IMM(op)                           \
136     Cycles = 2;                                 \
137     AC = AC op ReadMem (PC+1);                  \
138     TEST_ZF (AC);                               \
139     TEST_SF (AC);                               \
140     PC += 2
141
142 /* zp */
143 #define AC_OP_ZP(op)                            \
144     Cycles = 3;                                 \
145     AC = AC op ReadMem (ReadMem (PC+1));        \
146     TEST_ZF (AC);                               \
147     TEST_SF (AC);                               \
148     PC += 2
149
150 /* zp,x */
151 #define AC_OP_ZPX(op)                           \
152     unsigned char ZPAddr;                       \
153     Cycles = 4;                                 \
154     ZPAddr = ReadMem (PC+1) + XR;               \
155     AC = AC op ReadMem (ZPAddr);                \
156     TEST_ZF (AC);                               \
157     TEST_SF (AC);                               \
158     PC += 2
159
160 /* zp,y */
161 #define AC_OP_ZPY(op)                           \
162     unsigned char ZPAddr;                       \
163     Cycles = 4;                                 \
164     ZPAddr = ReadMem (PC+1) + YR;               \
165     AC = AC op ReadMem (ZPAddr);                \
166     TEST_ZF (AC);                               \
167     TEST_SF (AC);                               \
168     PC += 2
169
170 /* abs */
171 #define AC_OP_ABS(op)                           \
172     unsigned Addr;                              \
173     Cycles = 4;                                 \
174     Addr = ReadMemW (PC+1);                     \
175     AC = AC op ReadMem (Addr);                  \
176     TEST_ZF (AC);                               \
177     TEST_SF (AC);                               \
178     PC += 3
179
180 /* abs,x */
181 #define AC_OP_ABSX(op)                          \
182     unsigned Addr;                              \
183     Cycles = 4;                                 \
184     Addr = ReadMemW (PC+1);                     \
185     if (PAGE_CROSS (Addr, XR)) {                \
186         ++Cycles;                               \
187     }                                           \
188     AC = AC | ReadMem (Addr + XR);              \
189     TEST_ZF (AC);                               \
190     TEST_SF (AC);                               \
191     PC += 3
192
193 /* abs,y */
194 #define AC_OP_ABSY(op)                          \
195     unsigned Addr;                              \
196     Cycles = 4;                                 \
197     Addr = ReadMemW (PC+1);                     \
198     if (PAGE_CROSS (Addr, YR)) {                \
199         ++Cycles;                               \
200     }                                           \
201     AC = AC | ReadMem (Addr + YR);              \
202     TEST_ZF (AC);                               \
203     TEST_SF (AC);                               \
204     PC += 3
205
206 /* (zp,x) */
207 #define AC_OP_ZPXIND(op)                        \
208     unsigned char ZPAddr;                       \
209     unsigned Addr;                              \
210     Cycles = 6;                                 \
211     ZPAddr = ReadMem (PC+1) + XR;               \
212     Addr = ReadZeroPageW (ZPAddr);              \
213     AC = AC op ReadMem (Addr);                  \
214     TEST_ZF (AC);                               \
215     TEST_SF (AC);                               \
216     PC += 2
217
218 /* (zp),y */
219 #define AC_OP_ZPINDY(op)                        \
220     unsigned char ZPAddr;                       \
221     unsigned Addr;                              \
222     Cycles = 5;                                 \
223     ZPAddr = ReadMem (PC+1);                    \
224     Addr = ReadZeroPageW (ZPAddr) + YR;         \
225     AC = AC op ReadMem (Addr);                  \
226     TEST_ZF (AC);                               \
227     TEST_SF (AC);                               \
228     PC += 2
229
230 /* branches */
231 #define BRANCH(cond)                            \
232     Cycles = 2;                                 \
233     if (cond) {                                 \
234         signed char Offs;                       \
235         unsigned char OldPCH;                   \
236         ++Cycles;                               \
237         Offs = (signed char) ReadMem (PC+1);    \
238         OldPCH = PCH;                           \
239         PC += (int) Offs;                       \
240         if (PCH != OldPCH) {                    \
241             ++Cycles;                           \
242         }                                       \
243     } else {                                    \
244         PC += 2;                                \
245     }
246
247 /* compares */
248 #define CMP(v1,v2)                              \
249     {                                           \
250         unsigned Result = v1 - v2;              \
251         TEST_ZF (Result & 0xFF);                \
252         TEST_SF (Result);                       \
253         TEST_CF (Result <= 0xFF);               \
254     }
255
256
257
258 /*****************************************************************************/
259 /*                               Helper functions                            */
260 /*****************************************************************************/
261
262
263
264 static void Illegal (void)
265 {
266     fprintf (stderr, "Illegal: $%02X\n", ReadMem (PC));
267     exit (EXIT_FAILURE);
268 }
269
270
271
272 static void NotImplemented (void)
273 {
274     fprintf (stderr, "Not implemented: $%02X\n", ReadMem (PC));
275     exit (EXIT_FAILURE);
276 }
277
278
279
280 /*****************************************************************************/
281 /*                                   Code                                    */
282 /*****************************************************************************/
283
284
285
286 static void OPC_6502_00 (void)
287 /* Opcode $00: BRK */
288 {
289     Cycles = 7;
290     PC += 2;
291     SET_BF ();
292     PUSH (PCH);
293     PUSH (PCL);
294     PUSH (SR);
295     SET_IF ();
296     PC = ReadMemW (0xFFFE);
297 }
298
299
300
301 static void OPC_6502_01 (void)
302 /* Opcode $01: ORA (ind,x) */
303 {
304     AC_OP_ZPXIND (|);
305 }
306
307
308
309 static void OPC_6502_02 (void)
310 /* Opcode $02 */
311 {
312     Illegal ();
313 }
314
315
316
317 static void OPC_6502_03 (void)
318 /* Opcode $03 */
319 {
320     Illegal ();
321 }
322
323
324
325 static void OPC_6502_04 (void)
326 /* Opcode $04 */
327 {
328     Illegal ();
329 }
330
331
332
333 static void OPC_6502_05 (void)
334 /* Opcode $05: ORA zp */
335 {
336     AC_OP_ZP (|);
337 }
338
339
340
341 static void OPC_6502_06 (void)
342 /* Opcode $06: ASL zp */
343 {
344     NotImplemented ();
345 }
346
347
348
349 static void OPC_6502_07 (void)
350 /* Opcode $07 */
351 {
352     Illegal ();
353 }
354
355
356
357 static void OPC_6502_08 (void)
358 /* Opcode $08: PHP */
359 {
360     Cycles = 3;
361     PUSH (SR & ~BF);
362     PC += 1;
363 }
364
365
366
367 static void OPC_6502_09 (void)
368 /* Opcode $09: ORA #imm */
369 {
370     AC_OP_IMM (|);
371 }
372
373
374
375 static void OPC_6502_0A (void)
376 /* Opcode $0A: ASL a */
377 {
378     NotImplemented ();
379 }
380
381
382
383 static void OPC_6502_0B (void)
384 /* Opcode $0B */
385 {
386     Illegal ();
387 }
388
389
390
391 static void OPC_6502_0C (void)
392 /* Opcode $0C */
393 {
394     Illegal ();
395 }
396
397
398
399 static void OPC_6502_0D (void)
400 /* Opcode $0D: ORA abs */
401 {
402     AC_OP_ABS (|);
403 }
404
405
406
407 static void OPC_6502_0E (void)
408 /* Opcode $0E: ALS abs */
409 {
410     NotImplemented ();
411 }
412
413
414
415 static void OPC_6502_0F (void)
416 /* Opcode $0F */
417 {
418     Illegal ();
419 }
420
421
422
423 static void OPC_6502_10 (void)
424 /* Opcode $10: BPL */
425 {
426     BRANCH (!SF_IS_SET ());
427 }
428
429
430
431 static void OPC_6502_11 (void)
432 /* Opcode $11: ORA (zp),y */
433 {
434     AC_OP_ZPINDY (|);
435 }
436
437
438
439 static void OPC_6502_12 (void)
440 /* Opcode $12 */
441 {
442     Illegal ();
443 }
444
445
446
447 static void OPC_6502_13 (void)
448 /* Opcode $13 */
449 {
450     Illegal ();
451 }
452
453
454
455 static void OPC_6502_14 (void)
456 /* Opcode $14 */
457 {
458     Illegal ();
459 }
460
461
462
463 static void OPC_6502_15 (void)
464 /* Opcode $15: ORA zp,x */
465 {
466    AC_OP_ZPX (|);
467 }
468
469
470
471 static void OPC_6502_16 (void)
472 /* Opcode $16: ASL zp,x */
473 {
474     NotImplemented ();
475 }
476
477
478
479 static void OPC_6502_17 (void)
480 /* Opcode $17 */
481 {
482     Illegal ();
483 }
484
485
486
487 static void OPC_6502_18 (void)
488 /* Opcode $18: CLC */
489 {
490     Cycles = 2;
491     CLR_CF ();
492     PC += 1;
493 }
494
495
496
497 static void OPC_6502_19 (void)
498 /* Opcode $19: ORA abs,y */
499 {
500     AC_OP_ABSY (|);
501 }
502
503
504
505 static void OPC_6502_1A (void)
506 /* Opcode $1A */
507 {
508     Illegal ();
509 }
510
511
512
513 static void OPC_6502_1B (void)
514 /* Opcode $1B */
515 {
516     Illegal ();
517 }
518
519
520
521 static void OPC_6502_1C (void)
522 /* Opcode $1C */
523 {
524     Illegal ();
525 }
526
527
528
529 static void OPC_6502_1D (void)
530 /* Opcode $1D: ORA abs,x */
531 {
532     AC_OP_ABSX (|);
533 }
534
535
536
537 static void OPC_6502_1E (void)
538 /* Opcode $1E: ASL abs,x */
539 {
540     NotImplemented ();
541 }
542
543
544
545 static void OPC_6502_1F (void)
546 /* Opcode $1F */
547 {
548     Illegal ();
549 }
550
551
552
553 static void OPC_6502_20 (void)
554 /* Opcode $20: JSR */
555 {
556     NotImplemented ();
557 }
558
559
560
561 static void OPC_6502_21 (void)
562 /* Opcode $21: AND (zp,x) */
563 {
564     AC_OP_ZPXIND (&);
565 }
566
567
568
569 static void OPC_6502_22 (void)
570 /* Opcode $22 */
571 {
572     Illegal ();
573 }
574
575
576
577 static void OPC_6502_23 (void)
578 /* Opcode $23 */
579 {
580     Illegal ();
581 }
582
583
584
585 static void OPC_6502_24 (void)
586 /* Opcode $24: BIT zp */
587 {
588     NotImplemented ();
589 }
590
591
592
593 static void OPC_6502_25 (void)
594 /* Opcode $25: AND zp */
595 {
596     AC_OP_ZP (&);
597 }
598
599
600
601 static void OPC_6502_26 (void)
602 /* Opcode $26: ROL zp */
603 {
604     NotImplemented ();
605 }
606
607
608
609 static void OPC_6502_27 (void)
610 /* Opcode $27 */
611 {
612     Illegal ();
613 }
614
615
616
617 static void OPC_6502_28 (void)
618 /* Opcode $28: PLP */
619 {
620     Cycles = 4;
621     SR = (POP () & ~BF);
622     PC += 1;
623 }
624
625
626
627 static void OPC_6502_29 (void)
628 /* Opcode $29: AND #imm */
629 {
630     AC_OP_IMM (&);
631 }
632
633
634
635 static void OPC_6502_2A (void)
636 /* Opcode $2A: ROL a */
637 {
638     NotImplemented ();
639 }
640
641
642
643 static void OPC_6502_2B (void)
644 /* Opcode $2B */
645 {
646     Illegal ();
647 }
648
649
650
651 static void OPC_6502_2C (void)
652 /* Opcode $2C: BIT abs */
653 {
654     NotImplemented ();
655 }
656
657
658
659 static void OPC_6502_2D (void)
660 /* Opcode $2D: AND abs */
661 {
662     AC_OP_ABS (&);
663 }
664
665
666
667 static void OPC_6502_2E (void)
668 /* Opcode $2E: ROL abs */
669 {
670     NotImplemented ();
671 }
672
673
674
675 static void OPC_6502_2F (void)
676 /* Opcode $2F */
677 {
678     Illegal ();
679 }
680
681
682
683 static void OPC_6502_30 (void)
684 /* Opcode $30: BMI */
685 {
686     BRANCH (SF_IS_SET ());
687 }
688
689
690
691 static void OPC_6502_31 (void)
692 /* Opcode $31: AND (zp),y */
693 {
694     AC_OP_ZPINDY (&);
695 }
696
697
698
699 static void OPC_6502_32 (void)
700 /* Opcode $32 */
701 {
702     Illegal ();
703 }
704
705
706
707 static void OPC_6502_33 (void)
708 /* Opcode $33 */
709 {
710     Illegal ();
711 }
712
713
714
715 static void OPC_6502_34 (void)
716 /* Opcode $34 */
717 {
718     Illegal ();
719 }
720
721
722
723 static void OPC_6502_35 (void)
724 /* Opcode $35: AND zp,x */
725 {
726     AC_OP_ZPX (&);
727 }
728
729
730
731 static void OPC_6502_36 (void)
732 /* Opcode $36: ROL zp,x */
733 {
734     NotImplemented ();
735 }
736
737
738
739 static void OPC_6502_37 (void)
740 /* Opcode $37 */
741 {
742     Illegal ();
743 }
744
745
746
747 static void OPC_6502_38 (void)
748 /* Opcode $38: SEC */
749 {
750     Cycles = 2;
751     SET_CF ();
752     PC += 1;
753 }
754
755
756
757 static void OPC_6502_39 (void)
758 /* Opcode $39: AND abs,y */
759 {
760     AC_OP_ABSY (&);
761 }
762
763
764
765 static void OPC_6502_3A (void)
766 /* Opcode $3A */
767 {
768     Illegal ();
769 }
770
771
772
773 static void OPC_6502_3B (void)
774 /* Opcode $3B */
775 {
776     Illegal ();
777 }
778
779
780
781 static void OPC_6502_3C (void)
782 /* Opcode $3C */
783 {
784     Illegal ();
785 }
786
787
788
789 static void OPC_6502_3D (void)
790 /* Opcode $3D: AND abs,x */
791 {
792     AC_OP_ABSX (&);
793 }
794
795
796
797 static void OPC_6502_3E (void)
798 /* Opcode $3E: ROL abs,x */
799 {
800     NotImplemented ();
801 }
802
803
804
805 static void OPC_6502_3F (void)
806 /* Opcode $3F */
807 {
808     Illegal ();
809 }
810
811
812
813 static void OPC_6502_40 (void)
814 /* Opcode $40: RTI */
815 {
816     Cycles = 6;
817     SR = POP ();
818     PC = POP ();                /* PCL */
819     PC |= (POP () << 8);        /* PCH */
820 }
821
822
823
824 static void OPC_6502_41 (void)
825 /* Opcode $41: EOR (zp,x) */
826 {
827     AC_OP_ZPXIND (^);
828 }
829
830
831
832 static void OPC_6502_42 (void)
833 /* Opcode $42 */
834 {
835     Illegal ();
836 }
837
838
839
840 static void OPC_6502_43 (void)
841 /* Opcode $43 */
842 {
843     Illegal ();
844 }
845
846
847
848 static void OPC_6502_44 (void)
849 /* Opcode $44 */
850 {
851     Illegal ();
852 }
853
854
855
856 static void OPC_6502_45 (void)
857 /* Opcode $45: EOR zp */
858 {
859     AC_OP_ZP (^);
860 }
861
862
863
864 static void OPC_6502_46 (void)
865 /* Opcode $46: LSR zp */
866 {
867     NotImplemented ();
868 }
869
870
871
872 static void OPC_6502_47 (void)
873 /* Opcode $47 */
874 {
875     Illegal ();
876 }
877
878
879
880 static void OPC_6502_48 (void)
881 /* Opcode $48: PHA */
882 {
883     Cycles = 3;
884     PUSH (AC);
885     PC += 1;
886 }
887
888
889
890 static void OPC_6502_49 (void)
891 /* Opcode $49: EOR #imm */
892 {
893     AC_OP_IMM (^);
894 }
895
896
897
898 static void OPC_6502_4A (void)
899 /* Opcode $4A: LSR a */
900 {
901     NotImplemented ();
902 }
903
904
905
906 static void OPC_6502_4B (void)
907 /* Opcode $4B */
908 {
909     Illegal ();
910 }
911
912
913
914 static void OPC_6502_4C (void)
915 /* Opcode $4C: JMP abs */
916 {
917     Cycles = 3;
918     PC = ReadMemW (PC+1);
919 }
920
921
922
923 static void OPC_6502_4D (void)
924 /* Opcode $4D: EOR abs */
925 {
926     AC_OP_ABS (^);
927 }
928
929
930
931 static void OPC_6502_4E (void)
932 /* Opcode $4E: LSR abs */
933 {
934     NotImplemented ();
935 }
936
937
938
939 static void OPC_6502_4F (void)
940 /* Opcode $4F */
941 {
942     Illegal ();
943 }
944
945
946
947 static void OPC_6502_50 (void)
948 /* Opcode $50: BVC */
949 {
950     BRANCH (!OF_IS_SET());
951 }
952
953
954
955 static void OPC_6502_51 (void)
956 /* Opcode $51: EOR (zp),y */
957 {
958     AC_OP_ZPINDY (^);
959 }
960
961
962
963 static void OPC_6502_52 (void)
964 /* Opcode $52 */
965 {
966     Illegal ();
967 }
968
969
970
971 static void OPC_6502_53 (void)
972 /* Opcode $53 */
973 {
974     Illegal ();
975 }
976
977
978
979 static void OPC_6502_54 (void)
980 /* Opcode $54 */
981 {
982     Illegal ();
983 }
984
985
986
987 static void OPC_6502_55 (void)
988 /* Opcode $55: EOR zp,x */
989 {
990     AC_OP_ZPX (^);
991 }
992
993
994
995 static void OPC_6502_56 (void)
996 /* Opcode $56: LSR zp,x */
997 {
998     NotImplemented ();
999 }
1000
1001
1002
1003 static void OPC_6502_57 (void)
1004 /* Opcode $57 */
1005 {
1006     Illegal ();
1007 }
1008
1009
1010
1011 static void OPC_6502_58 (void)
1012 /* Opcode $58: CLI */
1013 {
1014     Cycles = 2;
1015     CLR_IF ();
1016     PC += 1;
1017 }
1018
1019
1020
1021 static void OPC_6502_59 (void)
1022 /* Opcode $59: EOR abs,y */
1023 {
1024     AC_OP_ABSY (^);
1025 }
1026
1027
1028
1029 static void OPC_6502_5A (void)
1030 /* Opcode $5A */
1031 {
1032     Illegal ();
1033 }
1034
1035
1036
1037 static void OPC_6502_5B (void)
1038 /* Opcode $5B */
1039 {
1040     Illegal ();
1041 }
1042
1043
1044
1045 static void OPC_6502_5C (void)
1046 /* Opcode $5C */
1047 {
1048     Illegal ();
1049 }
1050
1051
1052
1053 static void OPC_6502_5D (void)
1054 /* Opcode $5D: EOR abs,x */
1055 {
1056     AC_OP_ABSX (^);
1057 }
1058
1059
1060
1061 static void OPC_6502_5E (void)
1062 /* Opcode $5E: LSR abs,x */
1063 {
1064     NotImplemented ();
1065 }
1066
1067
1068
1069 static void OPC_6502_5F (void)
1070 /* Opcode $5F */
1071 {
1072     Illegal ();
1073 }
1074
1075
1076
1077 static void OPC_6502_60 (void)
1078 /* Opcode $60: RTS */
1079 {
1080     Cycles = 6;
1081     PC = POP ();                /* PCL */
1082     PC |= (POP () << 8);        /* PCH */
1083     PC += 1;
1084 }
1085
1086
1087
1088 static void OPC_6502_61 (void)
1089 /* Opcode $61: ADC (zp,x) */
1090 {
1091     NotImplemented ();
1092 }
1093
1094
1095
1096 static void OPC_6502_62 (void)
1097 /* Opcode $62 */
1098 {
1099     Illegal ();
1100 }
1101
1102
1103
1104 static void OPC_6502_63 (void)
1105 /* Opcode $63 */
1106 {
1107     Illegal ();
1108 }
1109
1110
1111
1112 static void OPC_6502_64 (void)
1113 /* Opcode $64 */
1114 {
1115     Illegal ();
1116 }
1117
1118
1119
1120 static void OPC_6502_65 (void)
1121 /* Opcode $65: ADC zp */
1122 {
1123     NotImplemented ();
1124 }
1125
1126
1127
1128 static void OPC_6502_66 (void)
1129 /* Opcode $66: ROR zp */
1130 {
1131     NotImplemented ();
1132 }
1133
1134
1135
1136 static void OPC_6502_67 (void)
1137 /* Opcode $67 */
1138 {
1139     Illegal ();
1140 }
1141
1142
1143
1144 static void OPC_6502_68 (void)
1145 /* Opcode $68: PLA */
1146 {
1147     Cycles = 4;
1148     AC = POP ();
1149     TEST_ZF (AC);
1150     TEST_SF (AC);
1151     PC += 1;
1152 }
1153
1154
1155
1156 static void OPC_6502_69 (void)
1157 /* Opcode $69: ADC #imm */
1158 {
1159     NotImplemented ();
1160 }
1161
1162
1163
1164 static void OPC_6502_6A (void)
1165 /* Opcode $6A: ROR a */
1166 {
1167     NotImplemented ();
1168 }
1169
1170
1171
1172 static void OPC_6502_6B (void)
1173 /* Opcode $6B */
1174 {
1175     Illegal ();
1176 }
1177
1178
1179
1180 static void OPC_6502_6C (void)
1181 /* Opcode $6C: JMP (ind) */
1182 {
1183     unsigned Addr;
1184     Cycles = 5;
1185     Addr = ReadMemW (PC+1);
1186     if (CPU == CPU_6502) {
1187         /* Emulate the 6502 bug */
1188         PC = ReadMem (Addr);
1189         Addr = (Addr & 0xFF00) | ((Addr + 1) & 0xFF);
1190         PC |= (ReadMem (Addr) << 8);
1191     } else {
1192         /* 65C02 and above have this bug fixed */
1193         PC = ReadMemW (Addr);
1194     }
1195     PC += 3;
1196 }
1197
1198
1199
1200 static void OPC_6502_6D (void)
1201 /* Opcode $6D: ADC abs */
1202 {
1203     NotImplemented ();
1204 }
1205
1206
1207
1208 static void OPC_6502_6E (void)
1209 /* Opcode $6E: ROR abs */
1210 {
1211     NotImplemented ();
1212 }
1213
1214
1215
1216 static void OPC_6502_6F (void)
1217 /* Opcode $6F */
1218 {
1219     Illegal ();
1220 }
1221
1222
1223
1224 static void OPC_6502_70 (void)
1225 /* Opcode $70: BVS */
1226 {
1227     BRANCH (OF_IS_SET ());
1228 }
1229
1230
1231
1232 static void OPC_6502_71 (void)
1233 /* Opcode $71: ADC (zp),y */
1234 {
1235     NotImplemented ();
1236 }
1237
1238
1239
1240 static void OPC_6502_72 (void)
1241 /* Opcode $72 */
1242 {
1243     Illegal ();
1244 }
1245
1246
1247
1248 static void OPC_6502_73 (void)
1249 /* Opcode $73 */
1250 {
1251     Illegal ();
1252 }
1253
1254
1255
1256 static void OPC_6502_74 (void)
1257 /* Opcode $74 */
1258 {
1259     Illegal ();
1260 }
1261
1262
1263
1264 static void OPC_6502_75 (void)
1265 /* Opcode $75: ADC zp,x */
1266 {
1267     NotImplemented ();
1268 }
1269
1270
1271
1272 static void OPC_6502_76 (void)
1273 /* Opcode $76: ROR zp,x */
1274 {
1275     NotImplemented ();
1276 }
1277
1278
1279
1280 static void OPC_6502_77 (void)
1281 /* Opcode $77 */
1282 {
1283     Illegal ();
1284 }
1285
1286
1287
1288 static void OPC_6502_78 (void)
1289 /* Opcode $78: SEI */
1290 {
1291     Cycles = 2;
1292     SET_IF ();
1293     PC += 1;
1294 }
1295
1296
1297
1298 static void OPC_6502_79 (void)
1299 /* Opcode $79: ADC abs,y */
1300 {
1301     NotImplemented ();
1302 }
1303
1304
1305
1306 static void OPC_6502_7A (void)
1307 /* Opcode $7A */
1308 {
1309     Illegal ();
1310 }
1311
1312
1313
1314 static void OPC_6502_7B (void)
1315 /* Opcode $7B */
1316 {
1317     Illegal ();
1318 }
1319
1320
1321
1322 static void OPC_6502_7C (void)
1323 /* Opcode $7C */
1324 {
1325     Illegal ();
1326 }
1327
1328
1329
1330 static void OPC_6502_7D (void)
1331 /* Opcode $7D: ADC abs,x */
1332 {
1333     NotImplemented ();
1334 }
1335
1336
1337
1338 static void OPC_6502_7E (void)
1339 /* Opcode $7E: ROR abs,x */
1340 {
1341     NotImplemented ();
1342 }
1343
1344
1345
1346 static void OPC_6502_7F (void)
1347 /* Opcode $7F */
1348 {
1349     Illegal ();
1350 }
1351
1352
1353
1354 static void OPC_6502_80 (void)
1355 /* Opcode $80 */
1356 {
1357     Illegal ();
1358 }
1359
1360
1361
1362 static void OPC_6502_81 (void)
1363 /* Opcode $81: STA (zp,x) */
1364 {
1365     NotImplemented ();
1366 }
1367
1368
1369
1370 static void OPC_6502_82 (void)
1371 /* Opcode $82 */
1372 {
1373     Illegal ();
1374 }
1375
1376
1377
1378 static void OPC_6502_83 (void)
1379 /* Opcode $83 */
1380 {
1381     Illegal ();
1382 }
1383
1384
1385
1386 static void OPC_6502_84 (void)
1387 /* Opcode $84: STY zp */
1388 {
1389     unsigned char ZPAddr;
1390     Cycles = 3;
1391     ZPAddr = ReadMem (PC+1);
1392     WriteMem (ZPAddr, YR);
1393     PC += 2;
1394 }
1395
1396
1397
1398 static void OPC_6502_85 (void)
1399 /* Opcode $85: STA zp */
1400 {
1401     unsigned char ZPAddr;
1402     Cycles = 3;
1403     ZPAddr = ReadMem (PC+1);
1404     WriteMem (ZPAddr, AC);
1405     PC += 2;
1406 }
1407
1408
1409
1410 static void OPC_6502_86 (void)
1411 /* Opcode $86: STX zp */
1412 {
1413     unsigned char ZPAddr;
1414     Cycles = 3;
1415     ZPAddr = ReadMem (PC+1);
1416     WriteMem (ZPAddr, XR);
1417     PC += 2;
1418 }
1419
1420
1421
1422 static void OPC_6502_87 (void)
1423 /* Opcode $87 */
1424 {
1425     Illegal ();
1426 }
1427
1428
1429
1430 static void OPC_6502_88 (void)
1431 /* Opcode $88: DEY */
1432 {
1433     Cycles = 2;
1434     --YR;
1435     TEST_ZF (YR);
1436     TEST_SF (YR);
1437     PC += 1;
1438 }
1439
1440
1441
1442 static void OPC_6502_89 (void)
1443 /* Opcode $89 */
1444 {
1445     Illegal ();
1446 }
1447
1448
1449
1450 static void OPC_6502_8A (void)
1451 /* Opcode $8A: TXA */
1452 {
1453     Cycles = 2;
1454     AC = XR;
1455     TEST_ZF (AC);
1456     TEST_SF (AC);
1457     PC += 1;
1458 }
1459
1460
1461
1462 static void OPC_6502_8B (void)
1463 /* Opcode $8B */
1464 {
1465     Illegal ();
1466 }
1467
1468
1469
1470 static void OPC_6502_8C (void)
1471 /* Opcode $8C: STY abs */
1472 {
1473     unsigned Addr;
1474     Cycles = 4;
1475     Addr = ReadMemW (PC+1);
1476     WriteMem (Addr, YR);
1477     PC += 3;
1478 }
1479
1480
1481
1482 static void OPC_6502_8D (void)
1483 /* Opcode $8D: STA abs */
1484 {
1485     unsigned Addr;
1486     Cycles = 4;
1487     Addr = ReadMemW (PC+1);
1488     WriteMem (Addr, AC);
1489     PC += 3;
1490 }
1491
1492
1493
1494 static void OPC_6502_8E (void)
1495 /* Opcode $8E: STX abs */
1496 {
1497     unsigned Addr;
1498     Cycles = 4;
1499     Addr = ReadMemW (PC+1);
1500     WriteMem (Addr, XR);
1501     PC += 3;
1502 }
1503
1504
1505
1506 static void OPC_6502_8F (void)
1507 /* Opcode $8F */
1508 {
1509     Illegal ();
1510 }
1511
1512
1513
1514 static void OPC_6502_90 (void)
1515 /* Opcode $90: BCC */
1516 {
1517     BRANCH (!CF_IS_SET ());
1518 }
1519
1520
1521
1522 static void OPC_6502_91 (void)
1523 /* Opcode $91: sta (zp),y */
1524 {
1525     unsigned char ZPAddr;
1526     unsigned Addr;
1527     Cycles = 6;
1528     ZPAddr = ReadMem (PC+1);
1529     Addr   = ReadZeroPageW (ZPAddr) + YR;
1530     WriteMem (Addr, AC);
1531     PC += 2;
1532 }
1533
1534
1535
1536 static void OPC_6502_92 (void)
1537 /* Opcode $92 */
1538 {
1539     Illegal ();
1540 }
1541
1542
1543
1544 static void OPC_6502_93 (void)
1545 /* Opcode $93 */
1546 {
1547     Illegal ();
1548 }
1549
1550
1551
1552 static void OPC_6502_94 (void)
1553 /* Opcode $94: STY zp,x */
1554 {
1555     unsigned char ZPAddr;
1556     Cycles = 4;
1557     ZPAddr = ReadMem (PC+1) + XR;
1558     WriteMem (ZPAddr, YR);
1559     PC += 2;
1560 }
1561
1562
1563
1564 static void OPC_6502_95 (void)
1565 /* Opcode $95: STA zp,x */
1566 {
1567     unsigned char ZPAddr;
1568     Cycles = 4;
1569     ZPAddr = ReadMem (PC+1) + XR;
1570     WriteMem (ZPAddr, AC);
1571     PC += 2;
1572 }
1573
1574
1575
1576 static void OPC_6502_96 (void)
1577 /* Opcode $96: stx zp,y */
1578 {
1579     unsigned char ZPAddr;
1580     Cycles = 4;
1581     ZPAddr = ReadMem (PC+1) + YR;
1582     WriteMem (ZPAddr, XR);
1583     PC += 2;
1584 }
1585
1586
1587
1588 static void OPC_6502_97 (void)
1589 /* Opcode $97 */
1590 {
1591     Illegal ();
1592 }
1593
1594
1595
1596 static void OPC_6502_98 (void)
1597 /* Opcode $98: TYA */
1598 {
1599     Cycles = 2;
1600     AC = YR;
1601     TEST_ZF (AC);
1602     TEST_SF (AC);
1603     PC += 1;
1604 }
1605
1606
1607
1608 static void OPC_6502_99 (void)
1609 /* Opcode $99: STA abs,y */
1610 {
1611     unsigned Addr;
1612     Cycles = 5;
1613     Addr   = ReadMemW (PC+1) + YR;
1614     WriteMem (Addr, AC);
1615     PC += 3;
1616 }
1617
1618
1619
1620 static void OPC_6502_9A (void)
1621 /* Opcode $9A: TXS */
1622 {
1623     Cycles = 2;
1624     SP = XR;
1625     PC += 1;
1626 }
1627
1628
1629
1630 static void OPC_6502_9B (void)
1631 /* Opcode $9B */
1632 {
1633     Illegal ();
1634 }
1635
1636
1637
1638 static void OPC_6502_9C (void)
1639 /* Opcode $9C */
1640 {
1641     Illegal ();
1642 }
1643
1644
1645
1646 static void OPC_6502_9D (void)
1647 /* Opcode $9D: STA abs,x */
1648 {
1649     unsigned Addr;
1650     Cycles = 5;
1651     Addr   = ReadMemW (PC+1) + XR;
1652     WriteMem (Addr, AC);
1653     PC += 3;
1654 }
1655
1656
1657
1658 static void OPC_6502_9E (void)
1659 /* Opcode $9E */
1660 {
1661     Illegal ();
1662 }
1663
1664
1665
1666 static void OPC_6502_9F (void)
1667 /* Opcode $9F */
1668 {
1669     Illegal ();
1670 }
1671
1672
1673
1674 static void OPC_6502_A0 (void)
1675 /* Opcode $A0: LDY #imm */
1676 {
1677     Cycles = 2;
1678     YR = ReadMem (PC+1);
1679     TEST_ZF (YR);
1680     TEST_SF (YR);
1681     PC += 2;
1682 }
1683
1684
1685
1686 static void OPC_6502_A1 (void)
1687 /* Opcode $A1: LDA (zp,x) */
1688 {
1689     unsigned char ZPAddr;
1690     unsigned Addr;
1691     Cycles = 6;
1692     ZPAddr = ReadMem (PC+1) + XR;
1693     Addr = ReadZeroPageW (ZPAddr);
1694     AC = ReadMem (Addr);
1695     TEST_ZF (AC);
1696     TEST_SF (AC);
1697     PC += 2;
1698 }
1699
1700
1701
1702 static void OPC_6502_A2 (void)
1703 /* Opcode $A2: LDX #imm */
1704 {
1705     Cycles = 2;
1706     XR = ReadMem (PC+1);
1707     TEST_ZF (XR);
1708     TEST_SF (XR);
1709     PC += 2;
1710 }
1711
1712
1713
1714 static void OPC_6502_A3 (void)
1715 /* Opcode $A3 */
1716 {
1717     Illegal ();
1718 }
1719
1720
1721
1722 static void OPC_6502_A4 (void)
1723 /* Opcode $A4: LDY zp */
1724 {
1725     unsigned char ZPAddr;
1726     Cycles = 3;
1727     ZPAddr = ReadMem (PC+1);
1728     YR = ReadMem (ZPAddr);
1729     TEST_ZF (YR);
1730     TEST_SF (YR);
1731     PC += 2;
1732 }
1733
1734
1735
1736 static void OPC_6502_A5 (void)
1737 /* Opcode $A5: LDA zp */
1738 {
1739     unsigned char ZPAddr;
1740     Cycles = 3;
1741     ZPAddr = ReadMem (PC+1);
1742     AC = ReadMem (ZPAddr);
1743     TEST_ZF (AC);
1744     TEST_SF (AC);
1745     PC += 2;
1746 }
1747
1748
1749
1750 static void OPC_6502_A6 (void)
1751 /* Opcode $A6: LDX zp */
1752 {
1753     unsigned char ZPAddr;
1754     Cycles = 3;
1755     ZPAddr = ReadMem (PC+1);
1756     XR = ReadMem (ZPAddr);
1757     TEST_ZF (XR);
1758     TEST_SF (XR);
1759     PC += 2;
1760 }
1761
1762
1763
1764 static void OPC_6502_A7 (void)
1765 /* Opcode $A7 */
1766 {
1767     Illegal ();
1768 }
1769
1770
1771
1772 static void OPC_6502_A8 (void)
1773 /* Opcode $A8: TAY */
1774 {
1775     Cycles = 2;
1776     YR = AC;
1777     TEST_ZF (YR);
1778     TEST_SF (YR);
1779     PC += 1;
1780 }
1781
1782
1783
1784 static void OPC_6502_A9 (void)
1785 /* Opcode $A9: LDA #imm */
1786 {
1787     Cycles = 2;
1788     AC = ReadMem (PC+1);
1789     TEST_ZF (AC);
1790     TEST_SF (AC);
1791     PC += 2;
1792 }
1793
1794
1795
1796 static void OPC_6502_AA (void)
1797 /* Opcode $AA: TAX */
1798 {
1799     Cycles = 2;
1800     XR = AC;
1801     TEST_ZF (XR);
1802     TEST_SF (XR);
1803     PC += 1;
1804 }
1805
1806
1807
1808 static void OPC_6502_AB (void)
1809 /* Opcode $AB */
1810 {
1811     Illegal ();
1812 }
1813
1814
1815
1816 static void OPC_6502_AC (void)
1817 /* Opcode $AC: LDY abs */
1818 {
1819     unsigned Addr;
1820     Cycles = 4;
1821     Addr   = ReadMemW (PC+1);
1822     YR     = ReadMem (Addr);
1823     TEST_ZF (YR);
1824     TEST_SF (YR);
1825     PC += 3;
1826 }
1827
1828
1829
1830 static void OPC_6502_AD (void)
1831 /* Opcode $AD: LDA abs */
1832 {
1833     unsigned Addr;
1834     Cycles = 4;
1835     Addr   = ReadMemW (PC+1);
1836     AC     = ReadMem (Addr);
1837     TEST_ZF (AC);
1838     TEST_SF (AC);
1839     PC += 3;
1840 }
1841
1842
1843
1844 static void OPC_6502_AE (void)
1845 /* Opcode $AE: LDX abs */
1846 {
1847     unsigned Addr;
1848     Cycles = 4;
1849     Addr   = ReadMemW (PC+1);
1850     XR     = ReadMem (Addr);
1851     TEST_ZF (XR);
1852     TEST_SF (XR);
1853     PC += 3;
1854 }
1855
1856
1857
1858 static void OPC_6502_AF (void)
1859 /* Opcode $AF */
1860 {
1861     Illegal ();
1862 }
1863
1864
1865
1866 static void OPC_6502_B0 (void)
1867 /* Opcode $B0: BCS */
1868 {
1869     BRANCH (CF_IS_SET ());
1870 }
1871
1872
1873
1874 static void OPC_6502_B1 (void)
1875 /* Opcode $B1: LDA (zp),y */
1876 {
1877     unsigned char ZPAddr;
1878     unsigned Addr;
1879     Cycles = 5;
1880     ZPAddr = ReadMem (PC+1);
1881     Addr   = ReadZeroPageW (ZPAddr);
1882     if (PAGE_CROSS (Addr, YR)) {
1883         ++Cycles;
1884     }
1885     AC = ReadMem (Addr + YR);
1886     TEST_ZF (AC);
1887     TEST_SF (AC);
1888     PC += 2;
1889 }
1890
1891
1892
1893 static void OPC_6502_B2 (void)
1894 /* Opcode $B2 */
1895 {
1896     Illegal ();
1897 }
1898
1899
1900
1901 static void OPC_6502_B3 (void)
1902 /* Opcode $B3 */
1903 {
1904     Illegal ();
1905 }
1906
1907
1908
1909 static void OPC_6502_B4 (void)
1910 /* Opcode $B4: LDY zp,x */
1911 {
1912     unsigned char ZPAddr;
1913     Cycles = 4;
1914     ZPAddr = ReadMem (PC+1) + XR;
1915     YR     = ReadMem (ZPAddr);
1916     TEST_ZF (YR);
1917     TEST_SF (YR);
1918     PC += 2;
1919 }
1920
1921
1922
1923 static void OPC_6502_B5 (void)
1924 /* Opcode $B5: LDA zp,x */
1925 {
1926     unsigned char ZPAddr;
1927     Cycles = 4;
1928     ZPAddr = ReadMem (PC+1) + XR;
1929     AC     = ReadMem (ZPAddr);
1930     TEST_ZF (AC);
1931     TEST_SF (AC);
1932     PC += 2;
1933 }
1934
1935
1936
1937 static void OPC_6502_B6 (void)
1938 /* Opcode $B6: LDX zp,y */
1939 {
1940     unsigned char ZPAddr;
1941     Cycles = 4;
1942     ZPAddr = ReadMem (PC+1) + YR;
1943     XR     = ReadMem (ZPAddr);
1944     TEST_ZF (XR);
1945     TEST_SF (XR);
1946     PC += 2;
1947 }
1948
1949
1950
1951 static void OPC_6502_B7 (void)
1952 /* Opcode $B7 */
1953 {
1954     Illegal ();
1955 }
1956
1957
1958
1959 static void OPC_6502_B8 (void)
1960 /* Opcode $B8: CLV */
1961 {
1962     Cycles = 2;
1963     CLR_OF ();
1964     PC += 1;
1965 }
1966
1967
1968
1969 static void OPC_6502_B9 (void)
1970 /* Opcode $B9: LDA abs,y */
1971 {
1972     unsigned Addr;
1973     Cycles = 4;
1974     Addr = ReadMemW (PC+1);
1975     if (PAGE_CROSS (Addr, YR)) {
1976         ++Cycles;
1977     }
1978     AC = ReadMem (Addr + YR);
1979     TEST_ZF (AC);
1980     TEST_SF (AC);
1981     PC += 3;
1982 }
1983
1984
1985
1986 static void OPC_6502_BA (void)
1987 /* Opcode $BA: TSX */
1988 {
1989     Cycles = 2;
1990     XR = SP;
1991     TEST_ZF (XR);
1992     TEST_SF (XR);
1993     PC += 1;
1994 }
1995
1996
1997
1998 static void OPC_6502_BB (void)
1999 /* Opcode $BB */
2000 {
2001     Illegal ();
2002 }
2003
2004
2005
2006 static void OPC_6502_BC (void)
2007 /* Opcode $BC: LDY abs,x */
2008 {
2009     unsigned Addr;
2010     Cycles = 4;
2011     Addr = ReadMemW (PC+1);
2012     if (PAGE_CROSS (Addr, XR)) {
2013         ++Cycles;
2014     }
2015     YR = ReadMem (Addr + XR);
2016     TEST_ZF (YR);
2017     TEST_SF (YR);
2018     PC += 3;
2019 }
2020
2021
2022
2023 static void OPC_6502_BD (void)
2024 /* Opcode $BD: LDA abs,x */
2025 {
2026     unsigned Addr;
2027     Cycles = 4;
2028     Addr = ReadMemW (PC+1);
2029     if (PAGE_CROSS (Addr, XR)) {
2030         ++Cycles;
2031     }
2032     AC = ReadMem (Addr + XR);
2033     TEST_ZF (AC);
2034     TEST_SF (AC);
2035     PC += 3;
2036 }
2037
2038
2039
2040 static void OPC_6502_BE (void)
2041 /* Opcode $BE: LDX abs,y */
2042 {
2043     unsigned Addr;
2044     Cycles = 4;
2045     Addr = ReadMemW (PC+1);
2046     if (PAGE_CROSS (Addr, YR)) {
2047         ++Cycles;
2048     }
2049     XR = ReadMem (Addr + YR);
2050     TEST_ZF (XR);
2051     TEST_SF (XR);
2052     PC += 3;
2053 }
2054
2055
2056
2057 static void OPC_6502_BF (void)
2058 /* Opcode $BF */
2059 {
2060     Illegal ();
2061 }
2062
2063
2064
2065 static void OPC_6502_C0 (void)
2066 /* Opcode $C0: CPY #imm */
2067 {
2068     Cycles = 2;
2069     CMP (YR, ReadMem (PC+1));
2070     PC += 2;
2071 }
2072
2073
2074
2075 static void OPC_6502_C1 (void)
2076 /* Opcode $C1: CMP (zp,x) */
2077 {
2078     unsigned char ZPAddr;
2079     unsigned Addr;
2080     Cycles = 6;
2081     ZPAddr = ReadMem (PC+1) + XR;
2082     Addr   = ReadZeroPageW (ZPAddr);
2083     CMP (AC, ReadMem (Addr));
2084     PC += 2;
2085 }
2086
2087
2088
2089 static void OPC_6502_C2 (void)
2090 /* Opcode $C2 */
2091 {
2092     Illegal ();
2093 }
2094
2095
2096
2097 static void OPC_6502_C3 (void)
2098 /* Opcode $C3 */
2099 {
2100     Illegal ();
2101 }
2102
2103
2104
2105 static void OPC_6502_C4 (void)
2106 /* Opcode $C4: CPY zp */
2107 {
2108     unsigned char ZPAddr;
2109     Cycles = 3;
2110     ZPAddr = ReadMem (PC+1);
2111     CMP (YR, ReadMem (ZPAddr));
2112     PC += 2;
2113 }
2114
2115
2116
2117 static void OPC_6502_C5 (void)
2118 /* Opcode $C5: CMP zp */
2119 {
2120     unsigned char ZPAddr;
2121     Cycles = 3;
2122     ZPAddr = ReadMem (PC+1);
2123     CMP (AC, ReadMem (ZPAddr));
2124     PC += 2;
2125 }
2126
2127
2128
2129 static void OPC_6502_C6 (void)
2130 /* Opcode $C6: DEC zp */
2131 {
2132     unsigned char ZPAddr;
2133     unsigned char Val;
2134     Cycles = 5;
2135     ZPAddr = ReadMem (PC+1);
2136     Val    = ReadMem (ZPAddr) - 1;
2137     WriteMem (ZPAddr, Val);
2138     TEST_ZF (Val);
2139     TEST_SF (Val);
2140     PC += 2;
2141 }
2142
2143
2144
2145 static void OPC_6502_C7 (void)
2146 /* Opcode $C7 */
2147 {
2148     Illegal ();
2149 }
2150
2151
2152
2153 static void OPC_6502_C8 (void)
2154 /* Opcode $C8: INY */
2155 {
2156     Cycles = 2;
2157     ++YR;
2158     TEST_ZF (YR);
2159     TEST_SF (YR);
2160     PC += 1;
2161 }
2162
2163
2164
2165 static void OPC_6502_C9 (void)
2166 /* Opcode $C9: CMP #imm */
2167 {
2168     Cycles = 2;
2169     CMP (AC, ReadMem (PC+1));
2170     PC += 2;
2171 }
2172
2173
2174
2175 static void OPC_6502_CA (void)
2176 /* Opcode $CA: DEX */
2177 {
2178     Cycles = 2;
2179     --XR;
2180     TEST_ZF (XR);
2181     TEST_SF (XR);
2182     PC += 1;
2183 }
2184
2185
2186
2187 static void OPC_6502_CB (void)
2188 /* Opcode $CB */
2189 {
2190     Illegal ();
2191 }
2192
2193
2194
2195 static void OPC_6502_CC (void)
2196 /* Opcode $CC: CPY abs */
2197 {
2198     unsigned Addr;
2199     Cycles = 4;
2200     Addr   = ReadMemW (PC+1);
2201     CMP (YR, ReadMem (Addr));
2202     PC += 3;
2203 }
2204
2205
2206
2207 static void OPC_6502_CD (void)
2208 /* Opcode $CD: CMP abs */
2209 {
2210     unsigned Addr;
2211     Cycles = 4;
2212     Addr   = ReadMemW (PC+1);
2213     CMP (AC, ReadMem (Addr));
2214     PC += 3;
2215 }
2216
2217
2218
2219 static void OPC_6502_CE (void)
2220 /* Opcode $CE: DEC abs */
2221 {
2222     unsigned Addr;
2223     unsigned char Val;
2224     Cycles = 6;
2225     Addr = ReadMemW (PC+1);
2226     Val  = ReadMem (Addr) - 1;
2227     WriteMem (Addr, Val);
2228     TEST_ZF (Val);
2229     TEST_SF (Val);
2230     PC += 3;
2231 }
2232
2233
2234
2235 static void OPC_6502_CF (void)
2236 /* Opcode $CF */
2237 {
2238     Illegal ();
2239 }
2240
2241
2242
2243 static void OPC_6502_D0 (void)
2244 /* Opcode $D0: BNE */
2245 {
2246     BRANCH (!ZF_IS_SET ());
2247 }
2248
2249
2250
2251 static void OPC_6502_D1 (void)
2252 /* Opcode $D1: CMP (zp),y */
2253 {
2254     unsigned ZPAddr;
2255     unsigned Addr;
2256     Cycles = 5;
2257     ZPAddr = ReadMem (PC+1);
2258     Addr   = ReadMemW (ZPAddr);
2259     if (PAGE_CROSS (Addr, YR)) {
2260         ++Cycles;
2261     }
2262     CMP (AC, ReadMem (Addr + YR));
2263     PC += 2;
2264 }
2265
2266
2267
2268 static void OPC_6502_D2 (void)
2269 /* Opcode $D2 */
2270 {
2271     Illegal ();
2272 }
2273
2274
2275
2276 static void OPC_6502_D3 (void)
2277 /* Opcode $D3 */
2278 {
2279     Illegal ();
2280 }
2281
2282
2283
2284 static void OPC_6502_D4 (void)
2285 /* Opcode $D4 */
2286 {
2287     Illegal ();
2288 }
2289
2290
2291
2292 static void OPC_6502_D5 (void)
2293 /* Opcode $D5: CMP zp,x */
2294 {
2295     unsigned char ZPAddr;
2296     Cycles = 4;
2297     ZPAddr = ReadMem (PC+1) + XR;
2298     CMP (AC, ReadMem (ZPAddr));
2299     PC += 2;
2300 }
2301
2302
2303
2304 static void OPC_6502_D6 (void)
2305 /* Opcode $D6: DEC zp,x */
2306 {
2307     unsigned char ZPAddr;
2308     unsigned char Val;
2309     Cycles = 6;
2310     ZPAddr = ReadMem (PC+1) + XR;
2311     Val  = ReadMem (ZPAddr) - 1;
2312     WriteMem (ZPAddr, Val);
2313     TEST_ZF (Val);
2314     TEST_SF (Val);
2315     PC += 2;
2316 }
2317
2318
2319
2320 static void OPC_6502_D7 (void)
2321 /* Opcode $D7 */
2322 {
2323     Illegal ();
2324 }
2325
2326
2327
2328 static void OPC_6502_D8 (void)
2329 /* Opcode $D8: CLD */
2330 {
2331     CLR_DF ();
2332 }
2333
2334
2335
2336 static void OPC_6502_D9 (void)
2337 /* Opcode $D9: CMP abs,y */
2338 {
2339     unsigned Addr;
2340     Cycles = 4;
2341     Addr = ReadMemW (PC+1);
2342     if (PAGE_CROSS (Addr, YR)) {
2343         ++Cycles;
2344     }
2345     CMP (AC, ReadMem (Addr + YR));
2346     PC += 3;
2347 }
2348
2349
2350
2351 static void OPC_6502_DA (void)
2352 /* Opcode $DA */
2353 {
2354     Illegal ();
2355 }
2356
2357
2358
2359 static void OPC_6502_DB (void)
2360 /* Opcode $DB */
2361 {
2362     Illegal ();
2363 }
2364
2365
2366
2367 static void OPC_6502_DC (void)
2368 /* Opcode $DC */
2369 {
2370     Illegal ();
2371 }
2372
2373
2374
2375 static void OPC_6502_DD (void)
2376 /* Opcode $DD: CMP abs,x */
2377 {
2378     unsigned Addr;
2379     Cycles = 4;
2380     Addr = ReadMemW (PC+1);
2381     if (PAGE_CROSS (Addr, XR)) {
2382         ++Cycles;
2383     }
2384     CMP (AC, ReadMem (Addr + XR));
2385     PC += 3;
2386 }
2387
2388
2389
2390 static void OPC_6502_DE (void)
2391 /* Opcode $DE: DEC abs,x */
2392 {
2393     unsigned Addr;
2394     unsigned char Val;
2395     Cycles = 7;
2396     Addr = ReadMemW (PC+1) + XR;
2397     Val  = ReadMem (Addr) - 1;
2398     WriteMem (Addr, Val);
2399     TEST_ZF (Val);
2400     TEST_SF (Val);
2401     PC += 3;
2402 }
2403
2404
2405
2406 static void OPC_6502_DF (void)
2407 /* Opcode $DF */
2408 {
2409     Illegal ();
2410 }
2411
2412
2413
2414 static void OPC_6502_E0 (void)
2415 /* Opcode $E0: CPX #imm */
2416 {
2417     Cycles = 2;
2418     CMP (XR, ReadMem (PC+1));
2419     PC += 2;
2420 }
2421
2422
2423
2424 static void OPC_6502_E1 (void)
2425 /* Opcode $E1 */
2426 {
2427 }
2428
2429
2430
2431 static void OPC_6502_E2 (void)
2432 /* Opcode $E2 */
2433 {
2434     Illegal ();
2435 }
2436
2437
2438
2439 static void OPC_6502_E3 (void)
2440 /* Opcode $E3 */
2441 {
2442     Illegal ();
2443 }
2444
2445
2446
2447 static void OPC_6502_E4 (void)
2448 /* Opcode $E4: CPX zp */
2449 {
2450     unsigned char ZPAddr;
2451     Cycles = 3;
2452     ZPAddr = ReadMem (PC+1);
2453     CMP (XR, ReadMem (ZPAddr));
2454     PC += 2;
2455 }
2456
2457
2458
2459 static void OPC_6502_E5 (void)
2460 /* Opcode $E5 */
2461 {
2462 }
2463
2464
2465
2466 static void OPC_6502_E6 (void)
2467 /* Opcode $E6: INC zp */
2468 {
2469     unsigned char ZPAddr;
2470     unsigned char Val;
2471     Cycles = 5;
2472     ZPAddr = ReadMem (PC+1);
2473     Val    = ReadMem (ZPAddr) + 1;
2474     WriteMem (ZPAddr, Val);
2475     TEST_ZF (Val);
2476     TEST_SF (Val);
2477     PC += 2;
2478 }
2479
2480
2481
2482 static void OPC_6502_E7 (void)
2483 /* Opcode $E7 */
2484 {
2485     Illegal ();
2486 }
2487
2488
2489
2490 static void OPC_6502_E8 (void)
2491 /* Opcode $E8: INX */
2492 {
2493     Cycles = 2;
2494     ++XR;
2495     TEST_ZF (XR);
2496     TEST_SF (XR);
2497     PC += 1;
2498 }
2499
2500
2501
2502 static void OPC_6502_E9 (void)
2503 /* Opcode $E9 */
2504 {
2505 }
2506
2507
2508
2509 static void OPC_6502_EA (void)
2510 /* Opcode $EA: NOP */
2511 {
2512     /* This one is easy... */
2513     Cycles = 2;
2514     PC += 1;
2515 }
2516
2517
2518
2519 static void OPC_6502_EB (void)
2520 /* Opcode $EB */
2521 {
2522     Illegal ();
2523 }
2524
2525
2526
2527 static void OPC_6502_EC (void)
2528 /* Opcode $EC: CPX abs */
2529 {
2530     unsigned Addr;
2531     Cycles = 4;
2532     Addr   = ReadMemW (PC+1);
2533     CMP (XR, ReadMem (Addr));
2534     PC += 3;
2535 }
2536
2537
2538
2539 static void OPC_6502_ED (void)
2540 /* Opcode $ED */
2541 {
2542 }
2543
2544
2545
2546 static void OPC_6502_EE (void)
2547 /* Opcode $EE: INC abs */
2548 {
2549     unsigned Addr;
2550     unsigned char Val;
2551     Cycles = 6;
2552     Addr = ReadMemW (PC+1);
2553     Val  = ReadMem (Addr) + 1;
2554     WriteMem (Addr, Val);
2555     TEST_ZF (Val);
2556     TEST_SF (Val);
2557     PC += 3;
2558 }
2559
2560
2561
2562 static void OPC_6502_EF (void)
2563 /* Opcode $EF */
2564 {
2565     Illegal ();
2566 }
2567
2568
2569
2570 static void OPC_6502_F0 (void)
2571 /* Opcode $F0: BEQ */
2572 {
2573     BRANCH (ZF_IS_SET ());
2574 }
2575
2576
2577
2578 static void OPC_6502_F1 (void)
2579 /* Opcode $F1 */
2580 {
2581 }
2582
2583
2584
2585 static void OPC_6502_F2 (void)
2586 /* Opcode $F2 */
2587 {
2588     Illegal ();
2589 }
2590
2591
2592
2593 static void OPC_6502_F3 (void)
2594 /* Opcode $F3 */
2595 {
2596     Illegal ();
2597 }
2598
2599
2600
2601 static void OPC_6502_F4 (void)
2602 /* Opcode $F4 */
2603 {
2604     Illegal ();
2605 }
2606
2607
2608
2609 static void OPC_6502_F5 (void)
2610 /* Opcode $F5 */
2611 {
2612 }
2613
2614
2615
2616 static void OPC_6502_F6 (void)
2617 /* Opcode $F6: INC zp,x */
2618 {
2619     unsigned char ZPAddr;
2620     unsigned char Val;
2621     Cycles = 6;
2622     ZPAddr = ReadMem (PC+1) + XR;
2623     Val  = ReadMem (ZPAddr) + 1;
2624     WriteMem (ZPAddr, Val);
2625     TEST_ZF (Val);
2626     TEST_SF (Val);
2627     PC += 2;
2628 }
2629
2630
2631
2632 static void OPC_6502_F7 (void)
2633 /* Opcode $F7 */
2634 {
2635     Illegal ();
2636 }
2637
2638
2639
2640 static void OPC_6502_F8 (void)
2641 /* Opcode $F8: SED */
2642 {
2643     SET_DF ();
2644 }
2645
2646
2647
2648 static void OPC_6502_F9 (void)
2649 /* Opcode $F9 */
2650 {
2651 }
2652
2653
2654
2655 static void OPC_6502_FA (void)
2656 /* Opcode $FA */
2657 {
2658     Illegal ();
2659 }
2660
2661
2662
2663 static void OPC_6502_FB (void)
2664 /* Opcode $FB */
2665 {
2666     Illegal ();
2667 }
2668
2669
2670
2671 static void OPC_6502_FC (void)
2672 /* Opcode $FC */
2673 {
2674     Illegal ();
2675 }
2676
2677
2678
2679 static void OPC_6502_FD (void)
2680 /* Opcode $FD */
2681 {
2682 }
2683
2684
2685
2686 static void OPC_6502_FE (void)
2687 /* Opcode $FE: INC abs,x */
2688 {
2689     unsigned Addr;
2690     unsigned char Val;
2691     Cycles = 7;
2692     Addr = ReadMemW (PC+1) + XR;
2693     Val  = ReadMem (Addr) + 1;
2694     WriteMem (Addr, Val);
2695     TEST_ZF (Val);
2696     TEST_SF (Val);
2697     PC += 3;
2698 }
2699
2700
2701
2702 static void OPC_6502_FF (void)
2703 /* Opcode $FF */
2704 {
2705     Illegal ();
2706 }
2707
2708
2709
2710 /*****************************************************************************/
2711 /*                                   Data                                    */
2712 /*****************************************************************************/
2713
2714
2715
2716 /* Opcode handler table */
2717 typedef void (*OPCFunc) (void);
2718 static OPCFunc OPCTable[256] = {
2719     OPC_6502_00,
2720     OPC_6502_01,
2721     OPC_6502_02,
2722     OPC_6502_03,
2723     OPC_6502_04,
2724     OPC_6502_05,
2725     OPC_6502_06,
2726     OPC_6502_07,
2727     OPC_6502_08,
2728     OPC_6502_09,
2729     OPC_6502_0A,
2730     OPC_6502_0B,
2731     OPC_6502_0C,
2732     OPC_6502_0D,
2733     OPC_6502_0E,
2734     OPC_6502_0F,
2735     OPC_6502_10,
2736     OPC_6502_11,
2737     OPC_6502_12,
2738     OPC_6502_13,
2739     OPC_6502_14,
2740     OPC_6502_15,
2741     OPC_6502_16,
2742     OPC_6502_17,
2743     OPC_6502_18,
2744     OPC_6502_19,
2745     OPC_6502_1A,
2746     OPC_6502_1B,
2747     OPC_6502_1C,
2748     OPC_6502_1D,
2749     OPC_6502_1E,
2750     OPC_6502_1F,
2751     OPC_6502_20,
2752     OPC_6502_21,
2753     OPC_6502_22,
2754     OPC_6502_23,
2755     OPC_6502_24,
2756     OPC_6502_25,
2757     OPC_6502_26,
2758     OPC_6502_27,
2759     OPC_6502_28,
2760     OPC_6502_29,
2761     OPC_6502_2A,
2762     OPC_6502_2B,
2763     OPC_6502_2C,
2764     OPC_6502_2D,
2765     OPC_6502_2E,
2766     OPC_6502_2F,
2767     OPC_6502_30,
2768     OPC_6502_31,
2769     OPC_6502_32,
2770     OPC_6502_33,
2771     OPC_6502_34,
2772     OPC_6502_35,
2773     OPC_6502_36,
2774     OPC_6502_37,
2775     OPC_6502_38,
2776     OPC_6502_39,
2777     OPC_6502_3A,
2778     OPC_6502_3B,
2779     OPC_6502_3C,
2780     OPC_6502_3D,
2781     OPC_6502_3E,
2782     OPC_6502_3F,
2783     OPC_6502_40,
2784     OPC_6502_41,
2785     OPC_6502_42,
2786     OPC_6502_43,
2787     OPC_6502_44,
2788     OPC_6502_45,
2789     OPC_6502_46,
2790     OPC_6502_47,
2791     OPC_6502_48,
2792     OPC_6502_49,
2793     OPC_6502_4A,
2794     OPC_6502_4B,
2795     OPC_6502_4C,
2796     OPC_6502_4D,
2797     OPC_6502_4E,
2798     OPC_6502_4F,
2799     OPC_6502_50,
2800     OPC_6502_51,
2801     OPC_6502_52,
2802     OPC_6502_53,
2803     OPC_6502_54,
2804     OPC_6502_55,
2805     OPC_6502_56,
2806     OPC_6502_57,
2807     OPC_6502_58,
2808     OPC_6502_59,
2809     OPC_6502_5A,
2810     OPC_6502_5B,
2811     OPC_6502_5C,
2812     OPC_6502_5D,
2813     OPC_6502_5E,
2814     OPC_6502_5F,
2815     OPC_6502_60,
2816     OPC_6502_61,
2817     OPC_6502_62,
2818     OPC_6502_63,
2819     OPC_6502_64,
2820     OPC_6502_65,
2821     OPC_6502_66,
2822     OPC_6502_67,
2823     OPC_6502_68,
2824     OPC_6502_69,
2825     OPC_6502_6A,
2826     OPC_6502_6B,
2827     OPC_6502_6C,
2828     OPC_6502_6D,
2829     OPC_6502_6E,
2830     OPC_6502_6F,
2831     OPC_6502_70,
2832     OPC_6502_71,
2833     OPC_6502_72,
2834     OPC_6502_73,
2835     OPC_6502_74,
2836     OPC_6502_75,
2837     OPC_6502_76,
2838     OPC_6502_77,
2839     OPC_6502_78,
2840     OPC_6502_79,
2841     OPC_6502_7A,
2842     OPC_6502_7B,
2843     OPC_6502_7C,
2844     OPC_6502_7D,
2845     OPC_6502_7E,
2846     OPC_6502_7F,
2847     OPC_6502_80,
2848     OPC_6502_81,
2849     OPC_6502_82,
2850     OPC_6502_83,
2851     OPC_6502_84,
2852     OPC_6502_85,
2853     OPC_6502_86,
2854     OPC_6502_87,
2855     OPC_6502_88,
2856     OPC_6502_89,
2857     OPC_6502_8A,
2858     OPC_6502_8B,
2859     OPC_6502_8C,
2860     OPC_6502_8D,
2861     OPC_6502_8E,
2862     OPC_6502_8F,
2863     OPC_6502_90,
2864     OPC_6502_91,
2865     OPC_6502_92,
2866     OPC_6502_93,
2867     OPC_6502_94,
2868     OPC_6502_95,
2869     OPC_6502_96,
2870     OPC_6502_97,
2871     OPC_6502_98,
2872     OPC_6502_99,
2873     OPC_6502_9A,
2874     OPC_6502_9B,
2875     OPC_6502_9C,
2876     OPC_6502_9D,
2877     OPC_6502_9E,
2878     OPC_6502_9F,
2879     OPC_6502_A0,
2880     OPC_6502_A1,
2881     OPC_6502_A2,
2882     OPC_6502_A3,
2883     OPC_6502_A4,
2884     OPC_6502_A5,
2885     OPC_6502_A6,
2886     OPC_6502_A7,
2887     OPC_6502_A8,
2888     OPC_6502_A9,
2889     OPC_6502_AA,
2890     OPC_6502_AB,
2891     OPC_6502_AC,
2892     OPC_6502_AD,
2893     OPC_6502_AE,
2894     OPC_6502_AF,
2895     OPC_6502_B0,
2896     OPC_6502_B1,
2897     OPC_6502_B2,
2898     OPC_6502_B3,
2899     OPC_6502_B4,
2900     OPC_6502_B5,
2901     OPC_6502_B6,
2902     OPC_6502_B7,
2903     OPC_6502_B8,
2904     OPC_6502_B9,
2905     OPC_6502_BA,
2906     OPC_6502_BB,
2907     OPC_6502_BC,
2908     OPC_6502_BD,
2909     OPC_6502_BE,
2910     OPC_6502_BF,
2911     OPC_6502_C0,
2912     OPC_6502_C1,
2913     OPC_6502_C2,
2914     OPC_6502_C3,
2915     OPC_6502_C4,
2916     OPC_6502_C5,
2917     OPC_6502_C6,
2918     OPC_6502_C7,
2919     OPC_6502_C8,
2920     OPC_6502_C9,
2921     OPC_6502_CA,
2922     OPC_6502_CB,
2923     OPC_6502_CC,
2924     OPC_6502_CD,
2925     OPC_6502_CE,
2926     OPC_6502_CF,
2927     OPC_6502_D0,
2928     OPC_6502_D1,
2929     OPC_6502_D2,
2930     OPC_6502_D3,
2931     OPC_6502_D4,
2932     OPC_6502_D5,
2933     OPC_6502_D6,
2934     OPC_6502_D7,
2935     OPC_6502_D8,
2936     OPC_6502_D9,
2937     OPC_6502_DA,
2938     OPC_6502_DB,
2939     OPC_6502_DC,
2940     OPC_6502_DD,
2941     OPC_6502_DE,
2942     OPC_6502_DF,
2943     OPC_6502_E0,
2944     OPC_6502_E1,
2945     OPC_6502_E2,
2946     OPC_6502_E3,
2947     OPC_6502_E4,
2948     OPC_6502_E5,
2949     OPC_6502_E6,
2950     OPC_6502_E7,
2951     OPC_6502_E8,
2952     OPC_6502_E9,
2953     OPC_6502_EA,
2954     OPC_6502_EB,
2955     OPC_6502_EC,
2956     OPC_6502_ED,
2957     OPC_6502_EE,
2958     OPC_6502_EF,
2959     OPC_6502_F0,
2960     OPC_6502_F1,
2961     OPC_6502_F2,
2962     OPC_6502_F3,
2963     OPC_6502_F4,
2964     OPC_6502_F5,
2965     OPC_6502_F6,
2966     OPC_6502_F7,
2967     OPC_6502_F8,
2968     OPC_6502_F9,
2969     OPC_6502_FA,
2970     OPC_6502_FB,
2971     OPC_6502_FC,
2972     OPC_6502_FD,
2973     OPC_6502_FE,
2974     OPC_6502_FF,
2975 };
2976
2977
2978
2979 /*****************************************************************************/
2980 /*                                   Code                                    */
2981 /*****************************************************************************/
2982
2983
2984
2985 void RunCPU (void)
2986 /* Run the CPU */
2987 {
2988     while (!CPUHalted) {
2989
2990         /* Get the next opcode */
2991         unsigned char B = 0x00;
2992
2993         /* Execute it */
2994         OPCTable[B] ();
2995     }
2996 }
2997
2998
2999