[FAST486]
[reactos.git] / lib / fast486 / opcodes.c
index db9c90d..3dffdaa 100644 (file)
 
 /* INCLUDES *******************************************************************/
 
-// #define WIN32_NO_STATUS
-// #define _INC_WINDOWS
 #include <windef.h>
-#include <limits.h>
 
 // #define NDEBUG
 #include <debug.h>
@@ -34,6 +31,7 @@
 #include "opgroups.h"
 #include "extraops.h"
 #include "common.h"
+#include "fpu.h"
 
 /* PUBLIC VARIABLES ***********************************************************/
 
@@ -256,14 +254,14 @@ Fast486OpcodeHandlers[FAST486_NUM_OPCODE_HANDLERS] =
     Fast486OpcodeAad,
     Fast486OpcodeSalc,
     Fast486OpcodeXlat,
-    NULL, // TODO: OPCODE 0xD8 NOT SUPPORTED
-    NULL, // TODO: OPCODE 0xD9 NOT SUPPORTED
-    NULL, // TODO: OPCODE 0xDA NOT SUPPORTED
-    NULL, // TODO: OPCODE 0xDB NOT SUPPORTED
-    NULL, // TODO: OPCODE 0xDC NOT SUPPORTED
-    NULL, // TODO: OPCODE 0xDD NOT SUPPORTED
-    NULL, // TODO: OPCODE 0xDE NOT SUPPORTED
-    NULL, // TODO: OPCODE 0xDF NOT SUPPORTED
+    Fast486FpuOpcodeD8,
+    Fast486FpuOpcodeD9,
+    Fast486FpuOpcodeDA,
+    Fast486FpuOpcodeDB,
+    Fast486FpuOpcodeDC,
+    Fast486FpuOpcodeDD,
+    Fast486FpuOpcodeDE,
+    Fast486FpuOpcodeDF,
     Fast486OpcodeLoop,
     Fast486OpcodeLoop,
     Fast486OpcodeLoop,
@@ -476,19 +474,19 @@ FAST486_OPCODE_HANDLER(Fast486OpcodeIncrement)
     {
         Value = ++State->GeneralRegs[Opcode & 0x07].Long;
 
-        State->Flags.Of = (Value == SIGN_FLAG_LONG) ? TRUE : FALSE;
-        State->Flags.Sf = (Value & SIGN_FLAG_LONG) ? TRUE : FALSE;
+        State->Flags.Of = (Value == SIGN_FLAG_LONG);
+        State->Flags.Sf = ((Value & SIGN_FLAG_LONG) != 0);
     }
     else
     {
         Value = ++State->GeneralRegs[Opcode & 0x07].LowWord;
 
-        State->Flags.Of = (Value == SIGN_FLAG_WORD) ? TRUE : FALSE;
-        State->Flags.Sf = (Value & SIGN_FLAG_WORD) ? TRUE : FALSE;
+        State->Flags.Of = (Value == SIGN_FLAG_WORD);
+        State->Flags.Sf = ((Value & SIGN_FLAG_WORD) != 0);
     }
 
-    State->Flags.Zf = (Value == 0) ? TRUE : FALSE;
-    State->Flags.Af = ((Value & 0x0F) == 0) ? TRUE : FALSE;
+    State->Flags.Zf = (Value == 0);
+    State->Flags.Af = ((Value & 0x0F) == 0);
     State->Flags.Pf = Fast486CalculateParity(LOBYTE(Value));
 
     /* Return success */
@@ -510,19 +508,19 @@ FAST486_OPCODE_HANDLER(Fast486OpcodeDecrement)
     {
         Value = --State->GeneralRegs[Opcode & 0x07].Long;
 
-        State->Flags.Of = (Value == (SIGN_FLAG_LONG - 1)) ? TRUE : FALSE;
-        State->Flags.Sf = (Value & SIGN_FLAG_LONG) ? TRUE : FALSE;
+        State->Flags.Of = (Value == (SIGN_FLAG_LONG - 1));
+        State->Flags.Sf = ((Value & SIGN_FLAG_LONG) != 0);
     }
     else
     {
         Value = --State->GeneralRegs[Opcode & 0x07].LowWord;
 
-        State->Flags.Of = (Value == (SIGN_FLAG_WORD - 1)) ? TRUE : FALSE;
-        State->Flags.Sf = (Value & SIGN_FLAG_WORD) ? TRUE : FALSE;
+        State->Flags.Of = (Value == (SIGN_FLAG_WORD - 1));
+        State->Flags.Sf = ((Value & SIGN_FLAG_WORD) != 0);
     }
 
-    State->Flags.Zf = (Value == 0) ? TRUE : FALSE;
-    State->Flags.Af = ((Value & 0x0F) == 0x0F) ? TRUE : FALSE;
+    State->Flags.Zf = (Value == 0);
+    State->Flags.Af = ((Value & 0x0F) == 0x0F);
     State->Flags.Pf = Fast486CalculateParity(LOBYTE(Value));
 
     /* Return success */
@@ -543,7 +541,7 @@ FAST486_OPCODE_HANDLER(Fast486OpcodePushReg)
 FAST486_OPCODE_HANDLER(Fast486OpcodePopReg)
 {
     ULONG Value;
-    BOOLEAN Size = State->SegmentRegs[FAST486_REG_SS].Size;
+    BOOLEAN Size = State->SegmentRegs[FAST486_REG_CS].Size;
 
     TOGGLE_OPSIZE(Size);
     NO_LOCK_PREFIX();
@@ -609,10 +607,13 @@ FAST486_OPCODE_HANDLER(Fast486OpcodeShortConditionalJmp)
 {
     BOOLEAN Jump = FALSE;
     CHAR Offset = 0;
+    BOOLEAN Size = State->SegmentRegs[FAST486_REG_CS].Size;
 
     /* Make sure this is the right instruction */
     ASSERT((Opcode & 0xF0) == 0x70);
 
+    TOGGLE_OPSIZE(Size);
+
     /* Fetch the offset */
     if (!Fast486FetchByte(State, (PUCHAR)&Offset))
     {
@@ -687,8 +688,14 @@ FAST486_OPCODE_HANDLER(Fast486OpcodeShortConditionalJmp)
 
     if (Jump)
     {
-        /* Move the instruction pointer */        
+        /* Move the instruction pointer */
         State->InstPtr.Long += Offset;
+
+        if (!Size)
+        {
+            /* Clear the top half of EIP */
+            State->InstPtr.Long &= 0xFFFF;
+        }
     }
 
     /* Return success */
@@ -876,7 +883,7 @@ FAST486_OPCODE_HANDLER(Fast486OpcodeHalt)
     }
 
     /* Halt */
-    while (!State->HardwareInt) State->IdleCallback(State);
+    // TODO: Halt the CPU until an interrupt occurs, using IdleCallback if needed.
 
     /* Return success */
     return TRUE;
@@ -909,7 +916,7 @@ FAST486_OPCODE_HANDLER(Fast486OpcodeInByte)
     }
 
     /* Read a byte from the I/O port */
-    State->IoReadCallback(State, Port, &Data, sizeof(UCHAR));
+    State->IoReadCallback(State, Port, &Data, 1, sizeof(UCHAR));
 
     /* Store the result in AL */
     State->GeneralRegs[FAST486_REG_EAX].LowByte = Data;
@@ -953,7 +960,7 @@ FAST486_OPCODE_HANDLER(Fast486OpcodeIn)
         ULONG Data;
 
         /* Read a dword from the I/O port */
-        State->IoReadCallback(State, Port, &Data, sizeof(ULONG));
+        State->IoReadCallback(State, Port, &Data, 1, sizeof(ULONG));
 
         /* Store the value in EAX */
         State->GeneralRegs[FAST486_REG_EAX].Long = Data;
@@ -963,7 +970,7 @@ FAST486_OPCODE_HANDLER(Fast486OpcodeIn)
         USHORT Data;
 
         /* Read a word from the I/O port */
-        State->IoReadCallback(State, Port, &Data, sizeof(USHORT));
+        State->IoReadCallback(State, Port, &Data, 1, sizeof(USHORT));
 
         /* Store the value in AX */
         State->GeneralRegs[FAST486_REG_EAX].LowWord = Data;
@@ -1000,9 +1007,9 @@ FAST486_OPCODE_HANDLER(Fast486OpcodeOutByte)
 
     /* 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, sizeof(UCHAR));
+    State->IoWriteCallback(State, Port, &Data, 1, sizeof(UCHAR));
 
     return TRUE;
 }
@@ -1044,7 +1051,7 @@ FAST486_OPCODE_HANDLER(Fast486OpcodeOut)
         ULONG Data = State->GeneralRegs[FAST486_REG_EAX].Long;
 
         /* Write a dword to the I/O port */
-        State->IoReadCallback(State, Port, &Data, sizeof(ULONG));
+        State->IoWriteCallback(State, Port, &Data, 1, sizeof(ULONG));
     }
     else
     {
@@ -1052,7 +1059,7 @@ FAST486_OPCODE_HANDLER(Fast486OpcodeOut)
         USHORT Data = State->GeneralRegs[FAST486_REG_EAX].LowWord;
 
         /* Write a word to the I/O port */
-        State->IoWriteCallback(State, Port, &Data, sizeof(USHORT));
+        State->IoWriteCallback(State, Port, &Data, 1, sizeof(USHORT));
     }
 
     return TRUE;
@@ -1061,6 +1068,9 @@ FAST486_OPCODE_HANDLER(Fast486OpcodeOut)
 FAST486_OPCODE_HANDLER(Fast486OpcodeShortJump)
 {
     CHAR Offset = 0;
+    BOOLEAN Size = State->SegmentRegs[FAST486_REG_CS].Size;
+
+    TOGGLE_OPSIZE(Size);
 
     /* Make sure this is the right instruction */
     ASSERT(Opcode == 0xEB);
@@ -1072,9 +1082,15 @@ FAST486_OPCODE_HANDLER(Fast486OpcodeShortJump)
         return FALSE;
     }
 
-    /* Move the instruction pointer */        
+    /* Move the instruction pointer */
     State->InstPtr.Long += Offset;
 
+    if (!Size)
+    {
+        /* Clear the top half of EIP */
+        State->InstPtr.Long &= 0xFFFF;
+    }
+
     return TRUE;
 }
 
@@ -1189,9 +1205,9 @@ FAST486_OPCODE_HANDLER(Fast486OpcodeAddByteModrm)
     State->Flags.Cf = (Result < FirstValue) && (Result < SecondValue);
     State->Flags.Of = ((FirstValue & SIGN_FLAG_BYTE) == (SecondValue & SIGN_FLAG_BYTE))
                       && ((FirstValue & SIGN_FLAG_BYTE) != (Result & SIGN_FLAG_BYTE));
-    State->Flags.Af = (((FirstValue & 0x0F) + (SecondValue & 0x0F)) & 0x10) ? TRUE : FALSE;
-    State->Flags.Zf = (Result == 0) ? TRUE : FALSE;
-    State->Flags.Sf = (Result & SIGN_FLAG_BYTE) ? TRUE : FALSE;
+    State->Flags.Af = ((((FirstValue & 0x0F) + (SecondValue & 0x0F)) & 0x10) != 0);
+    State->Flags.Zf = (Result == 0);
+    State->Flags.Sf = ((Result & SIGN_FLAG_BYTE) != 0);
     State->Flags.Pf = Fast486CalculateParity(Result);
 
     /* Write back the result */
@@ -1234,7 +1250,7 @@ FAST486_OPCODE_HANDLER(Fast486OpcodeAddModrm)
             /* Exception occurred */
             return FALSE;
         }
-    
+
         /* Calculate the result */
         Result = FirstValue + SecondValue;
 
@@ -1242,9 +1258,9 @@ FAST486_OPCODE_HANDLER(Fast486OpcodeAddModrm)
         State->Flags.Cf = (Result < FirstValue) && (Result < SecondValue);
         State->Flags.Of = ((FirstValue & SIGN_FLAG_LONG) == (SecondValue & SIGN_FLAG_LONG))
                           && ((FirstValue & SIGN_FLAG_LONG) != (Result & SIGN_FLAG_LONG));
-        State->Flags.Af = (((FirstValue & 0x0F) + (SecondValue & 0x0F)) & 0x10) ? TRUE : FALSE;
-        State->Flags.Zf = (Result == 0) ? TRUE : FALSE;
-        State->Flags.Sf = (Result & SIGN_FLAG_LONG) ? TRUE : FALSE;
+        State->Flags.Af = ((((FirstValue & 0x0F) + (SecondValue & 0x0F)) & 0x10) != 0);
+        State->Flags.Zf = (Result == 0);
+        State->Flags.Sf = ((Result & SIGN_FLAG_LONG) != 0);
         State->Flags.Pf = Fast486CalculateParity(Result);
 
         /* Write back the result */
@@ -1265,7 +1281,7 @@ FAST486_OPCODE_HANDLER(Fast486OpcodeAddModrm)
             /* Exception occurred */
             return FALSE;
         }
-    
+
         /* Calculate the result */
         Result = FirstValue + SecondValue;
 
@@ -1273,9 +1289,9 @@ FAST486_OPCODE_HANDLER(Fast486OpcodeAddModrm)
         State->Flags.Cf = (Result < FirstValue) && (Result < SecondValue);
         State->Flags.Of = ((FirstValue & SIGN_FLAG_WORD) == (SecondValue & SIGN_FLAG_WORD))
                           && ((FirstValue & SIGN_FLAG_WORD) != (Result & SIGN_FLAG_WORD));
-        State->Flags.Af = (((FirstValue & 0x0F) + (SecondValue & 0x0F)) & 0x10) ? TRUE : FALSE;
-        State->Flags.Zf = (Result == 0) ? TRUE : FALSE;
-        State->Flags.Sf = (Result & SIGN_FLAG_WORD) ? TRUE : FALSE;
+        State->Flags.Af = ((((FirstValue & 0x0F) + (SecondValue & 0x0F)) & 0x10) != 0);
+        State->Flags.Zf = (Result == 0);
+        State->Flags.Sf = ((Result & SIGN_FLAG_WORD) != 0);
         State->Flags.Pf = Fast486CalculateParity(Result);
 
         /* Write back the result */
@@ -1314,9 +1330,9 @@ FAST486_OPCODE_HANDLER(Fast486OpcodeAddAl)
     State->Flags.Cf = (Result < FirstValue) && (Result < SecondValue);
     State->Flags.Of = ((FirstValue & SIGN_FLAG_BYTE) == (SecondValue & SIGN_FLAG_BYTE))
                       && ((FirstValue & SIGN_FLAG_BYTE) != (Result & SIGN_FLAG_BYTE));
-    State->Flags.Af = (((FirstValue & 0x0F) + (SecondValue & 0x0F)) & 0x10) ? TRUE : FALSE;
-    State->Flags.Zf = (Result == 0) ? TRUE : FALSE;
-    State->Flags.Sf = (Result & SIGN_FLAG_BYTE) ? TRUE : FALSE;
+    State->Flags.Af = ((((FirstValue & 0x0F) + (SecondValue & 0x0F)) & 0x10) != 0);
+    State->Flags.Zf = (Result == 0);
+    State->Flags.Sf = ((Result & SIGN_FLAG_BYTE) != 0);
     State->Flags.Pf = Fast486CalculateParity(Result);
 
     /* Write back the result */
@@ -1353,9 +1369,9 @@ FAST486_OPCODE_HANDLER(Fast486OpcodeAddEax)
         State->Flags.Cf = (Result < FirstValue) && (Result < SecondValue);
         State->Flags.Of = ((FirstValue & SIGN_FLAG_LONG) == (SecondValue & SIGN_FLAG_LONG))
                           && ((FirstValue & SIGN_FLAG_LONG) != (Result & SIGN_FLAG_LONG));
-        State->Flags.Af = (((FirstValue & 0x0F) + (SecondValue & 0x0F)) & 0x10) ? TRUE : FALSE;
-        State->Flags.Zf = (Result == 0) ? TRUE : FALSE;
-        State->Flags.Sf = (Result & SIGN_FLAG_LONG) ? TRUE : FALSE;
+        State->Flags.Af = ((((FirstValue & 0x0F) + (SecondValue & 0x0F)) & 0x10) != 0);
+        State->Flags.Zf = (Result == 0);
+        State->Flags.Sf = ((Result & SIGN_FLAG_LONG) != 0);
         State->Flags.Pf = Fast486CalculateParity(Result);
 
         /* Write back the result */
@@ -1379,9 +1395,9 @@ FAST486_OPCODE_HANDLER(Fast486OpcodeAddEax)
         State->Flags.Cf = (Result < FirstValue) && (Result < SecondValue);
         State->Flags.Of = ((FirstValue & SIGN_FLAG_WORD) == (SecondValue & SIGN_FLAG_WORD))
                           && ((FirstValue & SIGN_FLAG_WORD) != (Result & SIGN_FLAG_WORD));
-        State->Flags.Af = (((FirstValue & 0x0F) + (SecondValue & 0x0F)) & 0x10) ? TRUE : FALSE;
-        State->Flags.Zf = (Result == 0) ? TRUE : FALSE;
-        State->Flags.Sf = (Result & SIGN_FLAG_WORD) ? TRUE : FALSE;
+        State->Flags.Af = ((((FirstValue & 0x0F) + (SecondValue & 0x0F)) & 0x10) != 0);
+        State->Flags.Zf = (Result == 0);
+        State->Flags.Sf = ((Result & SIGN_FLAG_WORD) != 0);
         State->Flags.Pf = Fast486CalculateParity(Result);
 
         /* Write back the result */
@@ -1424,8 +1440,8 @@ FAST486_OPCODE_HANDLER(Fast486OpcodeOrByteModrm)
     /* Update the flags */
     State->Flags.Cf = FALSE;
     State->Flags.Of = FALSE;
-    State->Flags.Zf = (Result == 0) ? TRUE : FALSE;
-    State->Flags.Sf = (Result & SIGN_FLAG_BYTE) ? TRUE : FALSE;
+    State->Flags.Zf = (Result == 0);
+    State->Flags.Sf = ((Result & SIGN_FLAG_BYTE) != 0);
     State->Flags.Pf = Fast486CalculateParity(Result);
 
     /* Write back the result */
@@ -1468,15 +1484,15 @@ FAST486_OPCODE_HANDLER(Fast486OpcodeOrModrm)
             /* Exception occurred */
             return FALSE;
         }
-    
+
         /* Calculate the result */
         Result = FirstValue | SecondValue;
 
         /* Update the flags */
         State->Flags.Cf = FALSE;
         State->Flags.Of = FALSE;
-        State->Flags.Zf = (Result == 0) ? TRUE : FALSE;
-        State->Flags.Sf = (Result & SIGN_FLAG_LONG) ? TRUE : FALSE;
+        State->Flags.Zf = (Result == 0);
+        State->Flags.Sf = ((Result & SIGN_FLAG_LONG) != 0);
         State->Flags.Pf = Fast486CalculateParity(Result);
 
         /* Write back the result */
@@ -1497,15 +1513,15 @@ FAST486_OPCODE_HANDLER(Fast486OpcodeOrModrm)
             /* Exception occurred */
             return FALSE;
         }
-    
+
         /* Calculate the result */
         Result = FirstValue | SecondValue;
 
         /* Update the flags */
         State->Flags.Cf = FALSE;
         State->Flags.Of = FALSE;
-        State->Flags.Zf = (Result == 0) ? TRUE : FALSE;
-        State->Flags.Sf = (Result & SIGN_FLAG_WORD) ? TRUE : FALSE;
+        State->Flags.Zf = (Result == 0);
+        State->Flags.Sf = ((Result & SIGN_FLAG_WORD) != 0);
         State->Flags.Pf = Fast486CalculateParity(Result);
 
         /* Write back the result */
@@ -1543,8 +1559,8 @@ FAST486_OPCODE_HANDLER(Fast486OpcodeOrAl)
     /* Update the flags */
     State->Flags.Cf = FALSE;
     State->Flags.Of = FALSE;
-    State->Flags.Zf = (Result == 0) ? TRUE : FALSE;
-    State->Flags.Sf = (Result & SIGN_FLAG_BYTE) ? TRUE : FALSE;
+    State->Flags.Zf = (Result == 0);
+    State->Flags.Sf = ((Result & SIGN_FLAG_BYTE) != 0);
     State->Flags.Pf = Fast486CalculateParity(Result);
 
     /* Write back the result */
@@ -1580,8 +1596,8 @@ FAST486_OPCODE_HANDLER(Fast486OpcodeOrEax)
         /* Update the flags */
         State->Flags.Cf = FALSE;
         State->Flags.Of = FALSE;
-        State->Flags.Zf = (Result == 0) ? TRUE : FALSE;
-        State->Flags.Sf = (Result & SIGN_FLAG_LONG) ? TRUE : FALSE;
+        State->Flags.Zf = (Result == 0);
+        State->Flags.Sf = ((Result & SIGN_FLAG_LONG) != 0);
         State->Flags.Pf = Fast486CalculateParity(Result);
 
         /* Write back the result */
@@ -1604,8 +1620,8 @@ FAST486_OPCODE_HANDLER(Fast486OpcodeOrEax)
         /* Update the flags */
         State->Flags.Cf = FALSE;
         State->Flags.Of = FALSE;
-        State->Flags.Zf = (Result == 0) ? TRUE : FALSE;
-        State->Flags.Sf = (Result & SIGN_FLAG_WORD) ? TRUE : FALSE;
+        State->Flags.Zf = (Result == 0);
+        State->Flags.Sf = ((Result & SIGN_FLAG_WORD) != 0);
         State->Flags.Pf = Fast486CalculateParity(Result);
 
         /* Write back the result */
@@ -1648,8 +1664,8 @@ FAST486_OPCODE_HANDLER(Fast486OpcodeAndByteModrm)
     /* Update the flags */
     State->Flags.Cf = FALSE;
     State->Flags.Of = FALSE;
-    State->Flags.Zf = (Result == 0) ? TRUE : FALSE;
-    State->Flags.Sf = (Result & SIGN_FLAG_BYTE) ? TRUE : FALSE;
+    State->Flags.Zf = (Result == 0);
+    State->Flags.Sf = ((Result & SIGN_FLAG_BYTE) != 0);
     State->Flags.Pf = Fast486CalculateParity(Result);
 
     /* Write back the result */
@@ -1692,15 +1708,15 @@ FAST486_OPCODE_HANDLER(Fast486OpcodeAndModrm)
             /* Exception occurred */
             return FALSE;
         }
-    
+
         /* Calculate the result */
         Result = FirstValue & SecondValue;
 
         /* Update the flags */
         State->Flags.Cf = FALSE;
         State->Flags.Of = FALSE;
-        State->Flags.Zf = (Result == 0) ? TRUE : FALSE;
-        State->Flags.Sf = (Result & SIGN_FLAG_LONG) ? TRUE : FALSE;
+        State->Flags.Zf = (Result == 0);
+        State->Flags.Sf = ((Result & SIGN_FLAG_LONG) != 0);
         State->Flags.Pf = Fast486CalculateParity(Result);
 
         /* Write back the result */
@@ -1721,15 +1737,15 @@ FAST486_OPCODE_HANDLER(Fast486OpcodeAndModrm)
             /* Exception occurred */
             return FALSE;
         }
-    
+
         /* Calculate the result */
         Result = FirstValue & SecondValue;
 
         /* Update the flags */
         State->Flags.Cf = FALSE;
         State->Flags.Of = FALSE;
-        State->Flags.Zf = (Result == 0) ? TRUE : FALSE;
-        State->Flags.Sf = (Result & SIGN_FLAG_WORD) ? TRUE : FALSE;
+        State->Flags.Zf = (Result == 0);
+        State->Flags.Sf = ((Result & SIGN_FLAG_WORD) != 0);
         State->Flags.Pf = Fast486CalculateParity(Result);
 
         /* Write back the result */
@@ -1762,8 +1778,8 @@ FAST486_OPCODE_HANDLER(Fast486OpcodeAndAl)
     /* Update the flags */
     State->Flags.Cf = FALSE;
     State->Flags.Of = FALSE;
-    State->Flags.Zf = (Result == 0) ? TRUE : FALSE;
-    State->Flags.Sf = (Result & SIGN_FLAG_BYTE) ? TRUE : FALSE;
+    State->Flags.Zf = (Result == 0);
+    State->Flags.Sf = ((Result & SIGN_FLAG_BYTE) != 0);
     State->Flags.Pf = Fast486CalculateParity(Result);
 
     /* Write back the result */
@@ -1799,8 +1815,8 @@ FAST486_OPCODE_HANDLER(Fast486OpcodeAndEax)
         /* Update the flags */
         State->Flags.Cf = FALSE;
         State->Flags.Of = FALSE;
-        State->Flags.Zf = (Result == 0) ? TRUE : FALSE;
-        State->Flags.Sf = (Result & SIGN_FLAG_LONG) ? TRUE : FALSE;
+        State->Flags.Zf = (Result == 0);
+        State->Flags.Sf = ((Result & SIGN_FLAG_LONG) != 0);
         State->Flags.Pf = Fast486CalculateParity(Result);
 
         /* Write back the result */
@@ -1823,8 +1839,8 @@ FAST486_OPCODE_HANDLER(Fast486OpcodeAndEax)
         /* Update the flags */
         State->Flags.Cf = FALSE;
         State->Flags.Of = FALSE;
-        State->Flags.Zf = (Result == 0) ? TRUE : FALSE;
-        State->Flags.Sf = (Result & SIGN_FLAG_WORD) ? TRUE : FALSE;
+        State->Flags.Zf = (Result == 0);
+        State->Flags.Sf = ((Result & SIGN_FLAG_WORD) != 0);
         State->Flags.Pf = Fast486CalculateParity(Result);
 
         /* Write back the result */
@@ -1867,8 +1883,8 @@ FAST486_OPCODE_HANDLER(Fast486OpcodeXorByteModrm)
     /* Update the flags */
     State->Flags.Cf = FALSE;
     State->Flags.Of = FALSE;
-    State->Flags.Zf = (Result == 0) ? TRUE : FALSE;
-    State->Flags.Sf = (Result & SIGN_FLAG_BYTE) ? TRUE : FALSE;
+    State->Flags.Zf = (Result == 0);
+    State->Flags.Sf = ((Result & SIGN_FLAG_BYTE) != 0);
     State->Flags.Pf = Fast486CalculateParity(Result);
 
     /* Write back the result */
@@ -1911,15 +1927,15 @@ FAST486_OPCODE_HANDLER(Fast486OpcodeXorModrm)
             /* Exception occurred */
             return FALSE;
         }
-    
+
         /* Calculate the result */
         Result = FirstValue ^ SecondValue;
 
         /* Update the flags */
         State->Flags.Cf = FALSE;
         State->Flags.Of = FALSE;
-        State->Flags.Zf = (Result == 0) ? TRUE : FALSE;
-        State->Flags.Sf = (Result & SIGN_FLAG_LONG) ? TRUE : FALSE;
+        State->Flags.Zf = (Result == 0);
+        State->Flags.Sf = ((Result & SIGN_FLAG_LONG) != 0);
         State->Flags.Pf = Fast486CalculateParity(Result);
 
         /* Write back the result */
@@ -1940,15 +1956,15 @@ FAST486_OPCODE_HANDLER(Fast486OpcodeXorModrm)
             /* Exception occurred */
             return FALSE;
         }
-    
+
         /* Calculate the result */
         Result = FirstValue ^ SecondValue;
 
         /* Update the flags */
         State->Flags.Cf = FALSE;
         State->Flags.Of = FALSE;
-        State->Flags.Zf = (Result == 0) ? TRUE : FALSE;
-        State->Flags.Sf = (Result & SIGN_FLAG_WORD) ? TRUE : FALSE;
+        State->Flags.Zf = (Result == 0);
+        State->Flags.Sf = ((Result & SIGN_FLAG_WORD) != 0);
         State->Flags.Pf = Fast486CalculateParity(Result);
 
         /* Write back the result */
@@ -1986,8 +2002,8 @@ FAST486_OPCODE_HANDLER(Fast486OpcodeXorAl)
     /* Update the flags */
     State->Flags.Cf = FALSE;
     State->Flags.Of = FALSE;
-    State->Flags.Zf = (Result == 0) ? TRUE : FALSE;
-    State->Flags.Sf = (Result & SIGN_FLAG_BYTE) ? TRUE : FALSE;
+    State->Flags.Zf = (Result == 0);
+    State->Flags.Sf = ((Result & SIGN_FLAG_BYTE) != 0);
     State->Flags.Pf = Fast486CalculateParity(Result);
 
     /* Write back the result */
@@ -2023,8 +2039,8 @@ FAST486_OPCODE_HANDLER(Fast486OpcodeXorEax)
         /* Update the flags */
         State->Flags.Cf = FALSE;
         State->Flags.Of = FALSE;
-        State->Flags.Zf = (Result == 0) ? TRUE : FALSE;
-        State->Flags.Sf = (Result & SIGN_FLAG_LONG) ? TRUE : FALSE;
+        State->Flags.Zf = (Result == 0);
+        State->Flags.Sf = ((Result & SIGN_FLAG_LONG) != 0);
         State->Flags.Pf = Fast486CalculateParity(Result);
 
         /* Write back the result */
@@ -2047,8 +2063,8 @@ FAST486_OPCODE_HANDLER(Fast486OpcodeXorEax)
         /* Update the flags */
         State->Flags.Cf = FALSE;
         State->Flags.Of = FALSE;
-        State->Flags.Zf = (Result == 0) ? TRUE : FALSE;
-        State->Flags.Sf = (Result & SIGN_FLAG_WORD) ? TRUE : FALSE;
+        State->Flags.Zf = (Result == 0);
+        State->Flags.Sf = ((Result & SIGN_FLAG_WORD) != 0);
         State->Flags.Pf = Fast486CalculateParity(Result);
 
         /* Write back the result */
@@ -2090,8 +2106,8 @@ FAST486_OPCODE_HANDLER(Fast486OpcodeTestByteModrm)
     /* Update the flags */
     State->Flags.Cf = FALSE;
     State->Flags.Of = FALSE;
-    State->Flags.Zf = (Result == 0) ? TRUE : FALSE;
-    State->Flags.Sf = (Result & SIGN_FLAG_BYTE) ? TRUE : FALSE;
+    State->Flags.Zf = (Result == 0);
+    State->Flags.Sf = ((Result & SIGN_FLAG_BYTE) != 0);
     State->Flags.Pf = Fast486CalculateParity(Result);
 
     /* The result is discarded */
@@ -2131,15 +2147,15 @@ FAST486_OPCODE_HANDLER(Fast486OpcodeTestModrm)
             /* Exception occurred */
             return FALSE;
         }
-    
+
         /* Calculate the result */
         Result = FirstValue & SecondValue;
 
         /* Update the flags */
         State->Flags.Cf = FALSE;
         State->Flags.Of = FALSE;
-        State->Flags.Zf = (Result == 0) ? TRUE : FALSE;
-        State->Flags.Sf = (Result & SIGN_FLAG_LONG) ? TRUE : FALSE;
+        State->Flags.Zf = (Result == 0);
+        State->Flags.Sf = ((Result & SIGN_FLAG_LONG) != 0);
         State->Flags.Pf = Fast486CalculateParity(Result);
     }
     else
@@ -2154,15 +2170,15 @@ FAST486_OPCODE_HANDLER(Fast486OpcodeTestModrm)
             /* Exception occurred */
             return FALSE;
         }
-    
+
         /* Calculate the result */
         Result = FirstValue & SecondValue;
 
         /* Update the flags */
         State->Flags.Cf = FALSE;
         State->Flags.Of = FALSE;
-        State->Flags.Zf = (Result == 0) ? TRUE : FALSE;
-        State->Flags.Sf = (Result & SIGN_FLAG_WORD) ? TRUE : FALSE;
+        State->Flags.Zf = (Result == 0);
+        State->Flags.Sf = ((Result & SIGN_FLAG_WORD) != 0);
         State->Flags.Pf = Fast486CalculateParity(Result);
     }
 
@@ -2197,8 +2213,8 @@ FAST486_OPCODE_HANDLER(Fast486OpcodeTestAl)
     /* Update the flags */
     State->Flags.Cf = FALSE;
     State->Flags.Of = FALSE;
-    State->Flags.Zf = (Result == 0) ? TRUE : FALSE;
-    State->Flags.Sf = (Result & SIGN_FLAG_BYTE) ? TRUE : FALSE;
+    State->Flags.Zf = (Result == 0);
+    State->Flags.Sf = ((Result & SIGN_FLAG_BYTE) != 0);
     State->Flags.Pf = Fast486CalculateParity(Result);
 
     /* The result is discarded */
@@ -2232,8 +2248,8 @@ FAST486_OPCODE_HANDLER(Fast486OpcodeTestEax)
         /* Update the flags */
         State->Flags.Cf = FALSE;
         State->Flags.Of = FALSE;
-        State->Flags.Zf = (Result == 0) ? TRUE : FALSE;
-        State->Flags.Sf = (Result & SIGN_FLAG_LONG) ? TRUE : FALSE;
+        State->Flags.Zf = (Result == 0);
+        State->Flags.Sf = ((Result & SIGN_FLAG_LONG) != 0);
         State->Flags.Pf = Fast486CalculateParity(Result);
     }
     else
@@ -2253,8 +2269,8 @@ FAST486_OPCODE_HANDLER(Fast486OpcodeTestEax)
         /* Update the flags */
         State->Flags.Cf = FALSE;
         State->Flags.Of = FALSE;
-        State->Flags.Zf = (Result == 0) ? TRUE : FALSE;
-        State->Flags.Sf = (Result & SIGN_FLAG_WORD) ? TRUE : FALSE;
+        State->Flags.Zf = (Result == 0);
+        State->Flags.Sf = ((Result & SIGN_FLAG_WORD) != 0);
         State->Flags.Pf = Fast486CalculateParity(Result);
     }
 
@@ -2378,7 +2394,7 @@ FAST486_OPCODE_HANDLER(Fast486OpcodeXchgModrm)
             /* Exception occurred */
             return FALSE;
         }
-    
+
         /* Write the value from the register to the R/M */
         if (!Fast486WriteModrmWordOperands(State,
                                            &ModRegRm,
@@ -2468,9 +2484,9 @@ FAST486_OPCODE_HANDLER(Fast486OpcodeAdcByteModrm)
     State->Flags.Cf = State->Flags.Cf || ((Result < FirstValue) && (Result < SecondValue));
     State->Flags.Of = ((FirstValue & SIGN_FLAG_BYTE) == (SecondValue & SIGN_FLAG_BYTE))
                       && ((FirstValue & SIGN_FLAG_BYTE) != (Result & SIGN_FLAG_BYTE));
-    State->Flags.Af = (((FirstValue & 0x0F) + (SecondValue & 0x0F)) & 0x10) ? TRUE : FALSE;
-    State->Flags.Zf = (Result == 0) ? TRUE : FALSE;
-    State->Flags.Sf = (Result & SIGN_FLAG_BYTE) ? TRUE : FALSE;
+    State->Flags.Af = ((FirstValue ^ SecondValue ^ Result) & 0x10) != 0;
+    State->Flags.Zf = (Result == 0);
+    State->Flags.Sf = ((Result & SIGN_FLAG_BYTE) != 0);
     State->Flags.Pf = Fast486CalculateParity(Result);
 
     /* Write back the result */
@@ -2513,7 +2529,7 @@ FAST486_OPCODE_HANDLER(Fast486OpcodeAdcModrm)
             /* Exception occurred */
             return FALSE;
         }
-    
+
         /* Calculate the result */
         Result = FirstValue + SecondValue + State->Flags.Cf;
 
@@ -2525,9 +2541,9 @@ FAST486_OPCODE_HANDLER(Fast486OpcodeAdcModrm)
         State->Flags.Cf = State->Flags.Cf || ((Result < FirstValue) && (Result < SecondValue));
         State->Flags.Of = ((FirstValue & SIGN_FLAG_LONG) == (SecondValue & SIGN_FLAG_LONG))
                           && ((FirstValue & SIGN_FLAG_LONG) != (Result & SIGN_FLAG_LONG));
-        State->Flags.Af = (((FirstValue & 0x0F) + (SecondValue & 0x0F)) & 0x10) ? TRUE : FALSE;
-        State->Flags.Zf = (Result == 0) ? TRUE : FALSE;
-        State->Flags.Sf = (Result & SIGN_FLAG_LONG) ? TRUE : FALSE;
+        State->Flags.Af = ((FirstValue ^ SecondValue ^ Result) & 0x10) != 0;
+        State->Flags.Zf = (Result == 0);
+        State->Flags.Sf = ((Result & SIGN_FLAG_LONG) != 0);
         State->Flags.Pf = Fast486CalculateParity(Result);
 
         /* Write back the result */
@@ -2548,7 +2564,7 @@ FAST486_OPCODE_HANDLER(Fast486OpcodeAdcModrm)
             /* Exception occurred */
             return FALSE;
         }
-    
+
         /* Calculate the result */
         Result = FirstValue + SecondValue + State->Flags.Cf;
 
@@ -2560,9 +2576,9 @@ FAST486_OPCODE_HANDLER(Fast486OpcodeAdcModrm)
         State->Flags.Cf = State->Flags.Cf || ((Result < FirstValue) && (Result < SecondValue));
         State->Flags.Of = ((FirstValue & SIGN_FLAG_WORD) == (SecondValue & SIGN_FLAG_WORD))
                           && ((FirstValue & SIGN_FLAG_WORD) != (Result & SIGN_FLAG_WORD));
-        State->Flags.Af = (((FirstValue & 0x0F) + (SecondValue & 0x0F)) & 0x10) ? TRUE : FALSE;
-        State->Flags.Zf = (Result == 0) ? TRUE : FALSE;
-        State->Flags.Sf = (Result & SIGN_FLAG_WORD) ? TRUE : FALSE;
+        State->Flags.Af = ((FirstValue ^ SecondValue ^ Result) & 0x10) != 0;
+        State->Flags.Zf = (Result == 0);
+        State->Flags.Sf = ((Result & SIGN_FLAG_WORD) != 0);
         State->Flags.Pf = Fast486CalculateParity(Result);
 
         /* Write back the result */
@@ -2606,9 +2622,9 @@ FAST486_OPCODE_HANDLER(Fast486OpcodeAdcAl)
     State->Flags.Cf = State->Flags.Cf || ((Result < FirstValue) && (Result < SecondValue));
     State->Flags.Of = ((FirstValue & SIGN_FLAG_BYTE) == (SecondValue & SIGN_FLAG_BYTE))
                       && ((FirstValue & SIGN_FLAG_BYTE) != (Result & SIGN_FLAG_BYTE));
-    State->Flags.Af = (((FirstValue & 0x0F) + (SecondValue & 0x0F)) & 0x10) ? TRUE : FALSE;
-    State->Flags.Zf = (Result == 0) ? TRUE : FALSE;
-    State->Flags.Sf = (Result & SIGN_FLAG_BYTE) ? TRUE : FALSE;
+    State->Flags.Af = ((FirstValue ^ SecondValue ^ Result) & 0x10) != 0;
+    State->Flags.Zf = (Result == 0);
+    State->Flags.Sf = ((Result & SIGN_FLAG_BYTE) != 0);
     State->Flags.Pf = Fast486CalculateParity(Result);
 
     /* Write back the result */
@@ -2649,9 +2665,9 @@ FAST486_OPCODE_HANDLER(Fast486OpcodeAdcEax)
         State->Flags.Cf = State->Flags.Cf || ((Result < FirstValue) && (Result < SecondValue));
         State->Flags.Of = ((FirstValue & SIGN_FLAG_LONG) == (SecondValue & SIGN_FLAG_LONG))
                           && ((FirstValue & SIGN_FLAG_LONG) != (Result & SIGN_FLAG_LONG));
-        State->Flags.Af = (((FirstValue & 0x0F) + (SecondValue & 0x0F)) & 0x10) ? TRUE : FALSE;
-        State->Flags.Zf = (Result == 0) ? TRUE : FALSE;
-        State->Flags.Sf = (Result & SIGN_FLAG_LONG) ? TRUE : FALSE;
+        State->Flags.Af = ((FirstValue ^ SecondValue ^ Result) & 0x10) != 0;
+        State->Flags.Zf = (Result == 0);
+        State->Flags.Sf = ((Result & SIGN_FLAG_LONG) != 0);
         State->Flags.Pf = Fast486CalculateParity(Result);
 
         /* Write back the result */
@@ -2679,9 +2695,9 @@ FAST486_OPCODE_HANDLER(Fast486OpcodeAdcEax)
         State->Flags.Cf = State->Flags.Cf || ((Result < FirstValue) && (Result < SecondValue));
         State->Flags.Of = ((FirstValue & SIGN_FLAG_WORD) == (SecondValue & SIGN_FLAG_WORD))
                           && ((FirstValue & SIGN_FLAG_WORD) != (Result & SIGN_FLAG_WORD));
-        State->Flags.Af = (((FirstValue & 0x0F) + (SecondValue & 0x0F)) & 0x10) ? TRUE : FALSE;
-        State->Flags.Zf = (Result == 0) ? TRUE : FALSE;
-        State->Flags.Sf = (Result & SIGN_FLAG_WORD) ? TRUE : FALSE;
+        State->Flags.Af = ((FirstValue ^ SecondValue ^ Result) & 0x10) != 0;
+        State->Flags.Zf = (Result == 0);
+        State->Flags.Sf = ((Result & SIGN_FLAG_WORD) != 0);
         State->Flags.Pf = Fast486CalculateParity(Result);
 
         /* Write back the result */
@@ -2750,12 +2766,12 @@ FAST486_OPCODE_HANDLER(Fast486OpcodeSbbByteModrm)
     Result = FirstValue - SecondValue - Carry;
 
     /* Update the flags */
-    State->Flags.Cf = FirstValue < (SecondValue + 1);
+    State->Flags.Cf = Carry ? (FirstValue <= SecondValue) : (FirstValue < SecondValue);
     State->Flags.Of = ((FirstValue & SIGN_FLAG_BYTE) != (SecondValue & SIGN_FLAG_BYTE))
                       && ((FirstValue & SIGN_FLAG_BYTE) != (Result & SIGN_FLAG_BYTE));
-    State->Flags.Af = (FirstValue & 0x0F) < ((SecondValue + 1) & 0x0F);
-    State->Flags.Zf = (Result == 0) ? TRUE : FALSE;
-    State->Flags.Sf = (Result & SIGN_FLAG_BYTE) ? TRUE : FALSE;
+    State->Flags.Af = ((FirstValue ^ SecondValue ^ Result) & 0x10) != 0;
+    State->Flags.Zf = (Result == 0);
+    State->Flags.Sf = ((Result & SIGN_FLAG_BYTE) != 0);
     State->Flags.Pf = Fast486CalculateParity(Result);
 
     /* Write back the result */
@@ -2806,17 +2822,17 @@ FAST486_OPCODE_HANDLER(Fast486OpcodeSbbModrm)
             /* Swap the order */
             SWAP(FirstValue, SecondValue);
         }
-    
+
         /* Calculate the result */
         Result = FirstValue - SecondValue - Carry;
 
         /* Update the flags */
-        State->Flags.Cf = FirstValue < (SecondValue + Carry);
+        State->Flags.Cf = Carry ? (FirstValue <= SecondValue) : (FirstValue < SecondValue);
         State->Flags.Of = ((FirstValue & SIGN_FLAG_LONG) != (SecondValue & SIGN_FLAG_LONG))
                           && ((FirstValue & SIGN_FLAG_LONG) != (Result & SIGN_FLAG_LONG));
-        State->Flags.Af = (FirstValue & 0x0F) < ((SecondValue + 1) & 0x0F);
-        State->Flags.Zf = (Result == 0) ? TRUE : FALSE;
-        State->Flags.Sf = (Result & SIGN_FLAG_LONG) ? TRUE : FALSE;
+        State->Flags.Af = ((FirstValue ^ SecondValue ^ Result) & 0x10) != 0;
+        State->Flags.Zf = (Result == 0);
+        State->Flags.Sf = ((Result & SIGN_FLAG_LONG) != 0);
         State->Flags.Pf = Fast486CalculateParity(Result);
 
         /* Write back the result */
@@ -2837,24 +2853,24 @@ FAST486_OPCODE_HANDLER(Fast486OpcodeSbbModrm)
             /* 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;
 
         /* Update the flags */
-        State->Flags.Cf = FirstValue < (SecondValue + Carry);
+        State->Flags.Cf = Carry ? (FirstValue <= SecondValue) : (FirstValue < SecondValue);
         State->Flags.Of = ((FirstValue & SIGN_FLAG_WORD) != (SecondValue & SIGN_FLAG_WORD))
                           && ((FirstValue & SIGN_FLAG_WORD) != (Result & SIGN_FLAG_WORD));
-        State->Flags.Af = (FirstValue & 0x0F) < ((SecondValue + 1) & 0x0F);
-        State->Flags.Zf = (Result == 0) ? TRUE : FALSE;
-        State->Flags.Sf = (Result & SIGN_FLAG_WORD) ? TRUE : FALSE;
+        State->Flags.Af = ((FirstValue ^ SecondValue ^ Result) & 0x10) != 0;
+        State->Flags.Zf = (Result == 0);
+        State->Flags.Sf = ((Result & SIGN_FLAG_WORD) != 0);
         State->Flags.Pf = Fast486CalculateParity(Result);
 
         /* Write back the result */
@@ -2891,12 +2907,12 @@ FAST486_OPCODE_HANDLER(Fast486OpcodeSbbAl)
     Result = FirstValue - SecondValue - Carry;
 
     /* Update the flags */
-    State->Flags.Cf = FirstValue < (SecondValue + Carry);
+    State->Flags.Cf = Carry ? (FirstValue <= SecondValue) : (FirstValue < SecondValue);
     State->Flags.Of = ((FirstValue & SIGN_FLAG_BYTE) != (SecondValue & SIGN_FLAG_BYTE))
                       && ((FirstValue & SIGN_FLAG_BYTE) != (Result & SIGN_FLAG_BYTE));
-    State->Flags.Af = (FirstValue & 0x0F) < ((SecondValue + 1) & 0x0F);
-    State->Flags.Zf = (Result == 0) ? TRUE : FALSE;
-    State->Flags.Sf = (Result & SIGN_FLAG_BYTE) ? TRUE : FALSE;
+    State->Flags.Af = ((FirstValue ^ SecondValue ^ Result) & 0x10) != 0;
+    State->Flags.Zf = (Result == 0);
+    State->Flags.Sf = ((Result & SIGN_FLAG_BYTE) != 0);
     State->Flags.Pf = Fast486CalculateParity(Result);
 
     /* Write back the result */
@@ -2932,12 +2948,12 @@ FAST486_OPCODE_HANDLER(Fast486OpcodeSbbEax)
         Result = FirstValue - SecondValue - Carry;
 
         /* Update the flags */
-        State->Flags.Cf = FirstValue < (SecondValue + Carry);
+        State->Flags.Cf = Carry ? (FirstValue <= SecondValue) : (FirstValue < SecondValue);
         State->Flags.Of = ((FirstValue & SIGN_FLAG_LONG) != (SecondValue & SIGN_FLAG_LONG))
                           && ((FirstValue & SIGN_FLAG_LONG) != (Result & SIGN_FLAG_LONG));
-        State->Flags.Af = (FirstValue & 0x0F) < ((SecondValue + Carry) & 0x0F);
-        State->Flags.Zf = (Result == 0) ? TRUE : FALSE;
-        State->Flags.Sf = (Result & SIGN_FLAG_LONG) ? TRUE : FALSE;
+        State->Flags.Af = ((FirstValue ^ SecondValue ^ Result) & 0x10) != 0;
+        State->Flags.Zf = (Result == 0);
+        State->Flags.Sf = ((Result & SIGN_FLAG_LONG) != 0);
         State->Flags.Pf = Fast486CalculateParity(Result);
 
         /* Write back the result */
@@ -2958,12 +2974,12 @@ FAST486_OPCODE_HANDLER(Fast486OpcodeSbbEax)
         Result = FirstValue - SecondValue - Carry;
 
         /* Update the flags */
-        State->Flags.Cf = FirstValue < (SecondValue + Carry);
+        State->Flags.Cf = Carry ? (FirstValue <= SecondValue) : (FirstValue < SecondValue);
         State->Flags.Of = ((FirstValue & SIGN_FLAG_WORD) != (SecondValue & SIGN_FLAG_WORD))
                           && ((FirstValue & SIGN_FLAG_WORD) != (Result & SIGN_FLAG_WORD));
-        State->Flags.Af = (FirstValue & 0x0F) < ((SecondValue + Carry) & 0x0F);
-        State->Flags.Zf = (Result == 0) ? TRUE : FALSE;
-        State->Flags.Sf = (Result & SIGN_FLAG_WORD) ? TRUE : FALSE;
+        State->Flags.Af = ((FirstValue ^ SecondValue ^ Result) & 0x10) != 0;
+        State->Flags.Zf = (Result == 0);
+        State->Flags.Sf = ((Result & SIGN_FLAG_WORD) != 0);
         State->Flags.Pf = Fast486CalculateParity(Result);
 
         /* Write back the result */
@@ -3027,6 +3043,13 @@ FAST486_OPCODE_HANDLER(Fast486OpcodeDaa)
         State->Flags.Cf = TRUE;
     }
 
+    Value = State->GeneralRegs[FAST486_REG_EAX].LowByte;
+
+    /* Update the flags */
+    State->Flags.Sf = (Value & SIGN_FLAG_BYTE) != 0;
+    State->Flags.Zf = (Value == 0);
+    State->Flags.Pf = Fast486CalculateParity(Value);
+
     return TRUE;
 }
 
@@ -3068,12 +3091,12 @@ FAST486_OPCODE_HANDLER(Fast486OpcodeCmpSubByteModrm)
     Result = FirstValue - SecondValue;
 
     /* Update the flags */
-    State->Flags.Cf = FirstValue < SecondValue;
+    State->Flags.Cf = (FirstValue < SecondValue);
     State->Flags.Of = ((FirstValue & SIGN_FLAG_BYTE) != (SecondValue & SIGN_FLAG_BYTE))
                       && ((FirstValue & SIGN_FLAG_BYTE) != (Result & SIGN_FLAG_BYTE));
     State->Flags.Af = (FirstValue & 0x0F) < (SecondValue & 0x0F);
-    State->Flags.Zf = (Result == 0) ? TRUE : FALSE;
-    State->Flags.Sf = (Result & SIGN_FLAG_BYTE) ? TRUE : FALSE;
+    State->Flags.Zf = (Result == 0);
+    State->Flags.Sf = ((Result & SIGN_FLAG_BYTE) != 0);
     State->Flags.Pf = Fast486CalculateParity(Result);
 
     /* Check if this is not a CMP */
@@ -3132,17 +3155,17 @@ FAST486_OPCODE_HANDLER(Fast486OpcodeCmpSubModrm)
             /* Swap the order */
             SWAP(FirstValue, SecondValue);
         }
-    
+
         /* Calculate the result */
         Result = FirstValue - SecondValue;
 
         /* Update the flags */
-        State->Flags.Cf = FirstValue < SecondValue;
+        State->Flags.Cf = (FirstValue < SecondValue);
         State->Flags.Of = ((FirstValue & SIGN_FLAG_LONG) != (SecondValue & SIGN_FLAG_LONG))
                           && ((FirstValue & SIGN_FLAG_LONG) != (Result & SIGN_FLAG_LONG));
         State->Flags.Af = (FirstValue & 0x0F) < (SecondValue & 0x0F);
-        State->Flags.Zf = (Result == 0) ? TRUE : FALSE;
-        State->Flags.Sf = (Result & SIGN_FLAG_LONG) ? TRUE : FALSE;
+        State->Flags.Zf = (Result == 0);
+        State->Flags.Sf = ((Result & SIGN_FLAG_LONG) != 0);
         State->Flags.Pf = Fast486CalculateParity(Result);
 
         /* Check if this is not a CMP */
@@ -3172,24 +3195,24 @@ FAST486_OPCODE_HANDLER(Fast486OpcodeCmpSubModrm)
             /* 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;
 
         /* Update the flags */
-        State->Flags.Cf = FirstValue < SecondValue;
+        State->Flags.Cf = (FirstValue < SecondValue);
         State->Flags.Of = ((FirstValue & SIGN_FLAG_WORD) != (SecondValue & SIGN_FLAG_WORD))
                           && ((FirstValue & SIGN_FLAG_WORD) != (Result & SIGN_FLAG_WORD));
         State->Flags.Af = (FirstValue & 0x0F) < (SecondValue & 0x0F);
-        State->Flags.Zf = (Result == 0) ? TRUE : FALSE;
-        State->Flags.Sf = (Result & SIGN_FLAG_WORD) ? TRUE : FALSE;
+        State->Flags.Zf = (Result == 0);
+        State->Flags.Sf = ((Result & SIGN_FLAG_WORD) != 0);
         State->Flags.Pf = Fast486CalculateParity(Result);
 
         /* Check if this is not a CMP */
@@ -3234,12 +3257,12 @@ FAST486_OPCODE_HANDLER(Fast486OpcodeCmpSubAl)
     Result = FirstValue - SecondValue;
 
     /* Update the flags */
-    State->Flags.Cf = FirstValue < SecondValue;
+    State->Flags.Cf = (FirstValue < SecondValue);
     State->Flags.Of = ((FirstValue & SIGN_FLAG_BYTE) != (SecondValue & SIGN_FLAG_BYTE))
                       && ((FirstValue & SIGN_FLAG_BYTE) != (Result & SIGN_FLAG_BYTE));
     State->Flags.Af = (FirstValue & 0x0F) < (SecondValue & 0x0F);
-    State->Flags.Zf = (Result == 0) ? TRUE : FALSE;
-    State->Flags.Sf = (Result & SIGN_FLAG_BYTE) ? TRUE : FALSE;
+    State->Flags.Zf = (Result == 0);
+    State->Flags.Sf = ((Result & SIGN_FLAG_BYTE) != 0);
     State->Flags.Pf = Fast486CalculateParity(Result);
 
     /* Check if this is not a CMP */
@@ -3277,12 +3300,12 @@ FAST486_OPCODE_HANDLER(Fast486OpcodeCmpSubEax)
         Result = FirstValue - SecondValue;
 
         /* Update the flags */
-        State->Flags.Cf = FirstValue < SecondValue;
+        State->Flags.Cf = (FirstValue < SecondValue);
         State->Flags.Of = ((FirstValue & SIGN_FLAG_LONG) != (SecondValue & SIGN_FLAG_LONG))
                           && ((FirstValue & SIGN_FLAG_LONG) != (Result & SIGN_FLAG_LONG));
         State->Flags.Af = (FirstValue & 0x0F) < (SecondValue & 0x0F);
-        State->Flags.Zf = (Result == 0) ? TRUE : FALSE;
-        State->Flags.Sf = (Result & SIGN_FLAG_LONG) ? TRUE : FALSE;
+        State->Flags.Zf = (Result == 0);
+        State->Flags.Sf = ((Result & SIGN_FLAG_LONG) != 0);
         State->Flags.Pf = Fast486CalculateParity(Result);
 
         /* Check if this is not a CMP */
@@ -3307,12 +3330,12 @@ FAST486_OPCODE_HANDLER(Fast486OpcodeCmpSubEax)
         Result = FirstValue - SecondValue;
 
         /* Update the flags */
-        State->Flags.Cf = FirstValue < SecondValue;
+        State->Flags.Cf = (FirstValue < SecondValue);
         State->Flags.Of = ((FirstValue & SIGN_FLAG_WORD) != (SecondValue & SIGN_FLAG_WORD))
                           && ((FirstValue & SIGN_FLAG_WORD) != (Result & SIGN_FLAG_WORD));
         State->Flags.Af = (FirstValue & 0x0F) < (SecondValue & 0x0F);
-        State->Flags.Zf = (Result == 0) ? TRUE : FALSE;
-        State->Flags.Sf = (Result & SIGN_FLAG_WORD) ? TRUE : FALSE;
+        State->Flags.Zf = (Result == 0);
+        State->Flags.Sf = ((Result & SIGN_FLAG_WORD) != 0);
         State->Flags.Pf = Fast486CalculateParity(Result);
 
         /* Check if this is not a CMP */
@@ -3359,6 +3382,13 @@ FAST486_OPCODE_HANDLER(Fast486OpcodeDas)
         State->Flags.Cf = TRUE;
     }
 
+    Value = State->GeneralRegs[FAST486_REG_EAX].LowByte;
+
+    /* Update the flags */
+    State->Flags.Sf = (Value & SIGN_FLAG_BYTE) != 0;
+    State->Flags.Zf = (Value == 0);
+    State->Flags.Pf = Fast486CalculateParity(Value);
+
     return TRUE;
 }
 
@@ -3373,7 +3403,7 @@ FAST486_OPCODE_HANDLER(Fast486OpcodeAaa)
     if (((Value & 0x0F) > 9) || State->Flags.Af)
     {
         /* Correct it */
-        State->GeneralRegs[FAST486_REG_EAX].LowByte += 0x06;
+        State->GeneralRegs[FAST486_REG_EAX].LowWord += 0x06;
         State->GeneralRegs[FAST486_REG_EAX].HighByte++;
 
         /* Set CF and AF */
@@ -3402,7 +3432,7 @@ FAST486_OPCODE_HANDLER(Fast486OpcodeAas)
     if (((Value & 0x0F) > 9) || State->Flags.Af)
     {
         /* Correct it */
-        State->GeneralRegs[FAST486_REG_EAX].LowByte -= 0x06;
+        State->GeneralRegs[FAST486_REG_EAX].LowWord -= 0x06;
         State->GeneralRegs[FAST486_REG_EAX].HighByte--;
 
         /* Set CF and AF */
@@ -3494,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)
@@ -3598,7 +3720,6 @@ FAST486_OPCODE_HANDLER(Fast486OpcodeImulModrmImm)
     BOOLEAN OperandSize, AddressSize;
     FAST486_MOD_REG_RM ModRegRm;
     LONG Multiplier;
-    LONGLONG Product;
 
     /* Make sure this is the right instruction */
     ASSERT((Opcode & 0xFD) == 0x69);
@@ -3661,6 +3782,7 @@ FAST486_OPCODE_HANDLER(Fast486OpcodeImulModrmImm)
     if (OperandSize)
     {
         LONG RegValue, Multiplicand;
+        LONGLONG Product;
 
         /* Read the operands */
         if (!Fast486ReadModrmDwordOperands(State,
@@ -3674,10 +3796,20 @@ FAST486_OPCODE_HANDLER(Fast486OpcodeImulModrmImm)
 
         /* 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,
@@ -3690,21 +3822,17 @@ FAST486_OPCODE_HANDLER(Fast486OpcodeImulModrmImm)
         }
 
         /* Multiply */
-        Product = (LONGLONG)Multiplicand * (LONGLONG)Multiplier;
-    }
+        Product = (LONG)Multiplicand * (LONG)Multiplier;
 
-    /* Check for carry/overflow */
-    if ((Product < LONG_MIN) || (Product > LONG_MAX))
-    {
-        State->Flags.Cf = State->Flags.Of = TRUE;
-    }
-    else State->Flags.Cf = State->Flags.Of = FALSE;
+        /* 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)
@@ -3798,7 +3926,7 @@ FAST486_OPCODE_HANDLER(Fast486OpcodeMovModrm)
 
         if (Opcode & FAST486_OPCODE_WRITE_REG) Result = SecondValue;
         else Result = FirstValue;
-    
+
         /* Write back the result */
         return Fast486WriteModrmDwordOperands(State,
                                               &ModRegRm,
@@ -3817,7 +3945,7 @@ FAST486_OPCODE_HANDLER(Fast486OpcodeMovModrm)
             /* Exception occurred */
             return FALSE;
         }
-    
+
         if (Opcode & FAST486_OPCODE_WRITE_REG) Result = SecondValue;
         else Result = FirstValue;
 
@@ -3948,9 +4076,9 @@ FAST486_OPCODE_HANDLER(Fast486OpcodeMovLoadSeg)
 
     if (OperandSize)
     {
-        ULONG Dummy, Selector;
+        ULONG Selector;
 
-        if (!Fast486ReadModrmDwordOperands(State, &ModRegRm, &Dummy, &Selector))
+        if (!Fast486ReadModrmDwordOperands(State, &ModRegRm, NULL, &Selector))
         {
             /* Exception occurred */
             return FALSE;
@@ -3960,9 +4088,9 @@ FAST486_OPCODE_HANDLER(Fast486OpcodeMovLoadSeg)
     }
     else
     {
-        USHORT Dummy, Selector;
+        USHORT Selector;
 
-        if (!Fast486ReadModrmWordOperands(State, &ModRegRm, &Dummy, &Selector))
+        if (!Fast486ReadModrmWordOperands(State, &ModRegRm, NULL, &Selector))
         {
             /* Exception occurred */
             return FALSE;
@@ -4128,121 +4256,39 @@ FAST486_OPCODE_HANDLER(Fast486OpcodePopFlags)
 {
     BOOLEAN Size = State->SegmentRegs[FAST486_REG_CS].Size;
     INT Cpl = Fast486GetCurrentPrivLevel(State);
-    ULONG NewFlags;
+    FAST486_FLAGS_REG NewFlags;
 
     NO_LOCK_PREFIX();
     TOGGLE_OPSIZE(Size);
 
     /* Pop the new flags */
-    if (!Fast486StackPop(State, &NewFlags))
+    if (!Fast486StackPop(State, &NewFlags.Long))
     {
         /* Exception occurred */
         return FALSE;
     }
 
-    if (!State->Flags.Vm)
+    /* Check for VM86 mode when IOPL is not 3 */
+    if (State->Flags.Vm && (State->Flags.Iopl != 3))
     {
-        /* Check the current privilege level */
-        if (Cpl == 0)
-        {
-            /* Supervisor */
-
-            /* Set the flags */
-            if (Size)
-            {
-                /* Memorize the old state of RF */
-                BOOLEAN OldRf = State->Flags.Rf;
-
-                State->Flags.Long = NewFlags;
-
-                /* Restore VM and RF */
-                State->Flags.Vm = FALSE;
-                State->Flags.Rf = OldRf;
-
-                /* Clear VIF and VIP */
-                State->Flags.Vif = State->Flags.Vip = FALSE;
-            }
-            else State->Flags.LowWord = LOWORD(NewFlags);
-
-            /* Restore the reserved bits */
-            State->Flags.AlwaysSet = TRUE;
-            State->Flags.Reserved0 = FALSE;
-            State->Flags.Reserved1 = FALSE;
-        }
-        else
-        {
-            /* User */
-
-            /* Memorize the old state of IF and IOPL */
-            BOOLEAN OldIf = State->Flags.If;
-            UINT OldIopl = State->Flags.Iopl;
-
-            /* Set the flags */
-            if (Size)
-            {
-                /* Memorize the old state of RF */
-                BOOLEAN OldRf = State->Flags.Rf;
-
-                State->Flags.Long = NewFlags;
-
-                /* Restore VM and RF */
-                State->Flags.Vm = FALSE;
-                State->Flags.Rf = OldRf;
-
-                /* Clear VIF and VIP */
-                State->Flags.Vif = State->Flags.Vip = FALSE;
-            }
-            else State->Flags.LowWord = LOWORD(NewFlags);
-
-            /* Restore the reserved bits and IOPL */
-            State->Flags.AlwaysSet = TRUE;
-            State->Flags.Reserved0 = FALSE;
-            State->Flags.Reserved1 = FALSE;
-            State->Flags.Iopl = OldIopl;
-
-            /* Check if the user doesn't have the privilege to change IF */
-            if (Cpl > State->Flags.Iopl)
-            {
-                /* Restore IF */
-                State->Flags.If = OldIf;
-            }
-        }
+        /* Call the VM86 monitor */
+        Fast486ExceptionWithErrorCode(State, FAST486_EXCEPTION_GP, 0);
+        return FALSE;
     }
-    else
-    {
-        /* Check the IOPL */
-        if (State->Flags.Iopl == 3)
-        {
-            if (Size)
-            {
-                /* Memorize the old state of RF, VIF and VIP */
-                BOOLEAN OldRf = State->Flags.Rf;
-                BOOLEAN OldVif = State->Flags.Vif;
-                BOOLEAN OldVip = State->Flags.Vip;
-
-                State->Flags.Long = NewFlags;
-
-                /* Restore VM, RF, VIF and VIP */
-                State->Flags.Vm = TRUE;
-                State->Flags.Rf = OldRf;
-                State->Flags.Vif = OldVif;
-                State->Flags.Vip = OldVip;
-            }
-            else State->Flags.LowWord = LOWORD(NewFlags);
 
-            /* Restore the reserved bits and IOPL */
-            State->Flags.AlwaysSet = TRUE;
-            State->Flags.Reserved0 = FALSE;
-            State->Flags.Reserved1 = FALSE;
-            State->Flags.Iopl = 3;
-        }
-        else
-        {
-            /* Call the VM86 monitor */
-            Fast486ExceptionWithErrorCode(State, FAST486_EXCEPTION_GP, 0);
-        }
-        
-    }
+    State->Flags.Cf = NewFlags.Cf;
+    State->Flags.Pf = NewFlags.Pf;
+    State->Flags.Af = NewFlags.Af;
+    State->Flags.Zf = NewFlags.Zf;
+    State->Flags.Sf = NewFlags.Sf;
+    State->Flags.Tf = NewFlags.Tf;
+    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;
 
     return TRUE;
 }
@@ -4260,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)
@@ -4271,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)
@@ -4321,6 +4367,7 @@ FAST486_OPCODE_HANDLER(Fast486OpcodeLdsLes)
 
     OperandSize = AddressSize = State->SegmentRegs[FAST486_REG_CS].Size;
 
+    TOGGLE_OPSIZE(OperandSize);
     TOGGLE_ADSIZE(AddressSize);
 
     /* Get the operands */
@@ -4338,10 +4385,10 @@ FAST486_OPCODE_HANDLER(Fast486OpcodeLdsLes)
             && (ModRegRm.SecondRegister == FAST486_REG_ESP)
             && (State->BopCallback != NULL))
         {
-            USHORT BopCode;
+            UCHAR BopCode;
 
             /* Fetch the BOP code */
-            if (!Fast486FetchWord(State, &BopCode))
+            if (!Fast486FetchByte(State, &BopCode))
             {
                 /* Exception occurred */
                 return FALSE;
@@ -4620,7 +4667,7 @@ FAST486_OPCODE_HANDLER(Fast486OpcodeInt)
 
 FAST486_OPCODE_HANDLER(Fast486OpcodeIret)
 {
-    INT i;
+    FAST486_SEG_REGS i;
     ULONG InstPtr, CodeSel, StackPtr, StackSel;
     FAST486_FLAGS_REG NewFlags;
     BOOLEAN Size = State->SegmentRegs[FAST486_REG_CS].Size;
@@ -4784,7 +4831,7 @@ FAST486_OPCODE_HANDLER(Fast486OpcodeIret)
             Cpl = Fast486GetCurrentPrivLevel(State);
 
             /* Check segment security */
-            for (i = 0; i <= FAST486_NUM_SEG_REGS; i++)
+            for (i = 0; i < FAST486_NUM_SEG_REGS; i++)
             {
                 /* Don't check CS or SS */
                 if ((i == FAST486_REG_CS) || (i == FAST486_REG_SS)) continue;
@@ -4854,8 +4901,9 @@ FAST486_OPCODE_HANDLER(Fast486OpcodeAam)
     State->GeneralRegs[FAST486_REG_EAX].LowByte = Value %= Base;
 
     /* Update flags */
-    State->Flags.Zf = (Value == 0) ? TRUE : FALSE;
-    State->Flags.Sf = (Value & SIGN_FLAG_BYTE) ? TRUE : FALSE;
+    State->Flags.Af = FALSE;
+    State->Flags.Zf = (Value == 0);
+    State->Flags.Sf = ((Value & SIGN_FLAG_BYTE) != 0);
     State->Flags.Pf = Fast486CalculateParity(Value);
 
     return TRUE;
@@ -4877,11 +4925,12 @@ FAST486_OPCODE_HANDLER(Fast486OpcodeAad)
 
     /* Adjust */
     Value += State->GeneralRegs[FAST486_REG_EAX].HighByte * Base;
-    State->GeneralRegs[FAST486_REG_EAX].LowByte = Value;
+    State->GeneralRegs[FAST486_REG_EAX].LowWord = Value;
 
     /* Update flags */
-    State->Flags.Zf = (Value == 0) ? TRUE : FALSE;
-    State->Flags.Sf = (Value & SIGN_FLAG_BYTE) ? TRUE : FALSE;
+    State->Flags.Af = FALSE;
+    State->Flags.Zf = (Value == 0);
+    State->Flags.Sf = ((Value & SIGN_FLAG_BYTE) != 0);
     State->Flags.Pf = Fast486CalculateParity(Value);
 
     return TRUE;
@@ -4897,8 +4946,8 @@ FAST486_OPCODE_HANDLER(Fast486OpcodeXlat)
     /* Read a byte from DS:[(E)BX + AL] */
     if (!Fast486ReadMemory(State,
                            FAST486_REG_DS,
-                           AddressSize ? State->GeneralRegs[FAST486_REG_EBX].Long
-                                       : State->GeneralRegs[FAST486_REG_EBX].LowWord
+                           (AddressSize ? State->GeneralRegs[FAST486_REG_EBX].Long
+                                        : State->GeneralRegs[FAST486_REG_EBX].LowWord)
                            + State->GeneralRegs[FAST486_REG_EAX].LowByte,
                            FALSE,
                            &Value,
@@ -4925,7 +4974,7 @@ FAST486_OPCODE_HANDLER(Fast486OpcodeLoop)
     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);
@@ -4952,7 +5001,8 @@ FAST486_OPCODE_HANDLER(Fast486OpcodeLoop)
     if (Condition)
     {
         /* Move the instruction pointer */
-        State->InstPtr.Long += Offset;
+        if (Size) State->InstPtr.Long += Offset;
+        else State->InstPtr.LowWord += Offset;
     }
 
     return TRUE;
@@ -4968,7 +5018,7 @@ FAST486_OPCODE_HANDLER(Fast486OpcodeJecxz)
     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);
@@ -4982,8 +5032,9 @@ FAST486_OPCODE_HANDLER(Fast486OpcodeJecxz)
 
     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;
@@ -5017,7 +5068,7 @@ FAST486_OPCODE_HANDLER(Fast486OpcodeCall)
             return FALSE;
         }
 
-        /* Move the instruction pointer */        
+        /* Move the instruction pointer */
         State->InstPtr.Long += Offset;
     }
     else
@@ -5038,7 +5089,7 @@ FAST486_OPCODE_HANDLER(Fast486OpcodeCall)
             return FALSE;
         }
 
-        /* Move the instruction pointer */        
+        /* Move the instruction pointer */
         State->InstPtr.LowWord += Offset;
     }
 
@@ -5066,7 +5117,7 @@ FAST486_OPCODE_HANDLER(Fast486OpcodeJmp)
             return FALSE;
         }
 
-        /* Move the instruction pointer */        
+        /* Move the instruction pointer */
         State->InstPtr.Long += Offset;
     }
     else
@@ -5080,8 +5131,11 @@ FAST486_OPCODE_HANDLER(Fast486OpcodeJmp)
             return FALSE;
         }
 
-        /* Move the instruction pointer */        
-        State->InstPtr.LowWord += Offset;
+        /* Move the instruction pointer */
+        State->InstPtr.Long += Offset;
+
+        /* Clear the top half of EIP */
+        State->InstPtr.Long &= 0xFFFF;
     }
 
     return TRUE;
@@ -5131,24 +5185,23 @@ FAST486_OPCODE_HANDLER(Fast486OpcodeJmpAbs)
         return FALSE;
     }
 
-    /* Load new (E)IP */
-    if (Size) State->InstPtr.Long = Offset;
-    else State->InstPtr.LowWord = LOWORD(Offset);
+    /* Load new EIP */
+    State->InstPtr.Long = Offset;
 
     return TRUE;
 }
 
 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))
         {
@@ -5181,14 +5234,17 @@ FAST486_OPCODE_HANDLER(Fast486OpcodeMovAlOffset)
 
 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;
 
@@ -5199,13 +5255,26 @@ FAST486_OPCODE_HANDLER(Fast486OpcodeMovEaxOffset)
         }
 
         /* 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
     {
@@ -5218,27 +5287,40 @@ FAST486_OPCODE_HANDLER(Fast486OpcodeMovEaxOffset)
         }
 
         /* 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))
         {
@@ -5270,14 +5352,17 @@ FAST486_OPCODE_HANDLER(Fast486OpcodeMovOffsetAl)
 
 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;
 
@@ -5288,12 +5373,24 @@ FAST486_OPCODE_HANDLER(Fast486OpcodeMovOffsetEax)
         }
 
         /* 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
     {
@@ -5306,12 +5403,24 @@ FAST486_OPCODE_HANDLER(Fast486OpcodeMovOffsetEax)
         }
 
         /* 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));
+        }
     }
 }
 
@@ -5348,162 +5457,90 @@ FAST486_OPCODE_HANDLER(Fast486OpcodeMovs)
         Segment = State->SegmentOverride;
     }
 
+    if (State->PrefixFlags & FAST486_PREFIX_REP)
+    {
+        if ((AddressSize && (State->GeneralRegs[FAST486_REG_ECX].Long == 0))
+            || (!AddressSize && (State->GeneralRegs[FAST486_REG_ECX].LowWord == 0)))
+        {
+            /* Do nothing */
+            return TRUE;
+        }
+    }
+
     /* Calculate the size */
     if (Opcode == 0xA4) DataSize = sizeof(UCHAR);
     else DataSize = OperandSize ? sizeof(ULONG) : sizeof(USHORT);
 
-    if (State->PrefixFlags & FAST486_PREFIX_REP)
+    /* Read from the source operand */
+    if (!Fast486ReadMemory(State,
+                           Segment,
+                           AddressSize ? State->GeneralRegs[FAST486_REG_ESI].Long
+                                       : State->GeneralRegs[FAST486_REG_ESI].LowWord,
+                           FALSE,
+                           &Data,
+                           DataSize))
     {
-        UCHAR Block[STRING_BLOCK_SIZE];
-        ULONG Count = OperandSize ? State->GeneralRegs[FAST486_REG_ECX].Long
-                                  : State->GeneralRegs[FAST486_REG_ECX].LowWord;
+        /* Exception occurred */
+        return FALSE;
+    }
 
-        /* Clear the memory block */
-        RtlZeroMemory(Block, sizeof(Block));
+    /* Write to the destination operand */
+    if (!Fast486WriteMemory(State,
+                            FAST486_REG_ES,
+                            AddressSize ? State->GeneralRegs[FAST486_REG_EDI].Long
+                                        : State->GeneralRegs[FAST486_REG_EDI].LowWord,
+                            &Data,
+                            DataSize))
+    {
+        /* Exception occurred */
+        return FALSE;
+    }
 
-        /* Transfer until finished */
-        while (Count)
+    /* Increment/decrement ESI and EDI */
+    if (AddressSize)
+    {
+        if (!State->Flags.Df)
         {
-            ULONG Processed = min(Count, STRING_BLOCK_SIZE / DataSize);
-
-            /* Simulate the 16-bit wrap-around of SI and DI in 16-bit address mode */
-            if (!AddressSize)
-            {
-                ULONG MaxBytesSrc = State->Flags.Df
-                                    ? (ULONG)State->GeneralRegs[FAST486_REG_ESI].LowWord
-                                    : (0x10000 - (ULONG)State->GeneralRegs[FAST486_REG_ESI].LowWord);
-                ULONG MaxBytesDest = State->Flags.Df
-                                     ? (ULONG)State->GeneralRegs[FAST486_REG_EDI].LowWord
-                                     : (0x10000 - (ULONG)State->GeneralRegs[FAST486_REG_EDI].LowWord);
-
-
-                Processed = min(Processed, min(MaxBytesSrc, MaxBytesDest) / DataSize);
-                if (Processed == 0) Processed = 1;
-            }
-
-            if (State->Flags.Df)
-            {
-                /* Reduce ESI and EDI by the number of bytes to transfer */
-                if (AddressSize)
-                {
-                    State->GeneralRegs[FAST486_REG_ESI].Long -= Processed * DataSize;
-                    State->GeneralRegs[FAST486_REG_EDI].Long -= Processed * DataSize;
-                }
-                else
-                {
-                    State->GeneralRegs[FAST486_REG_ESI].LowWord -= Processed * DataSize;
-                    State->GeneralRegs[FAST486_REG_EDI].LowWord -= Processed * DataSize;
-                }
-            }
-
-            /* Read from memory */
-            if (!Fast486ReadMemory(State,
-                                   Segment,
-                                   AddressSize ? State->GeneralRegs[FAST486_REG_ESI].Long
-                                               : State->GeneralRegs[FAST486_REG_ESI].LowWord,
-                                   FALSE,
-                                   Block,
-                                   Processed * DataSize))
-            {
-                /* Set ECX */
-                if (OperandSize) State->GeneralRegs[FAST486_REG_ECX].Long = Count;
-                else State->GeneralRegs[FAST486_REG_ECX].LowWord = LOWORD(Count);
-
-                /* Exception occurred */
-                return FALSE;
-            }
-
-            /* Write to memory */
-            if (!Fast486WriteMemory(State,
-                                    FAST486_REG_ES,
-                                    AddressSize ? State->GeneralRegs[FAST486_REG_EDI].Long
-                                                : State->GeneralRegs[FAST486_REG_EDI].LowWord,
-                                    Block,
-                                    Processed * DataSize))
-            {
-                /* Set ECX */
-                if (OperandSize) State->GeneralRegs[FAST486_REG_ECX].Long = Count;
-                else State->GeneralRegs[FAST486_REG_ECX].LowWord = LOWORD(Count);
-
-                /* Exception occurred */
-                return FALSE;
-            }
-
-            if (!State->Flags.Df)
-            {
-                /* Increase ESI and EDI by the number of bytes transfered */
-                if (AddressSize)
-                {
-                    State->GeneralRegs[FAST486_REG_ESI].Long += Processed * DataSize;
-                    State->GeneralRegs[FAST486_REG_EDI].Long += Processed * DataSize;
-                }
-                else
-                {
-                    State->GeneralRegs[FAST486_REG_ESI].LowWord += Processed * DataSize;
-                    State->GeneralRegs[FAST486_REG_EDI].LowWord += Processed * DataSize;
-                }
-            }
-
-            /* Reduce the total count by the number processed in this run */
-            Count -= Processed;
+            State->GeneralRegs[FAST486_REG_ESI].Long += DataSize;
+            State->GeneralRegs[FAST486_REG_EDI].Long += DataSize;
+        }
+        else
+        {
+            State->GeneralRegs[FAST486_REG_ESI].Long -= DataSize;
+            State->GeneralRegs[FAST486_REG_EDI].Long -= DataSize;
         }
-
-        /* Clear ECX */
-        if (OperandSize) State->GeneralRegs[FAST486_REG_ECX].Long = 0;
-        else State->GeneralRegs[FAST486_REG_ECX].LowWord = 0;
     }
     else
     {
-        /* Read from the source operand */
-        if (!Fast486ReadMemory(State,
-                               FAST486_REG_DS,
-                               AddressSize ? State->GeneralRegs[FAST486_REG_ESI].Long
-                                           : State->GeneralRegs[FAST486_REG_ESI].LowWord,
-                               FALSE,
-                               &Data,
-                               DataSize))
+        if (!State->Flags.Df)
         {
-            /* Exception occurred */
-            return FALSE;
+            State->GeneralRegs[FAST486_REG_ESI].LowWord += DataSize;
+            State->GeneralRegs[FAST486_REG_EDI].LowWord += DataSize;
         }
-
-        /* Write to the destination operand */
-        if (!Fast486WriteMemory(State,
-                                FAST486_REG_ES,
-                                AddressSize ? State->GeneralRegs[FAST486_REG_EDI].Long
-                                            : State->GeneralRegs[FAST486_REG_EDI].LowWord,
-                                &Data,
-                                DataSize))
+        else
         {
-            /* Exception occurred */
-            return FALSE;
+            State->GeneralRegs[FAST486_REG_ESI].LowWord -= DataSize;
+            State->GeneralRegs[FAST486_REG_EDI].LowWord -= DataSize;
         }
+    }
 
-        /* Increment/decrement ESI and EDI */
-        if (OperandSize)
+    // FIXME: This method is slow!
+    if (State->PrefixFlags & FAST486_PREFIX_REP)
+    {
+        if (AddressSize)
         {
-            if (!State->Flags.Df)
-            {
-                State->GeneralRegs[FAST486_REG_ESI].Long += DataSize;
-                State->GeneralRegs[FAST486_REG_EDI].Long += DataSize;
-            }
-            else
+            if (--State->GeneralRegs[FAST486_REG_ECX].Long)
             {
-                State->GeneralRegs[FAST486_REG_ESI].Long -= DataSize;
-                State->GeneralRegs[FAST486_REG_EDI].Long -= DataSize;
+                /* Repeat the instruction */
+                State->InstPtr = State->SavedInstPtr;
             }
         }
         else
         {
-            if (!State->Flags.Df)
+            if (--State->GeneralRegs[FAST486_REG_ECX].LowWord)
             {
-                State->GeneralRegs[FAST486_REG_ESI].LowWord += DataSize;
-                State->GeneralRegs[FAST486_REG_EDI].LowWord += DataSize;
-            }
-            else
-            {
-                State->GeneralRegs[FAST486_REG_ESI].LowWord -= DataSize;
-                State->GeneralRegs[FAST486_REG_EDI].LowWord -= DataSize;
+                /* Repeat the instruction */
+                State->InstPtr = State->SavedInstPtr;
             }
         }
     }
@@ -5533,13 +5570,24 @@ FAST486_OPCODE_HANDLER(Fast486OpcodeCmps)
         Segment = State->SegmentOverride;
     }
 
+    if ((State->PrefixFlags & FAST486_PREFIX_REP)
+        || (State->PrefixFlags & FAST486_PREFIX_REPNZ))
+    {
+        if ((AddressSize && (State->GeneralRegs[FAST486_REG_ECX].Long == 0))
+            || (!AddressSize && (State->GeneralRegs[FAST486_REG_ECX].LowWord == 0)))
+        {
+            /* Do nothing */
+            return TRUE;
+        }
+    }
+
     /* Calculate the size */
     if (Opcode == 0xA6) DataSize = sizeof(UCHAR);
     else DataSize = OperandSize ? sizeof(ULONG) : sizeof(USHORT);
 
     /* Calculate the mask and sign flag */
-    DataMask = (1 << (DataSize * 8)) - 1;
     SignFlag = 1 << ((DataSize * 8) - 1);
+    DataMask = SignFlag | (SignFlag - 1);
 
     /* Read from the first source operand */
     if (!Fast486ReadMemory(State,
@@ -5573,16 +5621,16 @@ FAST486_OPCODE_HANDLER(Fast486OpcodeCmps)
     Result = (FirstValue - SecondValue) & DataMask;
 
     /* Update the flags */
-    State->Flags.Cf = FirstValue < SecondValue;
+    State->Flags.Cf = (FirstValue < SecondValue);
     State->Flags.Of = ((FirstValue & SignFlag) != (SecondValue & SignFlag))
                       && ((FirstValue & SignFlag) != (Result & SignFlag));
     State->Flags.Af = (FirstValue & 0x0F) < (SecondValue & 0x0F);
-    State->Flags.Zf = (Result == 0) ? TRUE : FALSE;
-    State->Flags.Sf = (Result & SignFlag) ? TRUE : FALSE;
+    State->Flags.Zf = (Result == 0);
+    State->Flags.Sf = ((Result & SignFlag) != 0);
     State->Flags.Pf = Fast486CalculateParity(Result);
 
     /* Increment/decrement ESI and EDI */
-    if (OperandSize)
+    if (AddressSize)
     {
         if (!State->Flags.Df)
         {
@@ -5614,8 +5662,8 @@ FAST486_OPCODE_HANDLER(Fast486OpcodeCmps)
         || (State->PrefixFlags & FAST486_PREFIX_REPNZ))
     {
         BOOLEAN Repeat = TRUE;
-        
-        if (OperandSize)
+
+        if (AddressSize)
         {
             if ((--State->GeneralRegs[FAST486_REG_ECX].Long) == 0)
             {
@@ -5670,7 +5718,7 @@ FAST486_OPCODE_HANDLER(Fast486OpcodeStos)
     if (State->PrefixFlags & FAST486_PREFIX_REP)
     {
         UCHAR Block[STRING_BLOCK_SIZE];
-        ULONG Count = OperandSize ? State->GeneralRegs[FAST486_REG_ECX].Long
+        ULONG Count = AddressSize ? State->GeneralRegs[FAST486_REG_ECX].Long
                                   : State->GeneralRegs[FAST486_REG_ECX].LowWord;
 
         /* Fill the memory block with the data */
@@ -5713,9 +5761,9 @@ FAST486_OPCODE_HANDLER(Fast486OpcodeStos)
 
             if (State->Flags.Df)
             {
-                /* Reduce EDI by the number of bytes to transfer */
-                if (AddressSize) State->GeneralRegs[FAST486_REG_EDI].Long -= Processed * DataSize;
-                else State->GeneralRegs[FAST486_REG_EDI].LowWord -= Processed * DataSize;
+                /* Set EDI to the starting location */
+                if (AddressSize) State->GeneralRegs[FAST486_REG_EDI].Long -= (Processed - 1) * DataSize;
+                else State->GeneralRegs[FAST486_REG_EDI].LowWord -= (Processed - 1) * DataSize;
             }
 
             /* Write to memory */
@@ -5727,7 +5775,7 @@ FAST486_OPCODE_HANDLER(Fast486OpcodeStos)
                                     Processed * DataSize))
             {
                 /* Set ECX */
-                if (OperandSize) State->GeneralRegs[FAST486_REG_ECX].Long = Count;
+                if (AddressSize) State->GeneralRegs[FAST486_REG_ECX].Long = Count;
                 else State->GeneralRegs[FAST486_REG_ECX].LowWord = LOWORD(Count);
 
                 /* Exception occurred */
@@ -5740,13 +5788,19 @@ FAST486_OPCODE_HANDLER(Fast486OpcodeStos)
                 if (AddressSize) State->GeneralRegs[FAST486_REG_EDI].Long += Processed * DataSize;
                 else State->GeneralRegs[FAST486_REG_EDI].LowWord += Processed * DataSize;
             }
+            else
+            {
+                /* Reduce EDI */
+                if (AddressSize) State->GeneralRegs[FAST486_REG_EDI].Long -= DataSize;
+                else State->GeneralRegs[FAST486_REG_EDI].LowWord -= DataSize;
+            }
 
             /* Reduce the total count by the number processed in this run */
             Count -= Processed;
         }
 
         /* Clear ECX */
-        if (OperandSize) State->GeneralRegs[FAST486_REG_ECX].Long = 0;
+        if (AddressSize) State->GeneralRegs[FAST486_REG_ECX].Long = 0;
         else State->GeneralRegs[FAST486_REG_ECX].LowWord = 0;
     }
     else
@@ -5764,7 +5818,7 @@ FAST486_OPCODE_HANDLER(Fast486OpcodeStos)
         }
 
         /* Increment/decrement EDI */
-        if (OperandSize)
+        if (AddressSize)
         {
             if (!State->Flags.Df) State->GeneralRegs[FAST486_REG_EDI].Long += DataSize;
             else State->GeneralRegs[FAST486_REG_EDI].Long -= DataSize;
@@ -5806,7 +5860,7 @@ FAST486_OPCODE_HANDLER(Fast486OpcodeLods)
 
     if (State->PrefixFlags & FAST486_PREFIX_REP)
     {
-        ULONG Count = OperandSize ? State->GeneralRegs[FAST486_REG_ECX].Long
+        ULONG Count = AddressSize ? State->GeneralRegs[FAST486_REG_ECX].Long
                                   : State->GeneralRegs[FAST486_REG_ECX].LowWord;
 
         /* If the count is 0, do nothing */
@@ -5823,6 +5877,10 @@ FAST486_OPCODE_HANDLER(Fast486OpcodeLods)
             if (AddressSize) State->GeneralRegs[FAST486_REG_ESI].Long -= (Count - 1) * DataSize;
             else State->GeneralRegs[FAST486_REG_ESI].LowWord -= (Count - 1) * DataSize;
         }
+
+        /* Clear ECX */
+        if (AddressSize) State->GeneralRegs[FAST486_REG_ECX].Long = 0;
+        else State->GeneralRegs[FAST486_REG_ECX].LowWord = 0;
     }
 
     /* Read from the source operand */
@@ -5839,7 +5897,7 @@ FAST486_OPCODE_HANDLER(Fast486OpcodeLods)
     }
 
     /* Increment/decrement ESI */
-    if (OperandSize)
+    if (AddressSize)
     {
         if (!State->Flags.Df) State->GeneralRegs[FAST486_REG_ESI].Long += DataSize;
         else State->GeneralRegs[FAST486_REG_ESI].Long -= DataSize;
@@ -5870,13 +5928,24 @@ FAST486_OPCODE_HANDLER(Fast486OpcodeScas)
     TOGGLE_OPSIZE(OperandSize);
     TOGGLE_ADSIZE(AddressSize);
 
+    if ((State->PrefixFlags & FAST486_PREFIX_REP)
+        || (State->PrefixFlags & FAST486_PREFIX_REPNZ))
+    {
+        if ((AddressSize && (State->GeneralRegs[FAST486_REG_ECX].Long == 0))
+            || (!AddressSize && (State->GeneralRegs[FAST486_REG_ECX].LowWord == 0)))
+        {
+            /* Do nothing */
+            return TRUE;
+        }
+    }
+
     /* Calculate the size */
     if (Opcode == 0xAE) DataSize = sizeof(UCHAR);
     else DataSize = OperandSize ? sizeof(ULONG) : sizeof(USHORT);
 
     /* Calculate the mask and sign flag */
-    DataMask = (1 << (DataSize * 8)) - 1;
     SignFlag = 1 << ((DataSize * 8) - 1);
+    DataMask = SignFlag | (SignFlag - 1);
 
     /* Read from the source operand */
     if (!Fast486ReadMemory(State,
@@ -5897,16 +5966,16 @@ FAST486_OPCODE_HANDLER(Fast486OpcodeScas)
     Result = (FirstValue - SecondValue) & DataMask;
 
     /* Update the flags */
-    State->Flags.Cf = FirstValue < SecondValue;
+    State->Flags.Cf = (FirstValue < SecondValue);
     State->Flags.Of = ((FirstValue & SignFlag) != (SecondValue & SignFlag))
                       && ((FirstValue & SignFlag) != (Result & SignFlag));
     State->Flags.Af = (FirstValue & 0x0F) < (SecondValue & 0x0F);
-    State->Flags.Zf = (Result == 0) ? TRUE : FALSE;
-    State->Flags.Sf = (Result & SignFlag) ? TRUE : FALSE;
+    State->Flags.Zf = (Result == 0);
+    State->Flags.Sf = ((Result & SignFlag) != 0);
     State->Flags.Pf = Fast486CalculateParity(Result);
 
     /* Increment/decrement EDI */
-    if (OperandSize)
+    if (AddressSize)
     {
         if (!State->Flags.Df) State->GeneralRegs[FAST486_REG_EDI].Long += DataSize;
         else State->GeneralRegs[FAST486_REG_EDI].Long -= DataSize;
@@ -5922,8 +5991,8 @@ FAST486_OPCODE_HANDLER(Fast486OpcodeScas)
         || (State->PrefixFlags & FAST486_PREFIX_REPNZ))
     {
         BOOLEAN Repeat = TRUE;
-        
-        if (OperandSize)
+
+        if (AddressSize)
         {
             if ((--State->GeneralRegs[FAST486_REG_ECX].Long) == 0)
             {
@@ -5978,7 +6047,7 @@ FAST486_OPCODE_HANDLER(Fast486OpcodeIns)
     if (State->PrefixFlags & FAST486_PREFIX_REP)
     {
         UCHAR Block[STRING_BLOCK_SIZE];
-        ULONG Count = OperandSize ? State->GeneralRegs[FAST486_REG_ECX].Long
+        ULONG Count = AddressSize ? State->GeneralRegs[FAST486_REG_ECX].Long
                                   : State->GeneralRegs[FAST486_REG_ECX].LowWord;
 
         /* Clear the memory block */
@@ -6004,7 +6073,8 @@ FAST486_OPCODE_HANDLER(Fast486OpcodeIns)
             State->IoReadCallback(State,
                                   State->GeneralRegs[FAST486_REG_EDX].LowWord,
                                   Block,
-                                  Processed * DataSize);
+                                  Processed,
+                                  DataSize);
 
             if (State->Flags.Df)
             {
@@ -6036,7 +6106,7 @@ FAST486_OPCODE_HANDLER(Fast486OpcodeIns)
                                     Processed * DataSize))
             {
                 /* Set ECX */
-                if (OperandSize) State->GeneralRegs[FAST486_REG_ECX].Long = Count;
+                if (AddressSize) State->GeneralRegs[FAST486_REG_ECX].Long = Count;
                 else State->GeneralRegs[FAST486_REG_ECX].LowWord = LOWORD(Count);
 
                 /* Exception occurred */
@@ -6055,7 +6125,7 @@ FAST486_OPCODE_HANDLER(Fast486OpcodeIns)
         }
 
         /* Clear ECX */
-        if (OperandSize) State->GeneralRegs[FAST486_REG_ECX].Long = 0;
+        if (AddressSize) State->GeneralRegs[FAST486_REG_ECX].Long = 0;
         else State->GeneralRegs[FAST486_REG_ECX].LowWord = 0;
     }
     else
@@ -6066,6 +6136,7 @@ FAST486_OPCODE_HANDLER(Fast486OpcodeIns)
         State->IoReadCallback(State,
                               State->GeneralRegs[FAST486_REG_EDX].LowWord,
                               &Data,
+                              1,
                               DataSize);
 
         /* Write to the destination operand */
@@ -6081,7 +6152,7 @@ FAST486_OPCODE_HANDLER(Fast486OpcodeIns)
         }
 
         /* Increment/decrement EDI */
-        if (OperandSize)
+        if (AddressSize)
         {
             if (!State->Flags.Df) State->GeneralRegs[FAST486_REG_EDI].Long += DataSize;
             else State->GeneralRegs[FAST486_REG_EDI].Long -= DataSize;
@@ -6117,7 +6188,7 @@ FAST486_OPCODE_HANDLER(Fast486OpcodeOuts)
     if (State->PrefixFlags & FAST486_PREFIX_REP)
     {
         UCHAR Block[STRING_BLOCK_SIZE];
-        ULONG Count = OperandSize ? State->GeneralRegs[FAST486_REG_ECX].Long
+        ULONG Count = AddressSize ? State->GeneralRegs[FAST486_REG_ECX].Long
                                   : State->GeneralRegs[FAST486_REG_ECX].LowWord;
 
         /* Clear the memory block */
@@ -6149,7 +6220,7 @@ FAST486_OPCODE_HANDLER(Fast486OpcodeOuts)
                                    Processed * DataSize))
             {
                 /* Set ECX */
-                if (OperandSize) State->GeneralRegs[FAST486_REG_ECX].Long = Count;
+                if (AddressSize) State->GeneralRegs[FAST486_REG_ECX].Long = Count;
                 else State->GeneralRegs[FAST486_REG_ECX].LowWord = LOWORD(Count);
 
                 /* Exception occurred */
@@ -6181,7 +6252,8 @@ FAST486_OPCODE_HANDLER(Fast486OpcodeOuts)
             State->IoWriteCallback(State,
                                    State->GeneralRegs[FAST486_REG_EDX].LowWord,
                                    Block,
-                                   Processed * DataSize);
+                                   Processed,
+                                   DataSize);
 
             if (!State->Flags.Df)
             {
@@ -6195,7 +6267,7 @@ FAST486_OPCODE_HANDLER(Fast486OpcodeOuts)
         }
 
         /* Clear ECX */
-        if (OperandSize) State->GeneralRegs[FAST486_REG_ECX].Long = 0;
+        if (AddressSize) State->GeneralRegs[FAST486_REG_ECX].Long = 0;
         else State->GeneralRegs[FAST486_REG_ECX].LowWord = 0;
     }
     else
@@ -6219,10 +6291,11 @@ FAST486_OPCODE_HANDLER(Fast486OpcodeOuts)
         State->IoWriteCallback(State,
                                State->GeneralRegs[FAST486_REG_EDX].LowWord,
                                &Data,
+                               1,
                                DataSize);
 
         /* Increment/decrement ESI */
-        if (OperandSize)
+        if (AddressSize)
         {
             if (!State->Flags.Df) State->GeneralRegs[FAST486_REG_ESI].Long += DataSize;
             else State->GeneralRegs[FAST486_REG_ESI].Long -= DataSize;