}
/* 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;
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)
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;
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;
State->Flags.AlwaysSet = TRUE;
State->Flags.Reserved0 = State->Flags.Reserved1 = FALSE;
- return FALSE;
+ return TRUE;
}
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)