Author: aandrejevic
Date: Sun May 10 21:59:07 2015
New Revision: 67645
URL:
http://svn.reactos.org/svn/reactos?rev=67645&view=rev
Log:
[FAST486]
- Fix VM86-related stuff.
- Optimize MOV.
Modified:
trunk/reactos/lib/fast486/common.c
trunk/reactos/lib/fast486/common.inl
trunk/reactos/lib/fast486/opcodes.c
Modified: trunk/reactos/lib/fast486/common.c
URL:
http://svn.reactos.org/svn/reactos/trunk/reactos/lib/fast486/common.c?rev=6…
==============================================================================
--- trunk/reactos/lib/fast486/common.c [iso-8859-1] (original)
+++ trunk/reactos/lib/fast486/common.c [iso-8859-1] Sun May 10 21:59:07 2015
@@ -67,7 +67,7 @@
}
/* 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 @@
}
/* 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 @@
{
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 @@
}
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 @@
State->InstPtr.LowWord = IdtEntry->Offset;
}
+ if (OldVm)
+ {
+ /* Push GS, FS, DS and ES */
+ if (!Fast486StackPushInternal(State,
+ GateSize,
+
State->SegmentRegs[FAST486_REG_GS].Selector))
+ {
+ 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)) || State->Flags.Vm)
- {
- if (State->Flags.Vm)
- {
- /* 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;
- }
-
+ if ((OldCpl > GET_SEGMENT_RPL(IdtEntry->Selector)) || OldVm)
+ {
/* Push SS selector */
if (!Fast486StackPushInternal(State, GateSize, OldSs)) return FALSE;
Modified: trunk/reactos/lib/fast486/common.inl
URL:
http://svn.reactos.org/svn/reactos/trunk/reactos/lib/fast486/common.inl?rev…
==============================================================================
--- trunk/reactos/lib/fast486/common.inl [iso-8859-1] (original)
+++ trunk/reactos/lib/fast486/common.inl [iso-8859-1] Sun May 10 21:59:07 2015
@@ -554,8 +554,24 @@
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 */
Modified: trunk/reactos/lib/fast486/opcodes.c
URL:
http://svn.reactos.org/svn/reactos/trunk/reactos/lib/fast486/opcodes.c?rev=…
==============================================================================
--- trunk/reactos/lib/fast486/opcodes.c [iso-8859-1] (original)
+++ trunk/reactos/lib/fast486/opcodes.c [iso-8859-1] Sun May 10 21:59:07 2015
@@ -3727,7 +3727,7 @@
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 @@
return;
}
- if (!Fast486ReadModrmByteOperands(State,
- &ModRegRm,
- &FirstValue,
- &SecondValue))
- {
- /* Exception occurred */
- return;
- }
-
- if (Opcode & FAST486_OPCODE_WRITE_REG) Result = SecondValue;
- else Result = FirstValue;
+ if (Opcode & FAST486_OPCODE_WRITE_REG)
+ {
+ if (!Fast486ReadModrmByteOperands(State, &ModRegRm, NULL, &Result))
+ {
+ /* Exception occurred */
+ return;
+ }
+ }
+ else
+ {
+ if (!Fast486ReadModrmByteOperands(State, &ModRegRm, &Result, NULL))
+ {
+ /* Exception occurred */
+ return;
+ }
+ }
/* Write back the result */
Fast486WriteModrmByteOperands(State,
&ModRegRm,
Opcode & FAST486_OPCODE_WRITE_REG,
Result);
-
}
FAST486_OPCODE_HANDLER(Fast486OpcodeMovModrm)
@@ -3786,19 +3790,26 @@
/* Check the operand size */
if (OperandSize)
{
- ULONG FirstValue, SecondValue, Result;
-
- if (!Fast486ReadModrmDwordOperands(State,
- &ModRegRm,
- &FirstValue,
- &SecondValue))
- {
- /* Exception occurred */
- return;
- }
-
- if (Opcode & FAST486_OPCODE_WRITE_REG) Result = SecondValue;
- else Result = FirstValue;
+ ULONG Result;
+
+
+
+ if (Opcode & FAST486_OPCODE_WRITE_REG)
+ {
+ if (!Fast486ReadModrmDwordOperands(State, &ModRegRm, NULL, &Result))
+ {
+ /* Exception occurred */
+ return;
+ }
+ }
+ else
+ {
+ if (!Fast486ReadModrmDwordOperands(State, &ModRegRm, &Result, NULL))
+ {
+ /* Exception occurred */
+ return;
+ }
+ }
/* Write back the result */
Fast486WriteModrmDwordOperands(State,
@@ -3808,19 +3819,24 @@
}
else
{
- USHORT FirstValue, SecondValue, Result;
-
- if (!Fast486ReadModrmWordOperands(State,
- &ModRegRm,
- &FirstValue,
- &SecondValue))
- {
- /* Exception occurred */
- return;
- }
-
- if (Opcode & FAST486_OPCODE_WRITE_REG) Result = SecondValue;
- else Result = FirstValue;
+ USHORT Result;
+
+ if (Opcode & FAST486_OPCODE_WRITE_REG)
+ {
+ if (!Fast486ReadModrmWordOperands(State, &ModRegRm, NULL, &Result))
+ {
+ /* Exception occurred */
+ return;
+ }
+ }
+ else
+ {
+ if (!Fast486ReadModrmWordOperands(State, &ModRegRm, &Result, NULL))
+ {
+ /* Exception occurred */
+ return;
+ }
+ }
/* Write back the result */
Fast486WriteModrmWordOperands(State,
@@ -4696,10 +4712,16 @@
/* 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;