summaryrefslogtreecommitdiff
path: root/apps/codecs/libasap/acpu.c
diff options
context:
space:
mode:
Diffstat (limited to 'apps/codecs/libasap/acpu.c')
-rw-r--r--apps/codecs/libasap/acpu.c862
1 files changed, 453 insertions, 409 deletions
diff --git a/apps/codecs/libasap/acpu.c b/apps/codecs/libasap/acpu.c
index a4def24371..7c3c8f6f28 100644
--- a/apps/codecs/libasap/acpu.c
+++ b/apps/codecs/libasap/acpu.c
@@ -1,7 +1,7 @@
1/* 1/*
2 * acpu.c - another 6502 CPU emulator 2 * acpu.c - another 6502 CPU emulator
3 * 3 *
4 * Copyright (C) 2007-2008 Piotr Fusik 4 * Copyright (C) 2007-2009 Piotr Fusik
5 * 5 *
6 * This file is part of ASAP (Another Slight Atari Player), 6 * This file is part of ASAP (Another Slight Atari Player),
7 * see http://asap.sourceforge.net 7 * see http://asap.sourceforge.net
@@ -21,10 +21,37 @@
21 * 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA 21 * 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA
22 */ 22 */
23 23
24/* How 6502 registers are stored in this emulator:
25 All variables are int, because modern processors (and Java bytecode)
26 tend to operate more effectively on these type than narrower ones.
27 pc is really an unsigned 16-bit integer.
28 a, x, y and s are unsigned 8-bit integers.
29 Flags are decomposed into three variables for improved performance.
30 c is either 0 or 1.
31 nz contains 6502 flags N and Z.
32 N is set if (nz >= 0x80). Z is set if ((nz & 0xff) == 0).
33 Usually nz is simply assigned the unsigned 8-bit operation result.
34 There are just a few operations (ADC in decimal mode, BIT, PLP and RTI)
35 where both N and Z may be set. In these cases, N is reflected by the 8th
36 (not 7th) bit of nz.
37 vdi contains rarely used flags V, D and I, as a combination
38 of V_FLAG, D_FLAG and I_FLAG. Other vdi bits are clear.
39
40 "Unofficial" opcodes are not documented as "legal" 6502 opcodes.
41 Their operation has been reverse-engineered on Atari 800XL and Atari 65XE.
42 Unofficial opcodes are identical to C64's 6510, except for 0x8b and 0xab.
43 The operation of "unstable" opcodes is partially uncertain.
44 Explanation is welcome.
45
46 Emulation of POKEY timer interrupts is included.
47
48 Two preprocessor symbols may be used to strip the size of this emulator.
49 Define ACPU_NO_DECIMAL to disable emulation of the BCD mode.
50 Define ACPU_NO_UNOFFICIAL to disable emulation of unofficial opcodes. */
51
24#include "asap_internal.h" 52#include "asap_internal.h"
25 53
26CONST_LOOKUP(int, opcode_cycles) = 54CONST_ARRAY(int, opcode_cycles)
27{
28/* 0 1 2 3 4 5 6 7 8 9 A B C D E F */ 55/* 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 */ 56 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 */ 57 2, 5, 2, 8, 4, 4, 6, 6, 2, 4, 2, 7, 4, 4, 7, 7, /* 1x */
@@ -42,12 +69,38 @@ CONST_LOOKUP(int, opcode_cycles) =
42 2, 5, 2, 8, 4, 4, 6, 6, 2, 4, 2, 7, 4, 4, 7, 7, /* Dx */ 69 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 */ 70 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 */ 71 2, 5, 2, 8, 4, 4, 6, 6, 2, 4, 2, 7, 4, 4, 7, 7 /* Fx */
45}; 72END_CONST_ARRAY;
73
74#ifdef ACPU_NO_DECIMAL
75
76#define DO_ADC \
77 { \
78 /* binary mode */ \
79 V(int, tmp) = a + data + c; \
80 c = tmp >> 8; \
81 vdi &= D_FLAG | I_FLAG; \
82 if (((a ^ data) & 0x80) == 0 && ((data ^ tmp) & 0x80) != 0) \
83 vdi += V_FLAG; \
84 nz = a = tmp & 0xff; \
85 }
86
87#define DO_SBC \
88 { \
89 /* binary mode */ \
90 V(int, tmp) = a - data - 1 + c; \
91 c = (tmp >= 0) ? 1 : 0; \
92 vdi &= D_FLAG | I_FLAG; \
93 if (((a ^ tmp) & 0x80) != 0 && ((a ^ data) & 0x80) != 0) \
94 vdi += V_FLAG; \
95 nz = a = tmp & 0xff; \
96 }
97
98#else /* ACPU_NO_DECIMAL */
46 99
47#define DO_ADC \ 100#define DO_ADC \
48 if ((vdi & D_FLAG) == 0) { \ 101 if ((vdi & D_FLAG) == 0) { \
49 /* binary mode */ \ 102 /* binary mode */ \
50 int tmp = a + data + c; \ 103 V(int, tmp) = a + data + c; \
51 c = tmp >> 8; \ 104 c = tmp >> 8; \
52 vdi &= D_FLAG | I_FLAG; \ 105 vdi &= D_FLAG | I_FLAG; \
53 if (((a ^ data) & 0x80) == 0 && ((data ^ tmp) & 0x80) != 0) \ 106 if (((a ^ data) & 0x80) == 0 && ((data ^ tmp) & 0x80) != 0) \
@@ -56,7 +109,7 @@ CONST_LOOKUP(int, opcode_cycles) =
56 } \ 109 } \
57 else { \ 110 else { \
58 /* decimal mode */ \ 111 /* decimal mode */ \
59 int tmp = (a & 0x0f) + (data & 0x0f) + c; \ 112 V(int, tmp) = (a & 0x0f) + (data & 0x0f) + c; \
60 if (tmp >= 10) \ 113 if (tmp >= 10) \
61 tmp = (tmp - 10) | 0x10; \ 114 tmp = (tmp - 10) | 0x10; \
62 tmp += (a & 0xf0) + (data & 0xf0); \ 115 tmp += (a & 0xf0) + (data & 0xf0); \
@@ -73,7 +126,7 @@ CONST_LOOKUP(int, opcode_cycles) =
73#define DO_SBC \ 126#define DO_SBC \
74 if ((vdi & D_FLAG) == 0) { \ 127 if ((vdi & D_FLAG) == 0) { \
75 /* binary mode */ \ 128 /* binary mode */ \
76 int tmp = a - data - 1 + c; \ 129 V(int, tmp) = a - data - 1 + c; \
77 c = (tmp >= 0) ? 1 : 0; \ 130 c = (tmp >= 0) ? 1 : 0; \
78 vdi &= D_FLAG | I_FLAG; \ 131 vdi &= D_FLAG | I_FLAG; \
79 if (((a ^ tmp) & 0x80) != 0 && ((a ^ data) & 0x80) != 0) \ 132 if (((a ^ tmp) & 0x80) != 0 && ((a ^ data) & 0x80) != 0) \
@@ -82,9 +135,9 @@ CONST_LOOKUP(int, opcode_cycles) =
82 } \ 135 } \
83 else { \ 136 else { \
84 /* decimal mode */ \ 137 /* decimal mode */ \
85 int tmp = a - data - 1 + c; \ 138 V(int, tmp) = a - data - 1 + c; \
86 int al = (a & 0x0f) - (data & 0x0f) - 1 + c; \ 139 V(int, al) = (a & 0x0f) - (data & 0x0f) - 1 + c; \
87 int ah = (a >> 4) - (data >> 4); \ 140 V(int, ah) = (a >> 4) - (data >> 4); \
88 if ((al & 0x10) != 0) { \ 141 if ((al & 0x10) != 0) { \
89 al -= 6; \ 142 al -= 6; \
90 ah--; \ 143 ah--; \
@@ -99,6 +152,8 @@ CONST_LOOKUP(int, opcode_cycles) =
99 a = ((ah & 0xf) << 4) + (al & 0x0f); \ 152 a = ((ah & 0xf) << 4) + (al & 0x0f); \
100 } 153 }
101 154
155#endif /* ACPU_NO_DECIMAL */
156
102#define zGetByte(addr) dGetByte((addr) & 0xff) 157#define zGetByte(addr) dGetByte((addr) & 0xff)
103 158
104#define PEEK dGetByte(pc) 159#define PEEK dGetByte(pc)
@@ -112,13 +167,13 @@ CONST_LOOKUP(int, opcode_cycles) =
112#define ZPAGE_Y addr = (FETCH + y) & 0xff 167#define ZPAGE_Y addr = (FETCH + y) & 0xff
113#define INDIRECT_X addr = (FETCH + x) & 0xff; addr = dGetByte(addr) + (zGetByte(addr + 1) << 8) 168#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 169#define INDIRECT_Y addr = FETCH; addr = (dGetByte(addr) + (zGetByte(addr + 1) << 8) + y) & 0xffff
115#define NCYCLES_X if ((addr & 0xff) < x) AST cycle++ 170#define NCYCLES_X if ((addr & 0xff) < x) ast _ cycle++
116#define NCYCLES_Y if ((addr & 0xff) < y) AST cycle++ 171#define NCYCLES_Y if ((addr & 0xff) < y) ast _ cycle++
117 172
118#define PL(dest) s = (s + 1) & 0xff; dest = dGetByte(0x0100 + s) 173#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 174#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 175#define PH(data) dPutByte(0x0100 + s, data); s = (s - 1) & 0xff
121#define PHW(data) PH((data) >> 8); PH(data) 176#define PHW(data) PH((data) >> 8); PH(TO_BYTE(data))
122#define PHP(bflag) PH(((nz | (nz >> 1)) & 0x80) + vdi + ((nz & 0xff) == 0 ? Z_FLAG : 0) + c + bflag) 177#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) */ 178#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) */ 179#define PHPB1 PHP(0x30) /* push flags with B flag set (PHP, BRK) */
@@ -163,28 +218,8 @@ CONST_LOOKUP(int, opcode_cycles) =
163#define ROL_ZP nz = dGetByte(addr); nz = (nz << 1) + c; c = nz >> 8; nz &= 0xff; dPutByte(addr, nz) 218#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) 219#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) 220#define LSR_ZP nz = dGetByte(addr); c = nz & 1; nz >>= 1; dPutByte(addr, nz)
166#define ROR \ 221#define ROR RMW_GetByte(nz, addr); nz += c << 8; c = nz & 1; nz >>= 1; PutByte(addr, nz)
167 RMW_GetByte(nz, addr); \ 222#define ROR_ZP nz = dGetByte(addr) + (c << 8); c = nz & 1; nz >>= 1; dPutByte(addr, nz)
168 if (c == 0) { \
169 c = nz & 1; \
170 nz >>= 1; \
171 } \
172 else { \
173 c = nz & 1; \
174 nz = (nz >> 1) + 128; \
175 } \
176 PutByte(addr, nz)
177#define ROR_ZP \
178 nz = dGetByte(addr); \
179 if (c == 0) { \
180 c = nz & 1; \
181 nz >>= 1; \
182 } \
183 else { \
184 c = nz & 1; \
185 nz = (nz >> 1) + 128; \
186 } \
187 dPutByte(addr, nz)
188#define DEC RMW_GetByte(nz, addr); nz = (nz - 1) & 0xff; PutByte(addr, nz) 223#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) 224#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) 225#define INC RMW_GetByte(nz, addr); nz = (nz + 1) & 0xff; PutByte(addr, nz)
@@ -205,11 +240,12 @@ CONST_LOOKUP(int, opcode_cycles) =
205 240
206#define BRANCH(cond) \ 241#define BRANCH(cond) \
207 if (cond) { \ 242 if (cond) { \
208 addr = SBYTE(FETCH); \ 243 addr = SBYTE(PEEK); \
244 pc++; \
209 addr += pc; \ 245 addr += pc; \
210 if (((addr ^ pc) & 0xff00) != 0) \ 246 if ((addr ^ pc) >> 8 != 0) \
211 AST cycle++; \ 247 ast _ cycle++; \
212 AST cycle++; \ 248 ast _ cycle++; \
213 pc = addr; \ 249 pc = addr; \
214 break; \ 250 break; \
215 } \ 251 } \
@@ -217,78 +253,81 @@ CONST_LOOKUP(int, opcode_cycles) =
217 break 253 break
218 254
219#define CHECK_IRQ \ 255#define CHECK_IRQ \
220 if ((vdi & I_FLAG) == 0 && AST irqst != 0xff) { \ 256 if ((vdi & I_FLAG) == 0 && ast _ irqst != 0xff) { \
221 PHPC; \ 257 PHPC; \
222 PHPB0; \ 258 PHPB0; \
223 vdi |= I_FLAG; \ 259 vdi |= I_FLAG; \
224 pc = dGetWord(0xfffe); \ 260 pc = dGetWord(0xfffe); \
225 AST cycle += 7; \ 261 ast _ cycle += 7; \
226 } 262 }
227 263
228ASAP_FUNC void Cpu_RunScanlines(ASAP_State PTR ast, int scanlines) 264/* Runs 6502 emulation for the specified number of Atari scanlines.
265 Each scanline is 114 cycles of which 9 is taken by ANTIC for memory refresh. */
266FUNC(void, Cpu_RunScanlines, (P(ASAP_State PTR, ast), P(int, scanlines)))
229{ 267{
230 int pc; 268 /* copy registers from ASAP_State to local variables for improved performance */
231 int nz; 269 V(int, pc);
232 int a; 270 V(int, nz);
233 int x; 271 V(int, a);
234 int y; 272 V(int, x);
235 int c; 273 V(int, y);
236 int s; 274 V(int, c);
237 int vdi; 275 V(int, s);
238 int next_event_cycle; 276 V(int, vdi);
239 int cycle_limit; 277 V(int, next_event_cycle);
240 pc = AST cpu_pc; 278 V(int, cycle_limit);
241 nz = AST cpu_nz; 279 pc = ast _ cpu_pc;
242 a = AST cpu_a; 280 nz = ast _ cpu_nz;
243 x = AST cpu_x; 281 a = ast _ cpu_a;
244 y = AST cpu_y; 282 x = ast _ cpu_x;
245 c = AST cpu_c; 283 y = ast _ cpu_y;
246 s = AST cpu_s; 284 c = ast _ cpu_c;
247 vdi = AST cpu_vdi; 285 s = ast _ cpu_s;
248 AST next_scanline_cycle = 114; 286 vdi = ast _ cpu_vdi;
287 ast _ next_scanline_cycle = 114;
249 next_event_cycle = 114; 288 next_event_cycle = 114;
250 cycle_limit = 114 * scanlines; 289 cycle_limit = 114 * scanlines;
251 if (next_event_cycle > AST timer1_cycle) 290 if (next_event_cycle > ast _ timer1_cycle)
252 next_event_cycle = AST timer1_cycle; 291 next_event_cycle = ast _ timer1_cycle;
253 if (next_event_cycle > AST timer2_cycle) 292 if (next_event_cycle > ast _ timer2_cycle)
254 next_event_cycle = AST timer2_cycle; 293 next_event_cycle = ast _ timer2_cycle;
255 if (next_event_cycle > AST timer4_cycle) 294 if (next_event_cycle > ast _ timer4_cycle)
256 next_event_cycle = AST timer4_cycle; 295 next_event_cycle = ast _ timer4_cycle;
257 AST nearest_event_cycle = next_event_cycle; 296 ast _ nearest_event_cycle = next_event_cycle;
258 for (;;) { 297 for (;;) {
259 int cycle; 298 V(int, cycle);
260 int addr; 299 V(int, addr);
261 int data; 300 V(int, data);
262 cycle = AST cycle; 301 cycle = ast _ cycle;
263 if (cycle >= AST nearest_event_cycle) { 302 if (cycle >= ast _ nearest_event_cycle) {
264 if (cycle >= AST next_scanline_cycle) { 303 if (cycle >= ast _ next_scanline_cycle) {
265 if (++AST scanline_number == 312) 304 if (++ast _ scanline_number == 312)
266 AST scanline_number = 0; 305 ast _ scanline_number = 0;
267 AST cycle = cycle += 9; 306 ast _ cycle = cycle += 9;
268 AST next_scanline_cycle += 114; 307 ast _ next_scanline_cycle += 114;
269 if (--scanlines <= 0) 308 if (--scanlines <= 0)
270 break; 309 break;
271 } 310 }
272 next_event_cycle = AST next_scanline_cycle; 311 next_event_cycle = ast _ next_scanline_cycle;
273#define CHECK_TIMER_IRQ(ch) \ 312#define CHECK_TIMER_IRQ(ch) \
274 if (cycle >= AST timer##ch##_cycle) { \ 313 if (cycle >= ast _ timer##ch##_cycle) { \
275 AST irqst &= ~ch; \ 314 ast _ irqst &= ~ch; \
276 AST timer##ch##_cycle = NEVER; \ 315 ast _ timer##ch##_cycle = NEVER; \
277 } \ 316 } \
278 else if (next_event_cycle > AST timer##ch##_cycle) \ 317 else if (next_event_cycle > ast _ timer##ch##_cycle) \
279 next_event_cycle = AST timer##ch##_cycle; 318 next_event_cycle = ast _ timer##ch##_cycle;
280 CHECK_TIMER_IRQ(1); 319 CHECK_TIMER_IRQ(1);
281 CHECK_TIMER_IRQ(2); 320 CHECK_TIMER_IRQ(2);
282 CHECK_TIMER_IRQ(4); 321 CHECK_TIMER_IRQ(4);
283 AST nearest_event_cycle = next_event_cycle; 322 ast _ nearest_event_cycle = next_event_cycle;
284 CHECK_IRQ; 323 CHECK_IRQ;
285 } 324 }
286#ifdef ASAPSCAN 325#ifdef ASAPSCAN
287 if (cpu_trace) 326 if (cpu_trace != 0)
288 print_cpu_state(as, pc, a, x, y, s, nz, vdi, c); 327 trace_cpu(ast, pc, a, x, y, s, nz, vdi, c);
289#endif 328#endif
290 data = FETCH; 329 data = FETCH;
291 AST cycle += opcode_cycles[data]; 330 ast _ cycle += opcode_cycles[data];
292 switch (data) { 331 switch (data) {
293 case 0x00: /* BRK */ 332 case 0x00: /* BRK */
294 pc++; 333 pc++;
@@ -313,10 +352,11 @@ ASAP_FUNC void Cpu_RunScanlines(ASAP_State PTR ast, int scanlines)
313 case 0xb2: 352 case 0xb2:
314 case 0xd2: 353 case 0xd2:
315 case 0xf2: 354 case 0xf2:
316 AST scanline_number = (AST scanline_number + scanlines - 1) % 312; 355 ast _ scanline_number = (ast _ scanline_number + scanlines - 1) % 312;
317 scanlines = 1; 356 scanlines = 1;
318 AST cycle = cycle_limit; 357 ast _ cycle = cycle_limit;
319 break; 358 break;
359#ifndef ACPU_NO_UNOFFICIAL
320 case 0x03: /* ASO (ab,x) [unofficial] */ 360 case 0x03: /* ASO (ab,x) [unofficial] */
321 INDIRECT_X; 361 INDIRECT_X;
322 ASO; 362 ASO;
@@ -337,6 +377,314 @@ ASAP_FUNC void Cpu_RunScanlines(ASAP_State PTR ast, int scanlines)
337 case 0xe2: 377 case 0xe2:
338 pc++; 378 pc++;
339 break; 379 break;
380 case 0x07: /* ASO ab [unofficial] */
381 ZPAGE;
382 ASO_ZP;
383 break;
384 case 0x0b: /* ANC #ab [unofficial] */
385 case 0x2b:
386 nz = a &= FETCH;
387 c = nz >> 7;
388 break;
389 case 0x0c: /* NOP abcd [unofficial] */
390 pc += 2;
391 break;
392 case 0x0f: /* ASO abcd [unofficial] */
393 ABSOLUTE;
394 ASO;
395 break;
396 case 0x13: /* ASO (ab),y [unofficial] */
397 INDIRECT_Y;
398 ASO;
399 break;
400 case 0x17: /* ASO ab,x [unofficial] */
401 ZPAGE_X;
402 ASO_ZP;
403 break;
404 case 0x1b: /* ASO abcd,y [unofficial] */
405 ABSOLUTE_Y;
406 ASO;
407 break;
408 case 0x1c: /* NOP abcd,x [unofficial] */
409 case 0x3c:
410 case 0x5c:
411 case 0x7c:
412 case 0xdc:
413 case 0xfc:
414 if (FETCH + x >= 0x100)
415 ast _ cycle++;
416 pc++;
417 break;
418 case 0x1f: /* ASO abcd,x [unofficial] */
419 ABSOLUTE_X;
420 ASO;
421 break;
422 case 0x23: /* RLA (ab,x) [unofficial] */
423 INDIRECT_X;
424 RLA;
425 break;
426 case 0x27: /* RLA ab [unofficial] */
427 ZPAGE;
428 RLA_ZP;
429 break;
430 case 0x2f: /* RLA abcd [unofficial] */
431 ABSOLUTE;
432 RLA;
433 break;
434 case 0x33: /* RLA (ab),y [unofficial] */
435 INDIRECT_Y;
436 RLA;
437 break;
438 case 0x37: /* RLA ab,x [unofficial] */
439 ZPAGE_X;
440 RLA_ZP;
441 break;
442 case 0x3b: /* RLA abcd,y [unofficial] */
443 ABSOLUTE_Y;
444 RLA;
445 break;
446 case 0x3f: /* RLA abcd,x [unofficial] */
447 ABSOLUTE_X;
448 RLA;
449 break;
450 case 0x43: /* LSE (ab,x) [unofficial] */
451 INDIRECT_X;
452 LSE;
453 break;
454 case 0x47: /* LSE ab [unofficial] */
455 ZPAGE;
456 LSE_ZP;
457 break;
458 case 0x4b: /* ALR #ab [unofficial] */
459 a &= FETCH;
460 c = a & 1;
461 nz = a >>= 1;
462 break;
463 case 0x4f: /* LSE abcd [unofficial] */
464 ABSOLUTE;
465 LSE;
466 break;
467 case 0x53: /* LSE (ab),y [unofficial] */
468 INDIRECT_Y;
469 LSE;
470 break;
471 case 0x57: /* LSE ab,x [unofficial] */
472 ZPAGE_X;
473 LSE_ZP;
474 break;
475 case 0x5b: /* LSE abcd,y [unofficial] */
476 ABSOLUTE_Y;
477 LSE;
478 break;
479 case 0x5f: /* LSE abcd,x [unofficial] */
480 ABSOLUTE_X;
481 LSE;
482 break;
483 case 0x63: /* RRA (ab,x) [unofficial] */
484 INDIRECT_X;
485 RRA;
486 break;
487 case 0x67: /* RRA ab [unofficial] */
488 ZPAGE;
489 RRA_ZP;
490 break;
491 case 0x6b: /* ARR #ab [unofficial] */
492 data = a & FETCH;
493 nz = a = (data >> 1) + (c << 7);
494 vdi = (vdi & (D_FLAG | I_FLAG)) + ((a ^ data) & V_FLAG);
495#ifdef ACPU_NO_DECIMAL
496 c = data >> 7;
497#else
498 if ((vdi & D_FLAG) == 0)
499 c = data >> 7;
500 else {
501 if ((data & 0xf) >= 5)
502 a = (a & 0xf0) + ((a + 6) & 0xf);
503 if (data >= 0x50) {
504 a = (a + 0x60) & 0xff;
505 c = 1;
506 }
507 else
508 c = 0;
509 }
510#endif
511 break;
512 case 0x6f: /* RRA abcd [unofficial] */
513 ABSOLUTE;
514 RRA;
515 break;
516 case 0x73: /* RRA (ab),y [unofficial] */
517 INDIRECT_Y;
518 RRA;
519 break;
520 case 0x77: /* RRA ab,x [unofficial] */
521 ZPAGE_X;
522 RRA_ZP;
523 break;
524 case 0x7b: /* RRA abcd,y [unofficial] */
525 ABSOLUTE_Y;
526 RRA;
527 break;
528 case 0x7f: /* RRA abcd,x [unofficial] */
529 ABSOLUTE_X;
530 RRA;
531 break;
532 case 0x83: /* SAX (ab,x) [unofficial] */
533 INDIRECT_X;
534 SAX;
535 break;
536 case 0x87: /* SAX ab [unofficial] */
537 ZPAGE;
538 SAX_ZP;
539 break;
540 case 0x8b: /* ANE #ab [unofficial] */
541 data = FETCH;
542 a &= x;
543 nz = a & data;
544 a &= data | 0xef;
545 break;
546 case 0x8f: /* SAX abcd [unofficial] */
547 ABSOLUTE;
548 SAX;
549 break;
550 case 0x93: /* SHA (ab),y [unofficial, unstable] */
551 ZPAGE;
552 data = zGetByte(addr + 1);
553 addr = (dGetByte(addr) + (data << 8) + y) & 0xffff;
554 data = a & x & (data + 1);
555 PutByte(addr, data);
556 break;
557 case 0x97: /* SAX ab,y [unofficial] */
558 ZPAGE_Y;
559 SAX_ZP;
560 break;
561 case 0x9b: /* SHS abcd,y [unofficial, unstable] */
562 /* S seems to be stable, only memory values vary */
563 addr = FETCH;
564 data = FETCH;
565 addr = (addr + (data << 8) + y) & 0xffff;
566 s = a & x;
567 data = s & (data + 1);
568 PutByte(addr, data);
569 break;
570 case 0x9c: /* SHY abcd,x [unofficial] */
571 addr = FETCH;
572 data = FETCH;
573 addr = (addr + (data << 8) + x) & 0xffff;
574 data = y & (data + 1);
575 PutByte(addr, data);
576 break;
577 case 0x9e: /* SHX abcd,y [unofficial] */
578 addr = FETCH;
579 data = FETCH;
580 addr = (addr + (data << 8) + y) & 0xffff;
581 data = x & (data + 1);
582 PutByte(addr, data);
583 break;
584 case 0x9f: /* SHA abcd,y [unofficial, unstable] */
585 addr = FETCH;
586 data = FETCH;
587 addr = (addr + (data << 8) + y) & 0xffff;
588 data = a & x & (data + 1);
589 PutByte(addr, data);
590 break;
591 case 0xa3: /* LAX (ab,x) [unofficial] */
592 INDIRECT_X;
593 LAX;
594 break;
595 case 0xa7: /* LAX ab [unofficial] */
596 ZPAGE;
597 LAX_ZP;
598 break;
599 case 0xab: /* ANX #ab [unofficial] */
600 nz = x = a &= FETCH;
601 break;
602 case 0xaf: /* LAX abcd [unofficial] */
603 ABSOLUTE;
604 LAX;
605 break;
606 case 0xb3: /* LAX (ab),y [unofficial] */
607 INDIRECT_Y;
608 NCYCLES_Y;
609 LAX;
610 break;
611 case 0xb7: /* LAX ab,y [unofficial] */
612 ZPAGE_Y;
613 LAX_ZP;
614 break;
615 case 0xbb: /* LAS abcd,y [unofficial] */
616 ABSOLUTE_Y;
617 NCYCLES_Y;
618 nz = x = a = s &= GetByte(addr);
619 break;
620 case 0xbf: /* LAX abcd,y [unofficial] */
621 ABSOLUTE_Y;
622 NCYCLES_Y;
623 LAX;
624 break;
625 case 0xc3: /* DCM (ab,x) [unofficial] */
626 INDIRECT_X;
627 DCM;
628 break;
629 case 0xc7: /* DCM ab [unofficial] */
630 ZPAGE;
631 DCM_ZP;
632 break;
633 case 0xcb: /* SBX #ab [unofficial] */
634 nz = FETCH;
635 x &= a;
636 c = (x >= nz) ? 1 : 0;
637 nz = x = (x - nz) & 0xff;
638 break;
639 case 0xcf: /* DCM abcd [unofficial] */
640 ABSOLUTE;
641 DCM;
642 break;
643 case 0xd3: /* DCM (ab),y [unofficial] */
644 INDIRECT_Y;
645 DCM;
646 break;
647 case 0xd7: /* DCM ab,x [unofficial] */
648 ZPAGE_X;
649 DCM_ZP;
650 break;
651 case 0xdb: /* DCM abcd,y [unofficial] */
652 ABSOLUTE_Y;
653 DCM;
654 break;
655 case 0xdf: /* DCM abcd,x [unofficial] */
656 ABSOLUTE_X;
657 DCM;
658 break;
659 case 0xe3: /* INS (ab,x) [unofficial] */
660 INDIRECT_X;
661 INS;
662 break;
663 case 0xe7: /* INS ab [unofficial] */
664 ZPAGE;
665 INS_ZP;
666 break;
667 case 0xef: /* INS abcd [unofficial] */
668 ABSOLUTE;
669 INS;
670 break;
671 case 0xf3: /* INS (ab),y [unofficial] */
672 INDIRECT_Y;
673 INS;
674 break;
675 case 0xf7: /* INS ab,x [unofficial] */
676 ZPAGE_X;
677 INS_ZP;
678 break;
679 case 0xfb: /* INS abcd,y [unofficial] */
680 ABSOLUTE_Y;
681 INS;
682 break;
683 case 0xff: /* INS abcd,x [unofficial] */
684 ABSOLUTE_X;
685 INS;
686 break;
687#endif /* ACPU_NO_UNOFFICIAL */
340 case 0x05: /* ORA ab */ 688 case 0x05: /* ORA ab */
341 ZPAGE; 689 ZPAGE;
342 ORA_ZP; 690 ORA_ZP;
@@ -345,10 +693,6 @@ ASAP_FUNC void Cpu_RunScanlines(ASAP_State PTR ast, int scanlines)
345 ZPAGE; 693 ZPAGE;
346 ASL_ZP; 694 ASL_ZP;
347 break; 695 break;
348 case 0x07: /* ASO ab [unofficial] */
349 ZPAGE;
350 ASO_ZP;
351 break;
352 case 0x08: /* PHP */ 696 case 0x08: /* PHP */
353 PHPB1; 697 PHPB1;
354 break; 698 break;
@@ -359,14 +703,6 @@ ASAP_FUNC void Cpu_RunScanlines(ASAP_State PTR ast, int scanlines)
359 c = a >> 7; 703 c = a >> 7;
360 nz = a = (a << 1) & 0xff; 704 nz = a = (a << 1) & 0xff;
361 break; 705 break;
362 case 0x0b: /* ANC #ab [unofficial] */
363 case 0x2b:
364 nz = a &= FETCH;
365 c = nz >> 7;
366 break;
367 case 0x0c: /* NOP abcd [unofficial] */
368 pc += 2;
369 break;
370 case 0x0d: /* ORA abcd */ 706 case 0x0d: /* ORA abcd */
371 ABSOLUTE; 707 ABSOLUTE;
372 ORA; 708 ORA;
@@ -375,10 +711,6 @@ ASAP_FUNC void Cpu_RunScanlines(ASAP_State PTR ast, int scanlines)
375 ABSOLUTE; 711 ABSOLUTE;
376 ASL; 712 ASL;
377 break; 713 break;
378 case 0x0f: /* ASO abcd [unofficial] */
379 ABSOLUTE;
380 ASO;
381 break;
382 case 0x10: /* BPL */ 714 case 0x10: /* BPL */
383 BRANCH(nz < 0x80); 715 BRANCH(nz < 0x80);
384 case 0x11: /* ORA (ab),y */ 716 case 0x11: /* ORA (ab),y */
@@ -386,10 +718,6 @@ ASAP_FUNC void Cpu_RunScanlines(ASAP_State PTR ast, int scanlines)
386 NCYCLES_Y; 718 NCYCLES_Y;
387 ORA; 719 ORA;
388 break; 720 break;
389 case 0x13: /* ASO (ab),y [unofficial] */
390 INDIRECT_Y;
391 ASO;
392 break;
393 case 0x15: /* ORA ab,x */ 721 case 0x15: /* ORA ab,x */
394 ZPAGE_X; 722 ZPAGE_X;
395 ORA_ZP; 723 ORA_ZP;
@@ -398,10 +726,6 @@ ASAP_FUNC void Cpu_RunScanlines(ASAP_State PTR ast, int scanlines)
398 ZPAGE_X; 726 ZPAGE_X;
399 ASL_ZP; 727 ASL_ZP;
400 break; 728 break;
401 case 0x17: /* ASO ab,x [unofficial] */
402 ZPAGE_X;
403 ASO_ZP;
404 break;
405 case 0x18: /* CLC */ 729 case 0x18: /* CLC */
406 c = 0; 730 c = 0;
407 break; 731 break;
@@ -410,20 +734,6 @@ ASAP_FUNC void Cpu_RunScanlines(ASAP_State PTR ast, int scanlines)
410 NCYCLES_Y; 734 NCYCLES_Y;
411 ORA; 735 ORA;
412 break; 736 break;
413 case 0x1b: /* ASO abcd,y [unofficial] */
414 ABSOLUTE_Y;
415 ASO;
416 break;
417 case 0x1c: /* NOP abcd,x [unofficial] */
418 case 0x3c:
419 case 0x5c:
420 case 0x7c:
421 case 0xdc:
422 case 0xfc:
423 if (FETCH + x >= 0x100)
424 AST cycle++;
425 pc++;
426 break;
427 case 0x1d: /* ORA abcd,x */ 737 case 0x1d: /* ORA abcd,x */
428 ABSOLUTE_X; 738 ABSOLUTE_X;
429 NCYCLES_X; 739 NCYCLES_X;
@@ -433,10 +743,6 @@ ASAP_FUNC void Cpu_RunScanlines(ASAP_State PTR ast, int scanlines)
433 ABSOLUTE_X; 743 ABSOLUTE_X;
434 ASL; 744 ASL;
435 break; 745 break;
436 case 0x1f: /* ASO abcd,x [unofficial] */
437 ABSOLUTE_X;
438 ASO;
439 break;
440 case 0x20: /* JSR abcd */ 746 case 0x20: /* JSR abcd */
441 addr = FETCH; 747 addr = FETCH;
442 PHPC; 748 PHPC;
@@ -446,10 +752,6 @@ ASAP_FUNC void Cpu_RunScanlines(ASAP_State PTR ast, int scanlines)
446 INDIRECT_X; 752 INDIRECT_X;
447 AND; 753 AND;
448 break; 754 break;
449 case 0x23: /* RLA (ab,x) [unofficial] */
450 INDIRECT_X;
451 RLA;
452 break;
453 case 0x24: /* BIT ab */ 755 case 0x24: /* BIT ab */
454 ZPAGE; 756 ZPAGE;
455 nz = dGetByte(addr); 757 nz = dGetByte(addr);
@@ -464,10 +766,6 @@ ASAP_FUNC void Cpu_RunScanlines(ASAP_State PTR ast, int scanlines)
464 ZPAGE; 766 ZPAGE;
465 ROL_ZP; 767 ROL_ZP;
466 break; 768 break;
467 case 0x27: /* RLA ab [unofficial] */
468 ZPAGE;
469 RLA_ZP;
470 break;
471 case 0x28: /* PLP */ 769 case 0x28: /* PLP */
472 PLP; 770 PLP;
473 CHECK_IRQ; 771 CHECK_IRQ;
@@ -494,10 +792,6 @@ ASAP_FUNC void Cpu_RunScanlines(ASAP_State PTR ast, int scanlines)
494 ABSOLUTE; 792 ABSOLUTE;
495 ROL; 793 ROL;
496 break; 794 break;
497 case 0x2f: /* RLA abcd [unofficial] */
498 ABSOLUTE;
499 RLA;
500 break;
501 case 0x30: /* BMI */ 795 case 0x30: /* BMI */
502 BRANCH(nz >= 0x80); 796 BRANCH(nz >= 0x80);
503 case 0x31: /* AND (ab),y */ 797 case 0x31: /* AND (ab),y */
@@ -505,10 +799,6 @@ ASAP_FUNC void Cpu_RunScanlines(ASAP_State PTR ast, int scanlines)
505 NCYCLES_Y; 799 NCYCLES_Y;
506 AND; 800 AND;
507 break; 801 break;
508 case 0x33: /* RLA (ab),y [unofficial] */
509 INDIRECT_Y;
510 RLA;
511 break;
512 case 0x35: /* AND ab,x */ 802 case 0x35: /* AND ab,x */
513 ZPAGE_X; 803 ZPAGE_X;
514 AND_ZP; 804 AND_ZP;
@@ -517,10 +807,6 @@ ASAP_FUNC void Cpu_RunScanlines(ASAP_State PTR ast, int scanlines)
517 ZPAGE_X; 807 ZPAGE_X;
518 ROL_ZP; 808 ROL_ZP;
519 break; 809 break;
520 case 0x37: /* RLA ab,x [unofficial] */
521 ZPAGE_X;
522 RLA_ZP;
523 break;
524 case 0x38: /* SEC */ 810 case 0x38: /* SEC */
525 c = 1; 811 c = 1;
526 break; 812 break;
@@ -529,10 +815,6 @@ ASAP_FUNC void Cpu_RunScanlines(ASAP_State PTR ast, int scanlines)
529 NCYCLES_Y; 815 NCYCLES_Y;
530 AND; 816 AND;
531 break; 817 break;
532 case 0x3b: /* RLA abcd,y [unofficial] */
533 ABSOLUTE_Y;
534 RLA;
535 break;
536 case 0x3d: /* AND abcd,x */ 818 case 0x3d: /* AND abcd,x */
537 ABSOLUTE_X; 819 ABSOLUTE_X;
538 NCYCLES_X; 820 NCYCLES_X;
@@ -542,10 +824,6 @@ ASAP_FUNC void Cpu_RunScanlines(ASAP_State PTR ast, int scanlines)
542 ABSOLUTE_X; 824 ABSOLUTE_X;
543 ROL; 825 ROL;
544 break; 826 break;
545 case 0x3f: /* RLA abcd,x [unofficial] */
546 ABSOLUTE_X;
547 RLA;
548 break;
549 case 0x40: /* RTI */ 827 case 0x40: /* RTI */
550 PLP; 828 PLP;
551 PL(pc); 829 PL(pc);
@@ -557,10 +835,6 @@ ASAP_FUNC void Cpu_RunScanlines(ASAP_State PTR ast, int scanlines)
557 INDIRECT_X; 835 INDIRECT_X;
558 EOR; 836 EOR;
559 break; 837 break;
560 case 0x43: /* LSE (ab,x) [unofficial] */
561 INDIRECT_X;
562 LSE;
563 break;
564 case 0x45: /* EOR ab */ 838 case 0x45: /* EOR ab */
565 ZPAGE; 839 ZPAGE;
566 EOR_ZP; 840 EOR_ZP;
@@ -569,10 +843,6 @@ ASAP_FUNC void Cpu_RunScanlines(ASAP_State PTR ast, int scanlines)
569 ZPAGE; 843 ZPAGE;
570 LSR_ZP; 844 LSR_ZP;
571 break; 845 break;
572 case 0x47: /* LSE ab [unofficial] */
573 ZPAGE;
574 LSE_ZP;
575 break;
576 case 0x48: /* PHA */ 846 case 0x48: /* PHA */
577 PH(a); 847 PH(a);
578 break; 848 break;
@@ -583,11 +853,6 @@ ASAP_FUNC void Cpu_RunScanlines(ASAP_State PTR ast, int scanlines)
583 c = a & 1; 853 c = a & 1;
584 nz = a >>= 1; 854 nz = a >>= 1;
585 break; 855 break;
586 case 0x4b: /* ALR #ab [unofficial] */
587 a &= FETCH;
588 c = a & 1;
589 nz = a >>= 1;
590 break;
591 case 0x4c: /* JMP abcd */ 856 case 0x4c: /* JMP abcd */
592 addr = FETCH; 857 addr = FETCH;
593 pc = addr + (PEEK << 8); 858 pc = addr + (PEEK << 8);
@@ -600,10 +865,6 @@ ASAP_FUNC void Cpu_RunScanlines(ASAP_State PTR ast, int scanlines)
600 ABSOLUTE; 865 ABSOLUTE;
601 LSR; 866 LSR;
602 break; 867 break;
603 case 0x4f: /* LSE abcd [unofficial] */
604 ABSOLUTE;
605 LSE;
606 break;
607 case 0x50: /* BVC */ 868 case 0x50: /* BVC */
608 BRANCH((vdi & V_FLAG) == 0); 869 BRANCH((vdi & V_FLAG) == 0);
609 case 0x51: /* EOR (ab),y */ 870 case 0x51: /* EOR (ab),y */
@@ -611,10 +872,6 @@ ASAP_FUNC void Cpu_RunScanlines(ASAP_State PTR ast, int scanlines)
611 NCYCLES_Y; 872 NCYCLES_Y;
612 EOR; 873 EOR;
613 break; 874 break;
614 case 0x53: /* LSE (ab),y [unofficial] */
615 INDIRECT_Y;
616 LSE;
617 break;
618 case 0x55: /* EOR ab,x */ 875 case 0x55: /* EOR ab,x */
619 ZPAGE_X; 876 ZPAGE_X;
620 EOR_ZP; 877 EOR_ZP;
@@ -623,10 +880,6 @@ ASAP_FUNC void Cpu_RunScanlines(ASAP_State PTR ast, int scanlines)
623 ZPAGE_X; 880 ZPAGE_X;
624 LSR_ZP; 881 LSR_ZP;
625 break; 882 break;
626 case 0x57: /* LSE ab,x [unofficial] */
627 ZPAGE_X;
628 LSE_ZP;
629 break;
630 case 0x58: /* CLI */ 883 case 0x58: /* CLI */
631 vdi &= V_FLAG | D_FLAG; 884 vdi &= V_FLAG | D_FLAG;
632 CHECK_IRQ; 885 CHECK_IRQ;
@@ -636,10 +889,6 @@ ASAP_FUNC void Cpu_RunScanlines(ASAP_State PTR ast, int scanlines)
636 NCYCLES_Y; 889 NCYCLES_Y;
637 EOR; 890 EOR;
638 break; 891 break;
639 case 0x5b: /* LSE abcd,y [unofficial] */
640 ABSOLUTE_Y;
641 LSE;
642 break;
643 case 0x5d: /* EOR abcd,x */ 892 case 0x5d: /* EOR abcd,x */
644 ABSOLUTE_X; 893 ABSOLUTE_X;
645 NCYCLES_X; 894 NCYCLES_X;
@@ -649,10 +898,6 @@ ASAP_FUNC void Cpu_RunScanlines(ASAP_State PTR ast, int scanlines)
649 ABSOLUTE_X; 898 ABSOLUTE_X;
650 LSR; 899 LSR;
651 break; 900 break;
652 case 0x5f: /* LSE abcd,x [unofficial] */
653 ABSOLUTE_X;
654 LSE;
655 break;
656 case 0x60: /* RTS */ 901 case 0x60: /* RTS */
657 PL(pc); 902 PL(pc);
658 PL(addr); 903 PL(addr);
@@ -662,10 +907,6 @@ ASAP_FUNC void Cpu_RunScanlines(ASAP_State PTR ast, int scanlines)
662 INDIRECT_X; 907 INDIRECT_X;
663 ADC; 908 ADC;
664 break; 909 break;
665 case 0x63: /* RRA (ab,x) [unofficial] */
666 INDIRECT_X;
667 RRA;
668 break;
669 case 0x65: /* ADC ab */ 910 case 0x65: /* ADC ab */
670 ZPAGE; 911 ZPAGE;
671 ADC_ZP; 912 ADC_ZP;
@@ -674,10 +915,6 @@ ASAP_FUNC void Cpu_RunScanlines(ASAP_State PTR ast, int scanlines)
674 ZPAGE; 915 ZPAGE;
675 ROR_ZP; 916 ROR_ZP;
676 break; 917 break;
677 case 0x67: /* RRA ab [unofficial] */
678 ZPAGE;
679 RRA_ZP;
680 break;
681 case 0x68: /* PLA */ 918 case 0x68: /* PLA */
682 PL(a); 919 PL(a);
683 nz = a; 920 nz = a;
@@ -691,24 +928,6 @@ ASAP_FUNC void Cpu_RunScanlines(ASAP_State PTR ast, int scanlines)
691 c = a & 1; 928 c = a & 1;
692 a = nz; 929 a = nz;
693 break; 930 break;
694 case 0x6b: /* ARR #ab [unofficial] */
695 data = a & FETCH;
696 nz = a = (data >> 1) + (c << 7);
697 vdi = (vdi & (D_FLAG | I_FLAG)) + ((a ^ data) & V_FLAG);
698 if ((vdi & D_FLAG) == 0)
699 c = data >> 7;
700 else {
701 if ((data & 0xf) + (data & 1) > 5)
702 a = (a & 0xf0) + ((a + 6) & 0xf);
703 if (data + (data & 0x10) >= 0x60) {
704 a += 0x60;
705 c = 1;
706 }
707 else
708 c = 0;
709 a &= 0xff;
710 }
711 break;
712 case 0x6c: /* JMP (abcd) */ 931 case 0x6c: /* JMP (abcd) */
713 ABSOLUTE; 932 ABSOLUTE;
714 if ((addr & 0xff) == 0xff) 933 if ((addr & 0xff) == 0xff)
@@ -724,10 +943,6 @@ ASAP_FUNC void Cpu_RunScanlines(ASAP_State PTR ast, int scanlines)
724 ABSOLUTE; 943 ABSOLUTE;
725 ROR; 944 ROR;
726 break; 945 break;
727 case 0x6f: /* RRA abcd [unofficial] */
728 ABSOLUTE;
729 RRA;
730 break;
731 case 0x70: /* BVS */ 946 case 0x70: /* BVS */
732 BRANCH((vdi & V_FLAG) != 0); 947 BRANCH((vdi & V_FLAG) != 0);
733 case 0x71: /* ADC (ab),y */ 948 case 0x71: /* ADC (ab),y */
@@ -735,10 +950,6 @@ ASAP_FUNC void Cpu_RunScanlines(ASAP_State PTR ast, int scanlines)
735 NCYCLES_Y; 950 NCYCLES_Y;
736 ADC; 951 ADC;
737 break; 952 break;
738 case 0x73: /* RRA (ab),y [unofficial] */
739 INDIRECT_Y;
740 RRA;
741 break;
742 case 0x75: /* ADC ab,x */ 953 case 0x75: /* ADC ab,x */
743 ZPAGE_X; 954 ZPAGE_X;
744 ADC_ZP; 955 ADC_ZP;
@@ -747,10 +958,6 @@ ASAP_FUNC void Cpu_RunScanlines(ASAP_State PTR ast, int scanlines)
747 ZPAGE_X; 958 ZPAGE_X;
748 ROR_ZP; 959 ROR_ZP;
749 break; 960 break;
750 case 0x77: /* RRA ab,x [unofficial] */
751 ZPAGE_X;
752 RRA_ZP;
753 break;
754 case 0x78: /* SEI */ 961 case 0x78: /* SEI */
755 vdi |= I_FLAG; 962 vdi |= I_FLAG;
756 break; 963 break;
@@ -759,10 +966,6 @@ ASAP_FUNC void Cpu_RunScanlines(ASAP_State PTR ast, int scanlines)
759 NCYCLES_Y; 966 NCYCLES_Y;
760 ADC; 967 ADC;
761 break; 968 break;
762 case 0x7b: /* RRA abcd,y [unofficial] */
763 ABSOLUTE_Y;
764 RRA;
765 break;
766 case 0x7d: /* ADC abcd,x */ 969 case 0x7d: /* ADC abcd,x */
767 ABSOLUTE_X; 970 ABSOLUTE_X;
768 NCYCLES_X; 971 NCYCLES_X;
@@ -772,18 +975,10 @@ ASAP_FUNC void Cpu_RunScanlines(ASAP_State PTR ast, int scanlines)
772 ABSOLUTE_X; 975 ABSOLUTE_X;
773 ROR; 976 ROR;
774 break; 977 break;
775 case 0x7f: /* RRA abcd,x [unofficial] */
776 ABSOLUTE_X;
777 RRA;
778 break;
779 case 0x81: /* STA (ab,x) */ 978 case 0x81: /* STA (ab,x) */
780 INDIRECT_X; 979 INDIRECT_X;
781 STA; 980 STA;
782 break; 981 break;
783 case 0x83: /* SAX (ab,x) [unofficial] */
784 INDIRECT_X;
785 SAX;
786 break;
787 case 0x84: /* STY ab */ 982 case 0x84: /* STY ab */
788 ZPAGE; 983 ZPAGE;
789 STY_ZP; 984 STY_ZP;
@@ -796,22 +991,12 @@ ASAP_FUNC void Cpu_RunScanlines(ASAP_State PTR ast, int scanlines)
796 ZPAGE; 991 ZPAGE;
797 STX_ZP; 992 STX_ZP;
798 break; 993 break;
799 case 0x87: /* SAX ab [unofficial] */
800 ZPAGE;
801 SAX_ZP;
802 break;
803 case 0x88: /* DEY */ 994 case 0x88: /* DEY */
804 nz = y = (y - 1) & 0xff; 995 nz = y = (y - 1) & 0xff;
805 break; 996 break;
806 case 0x8a: /* TXA */ 997 case 0x8a: /* TXA */
807 nz = a = x; 998 nz = a = x;
808 break; 999 break;
809 case 0x8b: /* ANE #ab [unofficial] */
810 data = FETCH;
811 a &= x;
812 nz = a & data;
813 a &= data | 0xef;
814 break;
815 case 0x8c: /* STY abcd */ 1000 case 0x8c: /* STY abcd */
816 ABSOLUTE; 1001 ABSOLUTE;
817 STY; 1002 STY;
@@ -824,23 +1009,12 @@ ASAP_FUNC void Cpu_RunScanlines(ASAP_State PTR ast, int scanlines)
824 ABSOLUTE; 1009 ABSOLUTE;
825 STX; 1010 STX;
826 break; 1011 break;
827 case 0x8f: /* SAX abcd [unofficial] */
828 ABSOLUTE;
829 SAX;
830 break;
831 case 0x90: /* BCC */ 1012 case 0x90: /* BCC */
832 BRANCH(c == 0); 1013 BRANCH(c == 0);
833 case 0x91: /* STA (ab),y */ 1014 case 0x91: /* STA (ab),y */
834 INDIRECT_Y; 1015 INDIRECT_Y;
835 STA; 1016 STA;
836 break; 1017 break;
837 case 0x93: /* SHA (ab),y [unofficial, unstable] */
838 ZPAGE;
839 data = zGetByte(addr + 1);
840 addr = (dGetByte(addr) + (data << 8) + y) & 0xffff;
841 data = a & x & (data + 1);
842 PutByte(addr, data);
843 break;
844 case 0x94: /* STY ab,x */ 1018 case 0x94: /* STY ab,x */
845 ZPAGE_X; 1019 ZPAGE_X;
846 STY_ZP; 1020 STY_ZP;
@@ -853,10 +1027,6 @@ ASAP_FUNC void Cpu_RunScanlines(ASAP_State PTR ast, int scanlines)
853 ZPAGE_Y; 1027 ZPAGE_Y;
854 STX_ZP; 1028 STX_ZP;
855 break; 1029 break;
856 case 0x97: /* SAX ab,y [unofficial] */
857 ZPAGE_Y;
858 SAX_ZP;
859 break;
860 case 0x98: /* TYA */ 1030 case 0x98: /* TYA */
861 nz = a = y; 1031 nz = a = y;
862 break; 1032 break;
@@ -867,40 +1037,10 @@ ASAP_FUNC void Cpu_RunScanlines(ASAP_State PTR ast, int scanlines)
867 case 0x9a: /* TXS */ 1037 case 0x9a: /* TXS */
868 s = x; 1038 s = x;
869 break; 1039 break;
870 case 0x9b: /* SHS abcd,y [unofficial, unstable] */
871 /* S seems to be stable, only memory values vary */
872 addr = FETCH;
873 data = FETCH;
874 addr = (addr + (data << 8) + y) & 0xffff;
875 s = a & x;
876 data = s & (data + 1);
877 PutByte(addr, data);
878 break;
879 case 0x9c: /* SHY abcd,x [unofficial] */
880 addr = FETCH;
881 data = FETCH;
882 addr = (addr + (data << 8) + x) & 0xffff;
883 data = y & (data + 1);
884 PutByte(addr, data);
885 break;
886 case 0x9d: /* STA abcd,x */ 1040 case 0x9d: /* STA abcd,x */
887 ABSOLUTE_X; 1041 ABSOLUTE_X;
888 STA; 1042 STA;
889 break; 1043 break;
890 case 0x9e: /* SHX abcd,y [unofficial] */
891 addr = FETCH;
892 data = FETCH;
893 addr = (addr + (data << 8) + y) & 0xffff;
894 data = x & (data + 1);
895 PutByte(addr, data);
896 break;
897 case 0x9f: /* SHA abcd,y [unofficial, unstable] */
898 addr = FETCH;
899 data = FETCH;
900 addr = (addr + (data << 8) + y) & 0xffff;
901 data = a & x & (data + 1);
902 PutByte(addr, data);
903 break;
904 case 0xa0: /* LDY #ab */ 1044 case 0xa0: /* LDY #ab */
905 nz = y = FETCH; 1045 nz = y = FETCH;
906 break; 1046 break;
@@ -911,10 +1051,6 @@ ASAP_FUNC void Cpu_RunScanlines(ASAP_State PTR ast, int scanlines)
911 case 0xa2: /* LDX #ab */ 1051 case 0xa2: /* LDX #ab */
912 nz = x = FETCH; 1052 nz = x = FETCH;
913 break; 1053 break;
914 case 0xa3: /* LAX (ab,x) [unofficial] */
915 INDIRECT_X;
916 LAX;
917 break;
918 case 0xa4: /* LDY ab */ 1054 case 0xa4: /* LDY ab */
919 ZPAGE; 1055 ZPAGE;
920 LDY_ZP; 1056 LDY_ZP;
@@ -927,10 +1063,6 @@ ASAP_FUNC void Cpu_RunScanlines(ASAP_State PTR ast, int scanlines)
927 ZPAGE; 1063 ZPAGE;
928 LDX_ZP; 1064 LDX_ZP;
929 break; 1065 break;
930 case 0xa7: /* LAX ab [unofficial] */
931 ZPAGE;
932 LAX_ZP;
933 break;
934 case 0xa8: /* TAY */ 1066 case 0xa8: /* TAY */
935 nz = y = a; 1067 nz = y = a;
936 break; 1068 break;
@@ -940,9 +1072,6 @@ ASAP_FUNC void Cpu_RunScanlines(ASAP_State PTR ast, int scanlines)
940 case 0xaa: /* TAX */ 1072 case 0xaa: /* TAX */
941 nz = x = a; 1073 nz = x = a;
942 break; 1074 break;
943 case 0xab: /* ANX #ab [unofficial] */
944 nz = x = a &= FETCH;
945 break;
946 case 0xac: /* LDY abcd */ 1075 case 0xac: /* LDY abcd */
947 ABSOLUTE; 1076 ABSOLUTE;
948 LDY; 1077 LDY;
@@ -955,10 +1084,6 @@ ASAP_FUNC void Cpu_RunScanlines(ASAP_State PTR ast, int scanlines)
955 ABSOLUTE; 1084 ABSOLUTE;
956 LDX; 1085 LDX;
957 break; 1086 break;
958 case 0xaf: /* LAX abcd [unofficial] */
959 ABSOLUTE;
960 LAX;
961 break;
962 case 0xb0: /* BCS */ 1087 case 0xb0: /* BCS */
963 BRANCH(c != 0); 1088 BRANCH(c != 0);
964 case 0xb1: /* LDA (ab),y */ 1089 case 0xb1: /* LDA (ab),y */
@@ -966,11 +1091,6 @@ ASAP_FUNC void Cpu_RunScanlines(ASAP_State PTR ast, int scanlines)
966 NCYCLES_Y; 1091 NCYCLES_Y;
967 LDA; 1092 LDA;
968 break; 1093 break;
969 case 0xb3: /* LAX (ab),y [unofficial] */
970 INDIRECT_Y;
971 NCYCLES_Y;
972 LAX;
973 break;
974 case 0xb4: /* LDY ab,x */ 1094 case 0xb4: /* LDY ab,x */
975 ZPAGE_X; 1095 ZPAGE_X;
976 LDY_ZP; 1096 LDY_ZP;
@@ -983,10 +1103,6 @@ ASAP_FUNC void Cpu_RunScanlines(ASAP_State PTR ast, int scanlines)
983 ZPAGE_Y; 1103 ZPAGE_Y;
984 LDX_ZP; 1104 LDX_ZP;
985 break; 1105 break;
986 case 0xb7: /* LAX ab,y [unofficial] */
987 ZPAGE_Y;
988 LAX_ZP;
989 break;
990 case 0xb8: /* CLV */ 1106 case 0xb8: /* CLV */
991 vdi &= D_FLAG | I_FLAG; 1107 vdi &= D_FLAG | I_FLAG;
992 break; 1108 break;
@@ -998,11 +1114,6 @@ ASAP_FUNC void Cpu_RunScanlines(ASAP_State PTR ast, int scanlines)
998 case 0xba: /* TSX */ 1114 case 0xba: /* TSX */
999 nz = x = s; 1115 nz = x = s;
1000 break; 1116 break;
1001 case 0xbb: /* LAS abcd,y [unofficial] */
1002 ABSOLUTE_Y;
1003 NCYCLES_Y;
1004 nz = x = a = s &= GetByte(addr);
1005 break;
1006 case 0xbc: /* LDY abcd,x */ 1117 case 0xbc: /* LDY abcd,x */
1007 ABSOLUTE_X; 1118 ABSOLUTE_X;
1008 NCYCLES_X; 1119 NCYCLES_X;
@@ -1018,11 +1129,6 @@ ASAP_FUNC void Cpu_RunScanlines(ASAP_State PTR ast, int scanlines)
1018 NCYCLES_Y; 1129 NCYCLES_Y;
1019 LDX; 1130 LDX;
1020 break; 1131 break;
1021 case 0xbf: /* LAX abcd,y [unofficial] */
1022 ABSOLUTE_Y;
1023 NCYCLES_Y;
1024 LAX;
1025 break;
1026 case 0xc0: /* CPY #ab */ 1132 case 0xc0: /* CPY #ab */
1027 nz = FETCH; 1133 nz = FETCH;
1028 c = (y >= nz) ? 1 : 0; 1134 c = (y >= nz) ? 1 : 0;
@@ -1032,10 +1138,6 @@ ASAP_FUNC void Cpu_RunScanlines(ASAP_State PTR ast, int scanlines)
1032 INDIRECT_X; 1138 INDIRECT_X;
1033 CMP; 1139 CMP;
1034 break; 1140 break;
1035 case 0xc3: /* DCM (ab,x) [unofficial] */
1036 INDIRECT_X;
1037 DCM;
1038 break;
1039 case 0xc4: /* CPY ab */ 1141 case 0xc4: /* CPY ab */
1040 ZPAGE; 1142 ZPAGE;
1041 CPY_ZP; 1143 CPY_ZP;
@@ -1048,10 +1150,6 @@ ASAP_FUNC void Cpu_RunScanlines(ASAP_State PTR ast, int scanlines)
1048 ZPAGE; 1150 ZPAGE;
1049 DEC_ZP; 1151 DEC_ZP;
1050 break; 1152 break;
1051 case 0xc7: /* DCM ab [unofficial] */
1052 ZPAGE;
1053 DCM_ZP;
1054 break;
1055 case 0xc8: /* INY */ 1153 case 0xc8: /* INY */
1056 nz = y = (y + 1) & 0xff; 1154 nz = y = (y + 1) & 0xff;
1057 break; 1155 break;
@@ -1063,12 +1161,6 @@ ASAP_FUNC void Cpu_RunScanlines(ASAP_State PTR ast, int scanlines)
1063 case 0xca: /* DEX */ 1161 case 0xca: /* DEX */
1064 nz = x = (x - 1) & 0xff; 1162 nz = x = (x - 1) & 0xff;
1065 break; 1163 break;
1066 case 0xcb: /* SBX #ab [unofficial] */
1067 nz = FETCH;
1068 x &= a;
1069 c = (x >= nz) ? 1 : 0;
1070 nz = x = (x - nz) & 0xff;
1071 break;
1072 case 0xcc: /* CPY abcd */ 1164 case 0xcc: /* CPY abcd */
1073 ABSOLUTE; 1165 ABSOLUTE;
1074 CPY; 1166 CPY;
@@ -1081,10 +1173,6 @@ ASAP_FUNC void Cpu_RunScanlines(ASAP_State PTR ast, int scanlines)
1081 ABSOLUTE; 1173 ABSOLUTE;
1082 DEC; 1174 DEC;
1083 break; 1175 break;
1084 case 0xcf: /* DCM abcd [unofficial] */
1085 ABSOLUTE;
1086 DCM;
1087 break;
1088 case 0xd0: /* BNE */ 1176 case 0xd0: /* BNE */
1089 BRANCH((nz & 0xff) != 0); 1177 BRANCH((nz & 0xff) != 0);
1090 case 0xd1: /* CMP (ab),y */ 1178 case 0xd1: /* CMP (ab),y */
@@ -1092,10 +1180,6 @@ ASAP_FUNC void Cpu_RunScanlines(ASAP_State PTR ast, int scanlines)
1092 NCYCLES_Y; 1180 NCYCLES_Y;
1093 CMP; 1181 CMP;
1094 break; 1182 break;
1095 case 0xd3: /* DCM (ab),y [unofficial] */
1096 INDIRECT_Y;
1097 DCM;
1098 break;
1099 case 0xd5: /* CMP ab,x */ 1183 case 0xd5: /* CMP ab,x */
1100 ZPAGE_X; 1184 ZPAGE_X;
1101 CMP_ZP; 1185 CMP_ZP;
@@ -1104,10 +1188,6 @@ ASAP_FUNC void Cpu_RunScanlines(ASAP_State PTR ast, int scanlines)
1104 ZPAGE_X; 1188 ZPAGE_X;
1105 DEC_ZP; 1189 DEC_ZP;
1106 break; 1190 break;
1107 case 0xd7: /* DCM ab,x [unofficial] */
1108 ZPAGE_X;
1109 DCM_ZP;
1110 break;
1111 case 0xd8: /* CLD */ 1191 case 0xd8: /* CLD */
1112 vdi &= V_FLAG | I_FLAG; 1192 vdi &= V_FLAG | I_FLAG;
1113 break; 1193 break;
@@ -1116,10 +1196,6 @@ ASAP_FUNC void Cpu_RunScanlines(ASAP_State PTR ast, int scanlines)
1116 NCYCLES_Y; 1196 NCYCLES_Y;
1117 CMP; 1197 CMP;
1118 break; 1198 break;
1119 case 0xdb: /* DCM abcd,y [unofficial] */
1120 ABSOLUTE_Y;
1121 DCM;
1122 break;
1123 case 0xdd: /* CMP abcd,x */ 1199 case 0xdd: /* CMP abcd,x */
1124 ABSOLUTE_X; 1200 ABSOLUTE_X;
1125 NCYCLES_X; 1201 NCYCLES_X;
@@ -1129,10 +1205,6 @@ ASAP_FUNC void Cpu_RunScanlines(ASAP_State PTR ast, int scanlines)
1129 ABSOLUTE_X; 1205 ABSOLUTE_X;
1130 DEC; 1206 DEC;
1131 break; 1207 break;
1132 case 0xdf: /* DCM abcd,x [unofficial] */
1133 ABSOLUTE_X;
1134 DCM;
1135 break;
1136 case 0xe0: /* CPX #ab */ 1208 case 0xe0: /* CPX #ab */
1137 nz = FETCH; 1209 nz = FETCH;
1138 c = (x >= nz) ? 1 : 0; 1210 c = (x >= nz) ? 1 : 0;
@@ -1142,10 +1214,6 @@ ASAP_FUNC void Cpu_RunScanlines(ASAP_State PTR ast, int scanlines)
1142 INDIRECT_X; 1214 INDIRECT_X;
1143 SBC; 1215 SBC;
1144 break; 1216 break;
1145 case 0xe3: /* INS (ab,x) [unofficial] */
1146 INDIRECT_X;
1147 INS;
1148 break;
1149 case 0xe4: /* CPX ab */ 1217 case 0xe4: /* CPX ab */
1150 ZPAGE; 1218 ZPAGE;
1151 CPX_ZP; 1219 CPX_ZP;
@@ -1158,10 +1226,6 @@ ASAP_FUNC void Cpu_RunScanlines(ASAP_State PTR ast, int scanlines)
1158 ZPAGE; 1226 ZPAGE;
1159 INC_ZP; 1227 INC_ZP;
1160 break; 1228 break;
1161 case 0xe7: /* INS ab [unofficial] */
1162 ZPAGE;
1163 INS_ZP;
1164 break;
1165 case 0xe8: /* INX */ 1229 case 0xe8: /* INX */
1166 nz = x = (x + 1) & 0xff; 1230 nz = x = (x + 1) & 0xff;
1167 break; 1231 break;
@@ -1190,10 +1254,6 @@ ASAP_FUNC void Cpu_RunScanlines(ASAP_State PTR ast, int scanlines)
1190 ABSOLUTE; 1254 ABSOLUTE;
1191 INC; 1255 INC;
1192 break; 1256 break;
1193 case 0xef: /* INS abcd [unofficial] */
1194 ABSOLUTE;
1195 INS;
1196 break;
1197 case 0xf0: /* BEQ */ 1257 case 0xf0: /* BEQ */
1198 BRANCH((nz & 0xff) == 0); 1258 BRANCH((nz & 0xff) == 0);
1199 case 0xf1: /* SBC (ab),y */ 1259 case 0xf1: /* SBC (ab),y */
@@ -1201,10 +1261,6 @@ ASAP_FUNC void Cpu_RunScanlines(ASAP_State PTR ast, int scanlines)
1201 NCYCLES_Y; 1261 NCYCLES_Y;
1202 SBC; 1262 SBC;
1203 break; 1263 break;
1204 case 0xf3: /* INS (ab),y [unofficial] */
1205 INDIRECT_Y;
1206 INS;
1207 break;
1208 case 0xf5: /* SBC ab,x */ 1264 case 0xf5: /* SBC ab,x */
1209 ZPAGE_X; 1265 ZPAGE_X;
1210 SBC_ZP; 1266 SBC_ZP;
@@ -1213,10 +1269,6 @@ ASAP_FUNC void Cpu_RunScanlines(ASAP_State PTR ast, int scanlines)
1213 ZPAGE_X; 1269 ZPAGE_X;
1214 INC_ZP; 1270 INC_ZP;
1215 break; 1271 break;
1216 case 0xf7: /* INS ab,x [unofficial] */
1217 ZPAGE_X;
1218 INS_ZP;
1219 break;
1220 case 0xf8: /* SED */ 1272 case 0xf8: /* SED */
1221 vdi |= D_FLAG; 1273 vdi |= D_FLAG;
1222 break; 1274 break;
@@ -1225,10 +1277,6 @@ ASAP_FUNC void Cpu_RunScanlines(ASAP_State PTR ast, int scanlines)
1225 NCYCLES_Y; 1277 NCYCLES_Y;
1226 SBC; 1278 SBC;
1227 break; 1279 break;
1228 case 0xfb: /* INS abcd,y [unofficial] */
1229 ABSOLUTE_Y;
1230 INS;
1231 break;
1232 case 0xfd: /* SBC abcd,x */ 1280 case 0xfd: /* SBC abcd,x */
1233 ABSOLUTE_X; 1281 ABSOLUTE_X;
1234 NCYCLES_X; 1282 NCYCLES_X;
@@ -1238,25 +1286,21 @@ ASAP_FUNC void Cpu_RunScanlines(ASAP_State PTR ast, int scanlines)
1238 ABSOLUTE_X; 1286 ABSOLUTE_X;
1239 INC; 1287 INC;
1240 break; 1288 break;
1241 case 0xff: /* INS abcd,x */
1242 ABSOLUTE_X;
1243 INS;
1244 break;
1245 } 1289 }
1246 } 1290 }
1247 AST cpu_pc = pc; 1291 ast _ cpu_pc = pc;
1248 AST cpu_nz = nz; 1292 ast _ cpu_nz = nz;
1249 AST cpu_a = a; 1293 ast _ cpu_a = a;
1250 AST cpu_x = x; 1294 ast _ cpu_x = x;
1251 AST cpu_y = y; 1295 ast _ cpu_y = y;
1252 AST cpu_c = c; 1296 ast _ cpu_c = c;
1253 AST cpu_s = s; 1297 ast _ cpu_s = s;
1254 AST cpu_vdi = vdi; 1298 ast _ cpu_vdi = vdi;
1255 AST cycle -= cycle_limit; 1299 ast _ cycle -= cycle_limit;
1256 if (AST timer1_cycle != NEVER) 1300 if (ast _ timer1_cycle != NEVER)
1257 AST timer1_cycle -= cycle_limit; 1301 ast _ timer1_cycle -= cycle_limit;
1258 if (AST timer2_cycle != NEVER) 1302 if (ast _ timer2_cycle != NEVER)
1259 AST timer2_cycle -= cycle_limit; 1303 ast _ timer2_cycle -= cycle_limit;
1260 if (AST timer4_cycle != NEVER) 1304 if (ast _ timer4_cycle != NEVER)
1261 AST timer4_cycle -= cycle_limit; 1305 ast _ timer4_cycle -= cycle_limit;
1262} 1306}