[FAST486]
[reactos.git] / lib / fast486 / opcodes.c
index ecba01a..3dffdaa 100644 (file)
@@ -883,7 +883,7 @@ FAST486_OPCODE_HANDLER(Fast486OpcodeHalt)
     }
 
     /* Halt */
-    while (State->IntStatus != FAST486_INT_SIGNAL) State->IdleCallback(State);
+    // TODO: Halt the CPU until an interrupt occurs, using IdleCallback if needed.
 
     /* Return success */
     return TRUE;
@@ -3524,10 +3524,102 @@ FAST486_OPCODE_HANDLER(Fast486OpcodePopAll)
 
 FAST486_OPCODE_HANDLER(Fast486OpcodeBound)
 {
-    // TODO: NOT IMPLEMENTED
-    UNIMPLEMENTED;
+    BOOLEAN OperandSize, AddressSize;
+    FAST486_MOD_REG_RM ModRegRm;
+    FAST486_SEG_REGS Segment = FAST486_REG_DS;
 
-    return FALSE;
+    OperandSize = AddressSize = State->SegmentRegs[FAST486_REG_CS].Size;
+
+    NO_LOCK_PREFIX();
+    TOGGLE_OPSIZE(OperandSize);
+    TOGGLE_ADSIZE(AddressSize);
+
+    if (!Fast486ParseModRegRm(State, AddressSize, &ModRegRm))
+    {
+        /* Exception occurred */
+        return FALSE;
+    }
+
+    if (!ModRegRm.Memory)
+    {
+        /* Invalid */
+        Fast486Exception(State, FAST486_EXCEPTION_UD);
+        return FALSE;
+    }
+
+    /* Check for the segment override */
+    if (State->PrefixFlags & FAST486_PREFIX_SEG)
+    {
+        /* Use the override segment instead */
+        Segment = State->SegmentOverride;
+    }
+
+    if (OperandSize)
+    {
+        LONG Index, LowerBound, UpperBound;
+
+        /* Read the operands */
+        if (!Fast486ReadModrmDwordOperands(State,
+                                           &ModRegRm,
+                                           (PULONG)&Index,
+                                           (PULONG)&LowerBound))
+        {
+            /* Exception occurred */
+            return FALSE;
+        }
+
+        if (!Fast486ReadMemory(State,
+                               Segment,
+                               ModRegRm.MemoryAddress + sizeof(ULONG),
+                               FALSE,
+                               &UpperBound,
+                               sizeof(ULONG)))
+        {
+            /* Exception occurred */
+            return FALSE;
+        }
+
+        if ((Index < LowerBound) || (Index > UpperBound))
+        {
+            /* Out of bounds */
+            Fast486Exception(State, FAST486_EXCEPTION_BR);
+            return FALSE;
+        }
+    }
+    else
+    {
+        SHORT Index, LowerBound, UpperBound;
+
+        /* Read the operands */
+        if (!Fast486ReadModrmWordOperands(State,
+                                          &ModRegRm,
+                                          (PUSHORT)&Index,
+                                          (PUSHORT)&LowerBound))
+        {
+            /* Exception occurred */
+            return FALSE;
+        }
+
+        if (!Fast486ReadMemory(State,
+                               Segment,
+                               ModRegRm.MemoryAddress + sizeof(USHORT),
+                               FALSE,
+                               &UpperBound,
+                               sizeof(USHORT)))
+        {
+            /* Exception occurred */
+            return FALSE;
+        }
+
+        if ((Index < LowerBound) || (Index > UpperBound))
+        {
+            /* Out of bounds */
+            Fast486Exception(State, FAST486_EXCEPTION_BR);
+            return FALSE;
+        }
+    }
+
+    return TRUE;
 }
 
 FAST486_OPCODE_HANDLER(Fast486OpcodeArpl)
@@ -4176,11 +4268,12 @@ FAST486_OPCODE_HANDLER(Fast486OpcodePopFlags)
         return FALSE;
     }
 
+    /* Check for VM86 mode when IOPL is not 3 */
     if (State->Flags.Vm && (State->Flags.Iopl != 3))
     {
         /* Call the VM86 monitor */
         Fast486ExceptionWithErrorCode(State, FAST486_EXCEPTION_GP, 0);
-        return TRUE;
+        return FALSE;
     }
 
     State->Flags.Cf = NewFlags.Cf;
@@ -4192,6 +4285,7 @@ FAST486_OPCODE_HANDLER(Fast486OpcodePopFlags)
     State->Flags.Df = NewFlags.Df;
     State->Flags.Of = NewFlags.Of;
     State->Flags.Nt = NewFlags.Nt;
+    State->Flags.Ac = NewFlags.Ac;
 
     if (Cpl == 0) State->Flags.Iopl = NewFlags.Iopl;
     if (Cpl <= State->Flags.Iopl) State->Flags.If = NewFlags.If;
@@ -4212,7 +4306,7 @@ FAST486_OPCODE_HANDLER(Fast486OpcodeSahf)
     State->Flags.AlwaysSet = TRUE;
     State->Flags.Reserved0 = State->Flags.Reserved1 = FALSE;
 
-    return FALSE;
+    return TRUE;
 }
 
 FAST486_OPCODE_HANDLER(Fast486OpcodeLahf)
@@ -4223,7 +4317,7 @@ FAST486_OPCODE_HANDLER(Fast486OpcodeLahf)
     /* Set AH to the low-order byte of FLAGS */
     State->GeneralRegs[FAST486_REG_EAX].HighByte = LOBYTE(State->Flags.Long);
 
-    return FALSE;
+    return TRUE;
 }
 
 FAST486_OPCODE_HANDLER(Fast486OpcodeRet)