[FAST486]
authorAleksandar Andrejevic <aandrejevic@reactos.org>
Sat, 23 Nov 2013 01:34:03 +0000 (01:34 +0000)
committerAleksandar Andrejevic <aandrejevic@reactos.org>
Sat, 23 Nov 2013 01:34:03 +0000 (01:34 +0000)
The 486 doesn't have AC, VIF, VIP or ID.
Fix and simplify POPF.
[NTVDM]
Fix the count in the XMS copy function (INT 15h, AH = 87h).

svn path=/branches/ntvdm/; revision=61082

include/reactos/libs/fast486/fast486.h
lib/fast486/fast486.c
lib/fast486/opcodes.c
subsystems/ntvdm/bios.c

index d545704..3a7a608 100644 (file)
@@ -341,12 +341,8 @@ typedef union _FAST486_FLAGS_REG
         ULONG Reserved2 : 1;
         ULONG Rf        : 1;
         ULONG Vm        : 1;
-        ULONG Ac        : 1;
-        ULONG Vif       : 1;
-        ULONG Vip       : 1;
-        ULONG Id        : 1;
 
-        // ULONG Reserved : 10;
+        // ULONG Reserved : 14;
     };
 } FAST486_FLAGS_REG, *PFAST486_FLAGS_REG;
 
index 7fef986..f28e9c9 100644 (file)
@@ -330,7 +330,7 @@ Fast486DumpState(PFAST486_STATE State)
             State->SegmentRegs[FAST486_REG_GS].Base,
             State->SegmentRegs[FAST486_REG_GS].Limit,
             State->SegmentRegs[FAST486_REG_GS].Dpl);
-    DPRINT1("\nFlags: %08X (%s %s %s %s %s %s %s %s %s %s %s %s %s %s %s) Iopl: %u\n",
+    DPRINT1("\nFlags: %08X (%s %s %s %s %s %s %s %s %s %s %s %s) Iopl: %u\n",
             State->Flags.Long,
             State->Flags.Cf ? "CF" : "cf",
             State->Flags.Pf ? "PF" : "pf",
@@ -344,9 +344,6 @@ Fast486DumpState(PFAST486_STATE State)
             State->Flags.Nt ? "NT" : "nt",
             State->Flags.Rf ? "RF" : "rf",
             State->Flags.Vm ? "VM" : "vm",
-            State->Flags.Ac ? "AC" : "ac",
-            State->Flags.Vif ? "VIF" : "vif",
-            State->Flags.Vip ? "VIP" : "vip",
             State->Flags.Iopl);
     DPRINT1("\nControl Registers:\n"
             "CR0 = %08X\tCR2 = %08X\tCR3 = %08X\n",
index 48c249f..52970d4 100644 (file)
@@ -4163,121 +4163,37 @@ FAST486_OPCODE_HANDLER(Fast486OpcodePopFlags)
 {
     BOOLEAN Size = State->SegmentRegs[FAST486_REG_CS].Size;
     INT Cpl = Fast486GetCurrentPrivLevel(State);
-    ULONG NewFlags;
+    FAST486_FLAGS_REG NewFlags;
 
     NO_LOCK_PREFIX();
     TOGGLE_OPSIZE(Size);
 
     /* Pop the new flags */
-    if (!Fast486StackPop(State, &NewFlags))
+    if (!Fast486StackPop(State, &NewFlags.Long))
     {
         /* Exception occurred */
         return FALSE;
     }
 
-    if (!State->Flags.Vm)
+    if (State->Flags.Vm && (State->Flags.Iopl != 3))
     {
-        /* Check the current privilege level */
-        if (Cpl == 0)
-        {
-            /* Supervisor */
-
-            /* Set the flags */
-            if (Size)
-            {
-                /* Memorize the old state of RF */
-                BOOLEAN OldRf = State->Flags.Rf;
-
-                State->Flags.Long = NewFlags;
-
-                /* Restore VM and RF */
-                State->Flags.Vm = FALSE;
-                State->Flags.Rf = OldRf;
-
-                /* Clear VIF and VIP */
-                State->Flags.Vif = State->Flags.Vip = FALSE;
-            }
-            else State->Flags.LowWord = LOWORD(NewFlags);
-
-            /* Restore the reserved bits */
-            State->Flags.AlwaysSet = TRUE;
-            State->Flags.Reserved0 = FALSE;
-            State->Flags.Reserved1 = FALSE;
-        }
-        else
-        {
-            /* User */
-
-            /* Memorize the old state of IF and IOPL */
-            BOOLEAN OldIf = State->Flags.If;
-            UINT OldIopl = State->Flags.Iopl;
-
-            /* Set the flags */
-            if (Size)
-            {
-                /* Memorize the old state of RF */
-                BOOLEAN OldRf = State->Flags.Rf;
-
-                State->Flags.Long = NewFlags;
-
-                /* Restore VM and RF */
-                State->Flags.Vm = FALSE;
-                State->Flags.Rf = OldRf;
-
-                /* Clear VIF and VIP */
-                State->Flags.Vif = State->Flags.Vip = FALSE;
-            }
-            else State->Flags.LowWord = LOWORD(NewFlags);
-
-            /* Restore the reserved bits and IOPL */
-            State->Flags.AlwaysSet = TRUE;
-            State->Flags.Reserved0 = FALSE;
-            State->Flags.Reserved1 = FALSE;
-            State->Flags.Iopl = OldIopl;
-
-            /* Check if the user doesn't have the privilege to change IF */
-            if (Cpl > State->Flags.Iopl)
-            {
-                /* Restore IF */
-                State->Flags.If = OldIf;
-            }
-        }
+        /* Call the VM86 monitor */
+        Fast486ExceptionWithErrorCode(State, FAST486_EXCEPTION_GP, 0);
+        return TRUE;
     }
-    else
-    {
-        /* Check the IOPL */
-        if (State->Flags.Iopl == 3)
-        {
-            if (Size)
-            {
-                /* Memorize the old state of RF, VIF and VIP */
-                BOOLEAN OldRf = State->Flags.Rf;
-                BOOLEAN OldVif = State->Flags.Vif;
-                BOOLEAN OldVip = State->Flags.Vip;
-
-                State->Flags.Long = NewFlags;
-
-                /* Restore VM, RF, VIF and VIP */
-                State->Flags.Vm = TRUE;
-                State->Flags.Rf = OldRf;
-                State->Flags.Vif = OldVif;
-                State->Flags.Vip = OldVip;
-            }
-            else State->Flags.LowWord = LOWORD(NewFlags);
 
-            /* Restore the reserved bits and IOPL */
-            State->Flags.AlwaysSet = TRUE;
-            State->Flags.Reserved0 = FALSE;
-            State->Flags.Reserved1 = FALSE;
-            State->Flags.Iopl = 3;
-        }
-        else
-        {
-            /* Call the VM86 monitor */
-            Fast486ExceptionWithErrorCode(State, FAST486_EXCEPTION_GP, 0);
-        }
+    State->Flags.Cf = NewFlags.Cf;
+    State->Flags.Pf = NewFlags.Pf;
+    State->Flags.Af = NewFlags.Af;
+    State->Flags.Zf = NewFlags.Zf;
+    State->Flags.Sf = NewFlags.Sf;
+    State->Flags.Tf = NewFlags.Tf;
+    State->Flags.Df = NewFlags.Df;
+    State->Flags.Of = NewFlags.Of;
+    State->Flags.Nt = NewFlags.Nt;
 
-    }
+    if (Cpl == 0) State->Flags.Iopl = NewFlags.Iopl;
+    if (Cpl <= State->Flags.Iopl) State->Flags.If = NewFlags.If;
 
     return TRUE;
 }
index 8e85702..183ceba 100644 (file)
@@ -1226,7 +1226,7 @@ VOID WINAPI BiosMiscService(LPWORD Stack)
         /* Copy Extended Memory */
         case 0x87:
         {
-            WORD Count = getCX() * 2 - 1;
+            DWORD Count = (DWORD)getCX() * 2;
             PFAST486_GDT_ENTRY Gdt = (PFAST486_GDT_ENTRY)SEG_OFF_TO_PTR(getES(), getSI());
             DWORD SourceBase = Gdt[2].Base + (Gdt[2].BaseMid << 16) + (Gdt[2].BaseHigh << 24);
             DWORD SourceLimit = Gdt[2].Limit + (Gdt[2].LimitHigh << 16);