--- np2/i386c/ia32/instructions/flag_ctrl.c 2003/12/12 15:05:13 1.2 +++ np2/i386c/ia32/instructions/flag_ctrl.c 2008/01/25 17:49:46 1.11 @@ -1,4 +1,4 @@ -/* $Id: flag_ctrl.c,v 1.2 2003/12/12 15:05:13 monaka Exp $ */ +/* $Id: flag_ctrl.c,v 1.11 2008/01/25 17:49:46 monaka Exp $ */ /* * Copyright (c) 2003 NONAKA Kimihiro @@ -12,8 +12,6 @@ * 2. Redistributions in binary form must reproduce the above copyright * notice, this list of conditions and the following disclaimer in the * documentation and/or other materials provided with the distribution. - * 3. The name of the author may not be used to endorse or promote products - * derived from this software without specific prior written permission. * * THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS OR * IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES @@ -101,8 +99,8 @@ PUSHF_Fw(void) { CPU_WORKCLOCK(3); - if (!CPU_STAT_PM || !CPU_STAT_VM86 || (CPU_STAT_CPL == 3)) { - WORD flags = REAL_FLAGREG; + 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; @@ -116,8 +114,8 @@ PUSHFD_Fd(void) { CPU_WORKCLOCK(3); - if (!CPU_STAT_PM || !CPU_STAT_VM86 || (CPU_STAT_CPL == 3)) { - DWORD flags = REAL_EFLAGREG; + 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; @@ -129,7 +127,7 @@ PUSHFD_Fd(void) void POPF_Fw(void) { - WORD flags, mask = 0; + UINT16 flags, mask; CPU_WORKCLOCK(3); if (!CPU_STAT_PM) { @@ -143,6 +141,8 @@ POPF_Fw(void) 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 */ @@ -151,32 +151,36 @@ POPF_Fw(void) } else { EXCEPTION(GP_EXCEPTION, 0); flags = 0; + mask = 0; /* compiler happy */ } - set_flags(flags, mask); + set_eflags(flags, mask); IRQCHECKTERM(); } void POPFD_Fd(void) { - DWORD flags, mask = 0; + UINT32 flags, mask; CPU_WORKCLOCK(3); if (!CPU_STAT_PM) { /* Real Mode */ POP0_32(flags); - flags &= ~(VIF_FLAG|VIP_FLAG); + flags &= ~(RF_FLAG|VIF_FLAG|VIP_FLAG); mask = I_FLAG|IOPL_FLAG|RF_FLAG|VIF_FLAG|VIP_FLAG; } else if (!CPU_STAT_VM86) { /* Protected Mode */ POP0_32(flags); + flags &= ~RF_FLAG; if (CPU_STAT_CPL == 0) { flags &= ~(VIP_FLAG|VIF_FLAG); mask = I_FLAG|IOPL_FLAG|RF_FLAG|VIF_FLAG|VIP_FLAG; } else if (CPU_STAT_CPL <= CPU_STAT_IOPL) { flags &= ~(VIP_FLAG|VIF_FLAG); mask = I_FLAG|RF_FLAG|VIF_FLAG|VIP_FLAG; + } else { + mask = RF_FLAG; } } else if (CPU_STAT_IOPL == CPU_IOPL3) { /* Virtual-8086 Mode, IOPL == 3 */ @@ -185,6 +189,7 @@ POPFD_Fd(void) } else { EXCEPTION(GP_EXCEPTION, 0); flags = 0; + mask = 0; /* compiler happy */ } set_eflags(flags, mask); @@ -196,6 +201,17 @@ 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(); @@ -207,6 +223,17 @@ 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; }