Implement 386 instruction table, improve 8086/186/286 instruction table
[multi_emu.git] / cpu_65c02.c
1 #include <stdbool.h>
2 #include <stdlib.h>
3 #include <string.h>
4 #include "cpu_65c02.h"
5
6 // initialization
7 void cpu_65c02_init(
8   struct cpu_65c02 *self,
9   int (*read_byte)(void *context, int addr),
10   void *read_byte_context,
11   void (*write_byte)(void *context, int addr, int data),
12   void *write_byte_context
13 ) {
14   memset(self, 0, sizeof(struct cpu_65c02));
15   self->regs.byte.p = 0x30; // unused bits are hard coded to 1
16   self->read_byte = read_byte;
17   self->read_byte_context = read_byte_context;
18   self->write_byte = write_byte;
19   self->write_byte_context = write_byte_context;
20 }
21
22 void cpu_65c02_reset(struct cpu_65c02 *self) {
23   self->regs.word.pc = cpu_65c02_read_word(self, CPU_65C02_RESET_VECTOR);
24   self->regs.byte.iflags = 0;
25   self->regs.bit._if = true;
26   self->regs.bit.df = false;
27 }
28
29 // instruction decode
30 void cpu_65c02_execute(struct cpu_65c02 *self) {
31   if (self->regs.bit.stp_flag) {
32     ++self->cycles;
33     return;
34   }
35
36   if (self->regs.bit.nmi_pending) {
37     self->regs.bit.nmi_pending = false;
38     self->regs.bit.wai_flag = false;
39     cpu_65c02_irq(self, false, CPU_65C02_NMI_VECTOR);
40     return;
41   }
42
43   if (self->regs.bit.irq_pending) {
44     if (self->regs.bit._if == 0) {
45       self->regs.bit.irq_pending = false;
46       self->regs.bit.wai_flag = false;
47       cpu_65c02_irq(self, false, CPU_65C02_IRQ_VECTOR);
48       return;
49     }
50     if (self->regs.bit.wai_flag) {
51       self->regs.bit.irq_pending = false;
52       self->regs.bit.wai_flag = false;
53     }
54   }
55   else if (self->regs.bit.wai_flag) {
56     ++self->cycles;
57     return;
58   }
59
60   switch (cpu_65c02_fetch_byte(self)) {
61   case 0x00:
62     ++self->regs.word.pc;
63     cpu_65c02_irq(self, true, CPU_65C02_IRQ_VECTOR);
64     break;
65   case 0x01:
66     cpu_65c02_ora(self, cpu_65c02_read_byte(self, cpu_65c02_ea_zero_page_indexed_indirect(self, self->regs.byte.x)));
67     break;
68   case 0x02:
69     cpu_65c02_illegal_opcode22(self);
70     break;
71   case 0x03:
72     cpu_65c02_illegal_opcode11(self);
73     break;
74   case 0x04:
75     cpu_65c02_tsb(self, cpu_65c02_ea_zero_page(self));
76     break;
77   case 0x05:
78     cpu_65c02_ora(self, cpu_65c02_read_byte(self, cpu_65c02_ea_zero_page(self)));
79     break;
80   case 0x06:
81     cpu_65c02_asl(self, cpu_65c02_ea_zero_page(self));
82     break;
83   case 0x07:
84     cpu_65c02_rmb(self, 0, cpu_65c02_ea_zero_page(self));
85     break;
86   case 0x08:
87     cpu_65c02_ph(self, self->regs.byte.p);
88     break;
89   case 0x09:
90     cpu_65c02_ora(self, cpu_65c02_fetch_byte(self));
91     break;
92   case 0x0a:
93     cpu_65c02_asl(self, CPU_65C02_EA_A);
94     break;
95   case 0x0b:
96     cpu_65c02_illegal_opcode11(self);
97     break;
98   case 0x0c:
99     cpu_65c02_tsb(self, cpu_65c02_ea_absolute(self));
100     break;
101   case 0x0d:
102     cpu_65c02_ora(self, cpu_65c02_read_byte(self, cpu_65c02_ea_absolute(self)));
103     break;
104   case 0x0e:
105     cpu_65c02_asl(self, cpu_65c02_ea_absolute(self));
106     break;
107   case 0x0f:
108     {
109       int rvalue = cpu_65c02_read_byte(self, cpu_65c02_ea_zero_page(self));
110       cpu_65c02_bra(self, !(rvalue & 1), cpu_65c02_ea_relative(self));
111     }
112     break;
113   case 0x10:
114     cpu_65c02_bra(self, !self->regs.bit.nf, cpu_65c02_ea_relative(self));
115     break;
116   case 0x11:
117     cpu_65c02_ora(self, cpu_65c02_read_byte(self, cpu_65c02_ea_zero_page_indirect_indexed(self, self->regs.byte.y)));
118     break;
119   case 0x12:
120     cpu_65c02_ora(self, cpu_65c02_read_byte(self, cpu_65c02_ea_zero_page_indirect(self)));
121     break;
122   case 0x13:
123     cpu_65c02_illegal_opcode11(self);
124     break;
125   case 0x14:
126     cpu_65c02_trb(self, cpu_65c02_ea_zero_page(self));
127     break;
128   case 0x15:
129     cpu_65c02_ora(self, cpu_65c02_read_byte(self, cpu_65c02_ea_zero_page_indexed(self, self->regs.byte.x)));
130     break;
131   case 0x16:
132     cpu_65c02_asl(self, cpu_65c02_ea_zero_page_indexed(self, self->regs.byte.x));
133     break;
134   case 0x17:
135     cpu_65c02_rmb(self, 1, cpu_65c02_ea_zero_page(self));
136     break;
137   case 0x18:
138     cpu_65c02_cl(self, CPU_65C02_REG_P_BIT_C);
139     break;
140   case 0x19:
141     cpu_65c02_ora(self, cpu_65c02_read_byte(self, cpu_65c02_ea_absolute_indexed(self, self->regs.byte.y)));
142     break;
143   case 0x1a:
144     cpu_65c02_inc(self, CPU_65C02_EA_A);
145     break;
146   case 0x1b:
147     cpu_65c02_illegal_opcode11(self);
148     break;
149   case 0x1c:
150     cpu_65c02_trb(self, cpu_65c02_ea_absolute(self));
151     break;
152   case 0x1d:
153     cpu_65c02_ora(self, cpu_65c02_read_byte(self, cpu_65c02_ea_absolute_indexed(self, self->regs.byte.x)));
154     break;
155   case 0x1e:
156     cpu_65c02_asl(self, cpu_65c02_ea_absolute_indexed(self, self->regs.byte.x));
157     break;
158   case 0x1f:
159     {
160       int rvalue = cpu_65c02_read_byte(self, cpu_65c02_ea_zero_page(self));
161       cpu_65c02_bra(self, !((rvalue >> 1) & 1), cpu_65c02_ea_relative(self));
162     }
163     break;
164   case 0x20:
165     cpu_65c02_jsr(self, cpu_65c02_ea_absolute(self));
166     break;
167   case 0x21:
168     cpu_65c02_and(self, cpu_65c02_read_byte(self, cpu_65c02_ea_zero_page_indexed_indirect(self, self->regs.byte.x)));
169     break;
170   case 0x22:
171     cpu_65c02_illegal_opcode22(self);
172     break;
173   case 0x23:
174     cpu_65c02_illegal_opcode11(self);
175     break;
176   case 0x24:
177     cpu_65c02_bit(self, cpu_65c02_read_byte(self, cpu_65c02_ea_zero_page(self)));
178     break;
179   case 0x25:
180     cpu_65c02_and(self, cpu_65c02_read_byte(self, cpu_65c02_ea_zero_page(self)));
181     break;
182   case 0x26:
183     cpu_65c02_rol(self, cpu_65c02_ea_zero_page(self));
184     break;
185   case 0x27:
186     cpu_65c02_rmb(self, 2, cpu_65c02_ea_zero_page(self));
187     break;
188   case 0x28:
189     cpu_65c02_plp(self);
190     break;
191   case 0x29:
192     cpu_65c02_and(self, cpu_65c02_fetch_byte(self));
193     break;
194   case 0x2a:
195     cpu_65c02_rol(self, CPU_65C02_EA_A);
196     break;
197   case 0x2b:
198     cpu_65c02_illegal_opcode11(self);
199     break;
200   case 0x2c:
201     cpu_65c02_bit(self, cpu_65c02_read_byte(self, cpu_65c02_ea_absolute(self)));
202     break;
203   case 0x2d:
204     cpu_65c02_and(self, cpu_65c02_read_byte(self, cpu_65c02_ea_absolute(self)));
205     break;
206   case 0x2e:
207     cpu_65c02_rol(self, cpu_65c02_ea_absolute(self));
208     break;
209   case 0x2f:
210     {
211       int rvalue = cpu_65c02_read_byte(self, cpu_65c02_ea_zero_page(self));
212       cpu_65c02_bra(self, !((rvalue >> 2) & 1), cpu_65c02_ea_relative(self));
213     }
214     break;
215   case 0x30:
216     cpu_65c02_bra(self, self->regs.bit.nf, cpu_65c02_ea_relative(self));
217     break;
218   case 0x31:
219     cpu_65c02_and(self, cpu_65c02_read_byte(self, cpu_65c02_ea_zero_page_indirect_indexed(self, self->regs.byte.y)));
220     break;
221   case 0x32:
222     cpu_65c02_and(self, cpu_65c02_read_byte(self, cpu_65c02_ea_zero_page_indirect(self)));
223     break;
224   case 0x33:
225     cpu_65c02_illegal_opcode11(self);
226     break;
227   case 0x34:
228     cpu_65c02_bit(self, cpu_65c02_read_byte(self, cpu_65c02_ea_zero_page_indexed(self, self->regs.byte.x)));
229     break;
230   case 0x35:
231     cpu_65c02_and(self, cpu_65c02_read_byte(self, cpu_65c02_ea_zero_page_indexed(self, self->regs.byte.x)));
232     break;
233   case 0x36:
234     cpu_65c02_rol(self, cpu_65c02_ea_zero_page_indexed(self, self->regs.byte.x));
235     break;
236   case 0x37:
237     cpu_65c02_rmb(self, 3, cpu_65c02_ea_zero_page(self));
238     break;
239   case 0x38:
240     cpu_65c02_se(self, CPU_65C02_REG_P_BIT_C);
241     break;
242   case 0x39:
243     cpu_65c02_and(self, cpu_65c02_read_byte(self, cpu_65c02_ea_absolute_indexed(self, self->regs.byte.y)));
244     break;
245   case 0x3a:
246     cpu_65c02_dec(self, CPU_65C02_EA_A);
247     break;
248   case 0x3b:
249     cpu_65c02_illegal_opcode11(self);
250     break;
251   case 0x3c:
252     cpu_65c02_bit(self, cpu_65c02_read_byte(self, cpu_65c02_ea_absolute_indexed(self, self->regs.byte.x)));
253     break;
254   case 0x3d:
255     cpu_65c02_and(self, cpu_65c02_read_byte(self, cpu_65c02_ea_absolute_indexed(self, self->regs.byte.x)));
256     break;
257   case 0x3e:
258     cpu_65c02_rol(self, cpu_65c02_ea_absolute_indexed(self, self->regs.byte.x));
259     break;
260   case 0x3f:
261     {
262       int rvalue = cpu_65c02_read_byte(self, cpu_65c02_ea_zero_page(self));
263       cpu_65c02_bra(self, !((rvalue >> 3) & 1), cpu_65c02_ea_relative(self));
264     }
265     break;
266   case 0x40:
267     cpu_65c02_rti(self);
268     break;
269   case 0x41:
270     cpu_65c02_eor(self, cpu_65c02_read_byte(self, cpu_65c02_ea_zero_page_indexed_indirect(self, self->regs.byte.x)));
271     break;
272   case 0x42:
273     cpu_65c02_illegal_opcode22(self);
274     break;
275   case 0x43:
276     cpu_65c02_illegal_opcode11(self);
277     break;
278   case 0x44:
279     cpu_65c02_illegal_opcode23(self);
280     break;
281   case 0x45:
282     cpu_65c02_eor(self, cpu_65c02_read_byte(self, cpu_65c02_ea_zero_page(self)));
283     break;
284   case 0x46:
285     cpu_65c02_lsr(self, cpu_65c02_ea_zero_page(self));
286     break;
287   case 0x47:
288     cpu_65c02_rmb(self, 4, cpu_65c02_ea_zero_page(self));
289     break;
290   case 0x48:
291     cpu_65c02_ph(self, self->regs.byte.a);
292     break;
293   case 0x49:
294     cpu_65c02_eor(self, cpu_65c02_fetch_byte(self));
295     break;
296   case 0x4a:
297     cpu_65c02_lsr(self, CPU_65C02_EA_A);
298     break;
299   case 0x4b:
300     cpu_65c02_illegal_opcode11(self);
301     break;
302   case 0x4c:
303     cpu_65c02_jmp(self, cpu_65c02_ea_absolute(self));
304     break;
305   case 0x4d:
306     cpu_65c02_eor(self, cpu_65c02_read_byte(self, cpu_65c02_ea_absolute(self)));
307     break;
308   case 0x4e:
309     cpu_65c02_lsr(self, cpu_65c02_ea_absolute(self));
310     break;
311   case 0x4f:
312     {
313       int rvalue = cpu_65c02_read_byte(self, cpu_65c02_ea_zero_page(self));
314       cpu_65c02_bra(self, !((rvalue >> 4) & 1), cpu_65c02_ea_relative(self));
315     }
316     break;
317   case 0x50:
318     cpu_65c02_bra(self, !self->regs.bit.vf, cpu_65c02_ea_relative(self));
319     break;
320   case 0x51:
321     cpu_65c02_eor(self, cpu_65c02_read_byte(self, cpu_65c02_ea_zero_page_indirect_indexed(self, self->regs.byte.y)));
322     break;
323   case 0x52:
324     cpu_65c02_eor(self, cpu_65c02_read_byte(self, cpu_65c02_ea_zero_page_indirect(self)));
325     break;
326   case 0x53:
327     cpu_65c02_illegal_opcode11(self);
328     break;
329   case 0x54:
330     cpu_65c02_illegal_opcode24(self);
331     break;
332   case 0x55:
333     cpu_65c02_eor(self, cpu_65c02_read_byte(self, cpu_65c02_ea_zero_page_indexed(self, self->regs.byte.x)));
334     break;
335   case 0x56:
336     cpu_65c02_lsr(self, cpu_65c02_ea_zero_page_indexed(self, self->regs.byte.x));
337     break;
338   case 0x57:
339     cpu_65c02_rmb(self, 5, cpu_65c02_ea_zero_page(self));
340     break;
341   case 0x58:
342     cpu_65c02_cl(self, CPU_65C02_REG_P_BIT_I);
343     break;
344   case 0x59:
345     cpu_65c02_eor(self, cpu_65c02_read_byte(self, cpu_65c02_ea_absolute_indexed(self, self->regs.byte.y)));
346     break;
347   case 0x5a:
348     cpu_65c02_ph(self, self->regs.byte.y);
349     break;
350   case 0x5b:
351     cpu_65c02_illegal_opcode11(self);
352     break;
353   case 0x5c:
354     cpu_65c02_illegal_opcode38(self);
355     break;
356   case 0x5d:
357     cpu_65c02_eor(self, cpu_65c02_read_byte(self, cpu_65c02_ea_absolute_indexed(self, self->regs.byte.x)));
358     break;
359   case 0x5e:
360     cpu_65c02_lsr(self, cpu_65c02_ea_absolute_indexed(self, self->regs.byte.x));
361     break;
362   case 0x5f:
363     {
364       int rvalue = cpu_65c02_read_byte(self, cpu_65c02_ea_zero_page(self));
365       cpu_65c02_bra(self, !((rvalue >> 5) & 1), cpu_65c02_ea_relative(self));
366     }
367     break;
368   case 0x60:
369     cpu_65c02_rts(self);
370     break;
371   case 0x61:
372     cpu_65c02_adc(self, cpu_65c02_read_byte(self, cpu_65c02_ea_zero_page_indexed_indirect(self, self->regs.byte.x)));
373     break;
374   case 0x62:
375     cpu_65c02_illegal_opcode22(self);
376     break;
377   case 0x63:
378     cpu_65c02_illegal_opcode11(self);
379     break;
380   case 0x64:
381     cpu_65c02_st(self, 0, cpu_65c02_ea_zero_page(self));
382     break;
383   case 0x65:
384     cpu_65c02_adc(self, cpu_65c02_read_byte(self, cpu_65c02_ea_zero_page(self)));
385     break;
386   case 0x66:
387     cpu_65c02_ror(self, cpu_65c02_ea_zero_page(self));
388     break;
389   case 0x67:
390     cpu_65c02_rmb(self, 6, cpu_65c02_ea_zero_page(self));
391     break;
392   case 0x68:
393     cpu_65c02_pl(self, CPU_65C02_EA_A);
394     break;
395   case 0x69:
396     cpu_65c02_adc(self, cpu_65c02_fetch_byte(self));
397     break;
398   case 0x6a:
399     cpu_65c02_ror(self, CPU_65C02_EA_A);
400     break;
401   case 0x6b:
402     cpu_65c02_illegal_opcode11(self);
403     break;
404   case 0x6c:
405     cpu_65c02_jmp(self, cpu_65c02_ea_absolute_indirect(self));
406     break;
407   case 0x6d:
408     cpu_65c02_adc(self, cpu_65c02_read_byte(self, cpu_65c02_ea_absolute(self)));
409     break;
410   case 0x6e:
411     cpu_65c02_ror(self, cpu_65c02_ea_absolute(self));
412     break;
413   case 0x6f:
414     {
415       int rvalue = cpu_65c02_read_byte(self, cpu_65c02_ea_zero_page(self));
416       cpu_65c02_bra(self, !((rvalue >> 6) & 1), cpu_65c02_ea_relative(self));
417     }
418     break;
419   case 0x70:
420     cpu_65c02_bra(self, self->regs.bit.vf, cpu_65c02_ea_relative(self));
421     break;
422   case 0x71:
423     cpu_65c02_adc(self, cpu_65c02_read_byte(self, cpu_65c02_ea_zero_page_indirect_indexed(self, self->regs.byte.y)));
424     break;
425   case 0x72:
426     cpu_65c02_adc(self, cpu_65c02_read_byte(self, cpu_65c02_ea_zero_page_indirect(self)));
427     break;
428   case 0x73:
429     cpu_65c02_illegal_opcode11(self);
430     break;
431   case 0x74:
432     cpu_65c02_st(self, 0, cpu_65c02_ea_zero_page_indexed(self, self->regs.byte.x));
433     break;
434   case 0x75:
435     cpu_65c02_adc(self, cpu_65c02_read_byte(self, cpu_65c02_ea_zero_page_indexed(self, self->regs.byte.x)));
436     break;
437   case 0x76:
438     cpu_65c02_ror(self, cpu_65c02_ea_zero_page_indexed(self, self->regs.byte.x));
439     break;
440   case 0x77:
441     cpu_65c02_rmb(self, 7, cpu_65c02_ea_zero_page(self));
442     break;
443   case 0x78:
444     cpu_65c02_se(self, CPU_65C02_REG_P_BIT_I);
445     break;
446   case 0x79:
447     cpu_65c02_adc(self, cpu_65c02_read_byte(self, cpu_65c02_ea_absolute_indexed(self, self->regs.byte.y)));
448     break;
449   case 0x7a:
450     cpu_65c02_pl(self, CPU_65C02_EA_Y);
451     break;
452   case 0x7b:
453     cpu_65c02_illegal_opcode11(self);
454     break;
455   case 0x7c:
456     cpu_65c02_jmp(self, cpu_65c02_ea_absolute_indexed_indirect(self, self->regs.byte.x));
457     break;
458   case 0x7d:
459     cpu_65c02_adc(self, cpu_65c02_read_byte(self, cpu_65c02_ea_absolute_indexed(self, self->regs.byte.x)));
460     break;
461   case 0x7e:
462     cpu_65c02_ror(self, cpu_65c02_ea_absolute_indexed(self, self->regs.byte.x));
463     break;
464   case 0x7f:
465     {
466       int rvalue = cpu_65c02_read_byte(self, cpu_65c02_ea_zero_page(self));
467       cpu_65c02_bra(self, !((rvalue >> 7) & 1), cpu_65c02_ea_relative(self));
468     }
469     break;
470   case 0x80:
471     cpu_65c02_bra(self, true, cpu_65c02_ea_relative(self));
472     break;
473   case 0x81:
474     cpu_65c02_st(self, self->regs.byte.a, cpu_65c02_ea_zero_page_indexed_indirect(self, self->regs.byte.x));
475     break;
476   case 0x82:
477     cpu_65c02_illegal_opcode22(self);
478     break;
479   case 0x83:
480     cpu_65c02_illegal_opcode11(self);
481     break;
482   case 0x84:
483     cpu_65c02_st(self, self->regs.byte.y, cpu_65c02_ea_zero_page(self));
484     break;
485   case 0x85:
486     cpu_65c02_st(self, self->regs.byte.a, cpu_65c02_ea_zero_page(self));
487     break;
488   case 0x86:
489     cpu_65c02_st(self, self->regs.byte.x, cpu_65c02_ea_zero_page(self));
490     break;
491   case 0x87:
492     cpu_65c02_smb(self, 0, cpu_65c02_ea_zero_page(self));
493     break;
494   case 0x88:
495     cpu_65c02_dec(self, CPU_65C02_EA_Y);
496     break;
497   case 0x89:
498     cpu_65c02_bit_imm(self, cpu_65c02_fetch_byte(self));
499     break;
500   case 0x8a:
501     cpu_65c02_ld(self, CPU_65C02_EA_A, self->regs.byte.x);
502     break;
503   case 0x8b:
504     cpu_65c02_illegal_opcode11(self);
505     break;
506   case 0x8c:
507     cpu_65c02_st(self, self->regs.byte.y, cpu_65c02_ea_absolute(self));
508     break;
509   case 0x8d:
510     cpu_65c02_st(self, self->regs.byte.a, cpu_65c02_ea_absolute(self));
511     break;
512   case 0x8e:
513     cpu_65c02_st(self, self->regs.byte.x, cpu_65c02_ea_absolute(self));
514     break;
515   case 0x8f:
516     {
517       int rvalue = cpu_65c02_read_byte(self, cpu_65c02_ea_zero_page(self));
518       cpu_65c02_bra(self, rvalue & 1, cpu_65c02_ea_relative(self));
519     }
520     break;
521   case 0x90:
522     cpu_65c02_bra(self, !self->regs.bit.cf, cpu_65c02_ea_relative(self));
523     break;
524   case 0x91:
525     cpu_65c02_st(self, self->regs.byte.a, cpu_65c02_ea_zero_page_indirect_indexed(self, self->regs.byte.y));
526     break;
527   case 0x92:
528     cpu_65c02_st(self, self->regs.byte.a, cpu_65c02_ea_zero_page_indirect(self));
529     break;
530   case 0x93:
531     cpu_65c02_illegal_opcode11(self);
532     break;
533   case 0x94:
534     cpu_65c02_st(self, self->regs.byte.y, cpu_65c02_ea_zero_page_indexed(self, self->regs.byte.x));
535     break;
536   case 0x95:
537     cpu_65c02_st(self, self->regs.byte.a, cpu_65c02_ea_zero_page_indexed(self, self->regs.byte.x));
538     break;
539   case 0x96:
540     cpu_65c02_st(self, self->regs.byte.x, cpu_65c02_ea_zero_page_indexed(self, self->regs.byte.y));
541     break;
542   case 0x97:
543     cpu_65c02_smb(self, 1, cpu_65c02_ea_zero_page(self));
544     break;
545   case 0x98:
546     cpu_65c02_ld(self, CPU_65C02_EA_A, self->regs.byte.y);
547     break;
548   case 0x99:
549     cpu_65c02_st(self, self->regs.byte.a, cpu_65c02_ea_absolute_indexed(self, self->regs.byte.y));
550     break;
551   case 0x9a:
552     cpu_65c02_st(self, self->regs.byte.x, CPU_65C02_EA_S);
553     break;
554   case 0x9b:
555     cpu_65c02_illegal_opcode11(self);
556     break;
557   case 0x9c:
558     cpu_65c02_st(self, 0, cpu_65c02_ea_absolute(self));
559     break;
560   case 0x9d:
561     cpu_65c02_st(self, self->regs.byte.a, cpu_65c02_ea_absolute_indexed(self, self->regs.byte.x));
562     break;
563   case 0x9e:
564     cpu_65c02_st(self, 0, cpu_65c02_ea_absolute_indexed(self, self->regs.byte.x));
565     break;
566   case 0x9f:
567     {
568       int rvalue = cpu_65c02_read_byte(self, cpu_65c02_ea_zero_page(self));
569       cpu_65c02_bra(self, (rvalue >> 1) & 1, cpu_65c02_ea_relative(self));
570     }
571     break;
572   case 0xa0:
573     cpu_65c02_ld(self, CPU_65C02_EA_Y, cpu_65c02_fetch_byte(self));
574     break;
575   case 0xa1:
576     cpu_65c02_ld(self, CPU_65C02_EA_A, cpu_65c02_read_byte(self, cpu_65c02_ea_zero_page_indexed_indirect(self, self->regs.byte.x)));
577     break;
578   case 0xa2:
579     cpu_65c02_ld(self, CPU_65C02_EA_X, cpu_65c02_fetch_byte(self));
580     break;
581   case 0xa3:
582     cpu_65c02_illegal_opcode11(self);
583     break;
584   case 0xa4:
585     cpu_65c02_ld(self, CPU_65C02_EA_Y, cpu_65c02_read_byte(self, cpu_65c02_ea_zero_page(self)));
586     break;
587   case 0xa5:
588     cpu_65c02_ld(self, CPU_65C02_EA_A, cpu_65c02_read_byte(self, cpu_65c02_ea_zero_page(self)));
589     break;
590   case 0xa6:
591     cpu_65c02_ld(self, CPU_65C02_EA_X, cpu_65c02_read_byte(self, cpu_65c02_ea_zero_page(self)));
592     break;
593   case 0xa7:
594     cpu_65c02_smb(self, 2, cpu_65c02_ea_zero_page(self));
595     break;
596   case 0xa8:
597     cpu_65c02_ld(self, CPU_65C02_EA_Y, self->regs.byte.a);
598     break;
599   case 0xa9:
600     cpu_65c02_ld(self, CPU_65C02_EA_A, cpu_65c02_fetch_byte(self));
601     break;
602   case 0xaa:
603     cpu_65c02_ld(self, CPU_65C02_EA_X, self->regs.byte.a);
604     break;
605   case 0xab:
606     cpu_65c02_illegal_opcode11(self);
607     break;
608   case 0xac:
609     cpu_65c02_ld(self, CPU_65C02_EA_Y, cpu_65c02_read_byte(self, cpu_65c02_ea_absolute(self)));
610     break;
611   case 0xad:
612     cpu_65c02_ld(self, CPU_65C02_EA_A, cpu_65c02_read_byte(self, cpu_65c02_ea_absolute(self)));
613     break;
614   case 0xae:
615     cpu_65c02_ld(self, CPU_65C02_EA_X, cpu_65c02_read_byte(self, cpu_65c02_ea_absolute(self)));
616     break;
617   case 0xaf:
618     {
619       int rvalue = cpu_65c02_read_byte(self, cpu_65c02_ea_zero_page(self));
620       cpu_65c02_bra(self, (rvalue >> 2) & 1, cpu_65c02_ea_relative(self));
621     }
622     break;
623   case 0xb0:
624     cpu_65c02_bra(self, self->regs.bit.cf, cpu_65c02_ea_relative(self));
625     break;
626   case 0xb1:
627     cpu_65c02_ld(self, CPU_65C02_EA_A, cpu_65c02_read_byte(self, cpu_65c02_ea_zero_page_indirect_indexed(self, self->regs.byte.y)));
628     break;
629   case 0xb2:
630     cpu_65c02_ld(self, CPU_65C02_EA_A, cpu_65c02_read_byte(self, cpu_65c02_ea_zero_page_indirect(self)));
631     break;
632   case 0xb3:
633     cpu_65c02_illegal_opcode11(self);
634     break;
635   case 0xb4:
636     cpu_65c02_ld(self, CPU_65C02_EA_Y, cpu_65c02_read_byte(self, cpu_65c02_ea_zero_page_indexed(self, self->regs.byte.x)));
637     break;
638   case 0xb5:
639     cpu_65c02_ld(self, CPU_65C02_EA_A, cpu_65c02_read_byte(self, cpu_65c02_ea_zero_page_indexed(self, self->regs.byte.x)));
640     break;
641   case 0xb6:
642     cpu_65c02_ld(self, CPU_65C02_EA_X, cpu_65c02_read_byte(self, cpu_65c02_ea_zero_page_indexed(self, self->regs.byte.y)));
643     break;
644   case 0xb7:
645     cpu_65c02_smb(self, 3, cpu_65c02_ea_zero_page(self));
646     break;
647   case 0xb8:
648     cpu_65c02_cl(self, CPU_65C02_REG_P_BIT_V);
649     break;
650   case 0xb9:
651     cpu_65c02_ld(self, CPU_65C02_EA_A, cpu_65c02_read_byte(self, cpu_65c02_ea_absolute_indexed(self, self->regs.byte.y)));
652     break;
653   case 0xba:
654     cpu_65c02_ld(self, CPU_65C02_EA_X, self->regs.byte.s);
655     break;
656   case 0xbb:
657     cpu_65c02_illegal_opcode11(self);
658     break;
659   case 0xbc:
660     cpu_65c02_ld(self, CPU_65C02_EA_Y, cpu_65c02_read_byte(self, cpu_65c02_ea_absolute_indexed(self, self->regs.byte.x)));
661     break;
662   case 0xbd:
663     cpu_65c02_ld(self, CPU_65C02_EA_A, cpu_65c02_read_byte(self, cpu_65c02_ea_absolute_indexed(self, self->regs.byte.x)));
664     break;
665   case 0xbe:
666     cpu_65c02_ld(self, CPU_65C02_EA_X, cpu_65c02_read_byte(self, cpu_65c02_ea_absolute_indexed(self, self->regs.byte.y)));
667     break;
668   case 0xbf:
669     {
670       int rvalue = cpu_65c02_read_byte(self, cpu_65c02_ea_zero_page(self));
671       cpu_65c02_bra(self, (rvalue >> 3) & 1, cpu_65c02_ea_relative(self));
672     }
673     break;
674   case 0xc0:
675     cpu_65c02_cmp(self, self->regs.byte.y, cpu_65c02_fetch_byte(self));
676     break;
677   case 0xc1:
678     cpu_65c02_cmp(self, self->regs.byte.a, cpu_65c02_read_byte(self, cpu_65c02_ea_zero_page_indexed_indirect(self, self->regs.byte.x)));
679     break;
680   case 0xc2:
681     cpu_65c02_illegal_opcode22(self);
682     break;
683   case 0xc3:
684     cpu_65c02_illegal_opcode11(self);
685     break;
686   case 0xc4:
687     cpu_65c02_cmp(self, self->regs.byte.y, cpu_65c02_read_byte(self, cpu_65c02_ea_zero_page(self)));
688     break;
689   case 0xc5:
690     cpu_65c02_cmp(self, self->regs.byte.a, cpu_65c02_read_byte(self, cpu_65c02_ea_zero_page(self)));
691     break;
692   case 0xc6:
693     cpu_65c02_dec(self, cpu_65c02_ea_zero_page(self));
694     break;
695   case 0xc7:
696     cpu_65c02_smb(self, 4, cpu_65c02_ea_zero_page(self));
697     break;
698   case 0xc8:
699     cpu_65c02_inc(self, CPU_65C02_EA_Y);
700     break;
701   case 0xc9:
702     cpu_65c02_cmp(self, self->regs.byte.a, cpu_65c02_fetch_byte(self));
703     break;
704   case 0xca:
705     cpu_65c02_dec(self, CPU_65C02_EA_X);
706     break;
707   case 0xcb:
708     cpu_65c02_wai(self);
709     break;
710   case 0xcc:
711     cpu_65c02_cmp(self, self->regs.byte.y, cpu_65c02_read_byte(self, cpu_65c02_ea_absolute(self)));
712     break;
713   case 0xcd:
714     cpu_65c02_cmp(self, self->regs.byte.a, cpu_65c02_read_byte(self, cpu_65c02_ea_absolute(self)));
715     break;
716   case 0xce:
717     cpu_65c02_dec(self, cpu_65c02_ea_absolute(self));
718     break;
719   case 0xcf:
720     {
721       int rvalue = cpu_65c02_read_byte(self, cpu_65c02_ea_zero_page(self));
722       cpu_65c02_bra(self, (rvalue >> 4) & 1, cpu_65c02_ea_relative(self));
723     }
724     break;
725   case 0xd0:
726     cpu_65c02_bra(self, !self->regs.bit.zf, cpu_65c02_ea_relative(self));
727     break;
728   case 0xd1:
729     cpu_65c02_cmp(self, self->regs.byte.a, cpu_65c02_read_byte(self, cpu_65c02_ea_zero_page_indirect_indexed(self, self->regs.byte.y)));
730     break;
731   case 0xd2:
732     cpu_65c02_cmp(self, self->regs.byte.a, cpu_65c02_read_byte(self, cpu_65c02_ea_zero_page_indirect(self)));
733     break;
734   case 0xd3:
735     cpu_65c02_illegal_opcode11(self);
736     break;
737   case 0xd4:
738     cpu_65c02_illegal_opcode24(self);
739     break;
740   case 0xd5:
741     cpu_65c02_cmp(self, self->regs.byte.a, cpu_65c02_read_byte(self, cpu_65c02_ea_zero_page_indexed(self, self->regs.byte.x)));
742     break;
743   case 0xd6:
744     cpu_65c02_dec(self, cpu_65c02_ea_zero_page_indexed(self, self->regs.byte.x));
745     break;
746   case 0xd7:
747     cpu_65c02_smb(self, 5, cpu_65c02_ea_zero_page(self));
748     break;
749   case 0xd8:
750     cpu_65c02_cl(self, CPU_65C02_REG_P_BIT_D);
751     break;
752   case 0xd9:
753     cpu_65c02_cmp(self, self->regs.byte.a, cpu_65c02_read_byte(self, cpu_65c02_ea_absolute_indexed(self, self->regs.byte.y)));
754     break;
755   case 0xda:
756     cpu_65c02_ph(self, self->regs.byte.x);
757     break;
758   case 0xdb:
759     cpu_65c02_illegal_opcode11(self);
760     break;
761   case 0xdc:
762     cpu_65c02_illegal_opcode34(self);
763     break;
764   case 0xdd:
765     cpu_65c02_cmp(self, self->regs.byte.a, cpu_65c02_read_byte(self, cpu_65c02_ea_absolute_indexed(self, self->regs.byte.x)));
766     break;
767   case 0xde:
768     cpu_65c02_dec(self, cpu_65c02_ea_absolute_indexed(self, self->regs.byte.x));
769     break;
770   case 0xdf:
771     {
772       int rvalue = cpu_65c02_read_byte(self, cpu_65c02_ea_zero_page(self));
773       cpu_65c02_bra(self, (rvalue >> 5) & 1, cpu_65c02_ea_relative(self));
774     }
775     break;
776   case 0xe0:
777     cpu_65c02_cmp(self, self->regs.byte.x, cpu_65c02_fetch_byte(self));
778     break;
779   case 0xe1:
780     cpu_65c02_sbc(self, cpu_65c02_read_byte(self, cpu_65c02_ea_zero_page_indexed_indirect(self, self->regs.byte.x)));
781     break;
782   case 0xe2:
783     cpu_65c02_illegal_opcode22(self);
784     break;
785   case 0xe3:
786     cpu_65c02_illegal_opcode11(self);
787     break;
788   case 0xe4:
789     cpu_65c02_cmp(self, self->regs.byte.x, cpu_65c02_read_byte(self, cpu_65c02_ea_zero_page(self)));
790     break;
791   case 0xe5:
792     cpu_65c02_sbc(self, cpu_65c02_read_byte(self, cpu_65c02_ea_zero_page(self)));
793     break;
794   case 0xe6:
795     cpu_65c02_inc(self, cpu_65c02_ea_zero_page(self));
796     break;
797   case 0xe7:
798     cpu_65c02_smb(self, 6, cpu_65c02_ea_zero_page(self));
799     break;
800   case 0xe8:
801     cpu_65c02_inc(self, CPU_65C02_EA_X);
802     break;
803   case 0xe9:
804     cpu_65c02_sbc(self, cpu_65c02_fetch_byte(self));
805     break;
806   case 0xea:
807     cpu_65c02_nop(self);
808     break;
809   case 0xeb:
810     cpu_65c02_illegal_opcode11(self);
811     break;
812   case 0xec:
813     cpu_65c02_cmp(self, self->regs.byte.x, cpu_65c02_read_byte(self, cpu_65c02_ea_absolute(self)));
814     break;
815   case 0xed:
816     cpu_65c02_sbc(self, cpu_65c02_read_byte(self, cpu_65c02_ea_absolute(self)));
817     break;
818   case 0xee:
819     cpu_65c02_inc(self, cpu_65c02_ea_absolute(self));
820     break;
821   case 0xef:
822     {
823       int rvalue = cpu_65c02_read_byte(self, cpu_65c02_ea_zero_page(self));
824       cpu_65c02_bra(self, (rvalue >> 6) & 1, cpu_65c02_ea_relative(self));
825     }
826     break;
827   case 0xf0:
828     cpu_65c02_bra(self, self->regs.bit.zf, cpu_65c02_ea_relative(self));
829     break;
830   case 0xf1:
831     cpu_65c02_sbc(self, cpu_65c02_read_byte(self, cpu_65c02_ea_zero_page_indirect_indexed(self, self->regs.byte.y)));
832     break;
833   case 0xf2:
834     cpu_65c02_sbc(self, cpu_65c02_read_byte(self, cpu_65c02_ea_zero_page_indirect(self)));
835     break;
836   case 0xf3:
837     cpu_65c02_illegal_opcode11(self);
838     break;
839   case 0xf4:
840     cpu_65c02_illegal_opcode24(self);
841     break;
842   case 0xf5:
843     cpu_65c02_sbc(self, cpu_65c02_read_byte(self, cpu_65c02_ea_zero_page_indexed(self, self->regs.byte.x)));
844     break;
845   case 0xf6:
846     cpu_65c02_inc(self, cpu_65c02_ea_zero_page_indexed(self, self->regs.byte.x));
847     break;
848   case 0xf7:
849     cpu_65c02_smb(self, 7, cpu_65c02_ea_zero_page(self));
850     break;
851   case 0xf8:
852     cpu_65c02_se(self, CPU_65C02_REG_P_BIT_D);
853     break;
854   case 0xf9:
855     cpu_65c02_sbc(self, cpu_65c02_read_byte(self, cpu_65c02_ea_absolute_indexed(self, self->regs.byte.y)));
856     break;
857   case 0xfa:
858     cpu_65c02_pl(self, CPU_65C02_EA_X);
859     break;
860   case 0xfb:
861     cpu_65c02_illegal_opcode11(self);
862     break;
863   case 0xfc:
864     cpu_65c02_illegal_opcode34(self);
865     break;
866   case 0xfd:
867     cpu_65c02_sbc(self, cpu_65c02_read_byte(self, cpu_65c02_ea_absolute_indexed(self, self->regs.byte.x)));
868     break;
869   case 0xfe:
870     cpu_65c02_inc(self, cpu_65c02_ea_absolute_indexed(self, self->regs.byte.x));
871     break;
872   case 0xff:
873     {
874       int rvalue = cpu_65c02_read_byte(self, cpu_65c02_ea_zero_page(self));
875       cpu_65c02_bra(self, (rvalue >> 7) & 1, cpu_65c02_ea_relative(self));
876     }
877     break;
878   }
879 }