]> git.lizzy.rs Git - plan9front.git/blob - sys/src/games/snes/cpu.c
602d4ca8f03ec15e96a872c9389f55e22dba65c8
[plan9front.git] / sys / src / games / snes / cpu.c
1 #include <u.h>
2 #include <libc.h>
3 #include <thread.h>
4 #include "dat.h"
5 #include "fns.h"
6
7 u8int rP, emu, irq, nmi, dma, wai;
8 u16int rA, rX, rY, rS, rD, pc;
9 u32int rDB, rPB, curpc, hdma;
10 static u8int m8, x8;
11 int cyc;
12 static u32int lastpc;
13 #define io() cyc += 6
14
15 static void
16 ioirq(void)
17 {
18         if(irq && (rP & FLAGI) == 0)
19                 memread(pc | rPB);
20         else
21                 io();
22 }
23
24 static u8int
25 fetch8(void)
26 {
27         return memread(pc++ | rPB);
28 }
29
30 static u16int
31 fetch16(void)
32 {
33         u16int r;
34         
35         r = memread(pc++ | rPB);
36         r |= memread(pc++ | rPB) << 8;
37         return r;
38 }
39
40 static u16int
41 mem16(u32int a)
42 {
43         u16int r;
44
45         r = memread(a++);
46         r |= memread(a) << 8;
47         return r;
48 }
49
50 static u16int
51 mem816(u32int a, u16int v)
52 {
53         if(m8)
54                 return memread(a) | v;
55         return mem16(a);
56 }
57
58 static u16int
59 memx816(u32int a)
60 {
61         if(x8)
62                 return memread(a);
63         return mem16(a);
64 }
65
66
67 static void
68 memw816(u32int a, u16int v)
69 {
70         memwrite(a, v);
71         if(m8)
72                 return;
73         memwrite(++a, v >> 8);
74 }
75
76 static void
77 memwx816(u32int a, u16int v)
78 {
79         memwrite(a, v);
80         if(x8)
81                 return;
82         memwrite(++a, v >> 8);
83 }
84
85 static void
86 push8(u8int a)
87 {
88         memwrite(rS, a);
89         if(emu && (rS & 0xFF) == 0)
90                 rS |= 0xFF;
91         else
92                 rS--;
93 }
94
95 static u8int
96 pop8(void)
97 {
98         if(emu && (rS & 0xFF) == 0xFF)
99                 rS &= ~0xFF;
100         else
101                 rS++;
102         return memread(rS);
103 }
104
105 static void
106 push16(u16int a)
107 {
108         push8(a >> 8);
109         push8(a);
110 }
111
112 static u16int
113 pop16(void)
114 {
115         u16int r;
116         
117         r = pop8();
118         r |= pop8() << 8;
119         return r;
120 }
121
122 static void
123 push816(u16int v, int m)
124 {
125         if(!m)
126                 push8(v >> 8);
127         push8(v);
128 }
129
130 static u16int
131 pop816(u16int a, int m)
132 {
133         u16int r;
134
135         r = pop8();
136         if(m)
137                 return r | a;
138         r |= pop8() << 8;
139         return r;
140 }
141
142 static u16int
143 nz8(u16int v)
144 {
145         rP &= ~(FLAGN | FLAGZ);
146         if((v & 0xFF) == 0)
147                 rP |= FLAGZ;
148         rP |= (v & 0x80);
149         return v;
150 }
151
152 static u16int
153 nz16(u16int v)
154 {
155         rP &= ~(FLAGN | FLAGZ);
156         if(v == 0)
157                 rP |= FLAGZ;
158         if((v & 0x8000) != 0)
159                 rP |= FLAGN;
160         return v;
161 }
162
163 static u16int
164 nz(u16int v)
165 {
166         if(m8)
167                 return nz8(v);
168         return nz16(v);
169 }
170
171 static u16int
172 nzx(u16int v)
173 {
174         if(x8)
175                 return nz8(v);
176         return nz16(v);
177 }
178
179 static u16int
180 imm(int a)
181 {
182         if(m8)
183                 return fetch8() | a;
184         return fetch16();
185 }
186
187 static u16int
188 immx(int a)
189 {
190         if(x8)
191                 return fetch8() | a;
192         return fetch16();
193 }
194
195 static u32int
196 abso(int l, int x)
197 {
198         u32int p;
199         
200         p = fetch16();
201         if(l)
202                 p |= fetch8() << 16;
203         else
204                 p |= rDB;
205         switch(x){
206         case 1: p += rX; break;
207         case 2: p += rY; break;
208         }
209         return p;
210 }
211
212 static u32int
213 absi(int x)
214 {
215         u16int p;
216         u32int b, r;
217         
218         p = fetch16();
219         if(x){
220                 p += rX;
221                 b = rPB;
222                 io();
223         }else
224                 b = 0;
225         r = memread(p++ | b);
226         r |= memread(p | b) << 8;
227         return r;
228 }
229
230 static u32int
231 dp(int x)
232 {
233         u32int p;
234
235         p = fetch8();
236         switch(x){
237         case 1: p += rX; io(); break;
238         case 2: p += rY; io(); break;
239         }
240         if((rD & 0xFF) != 0)
241                 io();
242         else if(emu)
243                 return rD & 0xFF00 | p & 0xFF;
244         p = (p + rD) & 0xFFFF;
245         return p;
246 }
247
248 static u32int
249 dpi(int l, int x, int y)
250 {
251         u32int p, r, s;
252         u32int b;
253         
254         p = dp(x);
255         r = memread(p++);
256         if(emu && (rD & 0xFF) == 0){
257                 if((p & 0xFF) == 0)
258                         p -= 0x100;
259         }else
260                 p &= 0xFFFF;
261         r |= memread(p++) << 8;
262         if(l){
263                 if(emu && (rD & 0xFF) == 0){
264                         if((p & 0xFF) == 0)
265                                 p -= 0x100;
266                 }else
267                         p &= 0xFFFF;
268                 b = memread(p) << 16;
269         }else
270                 b = rDB;
271         if(y){
272                 s = r + rY;
273                 if(x8 && ((r ^ s) & 0xFF00) != 0)
274                         io();
275                 r = s;
276         }
277         r += b;
278         return r;
279 }
280
281 static u32int
282 sr(void)
283 {
284         u8int d;
285         
286         d = fetch8();
287         io();
288         return (rS + d) & 0xFFFF;
289 }
290
291 static u32int
292 sry(void)
293 {
294         u8int d;
295         u32int a;
296         
297         d = fetch8();
298         io();
299         a = (mem16((rS + d) & 0xFFFF) | rDB) + rY;
300         io();
301         return a;
302 }
303
304 static void
305 rmw(u32int a, u16int, u16int w)
306 {
307         io();
308         memw816(a, w);
309         nz(w);
310 }
311
312 static void
313 branch(int c)
314 {
315         signed char t;
316         u16int npc;
317         
318         t = fetch8();
319         if(!c)
320                 return;
321         npc = pc + t;
322         io();
323         if(emu && (npc ^ pc) >> 8)
324                 io();
325         pc = npc;
326 }
327
328 static void
329 setrp(u8int v)
330 {
331         if(emu)
332                 v |= 0x30;
333         else if((v & 0x10) != 0){
334                 rX &= 0xff;
335                 rY &= 0xff;
336         }
337         rP = v;
338 }
339
340 static void
341 adc(u16int a)
342 {
343         int r;
344
345         if(m8){
346                 if((rP & FLAGD) != 0){
347                         r = (rA & 0xf) + (a & 0xf) + (rP & FLAGC);
348                         if(r > 0x09)
349                                 r += 0x06;
350                         if(r > 0x1f)
351                                 r -= 0x10;
352                         r += (rA & 0xf0) + (a & 0xf0);
353                 }else
354                         r = (rA & 0xff) + a + (rP & FLAGC);
355                 rP &= ~(FLAGC | FLAGN | FLAGV | FLAGZ);
356                 if((~(rA ^ a) & (rA ^ r)) & 0x80)
357                         rP |= FLAGV;
358                 if((rP & FLAGD) != 0 && r > 0x9f)
359                         r += 0x60;
360                 if(r > 0xFF)
361                         rP |= FLAGC;
362                 rP |= r & 0x80;
363                 r &= 0xFF;
364                 if(r == 0)
365                         rP |= FLAGZ;
366                 rA = rA & 0xFF00 | r;
367         }else{
368                 if((rP & FLAGD) != 0){
369                         r  = (rA & 0x000f) + (a & 0x000f) + (rP & FLAGC);
370                         if(r > 0x0009) r += 0x0006;
371                         if(r > 0x001f) r -= 0x0010;
372                         r += (rA & 0x00f0) + (a & 0x00f0);
373                         if(r > 0x009f) r += 0x0060;
374                         if(r > 0x01ff) r -= 0x0100;
375                         r += (rA & 0x0f00) + (a & 0x0f00);
376                         if(r > 0x09ff) r += 0x0600;
377                         if(r > 0x1fff) r -= 0x1000;
378                         r += (rA & 0xf000) + (a & 0xf000);
379                 }else
380                         r = rA + a + (rP & FLAGC);
381                 rP &= ~(FLAGC | FLAGN | FLAGV | FLAGZ);
382                 if((~(rA ^ a) & (rA ^ r)) & 0x8000)
383                         rP |= FLAGV;
384                 if((rP & FLAGD) != 0 && r > 0x9fff)
385                         r += 0x6000;
386                 if(r > 0xFFFF)
387                         rP |= FLAGC;
388                 if((r & 0x8000) != 0)
389                         rP |= FLAGN;
390                 rA = r;
391                 if(rA == 0)
392                         rP |= FLAGZ;
393         }
394 }
395
396 static void
397 asl(u32int a)
398 {
399         u16int v;
400
401         v = mem816(a, 0);
402         rP &= ~FLAGC;
403         rP |= v >> (m8 ? 7 : 15);
404         rmw(a, v, v << 1);
405 }
406
407 static void
408 bit(u16int a)
409 {
410         rP &= ~(FLAGN | FLAGZ | FLAGV);
411         if((a & rA) == 0)
412                 rP |= FLAGZ;
413         if(m8)
414                 rP |= a & 0xC0;
415         else
416                 rP |= (a >> 8) & 0xC0;
417 }
418
419 static void
420 block(int incr)
421 {
422         u32int sb;
423         
424         rDB = fetch8() << 16;
425         sb = fetch8() << 16;
426         memwrite(rDB | rY, memread(sb | rX));
427         if(incr){
428                 rX++;
429                 rY++;
430         }else{
431                 rX--;
432                 rY--;
433         }
434         if(x8){
435                 rX &= 0xff;
436                 rY &= 0xff;
437         }
438         if(rA-- != 0)
439                 pc -= 3;
440         io();
441         io();
442 }
443
444 static void
445 cmp(u16int a, u16int b, int m)
446 {
447         if(m){
448                 a &= 0xff;
449                 b &= 0xff;
450         }
451         rP &= ~(FLAGN | FLAGZ | FLAGC);
452         if(a == b)
453                 rP |= FLAGZ;
454         if(a >= b)
455                 rP |= FLAGC;
456         if((a - b) & (m ? 0x80 : 0x8000))
457                 rP |= FLAGN;
458 }
459
460 static void
461 dec(u32int a)
462 {
463         u16int v;
464         
465         v = mem816(a, 0);
466         rmw(a, v, v-1);
467 }
468
469 static void
470 inc(u32int a)
471 {
472         u16int v;
473
474         v = mem816(a, 0);
475         rmw(a, v, v+1);
476 }
477
478 static void
479 lsr(u32int a)
480 {
481         u16int v;
482         
483         v = mem816(a, 0);
484         rP &= ~FLAGC;
485         rP |= v & 1;
486         rmw(a, v, v>>1);
487 }
488
489 static void
490 rol(u32int a)
491 {
492         u16int v, w;
493         
494         v = rP & FLAGC;
495         w = mem816(a, 0);
496         rP &= ~FLAGC;
497         rP |= w >> (m8 ? 7 : 15);
498         rmw(a, w, w<<1 | v);
499 }
500
501 static void
502 ror(u32int a)
503 {
504         u16int v, w;
505         
506         v = (rP & FLAGC) << (m8 ? 7 : 15);
507         w = mem816(a, 0);
508         rP &= ~FLAGC;
509         rP |= w & 1;
510         rmw(a, w, w>>1 | v);
511 }
512
513 static void
514 sbc(u16int a)
515 {
516         int r;
517
518         if(m8){
519                 a ^= 0xff;
520                 if((rP & FLAGD) != 0){
521                         r = (rA & 0xf) + (a & 0xf) + (rP & FLAGC);
522                         if(r < 0x10) r -= 0x06;
523                         if(r < 0) r += 0x10;
524                         r += (rA & 0xf0) + (a & 0xf0);
525                 }else
526                         r = (rA & 0xff) + a + (rP & FLAGC);
527                 rP &= ~(FLAGC | FLAGN | FLAGV | FLAGZ);
528                 if((~(rA ^ a) & (rA ^ r)) & 0x80)
529                         rP |= FLAGV;
530                 if(r > 0xff)
531                         rP |= FLAGC;
532                 else if((rP & FLAGD) != 0)
533                         r -= 0x60;
534                 rP |= r & 0x80;
535                 r &= 0xFF;
536                 if(r == 0)
537                         rP |= FLAGZ;
538                 rA = rA & 0xFF00 | r;
539         }else{
540                 a ^= 0xffff;
541                 if((rP & FLAGD) != 0){
542                         r  = (rA & 0x000f) + (a & 0x000f) + (rP & FLAGC);
543                         if(r < 0x0010) r -= 0x0006;
544                         if(r < 0x0000) r += 0x0010;
545                         r += (rA & 0x00f0) + (a & 0x00f0);
546                         if(r < 0x0100) r -= 0x0060;
547                         if(r < 0x0000) r += 0x0100;
548                         r += (rA & 0x0f00) + (a & 0x0f00);
549                         if(r < 0x1000) r -= 0x0600;
550                         if(r < 0x0000) r += 0x1000;
551                         r += (rA & 0xf000) + (a & 0xf000);
552                 }else
553                         r = rA + a + (rP & FLAGC);
554                 rP &= ~(FLAGC | FLAGN | FLAGV | FLAGZ);
555                 if((~(rA ^ a) & (rA ^ r)) & 0x8000)
556                         rP |= FLAGV;    
557                 if(r > 0xFFFF)
558                         rP |= FLAGC;
559                 else if((rP & FLAGD) != 0)
560                         r -= 0x6000;
561                 if((r & 0x8000) != 0)
562                         rP |= FLAGN;
563                 rA = r;
564                 if(rA == 0)
565                         rP |= FLAGZ;
566         }
567 }
568
569 static void
570 setra(u16int a)
571 {
572         if(m8)
573                 rA = rA & 0xff00 | nz8(a & 0xff);
574         else
575                 rA = nz16(a);
576 }
577
578 static void
579 setx(u16int a, u16int *b)
580 {
581         if(x8)
582                 *b = nz8(a & 0xff);
583         else
584                 *b = nz16(a);
585 }
586
587 static void
588 tsb(u32int a, int set)
589 {
590         u16int v;
591
592         v = mem816(a, 0);
593         rP &= ~FLAGZ;
594         if(m8){
595                 if((rA & v & 0xFF) == 0)
596                         rP |= FLAGZ;
597         }else
598                 if((rA & v) == 0)
599                         rP |= FLAGZ;
600         io();
601         if(set)
602                 memw816(a, v | rA);
603         else
604                 memw816(a, v & ~rA);
605 }
606
607 enum { COP = 0, BRK = 1, NMI = 3, IRQ = 5 };
608
609 static void
610 interrupt(int src)
611 {
612         if(src > BRK)
613                 memread(pc | rPB);
614         if(!emu)
615                 push8(rPB >> 16);
616         push16(pc);
617         if(emu && src != BRK)
618                 push8(rP & ~(1<<5));
619         else
620                 push8(rP);
621         if(emu && src == BRK)
622                 src = IRQ;
623         pc = mem16(0xffe4 + src * 2 + emu * 0x10);
624         rP |= FLAGI;
625         rP &= ~FLAGD;
626         rPB = 0;
627         if(emu)
628                 rDB = 0;
629         wai = 0;
630 }
631
632 void
633 cpureset(void)
634 {
635         pc = mem16(0xfffc);
636         rD = 0;
637         rDB = 0;
638         rPB = 0;
639         rS = 0x100;
640         rP = 0x35;
641 }
642
643 int trace;
644
645 int
646 cpustep(void)
647 {
648         u8int op;
649         int a;
650         static int cnt;
651
652         cyc = 0;
653         if((hdma & 0xffff) != 0){
654                 curpc = -1;
655                 return hdmastep();
656         }
657         if(dma){
658                 curpc = -1;
659                 return dmastep();
660         }
661         if(nmi)
662                 if(--nmi == 0){
663                         interrupt(NMI);
664                         return cyc;
665                 }
666         if(irq && (rP & FLAGI) == 0){
667                 interrupt(IRQ);
668                 return cyc;
669         }
670         curpc = pc|rPB;
671         if(wai){
672                 io();
673                 if(irq){
674                         wai = 0;
675                         io();
676                 }else
677                         return cyc;
678         }
679         m8 = (rP & FLAGM) != 0;
680         x8 = (rP & FLAGX) != 0;
681         op = fetch8();
682         if(op == 0)
683                 print("BRK PC=%.6x from PC=%.6x\n", curpc, lastpc);
684         lastpc = curpc;
685         if(trace)
686                 print("%.6x %.2x A=%.4x X=%.4x Y=%.4x P=%.2x %.2x\n", curpc, op, rA, rX, rY, rP, rS);
687         switch(op){
688         case 0x00: fetch8(); interrupt(BRK); break;
689         case 0x01: nz(rA |= mem816(dpi(0, 1, 0), 0)); break;
690         case 0x02: fetch8(); interrupt(COP); break;
691         case 0x03: nz(rA |= mem816(sr(), 0)); break;
692         case 0x04: tsb(dp(0), 1); break;
693         case 0x05: nz(rA |= mem816(dp(0), 0)); break;
694         case 0x06: asl(dp(0)); break;
695         case 0x07: nz(rA |= mem816(dpi(1, 0, 0), 0)); break;
696         case 0x08: io(); push8(rP); break;
697         case 0x09: nz(rA |= imm(0)); break;
698         case 0x0A:
699                 rP &= ~FLAGC;
700                 if(m8){
701                         rP |= (rA >> 7) & 1;
702                         rA = (rA & 0xFF00) | ((rA << 1) & 0xFF);
703                 }else{
704                         rP |= (rA >> 15) & 1;
705                         rA <<= 1;
706                 }
707                 nz(rA);
708                 ioirq();
709                 break;
710         case 0x0B: io(); push16(rD); break;
711         case 0x0C: tsb(abso(0, 0), 1); break;
712         case 0x0D: nz(rA |= mem816(abso(0, 0), 0)); break;
713         case 0x0E: asl(abso(0, 0)); break;
714         case 0x0F: nz(rA |= mem816(abso(1, 0), 0)); break;
715         case 0x10: branch((rP & FLAGN) == 0); break;
716         case 0x11: nz(rA |= mem816(dpi(0, 0, 1), 0)); break;
717         case 0x12: nz(rA |= mem816(dpi(0, 0, 0), 0)); break;
718         case 0x13: nz(rA |= mem816(sry(), 0)); break;
719         case 0x14: tsb(dp(0), 0); break;
720         case 0x15: nz(rA |= mem816(dp(1), 0)); break;
721         case 0x16: asl(dp(1)); break;
722         case 0x17: nz(rA |= mem816(dpi(1, 0, 1), 0)); break;
723         case 0x18: rP &= ~FLAGC; ioirq(); break;
724         case 0x19: nz(rA |= mem816(abso(0, 2), 0)); break;
725         case 0x1A:
726                 if(m8 && (rA & 0xFF) == 0xFF)
727                         rA &= ~0xFF;
728                 else
729                         rA++;
730                 nz(rA);
731                 ioirq();
732                 break;
733         case 0x1B: rS = rA; if(emu) rS = rS & 0xff | 0x100; ioirq(); break;
734         case 0x1C: tsb(abso(0, 0), 0); break;
735         case 0x1D: nz(rA |= mem816(abso(0, 1), 0)); break;
736         case 0x1E: asl(abso(0, 1)); break;
737         case 0x1F: nz(rA |= mem816(abso(1, 1), 0)); break;
738         case 0x20: a = fetch16(); io(); push16(pc-1); pc = a; break;
739         case 0x21: nz(rA &= mem816(dpi(0, 1, 0), 0xFF00)); break;
740         case 0x22: a = fetch16(); push8(rPB>>16); io(); rPB = fetch8()<<16; push16(pc-1); pc = a; break;
741         case 0x23: nz(rA &= mem816(sr(), 0xFF00)); break;
742         case 0x24: bit(mem816(dp(0), 0)); break;
743         case 0x25: nz(rA &= mem816(dp(0), 0xFF00)); break;
744         case 0x26: rol(dp(0)); break;
745         case 0x27: nz(rA &= mem816(dpi(1, 0, 0), 0xFF00)); break;
746         case 0x28: io(); io(); setrp(pop8()); break;
747         case 0x29: nz(rA &= imm(0xFF00)); break;
748         case 0x2A:
749                 a = rP & FLAGC;
750                 rP &= ~FLAGC;
751                 if(m8){
752                         rP |= (rA >> 7) & 1;
753                         rA = (rA & 0xFF00) | ((rA << 1) & 0xFF) | a;
754                 }else{
755                         rP |= (rA >> 15) & 1;
756                         rA = (rA << 1) | a;
757                 }
758                 nz(rA);
759                 ioirq();
760                 break;
761         case 0x2B: io(); io(); nz16(rD = pop16()); break;
762         case 0x2C: bit(mem816(abso(0, 0), 0)); break;
763         case 0x2D: nz(rA &= mem816(abso(0, 0), 0xFF00)); break;
764         case 0x2E: rol(abso(0, 0)); break;
765         case 0x2F: nz(rA &= mem816(abso(1, 0), 0xFF00)); break;
766         case 0x30: branch((rP & FLAGN) != 0); break;
767         case 0x31: nz(rA &= mem816(dpi(0, 0, 1), 0xFF00)); break;
768         case 0x32: nz(rA &= mem816(dpi(0, 0, 0), 0xFF00)); break;
769         case 0x33: nz(rA &= mem816(sry(), 0xFF00)); break;
770         case 0x34: bit(mem816(dp(1), 0)); break;
771         case 0x35: nz(rA &= mem816(dp(1), 0xFF00)); break;
772         case 0x36: rol(dp(1)); break;
773         case 0x37: nz(rA &= mem816(dpi(1, 0, 1), 0xFF00)); break;
774         case 0x38: rP |= FLAGC; ioirq(); break;
775         case 0x39: nz(rA &= mem816(abso(0, 2), 0xFF00)); break;
776         case 0x3A:
777                 if(m8 && (rA & 0xFF) == 0)
778                         rA |= 0xFF;
779                 else
780                         rA--;
781                 nz(rA);
782                 ioirq();
783                 break;
784         case 0x3B: nz16(rA = rS); ioirq(); break;
785         case 0x3C: bit(mem816(abso(0, 1), 0)); break;
786         case 0x3D: nz(rA &= mem816(abso(0, 1), 0xFF00)); break;
787         case 0x3E: rol(abso(0, 1)); break;
788         case 0x3F: nz(rA &= mem816(abso(1, 1), 0xFF00)); break;
789         case 0x40:
790                 io();
791                 io();
792                 setrp(pop8());
793                 pc = pop16();
794                 if(!emu)
795                         rPB = pop8() << 16;
796                 break;
797         case 0x41: nz(rA ^= mem816(dpi(0, 1, 0), 0)); break;
798         case 0x42: fetch8(); break;
799         case 0x43: nz(rA ^= mem816(sr(), 0)); break;
800         case 0x44: block(0); break;
801         case 0x45: nz(rA ^= mem816(dp(0), 0)); break;
802         case 0x46: lsr(dp(0)); break;
803         case 0x47: nz(rA ^= mem816(dpi(1, 0, 0), 0)); break;
804         case 0x48: io(); push816(rA, m8); break;
805         case 0x49: nz(rA ^= imm(0)); break;
806         case 0x4A:
807                 rP &= ~FLAGC;
808                 rP |= rA & 1;
809                 if(m8)
810                         rA = rA & 0xFF00 | (rA >> 1) & 0x7F;
811                 else
812                         rA >>= 1;
813                 nz(rA);
814                 ioirq();
815                 break;
816         case 0x4B: io(); push8(rPB >> 16); break;
817         case 0x4C: pc = fetch16(); break;
818         case 0x4D: nz(rA ^= mem816(abso(0, 0), 0)); break;
819         case 0x4E: lsr(abso(0, 0)); break;
820         case 0x4F: nz(rA ^= mem816(abso(1, 0), 0)); break;
821         case 0x50: branch((rP & FLAGV) == 0); break;
822         case 0x51: nz(rA ^= mem816(dpi(0, 0, 1), 0)); break;
823         case 0x52: nz(rA ^= mem816(dpi(0, 0, 0), 0)); break;
824         case 0x53: nz(rA ^= mem816(sry(), 0)); break;
825         case 0x54: block(1); break;
826         case 0x55: nz(rA ^= mem816(dp(1), 0)); break;
827         case 0x56: lsr(dp(1)); break;
828         case 0x57: nz(rA ^= mem816(dpi(1, 0, 1), 0)); break;
829         case 0x58: rP &= ~FLAGI; ioirq(); break;
830         case 0x59: nz(rA ^= mem816(abso(0, 2), 0)); break;
831         case 0x5A: io(); push816(rY, x8); break;
832         case 0x5B: nz16(rD = rA); ioirq(); break;
833         case 0x5C: a = fetch16(); rPB = fetch8() << 16; pc = a; break;
834         case 0x5D: nz(rA ^= mem816(abso(0, 1), 0)); break;
835         case 0x5E: lsr(abso(0, 1)); break;
836         case 0x5F: nz(rA ^= mem816(abso(1, 1), 0)); break;
837         case 0x60: io(); io(); pc = pop16() + 1; io(); break;
838         case 0x61: adc(mem816(dpi(0, 1, 0), 0)); break;
839         case 0x62: a = fetch16(); io(); push16(a + pc); break;
840         case 0x63: adc(mem816(sr(), 0)); break;
841         case 0x64: memw816(dp(0), 0); break;
842         case 0x65: adc(mem816(dp(0), 0)); break;
843         case 0x66: ror(dp(0)); break;
844         case 0x67: adc(mem816(dpi(1, 0, 0), 0)); break;
845         case 0x68: nz(rA = pop816(rA & 0xFF00, m8)); break;
846         case 0x69: adc(imm(0)); break;
847         case 0x6A:
848                 a = rP & FLAGC;
849                 rP &= ~FLAGC;
850                 rP |= rA & 1;
851                 if(m8)
852                         rA = rA & 0xFF00 | (rA >> 1) & 0x7F | a << 7;
853                 else
854                         rA = rA >> 1 | a << 15;
855                 nz(rA);
856                 ioirq();
857                 break;
858         case 0x6B: io(); io(); pc = pop16() + 1; rPB = pop8() << 16; break;
859         case 0x6C: pc = absi(0); break;
860         case 0x6D: adc(mem816(abso(0, 0), 0)); break;
861         case 0x6E: ror(abso(0, 0)); break;
862         case 0x6F: adc(mem816(abso(1, 0), 0)); break;
863         case 0x70: branch((rP & FLAGV) != 0); break;
864         case 0x71: adc(mem816(dpi(0, 0, 1), 0)); break;
865         case 0x72: adc(mem816(dpi(0, 0, 0), 0)); break;
866         case 0x73: adc(mem816(sry(), 0)); break;
867         case 0x74: memw816(dp(1), 0); break;
868         case 0x75: adc(mem816(dp(1), 0)); break;
869         case 0x76: ror(dp(1)); break;
870         case 0x77: adc(mem816(dpi(1, 0, 1), 0)); break;
871         case 0x78: rP |= FLAGI; io(); break;
872         case 0x79: adc(mem816(abso(0, 2), 0)); break;
873         case 0x7A: io(); io(); nzx(rY = pop816(0, x8)); break;
874         case 0x7B: nz16(rA = rD); ioirq(); break;
875         case 0x7C: pc = absi(1); break;
876         case 0x7D: adc(mem816(abso(0, 1), 0)); break;
877         case 0x7E: ror(abso(0, 1)); break;
878         case 0x7F: adc(mem816(abso(1, 1), 0)); break;
879         case 0x80: branch(1); break;
880         case 0x81: memw816(dpi(0, 1, 0), rA); break;
881         case 0x82: a = fetch16(); io(); pc += a; break;
882         case 0x83: memw816(sr(), rA); break;
883         case 0x84: memwx816(dp(0), rY); break;
884         case 0x85: memw816(dp(0), rA); break;
885         case 0x86: memwx816(dp(0), rX); break;
886         case 0x87: memw816(dpi(1, 0, 0), rA); break;
887         case 0x88: 
888                 rY--;
889                 if(x8)
890                         rY &= 0xff;
891                 nzx(rY);
892                 ioirq();
893                 break;
894         case 0x89:
895                 rP &= ~FLAGZ;
896                 if((imm(0) & rA) == 0)
897                         rP |= FLAGZ;
898                 break;
899         case 0x8A: setra(rX); ioirq(); break;
900         case 0x8B: io(); push8(rDB >> 16); break;
901         case 0x8C: memwx816(abso(0, 0), rY); break;
902         case 0x8D: memw816(abso(0, 0), rA); break;
903         case 0x8E: memwx816(abso(0, 0), rX); break;
904         case 0x8F: memw816(abso(1, 0), rA); break;
905         case 0x90: branch((rP & FLAGC) == 0); break;
906         case 0x91: memw816(dpi(0, 0, 1), rA); break;
907         case 0x92: memw816(dpi(0, 0, 0), rA); break;
908         case 0x93: memw816(sry(), rA); break;
909         case 0x94: memwx816(dp(1), rY); break;
910         case 0x95: memw816(dp(1), rA); break;
911         case 0x96: memwx816(dp(2), rX); break;
912         case 0x97: memw816(dpi(1, 0, 1), rA); break;
913         case 0x98: setra(rY); ioirq(); break;
914         case 0x99: memw816(abso(0, 2), rA); break;
915         case 0x9A: rS = rX; if(emu) rS = rS & 0xff | 0x100; ioirq(); break;
916         case 0x9B: setx(rX, &rY); ioirq(); break;
917         case 0x9C: memw816(abso(0, 0), 0); break;
918         case 0x9D: memw816(abso(0, 1), rA); break;
919         case 0x9E: memw816(abso(0, 1), 0); break;
920         case 0x9F: memw816(abso(1, 1), rA); break;
921         case 0xA0: nzx(rY = immx(0)); break;
922         case 0xA1: nz(rA = mem816(dpi(0, 1, 0), rA & 0xFF00)); break;
923         case 0xA2: nzx(rX = immx(0)); break;
924         case 0xA3: nz(rA = mem816(sr(), rA & 0xFF00)); break;
925         case 0xA4: nzx(rY = memx816(dp(0))); break;
926         case 0xA5: nz(rA = mem816(dp(0), rA & 0xFF00)); break;
927         case 0xA6: nzx(rX = memx816(dp(0))); break;
928         case 0xA7: nz(rA = mem816(dpi(1, 0, 0), rA & 0xFF00)); break;
929         case 0xA8: setx(rA, &rY); ioirq(); break;
930         case 0xA9: nz(rA = imm(rA & 0xFF00)); break;
931         case 0xAA: setx(rA, &rX); ioirq(); break;
932         case 0xAB: io(); io(); rDB = nz8(pop8()) << 16; break;
933         case 0xAC: nzx(rY = memx816(abso(0, 0))); break;
934         case 0xAD: nz(rA = mem816(abso(0, 0), rA & 0xFF00)); break;
935         case 0xAE: nzx(rX = memx816(abso(0, 0))); break;
936         case 0xAF: nz(rA = mem816(abso(1, 0), rA & 0xFF00)); break;
937         case 0xB0: branch((rP & FLAGC) != 0); break;
938         case 0xB1: nz(rA = mem816(dpi(0, 0, 1), rA & 0xFF00)); break;
939         case 0xB2: nz(rA = mem816(dpi(0, 0, 0), rA & 0xFF00)); break;
940         case 0xB3: nz(rA = mem816(sry(), rA & 0xFF00)); break;
941         case 0xB4: nzx(rY = memx816(dp(1))); break;
942         case 0xB5: nz(rA = mem816(dp(1), rA & 0xFF00)); break;
943         case 0xB6: nzx(rX = memx816(dp(2))); break;
944         case 0xB7: nz(rA = mem816(dpi(1, 0, 1), rA & 0xFF00)); break;
945         case 0xB8: rP &= ~FLAGV; ioirq(); break;
946         case 0xB9: nz(rA = mem816(abso(0, 2), rA & 0xFF00)); break;
947         case 0xBA: setx(rS, &rX); ioirq(); break;
948         case 0xBB: setx(rY, &rX); ioirq(); break;
949         case 0xBC: nzx(rY = memx816(abso(0, 1))); break;
950         case 0xBD: nz(rA = mem816(abso(0, 1), rA & 0xFF00)); break;
951         case 0xBE: nzx(rX = memx816(abso(0, 2))); break;
952         case 0xBF: nz(rA = mem816(abso(1, 1), rA & 0xFF00)); break;
953         case 0xC0: cmp(rY, immx(0), x8); break;
954         case 0xC1: cmp(rA, mem816(dpi(0, 1, 0), 0), m8); break;
955         case 0xC2: setrp(rP & ~fetch8()); io(); break;
956         case 0xC3: cmp(rA, mem816(sr(), 0), m8); break;
957         case 0xC4: cmp(rY, memx816(dp(0)), x8); break;
958         case 0xC5: cmp(rA, mem816(dp(0), 0), m8); break;
959         case 0xC6: dec(dp(0)); break;
960         case 0xC7: cmp(rA, mem816(dpi(1, 0, 0), 0), m8); break;
961         case 0xC8: 
962                 rY++;
963                 if(x8)
964                         rY &= 0xff;
965                 nzx(rY);
966                 ioirq();
967                 break;
968         case 0xC9: cmp(rA, imm(0), m8); break;
969         case 0xCA:
970                 rX--;
971                 if(x8)
972                         rX &= 0xff;
973                 nzx(rX);
974                 ioirq();
975                 break;
976         case 0xCB: wai = 1; break;
977         case 0xCC: cmp(rY, memx816(abso(0, 0)), x8); break;
978         case 0xCD: cmp(rA, mem816(abso(0, 0), 0), m8); break;
979         case 0xCE: dec(abso(0, 0)); break;
980         case 0xCF: cmp(rA, mem816(abso(1, 0), 0), m8); break;
981         case 0xD0: branch((rP & FLAGZ) == 0); break;
982         case 0xD1: cmp(rA, mem816(dpi(0, 0, 1), 0), m8); break;
983         case 0xD2: cmp(rA, mem816(dpi(0, 0, 0), 0), m8); break;
984         case 0xD3: cmp(rA, mem816(sry(), 0), m8); break;
985         case 0xD4: io(); push16(dpi(0, 0, 0)); break;
986         case 0xD5: cmp(rA, mem816(dp(1), 0), m8); break;
987         case 0xD6: dec(dp(1)); break;
988         case 0xD7: cmp(rA, mem816(dpi(1, 0, 1), 0), m8); break;
989         case 0xD8: rP &= ~FLAGD; ioirq(); break;
990         case 0xD9: cmp(rA, mem816(abso(0, 2), 0), m8); break;
991         case 0xDA: io(); push816(rX, x8); break;
992         case 0xDB: print("STP\n"); break;
993         case 0xDC: a = fetch16(); pc = memread(a) | memread((u16int)(a+1))<<8; rPB = memread((u16int)(a+2)) << 16; break;
994         case 0xDD: cmp(rA, mem816(abso(0, 1), 0), m8); break;
995         case 0xDE: dec(abso(0, 1)); break;
996         case 0xDF: cmp(rA, mem816(abso(1, 1), 0), m8); break;
997         case 0xE0: cmp(rX, immx(0), x8); break;
998         case 0xE1: sbc(mem816(dpi(0, 1, 0), 0)); break;
999         case 0xE2: setrp(rP | fetch8()); io(); break;
1000         case 0xE3: sbc(mem816(sr(), 0)); break;
1001         case 0xE4: cmp(rX, memx816(dp(0)), x8); break;
1002         case 0xE5: sbc(mem816(dp(0), 0)); break;
1003         case 0xE6: inc(dp(0)); break;
1004         case 0xE7: sbc(mem816(dpi(1, 0, 0), 0)); break;
1005         case 0xE8:
1006                 rX++;
1007                 if(x8)
1008                         rX &= 0xff;
1009                 nzx(rX);
1010                 ioirq();
1011                 break;
1012         case 0xE9: sbc(imm(0)); break;
1013         case 0xEA: ioirq(); break;
1014         case 0xEB: nz8(rA = (rA >> 8) | (rA << 8)); io(); io(); break;
1015         case 0xEC: cmp(rX, memx816(abso(0, 0)), x8); break;
1016         case 0xED: sbc(mem816(abso(0, 0), 0)); break;
1017         case 0xEE: inc(abso(0, 0)); break;
1018         case 0xEF: sbc(mem816(abso(1, 0), 0)); break;
1019         case 0xF0: branch((rP & FLAGZ) != 0); break;
1020         case 0xF1: sbc(mem816(dpi(0, 0, 1), 0)); break;
1021         case 0xF2: sbc(mem816(dpi(0, 0, 0), 0)); break;
1022         case 0xF3: sbc(mem816(sry(), 0)); break;
1023         case 0xF4: push16(fetch16()); break;
1024         case 0xF5: sbc(mem816(dp(1), 0)); break;
1025         case 0xF6: inc(dp(1)); break;
1026         case 0xF7: sbc(mem816(dpi(1, 0, 1), 0)); break;
1027         case 0xF8: rP |= FLAGD; ioirq(); break;
1028         case 0xF9: sbc(mem816(abso(0, 2), 0)); break;
1029         case 0xFA: nzx(rX = pop816(0, x8)); break;
1030         case 0xFB:
1031                 a = emu;
1032                 emu = rP & 1;
1033                 if(emu){
1034                         rX &= 0xff;
1035                         rY &= 0xff;
1036                         rS = rS & 0xff | 0x100;
1037                         rP |= 0x30;
1038                 }
1039                 rP &= ~1;
1040                 rP |= a;
1041                 ioirq();
1042                 break;
1043         case 0xFC: push16(pc+1); pc = absi(1); break;
1044         case 0xFD: sbc(mem816(abso(0, 1), 0)); break;
1045         case 0xFE: inc(abso(0, 1)); break;
1046         case 0xFF: sbc(mem816(abso(1, 1), 0)); break;
1047         default:
1048                 print("undefined %#x (pc %#.6x)\n", op, curpc);
1049                 io();
1050         }
1051         return cyc;
1052 }