void JMP16_Ap(void) { descriptor_t sd; UINT16 new_ip; UINT16 new_cs; UINT16 sreg; CPU_WORKCLOCK(11); GET_PCWORD(new_ip); GET_PCWORD(new_cs); if (!CPU_STAT_PM || CPU_STAT_VM86) { /* Real mode or VM86 mode */ /* 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, new_cs); CPU_EIP = new_ip; } else { /* Protected mode */ JMPfar_pm(new_cs, new_ip); } }
void CALL16_Ap(void) { descriptor_t sd; UINT16 new_ip; UINT16 new_cs; UINT16 sreg; CPU_WORKCLOCK(13); GET_PCWORD(new_ip); GET_PCWORD(new_cs); if (!CPU_STAT_PM || CPU_STAT_VM86) { /* Real mode or VM86 mode */ CPU_SET_PREV_ESP(); load_segreg(CPU_CS_INDEX, new_cs, &sreg, &sd, GP_EXCEPTION); if (new_ip > sd.u.seg.limit) { EXCEPTION(GP_EXCEPTION, 0); } PUSH0_16(CPU_CS); PUSH0_16(CPU_IP); LOAD_SEGREG(CPU_CS_INDEX, new_cs); CPU_EIP = new_ip; CPU_CLEAR_PREV_ESP(); } else { /* Protected mode */ CALLfar_pm(new_cs, new_ip); } }
void TEST_AXIw(void) { UINT32 src, tmp; CPU_WORKCLOCK(3); tmp = CPU_AX; GET_PCWORD(src); WORD_AND(tmp, src); }
void TEST_EwIw(UINT32 op) { UINT32 src, tmp, madr; if (op >= 0xc0) { CPU_WORKCLOCK(2); tmp = *(reg16_b20[op]); } else { CPU_WORKCLOCK(6); madr = calc_ea_dst(op); tmp = cpu_vmemoryread_w(CPU_INST_SEGREG_INDEX, madr); } GET_PCWORD(src); WORD_AND(tmp, src); }
void RETnear32_Iw(void) { UINT32 new_ip; UINT16 size; CPU_WORKCLOCK(11); CPU_SET_PREV_ESP(); GET_PCWORD(size); POP0_32(new_ip); if (new_ip > CPU_STAT_CS_LIMIT) { EXCEPTION(GP_EXCEPTION, 0); } CPU_EIP = new_ip; if (!CPU_STAT_SS32) { CPU_SP += size; } else { CPU_ESP += size; } CPU_CLEAR_PREV_ESP(); }
void RETfar32_Iw(void) { descriptor_t sd; UINT32 new_ip; UINT32 new_cs; UINT16 sreg; UINT16 size; CPU_WORKCLOCK(15); GET_PCWORD(size); if (!CPU_STAT_PM || CPU_STAT_VM86) { /* Real mode or VM86 mode */ CPU_SET_PREV_ESP(); POP0_32(new_ip); POP0_32(new_cs); /* 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; if (!CPU_STAT_SS32) { CPU_SP += size; } else { CPU_ESP += size; } CPU_CLEAR_PREV_ESP(); } else { /* Protected mode */ RETfar_pm(size); } }
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(); }