mirror of
https://github.com/holub/mame
synced 2025-05-25 23:35:26 +03:00
i386: various fixes to 486 and Pentium eflags from MESS, and Carl's small
IRQ fix. (no whatsnew)
This commit is contained in:
parent
2642f11217
commit
814eebb930
@ -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;
|
||||
|
||||
|
@ -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);
|
||||
}
|
||||
|
@ -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);
|
||||
}
|
||||
|
@ -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
|
||||
|
||||
|
Loading…
Reference in New Issue
Block a user