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(); }
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 STI(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 = (CPU_FLAG & (I_FLAG|T_FLAG)) == (I_FLAG|T_FLAG); exec_1step(); IRQCHECKTERM(); }