Honore the fixed bits of flags when pushing them to the stack, fixes #5093.
This commit is contained in:
@@ -390,6 +390,8 @@ ropPUSHF(UNUSED(codeblock_t *block), ir_data_t *ir, UNUSED(uint8_t opcode), UNUS
|
|||||||
uop_MOV_IMM(ir, IREG_oldpc, cpu_state.oldpc);
|
uop_MOV_IMM(ir, IREG_oldpc, cpu_state.oldpc);
|
||||||
uop_CALL_FUNC(ir, flags_rebuild);
|
uop_CALL_FUNC(ir, flags_rebuild);
|
||||||
sp_reg = LOAD_SP_WITH_OFFSET(ir, -2);
|
sp_reg = LOAD_SP_WITH_OFFSET(ir, -2);
|
||||||
|
uop_AND_IMM(ir, IREG_flags, IREG_flags, 0x7fd5);
|
||||||
|
uop_OR_IMM(ir, IREG_flags, IREG_flags, 0x0002);
|
||||||
uop_MEM_STORE_REG(ir, IREG_SS_base, sp_reg, IREG_flags);
|
uop_MEM_STORE_REG(ir, IREG_SS_base, sp_reg, IREG_flags);
|
||||||
SUB_SP(ir, 2);
|
SUB_SP(ir, 2);
|
||||||
|
|
||||||
@@ -406,6 +408,8 @@ ropPUSHFD(UNUSED(codeblock_t *block), ir_data_t *ir, UNUSED(uint8_t opcode), UNU
|
|||||||
uop_MOV_IMM(ir, IREG_oldpc, cpu_state.oldpc);
|
uop_MOV_IMM(ir, IREG_oldpc, cpu_state.oldpc);
|
||||||
uop_CALL_FUNC(ir, flags_rebuild);
|
uop_CALL_FUNC(ir, flags_rebuild);
|
||||||
|
|
||||||
|
uop_AND_IMM(ir, IREG_flags, IREG_flags, 0x7fd5);
|
||||||
|
uop_OR_IMM(ir, IREG_flags, IREG_flags, 0x0002);
|
||||||
if (cpu_CR4_mask & CR4_VME)
|
if (cpu_CR4_mask & CR4_VME)
|
||||||
uop_AND_IMM(ir, IREG_temp0_W, IREG_eflags, 0x3c);
|
uop_AND_IMM(ir, IREG_temp0_W, IREG_eflags, 0x3c);
|
||||||
else if (CPUID)
|
else if (CPUID)
|
||||||
|
|||||||
@@ -121,6 +121,7 @@ opPUSHF(UNUSED(uint32_t fetchdat))
|
|||||||
temp = (cpu_state.flags & ~I_FLAG) | 0x3000;
|
temp = (cpu_state.flags & ~I_FLAG) | 0x3000;
|
||||||
if (cpu_state.eflags & VIF_FLAG)
|
if (cpu_state.eflags & VIF_FLAG)
|
||||||
temp |= I_FLAG;
|
temp |= I_FLAG;
|
||||||
|
temp = (temp & 0x7fd5) | 2;
|
||||||
PUSH_W(temp);
|
PUSH_W(temp);
|
||||||
} else {
|
} else {
|
||||||
x86gpf(NULL, 0);
|
x86gpf(NULL, 0);
|
||||||
@@ -128,6 +129,7 @@ opPUSHF(UNUSED(uint32_t fetchdat))
|
|||||||
}
|
}
|
||||||
} else {
|
} else {
|
||||||
flags_rebuild();
|
flags_rebuild();
|
||||||
|
cpu_state.flags = (cpu_state.flags & 0x7fd5) | 2;
|
||||||
PUSH_W(cpu_state.flags);
|
PUSH_W(cpu_state.flags);
|
||||||
}
|
}
|
||||||
CLOCK_CYCLES(4);
|
CLOCK_CYCLES(4);
|
||||||
@@ -149,6 +151,7 @@ opPUSHFD(UNUSED(uint32_t fetchdat))
|
|||||||
else
|
else
|
||||||
tempw = cpu_state.eflags & 4;
|
tempw = cpu_state.eflags & 4;
|
||||||
flags_rebuild();
|
flags_rebuild();
|
||||||
|
cpu_state.flags = (cpu_state.flags & 0x7fd5) | 2;
|
||||||
PUSH_L(cpu_state.flags | (tempw << 16));
|
PUSH_L(cpu_state.flags | (tempw << 16));
|
||||||
CLOCK_CYCLES(4);
|
CLOCK_CYCLES(4);
|
||||||
PREFETCH_RUN(4, 1, -1, 0, 0, 0, 1, 0);
|
PREFETCH_RUN(4, 1, -1, 0, 0, 0, 1, 0);
|
||||||
@@ -160,23 +163,11 @@ opPOPF_186(UNUSED(uint32_t fetchdat))
|
|||||||
{
|
{
|
||||||
uint16_t tempw;
|
uint16_t tempw;
|
||||||
|
|
||||||
if ((cpu_state.eflags & VM_FLAG) && (IOPL < 3)) {
|
|
||||||
x86gpf(NULL, 0);
|
|
||||||
return 1;
|
|
||||||
}
|
|
||||||
|
|
||||||
tempw = POP_W();
|
tempw = POP_W();
|
||||||
if (cpu_state.abrt)
|
if (cpu_state.abrt)
|
||||||
return 1;
|
return 1;
|
||||||
|
|
||||||
if (!(msw & 1))
|
|
||||||
cpu_state.flags = (cpu_state.flags & 0x7000) | (tempw & 0x0fd5) | 2;
|
cpu_state.flags = (cpu_state.flags & 0x7000) | (tempw & 0x0fd5) | 2;
|
||||||
else if (!(CPL))
|
|
||||||
cpu_state.flags = (tempw & 0x7fd5) | 2;
|
|
||||||
else if (IOPLp)
|
|
||||||
cpu_state.flags = (cpu_state.flags & 0x3000) | (tempw & 0x4fd5) | 2;
|
|
||||||
else
|
|
||||||
cpu_state.flags = (cpu_state.flags & 0x3200) | (tempw & 0x4dd5) | 2;
|
|
||||||
flags_extract();
|
flags_extract();
|
||||||
#ifdef USE_DEBUG_REGS_486
|
#ifdef USE_DEBUG_REGS_486
|
||||||
rf_flag_no_clear = 1;
|
rf_flag_no_clear = 1;
|
||||||
|
|||||||
@@ -121,6 +121,7 @@ opPUSHF(UNUSED(uint32_t fetchdat))
|
|||||||
temp = (cpu_state.flags & ~I_FLAG) | 0x3000;
|
temp = (cpu_state.flags & ~I_FLAG) | 0x3000;
|
||||||
if (cpu_state.eflags & VIF_FLAG)
|
if (cpu_state.eflags & VIF_FLAG)
|
||||||
temp |= I_FLAG;
|
temp |= I_FLAG;
|
||||||
|
temp = (temp & 0x7fd5) | 2;
|
||||||
PUSH_W(temp);
|
PUSH_W(temp);
|
||||||
} else {
|
} else {
|
||||||
x86gpf(NULL, 0);
|
x86gpf(NULL, 0);
|
||||||
@@ -128,6 +129,7 @@ opPUSHF(UNUSED(uint32_t fetchdat))
|
|||||||
}
|
}
|
||||||
} else {
|
} else {
|
||||||
flags_rebuild();
|
flags_rebuild();
|
||||||
|
cpu_state.flags = (cpu_state.flags & 0x7fd5) | 2;
|
||||||
PUSH_W(cpu_state.flags);
|
PUSH_W(cpu_state.flags);
|
||||||
}
|
}
|
||||||
CLOCK_CYCLES(4);
|
CLOCK_CYCLES(4);
|
||||||
@@ -149,6 +151,7 @@ opPUSHFD(UNUSED(uint32_t fetchdat))
|
|||||||
else
|
else
|
||||||
tempw = cpu_state.eflags & 4;
|
tempw = cpu_state.eflags & 4;
|
||||||
flags_rebuild();
|
flags_rebuild();
|
||||||
|
cpu_state.flags = (cpu_state.flags & 0x7fd5) | 2;
|
||||||
PUSH_L(cpu_state.flags | (tempw << 16));
|
PUSH_L(cpu_state.flags | (tempw << 16));
|
||||||
CLOCK_CYCLES(4);
|
CLOCK_CYCLES(4);
|
||||||
PREFETCH_RUN(4, 1, -1, 0, 0, 0, 1, 0);
|
PREFETCH_RUN(4, 1, -1, 0, 0, 0, 1, 0);
|
||||||
@@ -160,23 +163,11 @@ opPOPF_186(UNUSED(uint32_t fetchdat))
|
|||||||
{
|
{
|
||||||
uint16_t tempw;
|
uint16_t tempw;
|
||||||
|
|
||||||
if ((cpu_state.eflags & VM_FLAG) && (IOPL < 3)) {
|
|
||||||
x86gpf(NULL, 0);
|
|
||||||
return 1;
|
|
||||||
}
|
|
||||||
|
|
||||||
tempw = POP_W();
|
tempw = POP_W();
|
||||||
if (cpu_state.abrt)
|
if (cpu_state.abrt)
|
||||||
return 1;
|
return 1;
|
||||||
|
|
||||||
if (!(msw & 1))
|
|
||||||
cpu_state.flags = (cpu_state.flags & 0x7000) | (tempw & 0x0fd5) | 2;
|
cpu_state.flags = (cpu_state.flags & 0x7000) | (tempw & 0x0fd5) | 2;
|
||||||
else if (!(CPL))
|
|
||||||
cpu_state.flags = (tempw & 0x7fd5) | 2;
|
|
||||||
else if (IOPLp)
|
|
||||||
cpu_state.flags = (cpu_state.flags & 0x3000) | (tempw & 0x4fd5) | 2;
|
|
||||||
else
|
|
||||||
cpu_state.flags = (cpu_state.flags & 0x3200) | (tempw & 0x4dd5) | 2;
|
|
||||||
flags_extract();
|
flags_extract();
|
||||||
rf_flag_no_clear = 1;
|
rf_flag_no_clear = 1;
|
||||||
|
|
||||||
|
|||||||
Reference in New Issue
Block a user