2 * acpu.c - another 6502 CPU emulator
4 * Copyright (C) 2007-2008 Piotr Fusik
6 * This file is part of ASAP (Another Slight Atari Player),
7 * see http://asap.sourceforge.net
9 * ASAP is free software; you can redistribute it and/or modify it
10 * under the terms of the GNU General Public License as published
11 * by the Free Software Foundation; either version 2 of the License,
12 * or (at your option) any later version.
14 * ASAP is distributed in the hope that it will be useful,
15 * but WITHOUT ANY WARRANTY; without even the implied warranty
16 * of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.
17 * See the GNU General Public License for more details.
19 * You should have received a copy of the GNU General Public License
20 * along with ASAP; if not, write to the Free Software Foundation, Inc.,
21 * 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA
24 #include "asap_internal.h"
26 CONST_LOOKUP(int, opcode_cycles
) =
28 /* 0 1 2 3 4 5 6 7 8 9 A B C D E F */
29 7, 6, 2, 8, 3, 3, 5, 5, 3, 2, 2, 2, 4, 4, 6, 6, /* 0x */
30 2, 5, 2, 8, 4, 4, 6, 6, 2, 4, 2, 7, 4, 4, 7, 7, /* 1x */
31 6, 6, 2, 8, 3, 3, 5, 5, 4, 2, 2, 2, 4, 4, 6, 6, /* 2x */
32 2, 5, 2, 8, 4, 4, 6, 6, 2, 4, 2, 7, 4, 4, 7, 7, /* 3x */
33 6, 6, 2, 8, 3, 3, 5, 5, 3, 2, 2, 2, 3, 4, 6, 6, /* 4x */
34 2, 5, 2, 8, 4, 4, 6, 6, 2, 4, 2, 7, 4, 4, 7, 7, /* 5x */
35 6, 6, 2, 8, 3, 3, 5, 5, 4, 2, 2, 2, 5, 4, 6, 6, /* 6x */
36 2, 5, 2, 8, 4, 4, 6, 6, 2, 4, 2, 7, 4, 4, 7, 7, /* 7x */
37 2, 6, 2, 6, 3, 3, 3, 3, 2, 2, 2, 2, 4, 4, 4, 4, /* 8x */
38 2, 6, 2, 6, 4, 4, 4, 4, 2, 5, 2, 5, 5, 5, 5, 5, /* 9x */
39 2, 6, 2, 6, 3, 3, 3, 3, 2, 2, 2, 2, 4, 4, 4, 4, /* Ax */
40 2, 5, 2, 5, 4, 4, 4, 4, 2, 4, 2, 4, 4, 4, 4, 4, /* Bx */
41 2, 6, 2, 8, 3, 3, 5, 5, 2, 2, 2, 2, 4, 4, 6, 6, /* Cx */
42 2, 5, 2, 8, 4, 4, 6, 6, 2, 4, 2, 7, 4, 4, 7, 7, /* Dx */
43 2, 6, 2, 8, 3, 3, 5, 5, 2, 2, 2, 2, 4, 4, 6, 6, /* Ex */
44 2, 5, 2, 8, 4, 4, 6, 6, 2, 4, 2, 7, 4, 4, 7, 7 /* Fx */
48 if ((vdi & D_FLAG) == 0) { \
50 int tmp = a + data + c; \
52 vdi &= D_FLAG | I_FLAG; \
53 if (((a ^ data) & 0x80) == 0 && ((data ^ tmp) & 0x80) != 0) \
55 nz = a = tmp & 0xff; \
59 int tmp = (a & 0x0f) + (data & 0x0f) + c; \
61 tmp = (tmp - 10) | 0x10; \
62 tmp += (a & 0xf0) + (data & 0xf0); \
63 nz = ((tmp & 0x80) << 1) + ((a + data + c) & 0xff); \
64 vdi &= D_FLAG | I_FLAG; \
65 if (((a ^ data) & 0x80) == 0 && ((data ^ tmp) & 0x80) != 0) \
69 c = (tmp > 0xff) ? 1 : 0; \
74 if ((vdi & D_FLAG) == 0) { \
76 int tmp = a - data - 1 + c; \
77 c = (tmp >= 0) ? 1 : 0; \
78 vdi &= D_FLAG | I_FLAG; \
79 if (((a ^ tmp) & 0x80) != 0 && ((a ^ data) & 0x80) != 0) \
81 nz = a = tmp & 0xff; \
85 int tmp = a - data - 1 + c; \
86 int al = (a & 0x0f) - (data & 0x0f) - 1 + c; \
87 int ah = (a >> 4) - (data >> 4); \
88 if ((al & 0x10) != 0) { \
92 if ((ah & 0x10) != 0) \
94 c = tmp >= 0 ? 1 : 0; \
95 vdi &= D_FLAG | I_FLAG; \
96 if (((a ^ tmp) & 0x80) != 0 && ((a ^ data) & 0x80) != 0) \
99 a = ((ah & 0xf) << 4) + (al & 0x0f); \
102 #define zGetByte(addr) dGetByte((addr) & 0xff)
104 #define PEEK dGetByte(pc)
105 #define FETCH dGetByte(pc++)
107 #define ABSOLUTE addr = FETCH; addr += FETCH << 8
108 #define ABSOLUTE_X addr = FETCH; addr = (addr + (FETCH << 8) + x) & 0xffff
109 #define ABSOLUTE_Y addr = FETCH; addr = (addr + (FETCH << 8) + y) & 0xffff
110 #define ZPAGE addr = FETCH
111 #define ZPAGE_X addr = (FETCH + x) & 0xff
112 #define ZPAGE_Y addr = (FETCH + y) & 0xff
113 #define INDIRECT_X addr = (FETCH + x) & 0xff; addr = dGetByte(addr) + (zGetByte(addr + 1) << 8)
114 #define INDIRECT_Y addr = FETCH; addr = (dGetByte(addr) + (zGetByte(addr + 1) << 8) + y) & 0xffff
115 #define NCYCLES_X if ((addr & 0xff) < x) AST cycle++
116 #define NCYCLES_Y if ((addr & 0xff) < y) AST cycle++
118 #define PL(dest) s = (s + 1) & 0xff; dest = dGetByte(0x0100 + s)
119 #define PLP PL(vdi); nz = ((vdi & 0x80) << 1) + (~vdi & Z_FLAG); c = vdi & 1; vdi &= V_FLAG | D_FLAG | I_FLAG
120 #define PH(data) dPutByte(0x0100 + s, data); s = (s - 1) & 0xff
121 #define PHW(data) PH((data) >> 8); PH(data)
122 #define PHP(bflag) PH(((nz | (nz >> 1)) & 0x80) + vdi + ((nz & 0xff) == 0 ? Z_FLAG : 0) + c + bflag)
123 #define PHPB0 PHP(0x20) /* push flags with B flag clear (NMI, IRQ) */
124 #define PHPB1 PHP(0x30) /* push flags with B flag set (PHP, BRK) */
127 #define LDA nz = a = GetByte(addr)
128 #define LDA_ZP nz = a = dGetByte(addr)
129 #define LDX nz = x = GetByte(addr)
130 #define LDX_ZP nz = x = dGetByte(addr)
131 #define LDY nz = y = GetByte(addr)
132 #define LDY_ZP nz = y = dGetByte(addr)
133 #define LAX nz = x = a = GetByte(addr)
134 #define LAX_ZP nz = x = a = dGetByte(addr)
135 #define STA PutByte(addr, a)
136 #define STA_ZP dPutByte(addr, a)
137 #define STX PutByte(addr, x)
138 #define STX_ZP dPutByte(addr, x)
139 #define STY PutByte(addr, y)
140 #define STY_ZP dPutByte(addr, y)
141 #define SAX data = a & x; PutByte(addr, data)
142 #define SAX_ZP data = a & x; dPutByte(addr, data)
143 #define CMP nz = GetByte(addr); c = (a >= nz) ? 1 : 0; nz = (a - nz) & 0xff
144 #define CMP_ZP nz = dGetByte(addr); c = (a >= nz) ? 1 : 0; nz = (a - nz) & 0xff
145 #define CPX nz = GetByte(addr); c = (x >= nz) ? 1 : 0; nz = (x - nz) & 0xff
146 #define CPX_ZP nz = dGetByte(addr); c = (x >= nz) ? 1 : 0; nz = (x - nz) & 0xff
147 #define CPY nz = GetByte(addr); c = (y >= nz) ? 1 : 0; nz = (y - nz) & 0xff
148 #define CPY_ZP nz = dGetByte(addr); c = (y >= nz) ? 1 : 0; nz = (y - nz) & 0xff
149 #define AND nz = a &= GetByte(addr)
150 #define AND_ZP nz = a &= dGetByte(addr)
151 #define ORA nz = a |= GetByte(addr)
152 #define ORA_ZP nz = a |= dGetByte(addr)
153 #define EOR nz = a ^= GetByte(addr)
154 #define EOR_ZP nz = a ^= dGetByte(addr)
155 #define ADC data = GetByte(addr); DO_ADC
156 #define ADC_ZP data = dGetByte(addr); DO_ADC
157 #define SBC data = GetByte(addr); DO_SBC
158 #define SBC_ZP data = dGetByte(addr); DO_SBC
160 #define ASL RMW_GetByte(nz, addr); c = nz >> 7; nz = (nz << 1) & 0xff; PutByte(addr, nz)
161 #define ASL_ZP nz = dGetByte(addr); c = nz >> 7; nz = (nz << 1) & 0xff; dPutByte(addr, nz)
162 #define ROL RMW_GetByte(nz, addr); nz = (nz << 1) + c; c = nz >> 8; nz &= 0xff; PutByte(addr, nz)
163 #define ROL_ZP nz = dGetByte(addr); nz = (nz << 1) + c; c = nz >> 8; nz &= 0xff; dPutByte(addr, nz)
164 #define LSR RMW_GetByte(nz, addr); c = nz & 1; nz >>= 1; PutByte(addr, nz)
165 #define LSR_ZP nz = dGetByte(addr); c = nz & 1; nz >>= 1; dPutByte(addr, nz)
167 RMW_GetByte(nz, addr); \
174 nz = (nz >> 1) + 128; \
178 nz = dGetByte(addr); \
185 nz = (nz >> 1) + 128; \
188 #define DEC RMW_GetByte(nz, addr); nz = (nz - 1) & 0xff; PutByte(addr, nz)
189 #define DEC_ZP nz = dGetByte(addr); nz = (nz - 1) & 0xff; dPutByte(addr, nz)
190 #define INC RMW_GetByte(nz, addr); nz = (nz + 1) & 0xff; PutByte(addr, nz)
191 #define INC_ZP nz = dGetByte(addr); nz = (nz + 1) & 0xff; dPutByte(addr, nz)
193 #define ASO ASL; nz = a |= nz
194 #define ASO_ZP ASL_ZP; nz = a |= nz
195 #define RLA ROL; nz = a &= nz
196 #define RLA_ZP ROL_ZP; nz = a &= nz
197 #define LSE LSR; nz = a ^= nz
198 #define LSE_ZP LSR_ZP; nz = a ^= nz
199 #define RRA ROR; data = nz; DO_ADC
200 #define RRA_ZP ROR_ZP; data = nz; DO_ADC
201 #define DCM DEC; c = (a >= nz) ? 1 : 0; nz = (a - nz) & 0xff
202 #define DCM_ZP DEC_ZP; c = (a >= nz) ? 1 : 0; nz = (a - nz) & 0xff
203 #define INS INC; data = nz; DO_SBC
204 #define INS_ZP INC_ZP; data = nz; DO_SBC
206 #define BRANCH(cond) \
208 addr = SBYTE(FETCH); \
210 if (((addr ^ pc) & 0xff00) != 0) \
220 if ((vdi & I_FLAG) == 0 && AST irqst != 0xff) { \
224 pc = dGetWord(0xfffe); \
228 ASAP_FUNC
void Cpu_RunScanlines(ASAP_State PTR ast
, int scanlines
)
238 int next_event_cycle
;
248 AST next_scanline_cycle
= 114;
249 next_event_cycle
= 114;
250 cycle_limit
= 114 * scanlines
;
251 if (next_event_cycle
> AST timer1_cycle
)
252 next_event_cycle
= AST timer1_cycle
;
253 if (next_event_cycle
> AST timer2_cycle
)
254 next_event_cycle
= AST timer2_cycle
;
255 if (next_event_cycle
> AST timer4_cycle
)
256 next_event_cycle
= AST timer4_cycle
;
257 AST nearest_event_cycle
= next_event_cycle
;
263 if (cycle
>= AST nearest_event_cycle
) {
264 if (cycle
>= AST next_scanline_cycle
) {
265 if (++AST scanline_number
== 312)
266 AST scanline_number
= 0;
267 AST cycle
= cycle
+= 9;
268 AST next_scanline_cycle
+= 114;
269 if (--scanlines
<= 0)
272 next_event_cycle
= AST next_scanline_cycle
;
273 #define CHECK_TIMER_IRQ(ch) \
274 if (cycle >= AST timer##ch##_cycle) { \
276 AST timer##ch##_cycle = NEVER; \
278 else if (next_event_cycle > AST timer##ch##_cycle) \
279 next_event_cycle = AST timer##ch##_cycle;
283 AST nearest_event_cycle
= next_event_cycle
;
288 print_cpu_state(as
, pc
, a
, x
, y
, s
, nz
, vdi
, c
);
291 AST cycle
+= opcode_cycles
[data
];
298 pc
= dGetWord(0xfffe);
300 case 0x01: /* ORA (ab,x) */
304 case 0x02: /* CIM [unofficial] */
316 AST scanline_number
= (AST scanline_number
+ scanlines
- 1) % 312;
318 AST cycle
= cycle_limit
;
320 case 0x03: /* ASO (ab,x) [unofficial] */
324 case 0x04: /* NOP ab [unofficial] */
327 case 0x14: /* NOP ab,x [unofficial] */
333 case 0x80: /* NOP #ab [unofficial] */
340 case 0x05: /* ORA ab */
344 case 0x06: /* ASL ab */
348 case 0x07: /* ASO ab [unofficial] */
355 case 0x09: /* ORA #ab */
360 nz
= a
= (a
<< 1) & 0xff;
362 case 0x0b: /* ANC #ab [unofficial] */
367 case 0x0c: /* NOP abcd [unofficial] */
370 case 0x0d: /* ORA abcd */
374 case 0x0e: /* ASL abcd */
378 case 0x0f: /* ASO abcd [unofficial] */
384 case 0x11: /* ORA (ab),y */
389 case 0x13: /* ASO (ab),y [unofficial] */
393 case 0x15: /* ORA ab,x */
397 case 0x16: /* ASL ab,x */
401 case 0x17: /* ASO ab,x [unofficial] */
408 case 0x19: /* ORA abcd,y */
413 case 0x1b: /* ASO abcd,y [unofficial] */
417 case 0x1c: /* NOP abcd,x [unofficial] */
423 if (FETCH
+ x
>= 0x100)
427 case 0x1d: /* ORA abcd,x */
432 case 0x1e: /* ASL abcd,x */
436 case 0x1f: /* ASO abcd,x [unofficial] */
440 case 0x20: /* JSR abcd */
443 pc
= addr
+ (PEEK
<< 8);
445 case 0x21: /* AND (ab,x) */
449 case 0x23: /* RLA (ab,x) [unofficial] */
453 case 0x24: /* BIT ab */
456 vdi
= (vdi
& (D_FLAG
| I_FLAG
)) + (nz
& V_FLAG
);
457 nz
= ((nz
& 0x80) << 1) + (nz
& a
);
459 case 0x25: /* AND ab */
463 case 0x26: /* ROL ab */
467 case 0x27: /* RLA ab [unofficial] */
475 case 0x29: /* AND #ab */
483 case 0x2c: /* BIT abcd */
486 vdi
= (vdi
& (D_FLAG
| I_FLAG
)) + (nz
& V_FLAG
);
487 nz
= ((nz
& 0x80) << 1) + (nz
& a
);
489 case 0x2d: /* AND abcd */
493 case 0x2e: /* ROL abcd */
497 case 0x2f: /* RLA abcd [unofficial] */
503 case 0x31: /* AND (ab),y */
508 case 0x33: /* RLA (ab),y [unofficial] */
512 case 0x35: /* AND ab,x */
516 case 0x36: /* ROL ab,x */
520 case 0x37: /* RLA ab,x [unofficial] */
527 case 0x39: /* AND abcd,y */
532 case 0x3b: /* RLA abcd,y [unofficial] */
536 case 0x3d: /* AND abcd,x */
541 case 0x3e: /* ROL abcd,x */
545 case 0x3f: /* RLA abcd,x [unofficial] */
556 case 0x41: /* EOR (ab,x) */
560 case 0x43: /* LSE (ab,x) [unofficial] */
564 case 0x45: /* EOR ab */
568 case 0x46: /* LSR ab */
572 case 0x47: /* LSE ab [unofficial] */
579 case 0x49: /* EOR #ab */
586 case 0x4b: /* ALR #ab [unofficial] */
591 case 0x4c: /* JMP abcd */
593 pc
= addr
+ (PEEK
<< 8);
595 case 0x4d: /* EOR abcd */
599 case 0x4e: /* LSR abcd */
603 case 0x4f: /* LSE abcd [unofficial] */
608 BRANCH((vdi
& V_FLAG
) == 0);
609 case 0x51: /* EOR (ab),y */
614 case 0x53: /* LSE (ab),y [unofficial] */
618 case 0x55: /* EOR ab,x */
622 case 0x56: /* LSR ab,x */
626 case 0x57: /* LSE ab,x [unofficial] */
631 vdi
&= V_FLAG
| D_FLAG
;
634 case 0x59: /* EOR abcd,y */
639 case 0x5b: /* LSE abcd,y [unofficial] */
643 case 0x5d: /* EOR abcd,x */
648 case 0x5e: /* LSR abcd,x */
652 case 0x5f: /* LSE abcd,x [unofficial] */
659 pc
+= (addr
<< 8) + 1;
661 case 0x61: /* ADC (ab,x) */
665 case 0x63: /* RRA (ab,x) [unofficial] */
669 case 0x65: /* ADC ab */
673 case 0x66: /* ROR ab */
677 case 0x67: /* RRA ab [unofficial] */
685 case 0x69: /* ADC #ab */
690 nz
= (c
<< 7) + (a
>> 1);
694 case 0x6b: /* ARR #ab [unofficial] */
696 nz
= a
= (data
>> 1) + (c
<< 7);
697 vdi
= (vdi
& (D_FLAG
| I_FLAG
)) + ((a
^ data
) & V_FLAG
);
698 if ((vdi
& D_FLAG
) == 0)
701 if ((data
& 0xf) + (data
& 1) > 5)
702 a
= (a
& 0xf0) + ((a
+ 6) & 0xf);
703 if (data
+ (data
& 0x10) >= 0x60) {
712 case 0x6c: /* JMP (abcd) */
714 if ((addr
& 0xff) == 0xff)
715 pc
= (dGetByte(addr
- 0xff) << 8) + dGetByte(addr
);
719 case 0x6d: /* ADC abcd */
723 case 0x6e: /* ROR abcd */
727 case 0x6f: /* RRA abcd [unofficial] */
732 BRANCH((vdi
& V_FLAG
) != 0);
733 case 0x71: /* ADC (ab),y */
738 case 0x73: /* RRA (ab),y [unofficial] */
742 case 0x75: /* ADC ab,x */
746 case 0x76: /* ROR ab,x */
750 case 0x77: /* RRA ab,x [unofficial] */
757 case 0x79: /* ADC abcd,y */
762 case 0x7b: /* RRA abcd,y [unofficial] */
766 case 0x7d: /* ADC abcd,x */
771 case 0x7e: /* ROR abcd,x */
775 case 0x7f: /* RRA abcd,x [unofficial] */
779 case 0x81: /* STA (ab,x) */
783 case 0x83: /* SAX (ab,x) [unofficial] */
787 case 0x84: /* STY ab */
791 case 0x85: /* STA ab */
795 case 0x86: /* STX ab */
799 case 0x87: /* SAX ab [unofficial] */
804 nz
= y
= (y
- 1) & 0xff;
809 case 0x8b: /* ANE #ab [unofficial] */
815 case 0x8c: /* STY abcd */
819 case 0x8d: /* STA abcd */
823 case 0x8e: /* STX abcd */
827 case 0x8f: /* SAX abcd [unofficial] */
833 case 0x91: /* STA (ab),y */
837 case 0x93: /* SHA (ab),y [unofficial, unstable] */
839 data
= zGetByte(addr
+ 1);
840 addr
= (dGetByte(addr
) + (data
<< 8) + y
) & 0xffff;
841 data
= a
& x
& (data
+ 1);
844 case 0x94: /* STY ab,x */
848 case 0x95: /* STA ab,x */
852 case 0x96: /* STX ab,y */
856 case 0x97: /* SAX ab,y [unofficial] */
863 case 0x99: /* STA abcd,y */
870 case 0x9b: /* SHS abcd,y [unofficial, unstable] */
871 /* S seems to be stable, only memory values vary */
874 addr
= (addr
+ (data
<< 8) + y
) & 0xffff;
876 data
= s
& (data
+ 1);
879 case 0x9c: /* SHY abcd,x [unofficial] */
882 addr
= (addr
+ (data
<< 8) + x
) & 0xffff;
883 data
= y
& (data
+ 1);
886 case 0x9d: /* STA abcd,x */
890 case 0x9e: /* SHX abcd,y [unofficial] */
893 addr
= (addr
+ (data
<< 8) + y
) & 0xffff;
894 data
= x
& (data
+ 1);
897 case 0x9f: /* SHA abcd,y [unofficial, unstable] */
900 addr
= (addr
+ (data
<< 8) + y
) & 0xffff;
901 data
= a
& x
& (data
+ 1);
904 case 0xa0: /* LDY #ab */
907 case 0xa1: /* LDA (ab,x) */
911 case 0xa2: /* LDX #ab */
914 case 0xa3: /* LAX (ab,x) [unofficial] */
918 case 0xa4: /* LDY ab */
922 case 0xa5: /* LDA ab */
926 case 0xa6: /* LDX ab */
930 case 0xa7: /* LAX ab [unofficial] */
937 case 0xa9: /* LDA #ab */
943 case 0xab: /* ANX #ab [unofficial] */
946 case 0xac: /* LDY abcd */
950 case 0xad: /* LDA abcd */
954 case 0xae: /* LDX abcd */
958 case 0xaf: /* LAX abcd [unofficial] */
964 case 0xb1: /* LDA (ab),y */
969 case 0xb3: /* LAX (ab),y [unofficial] */
974 case 0xb4: /* LDY ab,x */
978 case 0xb5: /* LDA ab,x */
982 case 0xb6: /* LDX ab,y */
986 case 0xb7: /* LAX ab,y [unofficial] */
991 vdi
&= D_FLAG
| I_FLAG
;
993 case 0xb9: /* LDA abcd,y */
1001 case 0xbb: /* LAS abcd,y [unofficial] */
1004 nz
= x
= a
= s
&= GetByte(addr
);
1006 case 0xbc: /* LDY abcd,x */
1011 case 0xbd: /* LDA abcd,x */
1016 case 0xbe: /* LDX abcd,y */
1021 case 0xbf: /* LAX abcd,y [unofficial] */
1026 case 0xc0: /* CPY #ab */
1028 c
= (y
>= nz
) ? 1 : 0;
1029 nz
= (y
- nz
) & 0xff;
1031 case 0xc1: /* CMP (ab,x) */
1035 case 0xc3: /* DCM (ab,x) [unofficial] */
1039 case 0xc4: /* CPY ab */
1043 case 0xc5: /* CMP ab */
1047 case 0xc6: /* DEC ab */
1051 case 0xc7: /* DCM ab [unofficial] */
1055 case 0xc8: /* INY */
1056 nz
= y
= (y
+ 1) & 0xff;
1058 case 0xc9: /* CMP #ab */
1060 c
= (a
>= nz
) ? 1 : 0;
1061 nz
= (a
- nz
) & 0xff;
1063 case 0xca: /* DEX */
1064 nz
= x
= (x
- 1) & 0xff;
1066 case 0xcb: /* SBX #ab [unofficial] */
1069 c
= (x
>= nz
) ? 1 : 0;
1070 nz
= x
= (x
- nz
) & 0xff;
1072 case 0xcc: /* CPY abcd */
1076 case 0xcd: /* CMP abcd */
1080 case 0xce: /* DEC abcd */
1084 case 0xcf: /* DCM abcd [unofficial] */
1088 case 0xd0: /* BNE */
1089 BRANCH((nz
& 0xff) != 0);
1090 case 0xd1: /* CMP (ab),y */
1095 case 0xd3: /* DCM (ab),y [unofficial] */
1099 case 0xd5: /* CMP ab,x */
1103 case 0xd6: /* DEC ab,x */
1107 case 0xd7: /* DCM ab,x [unofficial] */
1111 case 0xd8: /* CLD */
1112 vdi
&= V_FLAG
| I_FLAG
;
1114 case 0xd9: /* CMP abcd,y */
1119 case 0xdb: /* DCM abcd,y [unofficial] */
1123 case 0xdd: /* CMP abcd,x */
1128 case 0xde: /* DEC abcd,x */
1132 case 0xdf: /* DCM abcd,x [unofficial] */
1136 case 0xe0: /* CPX #ab */
1138 c
= (x
>= nz
) ? 1 : 0;
1139 nz
= (x
- nz
) & 0xff;
1141 case 0xe1: /* SBC (ab,x) */
1145 case 0xe3: /* INS (ab,x) [unofficial] */
1149 case 0xe4: /* CPX ab */
1153 case 0xe5: /* SBC ab */
1157 case 0xe6: /* INC ab */
1161 case 0xe7: /* INS ab [unofficial] */
1165 case 0xe8: /* INX */
1166 nz
= x
= (x
+ 1) & 0xff;
1168 case 0xe9: /* SBC #ab */
1169 case 0xeb: /* SBC #ab [unofficial] */
1173 case 0xea: /* NOP */
1174 case 0x1a: /* NOP [unofficial] */
1181 case 0xec: /* CPX abcd */
1185 case 0xed: /* SBC abcd */
1189 case 0xee: /* INC abcd */
1193 case 0xef: /* INS abcd [unofficial] */
1197 case 0xf0: /* BEQ */
1198 BRANCH((nz
& 0xff) == 0);
1199 case 0xf1: /* SBC (ab),y */
1204 case 0xf3: /* INS (ab),y [unofficial] */
1208 case 0xf5: /* SBC ab,x */
1212 case 0xf6: /* INC ab,x */
1216 case 0xf7: /* INS ab,x [unofficial] */
1220 case 0xf8: /* SED */
1223 case 0xf9: /* SBC abcd,y */
1228 case 0xfb: /* INS abcd,y [unofficial] */
1232 case 0xfd: /* SBC abcd,x */
1237 case 0xfe: /* INC abcd,x */
1241 case 0xff: /* INS abcd,x */
1255 AST cycle
-= cycle_limit
;
1256 if (AST timer1_cycle
!= NEVER
)
1257 AST timer1_cycle
-= cycle_limit
;
1258 if (AST timer2_cycle
!= NEVER
)
1259 AST timer2_cycle
-= cycle_limit
;
1260 if (AST timer4_cycle
!= NEVER
)
1261 AST timer4_cycle
-= cycle_limit
;