ref: 2aec1f8a09ae0bc9fb269d84ef53defebc47eede
dir: /sys/src/games/snes/cpu.c/
#include <u.h> #include <libc.h> #include <thread.h> #include "../eui.h" #include "dat.h" #include "fns.h" u8int rP, emu, irq, nmi, dma, wai; u16int rA, rX, rY, rS, rD, pc; u32int rDB, rPB, curpc, hdma; static u8int m8, x8; int cyc; static u32int lastpc; #define io() cyc += 6 static void ioirq(void) { if(irq && (rP & FLAGI) == 0) memread(pc | rPB); else io(); } static u8int fetch8(void) { return memread(pc++ | rPB); } static u16int fetch16(void) { u16int r; r = memread(pc++ | rPB); r |= memread(pc++ | rPB) << 8; return r; } static u16int mem16(u32int a) { u16int r; r = memread(a++); r |= memread(a) << 8; return r; } static u16int mem816(u32int a, u16int v) { if(m8) return memread(a) | v; return mem16(a); } static u16int memx816(u32int a) { if(x8) return memread(a); return mem16(a); } static void memw816(u32int a, u16int v) { memwrite(a, v); if(m8) return; memwrite(++a, v >> 8); } static void memwx816(u32int a, u16int v) { memwrite(a, v); if(x8) return; memwrite(++a, v >> 8); } static void push8(u8int a) { memwrite(rS, a); if(emu && (rS & 0xFF) == 0) rS |= 0xFF; else rS--; } static u8int pop8(void) { if(emu && (rS & 0xFF) == 0xFF) rS &= ~0xFF; else rS++; return memread(rS); } static void push16(u16int a) { push8(a >> 8); push8(a); } static u16int pop16(void) { u16int r; r = pop8(); r |= pop8() << 8; return r; } static void push816(u16int v, int m) { if(!m) push8(v >> 8); push8(v); } static u16int pop816(u16int a, int m) { u16int r; r = pop8(); if(m) return r | a; r |= pop8() << 8; return r; } static u16int nz8(u16int v) { rP &= ~(FLAGN | FLAGZ); if((v & 0xFF) == 0) rP |= FLAGZ; rP |= (v & 0x80); return v; } static u16int nz16(u16int v) { rP &= ~(FLAGN | FLAGZ); if(v == 0) rP |= FLAGZ; if((v & 0x8000) != 0) rP |= FLAGN; return v; } static u16int nz(u16int v) { if(m8) return nz8(v); return nz16(v); } static u16int nzx(u16int v) { if(x8) return nz8(v); return nz16(v); } static u16int imm(int a) { if(m8) return fetch8() | a; return fetch16(); } static u16int immx(int a) { if(x8) return fetch8() | a; return fetch16(); } static u32int abso(int l, int x) { u32int p; p = fetch16(); if(l) p |= fetch8() << 16; else p |= rDB; switch(x){ case 1: p += rX; break; case 2: p += rY; break; } return p; } static u32int absi(int x) { u16int p; u32int b, r; p = fetch16(); if(x){ p += rX; b = rPB; io(); }else b = 0; r = memread(p++ | b); r |= memread(p | b) << 8; return r; } static u32int dp(int x) { u32int p; p = fetch8(); switch(x){ case 1: p += rX; io(); break; case 2: p += rY; io(); break; } if((rD & 0xFF) != 0) io(); else if(emu) return rD & 0xFF00 | p & 0xFF; p = (p + rD) & 0xFFFF; return p; } static u32int dpi(int l, int x, int y) { u32int p, r, s; u32int b; p = dp(x); r = memread(p++); if(emu && (rD & 0xFF) == 0){ if((p & 0xFF) == 0) p -= 0x100; }else p &= 0xFFFF; r |= memread(p++) << 8; if(l){ if(emu && (rD & 0xFF) == 0){ if((p & 0xFF) == 0) p -= 0x100; }else p &= 0xFFFF; b = memread(p) << 16; }else b = rDB; if(y){ s = r + rY; if(x8 && ((r ^ s) & 0xFF00) != 0) io(); r = s; } r += b; return r; } static u32int sr(void) { u8int d; d = fetch8(); io(); return (rS + d) & 0xFFFF; } static u32int sry(void) { u8int d; u32int a; d = fetch8(); io(); a = (mem16((rS + d) & 0xFFFF) | rDB) + rY; io(); return a; } static void rmw(u32int a, u16int, u16int w) { io(); memw816(a, w); nz(w); } static void branch(int c) { signed char t; u16int npc; t = fetch8(); if(!c) return; npc = pc + t; io(); if(emu && (npc ^ pc) >> 8) io(); pc = npc; } static void setrp(u8int v) { if(emu) v |= 0x30; else if((v & 0x10) != 0){ rX &= 0xff; rY &= 0xff; } rP = v; } static void adc(u16int a) { int r; if(m8){ if((rP & FLAGD) != 0){ r = (rA & 0xf) + (a & 0xf) + (rP & FLAGC); if(r > 0x09) r += 0x06; if(r > 0x1f) r -= 0x10; r += (rA & 0xf0) + (a & 0xf0); }else r = (rA & 0xff) + a + (rP & FLAGC); rP &= ~(FLAGC | FLAGN | FLAGV | FLAGZ); if((~(rA ^ a) & (rA ^ r)) & 0x80) rP |= FLAGV; if((rP & FLAGD) != 0 && r > 0x9f) r += 0x60; if(r > 0xFF) rP |= FLAGC; rP |= r & 0x80; r &= 0xFF; if(r == 0) rP |= FLAGZ; rA = rA & 0xFF00 | r; }else{ if((rP & FLAGD) != 0){ r = (rA & 0x000f) + (a & 0x000f) + (rP & FLAGC); if(r > 0x0009) r += 0x0006; if(r > 0x001f) r -= 0x0010; r += (rA & 0x00f0) + (a & 0x00f0); if(r > 0x009f) r += 0x0060; if(r > 0x01ff) r -= 0x0100; r += (rA & 0x0f00) + (a & 0x0f00); if(r > 0x09ff) r += 0x0600; if(r > 0x1fff) r -= 0x1000; r += (rA & 0xf000) + (a & 0xf000); }else r = rA + a + (rP & FLAGC); rP &= ~(FLAGC | FLAGN | FLAGV | FLAGZ); if((~(rA ^ a) & (rA ^ r)) & 0x8000) rP |= FLAGV; if((rP & FLAGD) != 0 && r > 0x9fff) r += 0x6000; if(r > 0xFFFF) rP |= FLAGC; if((r & 0x8000) != 0) rP |= FLAGN; rA = r; if(rA == 0) rP |= FLAGZ; } } static void asl(u32int a) { u16int v; v = mem816(a, 0); rP &= ~FLAGC; rP |= v >> (m8 ? 7 : 15); rmw(a, v, v << 1); } static void bit(u16int a) { rP &= ~(FLAGN | FLAGZ | FLAGV); if((a & rA) == 0) rP |= FLAGZ; if(m8) rP |= a & 0xC0; else rP |= (a >> 8) & 0xC0; } static void block(int incr) { u32int sb; rDB = fetch8() << 16; sb = fetch8() << 16; memwrite(rDB | rY, memread(sb | rX)); if(incr){ rX++; rY++; }else{ rX--; rY--; } if(x8){ rX &= 0xff; rY &= 0xff; } if(rA-- != 0) pc -= 3; io(); io(); } static void cmp(u16int a, u16int b, int m) { if(m){ a &= 0xff; b &= 0xff; } rP &= ~(FLAGN | FLAGZ | FLAGC); if(a == b) rP |= FLAGZ; if(a >= b) rP |= FLAGC; if((a - b) & (m ? 0x80 : 0x8000)) rP |= FLAGN; } static void dec(u32int a) { u16int v; v = mem816(a, 0); rmw(a, v, v-1); } static void inc(u32int a) { u16int v; v = mem816(a, 0); rmw(a, v, v+1); } static void lsr(u32int a) { u16int v; v = mem816(a, 0); rP &= ~FLAGC; rP |= v & 1; rmw(a, v, v>>1); } static void rol(u32int a) { u16int v, w; v = rP & FLAGC; w = mem816(a, 0); rP &= ~FLAGC; rP |= w >> (m8 ? 7 : 15); rmw(a, w, w<<1 | v); } static void ror(u32int a) { u16int v, w; v = (rP & FLAGC) << (m8 ? 7 : 15); w = mem816(a, 0); rP &= ~FLAGC; rP |= w & 1; rmw(a, w, w>>1 | v); } static void sbc(u16int a) { int r; if(m8){ a ^= 0xff; if((rP & FLAGD) != 0){ r = (rA & 0xf) + (a & 0xf) + (rP & FLAGC); if(r < 0x10) r -= 0x06; if(r < 0) r += 0x10; r += (rA & 0xf0) + (a & 0xf0); }else r = (rA & 0xff) + a + (rP & FLAGC); rP &= ~(FLAGC | FLAGN | FLAGV | FLAGZ); if((~(rA ^ a) & (rA ^ r)) & 0x80) rP |= FLAGV; if(r > 0xff) rP |= FLAGC; else if((rP & FLAGD) != 0) r -= 0x60; rP |= r & 0x80; r &= 0xFF; if(r == 0) rP |= FLAGZ; rA = rA & 0xFF00 | r; }else{ a ^= 0xffff; if((rP & FLAGD) != 0){ r = (rA & 0x000f) + (a & 0x000f) + (rP & FLAGC); if(r < 0x0010) r -= 0x0006; if(r < 0x0000) r += 0x0010; r += (rA & 0x00f0) + (a & 0x00f0); if(r < 0x0100) r -= 0x0060; if(r < 0x0000) r += 0x0100; r += (rA & 0x0f00) + (a & 0x0f00); if(r < 0x1000) r -= 0x0600; if(r < 0x0000) r += 0x1000; r += (rA & 0xf000) + (a & 0xf000); }else r = rA + a + (rP & FLAGC); rP &= ~(FLAGC | FLAGN | FLAGV | FLAGZ); if((~(rA ^ a) & (rA ^ r)) & 0x8000) rP |= FLAGV; if(r > 0xFFFF) rP |= FLAGC; else if((rP & FLAGD) != 0) r -= 0x6000; if((r & 0x8000) != 0) rP |= FLAGN; rA = r; if(rA == 0) rP |= FLAGZ; } } static void setra(u16int a) { if(m8) rA = rA & 0xff00 | nz8(a & 0xff); else rA = nz16(a); } static void setx(u16int a, u16int *b) { if(x8) *b = nz8(a & 0xff); else *b = nz16(a); } static void tsb(u32int a, int set) { u16int v; v = mem816(a, 0); rP &= ~FLAGZ; if(m8){ if((rA & v & 0xFF) == 0) rP |= FLAGZ; }else if((rA & v) == 0) rP |= FLAGZ; io(); if(set) memw816(a, v | rA); else memw816(a, v & ~rA); } enum { COP = 0, BRK = 1, NMI = 3, IRQ = 5 }; static void interrupt(int src) { if(src > BRK) memread(pc | rPB); if(!emu) push8(rPB >> 16); push16(pc); if(emu && src != BRK) push8(rP & ~(1<<5)); else push8(rP); if(emu && src == BRK) src = IRQ; pc = mem16(0xffe4 + src * 2 + emu * 0x10); rP |= FLAGI; rP &= ~FLAGD; rPB = 0; if(emu) rDB = 0; wai = 0; } void cpureset(void) { pc = mem16(0xfffc); rD = 0; rDB = 0; rPB = 0; rS = 0x100; rP = 0x35; } int cpustep(void) { u8int op; int a; static int cnt; cyc = 0; if((hdma & 0xffff) != 0){ curpc = -1; return hdmastep(); } if(dma){ curpc = -1; return dmastep(); } if(nmi) if(--nmi == 0){ interrupt(NMI); return cyc; } if(irq && (rP & FLAGI) == 0){ interrupt(IRQ); return cyc; } curpc = pc|rPB; if(wai){ io(); if(irq){ wai = 0; io(); }else return cyc; } m8 = (rP & FLAGM) != 0; x8 = (rP & FLAGX) != 0; op = fetch8(); if(op == 0) print("BRK PC=%.6x from PC=%.6x\n", curpc, lastpc); lastpc = curpc; if(trace) print("%.6x %.2x A=%.4x X=%.4x Y=%.4x P=%.2x %.2x\n", curpc, op, rA, rX, rY, rP, rS); switch(op){ case 0x00: fetch8(); interrupt(BRK); break; case 0x01: nz(rA |= mem816(dpi(0, 1, 0), 0)); break; case 0x02: fetch8(); interrupt(COP); break; case 0x03: nz(rA |= mem816(sr(), 0)); break; case 0x04: tsb(dp(0), 1); break; case 0x05: nz(rA |= mem816(dp(0), 0)); break; case 0x06: asl(dp(0)); break; case 0x07: nz(rA |= mem816(dpi(1, 0, 0), 0)); break; case 0x08: io(); push8(rP); break; case 0x09: nz(rA |= imm(0)); break; case 0x0A: rP &= ~FLAGC; if(m8){ rP |= (rA >> 7) & 1; rA = (rA & 0xFF00) | ((rA << 1) & 0xFF); }else{ rP |= (rA >> 15) & 1; rA <<= 1; } nz(rA); ioirq(); break; case 0x0B: io(); push16(rD); break; case 0x0C: tsb(abso(0, 0), 1); break; case 0x0D: nz(rA |= mem816(abso(0, 0), 0)); break; case 0x0E: asl(abso(0, 0)); break; case 0x0F: nz(rA |= mem816(abso(1, 0), 0)); break; case 0x10: branch((rP & FLAGN) == 0); break; case 0x11: nz(rA |= mem816(dpi(0, 0, 1), 0)); break; case 0x12: nz(rA |= mem816(dpi(0, 0, 0), 0)); break; case 0x13: nz(rA |= mem816(sry(), 0)); break; case 0x14: tsb(dp(0), 0); break; case 0x15: nz(rA |= mem816(dp(1), 0)); break; case 0x16: asl(dp(1)); break; case 0x17: nz(rA |= mem816(dpi(1, 0, 1), 0)); break; case 0x18: rP &= ~FLAGC; ioirq(); break; case 0x19: nz(rA |= mem816(abso(0, 2), 0)); break; case 0x1A: if(m8 && (rA & 0xFF) == 0xFF) rA &= ~0xFF; else rA++; nz(rA); ioirq(); break; case 0x1B: rS = rA; if(emu) rS = rS & 0xff | 0x100; ioirq(); break; case 0x1C: tsb(abso(0, 0), 0); break; case 0x1D: nz(rA |= mem816(abso(0, 1), 0)); break; case 0x1E: asl(abso(0, 1)); break; case 0x1F: nz(rA |= mem816(abso(1, 1), 0)); break; case 0x20: a = fetch16(); io(); push16(pc-1); pc = a; break; case 0x21: nz(rA &= mem816(dpi(0, 1, 0), 0xFF00)); break; case 0x22: a = fetch16(); push8(rPB>>16); io(); rPB = fetch8()<<16; push16(pc-1); pc = a; break; case 0x23: nz(rA &= mem816(sr(), 0xFF00)); break; case 0x24: bit(mem816(dp(0), 0)); break; case 0x25: nz(rA &= mem816(dp(0), 0xFF00)); break; case 0x26: rol(dp(0)); break; case 0x27: nz(rA &= mem816(dpi(1, 0, 0), 0xFF00)); break; case 0x28: io(); io(); setrp(pop8()); break; case 0x29: nz(rA &= imm(0xFF00)); break; case 0x2A: a = rP & FLAGC; rP &= ~FLAGC; if(m8){ rP |= (rA >> 7) & 1; rA = (rA & 0xFF00) | ((rA << 1) & 0xFF) | a; }else{ rP |= (rA >> 15) & 1; rA = (rA << 1) | a; } nz(rA); ioirq(); break; case 0x2B: io(); io(); nz16(rD = pop16()); break; case 0x2C: bit(mem816(abso(0, 0), 0)); break; case 0x2D: nz(rA &= mem816(abso(0, 0), 0xFF00)); break; case 0x2E: rol(abso(0, 0)); break; case 0x2F: nz(rA &= mem816(abso(1, 0), 0xFF00)); break; case 0x30: branch((rP & FLAGN) != 0); break; case 0x31: nz(rA &= mem816(dpi(0, 0, 1), 0xFF00)); break; case 0x32: nz(rA &= mem816(dpi(0, 0, 0), 0xFF00)); break; case 0x33: nz(rA &= mem816(sry(), 0xFF00)); break; case 0x34: bit(mem816(dp(1), 0)); break; case 0x35: nz(rA &= mem816(dp(1), 0xFF00)); break; case 0x36: rol(dp(1)); break; case 0x37: nz(rA &= mem816(dpi(1, 0, 1), 0xFF00)); break; case 0x38: rP |= FLAGC; ioirq(); break; case 0x39: nz(rA &= mem816(abso(0, 2), 0xFF00)); break; case 0x3A: if(m8 && (rA & 0xFF) == 0) rA |= 0xFF; else rA--; nz(rA); ioirq(); break; case 0x3B: nz16(rA = rS); ioirq(); break; case 0x3C: bit(mem816(abso(0, 1), 0)); break; case 0x3D: nz(rA &= mem816(abso(0, 1), 0xFF00)); break; case 0x3E: rol(abso(0, 1)); break; case 0x3F: nz(rA &= mem816(abso(1, 1), 0xFF00)); break; case 0x40: io(); io(); setrp(pop8()); pc = pop16(); if(!emu) rPB = pop8() << 16; break; case 0x41: nz(rA ^= mem816(dpi(0, 1, 0), 0)); break; case 0x42: fetch8(); break; case 0x43: nz(rA ^= mem816(sr(), 0)); break; case 0x44: block(0); break; case 0x45: nz(rA ^= mem816(dp(0), 0)); break; case 0x46: lsr(dp(0)); break; case 0x47: nz(rA ^= mem816(dpi(1, 0, 0), 0)); break; case 0x48: io(); push816(rA, m8); break; case 0x49: nz(rA ^= imm(0)); break; case 0x4A: rP &= ~FLAGC; rP |= rA & 1; if(m8) rA = rA & 0xFF00 | (rA >> 1) & 0x7F; else rA >>= 1; nz(rA); ioirq(); break; case 0x4B: io(); push8(rPB >> 16); break; case 0x4C: pc = fetch16(); break; case 0x4D: nz(rA ^= mem816(abso(0, 0), 0)); break; case 0x4E: lsr(abso(0, 0)); break; case 0x4F: nz(rA ^= mem816(abso(1, 0), 0)); break; case 0x50: branch((rP & FLAGV) == 0); break; case 0x51: nz(rA ^= mem816(dpi(0, 0, 1), 0)); break; case 0x52: nz(rA ^= mem816(dpi(0, 0, 0), 0)); break; case 0x53: nz(rA ^= mem816(sry(), 0)); break; case 0x54: block(1); break; case 0x55: nz(rA ^= mem816(dp(1), 0)); break; case 0x56: lsr(dp(1)); break; case 0x57: nz(rA ^= mem816(dpi(1, 0, 1), 0)); break; case 0x58: rP &= ~FLAGI; ioirq(); break; case 0x59: nz(rA ^= mem816(abso(0, 2), 0)); break; case 0x5A: io(); push816(rY, x8); break; case 0x5B: nz16(rD = rA); ioirq(); break; case 0x5C: a = fetch16(); rPB = fetch8() << 16; pc = a; break; case 0x5D: nz(rA ^= mem816(abso(0, 1), 0)); break; case 0x5E: lsr(abso(0, 1)); break; case 0x5F: nz(rA ^= mem816(abso(1, 1), 0)); break; case 0x60: io(); io(); pc = pop16() + 1; io(); break; case 0x61: adc(mem816(dpi(0, 1, 0), 0)); break; case 0x62: a = fetch16(); io(); push16(a + pc); break; case 0x63: adc(mem816(sr(), 0)); break; case 0x64: memw816(dp(0), 0); break; case 0x65: adc(mem816(dp(0), 0)); break; case 0x66: ror(dp(0)); break; case 0x67: adc(mem816(dpi(1, 0, 0), 0)); break; case 0x68: nz(rA = pop816(rA & 0xFF00, m8)); break; case 0x69: adc(imm(0)); break; case 0x6A: a = rP & FLAGC; rP &= ~FLAGC; rP |= rA & 1; if(m8) rA = rA & 0xFF00 | (rA >> 1) & 0x7F | a << 7; else rA = rA >> 1 | a << 15; nz(rA); ioirq(); break; case 0x6B: io(); io(); pc = pop16() + 1; rPB = pop8() << 16; break; case 0x6C: pc = absi(0); break; case 0x6D: adc(mem816(abso(0, 0), 0)); break; case 0x6E: ror(abso(0, 0)); break; case 0x6F: adc(mem816(abso(1, 0), 0)); break; case 0x70: branch((rP & FLAGV) != 0); break; case 0x71: adc(mem816(dpi(0, 0, 1), 0)); break; case 0x72: adc(mem816(dpi(0, 0, 0), 0)); break; case 0x73: adc(mem816(sry(), 0)); break; case 0x74: memw816(dp(1), 0); break; case 0x75: adc(mem816(dp(1), 0)); break; case 0x76: ror(dp(1)); break; case 0x77: adc(mem816(dpi(1, 0, 1), 0)); break; case 0x78: rP |= FLAGI; io(); break; case 0x79: adc(mem816(abso(0, 2), 0)); break; case 0x7A: io(); io(); nzx(rY = pop816(0, x8)); break; case 0x7B: nz16(rA = rD); ioirq(); break; case 0x7C: pc = absi(1); break; case 0x7D: adc(mem816(abso(0, 1), 0)); break; case 0x7E: ror(abso(0, 1)); break; case 0x7F: adc(mem816(abso(1, 1), 0)); break; case 0x80: branch(1); break; case 0x81: memw816(dpi(0, 1, 0), rA); break; case 0x82: a = fetch16(); io(); pc += a; break; case 0x83: memw816(sr(), rA); break; case 0x84: memwx816(dp(0), rY); break; case 0x85: memw816(dp(0), rA); break; case 0x86: memwx816(dp(0), rX); break; case 0x87: memw816(dpi(1, 0, 0), rA); break; case 0x88: rY--; if(x8) rY &= 0xff; nzx(rY); ioirq(); break; case 0x89: rP &= ~FLAGZ; if((imm(0) & rA) == 0) rP |= FLAGZ; break; case 0x8A: setra(rX); ioirq(); break; case 0x8B: io(); push8(rDB >> 16); break; case 0x8C: memwx816(abso(0, 0), rY); break; case 0x8D: memw816(abso(0, 0), rA); break; case 0x8E: memwx816(abso(0, 0), rX); break; case 0x8F: memw816(abso(1, 0), rA); break; case 0x90: branch((rP & FLAGC) == 0); break; case 0x91: memw816(dpi(0, 0, 1), rA); break; case 0x92: memw816(dpi(0, 0, 0), rA); break; case 0x93: memw816(sry(), rA); break; case 0x94: memwx816(dp(1), rY); break; case 0x95: memw816(dp(1), rA); break; case 0x96: memwx816(dp(2), rX); break; case 0x97: memw816(dpi(1, 0, 1), rA); break; case 0x98: setra(rY); ioirq(); break; case 0x99: memw816(abso(0, 2), rA); break; case 0x9A: rS = rX; if(emu) rS = rS & 0xff | 0x100; ioirq(); break; case 0x9B: setx(rX, &rY); ioirq(); break; case 0x9C: memw816(abso(0, 0), 0); break; case 0x9D: memw816(abso(0, 1), rA); break; case 0x9E: memw816(abso(0, 1), 0); break; case 0x9F: memw816(abso(1, 1), rA); break; case 0xA0: nzx(rY = immx(0)); break; case 0xA1: nz(rA = mem816(dpi(0, 1, 0), rA & 0xFF00)); break; case 0xA2: nzx(rX = immx(0)); break; case 0xA3: nz(rA = mem816(sr(), rA & 0xFF00)); break; case 0xA4: nzx(rY = memx816(dp(0))); break; case 0xA5: nz(rA = mem816(dp(0), rA & 0xFF00)); break; case 0xA6: nzx(rX = memx816(dp(0))); break; case 0xA7: nz(rA = mem816(dpi(1, 0, 0), rA & 0xFF00)); break; case 0xA8: setx(rA, &rY); ioirq(); break; case 0xA9: nz(rA = imm(rA & 0xFF00)); break; case 0xAA: setx(rA, &rX); ioirq(); break; case 0xAB: io(); io(); rDB = nz8(pop8()) << 16; break; case 0xAC: nzx(rY = memx816(abso(0, 0))); break; case 0xAD: nz(rA = mem816(abso(0, 0), rA & 0xFF00)); break; case 0xAE: nzx(rX = memx816(abso(0, 0))); break; case 0xAF: nz(rA = mem816(abso(1, 0), rA & 0xFF00)); break; case 0xB0: branch((rP & FLAGC) != 0); break; case 0xB1: nz(rA = mem816(dpi(0, 0, 1), rA & 0xFF00)); break; case 0xB2: nz(rA = mem816(dpi(0, 0, 0), rA & 0xFF00)); break; case 0xB3: nz(rA = mem816(sry(), rA & 0xFF00)); break; case 0xB4: nzx(rY = memx816(dp(1))); break; case 0xB5: nz(rA = mem816(dp(1), rA & 0xFF00)); break; case 0xB6: nzx(rX = memx816(dp(2))); break; case 0xB7: nz(rA = mem816(dpi(1, 0, 1), rA & 0xFF00)); break; case 0xB8: rP &= ~FLAGV; ioirq(); break; case 0xB9: nz(rA = mem816(abso(0, 2), rA & 0xFF00)); break; case 0xBA: setx(rS, &rX); ioirq(); break; case 0xBB: setx(rY, &rX); ioirq(); break; case 0xBC: nzx(rY = memx816(abso(0, 1))); break; case 0xBD: nz(rA = mem816(abso(0, 1), rA & 0xFF00)); break; case 0xBE: nzx(rX = memx816(abso(0, 2))); break; case 0xBF: nz(rA = mem816(abso(1, 1), rA & 0xFF00)); break; case 0xC0: cmp(rY, immx(0), x8); break; case 0xC1: cmp(rA, mem816(dpi(0, 1, 0), 0), m8); break; case 0xC2: setrp(rP & ~fetch8()); io(); break; case 0xC3: cmp(rA, mem816(sr(), 0), m8); break; case 0xC4: cmp(rY, memx816(dp(0)), x8); break; case 0xC5: cmp(rA, mem816(dp(0), 0), m8); break; case 0xC6: dec(dp(0)); break; case 0xC7: cmp(rA, mem816(dpi(1, 0, 0), 0), m8); break; case 0xC8: rY++; if(x8) rY &= 0xff; nzx(rY); ioirq(); break; case 0xC9: cmp(rA, imm(0), m8); break; case 0xCA: rX--; if(x8) rX &= 0xff; nzx(rX); ioirq(); break; case 0xCB: wai = 1; break; case 0xCC: cmp(rY, memx816(abso(0, 0)), x8); break; case 0xCD: cmp(rA, mem816(abso(0, 0), 0), m8); break; case 0xCE: dec(abso(0, 0)); break; case 0xCF: cmp(rA, mem816(abso(1, 0), 0), m8); break; case 0xD0: branch((rP & FLAGZ) == 0); break; case 0xD1: cmp(rA, mem816(dpi(0, 0, 1), 0), m8); break; case 0xD2: cmp(rA, mem816(dpi(0, 0, 0), 0), m8); break; case 0xD3: cmp(rA, mem816(sry(), 0), m8); break; case 0xD4: io(); push16(dpi(0, 0, 0)); break; case 0xD5: cmp(rA, mem816(dp(1), 0), m8); break; case 0xD6: dec(dp(1)); break; case 0xD7: cmp(rA, mem816(dpi(1, 0, 1), 0), m8); break; case 0xD8: rP &= ~FLAGD; ioirq(); break; case 0xD9: cmp(rA, mem816(abso(0, 2), 0), m8); break; case 0xDA: io(); push816(rX, x8); break; case 0xDB: print("STP\n"); break; case 0xDC: a = fetch16(); pc = memread(a) | memread((u16int)(a+1))<<8; rPB = memread((u16int)(a+2)) << 16; break; case 0xDD: cmp(rA, mem816(abso(0, 1), 0), m8); break; case 0xDE: dec(abso(0, 1)); break; case 0xDF: cmp(rA, mem816(abso(1, 1), 0), m8); break; case 0xE0: cmp(rX, immx(0), x8); break; case 0xE1: sbc(mem816(dpi(0, 1, 0), 0)); break; case 0xE2: setrp(rP | fetch8()); io(); break; case 0xE3: sbc(mem816(sr(), 0)); break; case 0xE4: cmp(rX, memx816(dp(0)), x8); break; case 0xE5: sbc(mem816(dp(0), 0)); break; case 0xE6: inc(dp(0)); break; case 0xE7: sbc(mem816(dpi(1, 0, 0), 0)); break; case 0xE8: rX++; if(x8) rX &= 0xff; nzx(rX); ioirq(); break; case 0xE9: sbc(imm(0)); break; case 0xEA: ioirq(); break; case 0xEB: nz8(rA = (rA >> 8) | (rA << 8)); io(); io(); break; case 0xEC: cmp(rX, memx816(abso(0, 0)), x8); break; case 0xED: sbc(mem816(abso(0, 0), 0)); break; case 0xEE: inc(abso(0, 0)); break; case 0xEF: sbc(mem816(abso(1, 0), 0)); break; case 0xF0: branch((rP & FLAGZ) != 0); break; case 0xF1: sbc(mem816(dpi(0, 0, 1), 0)); break; case 0xF2: sbc(mem816(dpi(0, 0, 0), 0)); break; case 0xF3: sbc(mem816(sry(), 0)); break; case 0xF4: push16(fetch16()); break; case 0xF5: sbc(mem816(dp(1), 0)); break; case 0xF6: inc(dp(1)); break; case 0xF7: sbc(mem816(dpi(1, 0, 1), 0)); break; case 0xF8: rP |= FLAGD; ioirq(); break; case 0xF9: sbc(mem816(abso(0, 2), 0)); break; case 0xFA: nzx(rX = pop816(0, x8)); break; case 0xFB: a = emu; emu = rP & 1; if(emu){ rX &= 0xff; rY &= 0xff; rS = rS & 0xff | 0x100; rP |= 0x30; } rP &= ~1; rP |= a; ioirq(); break; case 0xFC: push16(pc+1); pc = absi(1); break; case 0xFD: sbc(mem816(abso(0, 1), 0)); break; case 0xFE: inc(abso(0, 1)); break; case 0xFF: sbc(mem816(abso(1, 1), 0)); break; default: print("undefined %#x (pc %#.6x)\n", op, curpc); io(); } return cyc; }