case 1:
{
Result = FirstValue | SecondValue;
+ State->Flags.Cf = State->Flags.Of = FALSE;
break;
}
case 4:
{
Result = FirstValue & SecondValue;
+ State->Flags.Cf = State->Flags.Of = FALSE;
break;
}
case 6:
{
Result = FirstValue ^ SecondValue;
+ State->Flags.Cf = State->Flags.Of = FALSE;
break;
}
case 2:
{
Result = (Value << Count) | (State->Flags.Cf << (Count - 1));
-
+
/* Complete the calculation, but make sure we don't shift by too much */
if ((Bits - Count) < 31) Result |= Value >> (Bits - Count + 1);
/* DIV */
case 6:
{
- UCHAR Quotient, Remainder;
+ USHORT Quotient;
+ UCHAR Remainder;
if (Value == 0)
{
Quotient = State->GeneralRegs[FAST486_REG_EAX].LowWord / Value;
Remainder = State->GeneralRegs[FAST486_REG_EAX].LowWord % Value;
+ if (Quotient > 0xFF)
+ {
+ /* Divide error */
+ Fast486Exception(State, FAST486_EXCEPTION_DE);
+ return;
+ }
+
/* Write back the results */
- State->GeneralRegs[FAST486_REG_EAX].LowByte = Quotient;
+ State->GeneralRegs[FAST486_REG_EAX].LowByte = (UCHAR)Quotient;
State->GeneralRegs[FAST486_REG_EAX].HighByte = Remainder;
break;
/* IDIV */
case 7:
{
- CHAR Quotient, Remainder;
+ SHORT Quotient;
+ CHAR Remainder;
if (Value == 0)
{
Quotient = (SHORT)State->GeneralRegs[FAST486_REG_EAX].LowWord / (CHAR)Value;
Remainder = (SHORT)State->GeneralRegs[FAST486_REG_EAX].LowWord % (CHAR)Value;
+ if (Quotient > 127 || Quotient < -128)
+ {
+ /* Divide error */
+ Fast486Exception(State, FAST486_EXCEPTION_DE);
+ return;
+ }
+
/* Write back the results */
- State->GeneralRegs[FAST486_REG_EAX].LowByte = (UCHAR)Quotient;
+ State->GeneralRegs[FAST486_REG_EAX].LowByte = (UCHAR)((CHAR)Quotient);
State->GeneralRegs[FAST486_REG_EAX].HighByte = (UCHAR)Remainder;
break;
case 3:
{
/* Calculate the result */
- ULONG Result = -Value;
+ ULONG Result = -(LONG)Value;
if (!OperandSize) Result &= 0xFFFF;
/* Update the flags */
{
ULONGLONG Dividend = (ULONGLONG)State->GeneralRegs[FAST486_REG_EAX].Long
| ((ULONGLONG)State->GeneralRegs[FAST486_REG_EDX].Long << 32);
- ULONG Quotient = Dividend / Value;
+ ULONGLONG Quotient = Dividend / Value;
ULONG Remainder = Dividend % Value;
+ if (Quotient > 0xFFFFFFFFULL)
+ {
+ /* Divide error */
+ Fast486Exception(State, FAST486_EXCEPTION_DE);
+ return;
+ }
+
/* Write back the results */
- State->GeneralRegs[FAST486_REG_EAX].Long = Quotient;
+ State->GeneralRegs[FAST486_REG_EAX].Long = (ULONG)Quotient;
State->GeneralRegs[FAST486_REG_EDX].Long = Remainder;
}
else
{
ULONG Dividend = (ULONG)State->GeneralRegs[FAST486_REG_EAX].LowWord
| ((ULONG)State->GeneralRegs[FAST486_REG_EDX].LowWord << 16);
- USHORT Quotient = Dividend / Value;
+ ULONG Quotient = Dividend / Value;
USHORT Remainder = Dividend % Value;
+ if (Quotient > 0xFFFF)
+ {
+ /* Divide error */
+ Fast486Exception(State, FAST486_EXCEPTION_DE);
+ return;
+ }
+
/* Write back the results */
- State->GeneralRegs[FAST486_REG_EAX].LowWord = Quotient;
+ State->GeneralRegs[FAST486_REG_EAX].LowWord = (USHORT)Quotient;
State->GeneralRegs[FAST486_REG_EDX].LowWord = Remainder;
}
{
LONGLONG Dividend = (LONGLONG)State->GeneralRegs[FAST486_REG_EAX].Long
| ((LONGLONG)State->GeneralRegs[FAST486_REG_EDX].Long << 32);
- LONG Quotient = Dividend / (LONG)Value;
+ LONGLONG Quotient = Dividend / (LONG)Value;
LONG Remainder = Dividend % (LONG)Value;
+ if (Quotient > 2147483647LL || Quotient < -2147483648LL)
+ {
+ /* Divide error */
+ Fast486Exception(State, FAST486_EXCEPTION_DE);
+ return;
+ }
+
/* Write back the results */
- State->GeneralRegs[FAST486_REG_EAX].Long = (ULONG)Quotient;
+ State->GeneralRegs[FAST486_REG_EAX].Long = (ULONG)((LONG)Quotient);
State->GeneralRegs[FAST486_REG_EDX].Long = (ULONG)Remainder;
}
else
{
LONG Dividend = (LONG)State->GeneralRegs[FAST486_REG_EAX].LowWord
| ((LONG)State->GeneralRegs[FAST486_REG_EDX].LowWord << 16);
- SHORT Quotient = Dividend / (SHORT)LOWORD(Value);
+ LONG Quotient = Dividend / (SHORT)LOWORD(Value);
SHORT Remainder = Dividend % (SHORT)LOWORD(Value);
+ if (Quotient > 32767 || Quotient < -32768)
+ {
+ /* Divide error */
+ Fast486Exception(State, FAST486_EXCEPTION_DE);
+ return;
+ }
+
/* Write back the results */
- State->GeneralRegs[FAST486_REG_EAX].LowWord = (USHORT)Quotient;
+ State->GeneralRegs[FAST486_REG_EAX].LowWord = (USHORT)((SHORT)Quotient);
State->GeneralRegs[FAST486_REG_EDX].LowWord = (USHORT)Remainder;
}
return;
}
- if (Fast486ReadDescriptorEntry(State,
- Selector,
- &Valid,
- (PFAST486_GDT_ENTRY)&GdtEntry))
+ if (!Fast486ReadDescriptorEntry(State,
+ Selector,
+ &Valid,
+ (PFAST486_GDT_ENTRY)&GdtEntry))
{
/* Exception occurred */
return;
State->Ldtr.Selector = Selector;
State->Ldtr.Base = GdtEntry.Base | (GdtEntry.BaseMid << 16) | (GdtEntry.BaseHigh << 24);
State->Ldtr.Limit = GdtEntry.Limit | (GdtEntry.LimitHigh << 16);
- if (GdtEntry.Granularity) State->Ldtr.Limit <<= 12;
+
+ if (GdtEntry.Granularity)
+ {
+ State->Ldtr.Limit <<= 12;
+ State->Ldtr.Limit |= 0x00000FFF;
+ }
break;
}
return;
}
- if (Fast486ReadDescriptorEntry(State,
- Selector,
- &Valid,
- (PFAST486_GDT_ENTRY)&GdtEntry))
+ if (!Fast486ReadDescriptorEntry(State,
+ Selector,
+ &Valid,
+ (PFAST486_GDT_ENTRY)&GdtEntry))
{
/* Exception occurred */
return;
State->TaskReg.Selector = Selector;
State->TaskReg.Base = GdtEntry.Base | (GdtEntry.BaseMid << 16) | (GdtEntry.BaseHigh << 24);
State->TaskReg.Limit = GdtEntry.Limit | (GdtEntry.LimitHigh << 16);
- if (GdtEntry.Granularity) State->TaskReg.Limit <<= 12;
+
+ if (GdtEntry.Granularity)
+ {
+ State->TaskReg.Limit <<= 12;
+ State->TaskReg.Limit |= 0x00000FFF;
+ }
break;
}