i386: Added 32-bit versions of LMSW, and made LMSW only change the lower

4 bits of CR0. [Barry Rodewald]
      Fixed Windows 95 blue screen. [Carl]
This commit is contained in:
mahlemiut 2012-02-22 23:42:26 +00:00
parent 965547d513
commit b27a83bf13
4 changed files with 51 additions and 8 deletions

View File

@ -3331,8 +3331,8 @@ static void I386OP(group0F01_16)(i386_state *cpustate) // Opcode 0x0f 01
} }
if(PROTECTED_MODE) if(PROTECTED_MODE)
b |= 0x0001; // cannot return to real mode using this instruction. b |= 0x0001; // cannot return to real mode using this instruction.
cpustate->cr[0] &= ~0x0000ffff; cpustate->cr[0] &= ~0x0000000f;
cpustate->cr[0] |= b & 0x0000ffff; cpustate->cr[0] |= b & 0x0000000f;
break; break;
} }
default: default:

View File

@ -3163,6 +3163,25 @@ static void I386OP(group0F01_32)(i386_state *cpustate) // Opcode 0x0f 01
} }
break; break;
} }
case 6: /* LMSW */
{
if(PROTECTED_MODE && cpustate->CPL)
FAULT(FAULT_GP,0)
UINT16 b;
if( modrm >= 0xc0 ) {
b = LOAD_RM16(modrm);
CYCLES(cpustate,CYCLES_LMSW_REG);
} else {
ea = GetEA(cpustate,modrm,0);
CYCLES(cpustate,CYCLES_LMSW_MEM);
b = READ16(cpustate,ea);
}
if(PROTECTED_MODE)
b |= 0x0001; // cannot return to real mode using this instruction.
cpustate->cr[0] &= ~0x0000000f;
cpustate->cr[0] |= b & 0x0000000f;
break;
}
default: default:
fatalerror("i386: unimplemented opcode 0x0f 01 /%d at %08X", (modrm >> 3) & 0x7, cpustate->eip - 2); fatalerror("i386: unimplemented opcode 0x0f 01 /%d at %08X", (modrm >> 3) & 0x7, cpustate->eip - 2);
break; break;

View File

@ -736,7 +736,10 @@ static void I386OP(mov_rm16_sreg)(i386_state *cpustate) // Opcode 0x8c
int s = (modrm >> 3) & 0x7; int s = (modrm >> 3) & 0x7;
if( modrm >= 0xc0 ) { if( modrm >= 0xc0 ) {
STORE_RM16(modrm, cpustate->sreg[s].selector); if(cpustate->operand_size)
STORE_RM32(modrm, cpustate->sreg[s].selector);
else
STORE_RM16(modrm, cpustate->sreg[s].selector);
CYCLES(cpustate,CYCLES_MOV_SREG_REG); CYCLES(cpustate,CYCLES_MOV_SREG_REG);
} else { } else {
UINT32 ea = GetEA(cpustate,modrm,1); UINT32 ea = GetEA(cpustate,modrm,1);

View File

@ -282,19 +282,21 @@ static void I486OP(group0F01_16)(i386_state *cpustate) // Opcode 0x0f 01
} }
case 6: /* LMSW */ case 6: /* LMSW */
{ {
UINT8 b; UINT16 b;
if(PROTECTED_MODE && cpustate->CPL) if(PROTECTED_MODE && cpustate->CPL)
FAULT(FAULT_GP,0) FAULT(FAULT_GP,0)
if( modrm >= 0xc0 ) { if( modrm >= 0xc0 ) {
b = LOAD_RM8(modrm); b = LOAD_RM16(modrm);
CYCLES(cpustate,CYCLES_LMSW_REG); CYCLES(cpustate,CYCLES_LMSW_REG);
} else { } else {
ea = GetEA(cpustate,modrm,0); ea = GetEA(cpustate,modrm,0);
CYCLES(cpustate,CYCLES_LMSW_MEM); CYCLES(cpustate,CYCLES_LMSW_MEM);
b = READ8(cpustate,ea); b = READ16(cpustate,ea);
} }
cpustate->cr[0] &= ~0x03; if(PROTECTED_MODE)
cpustate->cr[0] |= b & 0x03; b |= 0x0001; // cannot return to real mode using this instruction.
cpustate->cr[0] &= ~0x0000000f;
cpustate->cr[0] |= b & 0x0000000f;
break; break;
} }
case 7: /* INVLPG */ case 7: /* INVLPG */
@ -387,6 +389,25 @@ static void I486OP(group0F01_32)(i386_state *cpustate) // Opcode 0x0f 01
} }
break; break;
} }
case 6: /* LMSW */
{
if(PROTECTED_MODE && cpustate->CPL)
FAULT(FAULT_GP,0)
UINT16 b;
if( modrm >= 0xc0 ) {
b = LOAD_RM16(modrm);
CYCLES(cpustate,CYCLES_LMSW_REG);
} else {
ea = GetEA(cpustate,modrm,0);
CYCLES(cpustate,CYCLES_LMSW_MEM);
b = READ16(cpustate,ea);
}
if(PROTECTED_MODE)
b |= 0x0001; // cannot return to real mode using this instruction.
cpustate->cr[0] &= ~0x0000000f;
cpustate->cr[0] |= b & 0x0000000f;
break;
}
case 7: /* INVLPG */ case 7: /* INVLPG */
{ {
// Nothing to do ? // Nothing to do ?