[FAST486]
[reactos.git] / reactos / lib / fast486 / opcodes.c
index 1a8f126..b9d198f 100644 (file)
@@ -2,7 +2,7 @@
  * Fast486 386/486 CPU Emulation Library
  * opcodes.c
  *
- * Copyright (C) 2013 Aleksandar Andrejevic <theflash AT sdf DOT lonestar DOT org>
+ * Copyright (C) 2014 Aleksandar Andrejevic <theflash AT sdf DOT lonestar DOT org>
  *
  * This program is free software; you can redistribute it and/or
  * modify it under the terms of the GNU General Public License
 FAST486_OPCODE_HANDLER_PROC
 Fast486OpcodeHandlers[FAST486_NUM_OPCODE_HANDLERS] =
 {
-    Fast486OpcodeAddByteModrm,
+    Fast486OpcodeAddByteModrm,          /* 0x00 - 0x03 */
     Fast486OpcodeAddModrm,
     Fast486OpcodeAddByteModrm,
     Fast486OpcodeAddModrm,
-    Fast486OpcodeAddAl,
-    Fast486OpcodeAddEax,
-    Fast486OpcodePushEs,
-    Fast486OpcodePopEs,
-    Fast486OpcodeOrByteModrm,
+    Fast486OpcodeAddAl,                 /* 0x04 */
+    Fast486OpcodeAddEax,                /* 0x05 */
+    Fast486OpcodePushEs,                /* 0x06 */
+    Fast486OpcodePopEs,                 /* 0x07 */
+    Fast486OpcodeOrByteModrm,           /* 0x08 - 0x0B */
     Fast486OpcodeOrModrm,
     Fast486OpcodeOrByteModrm,
     Fast486OpcodeOrModrm,
-    Fast486OpcodeOrAl,
-    Fast486OpcodeOrEax,
-    Fast486OpcodePushCs,
-    Fast486OpcodeExtended,
-    Fast486OpcodeAdcByteModrm,
+    Fast486OpcodeOrAl,                  /* 0x0C */
+    Fast486OpcodeOrEax,                 /* 0x0D */
+    Fast486OpcodePushCs,                /* 0x0E */
+    Fast486OpcodeExtended,              /* 0x0F */
+    Fast486OpcodeAdcByteModrm,          /* 0x10 - 0x13 */
     Fast486OpcodeAdcModrm,
     Fast486OpcodeAdcByteModrm,
     Fast486OpcodeAdcModrm,
-    Fast486OpcodeAdcAl,
-    Fast486OpcodeAdcEax,
-    Fast486OpcodePushSs,
-    Fast486OpcodePopSs,
-    Fast486OpcodeSbbByteModrm,
+    Fast486OpcodeAdcAl,                 /* 0x14 */
+    Fast486OpcodeAdcEax,                /* 0x15 */
+    Fast486OpcodePushSs,                /* 0x16 */
+    Fast486OpcodePopSs,                 /* 0x17 */
+    Fast486OpcodeSbbByteModrm,          /* 0x18 - 0x1B */
     Fast486OpcodeSbbModrm,
     Fast486OpcodeSbbByteModrm,
     Fast486OpcodeSbbModrm,
-    Fast486OpcodeSbbAl,
-    Fast486OpcodeSbbEax,
-    Fast486OpcodePushDs,
-    Fast486OpcodePopDs,
-    Fast486OpcodeAndByteModrm,
+    Fast486OpcodeSbbAl,                 /* 0x1C */
+    Fast486OpcodeSbbEax,                /* 0x1D */
+    Fast486OpcodePushDs,                /* 0x1E */
+    Fast486OpcodePopDs,                 /* 0x1F */
+    Fast486OpcodeAndByteModrm,          /* 0x20 - 0x23 */
     Fast486OpcodeAndModrm,
     Fast486OpcodeAndByteModrm,
     Fast486OpcodeAndModrm,
-    Fast486OpcodeAndAl,
-    Fast486OpcodeAndEax,
-    Fast486OpcodePrefix,
-    Fast486OpcodeDaa,
-    Fast486OpcodeCmpSubByteModrm,
+    Fast486OpcodeAndAl,                 /* 0x24 */
+    Fast486OpcodeAndEax,                /* 0x25 */
+    Fast486OpcodePrefix,                /* 0x26 */
+    Fast486OpcodeDaa,                   /* 0x27 */
+    Fast486OpcodeCmpSubByteModrm,       /* 0x28 - 0x2B */
     Fast486OpcodeCmpSubModrm,
     Fast486OpcodeCmpSubByteModrm,
     Fast486OpcodeCmpSubModrm,
-    Fast486OpcodeCmpSubAl,
-    Fast486OpcodeCmpSubEax,
-    Fast486OpcodePrefix,
-    Fast486OpcodeDas,
-    Fast486OpcodeXorByteModrm,
+    Fast486OpcodeCmpSubAl,              /* 0x2C */
+    Fast486OpcodeCmpSubEax,             /* 0x2D */
+    Fast486OpcodePrefix,                /* 0x2E */
+    Fast486OpcodeDas,                   /* 0x2F */
+    Fast486OpcodeXorByteModrm,          /* 0x30 - 0x33 */
     Fast486OpcodeXorModrm,
     Fast486OpcodeXorByteModrm,
     Fast486OpcodeXorModrm,
-    Fast486OpcodeXorAl,
-    Fast486OpcodeXorEax,
-    Fast486OpcodePrefix,
-    Fast486OpcodeAaa,
-    Fast486OpcodeCmpSubByteModrm,
+    Fast486OpcodeXorAl,                 /* 0x34 */
+    Fast486OpcodeXorEax,                /* 0x35 */
+    Fast486OpcodePrefix,                /* 0x36 */
+    Fast486OpcodeAaa,                   /* 0x37 */
+    Fast486OpcodeCmpSubByteModrm,       /* 0x38 - 0x3B */
     Fast486OpcodeCmpSubModrm,
     Fast486OpcodeCmpSubByteModrm,
     Fast486OpcodeCmpSubModrm,
-    Fast486OpcodeCmpSubAl,
-    Fast486OpcodeCmpSubEax,
-    Fast486OpcodePrefix,
-    Fast486OpcodeAas,
+    Fast486OpcodeCmpSubAl,              /* 0x3C */
+    Fast486OpcodeCmpSubEax,             /* 0x3D */
+    Fast486OpcodePrefix,                /* 0x3E */
+    Fast486OpcodeAas,                   /* 0x3F */
+    Fast486OpcodeIncrement,             /* 0x40 - 0x47 */
     Fast486OpcodeIncrement,
     Fast486OpcodeIncrement,
     Fast486OpcodeIncrement,
@@ -109,8 +110,7 @@ Fast486OpcodeHandlers[FAST486_NUM_OPCODE_HANDLERS] =
     Fast486OpcodeIncrement,
     Fast486OpcodeIncrement,
     Fast486OpcodeIncrement,
-    Fast486OpcodeIncrement,
-    Fast486OpcodeDecrement,
+    Fast486OpcodeDecrement,             /* 0x48 - 0x4F */
     Fast486OpcodeDecrement,
     Fast486OpcodeDecrement,
     Fast486OpcodeDecrement,
@@ -118,6 +118,7 @@ Fast486OpcodeHandlers[FAST486_NUM_OPCODE_HANDLERS] =
     Fast486OpcodeDecrement,
     Fast486OpcodeDecrement,
     Fast486OpcodeDecrement,
+    Fast486OpcodePushReg,               /* 0x50 - 0x57 */
     Fast486OpcodePushReg,
     Fast486OpcodePushReg,
     Fast486OpcodePushReg,
@@ -125,7 +126,7 @@ Fast486OpcodeHandlers[FAST486_NUM_OPCODE_HANDLERS] =
     Fast486OpcodePushReg,
     Fast486OpcodePushReg,
     Fast486OpcodePushReg,
-    Fast486OpcodePushReg,
+    Fast486OpcodePopReg,                /* 0x58 - 0x5F */
     Fast486OpcodePopReg,
     Fast486OpcodePopReg,
     Fast486OpcodePopReg,
@@ -133,23 +134,23 @@ Fast486OpcodeHandlers[FAST486_NUM_OPCODE_HANDLERS] =
     Fast486OpcodePopReg,
     Fast486OpcodePopReg,
     Fast486OpcodePopReg,
-    Fast486OpcodePopReg,
-    Fast486OpcodePushAll,
-    Fast486OpcodePopAll,
-    Fast486OpcodeBound,
-    Fast486OpcodeArpl,
-    Fast486OpcodePrefix,
+    Fast486OpcodePushAll,               /* 0x60 */
+    Fast486OpcodePopAll,                /* 0x61 */
+    Fast486OpcodeBound,                 /* 0x62 */
+    Fast486OpcodeArpl,                  /* 0x63 */
+    Fast486OpcodePrefix,                /* 0x64 - 0x67 */
     Fast486OpcodePrefix,
     Fast486OpcodePrefix,
     Fast486OpcodePrefix,
-    Fast486OpcodePushImm,
-    Fast486OpcodeImulModrmImm,
-    Fast486OpcodePushByteImm,
-    Fast486OpcodeImulModrmImm,
-    Fast486OpcodeIns,
-    Fast486OpcodeIns,
-    Fast486OpcodeOuts,
-    Fast486OpcodeOuts,
+    Fast486OpcodePushImm,               /* 0x68 */
+    Fast486OpcodeImulModrmImm,          /* 0x69 */
+    Fast486OpcodePushByteImm,           /* 0x6A */
+    Fast486OpcodeImulModrmImm,          /* 0x6B */
+    Fast486OpcodeIns,                   /* 0x6C */
+    Fast486OpcodeIns,                   /* 0x6D */
+    Fast486OpcodeOuts,                  /* 0x6E */
+    Fast486OpcodeOuts,                  /* 0x6F */
+    Fast486OpcodeShortConditionalJmp,   /* 0x70 - 0x7F */
     Fast486OpcodeShortConditionalJmp,
     Fast486OpcodeShortConditionalJmp,
     Fast486OpcodeShortConditionalJmp,
@@ -165,55 +166,55 @@ Fast486OpcodeHandlers[FAST486_NUM_OPCODE_HANDLERS] =
     Fast486OpcodeShortConditionalJmp,
     Fast486OpcodeShortConditionalJmp,
     Fast486OpcodeShortConditionalJmp,
-    Fast486OpcodeShortConditionalJmp,
-    Fast486OpcodeGroup8082,
-    Fast486OpcodeGroup81,
-    Fast486OpcodeGroup8082,
-    Fast486OpcodeGroup83,
-    Fast486OpcodeTestByteModrm,
-    Fast486OpcodeTestModrm,
-    Fast486OpcodeXchgByteModrm,
-    Fast486OpcodeXchgModrm,
-    Fast486OpcodeMovByteModrm,
-    Fast486OpcodeMovModrm,
-    Fast486OpcodeMovByteModrm,
-    Fast486OpcodeMovModrm,
-    Fast486OpcodeMovStoreSeg,
-    Fast486OpcodeLea,
-    Fast486OpcodeMovLoadSeg,
-    Fast486OpcodeGroup8F,
-    Fast486OpcodeNop,
-    Fast486OpcodeExchangeEax,
+    Fast486OpcodeGroup8082,             /* 0x80 */
+    Fast486OpcodeGroup81,               /* 0x81 */
+    Fast486OpcodeGroup8082,             /* 0x82 */
+    Fast486OpcodeGroup83,               /* 0x83 */
+    Fast486OpcodeTestByteModrm,         /* 0x84 */
+    Fast486OpcodeTestModrm,             /* 0x85 */
+    Fast486OpcodeXchgByteModrm,         /* 0x86 */
+    Fast486OpcodeXchgModrm,             /* 0x87 */
+    Fast486OpcodeMovByteModrm,          /* 0x88 */
+    Fast486OpcodeMovModrm,              /* 0x89 */
+    Fast486OpcodeMovByteModrm,          /* 0x8A */
+    Fast486OpcodeMovModrm,              /* 0x8B */
+    Fast486OpcodeMovStoreSeg,           /* 0x8C */
+    Fast486OpcodeLea,                   /* 0x8D */
+    Fast486OpcodeMovLoadSeg,            /* 0x8E */
+    Fast486OpcodeGroup8F,               /* 0x8F */
+    Fast486OpcodeNop,                   /* 0x90 */
+    Fast486OpcodeExchangeEax,           /* 0x91 - 0x97 */
     Fast486OpcodeExchangeEax,
     Fast486OpcodeExchangeEax,
     Fast486OpcodeExchangeEax,
     Fast486OpcodeExchangeEax,
     Fast486OpcodeExchangeEax,
     Fast486OpcodeExchangeEax,
-    Fast486OpcodeCwde,
-    Fast486OpcodeCdq,
-    Fast486OpcodeCallAbs,
-    Fast486OpcodeWait,
-    Fast486OpcodePushFlags,
-    Fast486OpcodePopFlags,
-    Fast486OpcodeSahf,
-    Fast486OpcodeLahf,
-    Fast486OpcodeMovAlOffset,
-    Fast486OpcodeMovEaxOffset,
-    Fast486OpcodeMovOffsetAl,
-    Fast486OpcodeMovOffsetEax,
-    Fast486OpcodeMovs,
-    Fast486OpcodeMovs,
-    Fast486OpcodeCmps,
-    Fast486OpcodeCmps,
-    Fast486OpcodeTestAl,
-    Fast486OpcodeTestEax,
-    Fast486OpcodeStos,
-    Fast486OpcodeStos,
-    Fast486OpcodeLods,
-    Fast486OpcodeLods,
-    Fast486OpcodeScas,
-    Fast486OpcodeScas,
+    Fast486OpcodeCwde,                  /* 0x98 */
+    Fast486OpcodeCdq,                   /* 0x99 */
+    Fast486OpcodeCallAbs,               /* 0x9A */
+    Fast486OpcodeWait,                  /* 0x9B */
+    Fast486OpcodePushFlags,             /* 0x9C */
+    Fast486OpcodePopFlags,              /* 0x9D */
+    Fast486OpcodeSahf,                  /* 0x9E */
+    Fast486OpcodeLahf,                  /* 0x9F */
+    Fast486OpcodeMovAlOffset,           /* 0xA0 */
+    Fast486OpcodeMovEaxOffset,          /* 0xA1 */
+    Fast486OpcodeMovOffsetAl,           /* 0xA2 */
+    Fast486OpcodeMovOffsetEax,          /* 0xA3 */
+    Fast486OpcodeMovs,                  /* 0xA4 */
+    Fast486OpcodeMovs,                  /* 0xA5 */
+    Fast486OpcodeCmps,                  /* 0xA6 */
+    Fast486OpcodeCmps,                  /* 0xA7 */
+    Fast486OpcodeTestAl,                /* 0xA8 */
+    Fast486OpcodeTestEax,               /* 0xA9 */
+    Fast486OpcodeStos,                  /* 0xAA */
+    Fast486OpcodeStos,                  /* 0xAB */
+    Fast486OpcodeLods,                  /* 0xAC */
+    Fast486OpcodeLods,                  /* 0xAD */
+    Fast486OpcodeScas,                  /* 0xAE */
+    Fast486OpcodeScas,                  /* 0xAF */
+    Fast486OpcodeMovByteRegImm,         /* 0xB0 - 0xB7 */
     Fast486OpcodeMovByteRegImm,
     Fast486OpcodeMovByteRegImm,
     Fast486OpcodeMovByteRegImm,
@@ -221,8 +222,7 @@ Fast486OpcodeHandlers[FAST486_NUM_OPCODE_HANDLERS] =
     Fast486OpcodeMovByteRegImm,
     Fast486OpcodeMovByteRegImm,
     Fast486OpcodeMovByteRegImm,
-    Fast486OpcodeMovByteRegImm,
-    Fast486OpcodeMovRegImm,
+    Fast486OpcodeMovRegImm,             /* 0xB8 - 0xBF */
     Fast486OpcodeMovRegImm,
     Fast486OpcodeMovRegImm,
     Fast486OpcodeMovRegImm,
@@ -230,74 +230,81 @@ Fast486OpcodeHandlers[FAST486_NUM_OPCODE_HANDLERS] =
     Fast486OpcodeMovRegImm,
     Fast486OpcodeMovRegImm,
     Fast486OpcodeMovRegImm,
-    Fast486OpcodeGroupC0,
-    Fast486OpcodeGroupC1,
-    Fast486OpcodeRet,
-    Fast486OpcodeRet,
-    Fast486OpcodeLdsLes,
-    Fast486OpcodeLdsLes,
-    Fast486OpcodeGroupC6,
-    Fast486OpcodeGroupC7,
-    Fast486OpcodeEnter,
-    Fast486OpcodeLeave,
-    Fast486OpcodeRetFar,
-    Fast486OpcodeRetFar,
-    Fast486OpcodeInt,
-    Fast486OpcodeInt,
-    Fast486OpcodeInt,
-    Fast486OpcodeIret,
-    Fast486OpcodeGroupD0,
+    Fast486OpcodeGroupC0,               /* 0xC0 */
+    Fast486OpcodeGroupC1,               /* 0xC1 */
+    Fast486OpcodeRet,                   /* 0xC2 */
+    Fast486OpcodeRet,                   /* 0xC3 */
+    Fast486OpcodeLdsLes,                /* 0xC4 */
+    Fast486OpcodeLdsLes,                /* 0xC5 */
+    Fast486OpcodeGroupC6,               /* 0xC6 */
+    Fast486OpcodeGroupC7,               /* 0xC7 */
+    Fast486OpcodeEnter,                 /* 0xC8 */
+    Fast486OpcodeLeave,                 /* 0xC9 */
+    Fast486OpcodeRetFar,                /* 0xCA */
+    Fast486OpcodeRetFar,                /* 0xCB */
+    Fast486OpcodeInt,                   /* 0xCC */
+    Fast486OpcodeInt,                   /* 0xCD */
+    Fast486OpcodeInt,                   /* 0xCE */
+    Fast486OpcodeIret,                  /* 0xCF */
+    Fast486OpcodeGroupD0,               /* 0xD0 - 0xD3 */
     Fast486OpcodeGroupD1,
     Fast486OpcodeGroupD2,
     Fast486OpcodeGroupD3,
-    Fast486OpcodeAam,
-    Fast486OpcodeAad,
-    Fast486OpcodeSalc,
-    Fast486OpcodeXlat,
-    Fast486FpuOpcodeD8,
+    Fast486OpcodeAam,                   /* 0xD4 */
+    Fast486OpcodeAad,                   /* 0xD5 */
+    Fast486OpcodeSalc,                  /* 0xD6 */
+    Fast486OpcodeXlat,                  /* 0xD7 */
+    Fast486FpuOpcodeD8DC,               /* 0xD8 - 0xDF */
     Fast486FpuOpcodeD9,
     Fast486FpuOpcodeDA,
     Fast486FpuOpcodeDB,
-    Fast486FpuOpcodeDC,
+    Fast486FpuOpcodeD8DC,
     Fast486FpuOpcodeDD,
     Fast486FpuOpcodeDE,
     Fast486FpuOpcodeDF,
+    Fast486OpcodeLoop,                  /* 0xE0 - 0xE2 */
     Fast486OpcodeLoop,
     Fast486OpcodeLoop,
-    Fast486OpcodeLoop,
-    Fast486OpcodeJecxz,
-    Fast486OpcodeInByte,
-    Fast486OpcodeIn,
-    Fast486OpcodeOutByte,
-    Fast486OpcodeOut,
-    Fast486OpcodeCall,
-    Fast486OpcodeJmp,
-    Fast486OpcodeJmpAbs,
-    Fast486OpcodeShortJump,
-    Fast486OpcodeInByte,
-    Fast486OpcodeIn,
-    Fast486OpcodeOutByte,
-    Fast486OpcodeOut,
-    Fast486OpcodePrefix,
-    NULL, // Invalid
-    Fast486OpcodePrefix,
-    Fast486OpcodePrefix,
-    Fast486OpcodeHalt,
-    Fast486OpcodeComplCarry,
-    Fast486OpcodeGroupF6,
-    Fast486OpcodeGroupF7,
-    Fast486OpcodeClearCarry,
-    Fast486OpcodeSetCarry,
-    Fast486OpcodeClearInt,
-    Fast486OpcodeSetInt,
-    Fast486OpcodeClearDir,
-    Fast486OpcodeSetDir,
-    Fast486OpcodeGroupFE,
-    Fast486OpcodeGroupFF,
+    Fast486OpcodeJecxz,                 /* 0xE3 */
+    Fast486OpcodeInByte,                /* 0xE4 */
+    Fast486OpcodeIn,                    /* 0xE5 */
+    Fast486OpcodeOutByte,               /* 0xE6 */
+    Fast486OpcodeOut,                   /* 0xE7 */
+    Fast486OpcodeCall,                  /* 0xE8 */
+    Fast486OpcodeJmp,                   /* 0xE9 */
+    Fast486OpcodeJmpAbs,                /* 0xEA */
+    Fast486OpcodeShortJump,             /* 0xEB */
+    Fast486OpcodeInByte,                /* 0xEC */
+    Fast486OpcodeIn,                    /* 0xED */
+    Fast486OpcodeOutByte,               /* 0xEE */
+    Fast486OpcodeOut,                   /* 0xEF */
+    Fast486OpcodePrefix,                /* 0xF0 */
+    Fast486OpcodeInvalid,               /* 0xF1 */  // Invalid opcode
+    Fast486OpcodePrefix,                /* 0xF2 */
+    Fast486OpcodePrefix,                /* 0xF3 */
+    Fast486OpcodeHalt,                  /* 0xF4 */
+    Fast486OpcodeComplCarry,            /* 0xF5 */
+    Fast486OpcodeGroupF6,               /* 0xF6 */
+    Fast486OpcodeGroupF7,               /* 0xF7 */
+    Fast486OpcodeClearCarry,            /* 0xF8 */
+    Fast486OpcodeSetCarry,              /* 0xF9 */
+    Fast486OpcodeClearInt,              /* 0xFA */
+    Fast486OpcodeSetInt,                /* 0xFB */
+    Fast486OpcodeClearDir,              /* 0xFC */
+    Fast486OpcodeSetDir,                /* 0xFD */
+    Fast486OpcodeGroupFE,               /* 0xFE */
+    Fast486OpcodeGroupFF,               /* 0xFF */
 };
 
 /* PUBLIC FUNCTIONS ***********************************************************/
 
+FAST486_OPCODE_HANDLER(Fast486OpcodeInvalid)
+{
+    /* This is not a valid opcode */
+    Fast486Exception(State, FAST486_EXCEPTION_UD);
+    return FALSE;
+}
+
 FAST486_OPCODE_HANDLER(Fast486OpcodePrefix)
 {
     BOOLEAN Valid = FALSE;
@@ -3702,9 +3709,9 @@ FAST486_OPCODE_HANDLER(Fast486OpcodePushImm)
     }
     else
     {
-        USHORT Data;
+        SHORT Data;
 
-        if (!Fast486FetchWord(State, &Data))
+        if (!Fast486FetchWord(State, (PUSHORT)&Data))
         {
             /* Exception occurred */
             return FALSE;
@@ -3837,12 +3844,12 @@ FAST486_OPCODE_HANDLER(Fast486OpcodeImulModrmImm)
 
 FAST486_OPCODE_HANDLER(Fast486OpcodePushByteImm)
 {
-    UCHAR Data;
+    CHAR Data;
 
     /* Make sure this is the right instruction */
     ASSERT(Opcode == 0x6A);
 
-    if (!Fast486FetchByte(State, &Data))
+    if (!Fast486FetchByte(State, (PUCHAR)&Data))
     {
         /* Exception occurred */
         return FALSE;
@@ -4615,7 +4622,6 @@ FAST486_OPCODE_HANDLER(Fast486OpcodeRetFar)
 FAST486_OPCODE_HANDLER(Fast486OpcodeInt)
 {
     UCHAR IntNum;
-    FAST486_IDT_ENTRY IdtEntry;
 
     switch (Opcode)
     {
@@ -4656,24 +4662,8 @@ FAST486_OPCODE_HANDLER(Fast486OpcodeInt)
         }
     }
 
-    /* Get the interrupt vector */
-    if (!Fast486GetIntVector(State, IntNum, &IdtEntry))
-    {
-        /* Exception occurred */
-        return FALSE;
-    }
-
     /* Perform the interrupt */
-    if (!Fast486InterruptInternal(State,
-                                  IdtEntry.Selector,
-                                  MAKELONG(IdtEntry.Offset, IdtEntry.OffsetHigh),
-                                  IdtEntry.Type))
-    {
-        /* Exception occurred */
-        return FALSE;
-    }
-
-    return TRUE;
+    return Fast486PerformInterrupt(State, IntNum);
 }
 
 FAST486_OPCODE_HANDLER(Fast486OpcodeIret)
@@ -4956,7 +4946,8 @@ FAST486_OPCODE_HANDLER(Fast486OpcodeXlat)
 
     /* Read a byte from DS:[(E)BX + AL] */
     if (!Fast486ReadMemory(State,
-                           FAST486_REG_DS,
+                           (State->PrefixFlags & FAST486_PREFIX_SEG)
+                           ? State->SegmentOverride : FAST486_REG_DS,
                            (AddressSize ? State->GeneralRegs[FAST486_REG_EBX].Long
                                         : State->GeneralRegs[FAST486_REG_EBX].LowWord)
                            + State->GeneralRegs[FAST486_REG_EAX].LowByte,
@@ -5468,7 +5459,7 @@ FAST486_OPCODE_HANDLER(Fast486OpcodeMovs)
         Segment = State->SegmentOverride;
     }
 
-    if (State->PrefixFlags & FAST486_PREFIX_REP)
+    if (State->PrefixFlags & (FAST486_PREFIX_REP | FAST486_PREFIX_REPNZ))
     {
         if ((AddressSize && (State->GeneralRegs[FAST486_REG_ECX].Long == 0))
             || (!AddressSize && (State->GeneralRegs[FAST486_REG_ECX].LowWord == 0)))
@@ -5536,7 +5527,7 @@ FAST486_OPCODE_HANDLER(Fast486OpcodeMovs)
     }
 
     // FIXME: This method is slow!
-    if (State->PrefixFlags & FAST486_PREFIX_REP)
+    if (State->PrefixFlags & (FAST486_PREFIX_REP | FAST486_PREFIX_REPNZ))
     {
         if (AddressSize)
         {
@@ -5726,7 +5717,7 @@ FAST486_OPCODE_HANDLER(Fast486OpcodeStos)
     if (Opcode == 0xAA) DataSize = sizeof(UCHAR);
     else DataSize = OperandSize ? sizeof(ULONG) : sizeof(USHORT);
 
-    if (State->PrefixFlags & FAST486_PREFIX_REP)
+    if (State->PrefixFlags & (FAST486_PREFIX_REP | FAST486_PREFIX_REPNZ))
     {
         UCHAR Block[STRING_BLOCK_SIZE];
         ULONG Count = AddressSize ? State->GeneralRegs[FAST486_REG_ECX].Long
@@ -5869,7 +5860,7 @@ FAST486_OPCODE_HANDLER(Fast486OpcodeLods)
     if (Opcode == 0xAC) DataSize = sizeof(UCHAR);
     else DataSize = OperandSize ? sizeof(ULONG) : sizeof(USHORT);
 
-    if (State->PrefixFlags & FAST486_PREFIX_REP)
+    if (State->PrefixFlags & (FAST486_PREFIX_REP | FAST486_PREFIX_REPNZ))
     {
         ULONG Count = AddressSize ? State->GeneralRegs[FAST486_REG_ECX].Long
                                   : State->GeneralRegs[FAST486_REG_ECX].LowWord;
@@ -6055,7 +6046,7 @@ FAST486_OPCODE_HANDLER(Fast486OpcodeIns)
     if (Opcode == 0x6C) DataSize = sizeof(UCHAR);
     else DataSize = OperandSize ? sizeof(ULONG) : sizeof(USHORT);
 
-    if (State->PrefixFlags & FAST486_PREFIX_REP)
+    if (State->PrefixFlags & (FAST486_PREFIX_REP | FAST486_PREFIX_REPNZ))
     {
         UCHAR Block[STRING_BLOCK_SIZE];
         ULONG Count = AddressSize ? State->GeneralRegs[FAST486_REG_ECX].Long
@@ -6196,7 +6187,7 @@ FAST486_OPCODE_HANDLER(Fast486OpcodeOuts)
     if (Opcode == 0x6E) DataSize = sizeof(UCHAR);
     else DataSize = OperandSize ? sizeof(ULONG) : sizeof(USHORT);
 
-    if (State->PrefixFlags & FAST486_PREFIX_REP)
+    if (State->PrefixFlags & (FAST486_PREFIX_REP | FAST486_PREFIX_REPNZ))
     {
         UCHAR Block[STRING_BLOCK_SIZE];
         ULONG Count = AddressSize ? State->GeneralRegs[FAST486_REG_ECX].Long
@@ -6214,8 +6205,8 @@ FAST486_OPCODE_HANDLER(Fast486OpcodeOuts)
             if (!AddressSize)
             {
                 ULONG MaxBytes = State->Flags.Df
-                                 ? (ULONG)State->GeneralRegs[FAST486_REG_EDI].LowWord
-                                 : (0x10000 - (ULONG)State->GeneralRegs[FAST486_REG_EDI].LowWord);
+                                 ? (ULONG)State->GeneralRegs[FAST486_REG_ESI].LowWord
+                                 : (0x10000 - (ULONG)State->GeneralRegs[FAST486_REG_ESI].LowWord);
 
                 Processed = min(Processed, MaxBytes / DataSize);
                 if (Processed == 0) Processed = 1;
@@ -6223,9 +6214,10 @@ FAST486_OPCODE_HANDLER(Fast486OpcodeOuts)
 
             /* Read from memory */
             if (!Fast486ReadMemory(State,
-                                   FAST486_REG_ES,
-                                   AddressSize ? State->GeneralRegs[FAST486_REG_EDI].Long
-                                               : State->GeneralRegs[FAST486_REG_EDI].LowWord,
+                                   (State->PrefixFlags & FAST486_PREFIX_SEG)
+                                   ? State->SegmentOverride : FAST486_REG_DS,
+                                   AddressSize ? State->GeneralRegs[FAST486_REG_ESI].Long
+                                               : State->GeneralRegs[FAST486_REG_ESI].LowWord,
                                    FALSE,
                                    Block,
                                    Processed * DataSize))
@@ -6242,9 +6234,9 @@ FAST486_OPCODE_HANDLER(Fast486OpcodeOuts)
             {
                 ULONG i, j;
 
-                /* 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;
+                /* Reduce ESI by the number of bytes to transfer */
+                if (AddressSize) State->GeneralRegs[FAST486_REG_ESI].Long -= Processed * DataSize;
+                else State->GeneralRegs[FAST486_REG_ESI].LowWord -= Processed * DataSize;
 
                 /* Reverse the block data */
                 for (i = 0; i < Processed / 2; i++)
@@ -6268,9 +6260,9 @@ FAST486_OPCODE_HANDLER(Fast486OpcodeOuts)
 
             if (!State->Flags.Df)
             {
-                /* Increase EDI by the number of bytes transfered */
-                if (AddressSize) State->GeneralRegs[FAST486_REG_EDI].Long += Processed * DataSize;
-                else State->GeneralRegs[FAST486_REG_EDI].LowWord += Processed * DataSize;
+                /* Increase ESI by the number of bytes transfered */
+                if (AddressSize) State->GeneralRegs[FAST486_REG_ESI].Long += Processed * DataSize;
+                else State->GeneralRegs[FAST486_REG_ESI].LowWord += Processed * DataSize;
             }
 
             /* Reduce the total count by the number processed in this run */
@@ -6287,7 +6279,8 @@ FAST486_OPCODE_HANDLER(Fast486OpcodeOuts)
 
         /* Read from the source operand */
         if (!Fast486ReadMemory(State,
-                               FAST486_REG_DS,
+                               (State->PrefixFlags & FAST486_PREFIX_SEG)
+                               ? State->SegmentOverride : FAST486_REG_DS,
                                AddressSize ? State->GeneralRegs[FAST486_REG_ESI].Long
                                            : State->GeneralRegs[FAST486_REG_ESI].LowWord,
                                FALSE,