ViewVC Help
View File | Revision Log | Show Annotations | Revision Graph | Root Listing
root/cebix/Frodo4/Src/CPU_emulline.h
Revision: 1.5
Committed: 2004-01-12T15:13:20Z (19 years ago) by cebix
Content type: text/plain
Branch: MAIN
Changes since 1.4: +1 -1 lines
Log Message:
Happy New Year!

File Contents

# User Rev Content
1 cebix 1.1 /*
2 cebix 1.2 * CPU_emulline.h - 6510/6502 emulation core (body of
3 cebix 1.1 * EmulateLine() function, the same for
4     * both 6510 and 6502)
5     *
6 cebix 1.5 * Frodo (C) 1994-1997,2002-2004 Christian Bauer
7 cebix 1.1 *
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 cebix 1.4 adr = read_adr_abs();
762     jump(adr);
763 cebix 1.1 ENDOP(3);
764    
765     case 0x6c: // JMP (ind)
766     adr = read_adr_abs();
767 cebix 1.4 adr = read_byte(adr) | (read_byte((adr + 1) & 0xff | adr & 0xff00) << 8);
768     jump(adr);
769 cebix 1.1 ENDOP(5);
770    
771     case 0x20: // JSR abs
772     #if PC_IS_POINTER
773     push_byte((pc-pc_base+1) >> 8); push_byte(pc-pc_base+1);
774     #else
775     push_byte(pc+1 >> 8); push_byte(pc+1);
776     #endif
777 cebix 1.4 adr = read_adr_abs();
778     jump(adr);
779 cebix 1.1 ENDOP(6);
780    
781     case 0x60: // RTS
782     adr = pop_byte(); // Split because of pop_byte ++sp side-effect
783 cebix 1.4 adr = (adr | pop_byte() << 8) + 1;
784     jump(adr);
785 cebix 1.1 ENDOP(6);
786    
787     case 0x40: // RTI
788     pop_flags();
789     adr = pop_byte(); // Split because of pop_byte ++sp side-effect
790 cebix 1.4 adr = adr | pop_byte() << 8;
791     jump(adr);
792 cebix 1.1 if (interrupt.intr_any && !i_flag)
793     goto handle_int;
794     ENDOP(6);
795    
796     case 0x00: // BRK
797     #if PC_IS_POINTER
798     push_byte((pc+1-pc_base) >> 8); push_byte(pc+1-pc_base);
799     #else
800     push_byte((pc+1) >> 8); push_byte(pc+1);
801     #endif
802     push_flags(true);
803     i_flag = true;
804 cebix 1.4 adr = read_word(0xfffe);
805     jump(adr);
806 cebix 1.1 ENDOP(7);
807    
808     #if PC_IS_POINTER
809     #if PRECISE_CPU_CYCLES
810     #define Branch(flag) \
811     if (flag) { \
812     pc += (int8)*pc + 1; \
813     if (((pc-pc_base) ^ (old_pc - pc_base)) & 0xff00) { \
814     ENDOP(4); \
815     } else { \
816     ENDOP(3); \
817     } \
818     } else { \
819     pc++; \
820     ENDOP(2); \
821     }
822     #else
823     #define Branch(flag) \
824     if (flag) { \
825     pc += (int8)*pc + 1; \
826     ENDOP(3); \
827     } else { \
828     pc++; \
829     ENDOP(2); \
830     }
831     #endif
832     #else
833     #define Branch(flag) \
834     if (flag) { \
835     uint16 old_pc = pc; \
836     pc += (int8)read_byte(pc) + 1; \
837     if ((pc ^ old_pc) & 0xff00) { \
838     ENDOP(4); \
839     } else { \
840     ENDOP(3); \
841     } \
842     } else { \
843     pc++; \
844     ENDOP(2); \
845     }
846     #endif
847    
848     case 0xb0: // BCS rel
849     Branch(c_flag);
850    
851     case 0x90: // BCC rel
852     Branch(!c_flag);
853    
854     case 0xf0: // BEQ rel
855     Branch(!z_flag);
856    
857     case 0xd0: // BNE rel
858     Branch(z_flag);
859    
860     case 0x70: // BVS rel
861     #ifndef IS_CPU_1541
862     Branch(v_flag);
863     #else
864     Branch((via2_pcr & 0x0e) == 0x0e ? 1 : v_flag); // GCR byte ready flag
865     #endif
866    
867     case 0x50: // BVC rel
868     #ifndef IS_CPU_1541
869     Branch(!v_flag);
870     #else
871     Branch(!((via2_pcr & 0x0e) == 0x0e) ? 0 : v_flag); // GCR byte ready flag
872     #endif
873    
874     case 0x30: // BMI rel
875     Branch(n_flag & 0x80);
876    
877     case 0x10: // BPL rel
878     Branch(!(n_flag & 0x80));
879    
880    
881     // Flags group
882     case 0x38: // SEC
883     c_flag = true;
884     ENDOP(2);
885    
886     case 0x18: // CLC
887     c_flag = false;
888     ENDOP(2);
889    
890     case 0xf8: // SED
891     d_flag = true;
892     ENDOP(2);
893    
894     case 0xd8: // CLD
895     d_flag = false;
896     ENDOP(2);
897    
898     case 0x78: // SEI
899     i_flag = true;
900     ENDOP(2);
901    
902     case 0x58: // CLI
903     i_flag = false;
904     if (interrupt.intr_any)
905     goto handle_int;
906     ENDOP(2);
907    
908     case 0xb8: // CLV
909     v_flag = false;
910     ENDOP(2);
911    
912    
913     // NOP group
914     case 0xea: // NOP
915     ENDOP(2);
916    
917    
918     /*
919     * Undocumented opcodes start here
920     */
921    
922     // NOP group
923     case 0x1a: // NOP
924     case 0x3a:
925     case 0x5a:
926     case 0x7a:
927     case 0xda:
928     case 0xfa:
929     ENDOP(2);
930    
931     case 0x80: // NOP #imm
932     case 0x82:
933     case 0x89:
934     case 0xc2:
935     case 0xe2:
936     pc++;
937     ENDOP(2);
938    
939     case 0x04: // NOP zero
940     case 0x44:
941     case 0x64:
942     pc++;
943     ENDOP(3);
944    
945     case 0x14: // NOP zero,X
946     case 0x34:
947     case 0x54:
948     case 0x74:
949     case 0xd4:
950     case 0xf4:
951     pc++;
952     ENDOP(4);
953    
954     case 0x0c: // NOP abs
955     pc+=2;
956     ENDOP(4);
957    
958     case 0x1c: // NOP abs,X
959     case 0x3c:
960     case 0x5c:
961     case 0x7c:
962     case 0xdc:
963     case 0xfc:
964     #if PRECISE_CPU_CYCLES
965     read_byte_abs_x();
966     #else
967     pc+=2;
968     #endif
969     ENDOP(4);
970    
971    
972     // Load A/X group
973     case 0xa7: // LAX zero
974     set_nz(a = x = read_byte_zero());
975     ENDOP(3);
976    
977     case 0xb7: // LAX zero,Y
978     set_nz(a = x = read_byte_zero_y());
979     ENDOP(4);
980    
981     case 0xaf: // LAX abs
982     set_nz(a = x = read_byte_abs());
983     ENDOP(4);
984    
985     case 0xbf: // LAX abs,Y
986     set_nz(a = x = read_byte_abs_y());
987     ENDOP(4);
988    
989     case 0xa3: // LAX (ind,X)
990     set_nz(a = x = read_byte_ind_x());
991     ENDOP(6);
992    
993     case 0xb3: // LAX (ind),Y
994     set_nz(a = x = read_byte_ind_y());
995     ENDOP(5);
996    
997    
998     // Store A/X group
999     case 0x87: // SAX zero
1000     write_byte(read_adr_zero(), a & x);
1001     ENDOP(3);
1002    
1003     case 0x97: // SAX zero,Y
1004     write_byte(read_adr_zero_y(), a & x);
1005     ENDOP(4);
1006    
1007     case 0x8f: // SAX abs
1008     write_byte(read_adr_abs(), a & x);
1009     ENDOP(4);
1010    
1011     case 0x83: // SAX (ind,X)
1012     write_byte(read_adr_ind_x(), a & x);
1013     ENDOP(6);
1014    
1015    
1016     // ASL/ORA group
1017     #define ShiftLeftOr \
1018     c_flag = tmp & 0x80; \
1019     tmp <<= 1; \
1020     set_nz(a |= tmp);
1021    
1022     case 0x07: // SLO zero
1023     tmp = read_zp(adr = read_adr_zero());
1024     ShiftLeftOr;
1025     write_zp(adr, tmp);
1026     ENDOP(5);
1027    
1028     case 0x17: // SLO zero,X
1029     tmp = read_zp(adr = read_adr_zero_x());
1030     ShiftLeftOr;
1031     write_zp(adr, tmp);
1032     ENDOP(6);
1033    
1034     case 0x0f: // SLO abs
1035     tmp = read_byte(adr = read_adr_abs());
1036     ShiftLeftOr;
1037     write_byte(adr, tmp);
1038     ENDOP(6);
1039    
1040     case 0x1f: // SLO abs,X
1041     tmp = read_byte(adr = read_adr_abs_x());
1042     ShiftLeftOr;
1043     write_byte(adr, tmp);
1044     ENDOP(7);
1045    
1046     case 0x1b: // SLO abs,Y
1047     tmp = read_byte(adr = read_adr_abs_y());
1048     ShiftLeftOr;
1049     write_byte(adr, tmp);
1050     ENDOP(7);
1051    
1052     case 0x03: // SLO (ind,X)
1053     tmp = read_byte(adr = read_adr_ind_x());
1054     ShiftLeftOr;
1055     write_byte(adr, tmp);
1056     ENDOP(8);
1057    
1058     case 0x13: // SLO (ind),Y
1059     tmp = read_byte(adr = read_adr_ind_y());
1060     ShiftLeftOr;
1061     write_byte(adr, tmp);
1062     ENDOP(8);
1063    
1064    
1065     // ROL/AND group
1066     #define RoLeftAnd \
1067     tmp2 = tmp & 0x80; \
1068     tmp = c_flag ? (tmp << 1) | 0x01 : tmp << 1; \
1069     set_nz(a &= tmp); \
1070     c_flag = tmp2;
1071    
1072     case 0x27: // RLA zero
1073     tmp = read_zp(adr = read_adr_zero());
1074     RoLeftAnd;
1075     write_zp(adr, tmp);
1076     ENDOP(5);
1077    
1078     case 0x37: // RLA zero,X
1079     tmp = read_zp(adr = read_adr_zero_x());
1080     RoLeftAnd;
1081     write_zp(adr, tmp);
1082     ENDOP(6);
1083    
1084     case 0x2f: // RLA abs
1085     tmp = read_byte(adr = read_adr_abs());
1086     RoLeftAnd;
1087     write_byte(adr, tmp);
1088     ENDOP(6);
1089    
1090     case 0x3f: // RLA abs,X
1091     tmp = read_byte(adr = read_adr_abs_x());
1092     RoLeftAnd;
1093     write_byte(adr, tmp);
1094     ENDOP(7);
1095    
1096     case 0x3b: // RLA abs,Y
1097     tmp = read_byte(adr = read_adr_abs_y());
1098     RoLeftAnd;
1099     write_byte(adr, tmp);
1100     ENDOP(7);
1101    
1102     case 0x23: // RLA (ind,X)
1103     tmp = read_byte(adr = read_adr_ind_x());
1104     RoLeftAnd;
1105     write_byte(adr, tmp);
1106     ENDOP(8);
1107    
1108     case 0x33: // RLA (ind),Y
1109     tmp = read_byte(adr = read_adr_ind_y());
1110     RoLeftAnd;
1111     write_byte(adr, tmp);
1112     ENDOP(8);
1113    
1114    
1115     // LSR/EOR group
1116     #define ShiftRightEor \
1117     c_flag = tmp & 0x01; \
1118     tmp >>= 1; \
1119     set_nz(a ^= tmp);
1120    
1121     case 0x47: // SRE zero
1122     tmp = read_zp(adr = read_adr_zero());
1123     ShiftRightEor;
1124     write_zp(adr, tmp);
1125     ENDOP(5);
1126    
1127     case 0x57: // SRE zero,X
1128     tmp = read_zp(adr = read_adr_zero_x());
1129     ShiftRightEor;
1130     write_zp(adr, tmp);
1131     ENDOP(6);
1132    
1133     case 0x4f: // SRE abs
1134     tmp = read_byte(adr = read_adr_abs());
1135     ShiftRightEor;
1136     write_byte(adr, tmp);
1137     ENDOP(6);
1138    
1139     case 0x5f: // SRE abs,X
1140     tmp = read_byte(adr = read_adr_abs_x());
1141     ShiftRightEor;
1142     write_byte(adr, tmp);
1143     ENDOP(7);
1144    
1145     case 0x5b: // SRE abs,Y
1146     tmp = read_byte(adr = read_adr_abs_y());
1147     ShiftRightEor;
1148     write_byte(adr, tmp);
1149     ENDOP(7);
1150    
1151     case 0x43: // SRE (ind,X)
1152     tmp = read_byte(adr = read_adr_ind_x());
1153     ShiftRightEor;
1154     write_byte(adr, tmp);
1155     ENDOP(8);
1156    
1157     case 0x53: // SRE (ind),Y
1158     tmp = read_byte(adr = read_adr_ind_y());
1159     ShiftRightEor;
1160     write_byte(adr, tmp);
1161     ENDOP(8);
1162    
1163    
1164     // ROR/ADC group
1165     #define RoRightAdc \
1166     tmp2 = tmp & 0x01; \
1167     tmp = c_flag ? (tmp >> 1) | 0x80 : tmp >> 1; \
1168     c_flag = tmp2; \
1169     do_adc(tmp);
1170    
1171     case 0x67: // RRA zero
1172     tmp = read_zp(adr = read_adr_zero());
1173     RoRightAdc;
1174     write_zp(adr, tmp);
1175     ENDOP(5);
1176    
1177     case 0x77: // RRA zero,X
1178     tmp = read_zp(adr = read_adr_zero_x());
1179     RoRightAdc;
1180     write_zp(adr, tmp);
1181     ENDOP(6);
1182    
1183     case 0x6f: // RRA abs
1184     tmp = read_byte(adr = read_adr_abs());
1185     RoRightAdc;
1186     write_byte(adr, tmp);
1187     ENDOP(6);
1188    
1189     case 0x7f: // RRA abs,X
1190     tmp = read_byte(adr = read_adr_abs_x());
1191     RoRightAdc;
1192     write_byte(adr, tmp);
1193     ENDOP(7);
1194    
1195     case 0x7b: // RRA abs,Y
1196     tmp = read_byte(adr = read_adr_abs_y());
1197     RoRightAdc;
1198     write_byte(adr, tmp);
1199     ENDOP(7);
1200    
1201     case 0x63: // RRA (ind,X)
1202     tmp = read_byte(adr = read_adr_ind_x());
1203     RoRightAdc;
1204     write_byte(adr, tmp);
1205     ENDOP(8);
1206    
1207     case 0x73: // RRA (ind),Y
1208     tmp = read_byte(adr = read_adr_ind_y());
1209     RoRightAdc;
1210     write_byte(adr, tmp);
1211     ENDOP(8);
1212    
1213    
1214     // DEC/CMP group
1215     #define DecCompare \
1216     set_nz(adr = a - tmp); \
1217     c_flag = adr < 0x100;
1218    
1219     case 0xc7: // DCP zero
1220     tmp = read_zp(adr = read_adr_zero()) - 1;
1221     write_zp(adr, tmp);
1222     DecCompare;
1223     ENDOP(5);
1224    
1225     case 0xd7: // DCP zero,X
1226     tmp = read_zp(adr = read_adr_zero_x()) - 1;
1227     write_zp(adr, tmp);
1228     DecCompare;
1229     ENDOP(6);
1230    
1231     case 0xcf: // DCP abs
1232     tmp = read_byte(adr = read_adr_abs()) - 1;
1233     write_byte(adr, tmp);
1234     DecCompare;
1235     ENDOP(6);
1236    
1237     case 0xdf: // DCP abs,X
1238     tmp = read_byte(adr = read_adr_abs_x()) - 1;
1239     write_byte(adr, tmp);
1240     DecCompare;
1241     ENDOP(7);
1242    
1243     case 0xdb: // DCP abs,Y
1244     tmp = read_byte(adr = read_adr_abs_y()) - 1;
1245     write_byte(adr, tmp);
1246     DecCompare;
1247     ENDOP(7);
1248    
1249     case 0xc3: // DCP (ind,X)
1250     tmp = read_byte(adr = read_adr_ind_x()) - 1;
1251     write_byte(adr, tmp);
1252     DecCompare;
1253     ENDOP(8);
1254    
1255     case 0xd3: // DCP (ind),Y
1256     tmp = read_byte(adr = read_adr_ind_y()) - 1;
1257     write_byte(adr, tmp);
1258     DecCompare;
1259     ENDOP(8);
1260    
1261    
1262     // INC/SBC group
1263     case 0xe7: // ISB zero
1264     tmp = read_zp(adr = read_adr_zero()) + 1;
1265     do_sbc(tmp);
1266     write_zp(adr, tmp);
1267     ENDOP(5);
1268    
1269     case 0xf7: // ISB zero,X
1270     tmp = read_zp(adr = read_adr_zero_x()) + 1;
1271     do_sbc(tmp);
1272     write_zp(adr, tmp);
1273     ENDOP(6);
1274    
1275     case 0xef: // ISB abs
1276     tmp = read_byte(adr = read_adr_abs()) + 1;
1277     do_sbc(tmp);
1278     write_byte(adr, tmp);
1279     ENDOP(6);
1280    
1281     case 0xff: // ISB abs,X
1282     tmp = read_byte(adr = read_adr_abs_x()) + 1;
1283     do_sbc(tmp);
1284     write_byte(adr, tmp);
1285     ENDOP(7);
1286    
1287     case 0xfb: // ISB abs,Y
1288     tmp = read_byte(adr = read_adr_abs_y()) + 1;
1289     do_sbc(tmp);
1290     write_byte(adr, tmp);
1291     ENDOP(7);
1292    
1293     case 0xe3: // ISB (ind,X)
1294     tmp = read_byte(adr = read_adr_ind_x()) + 1;
1295     do_sbc(tmp);
1296     write_byte(adr, tmp);
1297     ENDOP(8);
1298    
1299     case 0xf3: // ISB (ind),Y
1300     tmp = read_byte(adr = read_adr_ind_y()) + 1;
1301     do_sbc(tmp);
1302     write_byte(adr, tmp);
1303     ENDOP(8);
1304    
1305    
1306     // Complex functions
1307     case 0x0b: // ANC #imm
1308     case 0x2b:
1309     set_nz(a &= read_byte_imm());
1310     c_flag = n_flag & 0x80;
1311     ENDOP(2);
1312    
1313     case 0x4b: // ASR #imm
1314     a &= read_byte_imm();
1315     c_flag = a & 0x01;
1316     set_nz(a >>= 1);
1317     ENDOP(2);
1318    
1319     case 0x6b: // ARR #imm
1320     tmp2 = read_byte_imm() & a;
1321     a = (c_flag ? (tmp2 >> 1) | 0x80 : tmp2 >> 1);
1322     if (!d_flag) {
1323     set_nz(a);
1324     c_flag = a & 0x40;
1325     v_flag = (a & 0x40) ^ ((a & 0x20) << 1);
1326     } else {
1327     n_flag = c_flag ? 0x80 : 0;
1328     z_flag = a;
1329     v_flag = (tmp2 ^ a) & 0x40;
1330     if ((tmp2 & 0x0f) + (tmp2 & 0x01) > 5)
1331     a = a & 0xf0 | (a + 6) & 0x0f;
1332 cebix 1.4 if ((c_flag = ((tmp2 + (tmp2 & 0x10)) & 0x1f0) > 0x50) != 0)
1333 cebix 1.1 a += 0x60;
1334     }
1335     ENDOP(2);
1336    
1337     case 0x8b: // ANE #imm
1338     set_nz(a = read_byte_imm() & x & (a | 0xee));
1339     ENDOP(2);
1340    
1341     case 0x93: // SHA (ind),Y
1342     #if PC_IS_POINTER
1343     tmp2 = read_zp(pc[0] + 1);
1344     #else
1345     tmp2 = read_zp(read_byte(pc) + 1);
1346     #endif
1347     write_byte(read_adr_ind_y(), a & x & (tmp2+1));
1348     ENDOP(6);
1349    
1350     case 0x9b: // SHS abs,Y
1351     #if PC_IS_POINTER
1352     tmp2 = pc[1];
1353     #else
1354     tmp2 = read_byte(pc+1);
1355     #endif
1356     write_byte(read_adr_abs_y(), a & x & (tmp2+1));
1357     sp = a & x;
1358     ENDOP(5);
1359    
1360     case 0x9c: // SHY abs,X
1361     #if PC_IS_POINTER
1362     tmp2 = pc[1];
1363     #else
1364     tmp2 = read_byte(pc+1);
1365     #endif
1366     write_byte(read_adr_abs_x(), y & (tmp2+1));
1367     ENDOP(5);
1368    
1369     case 0x9e: // SHX abs,Y
1370     #if PC_IS_POINTER
1371     tmp2 = pc[1];
1372     #else
1373     tmp2 = read_byte(pc+1);
1374     #endif
1375     write_byte(read_adr_abs_y(), x & (tmp2+1));
1376     ENDOP(5);
1377    
1378     case 0x9f: // SHA abs,Y
1379     #if PC_IS_POINTER
1380     tmp2 = pc[1];
1381     #else
1382     tmp2 = read_byte(pc+1);
1383     #endif
1384     write_byte(read_adr_abs_y(), a & x & (tmp2+1));
1385     ENDOP(5);
1386    
1387     case 0xab: // LXA #imm
1388     set_nz(a = x = (a | 0xee) & read_byte_imm());
1389     ENDOP(2);
1390    
1391     case 0xbb: // LAS abs,Y
1392     set_nz(a = x = sp = read_byte_abs_y() & sp);
1393     ENDOP(4);
1394    
1395     case 0xcb: // SBX #imm
1396     x &= a;
1397     adr = x - read_byte_imm();
1398     c_flag = adr < 0x100;
1399     set_nz(x = adr);
1400     ENDOP(2);
1401    
1402     case 0x02:
1403     case 0x12:
1404     case 0x22:
1405     case 0x32:
1406     case 0x42:
1407     case 0x52:
1408     case 0x62:
1409     case 0x72:
1410     case 0x92:
1411     case 0xb2:
1412     case 0xd2:
1413     #if PC_IS_POINTER
1414     illegal_op(*(pc-1), pc-pc_base-1);
1415     #else
1416     illegal_op(read_byte(pc-1), pc-1);
1417     #endif
1418     break;