Author: aandrejevic
Date: Sat Nov 22 16:33:47 2014
New Revision: 65447

URL: http://svn.reactos.org/svn/reactos?rev=65447&view=rev
Log:
[FAST486]
- Fix interrupts in V86 mode.
- CLI and STI should call Fast486GetCurrentPrivLevel in their IOPL check, since 
it
  always returns 3 if the VM flag is set.


Modified:
    trunk/reactos/lib/fast486/common.c
    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=65447&r1=65446&r2=65447&view=diff
==============================================================================
--- trunk/reactos/lib/fast486/common.c  [iso-8859-1] (original)
+++ trunk/reactos/lib/fast486/common.c  [iso-8859-1] Sat Nov 22 16:33:47 2014
@@ -294,8 +294,9 @@
             State->PrefixFlags |= FAST486_PREFIX_OPSIZE;
         }
 
-        /* Check if the interrupt handler is more privileged */
-        if (Fast486GetCurrentPrivLevel(State) > 
GET_SEGMENT_RPL(SegmentSelector))
+        /* Check if the interrupt handler is more privileged or if we're in 
V86 mode */
+        if ((Fast486GetCurrentPrivLevel(State) > 
GET_SEGMENT_RPL(SegmentSelector))
+            || State->Flags.Vm)
         {
             /* Read the TSS */
             if (!Fast486ReadLinearMemory(State,
@@ -309,6 +310,24 @@
 
             /* Switch to the new privilege level */
             State->Cpl = GET_SEGMENT_RPL(SegmentSelector);
+
+            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)) goto Cleanup;
+                if (!Fast486StackPush(State, 
State->SegmentRegs[FAST486_REG_FS].Selector)) goto Cleanup;
+                if (!Fast486StackPush(State, 
State->SegmentRegs[FAST486_REG_DS].Selector)) goto Cleanup;
+                if (!Fast486StackPush(State, 
State->SegmentRegs[FAST486_REG_ES].Selector)) goto Cleanup;
+
+                /* Now load them with NULL selectors, since they are useless 
in protected mode */
+                if (!Fast486LoadSegment(State, FAST486_REG_GS, 0)) goto 
Cleanup;
+                if (!Fast486LoadSegment(State, FAST486_REG_FS, 0)) goto 
Cleanup;
+                if (!Fast486LoadSegment(State, FAST486_REG_DS, 0)) goto 
Cleanup;
+                if (!Fast486LoadSegment(State, FAST486_REG_ES, 0)) goto 
Cleanup;
+            }
 
             /* Check the new (higher) privilege level */
             switch (State->Cpl)

Modified: trunk/reactos/lib/fast486/opcodes.c
URL: 
http://svn.reactos.org/svn/reactos/trunk/reactos/lib/fast486/opcodes.c?rev=65447&r1=65446&r2=65447&view=diff
==============================================================================
--- trunk/reactos/lib/fast486/opcodes.c [iso-8859-1] (original)
+++ trunk/reactos/lib/fast486/opcodes.c [iso-8859-1] Sat Nov 22 16:33:47 2014
@@ -754,7 +754,7 @@
     if (State->ControlRegisters[FAST486_REG_CR0] & FAST486_CR0_PE)
     {
         /* Check IOPL */
-        if (State->Flags.Iopl >= State->SegmentRegs[FAST486_REG_CS].Dpl)
+        if (State->Flags.Iopl >= Fast486GetCurrentPrivLevel(State))
         {
             /* Clear the interrupt flag */
             State->Flags.If = FALSE;
@@ -789,7 +789,7 @@
     if (State->ControlRegisters[FAST486_REG_CR0] & FAST486_CR0_PE)
     {
         /* Check IOPL */
-        if (State->Flags.Iopl >= State->SegmentRegs[FAST486_REG_CS].Dpl)
+        if (State->Flags.Iopl >= Fast486GetCurrentPrivLevel(State))
         {
             /* Set the interrupt flag */
             State->Flags.If = TRUE;
@@ -4547,6 +4547,14 @@
 FAST486_OPCODE_HANDLER(Fast486OpcodeInt)
 {
     UCHAR IntNum;
+
+    /* Check for V86 mode */
+    if (State->Flags.Vm && (State->Flags.Iopl != 3))
+    {
+        /* Call the V86 monitor */
+        Fast486Exception(State, FAST486_EXCEPTION_GP);
+        return;
+    }
 
     switch (Opcode)
     {


Reply via email to