SOFT386_OPCODE_HANDLER(Soft386OpcodeGroupF6)
{
- UCHAR Dummy, Value;
+ UCHAR Dummy, Value = 0;
SOFT386_MOD_REG_RM ModRegRm;
BOOLEAN AddressSize = State->SegmentRegs[SOFT386_REG_CS].Size;
/* IMUL */
case 5:
{
- SHORT Result = (SHORT)Value * (SHORT)State->GeneralRegs[SOFT386_REG_EAX].LowByte;
+ SHORT Result = (SHORT)((CHAR)Value) * (SHORT)((CHAR)State->GeneralRegs[SOFT386_REG_EAX].LowByte);
/* Update the flags */
State->Flags.Cf = State->Flags.Of =
SOFT386_OPCODE_HANDLER(Soft386OpcodeGroupF7)
{
- ULONG Dummy, Value, SignFlag;
+ ULONG Dummy, Value = 0, SignFlag;
SOFT386_MOD_REG_RM ModRegRm;
BOOLEAN OperandSize, AddressSize;
{
if (OperandSize)
{
- LONGLONG Result = (LONGLONG)Value * (LONGLONG)State->GeneralRegs[SOFT386_REG_EAX].Long;
+ LONGLONG Result = (LONGLONG)((LONG)Value) * (LONGLONG)((LONG)State->GeneralRegs[SOFT386_REG_EAX].Long);
/* Update the flags */
State->Flags.Cf = State->Flags.Of =
}
else
{
- LONG Result = (LONG)Value * (LONG)State->GeneralRegs[SOFT386_REG_EAX].LowWord;
+ LONG Result = (LONG)((SHORT)Value) * (LONG)((SHORT)State->GeneralRegs[SOFT386_REG_EAX].LowWord);
/* Update the flags */
State->Flags.Cf = State->Flags.Of =
{
LONG Dividend = (LONG)State->GeneralRegs[SOFT386_REG_EAX].LowWord
| ((LONG)State->GeneralRegs[SOFT386_REG_EDX].LowWord << 16);
- SHORT Quotient = Dividend / (SHORT)Value;
- SHORT Remainder = Dividend % (SHORT)Value;
+ SHORT Quotient = Dividend / (SHORT)LOWORD(Value);
+ SHORT Remainder = Dividend % (SHORT)LOWORD(Value);
/* Write back the results */
State->GeneralRegs[SOFT386_REG_EAX].LowWord = (USHORT)Quotient;
if (ModRegRm.Register == 0)
{
- /* Increment and update OF */
+ /* Increment and update OF and AF */
Value++;
State->Flags.Of = (Value == SIGN_FLAG_BYTE) ? TRUE : FALSE;
+ State->Flags.Af = ((Value & 0x0F) == 0);
}
else
{
- /* Decrement and update OF */
+ /* Decrement and update OF and AF */
State->Flags.Of = (Value == SIGN_FLAG_BYTE) ? TRUE : FALSE;
Value--;
+ State->Flags.Af = ((Value & 0x0F) == 0x0F);
}
/* Update flags */
State->Flags.Sf = (Value & SIGN_FLAG_BYTE) ? TRUE : FALSE;
State->Flags.Zf = (Value == 0) ? TRUE : FALSE;
- State->Flags.Af = ((Value & 0x0F) == 0) ? TRUE : FALSE;
State->Flags.Pf = Soft386CalculateParity(Value);
/* Write back the result */
if (ModRegRm.Register == 0)
{
- /* Increment and update OF */
+ /* Increment and update OF and AF */
Value++;
State->Flags.Of = (Value == SIGN_FLAG_LONG) ? TRUE : FALSE;
+ State->Flags.Af = ((Value & 0x0F) == 0);
}
else if (ModRegRm.Register == 1)
{
- /* Decrement and update OF */
+ /* Decrement and update OF and AF */
State->Flags.Of = (Value == SIGN_FLAG_LONG) ? TRUE : FALSE;
Value--;
+ State->Flags.Af = ((Value & 0x0F) == 0x0F);
+ }
+ else if (ModRegRm.Register == 2)
+ {
+ /* Push the current value of EIP */
+ if (!Soft386StackPush(State, State->InstPtr.Long))
+ {
+ /* Exception occurred */
+ return FALSE;
+ }
+
+ /* Set the EIP to the address */
+ State->InstPtr.Long = Value;
+ }
+ else if (ModRegRm.Register == 3)
+ {
+ USHORT Selector;
+ INT Segment = SOFT386_REG_DS;
+
+ /* Check for the segment override */
+ if (State->PrefixFlags & SOFT386_PREFIX_SEG)
+ {
+ /* Use the override segment instead */
+ Segment = State->SegmentOverride;
+ }
+
+ /* Read the selector */
+ if (!Soft386ReadMemory(State,
+ Segment,
+ ModRegRm.MemoryAddress + sizeof(ULONG),
+ FALSE,
+ &Selector,
+ sizeof(USHORT)))
+ {
+ /* Exception occurred */
+ return FALSE;
+ }
+
+ /* Push the current value of CS */
+ if (!Soft386StackPush(State, State->SegmentRegs[SOFT386_REG_CS].Selector))
+ {
+ /* Exception occurred */
+ return FALSE;
+ }
+
+ /* Push the current value of EIP */
+ if (!Soft386StackPush(State, State->InstPtr.Long))
+ {
+ /* Exception occurred */
+ return FALSE;
+ }
+
+ /* Load the new code segment */
+ if (!Soft386LoadSegment(State, SOFT386_REG_CS, Selector))
+ {
+ /* Exception occurred */
+ return FALSE;
+ }
+
+ /* Set the EIP to the address */
+ State->InstPtr.Long = Value;
+ }
+ else if (ModRegRm.Register == 4)
+ {
+ /* Set the EIP to the address */
+ State->InstPtr.Long = Value;
+ }
+ else if (ModRegRm.Register == 5)
+ {
+ USHORT Selector;
+ INT Segment = SOFT386_REG_DS;
+
+ /* Check for the segment override */
+ if (State->PrefixFlags & SOFT386_PREFIX_SEG)
+ {
+ /* Use the override segment instead */
+ Segment = State->SegmentOverride;
+ }
+
+ /* Read the selector */
+ if (!Soft386ReadMemory(State,
+ Segment,
+ ModRegRm.MemoryAddress + sizeof(ULONG),
+ FALSE,
+ &Selector,
+ sizeof(USHORT)))
+ {
+ /* Exception occurred */
+ return FALSE;
+ }
+
+ /* Load the new code segment */
+ if (!Soft386LoadSegment(State, SOFT386_REG_CS, Selector))
+ {
+ /* Exception occurred */
+ return FALSE;
+ }
+
+ /* Set the EIP to the address */
+ State->InstPtr.Long = Value;
+ }
+ else if (ModRegRm.Register == 6)
+ {
+ /* Push the value on to the stack */
+ return Soft386StackPush(State, Value);
}
if (ModRegRm.Register <= 1)
/* Update flags */
State->Flags.Sf = (Value & SIGN_FLAG_LONG) ? TRUE : FALSE;
State->Flags.Zf = (Value == 0) ? TRUE : FALSE;
- State->Flags.Af = ((Value & 0x0F) == 0) ? TRUE : FALSE;
State->Flags.Pf = Soft386CalculateParity(Value);
/* Write back the result */
/* Increment and update OF */
Value++;
State->Flags.Of = (Value == SIGN_FLAG_WORD) ? TRUE : FALSE;
+ State->Flags.Af = ((Value & 0x0F) == 0);
}
else if (ModRegRm.Register == 1)
{
/* Decrement and update OF */
State->Flags.Of = (Value == SIGN_FLAG_WORD) ? TRUE : FALSE;
Value--;
+ State->Flags.Af = ((Value & 0x0F) == 0x0F);
+ }
+ else if (ModRegRm.Register == 2)
+ {
+ /* Push the current value of IP */
+ if (!Soft386StackPush(State, State->InstPtr.LowWord))
+ {
+ /* Exception occurred */
+ return FALSE;
+ }
+
+ /* Set the IP to the address */
+ State->InstPtr.LowWord = Value;
+ }
+ else if (ModRegRm.Register == 3)
+ {
+ USHORT Selector;
+ INT Segment = SOFT386_REG_DS;
+
+ /* Check for the segment override */
+ if (State->PrefixFlags & SOFT386_PREFIX_SEG)
+ {
+ /* Use the override segment instead */
+ Segment = State->SegmentOverride;
+ }
+
+ /* Read the selector */
+ if (!Soft386ReadMemory(State,
+ Segment,
+ ModRegRm.MemoryAddress + sizeof(USHORT),
+ FALSE,
+ &Selector,
+ sizeof(USHORT)))
+ {
+ /* Exception occurred */
+ return FALSE;
+ }
+
+ /* Push the current value of CS */
+ if (!Soft386StackPush(State, State->SegmentRegs[SOFT386_REG_CS].Selector))
+ {
+ /* Exception occurred */
+ return FALSE;
+ }
+
+ /* Push the current value of IP */
+ if (!Soft386StackPush(State, State->InstPtr.LowWord))
+ {
+ /* Exception occurred */
+ return FALSE;
+ }
+
+ /* Load the new code segment */
+ if (!Soft386LoadSegment(State, SOFT386_REG_CS, Selector))
+ {
+ /* Exception occurred */
+ return FALSE;
+ }
+
+ /* Set the IP to the address */
+ State->InstPtr.LowWord = Value;
+
+ }
+ else if (ModRegRm.Register == 4)
+ {
+ /* Set the IP to the address */
+ State->InstPtr.LowWord = Value;
+ }
+ else if (ModRegRm.Register == 5)
+ {
+ USHORT Selector;
+ INT Segment = SOFT386_REG_DS;
+
+ /* Check for the segment override */
+ if (State->PrefixFlags & SOFT386_PREFIX_SEG)
+ {
+ /* Use the override segment instead */
+ Segment = State->SegmentOverride;
+ }
+
+ /* Read the selector */
+ if (!Soft386ReadMemory(State,
+ Segment,
+ ModRegRm.MemoryAddress + sizeof(USHORT),
+ FALSE,
+ &Selector,
+ sizeof(USHORT)))
+ {
+ /* Exception occurred */
+ return FALSE;
+ }
+
+ /* Load the new code segment */
+ if (!Soft386LoadSegment(State, SOFT386_REG_CS, Selector))
+ {
+ /* Exception occurred */
+ return FALSE;
+ }
+
+ /* Set the IP to the address */
+ State->InstPtr.LowWord = Value;
+ }
+ else if (ModRegRm.Register == 6)
+ {
+ /* Push the value on to the stack */
+ return Soft386StackPush(State, Value);
+ }
+ else
+ {
+ /* Invalid */
+ Soft386Exception(State, SOFT386_EXCEPTION_UD);
+ return FALSE;
}
if (ModRegRm.Register <= 1)
/* Update flags */
State->Flags.Sf = (Value & SIGN_FLAG_WORD) ? TRUE : FALSE;
State->Flags.Zf = (Value == 0) ? TRUE : FALSE;
- State->Flags.Af = ((Value & 0x0F) == 0) ? TRUE : FALSE;
State->Flags.Pf = Soft386CalculateParity(Value);
/* Write back the result */
}
}
- if (ModRegRm.Register > 1)
- {
- UNIMPLEMENTED;
- return FALSE; // NOT IMPLEMENTED
- }
-
return TRUE;
}