if (Jump)
{
- /* Move the instruction pointer */
+ /* Move the instruction pointer */
State->InstPtr.Long += Offset;
}
/* Read the value from AL */
Data = State->GeneralRegs[FAST486_REG_EAX].LowByte;
-
+
/* Write the byte to the I/O port */
State->IoWriteCallback(State, Port, &Data, 1, sizeof(UCHAR));
ULONG Data = State->GeneralRegs[FAST486_REG_EAX].Long;
/* Write a dword to the I/O port */
- State->IoReadCallback(State, Port, &Data, 1, sizeof(ULONG));
+ State->IoWriteCallback(State, Port, &Data, 1, sizeof(ULONG));
}
else
{
return FALSE;
}
- /* Move the instruction pointer */
+ /* Move the instruction pointer */
State->InstPtr.Long += Offset;
return TRUE;
/* Exception occurred */
return FALSE;
}
-
+
/* Calculate the result */
Result = FirstValue + SecondValue;
/* Exception occurred */
return FALSE;
}
-
+
/* Calculate the result */
Result = FirstValue + SecondValue;
/* Exception occurred */
return FALSE;
}
-
+
/* Calculate the result */
Result = FirstValue | SecondValue;
/* Exception occurred */
return FALSE;
}
-
+
/* Calculate the result */
Result = FirstValue | SecondValue;
/* Exception occurred */
return FALSE;
}
-
+
/* Calculate the result */
Result = FirstValue & SecondValue;
/* Exception occurred */
return FALSE;
}
-
+
/* Calculate the result */
Result = FirstValue & SecondValue;
/* Exception occurred */
return FALSE;
}
-
+
/* Calculate the result */
Result = FirstValue ^ SecondValue;
/* Exception occurred */
return FALSE;
}
-
+
/* Calculate the result */
Result = FirstValue ^ SecondValue;
/* Exception occurred */
return FALSE;
}
-
+
/* Calculate the result */
Result = FirstValue & SecondValue;
/* Exception occurred */
return FALSE;
}
-
+
/* Calculate the result */
Result = FirstValue & SecondValue;
/* Exception occurred */
return FALSE;
}
-
+
/* Write the value from the register to the R/M */
if (!Fast486WriteModrmWordOperands(State,
&ModRegRm,
/* Exception occurred */
return FALSE;
}
-
+
/* Calculate the result */
Result = FirstValue + SecondValue + State->Flags.Cf;
/* Exception occurred */
return FALSE;
}
-
+
/* Calculate the result */
Result = FirstValue + SecondValue + State->Flags.Cf;
/* Swap the order */
SWAP(FirstValue, SecondValue);
}
-
+
/* Calculate the result */
Result = FirstValue - SecondValue - Carry;
/* Exception occurred */
return FALSE;
}
-
+
/* Check if this is the instruction that writes to R/M */
if (!(Opcode & FAST486_OPCODE_WRITE_REG))
{
/* Swap the order */
SWAP(FirstValue, SecondValue);
}
-
+
/* Calculate the result */
Result = FirstValue - SecondValue - Carry;
/* Swap the order */
SWAP(FirstValue, SecondValue);
}
-
+
/* Calculate the result */
Result = FirstValue - SecondValue;
/* Exception occurred */
return FALSE;
}
-
+
/* Check if this is the instruction that writes to R/M */
if (!(Opcode & FAST486_OPCODE_WRITE_REG))
{
/* Swap the order */
SWAP(FirstValue, SecondValue);
}
-
+
/* Calculate the result */
Result = FirstValue - SecondValue;
BOOLEAN OperandSize, AddressSize;
FAST486_MOD_REG_RM ModRegRm;
LONG Multiplier;
- LONGLONG Product;
/* Make sure this is the right instruction */
ASSERT((Opcode & 0xFD) == 0x69);
if (OperandSize)
{
LONG RegValue, Multiplicand;
+ LONGLONG Product;
/* Read the operands */
if (!Fast486ReadModrmDwordOperands(State,
/* Multiply */
Product = (LONGLONG)Multiplicand * (LONGLONG)Multiplier;
+
+ /* Check for carry/overflow */
+ State->Flags.Cf = State->Flags.Of = ((Product < MINLONG) || (Product > MAXLONG));
+
+ /* Write-back the result */
+ return Fast486WriteModrmDwordOperands(State,
+ &ModRegRm,
+ TRUE,
+ (ULONG)((LONG)Product));
}
else
{
SHORT RegValue, Multiplicand;
+ LONG Product;
/* Read the operands */
if (!Fast486ReadModrmWordOperands(State,
}
/* Multiply */
- Product = (LONGLONG)Multiplicand * (LONGLONG)Multiplier;
- }
+ Product = (LONG)Multiplicand * (LONG)Multiplier;
- /* Check for carry/overflow */
- State->Flags.Cf = State->Flags.Of = ((Product < MINLONG) || (Product > MAXLONG));
+ /* Check for carry/overflow */
+ State->Flags.Cf = State->Flags.Of = ((Product < MINSHORT) || (Product > MAXSHORT));
- /* Write-back the result */
- return Fast486WriteModrmDwordOperands(State,
- &ModRegRm,
- TRUE,
- (ULONG)((LONG)Product));
+ /* Write-back the result */
+ return Fast486WriteModrmWordOperands(State,
+ &ModRegRm,
+ TRUE,
+ (USHORT)((SHORT)Product));
+ }
}
FAST486_OPCODE_HANDLER(Fast486OpcodePushByteImm)
if (Opcode & FAST486_OPCODE_WRITE_REG) Result = SecondValue;
else Result = FirstValue;
-
+
/* Write back the result */
return Fast486WriteModrmDwordOperands(State,
&ModRegRm,
/* Exception occurred */
return FALSE;
}
-
+
if (Opcode & FAST486_OPCODE_WRITE_REG) Result = SecondValue;
else Result = FirstValue;
/* Call the VM86 monitor */
Fast486ExceptionWithErrorCode(State, FAST486_EXCEPTION_GP, 0);
}
-
+
}
return TRUE;
OperandSize = AddressSize = State->SegmentRegs[FAST486_REG_CS].Size;
+ TOGGLE_OPSIZE(OperandSize);
TOGGLE_ADSIZE(AddressSize);
/* Get the operands */
ASSERT((Opcode >= 0xE0) && (Opcode <= 0xE2));
NO_LOCK_PREFIX();
- TOGGLE_OPSIZE(Size);
+ TOGGLE_ADSIZE(Size);
if (Size) Condition = ((--State->GeneralRegs[FAST486_REG_ECX].Long) != 0);
else Condition = ((--State->GeneralRegs[FAST486_REG_ECX].LowWord) != 0);
if (Condition)
{
/* Move the instruction pointer */
- State->InstPtr.Long += Offset;
+ if (Size) State->InstPtr.Long += Offset;
+ else State->InstPtr.LowWord += Offset;
}
return TRUE;
ASSERT(Opcode == 0xE3);
NO_LOCK_PREFIX();
- TOGGLE_OPSIZE(Size);
+ TOGGLE_ADSIZE(Size);
if (Size) Condition = (State->GeneralRegs[FAST486_REG_ECX].Long == 0);
else Condition = (State->GeneralRegs[FAST486_REG_ECX].LowWord == 0);
if (Condition)
{
- /* Move the instruction pointer */
- State->InstPtr.Long += Offset;
+ /* Move the instruction pointer */
+ if (Size) State->InstPtr.Long += Offset;
+ else State->InstPtr.LowWord += Offset;
}
return TRUE;
return FALSE;
}
- /* Move the instruction pointer */
+ /* Move the instruction pointer */
State->InstPtr.Long += Offset;
}
else
return FALSE;
}
- /* Move the instruction pointer */
+ /* Move the instruction pointer */
State->InstPtr.LowWord += Offset;
}
return FALSE;
}
- /* Move the instruction pointer */
+ /* Move the instruction pointer */
State->InstPtr.Long += Offset;
}
else
return FALSE;
}
- /* Move the instruction pointer */
+ /* Move the instruction pointer */
State->InstPtr.LowWord += Offset;
}
FAST486_OPCODE_HANDLER(Fast486OpcodeMovAlOffset)
{
- BOOLEAN Size = State->SegmentRegs[FAST486_REG_CS].Size;
+ BOOLEAN AddressSize = State->SegmentRegs[FAST486_REG_CS].Size;
ULONG Offset;
/* Make sure this is the right instruction */
ASSERT(Opcode == 0xA0);
- TOGGLE_OPSIZE(Size);
+ TOGGLE_ADSIZE(AddressSize);
- if (Size)
+ if (AddressSize)
{
if (!Fast486FetchDword(State, &Offset))
{
FAST486_OPCODE_HANDLER(Fast486OpcodeMovEaxOffset)
{
- BOOLEAN Size = State->SegmentRegs[FAST486_REG_CS].Size;
+ BOOLEAN OperandSize, AddressSize;
+
+ OperandSize = AddressSize = State->SegmentRegs[FAST486_REG_CS].Size;
/* Make sure this is the right instruction */
ASSERT(Opcode == 0xA1);
- TOGGLE_OPSIZE(Size);
+ TOGGLE_OPSIZE(OperandSize);
+ TOGGLE_ADSIZE(AddressSize);
- if (Size)
+ if (AddressSize)
{
ULONG Offset;
}
/* Read from memory */
- return Fast486ReadMemory(State,
- (State->PrefixFlags & FAST486_PREFIX_SEG) ?
- State->SegmentOverride : FAST486_REG_DS,
- Offset,
- FALSE,
- &State->GeneralRegs[FAST486_REG_EAX].Long,
- sizeof(ULONG));
+ if (OperandSize)
+ {
+ return Fast486ReadMemory(State,
+ (State->PrefixFlags & FAST486_PREFIX_SEG) ?
+ State->SegmentOverride : FAST486_REG_DS,
+ Offset,
+ FALSE,
+ &State->GeneralRegs[FAST486_REG_EAX].Long,
+ sizeof(ULONG));
+ }
+ else
+ {
+ return Fast486ReadMemory(State,
+ (State->PrefixFlags & FAST486_PREFIX_SEG) ?
+ State->SegmentOverride : FAST486_REG_DS,
+ Offset,
+ FALSE,
+ &State->GeneralRegs[FAST486_REG_EAX].LowWord,
+ sizeof(USHORT));
+ }
}
else
{
}
/* Read from memory */
- return Fast486ReadMemory(State,
- (State->PrefixFlags & FAST486_PREFIX_SEG) ?
- State->SegmentOverride : FAST486_REG_DS,
- Offset,
- FALSE,
- &State->GeneralRegs[FAST486_REG_EAX].LowWord,
- sizeof(USHORT));
+ if (OperandSize)
+ {
+ return Fast486ReadMemory(State,
+ (State->PrefixFlags & FAST486_PREFIX_SEG) ?
+ State->SegmentOverride : FAST486_REG_DS,
+ Offset,
+ FALSE,
+ &State->GeneralRegs[FAST486_REG_EAX].Long,
+ sizeof(ULONG));
+ }
+ else
+ {
+ return Fast486ReadMemory(State,
+ (State->PrefixFlags & FAST486_PREFIX_SEG) ?
+ State->SegmentOverride : FAST486_REG_DS,
+ Offset,
+ FALSE,
+ &State->GeneralRegs[FAST486_REG_EAX].LowWord,
+ sizeof(USHORT));
+ }
}
}
FAST486_OPCODE_HANDLER(Fast486OpcodeMovOffsetAl)
{
- BOOLEAN Size = State->SegmentRegs[FAST486_REG_CS].Size;
+ BOOLEAN AddressSize = State->SegmentRegs[FAST486_REG_CS].Size;
ULONG Offset;
/* Make sure this is the right instruction */
ASSERT(Opcode == 0xA2);
- TOGGLE_OPSIZE(Size);
+ TOGGLE_ADSIZE(AddressSize);
- if (Size)
+ if (AddressSize)
{
if (!Fast486FetchDword(State, &Offset))
{
FAST486_OPCODE_HANDLER(Fast486OpcodeMovOffsetEax)
{
- BOOLEAN Size = State->SegmentRegs[FAST486_REG_CS].Size;
+ BOOLEAN OperandSize, AddressSize;
+
+ OperandSize = AddressSize = State->SegmentRegs[FAST486_REG_CS].Size;
/* Make sure this is the right instruction */
ASSERT(Opcode == 0xA3);
- TOGGLE_OPSIZE(Size);
+ TOGGLE_OPSIZE(OperandSize);
+ TOGGLE_ADSIZE(AddressSize);
- if (Size)
+ if (AddressSize)
{
ULONG Offset;
}
/* Write to memory */
- return Fast486WriteMemory(State,
- (State->PrefixFlags & FAST486_PREFIX_SEG) ?
- State->SegmentOverride : FAST486_REG_DS,
- Offset,
- &State->GeneralRegs[FAST486_REG_EAX].Long,
- sizeof(ULONG));
+ if (OperandSize)
+ {
+ return Fast486WriteMemory(State,
+ (State->PrefixFlags & FAST486_PREFIX_SEG) ?
+ State->SegmentOverride : FAST486_REG_DS,
+ Offset,
+ &State->GeneralRegs[FAST486_REG_EAX].Long,
+ sizeof(ULONG));
+ }
+ else
+ {
+ return Fast486WriteMemory(State,
+ (State->PrefixFlags & FAST486_PREFIX_SEG) ?
+ State->SegmentOverride : FAST486_REG_DS,
+ Offset,
+ &State->GeneralRegs[FAST486_REG_EAX].LowWord,
+ sizeof(USHORT));
+ }
}
else
{
}
/* Write to memory */
- return Fast486WriteMemory(State,
- (State->PrefixFlags & FAST486_PREFIX_SEG) ?
- State->SegmentOverride : FAST486_REG_DS,
- Offset,
- &State->GeneralRegs[FAST486_REG_EAX].LowWord,
- sizeof(USHORT));
+ if (OperandSize)
+ {
+ return Fast486WriteMemory(State,
+ (State->PrefixFlags & FAST486_PREFIX_SEG) ?
+ State->SegmentOverride : FAST486_REG_DS,
+ Offset,
+ &State->GeneralRegs[FAST486_REG_EAX].Long,
+ sizeof(ULONG));
+ }
+ else
+ {
+ return Fast486WriteMemory(State,
+ (State->PrefixFlags & FAST486_PREFIX_SEG) ?
+ State->SegmentOverride : FAST486_REG_DS,
+ Offset,
+ &State->GeneralRegs[FAST486_REG_EAX].LowWord,
+ sizeof(USHORT));
+ }
}
}
|| (State->PrefixFlags & FAST486_PREFIX_REPNZ))
{
BOOLEAN Repeat = TRUE;
-
+
if (OperandSize)
{
if ((--State->GeneralRegs[FAST486_REG_ECX].Long) == 0)
if (AddressSize) State->GeneralRegs[FAST486_REG_ESI].Long -= (Count - 1) * DataSize;
else State->GeneralRegs[FAST486_REG_ESI].LowWord -= (Count - 1) * DataSize;
}
+
+ /* Update registers */
+ if (OperandSize)
+ {
+ State->GeneralRegs[FAST486_REG_ECX].Long = 0;
+ State->GeneralRegs[FAST486_REG_ESI].Long += Count - 1;
+ }
+ else
+ {
+ State->GeneralRegs[FAST486_REG_ECX].LowWord = 0;
+ State->GeneralRegs[FAST486_REG_ESI].LowWord += Count - 1;
+ }
}
/* Read from the source operand */
|| (State->PrefixFlags & FAST486_PREFIX_REPNZ))
{
BOOLEAN Repeat = TRUE;
-
+
if (OperandSize)
{
if ((--State->GeneralRegs[FAST486_REG_ECX].Long) == 0)