void CPUCALL TEST_EdId(UINT32 op) { UINT32 src, tmp, madr; if (op >= 0xc0) { CPU_WORKCLOCK(2); tmp = *(reg32_b20[op]); } else { CPU_WORKCLOCK(6); madr = calc_ea_dst(op); tmp = cpu_vmemoryread_d(CPU_INST_SEGREG_INDEX, madr); } GET_PCDWORD(src); DWORD_AND(tmp, src); }
void SAHF(void) { CPU_WORKCLOCK(2); CPU_FLAGL = (CPU_AH & SZAPC_FLAG) | 0x2; /* SZ0A0P1C */ }
void CPUCALL 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 CLD(void) { CPU_WORKCLOCK(2); CPU_FLAG &= ~D_FLAG; }
void STD(void) { CPU_WORKCLOCK(2); CPU_FLAG |= D_FLAG; }
void CLC(void) { CPU_WORKCLOCK(2); CPU_FLAGL &= ~C_FLAG; }
void CMC(void) { CPU_WORKCLOCK(2); CPU_FLAGL ^= C_FLAG; }
/* * flag contol instructions */ void STC(void) { CPU_WORKCLOCK(2); CPU_FLAGL |= C_FLAG; }
void POPF_Fw(void) { UINT16 flags, mask; CPU_WORKCLOCK(3); if (!CPU_STAT_PM) { /* Real Mode */ POP0_16(flags); mask = I_FLAG|IOPL_FLAG; } else if (!CPU_STAT_VM86) { /* Protected Mode */ POP0_16(flags); if (CPU_STAT_CPL == 0) { mask = I_FLAG|IOPL_FLAG; } else if (CPU_STAT_CPL <= CPU_STAT_IOPL) { mask = I_FLAG; } else { mask = 0; } } else if (CPU_STAT_IOPL == CPU_IOPL3) { /* Virtual-8086 Mode, IOPL == 3 */ POP0_16(flags); mask = I_FLAG; } else { EXCEPTION(GP_EXCEPTION, 0); flags = 0; mask = 0; /* compiler happy */ } set_eflags(flags, mask); IRQCHECKTERM(); }
/* * TEST */ void TEST_EbGb(void) { UINT32 op, src, tmp, madr; PREPART_EA_REG8(op, src); if (op >= 0xc0) { CPU_WORKCLOCK(2); tmp = *(reg8_b20[op]); } else { CPU_WORKCLOCK(7); madr = calc_ea_dst(op); tmp = cpu_vmemoryread(CPU_INST_SEGREG_INDEX, madr); } 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); } }
/* undoc 8086 */ void SALC(void) { CPU_WORKCLOCK(2); CPU_AL = (CPU_FLAGL & C_FLAG) ? 0xff : 0; }
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 BT_EdGd(void) { UINT32 op, src, dst, madr; PREPART_EA_REG32(op, src); if (op >= 0xc0) { CPU_WORKCLOCK(2); dst = *(reg32_b20[op]); } else { CPU_WORKCLOCK(7); madr = calc_ea_dst(op); madr += BIT_OFFSET32(src); dst = cpu_vmemoryread_d(CPU_INST_SEGREG_INDEX, madr); } CPU_FLAGL &= ~C_FLAG; CPU_FLAGL |= (dst >> BIT_INDEX32(src)) & 1; }
void TEST_EAXId(void) { UINT32 src, tmp; CPU_WORKCLOCK(3); tmp = CPU_EAX; GET_PCDWORD(src); DWORD_AND(tmp, src); }
void TEST_AXIw(void) { UINT32 src, tmp; CPU_WORKCLOCK(3); tmp = CPU_AX; GET_PCWORD(src); WORD_AND(tmp, src); }
void TEST_ALIb(void) { UINT32 src, tmp; CPU_WORKCLOCK(3); tmp = CPU_AL; GET_PCBYTE(src); BYTE_AND(tmp, src); }
void CPUCALL JMP_Ed(UINT32 op) { UINT32 madr; UINT32 new_ip; if (op >= 0xc0) { CPU_WORKCLOCK(7); new_ip = *(reg32_b20[op]); } else { CPU_WORKCLOCK(11); madr = calc_ea_dst(op); new_ip = cpu_vmemoryread_d(CPU_INST_SEGREG_INDEX, madr); } if (new_ip > CPU_STAT_CS_LIMIT) { EXCEPTION(GP_EXCEPTION, 0); } CPU_EIP = new_ip; }
void XLAT(void) { CPU_WORKCLOCK(5); CPU_INST_SEGREG_INDEX = DS_FIX; if (!CPU_INST_AS32) { CPU_AL = cpu_vmemoryread(CPU_INST_SEGREG_INDEX, CPU_BX + CPU_AL); } else { CPU_AL = cpu_vmemoryread(CPU_INST_SEGREG_INDEX, CPU_EBX + CPU_AL); } }
void CPUCALL CALL_Ew(UINT32 op) { UINT32 madr; UINT16 new_ip; CPU_SET_PREV_ESP(); if (op >= 0xc0) { CPU_WORKCLOCK(7); new_ip = *(reg16_b20[op]); } else { CPU_WORKCLOCK(11); madr = calc_ea_dst(op); new_ip = cpu_vmemoryread_w(CPU_INST_SEGREG_INDEX, madr); } if (new_ip > CPU_STAT_CS_LIMIT) { EXCEPTION(GP_EXCEPTION, 0); } PUSH0_16(CPU_IP); CPU_EIP = new_ip; CPU_CLEAR_PREV_ESP(); }
/* * PUSHF/POPF */ void PUSHF_Fw(void) { CPU_WORKCLOCK(3); if (!CPU_STAT_PM || !CPU_STAT_VM86 || (CPU_STAT_IOPL == CPU_IOPL3)) { UINT16 flags = REAL_FLAGREG; flags = (flags & ALL_FLAG) | 2; PUSH0_16(flags); return; } /* VM86 && IOPL != 3 */ EXCEPTION(GP_EXCEPTION, 0); }
void RETnear32(void) { UINT32 new_ip; CPU_WORKCLOCK(11); CPU_SET_PREV_ESP(); POP0_32(new_ip); if (new_ip > CPU_STAT_CS_LIMIT) { EXCEPTION(GP_EXCEPTION, 0); } CPU_EIP = new_ip; CPU_CLEAR_PREV_ESP(); }
void PUSHFD_Fd(void) { CPU_WORKCLOCK(3); if (!CPU_STAT_PM || !CPU_STAT_VM86 || (CPU_STAT_IOPL == CPU_IOPL3)) { UINT32 flags = REAL_EFLAGREG & ~(RF_FLAG|VM_FLAG); flags = (flags & ALL_EFLAG) | 2; PUSH0_32(flags); return; } /* VM86 && IOPL != 3 */ EXCEPTION(GP_EXCEPTION, 0); }
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); }
void CALL_Ad(void) { UINT32 new_ip; UINT32 dest; CPU_WORKCLOCK(7); CPU_SET_PREV_ESP(); GET_PCDWORD(dest); new_ip = CPU_EIP + dest; if (new_ip > CPU_STAT_CS_LIMIT) { EXCEPTION(GP_EXCEPTION, 0); } PUSH0_32(CPU_EIP); CPU_EIP = new_ip; CPU_CLEAR_PREV_ESP(); }
/* * CALL */ void CALL_Aw(void) { UINT16 new_ip; SINT16 dest; CPU_WORKCLOCK(7); CPU_SET_PREV_ESP(); GET_PCWORDS(dest); new_ip = CPU_EIP + dest; if (new_ip > CPU_STAT_CS_LIMIT) { EXCEPTION(GP_EXCEPTION, 0); } PUSH0_16(CPU_IP); CPU_EIP = new_ip; CPU_CLEAR_PREV_ESP(); }
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 LEAVE(void) { CPU_WORKCLOCK(4); CPU_SET_PREV_ESP(); if (!CPU_STAT_SS32) { CPU_SP = CPU_BP; } else { CPU_ESP = CPU_EBP; } if (!CPU_INST_OP32) { POP0_16(CPU_BP); } else { POP0_32(CPU_EBP); } CPU_CLEAR_PREV_ESP(); }
void IRET(void) { descriptor_t sd; UINT32 new_ip; UINT32 new_flags; UINT32 new_cs; UINT32 mask; UINT16 sreg; CPU_WORKCLOCK(22); if (!CPU_STAT_PM) { /* Real mode */ CPU_SET_PREV_ESP(); mask = I_FLAG|IOPL_FLAG; if (!CPU_INST_OP32) { POP0_16(new_ip); POP0_16(new_cs); POP0_16(new_flags); } else { POP0_32(new_ip); POP0_32(new_cs); POP0_32(new_flags); mask |= RF_FLAG; } /* check new instrunction pointer with new code segment */ load_segreg(CPU_CS_INDEX, new_cs, &sreg, &sd, GP_EXCEPTION); if (new_ip > sd.u.seg.limit) { EXCEPTION(GP_EXCEPTION, 0); } LOAD_SEGREG(CPU_CS_INDEX, (UINT16)new_cs); CPU_EIP = new_ip; set_eflags(new_flags, mask); CPU_CLEAR_PREV_ESP(); } else { /* Protected mode */ IRET_pm(); } IRQCHECKTERM(); }
void CLI(void) { CPU_WORKCLOCK(2); if (CPU_STAT_PM) { if (!CPU_STAT_VM86) { if (CPU_STAT_CPL > CPU_STAT_IOPL) { EXCEPTION(GP_EXCEPTION, 0); } } else { if (CPU_STAT_IOPL < 3) { EXCEPTION(GP_EXCEPTION, 0); } } } CPU_FLAG &= ~I_FLAG; CPU_TRAP = 0; }