ref: df6478340d048ba76ab8e96aaaf490930a778eae
dir: /das.c/
#include <u.h> #include <libc.h> #include <bio.h> #include "dat.h" #include "fns.h" static void Xshld(CPU*, Insn*); static void Xsbi(CPU*, Insn*); static void Xjm(CPU*, Insn*); static void Xdaa(CPU*, Insn*); static void Xcz(CPU*, Insn*); static void Xpchl(CPU*, Insn*); static void Xnop(CPU*, Insn*); static void Xjmp(CPU*, Insn*); static void Xlxi(CPU*, Insn*); static void Xmvi(CPU*, Insn*); static void Xpop(CPU*, Insn*); static void Xcall(CPU*, Insn*); static void Xldax(CPU*, Insn*); static void Xmov(CPU*, Insn*); static void Xinx(CPU*, Insn*); static void Xdcr(CPU*, Insn*); static void Xret(CPU*, Insn*); static void Xdad(CPU*, Insn*); static void Xsta(CPU*, Insn*); static void Xxra(CPU*, Insn*); static void Xout(CPU*, Insn*); static void Xora(CPU*, Insn*); static void Xlda(CPU*, Insn*); static void Xana(CPU*, Insn*); static void Xpush(CPU*, Insn*); static void Xxchg(CPU*, Insn*); static void Xinr(CPU*, Insn*); static void Xani(CPU*, Insn*); static void Xrar(CPU*, Insn*); static void Xori(CPU*, Insn*); static void Xcmp(CPU*, Insn*); static void Xrlc(CPU*, Insn*); static void Xrim(CPU*, Insn*); static void Xrrc(CPU*, Insn*); static void Xdcx(CPU*, Insn*); static void Xstax(CPU*, Insn*); static void Xcpi(CPU*, Insn*); static void Xadi(CPU*, Insn*); static void Xei(CPU*, Insn*); static void Xdi(CPU*, Insn*); static void Xin(CPU*, Insn*); static void Xjc(CPU*, Insn*); static void Xjz(CPU*, Insn*); static void Xjnc(CPU*, Insn*); static void Xjnz(CPU*, Insn*); static void Xrc(CPU*, Insn*); static void Xrnc(CPU*, Insn*); static void Xrnz(CPU*, Insn*); static void Xrz(CPU*, Insn*); static void Xsui(CPU*, Insn*); static void Xxthl(CPU*, Insn*); static int dec0(Insn*, uchar*, long); static int decaddr(Insn*, uchar*, long); static int decimm(Insn*, uchar*, long); static int decr00000xxx(Insn*, uchar*, long); static int decr00xxx000(Insn*, uchar*, long); static int decrimm(Insn*, uchar*, long); static int decrp(Insn*, uchar*, long); static int decrpimm(Insn*, uchar*, long); static int decrr(Insn*, uchar*, long); static int das0(Fmt*, Insn*); static int dasaddr(Fmt*, Insn*); static int dasimm(Fmt*, Insn*); static int dasr(Fmt*, Insn*); static int dasrimm(Fmt*, Insn*); static int dasrp(Fmt*, Insn*); static int dasrpimm(Fmt*, Insn*); static int dasrr(Fmt*, Insn*); static InsnType insntypes[] = { [T0] = { 1, das0, dec0 }, [Taddr] = { 3, dasaddr, decaddr }, [Timm] = { 2, dasimm, decimm }, [Tr012] = { 1, dasr, decr00000xxx }, [Tr345] = { 1, dasr, decr00xxx000 }, [Trimm] = { 2, dasrimm, decrimm }, [Trp] = { 1, dasrp, decrp }, [Trpimm] = { 3, dasrpimm, decrpimm }, [Trr] = { 1, dasrr, decrr }, }; static ISA isa[] = { [Oadc]{"ADC", Tr012}, [Oadd]{"ADD", Tr012}, [Oadi]{"ADI", Timm, Xadi}, [Oana]{"ANA", Tr012, Xana}, [Oani]{"ANI", Timm, Xani}, [Ocall]{"CALL", Taddr, Xcall}, [Ocm]{"CM", Taddr}, [Ocma]{"CMA", T0}, [Ocmc]{"CMC", T0}, [Ocmp]{"CMP", Tr012, Xcmp}, [Ocnc]{"CNC", Taddr}, [Ocpe]{"CPE", Taddr}, [Ocpi]{"CPI", Timm, Xcpi}, [Ocz]{"CZ", Taddr, Xcz}, [Odaa]{"DAA", T0, Xdaa}, [Odad]{"DAD", Trp, Xdad}, [Odcr]{"DCR", Tr345, Xdcr}, [Odcx]{"DCX", Trp, Xdcx}, [Odi]{"DI", T0, Xdi}, [Oei]{"EI", T0, Xei}, [Oin]{"IN", Timm, Xin}, [Oinr]{"INR", Tr345, Xinr}, [Oinx]{"INX", Trp, Xinx}, [Ojc]{"JC", Taddr, Xjc}, [Ojm]{"JM", Taddr, Xjm}, [Ojmp]{"JMP", Taddr, Xjmp}, [Ojnc]{"JNC", Taddr, Xjnc}, [Ojnz]{"JNZ", Taddr, Xjnz}, [Ojpo]{"JPO", Taddr}, [Ojz]{"JZ", Taddr, Xjz}, [Olda]{"LDA", Taddr, Xlda}, [Oldax]{"LDAX", Trp, Xldax}, [Olxi]{"LXI", Trpimm, Xlxi}, [Omov]{"MOV", Trr, Xmov}, [Omvi]{"MVI", Trimm, Xmvi}, [Onop]{"NOP", T0, Xnop}, [Oora]{"ORA", Tr012, Xora}, [Oori]{"ORI", Timm, Xori}, [Oout]{"OUT", Timm, Xout}, [Opchl]{"PCHL", T0, Xpchl}, [Opop]{"POP", Trp, Xpop}, [Opush]{"PUSH", Trp, Xpush}, [Orar]{"RAR", T0, Xrar}, [Orc]{"RC", T0, Xrc}, [Oret]{"RET", T0, Xret}, [Orim]{"RIM", T0}, [Orlc]{"RLC", T0, Xrlc}, [Orm]{"RM", T0}, [Ornc]{"RNC", T0, Xrnc}, [Ornz]{"RNZ", T0, Xrnz}, [Orp]{"RP", T0}, [Orpo]{"RPO", T0}, [Orrc]{"RRC", T0, Xrrc}, [Orst]{"RST", Timm}, [Orz]{"RZ", T0, Xrz}, [Osbb]{"SBB", Tr012}, [Osbi]{"SBI", Timm, Xsbi}, [Oshld]{"SHLD", Taddr, Xshld}, [Osim]{"SIM", T0}, [Osta]{"STA", Taddr, Xsta}, [Ostax]{"STAX", Trp, Xstax}, [Osub]{"SUB", Tr012}, [Osui]{"SUI", Timm, Xsui}, [Oxchg]{"XCHG", T0, Xxchg}, [Oxra]{"XRA", Tr012, Xxra}, [Oxri]{"XRI", Timm}, [Oxthl]{"XTHL", T0, Xxthl}, }; static char* opstr(int op) { if(op < 0 || op >= nelem(isa)) return "XXX"; return isa[op].opstr; } static int das0(Fmt *fmt, Insn *insn) { return fmtprint(fmt, "%s", opstr(insn->op)); } static int dasr(Fmt *fmt, Insn *insn) { return fmtprint(fmt, "%s %s", opstr(insn->op), rnam(insn->r1)); } static int dasrr(Fmt *fmt, Insn *insn) { return fmtprint(fmt, "%s %s, %s", opstr(insn->op), rnam(insn->r1), rnam(insn->r2)); } static int dasimm(Fmt *fmt, Insn *insn) { char *fmtstr; if(insn->op == Orst) fmtstr = "%s %uhhd"; else fmtstr = "%s #$%#.2uhhx"; return fmtprint(fmt, fmtstr, opstr(insn->op), insn->imm); } static int dasrimm(Fmt *fmt, Insn *insn) { return fmtprint(fmt, "%s %s, #$%#.2uhhx", opstr(insn->op), rnam(insn->r1), insn->imm); } static int dasrp(Fmt *fmt, Insn *insn) { char *rp; rp = rpnam(insn->rp); if(insn->rp == 3){ switch(insn->op){ case Opush: case Opop: rp = "PSW"; break; case Odad: rp = "SP"; break; } } return fmtprint(fmt, "%s %s", opstr(insn->op), rp); } static int dasaddr(Fmt *fmt, Insn *insn) { return fmtprint(fmt, "%s %#.4x", opstr(insn->op), insn->addr); } static int dasrpimm(Fmt *fmt, Insn *insn) { return fmtprint(fmt, "%s %s, #$0x%.2uhhx%.2uhhx", opstr(insn->op), insn->rp == 3 ? "SP" : rpnam(insn->rp), insn->imm1, insn->imm); } static int dec0(Insn*, uchar*, long) { return 1; } static int decr00000xxx(Insn *insn, uchar *mem, long) { insn->r1 = mem[0]&0x7; return 1; } static int decr00xxx000(Insn *insn, uchar *mem, long) { insn->r1 = (mem[0]>>3)&0x7; return 1; } static int decrimm(Insn *insn, uchar *mem, long len) { if(len < 2) return 0; insn->r1 = (mem[0]>>3)&0x7; insn->imm = mem[1]; return 2; } static int decimm(Insn *insn, uchar *mem, long len) { if(len < 2) return 0; insn->imm = mem[1]; return 2; } static int decaddr(Insn *insn, uchar *mem, long len) { if(len < 3) return 0; insn->addr = (u8int)mem[1]|((u16int)mem[2])<<8; return 3; } static int decrr(Insn *insn, uchar *mem, long) { insn->r1 = (mem[0]>>3)&0x7; insn->r2 = mem[0]&0x7; if(insn->r1 == M && insn->r2 == M) insn->op = Onop; return 1; } static int decrp(Insn *insn, uchar *mem, long) { insn->rp = (mem[0]>>4)&0x3; return 1; } static int decrpimm(Insn *insn, uchar *mem, long len) { if(len < 3) return 0; insn->rp = (mem[0]>>4)&0x3; insn->imm = mem[1]; insn->imm1 = mem[2]; return 3; } int insnfmt(Fmt *fmt) { Insn *insn; insn = va_arg(fmt->args, Insn*); if(insn->op < 0 || insn->op >= nelem(isa)) return fmtprint(fmt, "XXX"); return insntypes[isa[insn->op].type].das(fmt, insn); } int insnlen(u8int op) { if(op >= nelem(isa)) return 0; return insntypes[isa[op].type].len; } int decodeop(u8int b) { if((b&0xc0) == 0x40) return Omov; switch(b){ case 0x0f: return Orrc; case 0x1f: return Orar; case 0x27: return Odaa; case 0x2f: return Ocma; case 0x3f: return Ocmc; case 0xc0: return Ornz; case 0xc2: return Ojnz; case 0xc3: return Ojmp; case 0xc4: return Ocz; case 0xc6: return Oadi; case 0xc8: return Orz; case 0xc9: return Oret; case 0xca: return Ojz; case 0xcc: return Ocz; case 0xcd: return Ocall; case 0xd0: return Ornc; case 0xd2: return Ojnc; case 0xd3: return Oout; case 0xd4: return Ocnc; case 0xd6: return Osui; case 0xd8: return Orc; case 0xda: return Ojc; case 0xdb: return Oin; case 0xde: return Osbi; case 0xe0: return Orpo; case 0xe2: return Ojpo; case 0xe3: return Oxthl; case 0xe6: return Oani; case 0xe9: return Opchl; case 0xea: return Ojpe; case 0xeb: return Oxchg; case 0xec: return Ocpe; case 0xee: return Oxri; case 0xf0: return Orp; case 0xf2: return Ojp; case 0xf3: return Odi; case 0xf6: return Oori; case 0xf8: return Orm; case 0xfa: return Ojm; case 0xfb: return Oei; case 0xfc: return Ocm; case 0xfe: return Ocpi; } if((b&0x80) != 0){ switch(b&0xf8){ case 0x80: return Oadd; case 0x88: return Oadc; case 0x90: return Osub; case 0x98: return Osbb; case 0xa0: return Oana; case 0xa8: return Oxra; case 0xb0: return Oora; case 0xb8: return Ocmp; } switch(b&0x7){ case 0x1: return Opop; case 0x5: switch(b&0xf){ case 0x5: return Opush; } break; case 0x7: return Orst; } }else{ if((b&0xc0) == 0x40) return Omov; switch(b&0x0f){ case 0x00: switch(b){ case 0x00: return Onop; case 0x10: return Onop; case 0x20: return Orim; case 0x30: return Osim; } break; case 0x01: return Olxi; case 0x02: switch((b>>5)&1){ case 0: return Ostax; case 1: switch(b){ case 0x22: return Oshld; case 0x32: return Osta; } break; } break; case 0x03: return Oinx; case 0x07: return Orlc; case 0x08: return Onop; case 0x09: return Odad; case 0x0a: switch((b>>5)&1){ case 0: return Oldax; case 1: return Olda; } break; case 0x0b: return Odcx; } switch(b&0x07){ case 0x04: return Oinr; case 0x05: return Odcr; case 0x06: return Omvi; } } return -1; } int decodeinsn(Insn *insn, uchar *mem, long len) { if(len < 1) return 0; if(insn->op == -1) return -1; return insntypes[isa[insn->op].type].dec(insn, mem, len); } static int decode(Insn *insn, uchar *mem, long len) { if(len < 1) return 0; insn->op = decodeop(mem[0]); return decodeinsn(insn, mem, len); } int das(uchar *mem, long mlen) { int n; Insn insn; if((n = decode(&insn, mem, mlen)) < 0) return -1; print("\t%I\n", &insn); return n; } int dasfile(char *file) { Biobuf *r; Insn insn; int buflen, n; u16int addr; uchar buf[1024]; uchar *bp; r = Bopen(file, OREAD); if(r == nil) return -1; addr = 0; buflen = 0; bp = buf; for(;;){ memmove(buf, bp, buflen); bp = buf; n = Bread(r, buf + buflen, sizeof(buf) - buflen); if(n < 0){ Bterm(r); return -1; } if(n == 0){ Bterm(r); break; } buflen += n; while(buflen > 0){ n = decode(&insn, bp, buflen); if(n == 0) break; if(n < 0){ print("%#.4ux\t???\t%#.2uhhx\n", addr, bp[0]); addr++; bp++; buflen--; }else{ print("%#.4ux\t%I\n", addr, &insn); addr += n; bp += n; buflen -= n; } } } while(buflen > 0){ print("%#.4x\t???\t%#.2x\n", addr, buf[0]); addr++; bp++; buflen--; } return 0; } void cpuexec(CPU *cpu, Insn *insn) { if(isa[insn->op].exec == nil){ fprint(2, "%s (%#.2uhhx) not implemented!\n", opstr(insn->op), insn->op); trap(); } itrace(opstr(insn->op)); isa[insn->op].exec(cpu, insn); } static u16int rpair(CPU *cpu, u8int rp) { switch(rp){ case BC: return cpu->r[B]<<8 | cpu->r[C]; case DE: return cpu->r[D]<<8 | cpu->r[E]; case HL: return cpu->r[H]<<8 | cpu->r[L]; } fatal("unknown register pair %d", rp); return 0; } static void wpair(CPU *cpu, u8int rp, u16int x) { cpu->r[(rp<<1)+B] = x>>8; cpu->r[(rp<<1)+B+1] = x; } static void Xnop(CPU*, Insn*) { } static void Xjmp(CPU *cpu, Insn *insn) { cpu->PC = insn->addr; } static void Xlxi(CPU *cpu, Insn *insn) { if(insn->rp == 3) cpu->SP = insn->imm1<<8|insn->imm; else wpair(cpu, insn->rp, insn->imm1<<8|insn->imm); } static void Xmvi(CPU *cpu, Insn *insn) { u16int addr; if(insn->r1 == M){ addr = rpair(cpu, HL); memwrite(addr, insn->imm); }else{ cpu->r[insn->r1] = insn->imm; } } static void Xcall(CPU *cpu, Insn *insn) { push16(cpu, cpu->PC); cpu->PC = insn->addr; } static void Xldax(CPU *cpu, Insn *insn) { cpu->r[A] = memread(rpair(cpu, insn->rp)); } static void Xmov(CPU *cpu, Insn *insn) { if(insn->r2 == M && insn->r1 == M) return; if(insn->r2 == M) cpu->r[insn->r1] = memread(rpair(cpu, HL)); else if(insn->r1 == M) memwrite(rpair(cpu, HL), cpu->r[insn->r2]); else cpu->r[insn->r1] = cpu->r[insn->r2]; } static void Xinx(CPU *cpu, Insn *insn) { wpair(cpu, insn->rp, rpair(cpu, insn->rp) + 1); } static void Xdcr(CPU *cpu, Insn *insn) { u16int a, x; if(insn->r1 == M){ a = rpair(cpu, HL); x = memread(a); }else{ a = 0; x = cpu->r[insn->r1]; } if(--x == 0) cpu->flg |= Fzero; cpu->flg &= ~Fsign; if((x&0x80) != 0) cpu->flg |= Fsign; if(insn->r1 == M) memwrite(a, x); else cpu->r[insn->r1] = x; } static void Xret(CPU *cpu, Insn*) { cpu->PC = pop16(cpu); } static void Xdad(CPU *cpu, Insn *insn) { u32int x; if(insn->rp == 3){ x = cpu->SP; }else{ x = rpair(cpu, insn->rp); } x += rpair(cpu, HL); if(x>>16 > 0) cpu->flg |= Fcarry; //else //cpu->flg &= ~Fcarry; wpair(cpu, HL, x); } static void Xsta(CPU *cpu, Insn *insn) { memwrite(insn->addr, cpu->r[A]); } static void Xxra(CPU *cpu, Insn *insn) { u8int x; if(insn->r1 == M) x = memread(rpair(cpu, HL)); else x = cpu->r[insn->r1]; cpu->r[A] ^= x; if(cpu->r[A] == 0) cpu->flg |= Fzero; else cpu->flg &= ~Fzero; if((cpu->r[A] & 0x80) != 0) cpu->flg |= Fsign; else cpu->flg &= ~Fsign; cpu->flg &= ~(Fcarry|Fhcarry); } void iow(u16int a, u8int v) { } static void Xout(CPU *cpu, Insn *insn) { iow(insn->imm<<8|insn->imm, cpu->r[A]); } static void Xora(CPU *cpu, Insn *insn) { u8int x; if(insn->r1 == M) x = memread(rpair(cpu, HL)); else x = cpu->r[insn->r1]; cpu->r[A] |= x; if(cpu->r[A] == 0) cpu->flg |= Fzero; else cpu->flg &= ~Fzero; if((cpu->r[A] & 0x80) != 0) cpu->flg |= Fsign; else cpu->flg &= ~Fsign; cpu->flg &= ~(Fcarry|Fhcarry); } static void Xlda(CPU *cpu, Insn *insn) { cpu->r[A] = memread(insn->addr); } static void Xana(CPU *cpu, Insn *insn) { u8int x; if(insn->r1 == M) x = memread(rpair(cpu, HL)); else x = cpu->r[insn->r1]; cpu->r[A] &= x; if(cpu->r[A] == 0) cpu->flg |= Fzero; else cpu->flg &= ~Fzero; if((cpu->r[A] & 0x80) != 0) cpu->flg |= Fsign; else cpu->flg &= ~Fsign; cpu->flg &= ~(Fcarry|Fhcarry); } static void Xpush(CPU *cpu, Insn *insn) { if(insn->rp == 3){ push8(cpu, cpu->r[A]); push8(cpu, cpu->flg); }else push16(cpu, rpair(cpu, insn->rp)); } static void Xpop(CPU *cpu, Insn *insn) { if(insn->rp == 3){ cpu->flg = pop8(cpu); cpu->r[A] = pop8(cpu); }else wpair(cpu, insn->rp, pop16(cpu)); } static void Xxchg(CPU *cpu, Insn*) { u16int x; x = rpair(cpu, HL); wpair(cpu, HL, rpair(cpu, DE)); wpair(cpu, DE, x); } static void Xinr(CPU *cpu, Insn *insn) { u8int x; u16int a; if(insn->r1 == M){ a = memread(rpair(cpu, HL)); x = memread(a) + 1; memwrite(a, x); }else{ x = cpu->r[insn->r1] + 1; cpu->r[insn->r1] = x; } if(x == 0) cpu->flg |= Fzero; else cpu->flg &= ~Fzero; if((x & 0x80) != 0) cpu->flg |= Fsign; else cpu->flg &= ~Fsign; cpu->flg &= ~Fhcarry; } static void Xani(CPU *cpu, Insn *insn) { cpu->r[A] &= insn->imm; if(cpu->r[A] == 0) cpu->flg |= Fzero; else cpu->flg &= ~Fzero; if((cpu->r[A] & 0x80) != 0) cpu->flg |= Fsign; else cpu->flg &= ~Fsign; cpu->flg &= ~(Fcarry|Fhcarry); } static void Xrar(CPU *cpu, Insn*) { u8int ocarry; ocarry = (cpu->flg&Fcarry) != 0; if((cpu->r[A]&1) != 0) cpu->flg |= Fcarry; else cpu->flg &= ~Fcarry; cpu->r[A] = ocarry<<7|((cpu->r[A]>>1)&0x7f); } static void Xori(CPU *cpu, Insn *insn) { cpu->r[A] |= insn->imm; if(cpu->r[A] == 0) cpu->flg |= Fzero; else cpu->flg &= ~Fzero; if((cpu->r[A] & 0x80) != 0) cpu->flg |= Fsign; else cpu->flg &= ~Fsign; cpu->flg &= ~(Fcarry|Fhcarry); } static void Xcmp(CPU *cpu, Insn *insn) { if(cpu->r[A] == insn->r1) cpu->flg |= Fzero; else{ cpu->flg &= ~Fzero; if(cpu->r[A] < insn->r1) cpu->flg |= Fcarry; else cpu->flg &= ~Fcarry; } } static void Xrlc(CPU *cpu, Insn*) { u8int ncarry; ncarry = (cpu->r[A]&0x80) != 0; if(ncarry != 0) cpu->flg |= Fcarry; else cpu->flg &= ~Fcarry; cpu->r[A] = ((cpu->r[A]<<1)&0xfe)|ncarry; } static void Xrrc(CPU *cpu, Insn*) { u8int ncarry; ncarry = cpu->r[A]&1; if(ncarry != 0) cpu->flg |= Fcarry; else cpu->flg &= ~Fcarry; cpu->r[A] = ncarry<<7|((cpu->r[A]>>1)&0x7f); } static void Xdcx(CPU *cpu, Insn *insn) { if(insn->rp == 3) cpu->SP--; else wpair(cpu, insn->rp, rpair(cpu, insn->rp) - 1); } static void Xstax(CPU *cpu, Insn *insn) { memwrite(rpair(cpu, insn->rp), cpu->r[A]); } static void Xcpi(CPU *cpu, Insn *insn) { if(cpu->r[A] == insn->imm) cpu->flg |= Fzero; else{ cpu->flg &= ~Fzero; if(cpu->r[A] < insn->imm) cpu->flg |= Fcarry; else cpu->flg &= ~Fcarry; } } static void psz(CPU *cpu, int f) { u8int x, p; if(cpu->r[A] == 0){ if(f & Fzero) cpu->flg |= Fzero; if(f & Fsign) cpu->flg &= ~Fsign; }else{ if(f & Fzero) cpu->flg &= ~Fzero; if((cpu->r[A] & 0x80) != 0) if(f & Fsign) cpu->flg |= Fsign; } if(f & Fparity){ x = cpu->r[A]; p = 0; p += (x&1); x >>= 1; p += (x&1); x >>= 1; p += (x&1); x >>= 1; p += (x&1); x >>= 1; p += (x&1); x >>= 1; p += (x&1); x >>= 1; p += (x&1); x >>= 1; p += (x&1); if((p & 1) != 0) cpu->flg |= Fparity; else cpu->flg &= ~Fparity; } } static void Xadi(CPU *cpu, Insn *insn) { u16int x; x = cpu->r[A] + insn->imm; if((x>>8) > 0) cpu->flg |= Fcarry; else cpu->flg &= ~Fcarry; cpu->r[A] = x; psz(cpu, Fparity|Fsign|Fzero); } static void Xei(CPU *cpu, Insn*) { cpu->intr |= Ienabled; } static void Xdi(CPU *cpu, Insn*) { cpu->intr &= ~Ienabled; } static void Xin(CPU *cpu, Insn*) { cpu->r[A] = 0; } static void Xjc(CPU *cpu, Insn *insn) { if((cpu->flg&Fcarry) != 0) cpu->PC = insn->addr; } static void Xjz(CPU *cpu, Insn *insn) { if((cpu->flg&Fzero) != 0) cpu->PC = insn->addr; } static void Xjnc(CPU *cpu, Insn *insn) { if((cpu->flg&Fcarry) == 0) cpu->PC = insn->addr; } static void Xjnz(CPU *cpu, Insn *insn) { if((cpu->flg&Fzero) == 0) cpu->PC = insn->addr; } static void Xrc(CPU *cpu, Insn*) { if((cpu->flg&Fcarry) != 0) cpu->PC = pop16(cpu); } static void Xrnc(CPU *cpu, Insn*) { if((cpu->flg&Fcarry) == 0) cpu->PC = pop16(cpu); } static void Xrz(CPU *cpu, Insn*) { if((cpu->flg&Fzero) != 0) cpu->PC = pop16(cpu); } static void Xrnz(CPU *cpu, Insn*) { if((cpu->flg&Fzero) == 0) cpu->PC = pop16(cpu); } static void Xsui(CPU *cpu, Insn *insn) { u8int a, b; u16int x; a = cpu->r[A]; b = -insn->imm; if((((a&0xf)+(b&0xf))&0x10) != 0) cpu->flg |= Fhcarry; else cpu->flg &= Fhcarry; x = a + b; if((x&0x100) != 0) cpu->flg &= ~Fcarry; else cpu->flg |= Fcarry; cpu->r[A] = x; psz(cpu, Fparity|Fsign|Fzero); } static void Xxthl(CPU *cpu, Insn*) { u8int x; x = memread(cpu->SP+0); memwrite(cpu->SP+0, cpu->r[L]); cpu->r[L] = x; x = memread(cpu->SP+1); memwrite(cpu->SP+1, cpu->r[H]); cpu->r[H] = x; } static void Xpchl(CPU *cpu, Insn*) { cpu->PC = rpair(cpu, HL); } static void Xcz(CPU *cpu, Insn *insn) { if((cpu->flg&Fzero) != 0){ push16(cpu, cpu->PC); cpu->PC = insn->addr; } } static void Xdaa(CPU *cpu, Insn*) { u16int x; if((cpu->flg&Fhcarry) != 0 || cpu->r[A] > 9){ x = (cpu->r[A]&0xf)+6; if(x>>4 > 0) cpu->flg |= Fhcarry; else cpu->flg &= ~Fhcarry; cpu->r[A] = (cpu->r[A]&0xf0)|(x&0x0f); } if((cpu->flg&Fcarry) != 0 || (cpu->r[A]>>4) > 9){ x = (cpu->r[A]>>4)+6; if(x>>4 > 0) cpu->flg |= Fcarry; else cpu->flg &= ~Fcarry; cpu->r[A] = (x<<4)|(cpu->r[A]&0xf); } } static void Xjm(CPU *cpu, Insn *insn) { if((cpu->flg&Fsign) != 0) cpu->PC = insn->addr; } static void Xsbi(CPU *cpu, Insn *insn) { insn->imm = -insn->imm; Xadi(cpu, insn); } static void Xshld(CPU *cpu, Insn *insn) { memwrite(insn->addr+0, cpu->r[L]); memwrite(insn->addr+1, cpu->r[H]); }