static constexpr trans[80]={ 0, 1, 0, 2, 4, 7, 256, 257, 1280, 2048, 2564, 2565, 3072, 3076, 4096, 4112, 4113, 4369, 65536, 65537, 917514, 917515, 921610, 15728650, 16777216, 16777217, 16777472, 16780288, 16780544, 16842752, 16842753, 16843009, 83887360, 134217728, 168689664, 201326592, 269488401, 286265617, 587133178, 808452106, 838991872, 2863309482U, 2863309483U, 2863311530U, 2863312558U, 2863312814U, 2863313594U, 2863315643U, 2863316670U, 2863379130U, 3356229632U, 3368861896U, 3368862152U, 3368862920U, 3368862924U, 3368864972U, 3402498048U, 3435973836U, 3623878656U, 3722233288U, 0, 3722233289U, 3722233304U, 3722233305U, 3722237401U, 3941523690U, 3941527278U, 3941527534U, 3941527802U, 3941530619U, 3941531390U, 3941531643U, 4042260490U, 4194365440U, 4194365441U, 4195221504U, 4211011834U, 4211077370U, 4211077371U, 4278124543U }; enum { o32 = op/32, o32m = 1u << (op % 32) }; #define t(s, code) { enum { i = o32m & trans[s[o32m]-32] }; if(i) { code; } } /* Decode address operand */ t(" !", addr = 0xFFFA) // NMI vector location t(" #", addr = 0xFFFC) // Reset vector location t("! $", addr = 0xFFFE) // Interrupt vector location t("mnmmmmmm ", addr = RB(PC++)) t("hhhhGGhh ", d = X) // register index t("BBBBXXBB ", d = Y) t("77777777 ", addr=u8(addr+d); d=0; tick()) // add zeropage-index t("ijiiiiii ", addr=u8(addr); addr+=256*RB(PC++)) // absolute address t("54464444%", addr=RB(c=addr); addr+=256*RB(wrap(c,c+1)))// indirect w/ page wrap t("HHHH kHH ", Misfire(addr, addr+d)) // abs. load: extra misread when cross-page t("RRRRk RR ", RB(wrap(addr, addr+d)))// abs. store: always issue a misread /* Load source operand */ t("LPM-K(K ", t &= A) // Many operations take A or X as operand. Some try in t(" Y ,1 ", t &= X) // error to take both; the outcome is an AND operation. t(" E 1 ", t &= Y) // sty,dey,iny,tya,cpy t(" C ", t &= S) // tsx, las t("?===2===%", t &= P.raw|pbits; c = t)// php, flag test/set/clear, interrupts t("INI O0 ", c = t; t = 0xFF) // save as second operand t("adaa ldd ", t &= RB(addr+d)) // memory operand t("****++++ ", t &= RB(PC++)) // immediate operand /* Operations that mogrify memory operands directly */ t(" / ", P.V = t & 0x40; P.N = t & 0x80) // bit t(" V W ", sb = P.C) // rol,rla, ror,rra,arr t("WW ) ", P.C = t & 0x80) // rol,rla, asl,slo,[arr,anc] t(" WV ", P.C = t & 0x01) // lsr,sre, ror,rra,asr t("VV ", t = (t << 1) | (sb << 0)) t(" WW ", t = (t >> 1) | (sb << 7)) t(" & U ", t = u8(t - 1)) // dec,dex,dey,dcp t(" &T ", t = u8(t + 1)) // inc,inx,iny,isb /* Store modified value (memory) */ t("SSSSF SS ", WB(addr+d, t)) t(" Z ", WB(wrap(addr, addr+d), t &= ((addr+d) >> 8))) // [shx,shy,shs,sha?] /* Some operations used up one clock cycle that we did not account for yet */ t("`]^_@@[[%", tick()) // nop,flag ops,inc,dec,shifts,stack,transregister,interrupts /* Stack operations and unconditional jumps */ t(" &!& ", tick(); t = Pop()) // pla,plp,rti t(" !! ", RB(PC++); PC = Pop(); PC |= (Pop() << 8)) // rti,rts t(" ! ", RB(PC++)) // rts t("!! %", d=PC+(op?-1:1); Push(d>>8); Push(d)) // jsr, interrupts t("!!.. %", PC = addr) // jmp, jsr, interrupts t("' & %", Push(t)) // pha, php, interrupts /* Bitmasks */ t(">===2===%", t = 1) t("22 == ", t <<= 1) t("32== 888%", t <<= 2) t("2222 8 ", t <<= 4) t("8 8 88K ", t = u8(~t)) // sbc, isb, clear flag t("J8 8 8%", t = c | t) // ora, slo, set flag t("=Q=22==2 ", t = c & t) // and, bit, rla, clear/test flag t(" I ", t = c ^ t) // eor, sre /* Conditional branches */ t(" 2 2 2 2 ", if(t) { tick(); Misfire(PC, addr = s8(addr) + PC); PC=addr; }) t("2 2 2 2 ", if(!t) { tick(); Misfire(PC, addr = s8(addr) + PC); PC=addr; }) /* Addition and subtraction */ t(" I K ", c = t; t += A + P.C; P.V = (c^t) & (A^t) & 0x80; P.C = t & 0x100) t(" O0 ", t = c - t; P.C = ~t & 0x100) // cmp,cpx,cpy, dcp, sbx /* Store modified value (register) */ t("LLLM;K K ", A = t) t(" Y,& ", X = t) // ldx, dex, tax, inx, tsx,lax,las,sbx t(" &D& ", Y = t) // ldy, dey, tay, iny t(" CA ", S = t) // txs, las, shs t("9:98 888%", P.raw = t & ~0x30) // plp, rti, flag set/clear /* Generic status flag updates */ t("bbbc> 5)+1)&2)) // [arr]