ViewVC Help
View File | Revision Log | Show Annotations | Revision Graph | Root Listing
root/cebix/Frodo4/Src/CPU_emulline.h
Revision: 1.1
Committed: 2003-07-01T17:16:21Z (19 years, 7 months ago) by cebix
Content type: text/plain
Branch: MAIN
Log Message:
imported files

File Contents

# User Rev Content
1 cebix 1.1 /*
2     * CPU_emulline.i - 6510/6502 emulation core (body of
3     * EmulateLine() function, the same for
4     * both 6510 and 6502)
5     *
6     * Frodo (C) 1994-1997,2002 Christian Bauer
7     *
8     * This program is free software; you can redistribute it and/or modify
9     * it under the terms of the GNU General Public License as published by
10     * the Free Software Foundation; either version 2 of the License, or
11     * (at your option) any later version.
12     *
13     * This program is distributed in the hope that it will be useful,
14     * but WITHOUT ANY WARRANTY; without even the implied warranty of
15     * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
16     * GNU General Public License for more details.
17     *
18     * You should have received a copy of the GNU General Public License
19     * along with this program; if not, write to the Free Software
20     * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
21     */
22    
23    
24     /*
25     * Addressing mode macros
26     */
27    
28     // Read immediate operand
29     #if PC_IS_POINTER
30     #define read_byte_imm() (*pc++)
31     #else
32     #define read_byte_imm() read_byte(pc++)
33     #endif
34    
35     // Read zeropage operand address
36     #define read_adr_zero() ((uint16)read_byte_imm())
37    
38     // Read zeropage x-indexed operand address
39     #define read_adr_zero_x() ((read_byte_imm() + x) & 0xff)
40    
41     // Read zeropage y-indexed operand address
42     #define read_adr_zero_y() ((read_byte_imm() + y) & 0xff)
43    
44     // Read absolute operand address (uses adr!)
45     #if PC_IS_POINTER
46     #if LITTLE_ENDIAN_UNALIGNED
47     #define read_adr_abs() (adr = *(UWORD *)pc, pc+=2, adr)
48     #else
49     #define read_adr_abs() (adr = ((*(pc+1)) << 8) | *pc, pc+=2, adr)
50     #endif
51     #else
52     #define read_adr_abs() (adr = read_word(pc), pc+=2, adr)
53     #endif
54    
55     // Read absolute x-indexed operand address
56     #define read_adr_abs_x() (read_adr_abs() + x)
57    
58     // Read absolute y-indexed operand address
59     #define read_adr_abs_y() (read_adr_abs() + y)
60    
61     // Read indexed indirect operand address
62     #define read_adr_ind_x() (read_zp_word(read_byte_imm() + x))
63    
64     // Read indirect indexed operand address
65     #define read_adr_ind_y() (read_zp_word(read_byte_imm()) + y)
66    
67     // Read zeropage operand
68     #define read_byte_zero() read_zp(read_adr_zero())
69    
70     // Read zeropage x-indexed operand
71     #define read_byte_zero_x() read_zp(read_adr_zero_x())
72    
73     // Read zeropage y-indexed operand
74     #define read_byte_zero_y() read_zp(read_adr_zero_y())
75    
76     // Read absolute operand
77     #define read_byte_abs() read_byte(read_adr_abs())
78    
79     #if PRECISE_CPU_CYCLES
80     // Acount for cyles due to crossing page boundaries
81     #define page_plus(exp, reg) \
82     (adr = exp, page_cycles = (adr & 0xff) + reg >= 0x100, adr + reg)
83    
84     // Read absolute x-indexed operand
85     #define read_byte_abs_x() read_byte(page_plus(read_adr_abs(), x))
86    
87     // Read absolute x-indexed operand
88     #define read_byte_abs_y() read_byte(page_plus(read_adr_abs(), y))
89    
90     // Read indirect y-indexed operand
91     #define read_byte_ind_y() read_byte(page_plus(read_zp_word(read_byte_imm()), y))
92    
93     #else
94    
95     // Read absolute x-indexed operand
96     #define read_byte_abs_x() read_byte(read_adr_abs_x())
97    
98     // Read absolute x-indexed operand
99     #define read_byte_abs_y() read_byte(read_adr_abs_y())
100    
101     // Read indirect y-indexed operand
102     #define read_byte_ind_y() read_byte(read_adr_ind_y())
103     #endif
104    
105     // Read indexed indirect operand
106     #define read_byte_ind_x() read_byte(read_adr_ind_x())
107    
108    
109     /*
110     * Set N and Z flags according to byte
111     */
112    
113     #define set_nz(x) (z_flag = n_flag = (x))
114    
115    
116     /*
117     * End of opcode, decrement cycles left
118     */
119    
120     #define ENDOP(cyc) last_cycles = cyc; break;
121    
122    
123     // Main opcode fetch/execute loop
124     #if PRECISE_CPU_CYCLES
125     if (cycles_left != 1)
126     cycles_left -= borrowed_cycles;
127     int page_cycles = 0;
128     for (;;) {
129     if (last_cycles) {
130     last_cycles += page_cycles;
131     page_cycles = 0;
132     #if PRECISE_CIA_CYCLES && !defined(IS_CPU_1541)
133     TheCIA1->EmulateLine(last_cycles);
134     TheCIA2->EmulateLine(last_cycles);
135     #endif
136     }
137     if ((cycles_left -= last_cycles) < 0) {
138     borrowed_cycles = -cycles_left;
139     break;
140     }
141     #else
142     while ((cycles_left -= last_cycles) >= 0) {
143     #endif
144    
145     switch (read_byte_imm()) {
146    
147    
148     // Load group
149     case 0xa9: // LDA #imm
150     set_nz(a = read_byte_imm());
151     ENDOP(2);
152    
153     case 0xa5: // LDA zero
154     set_nz(a = read_byte_zero());
155     ENDOP(3);
156    
157     case 0xb5: // LDA zero,X
158     set_nz(a = read_byte_zero_x());
159     ENDOP(4);
160    
161     case 0xad: // LDA abs
162     set_nz(a = read_byte_abs());
163     ENDOP(4);
164    
165     case 0xbd: // LDA abs,X
166     set_nz(a = read_byte_abs_x());
167     ENDOP(4);
168    
169     case 0xb9: // LDA abs,Y
170     set_nz(a = read_byte_abs_y());
171     ENDOP(4);
172    
173     case 0xa1: // LDA (ind,X)
174     set_nz(a = read_byte_ind_x());
175     ENDOP(6);
176    
177     case 0xb1: // LDA (ind),Y
178     set_nz(a = read_byte_ind_y());
179     ENDOP(5);
180    
181     case 0xa2: // LDX #imm
182     set_nz(x = read_byte_imm());
183     ENDOP(2);
184    
185     case 0xa6: // LDX zero
186     set_nz(x = read_byte_zero());
187     ENDOP(3);
188    
189     case 0xb6: // LDX zero,Y
190     set_nz(x = read_byte_zero_y());
191     ENDOP(4);
192    
193     case 0xae: // LDX abs
194     set_nz(x = read_byte_abs());
195     ENDOP(4);
196    
197     case 0xbe: // LDX abs,Y
198     set_nz(x = read_byte_abs_y());
199     ENDOP(4);
200    
201     case 0xa0: // LDY #imm
202     set_nz(y = read_byte_imm());
203     ENDOP(2);
204    
205     case 0xa4: // LDY zero
206     set_nz(y = read_byte_zero());
207     ENDOP(3);
208    
209     case 0xb4: // LDY zero,X
210     set_nz(y = read_byte_zero_x());
211     ENDOP(4);
212    
213     case 0xac: // LDY abs
214     set_nz(y = read_byte_abs());
215     ENDOP(4);
216    
217     case 0xbc: // LDY abs,X
218     set_nz(y = read_byte_abs_x());
219     ENDOP(4);
220    
221    
222     // Store group
223     case 0x85: // STA zero
224     write_byte(read_adr_zero(), a);
225     ENDOP(3);
226    
227     case 0x95: // STA zero,X
228     write_byte(read_adr_zero_x(), a);
229     ENDOP(4);
230    
231     case 0x8d: // STA abs
232     write_byte(read_adr_abs(), a);
233     ENDOP(4);
234    
235     case 0x9d: // STA abs,X
236     write_byte(read_adr_abs_x(), a);
237     ENDOP(5);
238    
239     case 0x99: // STA abs,Y
240     write_byte(read_adr_abs_y(), a);
241     ENDOP(5);
242    
243     case 0x81: // STA (ind,X)
244     write_byte(read_adr_ind_x(), a);
245     ENDOP(6);
246    
247     case 0x91: // STA (ind),Y
248     write_byte(read_adr_ind_y(), a);
249     ENDOP(6);
250    
251     case 0x86: // STX zero
252     write_byte(read_adr_zero(), x);
253     ENDOP(3);
254    
255     case 0x96: // STX zero,Y
256     write_byte(read_adr_zero_y(), x);
257     ENDOP(4);
258    
259     case 0x8e: // STX abs
260     write_byte(read_adr_abs(), x);
261     ENDOP(4);
262    
263     case 0x84: // STY zero
264     write_byte(read_adr_zero(), y);
265     ENDOP(3);
266    
267     case 0x94: // STY zero,X
268     write_byte(read_adr_zero_x(), y);
269     ENDOP(4);
270    
271     case 0x8c: // STY abs
272     write_byte(read_adr_abs(), y);
273     ENDOP(4);
274    
275    
276     // Transfer group
277     case 0xaa: // TAX
278     set_nz(x = a);
279     ENDOP(2);
280    
281     case 0x8a: // TXA
282     set_nz(a = x);
283     ENDOP(2);
284    
285     case 0xa8: // TAY
286     set_nz(y = a);
287     ENDOP(2);
288    
289     case 0x98: // TYA
290     set_nz(a = y);
291     ENDOP(2);
292    
293     case 0xba: // TSX
294     set_nz(x = sp);
295     ENDOP(2);
296    
297     case 0x9a: // TXS
298     sp = x;
299     ENDOP(2);
300    
301    
302     // Arithmetic group
303     case 0x69: // ADC #imm
304     do_adc(read_byte_imm());
305     ENDOP(2);
306    
307     case 0x65: // ADC zero
308     do_adc(read_byte_zero());
309     ENDOP(3);
310    
311     case 0x75: // ADC zero,X
312     do_adc(read_byte_zero_x());
313     ENDOP(4);
314    
315     case 0x6d: // ADC abs
316     do_adc(read_byte_abs());
317     ENDOP(4);
318    
319     case 0x7d: // ADC abs,X
320     do_adc(read_byte_abs_x());
321     ENDOP(4);
322    
323     case 0x79: // ADC abs,Y
324     do_adc(read_byte_abs_y());
325     ENDOP(4);
326    
327     case 0x61: // ADC (ind,X)
328     do_adc(read_byte_ind_x());
329     ENDOP(6);
330    
331     case 0x71: // ADC (ind),Y
332     do_adc(read_byte_ind_y());
333     ENDOP(5);
334    
335     case 0xe9: // SBC #imm
336     case 0xeb: // Undocumented opcode
337     do_sbc(read_byte_imm());
338     ENDOP(2);
339    
340     case 0xe5: // SBC zero
341     do_sbc(read_byte_zero());
342     ENDOP(3);
343    
344     case 0xf5: // SBC zero,X
345     do_sbc(read_byte_zero_x());
346     ENDOP(4);
347    
348     case 0xed: // SBC abs
349     do_sbc(read_byte_abs());
350     ENDOP(4);
351    
352     case 0xfd: // SBC abs,X
353     do_sbc(read_byte_abs_x());
354     ENDOP(4);
355    
356     case 0xf9: // SBC abs,Y
357     do_sbc(read_byte_abs_y());
358     ENDOP(4);
359    
360     case 0xe1: // SBC (ind,X)
361     do_sbc(read_byte_ind_x());
362     ENDOP(6);
363    
364     case 0xf1: // SBC (ind),Y
365     do_sbc(read_byte_ind_y());
366     ENDOP(5);
367    
368    
369     // Increment/decrement group
370     case 0xe8: // INX
371     set_nz(++x);
372     ENDOP(2);
373    
374     case 0xca: // DEX
375     set_nz(--x);
376     ENDOP(2);
377    
378     case 0xc8: // INY
379     set_nz(++y);
380     ENDOP(2);
381    
382     case 0x88: // DEY
383     set_nz(--y);
384     ENDOP(2);
385    
386     case 0xe6: // INC zero
387     adr = read_adr_zero();
388     write_zp(adr, set_nz(read_zp(adr) + 1));
389     ENDOP(5);
390    
391     case 0xf6: // INC zero,X
392     adr = read_adr_zero_x();
393     write_zp(adr, set_nz(read_zp(adr) + 1));
394     ENDOP(6);
395    
396     case 0xee: // INC abs
397     adr = read_adr_abs();
398     write_byte(adr, set_nz(read_byte(adr) + 1));
399     ENDOP(6);
400    
401     case 0xfe: // INC abs,X
402     adr = read_adr_abs_x();
403     write_byte(adr, set_nz(read_byte(adr) + 1));
404     ENDOP(7);
405    
406     case 0xc6: // DEC zero
407     adr = read_adr_zero();
408     write_zp(adr, set_nz(read_zp(adr) - 1));
409     ENDOP(5);
410    
411     case 0xd6: // DEC zero,X
412     adr = read_adr_zero_x();
413     write_zp(adr, set_nz(read_zp(adr) - 1));
414     ENDOP(6);
415    
416     case 0xce: // DEC abs
417     adr = read_adr_abs();
418     write_byte(adr, set_nz(read_byte(adr) - 1));
419     ENDOP(6);
420    
421     case 0xde: // DEC abs,X
422     adr = read_adr_abs_x();
423     write_byte(adr, set_nz(read_byte(adr) - 1));
424     ENDOP(7);
425    
426    
427     // Logic group
428     case 0x29: // AND #imm
429     set_nz(a &= read_byte_imm());
430     ENDOP(2);
431    
432     case 0x25: // AND zero
433     set_nz(a &= read_byte_zero());
434     ENDOP(3);
435    
436     case 0x35: // AND zero,X
437     set_nz(a &= read_byte_zero_x());
438     ENDOP(4);
439    
440     case 0x2d: // AND abs
441     set_nz(a &= read_byte_abs());
442     ENDOP(4);
443    
444     case 0x3d: // AND abs,X
445     set_nz(a &= read_byte_abs_x());
446     ENDOP(4);
447    
448     case 0x39: // AND abs,Y
449     set_nz(a &= read_byte_abs_y());
450     ENDOP(4);
451    
452     case 0x21: // AND (ind,X)
453     set_nz(a &= read_byte_ind_x());
454     ENDOP(6);
455    
456     case 0x31: // AND (ind),Y
457     set_nz(a &= read_byte_ind_y());
458     ENDOP(5);
459    
460     case 0x09: // ORA #imm
461     set_nz(a |= read_byte_imm());
462     ENDOP(2);
463    
464     case 0x05: // ORA zero
465     set_nz(a |= read_byte_zero());
466     ENDOP(3);
467    
468     case 0x15: // ORA zero,X
469     set_nz(a |= read_byte_zero_x());
470     ENDOP(4);
471    
472     case 0x0d: // ORA abs
473     set_nz(a |= read_byte_abs());
474     ENDOP(4);
475    
476     case 0x1d: // ORA abs,X
477     set_nz(a |= read_byte_abs_x());
478     ENDOP(4);
479    
480     case 0x19: // ORA abs,Y
481     set_nz(a |= read_byte_abs_y());
482     ENDOP(4);
483    
484     case 0x01: // ORA (ind,X)
485     set_nz(a |= read_byte_ind_x());
486     ENDOP(6);
487    
488     case 0x11: // ORA (ind),Y
489     set_nz(a |= read_byte_ind_y());
490     ENDOP(5);
491    
492     case 0x49: // EOR #imm
493     set_nz(a ^= read_byte_imm());
494     ENDOP(2);
495    
496     case 0x45: // EOR zero
497     set_nz(a ^= read_byte_zero());
498     ENDOP(3);
499    
500     case 0x55: // EOR zero,X
501     set_nz(a ^= read_byte_zero_x());
502     ENDOP(4);
503    
504     case 0x4d: // EOR abs
505     set_nz(a ^= read_byte_abs());
506     ENDOP(4);
507    
508     case 0x5d: // EOR abs,X
509     set_nz(a ^= read_byte_abs_x());
510     ENDOP(4);
511    
512     case 0x59: // EOR abs,Y
513     set_nz(a ^= read_byte_abs_y());
514     ENDOP(4);
515    
516     case 0x41: // EOR (ind,X)
517     set_nz(a ^= read_byte_ind_x());
518     ENDOP(6);
519    
520     case 0x51: // EOR (ind),Y
521     set_nz(a ^= read_byte_ind_y());
522     ENDOP(5);
523    
524    
525     // Compare group
526     case 0xc9: // CMP #imm
527     set_nz(adr = a - read_byte_imm());
528     c_flag = adr < 0x100;
529     ENDOP(2);
530    
531     case 0xc5: // CMP zero
532     set_nz(adr = a - read_byte_zero());
533     c_flag = adr < 0x100;
534     ENDOP(3);
535    
536     case 0xd5: // CMP zero,X
537     set_nz(adr = a - read_byte_zero_x());
538     c_flag = adr < 0x100;
539     ENDOP(4);
540    
541     case 0xcd: // CMP abs
542     set_nz(adr = a - read_byte_abs());
543     c_flag = adr < 0x100;
544     ENDOP(4);
545    
546     case 0xdd: // CMP abs,X
547     set_nz(adr = a - read_byte_abs_x());
548     c_flag = adr < 0x100;
549     ENDOP(4);
550    
551     case 0xd9: // CMP abs,Y
552     set_nz(adr = a - read_byte_abs_y());
553     c_flag = adr < 0x100;
554     ENDOP(4);
555    
556     case 0xc1: // CMP (ind,X)
557     set_nz(adr = a - read_byte_ind_x());
558     c_flag = adr < 0x100;
559     ENDOP(6);
560    
561     case 0xd1: // CMP (ind),Y
562     set_nz(adr = a - read_byte_ind_y());
563     c_flag = adr < 0x100;
564     ENDOP(5);
565    
566     case 0xe0: // CPX #imm
567     set_nz(adr = x - read_byte_imm());
568     c_flag = adr < 0x100;
569     ENDOP(2);
570    
571     case 0xe4: // CPX zero
572     set_nz(adr = x - read_byte_zero());
573     c_flag = adr < 0x100;
574     ENDOP(3);
575    
576     case 0xec: // CPX abs
577     set_nz(adr = x - read_byte_abs());
578     c_flag = adr < 0x100;
579     ENDOP(4);
580    
581     case 0xc0: // CPY #imm
582     set_nz(adr = y - read_byte_imm());
583     c_flag = adr < 0x100;
584     ENDOP(2);
585    
586     case 0xc4: // CPY zero
587     set_nz(adr = y - read_byte_zero());
588     c_flag = adr < 0x100;
589     ENDOP(3);
590    
591     case 0xcc: // CPY abs
592     set_nz(adr = y - read_byte_abs());
593     c_flag = adr < 0x100;
594     ENDOP(4);
595    
596    
597     // Bit-test group
598     case 0x24: // BIT zero
599     z_flag = a & (tmp = read_byte_zero());
600     n_flag = tmp;
601     v_flag = tmp & 0x40;
602     ENDOP(3);
603    
604     case 0x2c: // BIT abs
605     z_flag = a & (tmp = read_byte_abs());
606     n_flag = tmp;
607     v_flag = tmp & 0x40;
608     ENDOP(4);
609    
610    
611     // Shift/rotate group
612     case 0x0a: // ASL A
613     c_flag = a & 0x80;
614     set_nz(a <<= 1);
615     ENDOP(2);
616    
617     case 0x06: // ASL zero
618     tmp = read_zp(adr = read_adr_zero());
619     c_flag = tmp & 0x80;
620     write_zp(adr, set_nz(tmp << 1));
621     ENDOP(5);
622    
623     case 0x16: // ASL zero,X
624     tmp = read_zp(adr = read_adr_zero_x());
625     c_flag = tmp & 0x80;
626     write_zp(adr, set_nz(tmp << 1));
627     ENDOP(6);
628    
629     case 0x0e: // ASL abs
630     tmp = read_byte(adr = read_adr_abs());
631     c_flag = tmp & 0x80;
632     write_byte(adr, set_nz(tmp << 1));
633     ENDOP(6);
634    
635     case 0x1e: // ASL abs,X
636     tmp = read_byte(adr = read_adr_abs_x());
637     c_flag = tmp & 0x80;
638     write_byte(adr, set_nz(tmp << 1));
639     ENDOP(7);
640    
641     case 0x4a: // LSR A
642     c_flag = a & 0x01;
643     set_nz(a >>= 1);
644     ENDOP(2);
645    
646     case 0x46: // LSR zero
647     tmp = read_zp(adr = read_adr_zero());
648     c_flag = tmp & 0x01;
649     write_zp(adr, set_nz(tmp >> 1));
650     ENDOP(5);
651    
652     case 0x56: // LSR zero,X
653     tmp = read_zp(adr = read_adr_zero_x());
654     c_flag = tmp & 0x01;
655     write_zp(adr, set_nz(tmp >> 1));
656     ENDOP(6);
657    
658     case 0x4e: // LSR abs
659     tmp = read_byte(adr = read_adr_abs());
660     c_flag = tmp & 0x01;
661     write_byte(adr, set_nz(tmp >> 1));
662     ENDOP(6);
663    
664     case 0x5e: // LSR abs,X
665     tmp = read_byte(adr = read_adr_abs_x());
666     c_flag = tmp & 0x01;
667     write_byte(adr, set_nz(tmp >> 1));
668     ENDOP(7);
669    
670     case 0x2a: // ROL A
671     tmp2 = a & 0x80;
672     set_nz(a = c_flag ? (a << 1) | 0x01 : a << 1);
673     c_flag = tmp2;
674     ENDOP(2);
675    
676     case 0x26: // ROL zero
677     tmp = read_zp(adr = read_adr_zero());
678     tmp2 = tmp & 0x80;
679     write_zp(adr, set_nz(c_flag ? (tmp << 1) | 0x01 : tmp << 1));
680     c_flag = tmp2;
681     ENDOP(5);
682    
683     case 0x36: // ROL zero,X
684     tmp = read_zp(adr = read_adr_zero_x());
685     tmp2 = tmp & 0x80;
686     write_zp(adr, set_nz(c_flag ? (tmp << 1) | 0x01 : tmp << 1));
687     c_flag = tmp2;
688     ENDOP(6);
689    
690     case 0x2e: // ROL abs
691     tmp = read_byte(adr = read_adr_abs());
692     tmp2 = tmp & 0x80;
693     write_byte(adr, set_nz(c_flag ? (tmp << 1) | 0x01 : tmp << 1));
694     c_flag = tmp2;
695     ENDOP(6);
696    
697     case 0x3e: // ROL abs,X
698     tmp = read_byte(adr = read_adr_abs_x());
699     tmp2 = tmp & 0x80;
700     write_byte(adr, set_nz(c_flag ? (tmp << 1) | 0x01 : tmp << 1));
701     c_flag = tmp2;
702     ENDOP(7);
703    
704     case 0x6a: // ROR A
705     tmp2 = a & 0x01;
706     set_nz(a = (c_flag ? (a >> 1) | 0x80 : a >> 1));
707     c_flag = tmp2;
708     ENDOP(2);
709    
710     case 0x66: // ROR zero
711     tmp = read_zp(adr = read_adr_zero());
712     tmp2 = tmp & 0x01;
713     write_zp(adr, set_nz(c_flag ? (tmp >> 1) | 0x80 : tmp >> 1));
714     c_flag = tmp2;
715     ENDOP(5);
716    
717     case 0x76: // ROR zero,X
718     tmp = read_zp(adr = read_adr_zero_x());
719     tmp2 = tmp & 0x01;
720     write_zp(adr, set_nz(c_flag ? (tmp >> 1) | 0x80 : tmp >> 1));
721     c_flag = tmp2;
722     ENDOP(6);
723    
724     case 0x6e: // ROR abs
725     tmp = read_byte(adr = read_adr_abs());
726     tmp2 = tmp & 0x01;
727     write_byte(adr, set_nz(c_flag ? (tmp >> 1) | 0x80 : tmp >> 1));
728     c_flag = tmp2;
729     ENDOP(6);
730    
731     case 0x7e: // ROR abs,X
732     tmp = read_byte(adr = read_adr_abs_x());
733     tmp2 = tmp & 0x01;
734     write_byte(adr, set_nz(c_flag ? (tmp >> 1) | 0x80 : tmp >> 1));
735     c_flag = tmp2;
736     ENDOP(7);
737    
738    
739     // Stack group
740     case 0x48: // PHA
741     push_byte(a);
742     ENDOP(3);
743    
744     case 0x68: // PLA
745     set_nz(a = pop_byte());
746     ENDOP(4);
747    
748     case 0x08: // PHP
749     push_flags(true);
750     ENDOP(3);
751    
752     case 0x28: // PLP
753     pop_flags();
754     if (interrupt.intr_any && !i_flag)
755     goto handle_int;
756     ENDOP(4);
757    
758    
759     // Jump/branch group
760     case 0x4c: // JMP abs
761     jump(read_adr_abs());
762     ENDOP(3);
763    
764     case 0x6c: // JMP (ind)
765     adr = read_adr_abs();
766     jump(read_byte(adr) | (read_byte((adr + 1) & 0xff | adr & 0xff00) << 8));
767     ENDOP(5);
768    
769     case 0x20: // JSR abs
770     #if PC_IS_POINTER
771     push_byte((pc-pc_base+1) >> 8); push_byte(pc-pc_base+1);
772     #else
773     push_byte(pc+1 >> 8); push_byte(pc+1);
774     #endif
775     jump(read_adr_abs());
776     ENDOP(6);
777    
778     case 0x60: // RTS
779     adr = pop_byte(); // Split because of pop_byte ++sp side-effect
780     jump((adr | pop_byte() << 8) + 1);
781     ENDOP(6);
782    
783     case 0x40: // RTI
784     pop_flags();
785     adr = pop_byte(); // Split because of pop_byte ++sp side-effect
786     jump(adr | pop_byte() << 8);
787     if (interrupt.intr_any && !i_flag)
788     goto handle_int;
789     ENDOP(6);
790    
791     case 0x00: // BRK
792     #if PC_IS_POINTER
793     push_byte((pc+1-pc_base) >> 8); push_byte(pc+1-pc_base);
794     #else
795     push_byte((pc+1) >> 8); push_byte(pc+1);
796     #endif
797     push_flags(true);
798     i_flag = true;
799     jump(read_word(0xfffe));
800     ENDOP(7);
801    
802     #if PC_IS_POINTER
803     #if PRECISE_CPU_CYCLES
804     #define Branch(flag) \
805     if (flag) { \
806     pc += (int8)*pc + 1; \
807     if (((pc-pc_base) ^ (old_pc - pc_base)) & 0xff00) { \
808     ENDOP(4); \
809     } else { \
810     ENDOP(3); \
811     } \
812     } else { \
813     pc++; \
814     ENDOP(2); \
815     }
816     #else
817     #define Branch(flag) \
818     if (flag) { \
819     pc += (int8)*pc + 1; \
820     ENDOP(3); \
821     } else { \
822     pc++; \
823     ENDOP(2); \
824     }
825     #endif
826     #else
827     #define Branch(flag) \
828     if (flag) { \
829     uint16 old_pc = pc; \
830     pc += (int8)read_byte(pc) + 1; \
831     if ((pc ^ old_pc) & 0xff00) { \
832     ENDOP(4); \
833     } else { \
834     ENDOP(3); \
835     } \
836     } else { \
837     pc++; \
838     ENDOP(2); \
839     }
840     #endif
841    
842     case 0xb0: // BCS rel
843     Branch(c_flag);
844    
845     case 0x90: // BCC rel
846     Branch(!c_flag);
847    
848     case 0xf0: // BEQ rel
849     Branch(!z_flag);
850    
851     case 0xd0: // BNE rel
852     Branch(z_flag);
853    
854     case 0x70: // BVS rel
855     #ifndef IS_CPU_1541
856     Branch(v_flag);
857     #else
858     Branch((via2_pcr & 0x0e) == 0x0e ? 1 : v_flag); // GCR byte ready flag
859     #endif
860    
861     case 0x50: // BVC rel
862     #ifndef IS_CPU_1541
863     Branch(!v_flag);
864     #else
865     Branch(!((via2_pcr & 0x0e) == 0x0e) ? 0 : v_flag); // GCR byte ready flag
866     #endif
867    
868     case 0x30: // BMI rel
869     Branch(n_flag & 0x80);
870    
871     case 0x10: // BPL rel
872     Branch(!(n_flag & 0x80));
873    
874    
875     // Flags group
876     case 0x38: // SEC
877     c_flag = true;
878     ENDOP(2);
879    
880     case 0x18: // CLC
881     c_flag = false;
882     ENDOP(2);
883    
884     case 0xf8: // SED
885     d_flag = true;
886     ENDOP(2);
887    
888     case 0xd8: // CLD
889     d_flag = false;
890     ENDOP(2);
891    
892     case 0x78: // SEI
893     i_flag = true;
894     ENDOP(2);
895    
896     case 0x58: // CLI
897     i_flag = false;
898     if (interrupt.intr_any)
899     goto handle_int;
900     ENDOP(2);
901    
902     case 0xb8: // CLV
903     v_flag = false;
904     ENDOP(2);
905    
906    
907     // NOP group
908     case 0xea: // NOP
909     ENDOP(2);
910    
911    
912     /*
913     * Undocumented opcodes start here
914     */
915    
916     // NOP group
917     case 0x1a: // NOP
918     case 0x3a:
919     case 0x5a:
920     case 0x7a:
921     case 0xda:
922     case 0xfa:
923     ENDOP(2);
924    
925     case 0x80: // NOP #imm
926     case 0x82:
927     case 0x89:
928     case 0xc2:
929     case 0xe2:
930     pc++;
931     ENDOP(2);
932    
933     case 0x04: // NOP zero
934     case 0x44:
935     case 0x64:
936     pc++;
937     ENDOP(3);
938    
939     case 0x14: // NOP zero,X
940     case 0x34:
941     case 0x54:
942     case 0x74:
943     case 0xd4:
944     case 0xf4:
945     pc++;
946     ENDOP(4);
947    
948     case 0x0c: // NOP abs
949     pc+=2;
950     ENDOP(4);
951    
952     case 0x1c: // NOP abs,X
953     case 0x3c:
954     case 0x5c:
955     case 0x7c:
956     case 0xdc:
957     case 0xfc:
958     #if PRECISE_CPU_CYCLES
959     read_byte_abs_x();
960     #else
961     pc+=2;
962     #endif
963     ENDOP(4);
964    
965    
966     // Load A/X group
967     case 0xa7: // LAX zero
968     set_nz(a = x = read_byte_zero());
969     ENDOP(3);
970    
971     case 0xb7: // LAX zero,Y
972     set_nz(a = x = read_byte_zero_y());
973     ENDOP(4);
974    
975     case 0xaf: // LAX abs
976     set_nz(a = x = read_byte_abs());
977     ENDOP(4);
978    
979     case 0xbf: // LAX abs,Y
980     set_nz(a = x = read_byte_abs_y());
981     ENDOP(4);
982    
983     case 0xa3: // LAX (ind,X)
984     set_nz(a = x = read_byte_ind_x());
985     ENDOP(6);
986    
987     case 0xb3: // LAX (ind),Y
988     set_nz(a = x = read_byte_ind_y());
989     ENDOP(5);
990    
991    
992     // Store A/X group
993     case 0x87: // SAX zero
994     write_byte(read_adr_zero(), a & x);
995     ENDOP(3);
996    
997     case 0x97: // SAX zero,Y
998     write_byte(read_adr_zero_y(), a & x);
999     ENDOP(4);
1000    
1001     case 0x8f: // SAX abs
1002     write_byte(read_adr_abs(), a & x);
1003     ENDOP(4);
1004    
1005     case 0x83: // SAX (ind,X)
1006     write_byte(read_adr_ind_x(), a & x);
1007     ENDOP(6);
1008    
1009    
1010     // ASL/ORA group
1011     #define ShiftLeftOr \
1012     c_flag = tmp & 0x80; \
1013     tmp <<= 1; \
1014     set_nz(a |= tmp);
1015    
1016     case 0x07: // SLO zero
1017     tmp = read_zp(adr = read_adr_zero());
1018     ShiftLeftOr;
1019     write_zp(adr, tmp);
1020     ENDOP(5);
1021    
1022     case 0x17: // SLO zero,X
1023     tmp = read_zp(adr = read_adr_zero_x());
1024     ShiftLeftOr;
1025     write_zp(adr, tmp);
1026     ENDOP(6);
1027    
1028     case 0x0f: // SLO abs
1029     tmp = read_byte(adr = read_adr_abs());
1030     ShiftLeftOr;
1031     write_byte(adr, tmp);
1032     ENDOP(6);
1033    
1034     case 0x1f: // SLO abs,X
1035     tmp = read_byte(adr = read_adr_abs_x());
1036     ShiftLeftOr;
1037     write_byte(adr, tmp);
1038     ENDOP(7);
1039    
1040     case 0x1b: // SLO abs,Y
1041     tmp = read_byte(adr = read_adr_abs_y());
1042     ShiftLeftOr;
1043     write_byte(adr, tmp);
1044     ENDOP(7);
1045    
1046     case 0x03: // SLO (ind,X)
1047     tmp = read_byte(adr = read_adr_ind_x());
1048     ShiftLeftOr;
1049     write_byte(adr, tmp);
1050     ENDOP(8);
1051    
1052     case 0x13: // SLO (ind),Y
1053     tmp = read_byte(adr = read_adr_ind_y());
1054     ShiftLeftOr;
1055     write_byte(adr, tmp);
1056     ENDOP(8);
1057    
1058    
1059     // ROL/AND group
1060     #define RoLeftAnd \
1061     tmp2 = tmp & 0x80; \
1062     tmp = c_flag ? (tmp << 1) | 0x01 : tmp << 1; \
1063     set_nz(a &= tmp); \
1064     c_flag = tmp2;
1065    
1066     case 0x27: // RLA zero
1067     tmp = read_zp(adr = read_adr_zero());
1068     RoLeftAnd;
1069     write_zp(adr, tmp);
1070     ENDOP(5);
1071    
1072     case 0x37: // RLA zero,X
1073     tmp = read_zp(adr = read_adr_zero_x());
1074     RoLeftAnd;
1075     write_zp(adr, tmp);
1076     ENDOP(6);
1077    
1078     case 0x2f: // RLA abs
1079     tmp = read_byte(adr = read_adr_abs());
1080     RoLeftAnd;
1081     write_byte(adr, tmp);
1082     ENDOP(6);
1083    
1084     case 0x3f: // RLA abs,X
1085     tmp = read_byte(adr = read_adr_abs_x());
1086     RoLeftAnd;
1087     write_byte(adr, tmp);
1088     ENDOP(7);
1089    
1090     case 0x3b: // RLA abs,Y
1091     tmp = read_byte(adr = read_adr_abs_y());
1092     RoLeftAnd;
1093     write_byte(adr, tmp);
1094     ENDOP(7);
1095    
1096     case 0x23: // RLA (ind,X)
1097     tmp = read_byte(adr = read_adr_ind_x());
1098     RoLeftAnd;
1099     write_byte(adr, tmp);
1100     ENDOP(8);
1101    
1102     case 0x33: // RLA (ind),Y
1103     tmp = read_byte(adr = read_adr_ind_y());
1104     RoLeftAnd;
1105     write_byte(adr, tmp);
1106     ENDOP(8);
1107    
1108    
1109     // LSR/EOR group
1110     #define ShiftRightEor \
1111     c_flag = tmp & 0x01; \
1112     tmp >>= 1; \
1113     set_nz(a ^= tmp);
1114    
1115     case 0x47: // SRE zero
1116     tmp = read_zp(adr = read_adr_zero());
1117     ShiftRightEor;
1118     write_zp(adr, tmp);
1119     ENDOP(5);
1120    
1121     case 0x57: // SRE zero,X
1122     tmp = read_zp(adr = read_adr_zero_x());
1123     ShiftRightEor;
1124     write_zp(adr, tmp);
1125     ENDOP(6);
1126    
1127     case 0x4f: // SRE abs
1128     tmp = read_byte(adr = read_adr_abs());
1129     ShiftRightEor;
1130     write_byte(adr, tmp);
1131     ENDOP(6);
1132    
1133     case 0x5f: // SRE abs,X
1134     tmp = read_byte(adr = read_adr_abs_x());
1135     ShiftRightEor;
1136     write_byte(adr, tmp);
1137     ENDOP(7);
1138    
1139     case 0x5b: // SRE abs,Y
1140     tmp = read_byte(adr = read_adr_abs_y());
1141     ShiftRightEor;
1142     write_byte(adr, tmp);
1143     ENDOP(7);
1144    
1145     case 0x43: // SRE (ind,X)
1146     tmp = read_byte(adr = read_adr_ind_x());
1147     ShiftRightEor;
1148     write_byte(adr, tmp);
1149     ENDOP(8);
1150    
1151     case 0x53: // SRE (ind),Y
1152     tmp = read_byte(adr = read_adr_ind_y());
1153     ShiftRightEor;
1154     write_byte(adr, tmp);
1155     ENDOP(8);
1156    
1157    
1158     // ROR/ADC group
1159     #define RoRightAdc \
1160     tmp2 = tmp & 0x01; \
1161     tmp = c_flag ? (tmp >> 1) | 0x80 : tmp >> 1; \
1162     c_flag = tmp2; \
1163     do_adc(tmp);
1164    
1165     case 0x67: // RRA zero
1166     tmp = read_zp(adr = read_adr_zero());
1167     RoRightAdc;
1168     write_zp(adr, tmp);
1169     ENDOP(5);
1170    
1171     case 0x77: // RRA zero,X
1172     tmp = read_zp(adr = read_adr_zero_x());
1173     RoRightAdc;
1174     write_zp(adr, tmp);
1175     ENDOP(6);
1176    
1177     case 0x6f: // RRA abs
1178     tmp = read_byte(adr = read_adr_abs());
1179     RoRightAdc;
1180     write_byte(adr, tmp);
1181     ENDOP(6);
1182    
1183     case 0x7f: // RRA abs,X
1184     tmp = read_byte(adr = read_adr_abs_x());
1185     RoRightAdc;
1186     write_byte(adr, tmp);
1187     ENDOP(7);
1188    
1189     case 0x7b: // RRA abs,Y
1190     tmp = read_byte(adr = read_adr_abs_y());
1191     RoRightAdc;
1192     write_byte(adr, tmp);
1193     ENDOP(7);
1194    
1195     case 0x63: // RRA (ind,X)
1196     tmp = read_byte(adr = read_adr_ind_x());
1197     RoRightAdc;
1198     write_byte(adr, tmp);
1199     ENDOP(8);
1200    
1201     case 0x73: // RRA (ind),Y
1202     tmp = read_byte(adr = read_adr_ind_y());
1203     RoRightAdc;
1204     write_byte(adr, tmp);
1205     ENDOP(8);
1206    
1207    
1208     // DEC/CMP group
1209     #define DecCompare \
1210     set_nz(adr = a - tmp); \
1211     c_flag = adr < 0x100;
1212    
1213     case 0xc7: // DCP zero
1214     tmp = read_zp(adr = read_adr_zero()) - 1;
1215     write_zp(adr, tmp);
1216     DecCompare;
1217     ENDOP(5);
1218    
1219     case 0xd7: // DCP zero,X
1220     tmp = read_zp(adr = read_adr_zero_x()) - 1;
1221     write_zp(adr, tmp);
1222     DecCompare;
1223     ENDOP(6);
1224    
1225     case 0xcf: // DCP abs
1226     tmp = read_byte(adr = read_adr_abs()) - 1;
1227     write_byte(adr, tmp);
1228     DecCompare;
1229     ENDOP(6);
1230    
1231     case 0xdf: // DCP abs,X
1232     tmp = read_byte(adr = read_adr_abs_x()) - 1;
1233     write_byte(adr, tmp);
1234     DecCompare;
1235     ENDOP(7);
1236    
1237     case 0xdb: // DCP abs,Y
1238     tmp = read_byte(adr = read_adr_abs_y()) - 1;
1239     write_byte(adr, tmp);
1240     DecCompare;
1241     ENDOP(7);
1242    
1243     case 0xc3: // DCP (ind,X)
1244     tmp = read_byte(adr = read_adr_ind_x()) - 1;
1245     write_byte(adr, tmp);
1246     DecCompare;
1247     ENDOP(8);
1248    
1249     case 0xd3: // DCP (ind),Y
1250     tmp = read_byte(adr = read_adr_ind_y()) - 1;
1251     write_byte(adr, tmp);
1252     DecCompare;
1253     ENDOP(8);
1254    
1255    
1256     // INC/SBC group
1257     case 0xe7: // ISB zero
1258     tmp = read_zp(adr = read_adr_zero()) + 1;
1259     do_sbc(tmp);
1260     write_zp(adr, tmp);
1261     ENDOP(5);
1262    
1263     case 0xf7: // ISB zero,X
1264     tmp = read_zp(adr = read_adr_zero_x()) + 1;
1265     do_sbc(tmp);
1266     write_zp(adr, tmp);
1267     ENDOP(6);
1268    
1269     case 0xef: // ISB abs
1270     tmp = read_byte(adr = read_adr_abs()) + 1;
1271     do_sbc(tmp);
1272     write_byte(adr, tmp);
1273     ENDOP(6);
1274    
1275     case 0xff: // ISB abs,X
1276     tmp = read_byte(adr = read_adr_abs_x()) + 1;
1277     do_sbc(tmp);
1278     write_byte(adr, tmp);
1279     ENDOP(7);
1280    
1281     case 0xfb: // ISB abs,Y
1282     tmp = read_byte(adr = read_adr_abs_y()) + 1;
1283     do_sbc(tmp);
1284     write_byte(adr, tmp);
1285     ENDOP(7);
1286    
1287     case 0xe3: // ISB (ind,X)
1288     tmp = read_byte(adr = read_adr_ind_x()) + 1;
1289     do_sbc(tmp);
1290     write_byte(adr, tmp);
1291     ENDOP(8);
1292    
1293     case 0xf3: // ISB (ind),Y
1294     tmp = read_byte(adr = read_adr_ind_y()) + 1;
1295     do_sbc(tmp);
1296     write_byte(adr, tmp);
1297     ENDOP(8);
1298    
1299    
1300     // Complex functions
1301     case 0x0b: // ANC #imm
1302     case 0x2b:
1303     set_nz(a &= read_byte_imm());
1304     c_flag = n_flag & 0x80;
1305     ENDOP(2);
1306    
1307     case 0x4b: // ASR #imm
1308     a &= read_byte_imm();
1309     c_flag = a & 0x01;
1310     set_nz(a >>= 1);
1311     ENDOP(2);
1312    
1313     case 0x6b: // ARR #imm
1314     tmp2 = read_byte_imm() & a;
1315     a = (c_flag ? (tmp2 >> 1) | 0x80 : tmp2 >> 1);
1316     if (!d_flag) {
1317     set_nz(a);
1318     c_flag = a & 0x40;
1319     v_flag = (a & 0x40) ^ ((a & 0x20) << 1);
1320     } else {
1321     n_flag = c_flag ? 0x80 : 0;
1322     z_flag = a;
1323     v_flag = (tmp2 ^ a) & 0x40;
1324     if ((tmp2 & 0x0f) + (tmp2 & 0x01) > 5)
1325     a = a & 0xf0 | (a + 6) & 0x0f;
1326     if (c_flag = ((tmp2 + (tmp2 & 0x10)) & 0x1f0) > 0x50)
1327     a += 0x60;
1328     }
1329     ENDOP(2);
1330    
1331     case 0x8b: // ANE #imm
1332     set_nz(a = read_byte_imm() & x & (a | 0xee));
1333     ENDOP(2);
1334    
1335     case 0x93: // SHA (ind),Y
1336     #if PC_IS_POINTER
1337     tmp2 = read_zp(pc[0] + 1);
1338     #else
1339     tmp2 = read_zp(read_byte(pc) + 1);
1340     #endif
1341     write_byte(read_adr_ind_y(), a & x & (tmp2+1));
1342     ENDOP(6);
1343    
1344     case 0x9b: // SHS abs,Y
1345     #if PC_IS_POINTER
1346     tmp2 = pc[1];
1347     #else
1348     tmp2 = read_byte(pc+1);
1349     #endif
1350     write_byte(read_adr_abs_y(), a & x & (tmp2+1));
1351     sp = a & x;
1352     ENDOP(5);
1353    
1354     case 0x9c: // SHY abs,X
1355     #if PC_IS_POINTER
1356     tmp2 = pc[1];
1357     #else
1358     tmp2 = read_byte(pc+1);
1359     #endif
1360     write_byte(read_adr_abs_x(), y & (tmp2+1));
1361     ENDOP(5);
1362    
1363     case 0x9e: // SHX abs,Y
1364     #if PC_IS_POINTER
1365     tmp2 = pc[1];
1366     #else
1367     tmp2 = read_byte(pc+1);
1368     #endif
1369     write_byte(read_adr_abs_y(), x & (tmp2+1));
1370     ENDOP(5);
1371    
1372     case 0x9f: // SHA abs,Y
1373     #if PC_IS_POINTER
1374     tmp2 = pc[1];
1375     #else
1376     tmp2 = read_byte(pc+1);
1377     #endif
1378     write_byte(read_adr_abs_y(), a & x & (tmp2+1));
1379     ENDOP(5);
1380    
1381     case 0xab: // LXA #imm
1382     set_nz(a = x = (a | 0xee) & read_byte_imm());
1383     ENDOP(2);
1384    
1385     case 0xbb: // LAS abs,Y
1386     set_nz(a = x = sp = read_byte_abs_y() & sp);
1387     ENDOP(4);
1388    
1389     case 0xcb: // SBX #imm
1390     x &= a;
1391     adr = x - read_byte_imm();
1392     c_flag = adr < 0x100;
1393     set_nz(x = adr);
1394     ENDOP(2);
1395    
1396     case 0x02:
1397     case 0x12:
1398     case 0x22:
1399     case 0x32:
1400     case 0x42:
1401     case 0x52:
1402     case 0x62:
1403     case 0x72:
1404     case 0x92:
1405     case 0xb2:
1406     case 0xd2:
1407     #if PC_IS_POINTER
1408     illegal_op(*(pc-1), pc-pc_base-1);
1409     #else
1410     illegal_op(read_byte(pc-1), pc-1);
1411     #endif
1412     break;