ViewVC Help
View File | Revision Log | Show Annotations | Revision Graph | Root Listing
root/cebix/Frodo4/Src/CPU_emulcycle.h
Revision: 1.7
Committed: 2010-04-22T15:08:18Z (14 years ago) by cebix
Content type: text/plain
Branch: MAIN
CVS Tags: HEAD
Changes since 1.6: +15 -9 lines
Log Message:
better interrupt timing

File Contents

# User Rev Content
1 cebix 1.1 /*
2 cebix 1.2 * CPU_emulcycle.h - SC 6510/6502 emulation core (body of
3 cebix 1.1 * EmulateCycle() function, the same for
4     * both 6510 and 6502)
5     *
6 cebix 1.6 * Frodo (C) 1994-1997,2002-2005 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     * Stack macros
26     */
27    
28     // Pop processor flags from the stack
29     #define pop_flags() \
30     read_to(sp | 0x100, data); \
31     n_flag = data; \
32     v_flag = data & 0x40; \
33     d_flag = data & 0x08; \
34     i_flag = data & 0x04; \
35     z_flag = !(data & 0x02); \
36     c_flag = data & 0x01;
37    
38     // Push processor flags onto the stack
39     #define push_flags(b_flag) \
40     data = 0x20 | (n_flag & 0x80); \
41     if (v_flag) data |= 0x40; \
42     if (b_flag) data |= 0x10; \
43     if (d_flag) data |= 0x08; \
44     if (i_flag) data |= 0x04; \
45     if (!z_flag) data |= 0x02; \
46     if (c_flag) data |= 0x01; \
47     write_byte(sp-- | 0x100, data);
48    
49    
50     /*
51     * Other macros
52     */
53    
54     // Branch (cycle 1)
55     #define Branch(flag) \
56     read_to(pc++, data); \
57     if (flag) { \
58     ar = pc + (int8)data; \
59     if ((ar >> 8) != (pc >> 8)) { \
60     if (data & 0x80) \
61     state = O_BRANCH_BP; \
62     else \
63     state = O_BRANCH_FP; \
64     } else \
65     state = O_BRANCH_NP; \
66     } else \
67     state = 0; \
68     break;
69    
70     // Set N and Z flags according to byte
71     #define set_nz(x) (z_flag = n_flag = (x))
72    
73     // Address fetch of RMW instruction done, now read and write operand
74     #define DoRMW state = RMW_DO_IT; break;
75    
76     // Operand fetch done, now execute opcode
77     #define Execute state = OpTab[op]; break;
78    
79     // Last cycle of opcode
80     #define Last state = 0; break;
81    
82    
83     /*
84     * EmulCycle() function
85     */
86    
87     switch (state) {
88    
89    
90     // Opcode fetch (cycle 0)
91     case 0:
92     read_to(pc++, op);
93     state = ModeTab[op];
94 cebix 1.7 opflags = 0;
95 cebix 1.1 break;
96    
97    
98     // IRQ
99     case 0x0008:
100     read_idle(pc);
101     state = 0x0009;
102     break;
103     case 0x0009:
104     read_idle(pc);
105     state = 0x000a;
106     break;
107     case 0x000a:
108     write_byte(sp-- | 0x100, pc >> 8);
109     state = 0x000b;
110     break;
111     case 0x000b:
112     write_byte(sp-- | 0x100, pc);
113     state = 0x000c;
114     break;
115     case 0x000c:
116     push_flags(false);
117     i_flag = true;
118     state = 0x000d;
119     break;
120     case 0x000d:
121     read_to(0xfffe, pc);
122     state = 0x000e;
123     break;
124     case 0x000e:
125     read_to(0xffff, data);
126     pc |= data << 8;
127     Last;
128    
129    
130     // NMI
131     case 0x0010:
132     read_idle(pc);
133     state = 0x0011;
134     break;
135     case 0x0011:
136     read_idle(pc);
137     state = 0x0012;
138     break;
139     case 0x0012:
140     write_byte(sp-- | 0x100, pc >> 8);
141     state = 0x0013;
142     break;
143     case 0x0013:
144     write_byte(sp-- | 0x100, pc);
145     state = 0x0014;
146     break;
147     case 0x0014:
148     push_flags(false);
149     i_flag = true;
150     state = 0x0015;
151     break;
152     case 0x0015:
153     read_to(0xfffa, pc);
154     state = 0x0016;
155     break;
156     case 0x0016:
157     read_to(0xfffb, data);
158     pc |= data << 8;
159     Last;
160    
161    
162     // Addressing modes: Fetch effective address, no extra cycles (-> ar)
163     case A_ZERO:
164     read_to(pc++, ar);
165     Execute;
166    
167     case A_ZEROX:
168     read_to(pc++, ar);
169     state = A_ZEROX1;
170     break;
171     case A_ZEROX1:
172     read_idle(ar);
173     ar = (ar + x) & 0xff;
174     Execute;
175    
176     case A_ZEROY:
177     read_to(pc++, ar);
178     state = A_ZEROY1;
179     break;
180     case A_ZEROY1:
181     read_idle(ar);
182     ar = (ar + y) & 0xff;
183     Execute;
184    
185     case A_ABS:
186     read_to(pc++, ar);
187     state = A_ABS1;
188     break;
189     case A_ABS1:
190     read_to(pc++, data);
191     ar = ar | (data << 8);
192     Execute;
193    
194     case A_ABSX:
195     read_to(pc++, ar);
196     state = A_ABSX1;
197     break;
198     case A_ABSX1:
199     read_to(pc++, ar2); // Note: Some undocumented opcodes rely on the value of ar2
200     if (ar+x < 0x100)
201     state = A_ABSX2;
202     else
203     state = A_ABSX3;
204     ar = (ar + x) & 0xff | (ar2 << 8);
205     break;
206     case A_ABSX2: // No page crossed
207     read_idle(ar);
208     Execute;
209     case A_ABSX3: // Page crossed
210     read_idle(ar);
211     ar += 0x100;
212     Execute;
213    
214     case A_ABSY:
215     read_to(pc++, ar);
216     state = A_ABSY1;
217     break;
218     case A_ABSY1:
219     read_to(pc++, ar2); // Note: Some undocumented opcodes rely on the value of ar2
220     if (ar+y < 0x100)
221     state = A_ABSY2;
222     else
223     state = A_ABSY3;
224     ar = (ar + y) & 0xff | (ar2 << 8);
225     break;
226     case A_ABSY2: // No page crossed
227     read_idle(ar);
228     Execute;
229     case A_ABSY3: // Page crossed
230     read_idle(ar);
231     ar += 0x100;
232     Execute;
233    
234     case A_INDX:
235     read_to(pc++, ar2);
236     state = A_INDX1;
237     break;
238     case A_INDX1:
239     read_idle(ar2);
240     ar2 = (ar2 + x) & 0xff;
241     state = A_INDX2;
242     break;
243     case A_INDX2:
244     read_to(ar2, ar);
245     state = A_INDX3;
246     break;
247     case A_INDX3:
248     read_to((ar2 + 1) & 0xff, data);
249     ar = ar | (data << 8);
250     Execute;
251    
252     case A_INDY:
253     read_to(pc++, ar2);
254     state = A_INDY1;
255     break;
256     case A_INDY1:
257     read_to(ar2, ar);
258     state = A_INDY2;
259     break;
260     case A_INDY2:
261     read_to((ar2 + 1) & 0xff, ar2); // Note: Some undocumented opcodes rely on the value of ar2
262     if (ar+y < 0x100)
263     state = A_INDY3;
264     else
265     state = A_INDY4;
266     ar = (ar + y) & 0xff | (ar2 << 8);
267     break;
268     case A_INDY3: // No page crossed
269     read_idle(ar);
270     Execute;
271     case A_INDY4: // Page crossed
272     read_idle(ar);
273     ar += 0x100;
274     Execute;
275    
276    
277     // Addressing modes: Fetch effective address, extra cycle on page crossing (-> ar)
278     case AE_ABSX:
279     read_to(pc++, ar);
280     state = AE_ABSX1;
281     break;
282     case AE_ABSX1:
283     read_to(pc++, data);
284     if (ar+x < 0x100) {
285     ar = (ar + x) & 0xff | (data << 8);
286     Execute;
287     } else {
288     ar = (ar + x) & 0xff | (data << 8);
289     state = AE_ABSX2;
290     }
291     break;
292     case AE_ABSX2: // Page crossed
293     read_idle(ar);
294     ar += 0x100;
295     Execute;
296    
297     case AE_ABSY:
298     read_to(pc++, ar);
299     state = AE_ABSY1;
300     break;
301     case AE_ABSY1:
302     read_to(pc++, data);
303     if (ar+y < 0x100) {
304     ar = (ar + y) & 0xff | (data << 8);
305     Execute;
306     } else {
307     ar = (ar + y) & 0xff | (data << 8);
308     state = AE_ABSY2;
309     }
310     break;
311     case AE_ABSY2: // Page crossed
312     read_idle(ar);
313     ar += 0x100;
314     Execute;
315    
316     case AE_INDY:
317     read_to(pc++, ar2);
318     state = AE_INDY1;
319     break;
320     case AE_INDY1:
321     read_to(ar2, ar);
322     state = AE_INDY2;
323     break;
324     case AE_INDY2:
325     read_to((ar2 + 1) & 0xff, data);
326     if (ar+y < 0x100) {
327     ar = (ar + y) & 0xff | (data << 8);
328     Execute;
329     } else {
330     ar = (ar + y) & 0xff | (data << 8);
331     state = AE_INDY3;
332     }
333     break;
334     case AE_INDY3: // Page crossed
335     read_idle(ar);
336     ar += 0x100;
337     Execute;
338    
339    
340     // Addressing modes: Read operand, write it back, no extra cycles (-> ar, rdbuf)
341     case M_ZERO:
342     read_to(pc++, ar);
343     DoRMW;
344    
345     case M_ZEROX:
346     read_to(pc++, ar);
347     state = M_ZEROX1;
348     break;
349     case M_ZEROX1:
350     read_idle(ar);
351     ar = (ar + x) & 0xff;
352     DoRMW;
353    
354     case M_ZEROY:
355     read_to(pc++, ar);
356     state = M_ZEROY1;
357     break;
358     case M_ZEROY1:
359     read_idle(ar);
360     ar = (ar + y) & 0xff;
361     DoRMW;
362    
363     case M_ABS:
364     read_to(pc++, ar);
365     state = M_ABS1;
366     break;
367     case M_ABS1:
368     read_to(pc++, data);
369     ar = ar | (data << 8);
370     DoRMW;
371    
372     case M_ABSX:
373     read_to(pc++, ar);
374     state = M_ABSX1;
375     break;
376     case M_ABSX1:
377     read_to(pc++, data);
378     if (ar+x < 0x100)
379     state = M_ABSX2;
380     else
381     state = M_ABSX3;
382     ar = (ar + x) & 0xff | (data << 8);
383     break;
384     case M_ABSX2: // No page crossed
385     read_idle(ar);
386     DoRMW;
387     case M_ABSX3: // Page crossed
388     read_idle(ar);
389     ar += 0x100;
390     DoRMW;
391    
392     case M_ABSY:
393     read_to(pc++, ar);
394     state = M_ABSY1;
395     break;
396     case M_ABSY1:
397     read_to(pc++, data);
398     if (ar+y < 0x100)
399     state = M_ABSY2;
400     else
401     state = M_ABSY3;
402     ar = (ar + y) & 0xff | (data << 8);
403     break;
404     case M_ABSY2: // No page crossed
405     read_idle(ar);
406     DoRMW;
407     case M_ABSY3: // Page crossed
408     read_idle(ar);
409     ar += 0x100;
410     DoRMW;
411    
412     case M_INDX:
413     read_to(pc++, ar2);
414     state = M_INDX1;
415     break;
416     case M_INDX1:
417     read_idle(ar2);
418     ar2 = (ar2 + x) & 0xff;
419     state = M_INDX2;
420     break;
421     case M_INDX2:
422     read_to(ar2, ar);
423     state = M_INDX3;
424     break;
425     case M_INDX3:
426     read_to((ar2 + 1) & 0xff, data);
427     ar = ar | (data << 8);
428     DoRMW;
429    
430     case M_INDY:
431     read_to(pc++, ar2);
432     state = M_INDY1;
433     break;
434     case M_INDY1:
435     read_to(ar2, ar);
436     state = M_INDY2;
437     break;
438     case M_INDY2:
439     read_to((ar2 + 1) & 0xff, data);
440     if (ar+y < 0x100)
441     state = M_INDY3;
442     else
443     state = M_INDY4;
444     ar = (ar + y) & 0xff | (data << 8);
445     break;
446     case M_INDY3: // No page crossed
447     read_idle(ar);
448     DoRMW;
449     case M_INDY4: // Page crossed
450     read_idle(ar);
451     ar += 0x100;
452     DoRMW;
453    
454     case RMW_DO_IT:
455     read_to(ar, rdbuf);
456     state = RMW_DO_IT1;
457     break;
458     case RMW_DO_IT1:
459     write_byte(ar, rdbuf);
460     Execute;
461    
462    
463     // Load group
464     case O_LDA:
465     read_to(ar, data);
466     set_nz(a = data);
467     Last;
468     case O_LDA_I:
469     read_to(pc++, data);
470     set_nz(a = data);
471     Last;
472    
473     case O_LDX:
474     read_to(ar, data);
475     set_nz(x = data);
476     Last;
477     case O_LDX_I:
478     read_to(pc++, data);
479     set_nz(x = data);
480     Last;
481    
482     case O_LDY:
483     read_to(ar, data);
484     set_nz(y = data);
485     Last;
486     case O_LDY_I:
487     read_to(pc++, data);
488     set_nz(y = data);
489     Last;
490    
491    
492     // Store group
493     case O_STA:
494     write_byte(ar, a);
495     Last;
496    
497     case O_STX:
498     write_byte(ar, x);
499     Last;
500    
501     case O_STY:
502     write_byte(ar, y);
503     Last;
504    
505    
506     // Transfer group
507     case O_TAX:
508     read_idle(pc);
509     set_nz(x = a);
510     Last;
511    
512     case O_TXA:
513     read_idle(pc);
514     set_nz(a = x);
515     Last;
516    
517     case O_TAY:
518     read_idle(pc);
519     set_nz(y = a);
520     Last;
521    
522     case O_TYA:
523     read_idle(pc);
524     set_nz(a = y);
525     Last;
526    
527     case O_TSX:
528     read_idle(pc);
529     set_nz(x = sp);
530     Last;
531    
532     case O_TXS:
533     read_idle(pc);
534     sp = x;
535     Last;
536    
537    
538     // Arithmetic group
539     case O_ADC:
540     read_to(ar, data);
541     do_adc(data);
542     Last;
543     case O_ADC_I:
544     read_to(pc++, data);
545     do_adc(data);
546     Last;
547    
548     case O_SBC:
549     read_to(ar, data);
550     do_sbc(data);
551     Last;
552     case O_SBC_I:
553     read_to(pc++, data);
554     do_sbc(data);
555     Last;
556    
557    
558     // Increment/decrement group
559     case O_INX:
560     read_idle(pc);
561     set_nz(++x);
562     Last;
563    
564     case O_DEX:
565     read_idle(pc);
566     set_nz(--x);
567     Last;
568    
569     case O_INY:
570     read_idle(pc);
571     set_nz(++y);
572     Last;
573    
574     case O_DEY:
575     read_idle(pc);
576     set_nz(--y);
577     Last;
578    
579     case O_INC:
580     write_byte(ar, set_nz(rdbuf + 1));
581     Last;
582    
583     case O_DEC:
584     write_byte(ar, set_nz(rdbuf - 1));
585     Last;
586    
587    
588     // Logic group
589     case O_AND:
590     read_to(ar, data);
591     set_nz(a &= data);
592     Last;
593     case O_AND_I:
594     read_to(pc++, data);
595     set_nz(a &= data);
596     Last;
597    
598     case O_ORA:
599     read_to(ar, data);
600     set_nz(a |= data);
601     Last;
602     case O_ORA_I:
603     read_to(pc++, data);
604     set_nz(a |= data);
605     Last;
606    
607     case O_EOR:
608     read_to(ar, data);
609     set_nz(a ^= data);
610     Last;
611     case O_EOR_I:
612     read_to(pc++, data);
613     set_nz(a ^= data);
614     Last;
615    
616     // Compare group
617     case O_CMP:
618     read_to(ar, data);
619     set_nz(ar = a - data);
620     c_flag = ar < 0x100;
621     Last;
622     case O_CMP_I:
623     read_to(pc++, data);
624     set_nz(ar = a - data);
625     c_flag = ar < 0x100;
626     Last;
627    
628     case O_CPX:
629     read_to(ar, data);
630     set_nz(ar = x - data);
631     c_flag = ar < 0x100;
632     Last;
633     case O_CPX_I:
634     read_to(pc++, data);
635     set_nz(ar = x - data);
636     c_flag = ar < 0x100;
637     Last;
638    
639     case O_CPY:
640     read_to(ar, data);
641     set_nz(ar = y - data);
642     c_flag = ar < 0x100;
643     Last;
644     case O_CPY_I:
645     read_to(pc++, data);
646     set_nz(ar = y - data);
647     c_flag = ar < 0x100;
648     Last;
649    
650    
651     // Bit-test group
652     case O_BIT:
653     read_to(ar, data);
654     z_flag = a & data;
655     n_flag = data;
656     v_flag = data & 0x40;
657     Last;
658    
659    
660     // Shift/rotate group
661     case O_ASL:
662     c_flag = rdbuf & 0x80;
663     write_byte(ar, set_nz(rdbuf << 1));
664     Last;
665     case O_ASL_A:
666     read_idle(pc);
667     c_flag = a & 0x80;
668     set_nz(a <<= 1);
669     Last;
670    
671     case O_LSR:
672     c_flag = rdbuf & 0x01;
673     write_byte(ar, set_nz(rdbuf >> 1));
674     Last;
675     case O_LSR_A:
676     read_idle(pc);
677     c_flag = a & 0x01;
678     set_nz(a >>= 1);
679     Last;
680    
681     case O_ROL:
682     write_byte(ar, set_nz(c_flag ? (rdbuf << 1) | 0x01 : rdbuf << 1));
683     c_flag = rdbuf & 0x80;
684     Last;
685     case O_ROL_A:
686     read_idle(pc);
687     data = a & 0x80;
688     set_nz(a = c_flag ? (a << 1) | 0x01 : a << 1);
689     c_flag = data;
690     Last;
691    
692     case O_ROR:
693     write_byte(ar, set_nz(c_flag ? (rdbuf >> 1) | 0x80 : rdbuf >> 1));
694     c_flag = rdbuf & 0x01;
695     Last;
696     case O_ROR_A:
697     read_idle(pc);
698     data = a & 0x01;
699     set_nz(a = (c_flag ? (a >> 1) | 0x80 : a >> 1));
700     c_flag = data;
701     Last;
702    
703    
704     // Stack group
705     case O_PHA:
706     read_idle(pc);
707     state = O_PHA1;
708     break;
709     case O_PHA1:
710     write_byte(sp-- | 0x100, a);
711     Last;
712    
713     case O_PLA:
714     read_idle(pc);
715     state = O_PLA1;
716     break;
717     case O_PLA1:
718     read_idle(sp++ | 0x100);
719     state = O_PLA2;
720     break;
721     case O_PLA2:
722     read_to(sp | 0x100, data);
723     set_nz(a = data);
724     Last;
725    
726     case O_PHP:
727     read_idle(pc);
728     state = O_PHP1;
729     break;
730     case O_PHP1:
731     push_flags(true);
732     Last;
733    
734     case O_PLP:
735     read_idle(pc);
736     state = O_PLP1;
737     break;
738     case O_PLP1:
739     read_idle(sp++ | 0x100);
740     state = O_PLP2;
741     break;
742 cebix 1.7 case O_PLP2: {
743     bool old_i_flag = i_flag;
744 cebix 1.1 pop_flags();
745 cebix 1.7 if (!old_i_flag && i_flag) {
746     opflags |= OPFLAG_IRQ_DISABLED;
747     } else if (old_i_flag && !i_flag) {
748     opflags |= OPFLAG_IRQ_ENABLED;
749     }
750 cebix 1.1 Last;
751 cebix 1.7 }
752 cebix 1.1
753    
754     // Jump/branch group
755     case O_JMP:
756     read_to(pc++, ar);
757     state = O_JMP1;
758     break;
759     case O_JMP1:
760     read_to(pc, data);
761     pc = (data << 8) | ar;
762     Last;
763    
764     case O_JMP_I:
765     read_to(ar, pc);
766     state = O_JMP_I1;
767     break;
768     case O_JMP_I1:
769     read_to((ar + 1) & 0xff | ar & 0xff00, data);
770     pc |= data << 8;
771     Last;
772    
773     case O_JSR:
774     read_to(pc++, ar);
775     state = O_JSR1;
776     break;
777     case O_JSR1:
778     read_idle(sp | 0x100);
779     state = O_JSR2;
780     break;
781     case O_JSR2:
782     write_byte(sp-- | 0x100, pc >> 8);
783     state = O_JSR3;
784     break;
785     case O_JSR3:
786     write_byte(sp-- | 0x100, pc);
787     state = O_JSR4;
788     break;
789     case O_JSR4:
790     read_to(pc++, data);
791     pc = ar | (data << 8);
792     Last;
793    
794     case O_RTS:
795     read_idle(pc);
796     state = O_RTS1;
797     break;
798     case O_RTS1:
799     read_idle(sp++ | 0x100);
800     state = O_RTS2;
801     break;
802     case O_RTS2:
803     read_to(sp++ | 0x100, pc);
804     state = O_RTS3;
805     break;
806     case O_RTS3:
807     read_to(sp | 0x100, data);
808     pc |= data << 8;
809     state = O_RTS4;
810     break;
811     case O_RTS4:
812     read_idle(pc++);
813     Last;
814    
815     case O_RTI:
816     read_idle(pc);
817     state = O_RTI1;
818     break;
819     case O_RTI1:
820     read_idle(sp++ | 0x100);
821     state = O_RTI2;
822     break;
823     case O_RTI2:
824     pop_flags();
825     sp++;
826     state = O_RTI3;
827     break;
828     case O_RTI3:
829     read_to(sp++ | 0x100, pc);
830     state = O_RTI4;
831     break;
832     case O_RTI4:
833     read_to(sp | 0x100, data);
834     pc |= data << 8;
835     Last;
836    
837     case O_BRK:
838     read_idle(pc++);
839     state = O_BRK1;
840     break;
841     case O_BRK1:
842     write_byte(sp-- | 0x100, pc >> 8);
843     state = O_BRK2;
844     break;
845     case O_BRK2:
846     write_byte(sp-- | 0x100, pc);
847     state = O_BRK3;
848     break;
849     case O_BRK3:
850     push_flags(true);
851     i_flag = true;
852     #ifndef IS_CPU_1541
853 cebix 1.7 if (interrupt.intr[INT_NMI]) { // BRK interrupted by NMI?
854 cebix 1.1 interrupt.intr[INT_NMI] = false; // Simulate an edge-triggered input
855     state = 0x0015; // Jump to NMI sequence
856     break;
857     }
858     #endif
859     state = O_BRK4;
860     break;
861     case O_BRK4:
862     read_to(0xfffe, pc);
863     state = O_BRK5;
864     break;
865     case O_BRK5:
866     read_to(0xffff, data);
867     pc |= data << 8;
868     Last;
869    
870     case O_BCS:
871     Branch(c_flag);
872    
873     case O_BCC:
874     Branch(!c_flag);
875    
876     case O_BEQ:
877     Branch(!z_flag);
878    
879     case O_BNE:
880     Branch(z_flag);
881    
882     case O_BVS:
883     #ifndef IS_CPU_1541
884     Branch(v_flag);
885     #else
886     Branch((via2_pcr & 0x0e) == 0x0e ? 1 : v_flag); // GCR byte ready flag
887     #endif
888    
889     case O_BVC:
890     #ifndef IS_CPU_1541
891     Branch(!v_flag);
892     #else
893     Branch(!((via2_pcr & 0x0e) == 0x0e) ? 0 : v_flag); // GCR byte ready flag
894     #endif
895    
896     case O_BMI:
897     Branch(n_flag & 0x80);
898    
899     case O_BPL:
900     Branch(!(n_flag & 0x80));
901    
902     case O_BRANCH_NP: // No page crossed
903 cebix 1.7 opflags |= OPFLAG_INT_DELAYED;
904 cebix 1.1 read_idle(pc);
905     pc = ar;
906     Last;
907     case O_BRANCH_BP: // Page crossed, branch backwards
908     read_idle(pc);
909     pc = ar;
910     state = O_BRANCH_BP1;
911     break;
912     case O_BRANCH_BP1:
913     read_idle(pc + 0x100);
914     Last;
915     case O_BRANCH_FP: // Page crossed, branch forwards
916     read_idle(pc);
917     pc = ar;
918     state = O_BRANCH_FP1;
919     break;
920     case O_BRANCH_FP1:
921     read_idle(pc - 0x100);
922     Last;
923    
924    
925     // Flag group
926     case O_SEC:
927     read_idle(pc);
928     c_flag = true;
929     Last;
930    
931     case O_CLC:
932     read_idle(pc);
933     c_flag = false;
934     Last;
935    
936     case O_SED:
937     read_idle(pc);
938     d_flag = true;
939     Last;
940    
941     case O_CLD:
942     read_idle(pc);
943     d_flag = false;
944     Last;
945    
946     case O_SEI:
947     read_idle(pc);
948 cebix 1.7 if (!i_flag)
949     opflags |= OPFLAG_IRQ_DISABLED;
950 cebix 1.1 i_flag = true;
951     Last;
952    
953     case O_CLI:
954     read_idle(pc);
955 cebix 1.7 if (i_flag)
956     opflags |= OPFLAG_IRQ_ENABLED;
957 cebix 1.1 i_flag = false;
958     Last;
959    
960     case O_CLV:
961     read_idle(pc);
962     v_flag = false;
963     Last;
964    
965    
966     // NOP group
967     case O_NOP:
968     read_idle(pc);
969     Last;
970    
971    
972     /*
973     * Undocumented opcodes start here
974     */
975    
976     // NOP group
977     case O_NOP_I:
978     read_idle(pc++);
979     Last;
980    
981     case O_NOP_A:
982     read_idle(ar);
983     Last;
984    
985    
986     // Load A/X group
987     case O_LAX:
988     read_to(ar, data);
989     set_nz(a = x = data);
990     Last;
991    
992    
993     // Store A/X group
994     case O_SAX:
995     write_byte(ar, a & x);
996     Last;
997    
998    
999     // ASL/ORA group
1000     case O_SLO:
1001     c_flag = rdbuf & 0x80;
1002     rdbuf <<= 1;
1003     write_byte(ar, rdbuf);
1004     set_nz(a |= rdbuf);
1005     Last;
1006    
1007    
1008     // ROL/AND group
1009     case O_RLA:
1010     tmp = rdbuf & 0x80;
1011     rdbuf = c_flag ? (rdbuf << 1) | 0x01 : rdbuf << 1;
1012     c_flag = tmp;
1013     write_byte(ar, rdbuf);
1014     set_nz(a &= rdbuf);
1015     Last;
1016    
1017    
1018     // LSR/EOR group
1019     case O_SRE:
1020     c_flag = rdbuf & 0x01;
1021     rdbuf >>= 1;
1022     write_byte(ar, rdbuf);
1023     set_nz(a ^= rdbuf);
1024     Last;
1025    
1026    
1027     // ROR/ADC group
1028     case O_RRA:
1029     tmp = rdbuf & 0x01;
1030     rdbuf = c_flag ? (rdbuf >> 1) | 0x80 : rdbuf >> 1;
1031     c_flag = tmp;
1032     write_byte(ar, rdbuf);
1033     do_adc(rdbuf);
1034     Last;
1035    
1036    
1037     // DEC/CMP group
1038     case O_DCP:
1039     write_byte(ar, --rdbuf);
1040     set_nz(ar = a - rdbuf);
1041     c_flag = ar < 0x100;
1042     Last;
1043    
1044    
1045     // INC/SBC group
1046     case O_ISB:
1047     write_byte(ar, ++rdbuf);
1048     do_sbc(rdbuf);
1049     Last;
1050    
1051    
1052     // Complex functions
1053     case O_ANC_I:
1054     read_to(pc++, data);
1055     set_nz(a &= data);
1056     c_flag = n_flag & 0x80;
1057     Last;
1058    
1059     case O_ASR_I:
1060     read_to(pc++, data);
1061     a &= data;
1062     c_flag = a & 0x01;
1063     set_nz(a >>= 1);
1064     Last;
1065    
1066     case O_ARR_I:
1067     read_to(pc++, data);
1068     data &= a;
1069     a = (c_flag ? (data >> 1) | 0x80 : data >> 1);
1070     if (!d_flag) {
1071     set_nz(a);
1072     c_flag = a & 0x40;
1073     v_flag = (a & 0x40) ^ ((a & 0x20) << 1);
1074     } else {
1075     n_flag = c_flag ? 0x80 : 0;
1076     z_flag = a;
1077     v_flag = (data ^ a) & 0x40;
1078     if ((data & 0x0f) + (data & 0x01) > 5)
1079     a = a & 0xf0 | (a + 6) & 0x0f;
1080 cebix 1.4 if ((c_flag = ((data + (data & 0x10)) & 0x1f0) > 0x50) != 0)
1081 cebix 1.1 a += 0x60;
1082     }
1083     Last;
1084    
1085     case O_ANE_I:
1086     read_to(pc++, data);
1087     set_nz(a = (a | 0xee) & x & data);
1088     Last;
1089    
1090     case O_LXA_I:
1091     read_to(pc++, data);
1092     set_nz(a = x = (a | 0xee) & data);
1093     Last;
1094    
1095     case O_SBX_I:
1096     read_to(pc++, data);
1097     set_nz(x = ar = (x & a) - data);
1098     c_flag = ar < 0x100;
1099     Last;
1100    
1101     case O_LAS:
1102     read_to(ar, data);
1103     set_nz(a = x = sp = data & sp);
1104     Last;
1105    
1106     case O_SHS: // ar2 contains the high byte of the operand address
1107     write_byte(ar, (ar2+1) & (sp = a & x));
1108     Last;
1109    
1110     case O_SHY: // ar2 contains the high byte of the operand address
1111     write_byte(ar, y & (ar2+1));
1112     Last;
1113    
1114     case O_SHX: // ar2 contains the high byte of the operand address
1115     write_byte(ar, x & (ar2+1));
1116     Last;
1117    
1118     case O_SHA: // ar2 contains the high byte of the operand address
1119     write_byte(ar, a & x & (ar2+1));
1120     Last;