diff --git a/src/emu/cpu/i386/i386.c b/src/emu/cpu/i386/i386.c index 6d54afbd1af..1b5655e7928 100644 --- a/src/emu/cpu/i386/i386.c +++ b/src/emu/cpu/i386/i386.c @@ -169,7 +169,12 @@ static UINT32 get_flags(i386_state *cpustate) f |= cpustate->IOP1 << 12; f |= cpustate->IOP2 << 13; f |= cpustate->NT << 14; + f |= cpustate->RF << 16; f |= cpustate->VM << 17; + f |= cpustate->AC << 18; + f |= cpustate->VIF << 19; + f |= cpustate->VIP << 20; + f |= cpustate->ID << 21; return (cpustate->eflags & ~cpustate->eflags_mask) | (f & cpustate->eflags_mask); } @@ -187,7 +192,12 @@ static void set_flags(i386_state *cpustate, UINT32 f ) cpustate->IOP1 = (f & 0x1000) ? 1 : 0; cpustate->IOP2 = (f & 0x2000) ? 1 : 0; cpustate->NT = (f & 0x4000) ? 1 : 0; + cpustate->RF = (f & 0x10000) ? 1 : 0; cpustate->VM = (f & 0x20000) ? 1 : 0; + cpustate->AC = (f & 0x40000) ? 1 : 0; + cpustate->VIF = (f & 0x80000) ? 1 : 0; + cpustate->VIP = (f & 0x100000) ? 1 : 0; + cpustate->ID = (f & 0x200000) ? 1 : 0; cpustate->eflags = f & cpustate->eflags_mask; } @@ -2193,7 +2203,7 @@ static void i386_protected_mode_iret(i386_state* cpustate, int operand32) { UINT32 task = READ32(cpustate,cpustate->task.base); /* Task Return */ - popmessage("IRET: Nested task return."); + logerror("IRET (%08x): Nested task return.\n",cpustate->pc); /* Check back-link selector in TSS */ if(task & 0x04) { @@ -3022,6 +3032,7 @@ static CPU_EXECUTE( i386 ) while( cpustate->cycles > 0 ) { + i386_check_irq_line(cpustate); cpustate->operand_size = cpustate->sreg[CS].d; cpustate->address_size = cpustate->sreg[CS].d; cpustate->operand_prefix = 0; @@ -3034,7 +3045,6 @@ static CPU_EXECUTE( i386 ) debugger_instruction_hook(device, cpustate->pc); - i386_check_irq_line(cpustate); if(cpustate->delayed_interrupt_enable != 0) { cpustate->IF = 1; @@ -3540,8 +3550,8 @@ static CPU_RESET( pentium ) cpustate->a20_mask = ~0; cpustate->cr[0] = 0x00000010; - cpustate->eflags = 0; - cpustate->eflags_mask = 0x003b7fd7; + cpustate->eflags = 0x00200000; + cpustate->eflags_mask = 0x003f7fd7; cpustate->eip = 0xfff0; // [11:8] Family @@ -3672,7 +3682,7 @@ static CPU_RESET( mediagx ) cpustate->a20_mask = ~0; cpustate->cr[0] = 0x00000010; - cpustate->eflags = 0; + cpustate->eflags = 0x00200000; cpustate->eflags_mask = 0x00277fd7; /* TODO: is this correct? */ cpustate->eip = 0xfff0; diff --git a/src/emu/cpu/i386/i386op16.c b/src/emu/cpu/i386/i386op16.c index 2bb57fe9bfc..099d7650230 100644 --- a/src/emu/cpu/i386/i386op16.c +++ b/src/emu/cpu/i386/i386op16.c @@ -1626,6 +1626,16 @@ static void I386OP(popf)(i386_state *cpustate) // Opcode 0x9d if(cpustate->CPL > IOPL) mask &= ~0x00000200; + if(V8086_MODE) + { + if(IOPL < 3) + { + logerror("POPFD(%08x): IOPL < 3 while in V86 mode.\n",cpustate->pc); + FAULT(FAULT_GP,0) // #GP(0) + } + mask &= ~0x00003000; // IOPL cannot be changed while in V8086 mode + } + set_flags(cpustate,(current & ~mask) | (value & mask)); // mask out reserved bits CYCLES(cpustate,CYCLES_POPF); } diff --git a/src/emu/cpu/i386/i386op32.c b/src/emu/cpu/i386/i386op32.c index 463e3a4e60b..74fd59461d8 100644 --- a/src/emu/cpu/i386/i386op32.c +++ b/src/emu/cpu/i386/i386op32.c @@ -1492,7 +1492,9 @@ static void I386OP(popfd)(i386_state *cpustate) // Opcode 0x9d UINT32 value = POP32(cpustate); UINT32 current = get_flags(cpustate); UINT8 IOPL = (current >> 12) & 0x03; - UINT32 mask = 0x00007fd5; // VM and RF are not affected by POPF or POPFD, same for higher (486+) bits? + UINT32 mask = 0x00257fd5; // VM, VIP and VIF cannot be set by POPF/POPFD + + value &= ~0x00010000; // RF will always return zero // IOPL can only change if CPL is 0 if(cpustate->CPL != 0) @@ -1502,6 +1504,15 @@ static void I386OP(popfd)(i386_state *cpustate) // Opcode 0x9d if(cpustate->CPL > IOPL) mask &= ~0x00000200; + if(V8086_MODE) + { + if(IOPL < 3) + { + logerror("POPFD(%08x): IOPL < 3 while in V86 mode.\n",cpustate->pc); + FAULT(FAULT_GP,0) // #GP(0) + } + mask &= ~0x00003000; // IOPL cannot be changed while in V8086 mode + } set_flags(cpustate,(current & ~mask) | (value & mask)); // mask out reserved bits CYCLES(cpustate,CYCLES_POPF); } diff --git a/src/emu/cpu/i386/i386priv.h b/src/emu/cpu/i386/i386priv.h index 41928968707..651477e2092 100644 --- a/src/emu/cpu/i386/i386priv.h +++ b/src/emu/cpu/i386/i386priv.h @@ -225,7 +225,12 @@ struct _i386_state UINT8 IOP1; UINT8 IOP2; UINT8 NT; + UINT8 RF; UINT8 VM; + UINT8 AC; + UINT8 VIF; + UINT8 VIP; + UINT8 ID; UINT8 CPL; // current privilege level