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