]> git.sur5r.net Git - cc65/blob - src/sim65/cpucore.c
Working
[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 "attrib.h"
41 #include "print.h"
42
43 /* sim65 */
44 #include "cputype.h"
45 #include "global.h"
46 #include "memory.h"
47 #include "cpucore.h"
48
49
50
51 /*****************************************************************************/
52 /*                                   Data                                    */
53 /*****************************************************************************/
54
55
56
57 /* Registers */
58 unsigned char   AC;             /* Accumulator */
59 unsigned char   XR;             /* X register */
60 unsigned char   YR;             /* Y register */
61 unsigned char   SR;             /* Status register */
62 unsigned char   SP;             /* Stackpointer */
63 unsigned        PC;             /* Program counter */
64
65 /* Count the total number of cylcles */
66 unsigned        Cycles;         /* Cycles per insn */
67 unsigned long   TotalCycles;    /* Total cycles */
68
69 /* Allow the stack page to be changed */
70 static unsigned StackPage = 0x100;
71
72 /* Status register bits */
73 #define CF      0x01            /* Carry flag */
74 #define ZF      0x02            /* Zero flag */
75 #define IF      0x04            /* Interrupt flag */
76 #define DF      0x08            /* Decimal flag */
77 #define BF      0x10            /* Break flag */
78 #define OF      0x40            /* Overflow flag */
79 #define SF      0x80            /* Sign flag */
80
81 /* */
82 int CPUHalted;
83
84
85
86 /*****************************************************************************/
87 /*                        Helper functions and macros                        */
88 /*****************************************************************************/
89
90
91
92 /* Return the flags as a boolean value (0/1) */
93 #define GET_CF()        ((SR & CF) != 0)
94 #define GET_ZF()        ((SR & ZF) != 0)
95 #define GET_IF()        ((SR & IF) != 0)
96 #define GET_DF()        ((SR & DF) != 0)
97 #define GET_BF()        ((SR & BF) != 0)
98 #define GET_OF()        ((SR & OF) != 0)
99 #define GET_SF()        ((SR & SF) != 0)
100
101 /* Set the flags. The parameter is a boolean flag that says if the flag should be
102  * set or reset.
103  */
104 #define SET_CF(f)       do { if (f) { SR |= CF; } else { SR &= ~CF; } } while (0)
105 #define SET_ZF(f)       do { if (f) { SR |= ZF; } else { SR &= ~ZF; } } while (0)
106 #define SET_IF(f)       do { if (f) { SR |= IF; } else { SR &= ~IF; } } while (0)
107 #define SET_DF(f)       do { if (f) { SR |= DF; } else { SR &= ~DF; } } while (0)
108 #define SET_BF(f)       do { if (f) { SR |= BF; } else { SR &= ~BF; } } while (0)
109 #define SET_OF(f)       do { if (f) { SR |= OF; } else { SR &= ~OF; } } while (0)
110 #define SET_SF(f)       do { if (f) { SR |= SF; } else { SR &= ~SF; } } while (0)
111
112 /* Special test and set macros. The meaning of the parameter depends on the
113  * actual flag that should be set or reset.
114  */
115 #define TEST_ZF(v)              SET_ZF (((v) & 0xFF) == 0)
116 #define TEST_SF(v)              SET_SF (((v) & 0x80) != 0)
117 #define TEST_CF(v)              SET_CF (((v) & 0xFF00) != 0)
118
119 /* Program counter halves */
120 #define PCL             (PC & 0xFF)
121 #define PCH             ((PC >> 8) & 0xFF)
122
123 /* Stack operations */
124 #define PUSH(Val)       MemWriteByte (StackPage + SP--, Val)
125 #define POP()           MemReadByte (StackPage + ++SP)
126
127 /* Test for page cross */
128 #define PAGE_CROSS(addr,offs)   ((((addr) & 0xFF) + offs) >= 0x100)
129
130 /* #imm */
131 #define AC_OP_IMM(op)                           \
132     Cycles = 2;                                 \
133     AC = AC op MemReadByte (PC+1);              \
134     TEST_ZF (AC);                               \
135     TEST_SF (AC);                               \
136     PC += 2
137
138 /* zp */
139 #define AC_OP_ZP(op)                            \
140     Cycles = 3;                                 \
141     AC = AC op MemReadByte (MemReadByte (PC+1));\
142     TEST_ZF (AC);                               \
143     TEST_SF (AC);                               \
144     PC += 2
145
146 /* zp,x */
147 #define AC_OP_ZPX(op)                           \
148     unsigned char ZPAddr;                       \
149     Cycles = 4;                                 \
150     ZPAddr = MemReadByte (PC+1) + XR;           \
151     AC = AC op MemReadByte (ZPAddr);            \
152     TEST_ZF (AC);                               \
153     TEST_SF (AC);                               \
154     PC += 2
155
156 /* zp,y */
157 #define AC_OP_ZPY(op)                           \
158     unsigned char ZPAddr;                       \
159     Cycles = 4;                                 \
160     ZPAddr = MemReadByte (PC+1) + YR;           \
161     AC = AC op MemReadByte (ZPAddr);            \
162     TEST_ZF (AC);                               \
163     TEST_SF (AC);                               \
164     PC += 2
165
166 /* abs */
167 #define AC_OP_ABS(op)                           \
168     unsigned Addr;                              \
169     Cycles = 4;                                 \
170     Addr = MemReadWord (PC+1);                  \
171     AC = AC op MemReadByte (Addr);              \
172     TEST_ZF (AC);                               \
173     TEST_SF (AC);                               \
174     PC += 3
175
176 /* abs,x */
177 #define AC_OP_ABSX(op)                          \
178     unsigned Addr;                              \
179     Cycles = 4;                                 \
180     Addr = MemReadWord (PC+1);                  \
181     if (PAGE_CROSS (Addr, XR)) {                \
182         ++Cycles;                               \
183     }                                           \
184     AC = AC | MemReadByte (Addr + XR);          \
185     TEST_ZF (AC);                               \
186     TEST_SF (AC);                               \
187     PC += 3
188
189 /* abs,y */
190 #define AC_OP_ABSY(op)                          \
191     unsigned Addr;                              \
192     Cycles = 4;                                 \
193     Addr = MemReadWord (PC+1);                  \
194     if (PAGE_CROSS (Addr, YR)) {                \
195         ++Cycles;                               \
196     }                                           \
197     AC = AC | MemReadByte (Addr + YR);          \
198     TEST_ZF (AC);                               \
199     TEST_SF (AC);                               \
200     PC += 3
201
202 /* (zp,x) */
203 #define AC_OP_ZPXIND(op)                        \
204     unsigned char ZPAddr;                       \
205     unsigned Addr;                              \
206     Cycles = 6;                                 \
207     ZPAddr = MemReadByte (PC+1) + XR;           \
208     Addr = MemReadZPWord (ZPAddr);              \
209     AC = AC op MemReadByte (Addr);              \
210     TEST_ZF (AC);                               \
211     TEST_SF (AC);                               \
212     PC += 2
213
214 /* (zp),y */
215 #define AC_OP_ZPINDY(op)                        \
216     unsigned char ZPAddr;                       \
217     unsigned Addr;                              \
218     Cycles = 5;                                 \
219     ZPAddr = MemReadByte (PC+1);                \
220     Addr = MemReadZPWord (ZPAddr) + YR;         \
221     AC = AC op MemReadByte (Addr);              \
222     TEST_ZF (AC);                               \
223     TEST_SF (AC);                               \
224     PC += 2
225
226 /* ADC */
227 #define ADC(v)                                  \
228     if (GET_DF ()) {                            \
229         NotImplemented ();                      \
230     } else {                                    \
231         unsigned Val;                           \
232         unsigned char rhs = v;                  \
233         Val = AC + rhs + GET_CF ();             \
234         AC = (unsigned char) Val;               \
235         TEST_ZF (AC);                           \
236         TEST_SF (AC);                           \
237         TEST_CF (Val);                          \
238         SET_OF (!((AC ^ rhs) & 0x80) &&         \
239                 ((AC ^ Val) & 0x80));           \
240     }
241
242 /* branches */
243 #define BRANCH(cond)                            \
244     Cycles = 2;                                 \
245     if (cond) {                                 \
246         signed char Offs;                       \
247         unsigned char OldPCH;                   \
248         ++Cycles;                               \
249         Offs = (signed char) MemReadByte (PC+1);\
250         OldPCH = PCH;                           \
251         PC += 2 + (int) Offs;                   \
252         if (PCH != OldPCH) {                    \
253             ++Cycles;                           \
254         }                                       \
255     } else {                                    \
256         PC += 2;                                \
257     }
258
259 /* compares */
260 #define CMP(v1,v2)                              \
261     {                                           \
262         unsigned Result = v1 - v2;              \
263         TEST_ZF (Result & 0xFF);                \
264         TEST_SF (Result);                       \
265         SET_CF (Result <= 0xFF);                \
266     }
267
268
269 /* ROL */
270 #define ROL(Val)                                \
271     Val <<= 1;                                  \
272     if (GET_CF ()) {                            \
273         Val |= 0x01;                            \
274     }                                           \
275     TEST_ZF (Val);                              \
276     TEST_SF (Val);                              \
277     TEST_CF (Val)
278
279 /* ROR */
280 #define ROR(Val)                                \
281     if (GET_CF ()) {                            \
282         Val |= 0x100;                           \
283     }                                           \
284     SET_CF (Val & 0x01);                        \
285     Val >>= 1;                                  \
286     TEST_ZF (Val);                              \
287     TEST_SF (Val)
288
289 /* SBC */
290 #define SBC(v)                                  \
291     if (GET_DF ()) {                            \
292         NotImplemented ();                      \
293     } else {                                    \
294         unsigned Val;                           \
295         unsigned char rhs = v;                  \
296         Val = AC - rhs - (!GET_CF ());          \
297         AC = (unsigned char) Val;               \
298         TEST_ZF (AC);                           \
299         TEST_SF (AC);                           \
300         SET_CF (Val <= 0xFF);                   \
301         SET_OF (((AC^rhs) & (AC^Val) & 0x80));  \
302     }
303
304
305
306 /*****************************************************************************/
307 /*                               Helper functions                            */
308 /*****************************************************************************/
309
310
311
312 static void OPC_Illegal (void) attribute ((noreturn));
313 static void OPC_Illegal (void)
314 {
315     fprintf (stderr, "Illegal: $%02X\n", MemReadByte (PC));
316     exit (EXIT_FAILURE);
317 }
318
319
320
321 static void NotImplemented (void) attribute ((noreturn));
322 static void NotImplemented (void)
323 {
324     fprintf (stderr, "Not implemented: $%02X\n", MemReadByte (PC));
325     exit (EXIT_FAILURE);
326 }
327
328
329
330 /*****************************************************************************/
331 /*                                   Code                                    */
332 /*****************************************************************************/
333
334
335
336 static void OPC_6502_00 (void)
337 /* Opcode $00: BRK */
338 {
339     Cycles = 7;
340     PC += 2;
341     SET_BF (1);
342     PUSH (PCH);
343     PUSH (PCL);
344     PUSH (SR);
345     SET_IF (1);
346     PC = MemReadWord (0xFFFE);
347 }
348
349
350
351 static void OPC_6502_01 (void)
352 /* Opcode $01: ORA (ind,x) */
353 {
354     AC_OP_ZPXIND (|);
355 }
356
357
358
359 static void OPC_6502_05 (void)
360 /* Opcode $05: ORA zp */
361 {
362     AC_OP_ZP (|);
363 }
364
365
366
367 static void OPC_6502_06 (void)
368 /* Opcode $06: ASL zp */
369 {
370     unsigned char ZPAddr;
371     unsigned Val;
372     Cycles = 5;
373     ZPAddr = MemReadByte (PC+1);
374     Val    = MemReadByte (ZPAddr) << 1;
375     MemWriteByte (ZPAddr, (unsigned char) Val);
376     TEST_ZF (Val & 0xFF);
377     TEST_SF (Val);
378     SET_CF (Val & 0x100);
379     PC += 2;
380 }
381
382
383
384 static void OPC_6502_08 (void)
385 /* Opcode $08: PHP */
386 {
387     Cycles = 3;
388     PUSH (SR & ~BF);
389     PC += 1;
390 }
391
392
393
394 static void OPC_6502_09 (void)
395 /* Opcode $09: ORA #imm */
396 {
397     AC_OP_IMM (|);
398 }
399
400
401
402 static void OPC_6502_0A (void)
403 /* Opcode $0A: ASL a */
404 {
405     unsigned Val;
406     Cycles = 2;
407     Val    = AC << 1;
408     AC     = (unsigned char) Val;
409     TEST_ZF (Val & 0xFF);
410     TEST_SF (Val);
411     SET_CF (Val & 0x100);
412     PC += 1;
413 }
414
415
416
417 static void OPC_6502_0D (void)
418 /* Opcode $0D: ORA abs */
419 {
420     AC_OP_ABS (|);
421 }
422
423
424
425 static void OPC_6502_0E (void)
426 /* Opcode $0E: ALS abs */
427 {
428     unsigned Addr;
429     unsigned Val;
430     Cycles = 6;
431     Addr = MemReadWord (PC+1);
432     Val  = MemReadByte (Addr) << 1;
433     MemWriteByte (Addr, (unsigned char) Val);
434     TEST_ZF (Val & 0xFF);
435     TEST_SF (Val);
436     SET_CF (Val & 0x100);
437     PC += 3;
438 }
439
440
441
442 static void OPC_6502_10 (void)
443 /* Opcode $10: BPL */
444 {
445     BRANCH (!GET_SF ());
446 }
447
448
449
450 static void OPC_6502_11 (void)
451 /* Opcode $11: ORA (zp),y */
452 {
453     AC_OP_ZPINDY (|);
454 }
455
456
457
458 static void OPC_6502_15 (void)
459 /* Opcode $15: ORA zp,x */
460 {
461    AC_OP_ZPX (|);
462 }
463
464
465
466 static void OPC_6502_16 (void)
467 /* Opcode $16: ASL zp,x */
468 {
469     unsigned char ZPAddr;
470     unsigned Val;
471     Cycles = 6;
472     ZPAddr = MemReadByte (PC+1) + XR;
473     Val    = MemReadByte (ZPAddr) << 1;
474     MemWriteByte (ZPAddr, (unsigned char) Val);
475     TEST_ZF (Val & 0xFF);
476     TEST_SF (Val);
477     SET_CF (Val & 0x100);
478     PC += 2;
479 }
480
481
482
483 static void OPC_6502_18 (void)
484 /* Opcode $18: CLC */
485 {
486     Cycles = 2;
487     SET_CF (0);
488     PC += 1;
489 }
490
491
492
493 static void OPC_6502_19 (void)
494 /* Opcode $19: ORA abs,y */
495 {
496     AC_OP_ABSY (|);
497 }
498
499
500
501 static void OPC_6502_1D (void)
502 /* Opcode $1D: ORA abs,x */
503 {
504     AC_OP_ABSX (|);
505 }
506
507
508
509 static void OPC_6502_1E (void)
510 /* Opcode $1E: ASL abs,x */
511 {
512     unsigned Addr;
513     unsigned Val;
514     Cycles = 7;
515     Addr = MemReadWord (PC+1) + XR;
516     Val  = MemReadByte (Addr) << 1;
517     MemWriteByte (Addr, (unsigned char) Val);
518     TEST_ZF (Val & 0xFF);
519     TEST_SF (Val);
520     SET_CF (Val & 0x100);
521     PC += 3;
522 }
523
524
525
526 static void OPC_6502_20 (void)
527 /* Opcode $20: JSR */
528 {
529     unsigned Addr;
530     Cycles = 6;
531     Addr   = MemReadWord (PC+1);
532     PC += 2;
533     PUSH (PCH);
534     PUSH (PCL);
535     PC = Addr;
536 }
537
538
539
540 static void OPC_6502_21 (void)
541 /* Opcode $21: AND (zp,x) */
542 {
543     AC_OP_ZPXIND (&);
544 }
545
546
547
548 static void OPC_6502_24 (void)
549 /* Opcode $24: BIT zp */
550 {
551     unsigned char ZPAddr;
552     unsigned char Val;
553     Cycles = 3;
554     ZPAddr = MemReadByte (PC+1);
555     Val    = MemReadByte (ZPAddr);
556     SET_SF (Val & 0x80);
557     SET_OF (Val & 0x40);
558     SET_ZF ((Val & AC) == 0);
559     PC += 2;
560 }
561
562
563
564 static void OPC_6502_25 (void)
565 /* Opcode $25: AND zp */
566 {
567     AC_OP_ZP (&);
568 }
569
570
571
572 static void OPC_6502_26 (void)
573 /* Opcode $26: ROL zp */
574 {
575     unsigned char ZPAddr;
576     unsigned Val;
577     Cycles = 5;
578     ZPAddr = MemReadByte (PC+1);
579     Val    = MemReadByte (ZPAddr);
580     ROL (Val);
581     MemWriteByte (ZPAddr, Val);
582     PC += 2;
583 }
584
585
586
587 static void OPC_6502_28 (void)
588 /* Opcode $28: PLP */
589 {
590     Cycles = 4;
591     SR = (POP () & ~BF);
592     PC += 1;
593 }
594
595
596
597 static void OPC_6502_29 (void)
598 /* Opcode $29: AND #imm */
599 {
600     AC_OP_IMM (&);
601 }
602
603
604
605 static void OPC_6502_2A (void)
606 /* Opcode $2A: ROL a */
607 {
608     unsigned Val;
609     Cycles = 2;
610     Val    = AC;
611     ROL (Val);
612     AC = (unsigned char) Val;
613     PC += 1;
614 }
615
616
617
618 static void OPC_6502_2C (void)
619 /* Opcode $2C: BIT abs */
620 {
621     unsigned Addr;
622     unsigned char Val;
623     Cycles = 4;
624     Addr = MemReadByte (PC+1);
625     Val  = MemReadByte (Addr);
626     SET_SF (Val & 0x80);
627     SET_OF (Val & 0x40);
628     SET_ZF ((Val & AC) == 0);
629     PC += 3;
630 }
631
632
633
634 static void OPC_6502_2D (void)
635 /* Opcode $2D: AND abs */
636 {
637     AC_OP_ABS (&);
638 }
639
640
641
642 static void OPC_6502_2E (void)
643 /* Opcode $2E: ROL abs */
644 {
645     unsigned Addr;
646     unsigned Val;
647     Cycles = 6;
648     Addr = MemReadWord (PC+1);
649     Val  = MemReadByte (Addr);
650     ROL (Val);
651     MemWriteByte (Addr, Val);
652     PC += 3;
653 }
654
655
656
657 static void OPC_6502_30 (void)
658 /* Opcode $30: BMI */
659 {
660     BRANCH (GET_SF ());
661 }
662
663
664
665 static void OPC_6502_31 (void)
666 /* Opcode $31: AND (zp),y */
667 {
668     AC_OP_ZPINDY (&);
669 }
670
671
672
673 static void OPC_6502_35 (void)
674 /* Opcode $35: AND zp,x */
675 {
676     AC_OP_ZPX (&);
677 }
678
679
680
681 static void OPC_6502_36 (void)
682 /* Opcode $36: ROL zp,x */
683 {
684     unsigned char ZPAddr;
685     unsigned Val;
686     Cycles = 6;
687     ZPAddr = MemReadByte (PC+1) + XR;
688     Val    = MemReadByte (ZPAddr);
689     ROL (Val);
690     MemWriteByte (ZPAddr, Val);
691     PC += 2;
692 }
693
694
695
696 static void OPC_6502_38 (void)
697 /* Opcode $38: SEC */
698 {
699     Cycles = 2;
700     SET_CF (1);
701     PC += 1;
702 }
703
704
705
706 static void OPC_6502_39 (void)
707 /* Opcode $39: AND abs,y */
708 {
709     AC_OP_ABSY (&);
710 }
711
712
713
714 static void OPC_6502_3D (void)
715 /* Opcode $3D: AND abs,x */
716 {
717     AC_OP_ABSX (&);
718 }
719
720
721
722 static void OPC_6502_3E (void)
723 /* Opcode $3E: ROL abs,x */
724 {
725     unsigned Addr;
726     unsigned Val;
727     Cycles = 7;
728     Addr = MemReadWord (PC+1) + XR;
729     Val  = MemReadByte (Addr);
730     ROL (Val);
731     MemWriteByte (Addr, Val);
732     PC += 2;
733 }
734
735
736
737 static void OPC_6502_40 (void)
738 /* Opcode $40: RTI */
739 {
740     Cycles = 6;
741     SR = POP ();
742     PC = POP ();                /* PCL */
743     PC |= (POP () << 8);        /* PCH */
744 }
745
746
747
748 static void OPC_6502_41 (void)
749 /* Opcode $41: EOR (zp,x) */
750 {
751     AC_OP_ZPXIND (^);
752 }
753
754
755
756 static void OPC_6502_45 (void)
757 /* Opcode $45: EOR zp */
758 {
759     AC_OP_ZP (^);
760 }
761
762
763
764 static void OPC_6502_46 (void)
765 /* Opcode $46: LSR zp */
766 {
767     unsigned char ZPAddr;
768     unsigned char Val;
769     Cycles = 5;
770     ZPAddr = MemReadByte (PC+1);
771     Val    = MemReadByte (ZPAddr);
772     SET_CF (Val & 0x01);
773     Val >>= 1;
774     MemWriteByte (ZPAddr, Val);
775     TEST_ZF (Val);
776     TEST_SF (Val);
777     PC += 2;
778 }
779
780
781
782 static void OPC_6502_48 (void)
783 /* Opcode $48: PHA */
784 {
785     Cycles = 3;
786     PUSH (AC);
787     PC += 1;
788 }
789
790
791
792 static void OPC_6502_49 (void)
793 /* Opcode $49: EOR #imm */
794 {
795     AC_OP_IMM (^);
796 }
797
798
799
800 static void OPC_6502_4A (void)
801 /* Opcode $4A: LSR a */
802 {
803     Cycles = 2;
804     SET_CF (AC & 0x01);
805     AC >>= 1;
806     TEST_ZF (AC);
807     TEST_SF (AC);
808     PC += 1;
809 }
810
811
812
813 static void OPC_6502_4C (void)
814 /* Opcode $4C: JMP abs */
815 {
816     Cycles = 3;
817     PC = MemReadWord (PC+1);
818 }
819
820
821
822 static void OPC_6502_4D (void)
823 /* Opcode $4D: EOR abs */
824 {
825     AC_OP_ABS (^);
826 }
827
828
829
830 static void OPC_6502_4E (void)
831 /* Opcode $4E: LSR abs */
832 {
833     unsigned Addr;
834     unsigned char Val;
835     Cycles = 6;
836     Addr = MemReadWord (PC+1);
837     Val  = MemReadByte (Addr);
838     SET_CF (Val & 0x01);
839     Val >>= 1;
840     MemWriteByte (Addr, Val);
841     TEST_ZF (Val);
842     TEST_SF (Val);
843     PC += 3;
844 }
845
846
847
848 static void OPC_6502_50 (void)
849 /* Opcode $50: BVC */
850 {
851     BRANCH (!GET_OF ());
852 }
853
854
855
856 static void OPC_6502_51 (void)
857 /* Opcode $51: EOR (zp),y */
858 {
859     AC_OP_ZPINDY (^);
860 }
861
862
863
864 static void OPC_6502_55 (void)
865 /* Opcode $55: EOR zp,x */
866 {
867     AC_OP_ZPX (^);
868 }
869
870
871
872 static void OPC_6502_56 (void)
873 /* Opcode $56: LSR zp,x */
874 {
875     unsigned char ZPAddr;
876     unsigned char Val;
877     Cycles = 6;
878     ZPAddr = MemReadByte (PC+1) + XR;
879     Val    = MemReadByte (ZPAddr);
880     SET_CF (Val & 0x01);
881     Val >>= 1;
882     MemWriteByte (ZPAddr, Val);
883     TEST_ZF (Val);
884     TEST_SF (Val);
885     PC += 2;
886 }
887
888
889
890 static void OPC_6502_58 (void)
891 /* Opcode $58: CLI */
892 {
893     Cycles = 2;
894     SET_IF (0);
895     PC += 1;
896 }
897
898
899
900 static void OPC_6502_59 (void)
901 /* Opcode $59: EOR abs,y */
902 {
903     AC_OP_ABSY (^);
904 }
905
906
907
908 static void OPC_6502_5D (void)
909 /* Opcode $5D: EOR abs,x */
910 {
911     AC_OP_ABSX (^);
912 }
913
914
915
916 static void OPC_6502_5E (void)
917 /* Opcode $5E: LSR abs,x */
918 {
919     unsigned Addr;
920     unsigned char Val;
921     Cycles = 7;
922     Addr = MemReadWord (PC+1) + XR;
923     Val  = MemReadByte (Addr);
924     SET_CF (Val & 0x01);
925     Val >>= 1;
926     MemWriteByte (Addr, Val);
927     TEST_ZF (Val);
928     TEST_SF (Val);
929     PC += 3;
930 }
931
932
933
934 static void OPC_6502_60 (void)
935 /* Opcode $60: RTS */
936 {
937     Cycles = 6;
938     PC = POP ();                /* PCL */
939     PC |= (POP () << 8);        /* PCH */
940     PC += 1;
941 }
942
943
944
945 static void OPC_6502_61 (void)
946 /* Opcode $61: ADC (zp,x) */
947 {
948     unsigned char ZPAddr;
949     unsigned Addr;
950     Cycles = 6;
951     ZPAddr = MemReadByte (PC+1) + XR;
952     Addr   = MemReadZPWord (ZPAddr);
953     ADC (MemReadByte (Addr));
954     PC += 2;
955 }
956
957
958
959 static void OPC_6502_65 (void)
960 /* Opcode $65: ADC zp */
961 {
962     unsigned char ZPAddr;
963     Cycles = 3;
964     ZPAddr = MemReadByte (PC+1);
965     ADC (MemReadByte (ZPAddr));
966     PC += 2;
967 }
968
969
970
971 static void OPC_6502_66 (void)
972 /* Opcode $66: ROR zp */
973 {
974     unsigned char ZPAddr;
975     unsigned Val;
976     Cycles = 5;
977     ZPAddr = MemReadByte (PC+1);
978     Val    = MemReadByte (ZPAddr);
979     ROR (Val);
980     MemWriteByte (ZPAddr, Val);
981     PC += 2;
982 }
983
984
985
986 static void OPC_6502_68 (void)
987 /* Opcode $68: PLA */
988 {
989     Cycles = 4;
990     AC = POP ();
991     TEST_ZF (AC);
992     TEST_SF (AC);
993     PC += 1;
994 }
995
996
997
998 static void OPC_6502_69 (void)
999 /* Opcode $69: ADC #imm */
1000 {
1001     Cycles = 2;
1002     ADC (MemReadByte (PC+1));
1003     PC += 2;
1004 }
1005
1006
1007
1008 static void OPC_6502_6A (void)
1009 /* Opcode $6A: ROR a */
1010 {
1011     unsigned Val;
1012     Cycles = 2;
1013     Val = AC;
1014     ROR (Val);
1015     AC = (unsigned char) Val;
1016     PC += 1;
1017 }
1018
1019
1020
1021 static void OPC_6502_6C (void)
1022 /* Opcode $6C: JMP (ind) */
1023 {
1024     unsigned Addr;
1025     Cycles = 5;
1026     Addr = MemReadWord (PC+1);
1027     if (CPU == CPU_6502) {
1028         /* Emulate the 6502 bug */
1029         PC = MemReadByte (Addr);
1030         Addr = (Addr & 0xFF00) | ((Addr + 1) & 0xFF);
1031         PC |= (MemReadByte (Addr) << 8);
1032     } else {
1033         /* 65C02 and above have this bug fixed */
1034         PC = MemReadWord (Addr);
1035     }
1036     PC += 3;
1037 }
1038
1039
1040
1041 static void OPC_6502_6D (void)
1042 /* Opcode $6D: ADC abs */
1043 {
1044     unsigned Addr;
1045     Cycles = 4;
1046     Addr   = MemReadWord (PC+1);
1047     ADC (MemReadByte (Addr));
1048     PC += 3;
1049 }
1050
1051
1052
1053 static void OPC_6502_6E (void)
1054 /* Opcode $6E: ROR abs */
1055 {
1056     unsigned Addr;
1057     unsigned Val;
1058     Cycles = 6;
1059     Addr = MemReadWord (PC+1);
1060     Val  = MemReadByte (Addr);
1061     ROR (Val);
1062     MemWriteByte (Addr, Val);
1063     PC += 3;
1064 }
1065
1066
1067
1068 static void OPC_6502_70 (void)
1069 /* Opcode $70: BVS */
1070 {
1071     BRANCH (GET_OF ());
1072 }
1073
1074
1075
1076 static void OPC_6502_71 (void)
1077 /* Opcode $71: ADC (zp),y */
1078 {
1079     unsigned char ZPAddr;
1080     unsigned Addr;
1081     Cycles = 5;
1082     ZPAddr = MemReadByte (PC+1);
1083     Addr   = MemReadZPWord (ZPAddr);
1084     if (PAGE_CROSS (Addr, YR)) {
1085         ++Cycles;
1086     }
1087     ADC (MemReadByte (Addr + YR));
1088     PC += 2;
1089 }
1090
1091
1092
1093 static void OPC_6502_75 (void)
1094 /* Opcode $75: ADC zp,x */
1095 {
1096     unsigned char ZPAddr;
1097     Cycles = 4;
1098     ZPAddr = MemReadByte (PC+1) + XR;
1099     ADC (MemReadByte (ZPAddr));
1100     PC += 2;
1101 }
1102
1103
1104
1105 static void OPC_6502_76 (void)
1106 /* Opcode $76: ROR zp,x */
1107 {
1108     unsigned char ZPAddr;
1109     unsigned Val;
1110     Cycles = 6;
1111     ZPAddr = MemReadByte (PC+1) + XR;
1112     Val    = MemReadByte (ZPAddr);
1113     ROR (Val);
1114     MemWriteByte (ZPAddr, Val);
1115     PC += 2;
1116 }
1117
1118
1119
1120 static void OPC_6502_78 (void)
1121 /* Opcode $78: SEI */
1122 {
1123     Cycles = 2;
1124     SET_IF (1);
1125     PC += 1;
1126 }
1127
1128
1129
1130 static void OPC_6502_79 (void)
1131 /* Opcode $79: ADC abs,y */
1132 {
1133     unsigned Addr;
1134     Cycles = 4;
1135     Addr   = MemReadWord (PC+1);
1136     if (PAGE_CROSS (Addr, YR)) {
1137         ++Cycles;
1138     }
1139     ADC (MemReadByte (Addr + YR));
1140     PC += 3;
1141 }
1142
1143
1144
1145 static void OPC_6502_7D (void)
1146 /* Opcode $7D: ADC abs,x */
1147 {
1148     unsigned Addr;
1149     Cycles = 4;
1150     Addr   = MemReadWord (PC+1);
1151     if (PAGE_CROSS (Addr, XR)) {
1152         ++Cycles;
1153     }
1154     ADC (MemReadByte (Addr + XR));
1155     PC += 3;
1156 }
1157
1158
1159
1160 static void OPC_6502_7E (void)
1161 /* Opcode $7E: ROR abs,x */
1162 {
1163     unsigned Addr;
1164     unsigned Val;
1165     Cycles = 7;
1166     Addr = MemReadByte (PC+1) + XR;
1167     Val  = MemReadByte (Addr);
1168     ROR (Val);
1169     MemWriteByte (Addr, Val);
1170     PC += 3;
1171 }
1172
1173
1174
1175 static void OPC_6502_81 (void)
1176 /* Opcode $81: STA (zp,x) */
1177 {
1178     unsigned char ZPAddr;
1179     unsigned Addr;
1180     Cycles = 6;
1181     ZPAddr = MemReadByte (PC+1) + XR;
1182     Addr   = MemReadZPWord (ZPAddr);
1183     MemWriteByte (Addr, AC);
1184     PC += 2;
1185 }
1186
1187
1188
1189 static void OPC_6502_84 (void)
1190 /* Opcode $84: STY zp */
1191 {
1192     unsigned char ZPAddr;
1193     Cycles = 3;
1194     ZPAddr = MemReadByte (PC+1);
1195     MemWriteByte (ZPAddr, YR);
1196     PC += 2;
1197 }
1198
1199
1200
1201 static void OPC_6502_85 (void)
1202 /* Opcode $85: STA zp */
1203 {
1204     unsigned char ZPAddr;
1205     Cycles = 3;
1206     ZPAddr = MemReadByte (PC+1);
1207     MemWriteByte (ZPAddr, AC);
1208     PC += 2;
1209 }
1210
1211
1212
1213 static void OPC_6502_86 (void)
1214 /* Opcode $86: STX zp */
1215 {
1216     unsigned char ZPAddr;
1217     Cycles = 3;
1218     ZPAddr = MemReadByte (PC+1);
1219     MemWriteByte (ZPAddr, XR);
1220     PC += 2;
1221 }
1222
1223
1224
1225 static void OPC_6502_88 (void)
1226 /* Opcode $88: DEY */
1227 {
1228     Cycles = 2;
1229     --YR;
1230     TEST_ZF (YR);
1231     TEST_SF (YR);
1232     PC += 1;
1233 }
1234
1235
1236
1237 static void OPC_6502_8A (void)
1238 /* Opcode $8A: TXA */
1239 {
1240     Cycles = 2;
1241     AC = XR;
1242     TEST_ZF (AC);
1243     TEST_SF (AC);
1244     PC += 1;
1245 }
1246
1247
1248
1249 static void OPC_6502_8C (void)
1250 /* Opcode $8C: STY abs */
1251 {
1252     unsigned Addr;
1253     Cycles = 4;
1254     Addr = MemReadWord (PC+1);
1255     MemWriteByte (Addr, YR);
1256     PC += 3;
1257 }
1258
1259
1260
1261 static void OPC_6502_8D (void)
1262 /* Opcode $8D: STA abs */
1263 {
1264     unsigned Addr;
1265     Cycles = 4;
1266     Addr = MemReadWord (PC+1);
1267     MemWriteByte (Addr, AC);
1268     PC += 3;
1269 }
1270
1271
1272
1273 static void OPC_6502_8E (void)
1274 /* Opcode $8E: STX abs */
1275 {
1276     unsigned Addr;
1277     Cycles = 4;
1278     Addr = MemReadWord (PC+1);
1279     MemWriteByte (Addr, XR);
1280     PC += 3;
1281 }
1282
1283
1284
1285 static void OPC_6502_90 (void)
1286 /* Opcode $90: BCC */
1287 {
1288     BRANCH (!GET_CF ());
1289 }
1290
1291
1292
1293 static void OPC_6502_91 (void)
1294 /* Opcode $91: sta (zp),y */
1295 {
1296     unsigned char ZPAddr;
1297     unsigned Addr;
1298     Cycles = 6;
1299     ZPAddr = MemReadByte (PC+1);
1300     Addr   = MemReadZPWord (ZPAddr) + YR;
1301     MemWriteByte (Addr, AC);
1302     PC += 2;
1303 }
1304
1305
1306
1307 static void OPC_6502_94 (void)
1308 /* Opcode $94: STY zp,x */
1309 {
1310     unsigned char ZPAddr;
1311     Cycles = 4;
1312     ZPAddr = MemReadByte (PC+1) + XR;
1313     MemWriteByte (ZPAddr, YR);
1314     PC += 2;
1315 }
1316
1317
1318
1319 static void OPC_6502_95 (void)
1320 /* Opcode $95: STA zp,x */
1321 {
1322     unsigned char ZPAddr;
1323     Cycles = 4;
1324     ZPAddr = MemReadByte (PC+1) + XR;
1325     MemWriteByte (ZPAddr, AC);
1326     PC += 2;
1327 }
1328
1329
1330
1331 static void OPC_6502_96 (void)
1332 /* Opcode $96: stx zp,y */
1333 {
1334     unsigned char ZPAddr;
1335     Cycles = 4;
1336     ZPAddr = MemReadByte (PC+1) + YR;
1337     MemWriteByte (ZPAddr, XR);
1338     PC += 2;
1339 }
1340
1341
1342
1343 static void OPC_6502_98 (void)
1344 /* Opcode $98: TYA */
1345 {
1346     Cycles = 2;
1347     AC = YR;
1348     TEST_ZF (AC);
1349     TEST_SF (AC);
1350     PC += 1;
1351 }
1352
1353
1354
1355 static void OPC_6502_99 (void)
1356 /* Opcode $99: STA abs,y */
1357 {
1358     unsigned Addr;
1359     Cycles = 5;
1360     Addr   = MemReadWord (PC+1) + YR;
1361     MemWriteByte (Addr, AC);
1362     PC += 3;
1363 }
1364
1365
1366
1367 static void OPC_6502_9A (void)
1368 /* Opcode $9A: TXS */
1369 {
1370     Cycles = 2;
1371     SP = XR;
1372     PC += 1;
1373 }
1374
1375
1376
1377 static void OPC_6502_9D (void)
1378 /* Opcode $9D: STA abs,x */
1379 {
1380     unsigned Addr;
1381     Cycles = 5;
1382     Addr   = MemReadWord (PC+1) + XR;
1383     MemWriteByte (Addr, AC);
1384     PC += 3;
1385 }
1386
1387
1388
1389 static void OPC_6502_A0 (void)
1390 /* Opcode $A0: LDY #imm */
1391 {
1392     Cycles = 2;
1393     YR = MemReadByte (PC+1);
1394     TEST_ZF (YR);
1395     TEST_SF (YR);
1396     PC += 2;
1397 }
1398
1399
1400
1401 static void OPC_6502_A1 (void)
1402 /* Opcode $A1: LDA (zp,x) */
1403 {
1404     unsigned char ZPAddr;
1405     unsigned Addr;
1406     Cycles = 6;
1407     ZPAddr = MemReadByte (PC+1) + XR;
1408     Addr = MemReadZPWord (ZPAddr);
1409     AC = MemReadByte (Addr);
1410     TEST_ZF (AC);
1411     TEST_SF (AC);
1412     PC += 2;
1413 }
1414
1415
1416
1417 static void OPC_6502_A2 (void)
1418 /* Opcode $A2: LDX #imm */
1419 {
1420     Cycles = 2;
1421     XR = MemReadByte (PC+1);
1422     TEST_ZF (XR);
1423     TEST_SF (XR);
1424     PC += 2;
1425 }
1426
1427
1428
1429 static void OPC_6502_A4 (void)
1430 /* Opcode $A4: LDY zp */
1431 {
1432     unsigned char ZPAddr;
1433     Cycles = 3;
1434     ZPAddr = MemReadByte (PC+1);
1435     YR = MemReadByte (ZPAddr);
1436     TEST_ZF (YR);
1437     TEST_SF (YR);
1438     PC += 2;
1439 }
1440
1441
1442
1443 static void OPC_6502_A5 (void)
1444 /* Opcode $A5: LDA zp */
1445 {
1446     unsigned char ZPAddr;
1447     Cycles = 3;
1448     ZPAddr = MemReadByte (PC+1);
1449     AC = MemReadByte (ZPAddr);
1450     TEST_ZF (AC);
1451     TEST_SF (AC);
1452     PC += 2;
1453 }
1454
1455
1456
1457 static void OPC_6502_A6 (void)
1458 /* Opcode $A6: LDX zp */
1459 {
1460     unsigned char ZPAddr;
1461     Cycles = 3;
1462     ZPAddr = MemReadByte (PC+1);
1463     XR = MemReadByte (ZPAddr);
1464     TEST_ZF (XR);
1465     TEST_SF (XR);
1466     PC += 2;
1467 }
1468
1469
1470
1471 static void OPC_6502_A8 (void)
1472 /* Opcode $A8: TAY */
1473 {
1474     Cycles = 2;
1475     YR = AC;
1476     TEST_ZF (YR);
1477     TEST_SF (YR);
1478     PC += 1;
1479 }
1480
1481
1482
1483 static void OPC_6502_A9 (void)
1484 /* Opcode $A9: LDA #imm */
1485 {
1486     Cycles = 2;
1487     AC = MemReadByte (PC+1);
1488     TEST_ZF (AC);
1489     TEST_SF (AC);
1490     PC += 2;
1491 }
1492
1493
1494
1495 static void OPC_6502_AA (void)
1496 /* Opcode $AA: TAX */
1497 {
1498     Cycles = 2;
1499     XR = AC;
1500     TEST_ZF (XR);
1501     TEST_SF (XR);
1502     PC += 1;
1503 }
1504
1505
1506
1507 static void OPC_6502_AC (void)
1508 /* Opcode $AC: LDY abs */
1509 {
1510     unsigned Addr;
1511     Cycles = 4;
1512     Addr   = MemReadWord (PC+1);
1513     YR     = MemReadByte (Addr);
1514     TEST_ZF (YR);
1515     TEST_SF (YR);
1516     PC += 3;
1517 }
1518
1519
1520
1521 static void OPC_6502_AD (void)
1522 /* Opcode $AD: LDA abs */
1523 {
1524     unsigned Addr;
1525     Cycles = 4;
1526     Addr   = MemReadWord (PC+1);
1527     AC     = MemReadByte (Addr);
1528     TEST_ZF (AC);
1529     TEST_SF (AC);
1530     PC += 3;
1531 }
1532
1533
1534
1535 static void OPC_6502_AE (void)
1536 /* Opcode $AE: LDX abs */
1537 {
1538     unsigned Addr;
1539     Cycles = 4;
1540     Addr   = MemReadWord (PC+1);
1541     XR     = MemReadByte (Addr);
1542     TEST_ZF (XR);
1543     TEST_SF (XR);
1544     PC += 3;
1545 }
1546
1547
1548
1549 static void OPC_6502_B0 (void)
1550 /* Opcode $B0: BCS */
1551 {
1552     BRANCH (GET_CF ());
1553 }
1554
1555
1556
1557 static void OPC_6502_B1 (void)
1558 /* Opcode $B1: LDA (zp),y */
1559 {
1560     unsigned char ZPAddr;
1561     unsigned Addr;
1562     Cycles = 5;
1563     ZPAddr = MemReadByte (PC+1);
1564     Addr   = MemReadZPWord (ZPAddr);
1565     if (PAGE_CROSS (Addr, YR)) {
1566         ++Cycles;
1567     }
1568     AC = MemReadByte (Addr + YR);
1569     TEST_ZF (AC);
1570     TEST_SF (AC);
1571     PC += 2;
1572 }
1573
1574
1575
1576 static void OPC_6502_B4 (void)
1577 /* Opcode $B4: LDY zp,x */
1578 {
1579     unsigned char ZPAddr;
1580     Cycles = 4;
1581     ZPAddr = MemReadByte (PC+1) + XR;
1582     YR     = MemReadByte (ZPAddr);
1583     TEST_ZF (YR);
1584     TEST_SF (YR);
1585     PC += 2;
1586 }
1587
1588
1589
1590 static void OPC_6502_B5 (void)
1591 /* Opcode $B5: LDA zp,x */
1592 {
1593     unsigned char ZPAddr;
1594     Cycles = 4;
1595     ZPAddr = MemReadByte (PC+1) + XR;
1596     AC     = MemReadByte (ZPAddr);
1597     TEST_ZF (AC);
1598     TEST_SF (AC);
1599     PC += 2;
1600 }
1601
1602
1603
1604 static void OPC_6502_B6 (void)
1605 /* Opcode $B6: LDX zp,y */
1606 {
1607     unsigned char ZPAddr;
1608     Cycles = 4;
1609     ZPAddr = MemReadByte (PC+1) + YR;
1610     XR     = MemReadByte (ZPAddr);
1611     TEST_ZF (XR);
1612     TEST_SF (XR);
1613     PC += 2;
1614 }
1615
1616
1617
1618 static void OPC_6502_B8 (void)
1619 /* Opcode $B8: CLV */
1620 {
1621     Cycles = 2;
1622     SET_OF (0);
1623     PC += 1;
1624 }
1625
1626
1627
1628 static void OPC_6502_B9 (void)
1629 /* Opcode $B9: LDA abs,y */
1630 {
1631     unsigned Addr;
1632     Cycles = 4;
1633     Addr = MemReadWord (PC+1);
1634     if (PAGE_CROSS (Addr, YR)) {
1635         ++Cycles;
1636     }
1637     AC = MemReadByte (Addr + YR);
1638     TEST_ZF (AC);
1639     TEST_SF (AC);
1640     PC += 3;
1641 }
1642
1643
1644
1645 static void OPC_6502_BA (void)
1646 /* Opcode $BA: TSX */
1647 {
1648     Cycles = 2;
1649     XR = SP;
1650     TEST_ZF (XR);
1651     TEST_SF (XR);
1652     PC += 1;
1653 }
1654
1655
1656
1657 static void OPC_6502_BC (void)
1658 /* Opcode $BC: LDY abs,x */
1659 {
1660     unsigned Addr;
1661     Cycles = 4;
1662     Addr = MemReadWord (PC+1);
1663     if (PAGE_CROSS (Addr, XR)) {
1664         ++Cycles;
1665     }
1666     YR = MemReadByte (Addr + XR);
1667     TEST_ZF (YR);
1668     TEST_SF (YR);
1669     PC += 3;
1670 }
1671
1672
1673
1674 static void OPC_6502_BD (void)
1675 /* Opcode $BD: LDA abs,x */
1676 {
1677     unsigned Addr;
1678     Cycles = 4;
1679     Addr = MemReadWord (PC+1);
1680     if (PAGE_CROSS (Addr, XR)) {
1681         ++Cycles;
1682     }
1683     AC = MemReadByte (Addr + XR);
1684     TEST_ZF (AC);
1685     TEST_SF (AC);
1686     PC += 3;
1687 }
1688
1689
1690
1691 static void OPC_6502_BE (void)
1692 /* Opcode $BE: LDX abs,y */
1693 {
1694     unsigned Addr;
1695     Cycles = 4;
1696     Addr = MemReadWord (PC+1);
1697     if (PAGE_CROSS (Addr, YR)) {
1698         ++Cycles;
1699     }
1700     XR = MemReadByte (Addr + YR);
1701     TEST_ZF (XR);
1702     TEST_SF (XR);
1703     PC += 3;
1704 }
1705
1706
1707
1708 static void OPC_6502_C0 (void)
1709 /* Opcode $C0: CPY #imm */
1710 {
1711     Cycles = 2;
1712     CMP (YR, MemReadByte (PC+1));
1713     PC += 2;
1714 }
1715
1716
1717
1718 static void OPC_6502_C1 (void)
1719 /* Opcode $C1: CMP (zp,x) */
1720 {
1721     unsigned char ZPAddr;
1722     unsigned Addr;
1723     Cycles = 6;
1724     ZPAddr = MemReadByte (PC+1) + XR;
1725     Addr   = MemReadZPWord (ZPAddr);
1726     CMP (AC, MemReadByte (Addr));
1727     PC += 2;
1728 }
1729
1730
1731
1732 static void OPC_6502_C4 (void)
1733 /* Opcode $C4: CPY zp */
1734 {
1735     unsigned char ZPAddr;
1736     Cycles = 3;
1737     ZPAddr = MemReadByte (PC+1);
1738     CMP (YR, MemReadByte (ZPAddr));
1739     PC += 2;
1740 }
1741
1742
1743
1744 static void OPC_6502_C5 (void)
1745 /* Opcode $C5: CMP zp */
1746 {
1747     unsigned char ZPAddr;
1748     Cycles = 3;
1749     ZPAddr = MemReadByte (PC+1);
1750     CMP (AC, MemReadByte (ZPAddr));
1751     PC += 2;
1752 }
1753
1754
1755
1756 static void OPC_6502_C6 (void)
1757 /* Opcode $C6: DEC zp */
1758 {
1759     unsigned char ZPAddr;
1760     unsigned char Val;
1761     Cycles = 5;
1762     ZPAddr = MemReadByte (PC+1);
1763     Val    = MemReadByte (ZPAddr) - 1;
1764     MemWriteByte (ZPAddr, Val);
1765     TEST_ZF (Val);
1766     TEST_SF (Val);
1767     PC += 2;
1768 }
1769
1770
1771
1772 static void OPC_6502_C8 (void)
1773 /* Opcode $C8: INY */
1774 {
1775     Cycles = 2;
1776     ++YR;
1777     TEST_ZF (YR);
1778     TEST_SF (YR);
1779     PC += 1;
1780 }
1781
1782
1783
1784 static void OPC_6502_C9 (void)
1785 /* Opcode $C9: CMP #imm */
1786 {
1787     Cycles = 2;
1788     CMP (AC, MemReadByte (PC+1));
1789     PC += 2;
1790 }
1791
1792
1793
1794 static void OPC_6502_CA (void)
1795 /* Opcode $CA: DEX */
1796 {
1797     Cycles = 2;
1798     --XR;
1799     TEST_ZF (XR);
1800     TEST_SF (XR);
1801     PC += 1;
1802 }
1803
1804
1805
1806 static void OPC_6502_CC (void)
1807 /* Opcode $CC: CPY abs */
1808 {
1809     unsigned Addr;
1810     Cycles = 4;
1811     Addr   = MemReadWord (PC+1);
1812     CMP (YR, MemReadByte (Addr));
1813     PC += 3;
1814 }
1815
1816
1817
1818 static void OPC_6502_CD (void)
1819 /* Opcode $CD: CMP abs */
1820 {
1821     unsigned Addr;
1822     Cycles = 4;
1823     Addr   = MemReadWord (PC+1);
1824     CMP (AC, MemReadByte (Addr));
1825     PC += 3;
1826 }
1827
1828
1829
1830 static void OPC_6502_CE (void)
1831 /* Opcode $CE: DEC abs */
1832 {
1833     unsigned Addr;
1834     unsigned char Val;
1835     Cycles = 6;
1836     Addr = MemReadWord (PC+1);
1837     Val  = MemReadByte (Addr) - 1;
1838     MemWriteByte (Addr, Val);
1839     TEST_ZF (Val);
1840     TEST_SF (Val);
1841     PC += 3;
1842 }
1843
1844
1845
1846 static void OPC_6502_D0 (void)
1847 /* Opcode $D0: BNE */
1848 {
1849     BRANCH (!GET_ZF ());
1850 }
1851
1852
1853
1854 static void OPC_6502_D1 (void)
1855 /* Opcode $D1: CMP (zp),y */
1856 {
1857     unsigned ZPAddr;
1858     unsigned Addr;
1859     Cycles = 5;
1860     ZPAddr = MemReadByte (PC+1);
1861     Addr   = MemReadWord (ZPAddr);
1862     if (PAGE_CROSS (Addr, YR)) {
1863         ++Cycles;
1864     }
1865     CMP (AC, MemReadByte (Addr + YR));
1866     PC += 2;
1867 }
1868
1869
1870
1871 static void OPC_6502_D5 (void)
1872 /* Opcode $D5: CMP zp,x */
1873 {
1874     unsigned char ZPAddr;
1875     Cycles = 4;
1876     ZPAddr = MemReadByte (PC+1) + XR;
1877     CMP (AC, MemReadByte (ZPAddr));
1878     PC += 2;
1879 }
1880
1881
1882
1883 static void OPC_6502_D6 (void)
1884 /* Opcode $D6: DEC zp,x */
1885 {
1886     unsigned char ZPAddr;
1887     unsigned char Val;
1888     Cycles = 6;
1889     ZPAddr = MemReadByte (PC+1) + XR;
1890     Val  = MemReadByte (ZPAddr) - 1;
1891     MemWriteByte (ZPAddr, Val);
1892     TEST_ZF (Val);
1893     TEST_SF (Val);
1894     PC += 2;
1895 }
1896
1897
1898
1899 static void OPC_6502_D8 (void)
1900 /* Opcode $D8: CLD */
1901 {
1902     Cycles = 2;
1903     SET_DF (0);
1904     PC += 1;
1905 }
1906
1907
1908
1909 static void OPC_6502_D9 (void)
1910 /* Opcode $D9: CMP abs,y */
1911 {
1912     unsigned Addr;
1913     Cycles = 4;
1914     Addr = MemReadWord (PC+1);
1915     if (PAGE_CROSS (Addr, YR)) {
1916         ++Cycles;
1917     }
1918     CMP (AC, MemReadByte (Addr + YR));
1919     PC += 3;
1920 }
1921
1922
1923
1924 static void OPC_6502_DD (void)
1925 /* Opcode $DD: CMP abs,x */
1926 {
1927     unsigned Addr;
1928     Cycles = 4;
1929     Addr = MemReadWord (PC+1);
1930     if (PAGE_CROSS (Addr, XR)) {
1931         ++Cycles;
1932     }
1933     CMP (AC, MemReadByte (Addr + XR));
1934     PC += 3;
1935 }
1936
1937
1938
1939 static void OPC_6502_DE (void)
1940 /* Opcode $DE: DEC abs,x */
1941 {
1942     unsigned Addr;
1943     unsigned char Val;
1944     Cycles = 7;
1945     Addr = MemReadWord (PC+1) + XR;
1946     Val  = MemReadByte (Addr) - 1;
1947     MemWriteByte (Addr, Val);
1948     TEST_ZF (Val);
1949     TEST_SF (Val);
1950     PC += 3;
1951 }
1952
1953
1954
1955 static void OPC_6502_E0 (void)
1956 /* Opcode $E0: CPX #imm */
1957 {
1958     Cycles = 2;
1959     CMP (XR, MemReadByte (PC+1));
1960     PC += 2;
1961 }
1962
1963
1964
1965 static void OPC_6502_E1 (void)
1966 /* Opcode $E1: SBC (zp,x) */
1967 {
1968     unsigned char ZPAddr;
1969     unsigned Addr;
1970     Cycles = 6;
1971     ZPAddr = MemReadByte (PC+1) + XR;
1972     Addr   = MemReadZPWord (ZPAddr);
1973     SBC (MemReadByte (Addr));
1974     PC += 2;
1975 }
1976
1977
1978
1979 static void OPC_6502_E4 (void)
1980 /* Opcode $E4: CPX zp */
1981 {
1982     unsigned char ZPAddr;
1983     Cycles = 3;
1984     ZPAddr = MemReadByte (PC+1);
1985     CMP (XR, MemReadByte (ZPAddr));
1986     PC += 2;
1987 }
1988
1989
1990
1991 static void OPC_6502_E5 (void)
1992 /* Opcode $E5: SBC zp */
1993 {
1994     unsigned char ZPAddr;
1995     Cycles = 3;
1996     ZPAddr = MemReadByte (PC+1);
1997     SBC (MemReadByte (ZPAddr));
1998     PC += 2;
1999 }
2000
2001
2002
2003 static void OPC_6502_E6 (void)
2004 /* Opcode $E6: INC zp */
2005 {
2006     unsigned char ZPAddr;
2007     unsigned char Val;
2008     Cycles = 5;
2009     ZPAddr = MemReadByte (PC+1);
2010     Val    = MemReadByte (ZPAddr) + 1;
2011     MemWriteByte (ZPAddr, Val);
2012     TEST_ZF (Val);
2013     TEST_SF (Val);
2014     PC += 2;
2015 }
2016
2017
2018
2019 static void OPC_6502_E8 (void)
2020 /* Opcode $E8: INX */
2021 {
2022     Cycles = 2;
2023     ++XR;
2024     TEST_ZF (XR);
2025     TEST_SF (XR);
2026     PC += 1;
2027 }
2028
2029
2030
2031 static void OPC_6502_E9 (void)
2032 /* Opcode $E9: SBC #imm */
2033 {
2034     Cycles = 2;
2035     SBC (MemReadByte (PC+1));
2036     PC += 2;
2037 }
2038
2039
2040
2041 static void OPC_6502_EA (void)
2042 /* Opcode $EA: NOP */
2043 {
2044     /* This one is easy... */
2045     Cycles = 2;
2046     PC += 1;
2047 }
2048
2049
2050
2051 static void OPC_6502_EC (void)
2052 /* Opcode $EC: CPX abs */
2053 {
2054     unsigned Addr;
2055     Cycles = 4;
2056     Addr   = MemReadWord (PC+1);
2057     CMP (XR, MemReadByte (Addr));
2058     PC += 3;
2059 }
2060
2061
2062
2063 static void OPC_6502_ED (void)
2064 /* Opcode $ED: SBC abs */
2065 {
2066     unsigned Addr;
2067     Cycles = 4;
2068     Addr   = MemReadWord (PC+1);
2069     SBC (MemReadByte (Addr));
2070     PC += 3;
2071 }
2072
2073
2074
2075 static void OPC_6502_EE (void)
2076 /* Opcode $EE: INC abs */
2077 {
2078     unsigned Addr;
2079     unsigned char Val;
2080     Cycles = 6;
2081     Addr = MemReadWord (PC+1);
2082     Val  = MemReadByte (Addr) + 1;
2083     MemWriteByte (Addr, Val);
2084     TEST_ZF (Val);
2085     TEST_SF (Val);
2086     PC += 3;
2087 }
2088
2089
2090
2091 static void OPC_6502_F0 (void)
2092 /* Opcode $F0: BEQ */
2093 {
2094     BRANCH (GET_ZF ());
2095 }
2096
2097
2098
2099 static void OPC_6502_F1 (void)
2100 /* Opcode $F1: SBC (zp),y */
2101 {
2102     unsigned char ZPAddr;
2103     unsigned Addr;
2104     Cycles = 5;
2105     ZPAddr = MemReadByte (PC+1);
2106     Addr   = MemReadZPWord (ZPAddr);
2107     if (PAGE_CROSS (Addr, YR)) {
2108         ++Cycles;
2109     }
2110     SBC (MemReadByte (Addr + YR));
2111     PC += 2;
2112 }
2113
2114
2115
2116 static void OPC_6502_F5 (void)
2117 /* Opcode $F5: SBC zp,x */
2118 {
2119     unsigned char ZPAddr;
2120     Cycles = 4;
2121     ZPAddr = MemReadByte (PC+1) + XR;
2122     SBC (MemReadByte (ZPAddr));
2123     PC += 2;
2124 }
2125
2126
2127
2128 static void OPC_6502_F6 (void)
2129 /* Opcode $F6: INC zp,x */
2130 {
2131     unsigned char ZPAddr;
2132     unsigned char Val;
2133     Cycles = 6;
2134     ZPAddr = MemReadByte (PC+1) + XR;
2135     Val  = MemReadByte (ZPAddr) + 1;
2136     MemWriteByte (ZPAddr, Val);
2137     TEST_ZF (Val);
2138     TEST_SF (Val);
2139     PC += 2;
2140 }
2141
2142
2143
2144 static void OPC_6502_F8 (void)
2145 /* Opcode $F8: SED */
2146 {
2147     SET_DF (1);
2148 }
2149
2150
2151
2152 static void OPC_6502_F9 (void)
2153 /* Opcode $F9: SBC abs,y */
2154 {
2155     unsigned Addr;
2156     Cycles = 4;
2157     Addr   = MemReadWord (PC+1);
2158     if (PAGE_CROSS (Addr, YR)) {
2159         ++Cycles;
2160     }
2161     SBC (MemReadByte (Addr + YR));
2162     PC += 3;
2163 }
2164
2165
2166
2167 static void OPC_6502_FD (void)
2168 /* Opcode $FD: SBC abs,x */
2169 {
2170     unsigned Addr;
2171     Cycles = 4;
2172     Addr   = MemReadWord (PC+1);
2173     if (PAGE_CROSS (Addr, XR)) {
2174         ++Cycles;
2175     }
2176     SBC (MemReadByte (Addr + XR));
2177     PC += 3;
2178 }
2179
2180
2181
2182 static void OPC_6502_FE (void)
2183 /* Opcode $FE: INC abs,x */
2184 {
2185     unsigned Addr;
2186     unsigned char Val;
2187     Cycles = 7;
2188     Addr = MemReadWord (PC+1) + XR;
2189     Val  = MemReadByte (Addr) + 1;
2190     MemWriteByte (Addr, Val);
2191     TEST_ZF (Val);
2192     TEST_SF (Val);
2193     PC += 3;
2194 }
2195
2196
2197
2198 /*****************************************************************************/
2199 /*                                   Data                                    */
2200 /*****************************************************************************/
2201
2202
2203
2204 /* Opcode handler table */
2205 typedef void (*OPCFunc) (void);
2206 static OPCFunc OPCTable[256] = {
2207     OPC_6502_00,
2208     OPC_6502_01,
2209     OPC_Illegal,
2210     OPC_Illegal,
2211     OPC_Illegal,
2212     OPC_6502_05,
2213     OPC_6502_06,
2214     OPC_Illegal,
2215     OPC_6502_08,
2216     OPC_6502_09,
2217     OPC_6502_0A,
2218     OPC_Illegal,
2219     OPC_Illegal,
2220     OPC_6502_0D,
2221     OPC_6502_0E,
2222     OPC_Illegal,
2223     OPC_6502_10,
2224     OPC_6502_11,
2225     OPC_Illegal,
2226     OPC_Illegal,
2227     OPC_Illegal,
2228     OPC_6502_15,
2229     OPC_6502_16,
2230     OPC_Illegal,
2231     OPC_6502_18,
2232     OPC_6502_19,
2233     OPC_Illegal,
2234     OPC_Illegal,
2235     OPC_Illegal,
2236     OPC_6502_1D,
2237     OPC_6502_1E,
2238     OPC_Illegal,
2239     OPC_6502_20,
2240     OPC_6502_21,
2241     OPC_Illegal,
2242     OPC_Illegal,
2243     OPC_6502_24,
2244     OPC_6502_25,
2245     OPC_6502_26,
2246     OPC_Illegal,
2247     OPC_6502_28,
2248     OPC_6502_29,
2249     OPC_6502_2A,
2250     OPC_Illegal,
2251     OPC_6502_2C,
2252     OPC_6502_2D,
2253     OPC_6502_2E,
2254     OPC_Illegal,
2255     OPC_6502_30,
2256     OPC_6502_31,
2257     OPC_Illegal,
2258     OPC_Illegal,
2259     OPC_Illegal,
2260     OPC_6502_35,
2261     OPC_6502_36,
2262     OPC_Illegal,
2263     OPC_6502_38,
2264     OPC_6502_39,
2265     OPC_Illegal,
2266     OPC_Illegal,
2267     OPC_Illegal,
2268     OPC_6502_3D,
2269     OPC_6502_3E,
2270     OPC_Illegal,
2271     OPC_6502_40,
2272     OPC_6502_41,
2273     OPC_Illegal,
2274     OPC_Illegal,
2275     OPC_Illegal,
2276     OPC_6502_45,
2277     OPC_6502_46,
2278     OPC_Illegal,
2279     OPC_6502_48,
2280     OPC_6502_49,
2281     OPC_6502_4A,
2282     OPC_Illegal,
2283     OPC_6502_4C,
2284     OPC_6502_4D,
2285     OPC_6502_4E,
2286     OPC_Illegal,
2287     OPC_6502_50,
2288     OPC_6502_51,
2289     OPC_Illegal,
2290     OPC_Illegal,
2291     OPC_Illegal,
2292     OPC_6502_55,
2293     OPC_6502_56,
2294     OPC_Illegal,
2295     OPC_6502_58,
2296     OPC_6502_59,
2297     OPC_Illegal,
2298     OPC_Illegal,
2299     OPC_Illegal,
2300     OPC_6502_5D,
2301     OPC_6502_5E,
2302     OPC_Illegal,
2303     OPC_6502_60,
2304     OPC_6502_61,
2305     OPC_Illegal,
2306     OPC_Illegal,
2307     OPC_Illegal,
2308     OPC_6502_65,
2309     OPC_6502_66,
2310     OPC_Illegal,
2311     OPC_6502_68,
2312     OPC_6502_69,
2313     OPC_6502_6A,
2314     OPC_Illegal,
2315     OPC_6502_6C,
2316     OPC_6502_6D,
2317     OPC_6502_6E,
2318     OPC_Illegal,
2319     OPC_6502_70,
2320     OPC_6502_71,
2321     OPC_Illegal,
2322     OPC_Illegal,
2323     OPC_Illegal,
2324     OPC_6502_75,
2325     OPC_6502_76,
2326     OPC_Illegal,
2327     OPC_6502_78,
2328     OPC_6502_79,
2329     OPC_Illegal,
2330     OPC_Illegal,
2331     OPC_Illegal,
2332     OPC_6502_7D,
2333     OPC_6502_7E,
2334     OPC_Illegal,
2335     OPC_Illegal,
2336     OPC_6502_81,
2337     OPC_Illegal,
2338     OPC_Illegal,
2339     OPC_6502_84,
2340     OPC_6502_85,
2341     OPC_6502_86,
2342     OPC_Illegal,
2343     OPC_6502_88,
2344     OPC_Illegal,
2345     OPC_6502_8A,
2346     OPC_Illegal,
2347     OPC_6502_8C,
2348     OPC_6502_8D,
2349     OPC_6502_8E,
2350     OPC_Illegal,
2351     OPC_6502_90,
2352     OPC_6502_91,
2353     OPC_Illegal,
2354     OPC_Illegal,
2355     OPC_6502_94,
2356     OPC_6502_95,
2357     OPC_6502_96,
2358     OPC_Illegal,
2359     OPC_6502_98,
2360     OPC_6502_99,
2361     OPC_6502_9A,
2362     OPC_Illegal,
2363     OPC_Illegal,
2364     OPC_6502_9D,
2365     OPC_Illegal,
2366     OPC_Illegal,
2367     OPC_6502_A0,
2368     OPC_6502_A1,
2369     OPC_6502_A2,
2370     OPC_Illegal,
2371     OPC_6502_A4,
2372     OPC_6502_A5,
2373     OPC_6502_A6,
2374     OPC_Illegal,
2375     OPC_6502_A8,
2376     OPC_6502_A9,
2377     OPC_6502_AA,
2378     OPC_Illegal,
2379     OPC_6502_AC,
2380     OPC_6502_AD,
2381     OPC_6502_AE,
2382     OPC_Illegal,
2383     OPC_6502_B0,
2384     OPC_6502_B1,
2385     OPC_Illegal,
2386     OPC_Illegal,
2387     OPC_6502_B4,
2388     OPC_6502_B5,
2389     OPC_6502_B6,
2390     OPC_Illegal,
2391     OPC_6502_B8,
2392     OPC_6502_B9,
2393     OPC_6502_BA,
2394     OPC_Illegal,
2395     OPC_6502_BC,
2396     OPC_6502_BD,
2397     OPC_6502_BE,
2398     OPC_Illegal,
2399     OPC_6502_C0,
2400     OPC_6502_C1,
2401     OPC_Illegal,
2402     OPC_Illegal,
2403     OPC_6502_C4,
2404     OPC_6502_C5,
2405     OPC_6502_C6,
2406     OPC_Illegal,
2407     OPC_6502_C8,
2408     OPC_6502_C9,
2409     OPC_6502_CA,
2410     OPC_Illegal,
2411     OPC_6502_CC,
2412     OPC_6502_CD,
2413     OPC_6502_CE,
2414     OPC_Illegal,
2415     OPC_6502_D0,
2416     OPC_6502_D1,
2417     OPC_Illegal,
2418     OPC_Illegal,
2419     OPC_Illegal,
2420     OPC_6502_D5,
2421     OPC_6502_D6,
2422     OPC_Illegal,
2423     OPC_6502_D8,
2424     OPC_6502_D9,
2425     OPC_Illegal,
2426     OPC_Illegal,
2427     OPC_Illegal,
2428     OPC_6502_DD,
2429     OPC_6502_DE,
2430     OPC_Illegal,
2431     OPC_6502_E0,
2432     OPC_6502_E1,
2433     OPC_Illegal,
2434     OPC_Illegal,
2435     OPC_6502_E4,
2436     OPC_6502_E5,
2437     OPC_6502_E6,
2438     OPC_Illegal,
2439     OPC_6502_E8,
2440     OPC_6502_E9,
2441     OPC_6502_EA,
2442     OPC_Illegal,
2443     OPC_6502_EC,
2444     OPC_6502_ED,
2445     OPC_6502_EE,
2446     OPC_Illegal,
2447     OPC_6502_F0,
2448     OPC_6502_F1,
2449     OPC_Illegal,
2450     OPC_Illegal,
2451     OPC_Illegal,
2452     OPC_6502_F5,
2453     OPC_6502_F6,
2454     OPC_Illegal,
2455     OPC_6502_F8,
2456     OPC_6502_F9,
2457     OPC_Illegal,
2458     OPC_Illegal,
2459     OPC_Illegal,
2460     OPC_6502_FD,
2461     OPC_6502_FE,
2462     OPC_Illegal,
2463 };
2464
2465
2466
2467 /*****************************************************************************/
2468 /*                                   Code                                    */
2469 /*****************************************************************************/
2470
2471
2472
2473 void RunCPU (void)
2474 /* Run the CPU */
2475 {
2476     while (!CPUHalted) {
2477
2478         /* Get the next opcode */
2479         unsigned char B = 0x00;
2480
2481         /* Execute it */
2482         OPCTable[B] ();
2483
2484         /* Count cycles */
2485         TotalCycles += Cycles;
2486     }
2487 }
2488
2489
2490