void BTC_EdIb(UINT32 op) { UINT32 *out; UINT32 src, dst, res, madr; UINT32 bit; if (op >= 0xc0) { CPU_WORKCLOCK(2); GET_PCBYTE(src); out = reg32_b20[op]; dst = *out; bit = BIT_MAKEBIT32(src); if (dst & bit) { CPU_FLAGL |= C_FLAG; } else { CPU_FLAGL &= ~C_FLAG; } res = dst ^ bit; *out = res; } else { CPU_WORKCLOCK(6); madr = calc_ea_dst(op); GET_PCBYTE(src); dst = cpu_vmemoryread_d(CPU_INST_SEGREG_INDEX, madr); bit = BIT_MAKEBIT32(src); if (dst & bit) { CPU_FLAGL |= C_FLAG; } else { CPU_FLAGL &= ~C_FLAG; } res = dst ^ bit; cpu_vmemorywrite_d(CPU_INST_SEGREG_INDEX, madr, res); } }
void BTR_EwIb(UINT32 op) { UINT16 *out; UINT32 src, dst, res, madr; UINT16 bit; if (op >= 0xc0) { CPU_WORKCLOCK(2); GET_PCBYTE(src); out = reg16_b20[op]; dst = *out; bit = BIT_MAKEBIT16(src); if (dst & bit) { CPU_FLAGL |= C_FLAG; res = dst & ~bit; *out = (UINT16)res; } else { CPU_FLAGL &= ~C_FLAG; } } else { CPU_WORKCLOCK(6); madr = calc_ea_dst(op); GET_PCBYTE(src); dst = cpu_vmemoryread_w(CPU_INST_SEGREG_INDEX, madr); bit = BIT_MAKEBIT16(src); if (dst & bit) { CPU_FLAGL |= C_FLAG; } else { CPU_FLAGL &= ~C_FLAG; } res = dst & ~bit; cpu_vmemorywrite_w(CPU_INST_SEGREG_INDEX, madr, (UINT16)res); } }
I286FN v30shift_ea8_data8(void) { // C0: shift EA8, DATA8 UINT8 *out; UINT op; UINT32 madr; REG8 cl; GET_PCBYTE(op) if (op >= 0xc0) { I286_WORKCLOCK(5); out = REG8_B20(op); } else { I286_WORKCLOCK(8); madr = CALC_EA(op); if (madr >= I286_MEMWRITEMAX) { GET_PCBYTE(cl) I286_WORKCLOCK(cl); if (!(op & 0x20)) { // rotate if (!(op & 0x10)) { cl = rotatebase16[cl]; } else { // rotate with carry cl = rotatebase09[cl]; } } else { cl = max(cl, 9); } sft_e8cl_table[(op >> 3) & 7](madr, cl); return; } out = mem + madr; }
void _2byte_ESC32(void) { UINT32 op; GET_PCBYTE(op); (*insttable_2byte[1][op])(); }
void BT_EwIb(UINT32 op) { UINT32 src, dst, madr; if (op >= 0xc0) { CPU_WORKCLOCK(2); GET_PCBYTE(src); dst = *(reg16_b20[op]); } else { CPU_WORKCLOCK(6); madr = calc_ea_dst(op); GET_PCBYTE(src); dst = cpu_vmemoryread_w(CPU_INST_SEGREG_INDEX, madr); } CPU_FLAGL &= ~C_FLAG; CPU_FLAGL |= (dst >> BIT_INDEX16(src)) & 1; }
void TEST_ALIb(void) { UINT32 src, tmp; CPU_WORKCLOCK(3); tmp = CPU_AL; GET_PCBYTE(src); BYTE_AND(tmp, src); }
void ESC6(void) { UINT32 op, madr; GET_PCBYTE(op); // TRACEOUT(("use FPU de %.2x", op)); if (op >= 0xc0) { } else { madr = calc_ea_dst(op); } }
void LEA_GdM(void) { UINT32 *out; UINT32 op, dst; GET_PCBYTE(op); if (op < 0xc0) { CPU_WORKCLOCK(2); out = reg32_b53[op]; dst = calc_ea_dst(op); *out = dst; return; } EXCEPTION(UD_EXCEPTION, 0); }
I286FN v30segprefix_es(void) { // 26: es: SS_FIX = ES_BASE; DS_FIX = ES_BASE; I286_PREFIX++; if (I286_PREFIX < MAX_PREFIX) { UINT op; GET_PCBYTE(op); v30op[op](); REMOVE_PREFIX I286_PREFIX = 0; } else { INT_NUM(6, I286_IP); } }
void ESC1(void) { UINT32 op, madr; GET_PCBYTE(op); // TRACEOUT(("use FPU d9 %.2x", op)); if (op >= 0xc0) { } else { madr = calc_ea_dst(op); if ((op & 0x38) == 0x38) { TRACEOUT(("FSTCW")); cpu_vmemorywrite_w(CPU_INST_SEGREG_INDEX, madr, 0xffff); } } }
I286FN v30segprefix_ds(void) { // 3e: ds: I286_SS_FIX = I286_DS_BASE; I286_DS_FIX = I286_DS_BASE; I286_PREFIX++; if (I286_PREFIX < MAX_PREFIX) { UINT op; GET_PCBYTE(op); v30op[op](); REMOVE_PREFIX I286_PREFIX = 0; } else { INT_NUM(6, I286_IP); } }
void TEST_EbIb(UINT32 op) { UINT32 src, tmp, madr; if (op >= 0xc0) { CPU_WORKCLOCK(2); tmp = *(reg8_b20[op]); } else { CPU_WORKCLOCK(6); madr = calc_ea_dst(op); tmp = cpu_vmemoryread(CPU_INST_SEGREG_INDEX, madr); } GET_PCBYTE(src); BYTE_AND(tmp, src); }
void SETNLE_Eb(void) { UINT32 op, madr; UINT8 v = CC_NLE?1:0; GET_PCBYTE(op); if (op >= 0xc0) { CPU_WORKCLOCK(2); *(reg8_b20[op]) = v; } else { CPU_WORKCLOCK(3); madr = calc_ea_dst(op); cpu_vmemorywrite(CPU_INST_SEGREG_INDEX, madr, v); } }
void INT_Ib(void) { UINT8 vect; CPU_WORKCLOCK(37); if (!CPU_STAT_PM || !CPU_STAT_VM86 || (CPU_STAT_IOPL == CPU_IOPL3)) { GET_PCBYTE(vect); #if defined(ENABLE_TRAP) softinttrap(CPU_CS, CPU_EIP - 2, vect); #endif INTERRUPT(vect, INTR_TYPE_SOFTINTR); return; } VERBOSE(("INT_Ib: VM86 && IOPL < 3 && INTn")); EXCEPTION(GP_EXCEPTION, 0); }
void BOUND_GdMa(void) { UINT32 op, madr; UINT32 reg; CPU_WORKCLOCK(13); GET_PCBYTE(op); if (op < 0xc0) { reg = *(reg32_b53[op]); madr = calc_ea_dst(op); if (reg >= cpu_vmemoryread_d(CPU_INST_SEGREG_INDEX, madr) && reg <= cpu_vmemoryread_d(CPU_INST_SEGREG_INDEX, madr + 4)) { return; } EXCEPTION(BR_EXCEPTION, 0); return; } EXCEPTION(UD_EXCEPTION, 0); }
I286FN v30mov_seg_ea(void) { // 8E: mov segrem, EA UINT op; UINT tmp; UINT16 ipbak; ipbak = I286_IP; GET_PCBYTE(op); if (op >= 0xc0) { I286_WORKCLOCK(2); tmp = *(REG16_B20(op)); } else { I286_WORKCLOCK(5); tmp = i286_memoryread_w(CALC_EA(op)); } switch(op & 0x18) { case 0x00: // es I286_ES = (UINT16)tmp; ES_BASE = tmp << 4; break; case 0x08: // cs I286_CS = (UINT16)tmp; CS_BASE = tmp << 4; break; case 0x10: // ss I286_SS = (UINT16)tmp; SS_BASE = tmp << 4; SS_FIX = SS_BASE; NEXT_OPCODE break; case 0x18: // ds I286_DS = (UINT16)tmp; DS_BASE = tmp << 4; DS_FIX = DS_BASE; break; } }
void ENTER32_IwIb(void) { UINT32 sp, bp; UINT32 new_bp; UINT32 val; UINT16 dimsize; UINT8 level; GET_PCWORD(dimsize); GET_PCBYTE(level); level &= 0x1f; CPU_SET_PREV_ESP(); PUSH0_32(CPU_EBP); if (level == 0) { /* enter level=0 */ CPU_WORKCLOCK(11); CPU_EBP = CPU_ESP; if (!CPU_STAT_SS32) { CPU_SP -= dimsize; } else { CPU_ESP -= dimsize; } } else { --level; if (level == 0) { /* enter level=1 */ CPU_WORKCLOCK(15); sp = CPU_ESP; PUSH0_32(sp); CPU_EBP = sp; if (CPU_STAT_SS32) { CPU_ESP -= dimsize; } else { CPU_SP -= dimsize; } } else { /* enter level=2-31 */ CPU_WORKCLOCK(12 + level * 4); if (CPU_STAT_SS32) { bp = CPU_EBP; new_bp = CPU_ESP; while (level--) { bp -= 4; CPU_ESP -= 4; val = cpu_vmemoryread_d(CPU_SS_INDEX, bp); cpu_vmemorywrite_d(CPU_SS_INDEX, CPU_ESP, val); } REGPUSH0_32(new_bp); CPU_EBP = new_bp; CPU_ESP -= dimsize; } else { bp = CPU_BP; new_bp = CPU_ESP; while (level--) { bp -= 4; CPU_SP -= 4; val = cpu_vmemoryread_d(CPU_SS_INDEX, bp); cpu_vmemorywrite_d(CPU_SS_INDEX, CPU_SP, val); } REGPUSH0_32_16(new_bp); CPU_EBP = new_bp; CPU_SP -= dimsize; } } } CPU_CLEAR_PREV_ESP(); }
void exec_1step(void) { int prefix; UINT32 op; CPU_PREV_EIP = CPU_EIP; CPU_STATSAVE.cpu_inst = CPU_STATSAVE.cpu_inst_default; #if defined(ENABLE_TRAP) steptrap(CPU_CS, CPU_EIP); #endif #if defined(IA32_INSTRUCTION_TRACE) ctx[ctx_index].regs = CPU_STATSAVE.cpu_regs; if (cpu_inst_trace) { disasm_context_t *d = &ctx[ctx_index].disasm; UINT32 eip = CPU_EIP; int rv; rv = disasm(&eip, d); if (rv == 0) { char buf[256]; char tmp[32]; int len = d->nopbytes > 8 ? 8 : d->nopbytes; int i; buf[0] = '\0'; for (i = 0; i < len; i++) { snprintf(tmp, sizeof(tmp), "%02x ", d->opbyte[i]); milstr_ncat(buf, tmp, sizeof(buf)); } for (; i < 8; i++) { milstr_ncat(buf, " ", sizeof(buf)); } VERBOSE(("%04x:%08x: %s%s", CPU_CS, CPU_EIP, buf, d->str)); buf[0] = '\0'; for (; i < d->nopbytes; i++) { snprintf(tmp, sizeof(tmp), "%02x ", d->opbyte[i]); milstr_ncat(buf, tmp, sizeof(buf)); if ((i % 8) == 7) { VERBOSE((" : %s", buf)); buf[0] = '\0'; } } if ((i % 8) != 0) { VERBOSE((" : %s", buf)); } } } ctx[ctx_index].opbytes = 0; #endif for (prefix = 0; prefix < MAX_PREFIX; prefix++) { GET_PCBYTE(op); #if defined(IA32_INSTRUCTION_TRACE) ctx[ctx_index].op[prefix] = op; ctx[ctx_index].opbytes++; #endif /* prefix */ if (insttable_info[op] & INST_PREFIX) { (*insttable_1byte[0][op])(); continue; } break; } if (prefix == MAX_PREFIX) { EXCEPTION(UD_EXCEPTION, 0); } #if defined(IA32_INSTRUCTION_TRACE) if (op == 0x0f) { BYTE op2; op2 = cpu_codefetch(CPU_EIP); ctx[ctx_index].op[prefix + 1] = op2; ctx[ctx_index].opbytes++; } ctx_index = (ctx_index + 1) % NELEMENTS(ctx); #endif /* normal / rep, but not use */ if (!(insttable_info[op] & INST_STRING) || !CPU_INST_REPUSE) { #if defined(DEBUG) cpu_debug_rep_cont = 0; #endif (*insttable_1byte[CPU_INST_OP32][op])(); return; } /* rep */ CPU_WORKCLOCK(5); #if defined(DEBUG) if (!cpu_debug_rep_cont) { cpu_debug_rep_cont = 1; cpu_debug_rep_regs = CPU_STATSAVE.cpu_regs; } #endif if (!CPU_INST_AS32) { if (CPU_CX != 0) { if (!(insttable_info[op] & REP_CHECKZF)) { /* rep */ for (;;) { (*insttable_1byte[CPU_INST_OP32][op])(); if (--CPU_CX == 0) { #if defined(DEBUG) cpu_debug_rep_cont = 0; #endif break; } if (CPU_REMCLOCK <= 0) { CPU_EIP = CPU_PREV_EIP; break; } } } else if (CPU_INST_REPUSE != 0xf2) { /* repe */ for (;;) { (*insttable_1byte[CPU_INST_OP32][op])(); if (--CPU_CX == 0 || CC_NZ) { #if defined(DEBUG) cpu_debug_rep_cont = 0; #endif break; } if (CPU_REMCLOCK <= 0) { CPU_EIP = CPU_PREV_EIP; break; } } } else { /* repne */ for (;;) { (*insttable_1byte[CPU_INST_OP32][op])(); if (--CPU_CX == 0 || CC_Z) { #if defined(DEBUG) cpu_debug_rep_cont = 0; #endif break; } if (CPU_REMCLOCK <= 0) { CPU_EIP = CPU_PREV_EIP; break; } } } } } else { if (CPU_ECX != 0) { if (!(insttable_info[op] & REP_CHECKZF)) { /* rep */ for (;;) { (*insttable_1byte[CPU_INST_OP32][op])(); if (--CPU_ECX == 0) { #if defined(DEBUG) cpu_debug_rep_cont = 0; #endif break; } if (CPU_REMCLOCK <= 0) { CPU_EIP = CPU_PREV_EIP; break; } } } else if (CPU_INST_REPUSE != 0xf2) { /* repe */ for (;;) { (*insttable_1byte[CPU_INST_OP32][op])(); if (--CPU_ECX == 0 || CC_NZ) { #if defined(DEBUG) cpu_debug_rep_cont = 0; #endif break; } if (CPU_REMCLOCK <= 0) { CPU_EIP = CPU_PREV_EIP; break; } } } else { /* repne */ for (;;) { (*insttable_1byte[CPU_INST_OP32][op])(); if (--CPU_ECX == 0 || CC_Z) { #if defined(DEBUG) cpu_debug_rep_cont = 0; #endif break; } if (CPU_REMCLOCK <= 0) { CPU_EIP = CPU_PREV_EIP; break; } } } } } }