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