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)
b |= 0x0001; // cannot return to real mode using this instruction.
cpustate->cr[0] &= ~0x0000ffff;
cpustate->cr[0] |= b & 0x0000ffff;
cpustate->cr[0] &= ~0x0000000f;
cpustate->cr[0] |= b & 0x0000000f;
break;
}
default:

View File

@ -3163,6 +3163,25 @@ static void I386OP(group0F01_32)(i386_state *cpustate) // Opcode 0x0f 01
}
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:
fatalerror("i386: unimplemented opcode 0x0f 01 /%d at %08X", (modrm >> 3) & 0x7, cpustate->eip - 2);
break;

View File

@ -736,7 +736,10 @@ static void I386OP(mov_rm16_sreg)(i386_state *cpustate) // Opcode 0x8c
int s = (modrm >> 3) & 0x7;
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);
} else {
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 */
{
UINT8 b;
UINT16 b;
if(PROTECTED_MODE && cpustate->CPL)
FAULT(FAULT_GP,0)
if( modrm >= 0xc0 ) {
b = LOAD_RM8(modrm);
b = LOAD_RM16(modrm);
CYCLES(cpustate,CYCLES_LMSW_REG);
} else {
ea = GetEA(cpustate,modrm,0);
CYCLES(cpustate,CYCLES_LMSW_MEM);
b = READ8(cpustate,ea);
b = READ16(cpustate,ea);
}
cpustate->cr[0] &= ~0x03;
cpustate->cr[0] |= b & 0x03;
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 */
@ -387,6 +389,25 @@ static void I486OP(group0F01_32)(i386_state *cpustate) // Opcode 0x0f 01
}
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 */
{
// Nothing to do ?