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