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=67... ============================================================================== --- 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=6... ============================================================================== --- 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;