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