📄 inst.cc
字号:
intcl_hc08::inst_dec(t_mem code, bool prefix){ int ea = 0xffff; uchar operand; if ((code & 0xf0) == 0x40) operand = regs.A; else if ((code & 0xf0) == 0x50) operand = regs.X; else { ea = fetchea(code,prefix); operand = get1(ea); } operand--; FLAG_NZ (operand); FLAG_ASSIGN (BIT_V, operand == 0x7f); if ((code & 0xf0) == 0x40) regs.A = operand; else if ((code & 0xf0) == 0x50) regs.X = operand; else { store1(ea, operand); } return(resGO);}intcl_hc08::inst_dbnz(t_mem code, bool prefix){ int ea = 0xffff; uchar operand; signed char ofs; if ((code & 0xf0) == 0x40) operand = regs.A; else if ((code & 0xf0) == 0x50) operand = regs.X; else { ea = fetchea(code,prefix); operand = get1(ea); } operand--; FLAG_NZ (operand); FLAG_ASSIGN (BIT_V, operand == 0x7f); if ((code & 0xf0) == 0x40) regs.A = operand; else if ((code & 0xf0) == 0x50) regs.X = operand; else { store1(ea, operand); } ofs = fetch(); if (operand) PC += ofs; return(resGO);}intcl_hc08::inst_tst(t_mem code, bool prefix){ int ea = 0xffff; uchar operand; if ((code & 0xf0) == 0x40) operand = regs.A; else if ((code & 0xf0) == 0x50) operand = regs.X; else { ea = fetchea(code,prefix); operand = get1(ea); } FLAG_NZ (operand); FLAG_CLEAR (BIT_V); return(resGO);}intcl_hc08::inst_clr(t_mem code, bool prefix){ int ea = 0xffff; uchar operand; operand = 0; FLAG_CLEAR (BIT_V); FLAG_CLEAR (BIT_N); FLAG_SET (BIT_Z); if ((code & 0xf0) == 0x40) regs.A = operand; else if ((code & 0xf0) == 0x50) regs.X = operand; else { ea = fetchea(code,prefix); store1(ea, operand); } return(resGO);}intcl_hc08::inst_clrh(t_mem code, bool prefix){ FLAG_CLEAR (BIT_V); FLAG_CLEAR (BIT_N); FLAG_SET (BIT_Z); regs.H = 0; return(resGO);}intcl_hc08::inst_com(t_mem code, bool prefix){ int ea = 0xffff; uchar operand; if ((code & 0xf0) == 0x40) operand = regs.A; else if ((code & 0xf0) == 0x50) operand = regs.X; else { ea = fetchea(code,prefix); operand = get1(ea); } operand = ~operand; FLAG_SET (BIT_C); FLAG_NZ (operand); FLAG_CLEAR (BIT_V); if ((code & 0xf0) == 0x40) regs.A = operand; else if ((code & 0xf0) == 0x50) regs.X = operand; else { store1(ea, operand); } return(resGO);}intcl_hc08::inst_neg(t_mem code, bool prefix){ int ea = 0xffff; uchar operand; if ((code & 0xf0) == 0x40) operand = regs.A; else if ((code & 0xf0) == 0x50) operand = regs.X; else { ea = fetchea(code,prefix); operand = get1(ea); } FLAG_ASSIGN (BIT_V, operand==0x80); FLAG_ASSIGN (BIT_C, operand!=0x00); operand = -operand; FLAG_NZ (operand); if ((code & 0xf0) == 0x40) regs.A = operand; else if ((code & 0xf0) == 0x50) regs.X = operand; else { store1(ea, operand); } return(resGO);}intcl_hc08::inst_pushpull(t_mem code, bool prefix){ switch (code) { case 0x86: pop1(regs.A); break; case 0x87: push1(regs.A); break; case 0x88: pop1(regs.X); break; case 0x89: push1(regs.X); break; case 0x8a: pop1(regs.H); break; case 0x8b: push1(regs.H); break; default: return(resHALT); } return(resGO);}intcl_hc08::inst_stop(t_mem code, bool prefix){ FLAG_CLEAR (BIT_I); return(resGO);}intcl_hc08::inst_wait(t_mem code, bool prefix){ FLAG_CLEAR (BIT_I); return(resGO);}intcl_hc08::inst_daa(t_mem code, bool prefix){ uchar lsn, msn; lsn = regs.A & 0xf; msn = (regs.A >> 4) & 0xf; if (regs.P & BIT_H) { lsn += 16; msn = (msn-1) & 0xf; } if (regs.P & BIT_C) msn += 16; FLAG_CLEAR (BIT_C); while (lsn>9) { lsn -= 10; msn++; } if (msn>9) { msn = msn % 10; FLAG_SET (BIT_C); } return(resGO);}intcl_hc08::inst_mul(t_mem code, bool prefix){ int result = regs.A * regs.X; regs.A = result & 0xff; regs.X = (result >> 8) & 0xff; FLAG_CLEAR (BIT_C); FLAG_CLEAR (BIT_H); return(resGO);}intcl_hc08::inst_div(t_mem code, bool prefix){ unsigned int dividend = (regs.H << 8) | regs.A; unsigned int quotient; if (regs.X) { quotient = dividend / (unsigned int)regs.X; if (quotient<=0xff) { regs.A = quotient; regs.H = dividend % regs.X; FLAG_CLEAR (BIT_C); FLAG_ASSIGN (BIT_Z, quotient==0); } else FLAG_SET (BIT_C); // overflow } else FLAG_SET (BIT_C); // division by zero return(resGO);}intcl_hc08::inst_condbranch(t_mem code, bool prefix){ bool taken; signed char ofs; unsigned char maskedP; if ((code & 0xf0)==0x20) { switch ((code>>1) & 7) { case 0: // BRA taken = 1; break; case 1: // BHI taken = !(regs.P & (BIT_C | BIT_Z)); break; case 2: // BCC taken = !(regs.P & BIT_C); break; case 3: // BNE taken = !(regs.P & BIT_Z); break; case 4: // BHCC taken = !(regs.P & BIT_H); break; case 5: // BPL taken = !(regs.P & BIT_N); break; case 6: // BMC taken = !(regs.P & BIT_I); break; case 7: // BIL taken = 0; // TODO: should read simulated IRQ# pin default: return(resHALT); } } else if ((code & 0xf0)==0x90) { switch ((code>>1) & 7) { case 0: // BGE maskedP = regs.P & (BIT_N | BIT_V); taken = !maskedP || (maskedP == (BIT_N | BIT_V)); break; case 1: // BGT maskedP = regs.P & (BIT_N | BIT_V | BIT_Z); taken = !maskedP || (maskedP == (BIT_N | BIT_V)); break; default: return(resHALT); } } else return(resHALT); if (code & 1) taken = ! taken; ofs = fetch(); if (taken) PC += ofs; return(resGO);}intcl_hc08::inst_bitsetclear(t_mem code, bool prefix){ uchar bit = (code >> 1) & 7; int ea = fetchea(code, prefix); uchar operand = get1(ea); if (code & 1) operand &= ~(1 << bit); else operand |= (1 << bit); store1(ea, operand); return(resGO);}intcl_hc08::inst_bittestsetclear(t_mem code, bool prefix){ uchar bit = (code >> 1) & 7; int ea = fetchea(code, prefix); uchar operand = get1(ea); signed char ofs; bool taken; if (code & 1) taken = operand & (1 << bit); else taken = !(operand & (1 << bit)); ofs = fetch(); if (taken) PC += ofs; FLAG_ASSIGN (BIT_C, operand & (1 << bit)); return(resGO);}intcl_hc08::inst_cbeq(t_mem code, bool prefix){ int ea; uchar operand1, operand2; signed char ofs; if ((code & 0xf0) == 0x40) { operand1 = regs.A; operand2 = fetch(); } else if ((code & 0xf0) == 0x50) { operand1 = regs.X; operand2 = fetch(); } else { ea = fetchea(code,prefix); operand1 = get1(ea); operand2 = regs.A; } ofs = fetch(); if (operand1==operand2) PC += ofs; if (code==0x71) incx(); return(resGO);}intcl_hc08::inst_rti(t_mem code, bool prefix){ pop1(regs.P); regs.P |= 0x60; pop1(regs.A); pop1(regs.X); pop2(PC); return(resGO);}intcl_hc08::inst_rts(t_mem code, bool prefix){ pop2(PC); return(resGO);}intcl_hc08::inst_mov(t_mem code, bool prefix){ int ea; uchar operand; bool aix; int hx = (regs.H << 8) | (regs.X); switch (code) { case 0x4e: //mov opr8a,opr8a operand = get1(fetch()); ea = fetch(); aix = 0; break; case 0x5e: //mov opr8a,x+ operand = get1(fetch()); ea = hx; aix = 1; break; case 0x6e: //mov #opr8i,opr8a operand = fetch(); ea = fetch(); aix = 0; break; case 0x7e: //mov x+,opr8a operand = get1(hx); ea = fetch(); aix = 1; break; default: return(resHALT); } store1(ea, operand); if (aix) incx(); FLAG_NZ(operand); FLAG_CLEAR(BIT_V); return(resGO);}intcl_hc08::inst_sthx(t_mem code, bool prefix){ int ea = fetch1(); store1(ea, regs.H); store1((ea+1) & 0xffff, regs.X); FLAG_CLEAR(BIT_V); FLAG_ASSIGN(BIT_N, regs.H & 0x80); FLAG_ASSIGN(BIT_Z, !regs.X && !regs.H); return(resGO);}intcl_hc08::inst_ldhx(t_mem code, bool prefix){ int ea; if (code == 0x45) { regs.H = fetch(); regs.X = fetch(); } else if (code == 0x55) { ea = fetch(); regs.H = get1(ea); regs.X = get1(ea+1); } else return(resHALT); FLAG_CLEAR(BIT_V); FLAG_ASSIGN(BIT_N, regs.H & 0x80); FLAG_ASSIGN(BIT_Z, !regs.X && !regs.H); return(resGO);}intcl_hc08::inst_cphx(t_mem code, bool prefix){ int ea; int hx; int operand; int result; if (code == 0x65) { operand = fetch2(); } else if (code == 0x75) { ea = fetch(); operand = (get1(ea) << 8) | get1(ea+1); } else return(resHALT); hx = (regs.H << 8) | regs.X; result = hx-operand; FLAG_ASSIGN (BIT_V, 0x8000 & (hx ^ operand ^ result ^ (result>>1))); FLAG_ASSIGN (BIT_C, 0x10000 & result); FLAG_ASSIGN(BIT_N, result & 0x8000); FLAG_ASSIGN(BIT_Z, !(result & 0xffff)); return(resGO);}intcl_hc08::inst_swi(t_mem code, bool prefix){ push2(PC); push1(regs.X); push1(regs.A); push1(regs.P); FLAG_CLEAR(BIT_I); PC = get2(0xfffc); return(resGO);}/* End of hc08.src/inst.cc */
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -