mirror of
https://github.com/reactos/reactos.git
synced 2025-01-03 21:09:19 +00:00
[FAST486]
- Fix VM86-related stuff. - Optimize MOV. svn path=/trunk/; revision=67645
This commit is contained in:
parent
4daee24f06
commit
ed774c797b
3 changed files with 113 additions and 51 deletions
|
@ -67,7 +67,7 @@ Fast486ReadMemory(PFAST486_STATE State,
|
|||
}
|
||||
|
||||
/* Check for protected mode */
|
||||
if (State->ControlRegisters[FAST486_REG_CR0] & FAST486_CR0_PE)
|
||||
if ((State->ControlRegisters[FAST486_REG_CR0] & FAST486_CR0_PE) && !State->Flags.Vm)
|
||||
{
|
||||
/* Privilege checks */
|
||||
|
||||
|
@ -189,7 +189,7 @@ Fast486WriteMemory(PFAST486_STATE State,
|
|||
}
|
||||
|
||||
/* Check for protected mode */
|
||||
if (State->ControlRegisters[FAST486_REG_CR0] & FAST486_CR0_PE)
|
||||
if ((State->ControlRegisters[FAST486_REG_CR0] & FAST486_CR0_PE) && !State->Flags.Vm)
|
||||
{
|
||||
/* Privilege checks */
|
||||
|
||||
|
@ -304,6 +304,7 @@ Fast486InterruptInternal(PFAST486_STATE State,
|
|||
{
|
||||
USHORT OldSs = State->SegmentRegs[FAST486_REG_SS].Selector;
|
||||
ULONG OldEsp = State->GeneralRegs[FAST486_REG_ESP].Long;
|
||||
BOOLEAN OldVm = State->Flags.Vm;
|
||||
|
||||
if (IdtEntry->Type == FAST486_TASK_GATE_SIGNATURE)
|
||||
{
|
||||
|
@ -398,6 +399,12 @@ Fast486InterruptInternal(PFAST486_STATE State,
|
|||
}
|
||||
|
||||
State->GeneralRegs[FAST486_REG_ESP].Long = NewEsp;
|
||||
|
||||
if (State->Flags.Vm)
|
||||
{
|
||||
/* Clear the VM flag */
|
||||
State->Flags.Vm = FALSE;
|
||||
}
|
||||
}
|
||||
|
||||
/* Load new CS */
|
||||
|
@ -418,27 +425,44 @@ Fast486InterruptInternal(PFAST486_STATE State,
|
|||
State->InstPtr.LowWord = IdtEntry->Offset;
|
||||
}
|
||||
|
||||
/* Check if the interrupt handler is more privileged or we're in VM86 mode (again) */
|
||||
if ((OldCpl > GET_SEGMENT_RPL(IdtEntry->Selector)) || State->Flags.Vm)
|
||||
if (OldVm)
|
||||
{
|
||||
if (State->Flags.Vm)
|
||||
/* Push GS, FS, DS and ES */
|
||||
if (!Fast486StackPushInternal(State,
|
||||
GateSize,
|
||||
State->SegmentRegs[FAST486_REG_GS].Selector))
|
||||
{
|
||||
/* Clear the VM flag */
|
||||
State->Flags.Vm = FALSE;
|
||||
|
||||
/* Push GS, FS, DS and ES */
|
||||
if (!Fast486StackPush(State, State->SegmentRegs[FAST486_REG_GS].Selector)) return FALSE;
|
||||
if (!Fast486StackPush(State, State->SegmentRegs[FAST486_REG_FS].Selector)) return FALSE;
|
||||
if (!Fast486StackPush(State, State->SegmentRegs[FAST486_REG_DS].Selector)) return FALSE;
|
||||
if (!Fast486StackPush(State, State->SegmentRegs[FAST486_REG_ES].Selector)) return FALSE;
|
||||
|
||||
/* Now load them with NULL selectors, since they are useless in protected mode */
|
||||
if (!Fast486LoadSegment(State, FAST486_REG_GS, 0)) return FALSE;
|
||||
if (!Fast486LoadSegment(State, FAST486_REG_FS, 0)) return FALSE;
|
||||
if (!Fast486LoadSegment(State, FAST486_REG_DS, 0)) return FALSE;
|
||||
if (!Fast486LoadSegment(State, FAST486_REG_ES, 0)) return FALSE;
|
||||
return FALSE;
|
||||
}
|
||||
if (!Fast486StackPushInternal(State,
|
||||
GateSize,
|
||||
State->SegmentRegs[FAST486_REG_FS].Selector))
|
||||
{
|
||||
return FALSE;
|
||||
}
|
||||
if (!Fast486StackPushInternal(State,
|
||||
GateSize,
|
||||
State->SegmentRegs[FAST486_REG_DS].Selector))
|
||||
{
|
||||
return FALSE;
|
||||
}
|
||||
if (!Fast486StackPushInternal(State,
|
||||
GateSize,
|
||||
State->SegmentRegs[FAST486_REG_ES].Selector))
|
||||
{
|
||||
return FALSE;
|
||||
}
|
||||
|
||||
/* Now load them with NULL selectors, since they are useless in protected mode */
|
||||
if (!Fast486LoadSegment(State, FAST486_REG_GS, 0)) return FALSE;
|
||||
if (!Fast486LoadSegment(State, FAST486_REG_FS, 0)) return FALSE;
|
||||
if (!Fast486LoadSegment(State, FAST486_REG_DS, 0)) return FALSE;
|
||||
if (!Fast486LoadSegment(State, FAST486_REG_ES, 0)) return FALSE;
|
||||
}
|
||||
|
||||
/* Check if the interrupt handler is more privileged or we're in VM86 mode (again) */
|
||||
if ((OldCpl > GET_SEGMENT_RPL(IdtEntry->Selector)) || OldVm)
|
||||
{
|
||||
/* Push SS selector */
|
||||
if (!Fast486StackPushInternal(State, GateSize, OldSs)) return FALSE;
|
||||
|
||||
|
|
|
@ -554,8 +554,24 @@ Fast486LoadSegmentInternal(PFAST486_STATE State,
|
|||
CachedDescriptor = &State->SegmentRegs[Segment];
|
||||
|
||||
/* Check for protected mode */
|
||||
if ((State->ControlRegisters[FAST486_REG_CR0] & FAST486_CR0_PE) && !State->Flags.Vm)
|
||||
if (State->ControlRegisters[FAST486_REG_CR0] & FAST486_CR0_PE)
|
||||
{
|
||||
/* Check for VM86 mode */
|
||||
if (State->Flags.Vm)
|
||||
{
|
||||
/* Update the cached descriptor with VM86 values */
|
||||
CachedDescriptor->Selector = Selector;
|
||||
CachedDescriptor->Base = Selector << 4;
|
||||
CachedDescriptor->Limit = 0xFFFF;
|
||||
CachedDescriptor->ReadWrite = TRUE;
|
||||
CachedDescriptor->DirConf = FALSE;
|
||||
CachedDescriptor->SystemType = TRUE;
|
||||
CachedDescriptor->Dpl = CachedDescriptor->Rpl = 3;
|
||||
CachedDescriptor->Present = TRUE;
|
||||
CachedDescriptor->Size = FALSE;
|
||||
return TRUE;
|
||||
}
|
||||
|
||||
if (!Fast486ReadDescriptorEntry(State, Selector, &Valid, &GdtEntry))
|
||||
{
|
||||
/* Exception occurred */
|
||||
|
|
|
@ -3727,7 +3727,7 @@ FAST486_OPCODE_HANDLER(Fast486OpcodePushByteImm)
|
|||
|
||||
FAST486_OPCODE_HANDLER(Fast486OpcodeMovByteModrm)
|
||||
{
|
||||
UCHAR FirstValue, SecondValue, Result;
|
||||
UCHAR Result;
|
||||
FAST486_MOD_REG_RM ModRegRm;
|
||||
BOOLEAN AddressSize = State->SegmentRegs[FAST486_REG_CS].Size;
|
||||
|
||||
|
@ -3743,24 +3743,28 @@ FAST486_OPCODE_HANDLER(Fast486OpcodeMovByteModrm)
|
|||
return;
|
||||
}
|
||||
|
||||
if (!Fast486ReadModrmByteOperands(State,
|
||||
&ModRegRm,
|
||||
&FirstValue,
|
||||
&SecondValue))
|
||||
if (Opcode & FAST486_OPCODE_WRITE_REG)
|
||||
{
|
||||
/* Exception occurred */
|
||||
return;
|
||||
if (!Fast486ReadModrmByteOperands(State, &ModRegRm, NULL, &Result))
|
||||
{
|
||||
/* Exception occurred */
|
||||
return;
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
if (!Fast486ReadModrmByteOperands(State, &ModRegRm, &Result, NULL))
|
||||
{
|
||||
/* Exception occurred */
|
||||
return;
|
||||
}
|
||||
}
|
||||
|
||||
if (Opcode & FAST486_OPCODE_WRITE_REG) Result = SecondValue;
|
||||
else Result = FirstValue;
|
||||
|
||||
/* Write back the result */
|
||||
Fast486WriteModrmByteOperands(State,
|
||||
&ModRegRm,
|
||||
Opcode & FAST486_OPCODE_WRITE_REG,
|
||||
Result);
|
||||
|
||||
}
|
||||
|
||||
FAST486_OPCODE_HANDLER(Fast486OpcodeMovModrm)
|
||||
|
@ -3786,19 +3790,26 @@ FAST486_OPCODE_HANDLER(Fast486OpcodeMovModrm)
|
|||
/* Check the operand size */
|
||||
if (OperandSize)
|
||||
{
|
||||
ULONG FirstValue, SecondValue, Result;
|
||||
ULONG Result;
|
||||
|
||||
if (!Fast486ReadModrmDwordOperands(State,
|
||||
&ModRegRm,
|
||||
&FirstValue,
|
||||
&SecondValue))
|
||||
|
||||
|
||||
if (Opcode & FAST486_OPCODE_WRITE_REG)
|
||||
{
|
||||
/* Exception occurred */
|
||||
return;
|
||||
if (!Fast486ReadModrmDwordOperands(State, &ModRegRm, NULL, &Result))
|
||||
{
|
||||
/* Exception occurred */
|
||||
return;
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
if (!Fast486ReadModrmDwordOperands(State, &ModRegRm, &Result, NULL))
|
||||
{
|
||||
/* Exception occurred */
|
||||
return;
|
||||
}
|
||||
}
|
||||
|
||||
if (Opcode & FAST486_OPCODE_WRITE_REG) Result = SecondValue;
|
||||
else Result = FirstValue;
|
||||
|
||||
/* Write back the result */
|
||||
Fast486WriteModrmDwordOperands(State,
|
||||
|
@ -3808,19 +3819,24 @@ FAST486_OPCODE_HANDLER(Fast486OpcodeMovModrm)
|
|||
}
|
||||
else
|
||||
{
|
||||
USHORT FirstValue, SecondValue, Result;
|
||||
USHORT Result;
|
||||
|
||||
if (!Fast486ReadModrmWordOperands(State,
|
||||
&ModRegRm,
|
||||
&FirstValue,
|
||||
&SecondValue))
|
||||
if (Opcode & FAST486_OPCODE_WRITE_REG)
|
||||
{
|
||||
/* Exception occurred */
|
||||
return;
|
||||
if (!Fast486ReadModrmWordOperands(State, &ModRegRm, NULL, &Result))
|
||||
{
|
||||
/* Exception occurred */
|
||||
return;
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
if (!Fast486ReadModrmWordOperands(State, &ModRegRm, &Result, NULL))
|
||||
{
|
||||
/* Exception occurred */
|
||||
return;
|
||||
}
|
||||
}
|
||||
|
||||
if (Opcode & FAST486_OPCODE_WRITE_REG) Result = SecondValue;
|
||||
else Result = FirstValue;
|
||||
|
||||
/* Write back the result */
|
||||
Fast486WriteModrmWordOperands(State,
|
||||
|
@ -4696,11 +4712,17 @@ FAST486_OPCODE_HANDLER(Fast486OpcodeIret)
|
|||
/* Set the new IP */
|
||||
State->InstPtr.Long = LOWORD(InstPtr);
|
||||
|
||||
/* Set the new SP */
|
||||
State->GeneralRegs[FAST486_REG_ESP].Long = StackPtr;
|
||||
|
||||
/* Set the new flags */
|
||||
if (Size) State->Flags.Long = NewFlags.Long & REAL_MODE_FLAGS_MASK;
|
||||
else State->Flags.LowWord = NewFlags.LowWord & REAL_MODE_FLAGS_MASK;
|
||||
State->Flags.AlwaysSet = State->Flags.Vm = TRUE;
|
||||
|
||||
/* Switch to CPL 3 */
|
||||
State->Cpl = 3;
|
||||
|
||||
/* Load the new segments */
|
||||
if (!Fast486LoadSegment(State, FAST486_REG_CS, CodeSel)) return;
|
||||
if (!Fast486LoadSegment(State, FAST486_REG_SS, StackSel)) return;
|
||||
|
|
Loading…
Reference in a new issue