* 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
/* INCLUDES *******************************************************************/
-// #define WIN32_NO_STATUS
-// #define _INC_WINDOWS
#include <windef.h>
-#include <limits.h>
// #define NDEBUG
#include <debug.h>
#include "opgroups.h"
#include "extraops.h"
#include "common.h"
+#include "fpu.h"
/* PUBLIC VARIABLES ***********************************************************/
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,
Fast486OpcodeIncrement,
Fast486OpcodeIncrement,
Fast486OpcodeIncrement,
- Fast486OpcodeIncrement,
- Fast486OpcodeDecrement,
+ Fast486OpcodeDecrement, /* 0x48 - 0x4F */
Fast486OpcodeDecrement,
Fast486OpcodeDecrement,
Fast486OpcodeDecrement,
Fast486OpcodeDecrement,
Fast486OpcodeDecrement,
Fast486OpcodeDecrement,
+ Fast486OpcodePushReg, /* 0x50 - 0x57 */
Fast486OpcodePushReg,
Fast486OpcodePushReg,
Fast486OpcodePushReg,
Fast486OpcodePushReg,
Fast486OpcodePushReg,
Fast486OpcodePushReg,
- Fast486OpcodePushReg,
- Fast486OpcodePopReg,
+ Fast486OpcodePopReg, /* 0x58 - 0x5F */
Fast486OpcodePopReg,
Fast486OpcodePopReg,
Fast486OpcodePopReg,
Fast486OpcodePopReg,
Fast486OpcodePopReg,
Fast486OpcodePopReg,
- Fast486OpcodePushAll,
- Fast486OpcodePopAll,
- Fast486OpcodeBound,
- Fast486OpcodeArpl,
+ Fast486OpcodePushAll, /* 0x60 */
+ Fast486OpcodePopAll, /* 0x61 */
+ Fast486OpcodeBound, /* 0x62 */
+ Fast486OpcodeArpl, /* 0x63 */
+ Fast486OpcodePrefix, /* 0x64 - 0x67 */
Fast486OpcodePrefix,
Fast486OpcodePrefix,
Fast486OpcodePrefix,
- Fast486OpcodePrefix,
- Fast486OpcodePushImm,
- Fast486OpcodeImulModrmImm,
- Fast486OpcodePushByteImm,
- Fast486OpcodeImulModrmImm,
- Fast486OpcodeIns,
- Fast486OpcodeIns,
- Fast486OpcodeOuts,
- Fast486OpcodeOuts,
- Fast486OpcodeShortConditionalJmp,
+ Fast486OpcodePushImm, /* 0x68 */
+ Fast486OpcodeImulModrmImm, /* 0x69 */
+ Fast486OpcodePushByteImm, /* 0x6A */
+ Fast486OpcodeImulModrmImm, /* 0x6B */
+ Fast486OpcodeIns, /* 0x6C */
+ Fast486OpcodeIns, /* 0x6D */
+ Fast486OpcodeOuts, /* 0x6E */
+ Fast486OpcodeOuts, /* 0x6F */
+ Fast486OpcodeShortConditionalJmp, /* 0x70 - 0x7F */
Fast486OpcodeShortConditionalJmp,
Fast486OpcodeShortConditionalJmp,
Fast486OpcodeShortConditionalJmp,
Fast486OpcodeShortConditionalJmp,
Fast486OpcodeShortConditionalJmp,
Fast486OpcodeShortConditionalJmp,
- Fast486OpcodeGroup8082,
- Fast486OpcodeGroup81,
- Fast486OpcodeGroup8082,
- Fast486OpcodeGroup83,
- Fast486OpcodeTestByteModrm,
- Fast486OpcodeTestModrm,
- Fast486OpcodeXchgByteModrm,
- Fast486OpcodeXchgModrm,
- Fast486OpcodeMovByteModrm,
- Fast486OpcodeMovModrm,
- Fast486OpcodeMovByteModrm,
- Fast486OpcodeMovModrm,
- Fast486OpcodeMovStoreSeg,
- Fast486OpcodeLea,
- Fast486OpcodeMovLoadSeg,
- Fast486OpcodeGroup8F,
- Fast486OpcodeNop,
+ 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,
- 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,
- Fast486OpcodeMovByteRegImm,
+ 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,
Fast486OpcodeMovByteRegImm,
Fast486OpcodeMovByteRegImm,
Fast486OpcodeMovByteRegImm,
+ Fast486OpcodeMovRegImm, /* 0xB8 - 0xBF */
Fast486OpcodeMovRegImm,
Fast486OpcodeMovRegImm,
Fast486OpcodeMovRegImm,
Fast486OpcodeMovRegImm,
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,
- 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
- Fast486OpcodeLoop,
+ Fast486OpcodeAam, /* 0xD4 */
+ Fast486OpcodeAad, /* 0xD5 */
+ Fast486OpcodeSalc, /* 0xD6 */
+ Fast486OpcodeXlat, /* 0xD7 */
+ Fast486FpuOpcodeD8DC, /* 0xD8 - 0xDF */
+ Fast486FpuOpcodeD9,
+ Fast486FpuOpcodeDA,
+ Fast486FpuOpcodeDB,
+ Fast486FpuOpcodeD8DC,
+ Fast486FpuOpcodeDD,
+ Fast486FpuOpcodeDE,
+ Fast486FpuOpcodeDF,
+ Fast486OpcodeLoop, /* 0xE0 - 0xE2 */
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 -- ICEBP/INT01 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.
+ * Well, not totally: see http://www.rcollins.org/secrets/opcodes/ICEBP.html
+ * for more details.
+ */
+ DPRINT1("FAST486 -- Calling ICEBP opcode\n");
+ Fast486Exception(State, FAST486_EXCEPTION_UD);
+}
+
FAST486_OPCODE_HANDLER(Fast486OpcodePrefix)
{
BOOLEAN Valid = FALSE;
/* Throw an exception */
Fast486Exception(State, FAST486_EXCEPTION_UD);
- return FALSE;
}
-
- return TRUE;
}
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 */
- return TRUE;
}
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 */
- return TRUE;
}
FAST486_OPCODE_HANDLER(Fast486OpcodePushReg)
ASSERT((Opcode & 0xF8) == 0x50);
/* Call the internal function */
- return Fast486StackPush(State, State->GeneralRegs[Opcode & 0x07].Long);
+ Fast486StackPush(State, State->GeneralRegs[Opcode & 0x07].Long);
}
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();
ASSERT((Opcode & 0xF8) == 0x58);
/* Call the internal function */
- if (!Fast486StackPop(State, &Value)) return FALSE;
+ if (!Fast486StackPop(State, &Value)) return;
/* Store the value */
if (Size) State->GeneralRegs[Opcode & 0x07].Long = Value;
else State->GeneralRegs[Opcode & 0x07].LowWord = Value;
-
- /* Return success */
- return TRUE;
}
FAST486_OPCODE_HANDLER(Fast486OpcodeNop)
{
- if (State->PrefixFlags & FAST486_PREFIX_REP)
- {
- /* Idle cycle */
- State->IdleCallback(State);
- }
-
- return TRUE;
}
FAST486_OPCODE_HANDLER(Fast486OpcodeExchangeEax)
State->GeneralRegs[Reg].LowWord = State->GeneralRegs[FAST486_REG_EAX].LowWord;
State->GeneralRegs[FAST486_REG_EAX].LowWord = Value;
}
-
- return TRUE;
}
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))
{
/* An exception occurred */
- return FALSE;
+ return;
}
switch ((Opcode & 0x0F) >> 1)
if (Jump)
{
- /* Move the instruction pointer */
+ /* Move the instruction pointer */
State->InstPtr.Long += Offset;
- }
- /* Return success */
- return TRUE;
+ if (!Size)
+ {
+ /* Clear the top half of EIP */
+ State->InstPtr.Long &= 0xFFFF;
+ }
+ }
}
FAST486_OPCODE_HANDLER(Fast486OpcodeClearCarry)
if (State->PrefixFlags)
{
Fast486Exception(State, FAST486_EXCEPTION_UD);
- return FALSE;
+ return;
}
/* Clear CF and return success */
State->Flags.Cf = FALSE;
- return TRUE;
}
FAST486_OPCODE_HANDLER(Fast486OpcodeSetCarry)
if (State->PrefixFlags)
{
Fast486Exception(State, FAST486_EXCEPTION_UD);
- return FALSE;
+ return;
}
/* Set CF and return success*/
State->Flags.Cf = TRUE;
- return TRUE;
}
FAST486_OPCODE_HANDLER(Fast486OpcodeComplCarry)
if (State->PrefixFlags)
{
Fast486Exception(State, FAST486_EXCEPTION_UD);
- return FALSE;
+ return;
}
/* Toggle CF and return success */
State->Flags.Cf = !State->Flags.Cf;
- return TRUE;
+ return;
}
FAST486_OPCODE_HANDLER(Fast486OpcodeClearInt)
if (State->PrefixFlags)
{
Fast486Exception(State, FAST486_EXCEPTION_UD);
- return FALSE;
+ return;
}
/* Check for protected mode */
{
/* General Protection Fault */
Fast486Exception(State, FAST486_EXCEPTION_GP);
- return FALSE;
+ return;
}
}
else
/* Just clear the interrupt flag */
State->Flags.If = FALSE;
}
-
- /* Return success */
- return TRUE;
}
FAST486_OPCODE_HANDLER(Fast486OpcodeSetInt)
if (State->PrefixFlags)
{
Fast486Exception(State, FAST486_EXCEPTION_UD);
- return FALSE;
+ return;
}
/* Check for protected mode */
{
/* General Protection Fault */
Fast486Exception(State, FAST486_EXCEPTION_GP);
- return FALSE;
+ return;
}
}
else
/* Just set the interrupt flag */
State->Flags.If = TRUE;
}
-
- /* Return success */
- return TRUE;
}
FAST486_OPCODE_HANDLER(Fast486OpcodeClearDir)
if (State->PrefixFlags)
{
Fast486Exception(State, FAST486_EXCEPTION_UD);
- return FALSE;
+ return;
}
- /* Clear DF and return success */
+ /* Clear DF */
State->Flags.Df = FALSE;
- return TRUE;
}
FAST486_OPCODE_HANDLER(Fast486OpcodeSetDir)
if (State->PrefixFlags)
{
Fast486Exception(State, FAST486_EXCEPTION_UD);
- return FALSE;
+ return;
}
- /* Set DF and return success*/
+ /* Set DF */
State->Flags.Df = TRUE;
- return TRUE;
}
FAST486_OPCODE_HANDLER(Fast486OpcodeHalt)
if (State->PrefixFlags)
{
Fast486Exception(State, FAST486_EXCEPTION_UD);
- return FALSE;
+ return;
}
/* Privileged instructions can only be executed under CPL = 0 */
if (State->SegmentRegs[FAST486_REG_CS].Dpl != 0)
{
Fast486Exception(State, FAST486_EXCEPTION_GP);
- return FALSE;
+ return;
}
/* Halt */
- while (!State->HardwareInt) State->IdleCallback(State);
-
- /* Return success */
- return TRUE;
+ State->Halted = TRUE;
}
FAST486_OPCODE_HANDLER(Fast486OpcodeInByte)
if (!Fast486FetchByte(State, &Data))
{
/* Exception occurred */
- return FALSE;
+ return;
}
/* Set the port number to the parameter */
}
/* 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;
-
- return TRUE;
}
FAST486_OPCODE_HANDLER(Fast486OpcodeIn)
if (!Fast486FetchByte(State, &Data))
{
/* Exception occurred */
- return FALSE;
+ return;
}
/* Set the port number to the parameter */
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;
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;
}
-
- return TRUE;
}
FAST486_OPCODE_HANDLER(Fast486OpcodeOutByte)
if (!Fast486FetchByte(State, &Data))
{
/* Exception occurred */
- return FALSE;
+ return;
}
/* Set the port number to the parameter */
/* 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));
- return TRUE;
+ /* Write the byte to the I/O port */
+ State->IoWriteCallback(State, Port, &Data, 1, sizeof(UCHAR));
}
FAST486_OPCODE_HANDLER(Fast486OpcodeOut)
if (!Fast486FetchByte(State, &Data))
{
/* Exception occurred */
- return FALSE;
+ return;
}
/* Set the port number to the parameter */
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
{
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;
}
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);
if (!Fast486FetchByte(State, (PUCHAR)&Offset))
{
/* An exception occurred */
- return FALSE;
+ return;
}
- /* Move the instruction pointer */
+ /* Move the instruction pointer */
State->InstPtr.Long += Offset;
- return TRUE;
+ if (!Size)
+ {
+ /* Clear the top half of EIP */
+ State->InstPtr.Long &= 0xFFFF;
+ }
}
FAST486_OPCODE_HANDLER(Fast486OpcodeMovRegImm)
if (!Fast486FetchDword(State, &Value))
{
/* Exception occurred */
- return FALSE;
+ return;
}
/* Store the value in the register */
if (!Fast486FetchWord(State, &Value))
{
/* Exception occurred */
- return FALSE;
+ return;
}
/* Store the value in the register */
State->GeneralRegs[Opcode & 0x07].LowWord = Value;
}
-
- return TRUE;
}
FAST486_OPCODE_HANDLER(Fast486OpcodeMovByteRegImm)
{
/* Invalid prefix */
Fast486Exception(State, FAST486_EXCEPTION_UD);
- return FALSE;
+ return;
}
/* Fetch the byte */
if (!Fast486FetchByte(State, &Value))
{
/* Exception occurred */
- return FALSE;
+ return;
}
if (Opcode & 0x04)
/* AL, CL, DL or BL */
State->GeneralRegs[Opcode & 0x03].LowByte = Value;
}
-
- return TRUE;
}
FAST486_OPCODE_HANDLER(Fast486OpcodeAddByteModrm)
if (!Fast486ParseModRegRm(State, AddressSize, &ModRegRm))
{
/* Exception occurred */
- return FALSE;
+ return;
}
if (!Fast486ReadModrmByteOperands(State,
&SecondValue))
{
/* Exception occurred */
- return FALSE;
+ return;
}
/* Calculate the result */
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 */
- return Fast486WriteModrmByteOperands(State,
- &ModRegRm,
- Opcode & FAST486_OPCODE_WRITE_REG,
- Result);
+ Fast486WriteModrmByteOperands(State,
+ &ModRegRm,
+ Opcode & FAST486_OPCODE_WRITE_REG,
+ Result);
}
FAST486_OPCODE_HANDLER(Fast486OpcodeAddModrm)
if (!Fast486ParseModRegRm(State, AddressSize, &ModRegRm))
{
/* Exception occurred */
- return FALSE;
+ return;
}
/* Check the operand size */
&SecondValue))
{
/* Exception occurred */
- return FALSE;
+ return;
}
-
+
/* Calculate the result */
Result = FirstValue + SecondValue;
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 */
- return Fast486WriteModrmDwordOperands(State,
- &ModRegRm,
- Opcode & FAST486_OPCODE_WRITE_REG,
- Result);
+ Fast486WriteModrmDwordOperands(State,
+ &ModRegRm,
+ Opcode & FAST486_OPCODE_WRITE_REG,
+ Result);
}
else
{
&SecondValue))
{
/* Exception occurred */
- return FALSE;
+ return;
}
-
+
/* Calculate the result */
Result = FirstValue + SecondValue;
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 */
- return Fast486WriteModrmWordOperands(State,
- &ModRegRm,
- Opcode & FAST486_OPCODE_WRITE_REG,
- Result);
+ Fast486WriteModrmWordOperands(State,
+ &ModRegRm,
+ Opcode & FAST486_OPCODE_WRITE_REG,
+ Result);
}
}
{
/* This opcode doesn't take any prefixes */
Fast486Exception(State, FAST486_EXCEPTION_UD);
- return FALSE;
+ return;
}
if (!Fast486FetchByte(State, &SecondValue))
{
/* Exception occurred */
- return FALSE;
+ return;
}
/* Calculate the result */
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 */
State->GeneralRegs[FAST486_REG_EAX].LowByte = Result;
-
- return TRUE;
}
FAST486_OPCODE_HANDLER(Fast486OpcodeAddEax)
if (!Fast486FetchDword(State, &SecondValue))
{
/* Exception occurred */
- return FALSE;
+ return;
}
/* Calculate the result */
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 */
if (!Fast486FetchWord(State, &SecondValue))
{
/* Exception occurred */
- return FALSE;
+ return;
}
/* Calculate the result */
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 */
State->GeneralRegs[FAST486_REG_EAX].LowWord = Result;
}
-
- return TRUE;
}
FAST486_OPCODE_HANDLER(Fast486OpcodeOrByteModrm)
if (!Fast486ParseModRegRm(State, AddressSize, &ModRegRm))
{
/* Exception occurred */
- return FALSE;
+ return;
}
if (!Fast486ReadModrmByteOperands(State,
&SecondValue))
{
/* Exception occurred */
- return FALSE;
+ return;
}
/* Calculate the result */
/* 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 */
- return Fast486WriteModrmByteOperands(State,
- &ModRegRm,
- Opcode & FAST486_OPCODE_WRITE_REG,
- Result);
+ Fast486WriteModrmByteOperands(State,
+ &ModRegRm,
+ Opcode & FAST486_OPCODE_WRITE_REG,
+ Result);
}
FAST486_OPCODE_HANDLER(Fast486OpcodeOrModrm)
if (!Fast486ParseModRegRm(State, AddressSize, &ModRegRm))
{
/* Exception occurred */
- return FALSE;
+ return;
}
/* Check the operand size */
&SecondValue))
{
/* Exception occurred */
- return FALSE;
+ return;
}
-
+
/* 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 */
- return Fast486WriteModrmDwordOperands(State,
- &ModRegRm,
- Opcode & FAST486_OPCODE_WRITE_REG,
- Result);
+ Fast486WriteModrmDwordOperands(State,
+ &ModRegRm,
+ Opcode & FAST486_OPCODE_WRITE_REG,
+ Result);
}
else
{
&SecondValue))
{
/* Exception occurred */
- return FALSE;
+ return;
}
-
+
/* 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 */
- return Fast486WriteModrmWordOperands(State,
- &ModRegRm,
- Opcode & FAST486_OPCODE_WRITE_REG,
- Result);
+ Fast486WriteModrmWordOperands(State,
+ &ModRegRm,
+ Opcode & FAST486_OPCODE_WRITE_REG,
+ Result);
}
}
{
/* This opcode doesn't take any prefixes */
Fast486Exception(State, FAST486_EXCEPTION_UD);
- return FALSE;
+ return;
}
if (!Fast486FetchByte(State, &SecondValue))
{
/* Exception occurred */
- return FALSE;
+ return;
}
/* Calculate the result */
/* 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 */
State->GeneralRegs[FAST486_REG_EAX].LowByte = Result;
-
- return TRUE;
}
FAST486_OPCODE_HANDLER(Fast486OpcodeOrEax)
if (!Fast486FetchDword(State, &SecondValue))
{
/* Exception occurred */
- return FALSE;
+ return;
}
/* Calculate the result */
/* 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 */
if (!Fast486FetchWord(State, &SecondValue))
{
/* Exception occurred */
- return FALSE;
+ return;
}
/* Calculate the result */
/* 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 */
State->GeneralRegs[FAST486_REG_EAX].LowWord = Result;
}
-
- return TRUE;
}
FAST486_OPCODE_HANDLER(Fast486OpcodeAndByteModrm)
if (!Fast486ParseModRegRm(State, AddressSize, &ModRegRm))
{
/* Exception occurred */
- return FALSE;
+ return;
}
if (!Fast486ReadModrmByteOperands(State,
&SecondValue))
{
/* Exception occurred */
- return FALSE;
+ return;
}
/* Calculate the result */
/* 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 */
- return Fast486WriteModrmByteOperands(State,
- &ModRegRm,
- Opcode & FAST486_OPCODE_WRITE_REG,
- Result);
+ Fast486WriteModrmByteOperands(State,
+ &ModRegRm,
+ Opcode & FAST486_OPCODE_WRITE_REG,
+ Result);
}
FAST486_OPCODE_HANDLER(Fast486OpcodeAndModrm)
if (!Fast486ParseModRegRm(State, AddressSize, &ModRegRm))
{
/* Exception occurred */
- return FALSE;
+ return;
}
/* Check the operand size */
&SecondValue))
{
/* Exception occurred */
- return FALSE;
+ return;
}
-
+
/* 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 */
- return Fast486WriteModrmDwordOperands(State,
- &ModRegRm,
- Opcode & FAST486_OPCODE_WRITE_REG,
- Result);
+ Fast486WriteModrmDwordOperands(State,
+ &ModRegRm,
+ Opcode & FAST486_OPCODE_WRITE_REG,
+ Result);
}
else
{
&SecondValue))
{
/* Exception occurred */
- return FALSE;
+ return;
}
-
+
/* 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 */
- return Fast486WriteModrmWordOperands(State,
- &ModRegRm,
- Opcode & FAST486_OPCODE_WRITE_REG,
- Result);
+ Fast486WriteModrmWordOperands(State,
+ &ModRegRm,
+ Opcode & FAST486_OPCODE_WRITE_REG,
+ Result);
}
}
if (!Fast486FetchByte(State, &SecondValue))
{
/* Exception occurred */
- return FALSE;
+ return;
}
/* Calculate the result */
/* 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 */
State->GeneralRegs[FAST486_REG_EAX].LowByte = Result;
-
- return TRUE;
}
FAST486_OPCODE_HANDLER(Fast486OpcodeAndEax)
if (!Fast486FetchDword(State, &SecondValue))
{
/* Exception occurred */
- return FALSE;
+ return;
}
/* Calculate the result */
/* 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 */
if (!Fast486FetchWord(State, &SecondValue))
{
/* Exception occurred */
- return FALSE;
+ return;
}
/* Calculate the result */
/* 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 */
State->GeneralRegs[FAST486_REG_EAX].LowWord = Result;
}
-
- return TRUE;
}
FAST486_OPCODE_HANDLER(Fast486OpcodeXorByteModrm)
if (!Fast486ParseModRegRm(State, AddressSize, &ModRegRm))
{
/* Exception occurred */
- return FALSE;
+ return;
}
if (!Fast486ReadModrmByteOperands(State,
&SecondValue))
{
/* Exception occurred */
- return FALSE;
+ return;
}
/* Calculate the result */
/* 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 */
- return Fast486WriteModrmByteOperands(State,
- &ModRegRm,
- Opcode & FAST486_OPCODE_WRITE_REG,
- Result);
+ Fast486WriteModrmByteOperands(State,
+ &ModRegRm,
+ Opcode & FAST486_OPCODE_WRITE_REG,
+ Result);
}
FAST486_OPCODE_HANDLER(Fast486OpcodeXorModrm)
if (!Fast486ParseModRegRm(State, AddressSize, &ModRegRm))
{
/* Exception occurred */
- return FALSE;
+ return;
}
/* Check the operand size */
&SecondValue))
{
/* Exception occurred */
- return FALSE;
+ return;
}
-
+
/* 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 */
- return Fast486WriteModrmDwordOperands(State,
- &ModRegRm,
- Opcode & FAST486_OPCODE_WRITE_REG,
- Result);
+ Fast486WriteModrmDwordOperands(State,
+ &ModRegRm,
+ Opcode & FAST486_OPCODE_WRITE_REG,
+ Result);
}
else
{
&SecondValue))
{
/* Exception occurred */
- return FALSE;
+ return;
}
-
+
/* 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 */
- return Fast486WriteModrmWordOperands(State,
- &ModRegRm,
- Opcode & FAST486_OPCODE_WRITE_REG,
- Result);
+ Fast486WriteModrmWordOperands(State,
+ &ModRegRm,
+ Opcode & FAST486_OPCODE_WRITE_REG,
+ Result);
}
}
{
/* This opcode doesn't take any prefixes */
Fast486Exception(State, FAST486_EXCEPTION_UD);
- return FALSE;
+ return;
}
if (!Fast486FetchByte(State, &SecondValue))
{
/* Exception occurred */
- return FALSE;
+ return;
}
/* Calculate the result */
/* 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 */
State->GeneralRegs[FAST486_REG_EAX].LowByte = Result;
-
- return TRUE;
}
FAST486_OPCODE_HANDLER(Fast486OpcodeXorEax)
if (!Fast486FetchDword(State, &SecondValue))
{
/* Exception occurred */
- return FALSE;
+ return;
}
/* Calculate the result */
/* 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 */
if (!Fast486FetchWord(State, &SecondValue))
{
/* Exception occurred */
- return FALSE;
+ return;
}
/* Calculate the result */
/* 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 */
State->GeneralRegs[FAST486_REG_EAX].LowWord = Result;
}
-
- return TRUE;
}
FAST486_OPCODE_HANDLER(Fast486OpcodeTestByteModrm)
if (!Fast486ParseModRegRm(State, AddressSize, &ModRegRm))
{
/* Exception occurred */
- return FALSE;
+ return;
}
if (!Fast486ReadModrmByteOperands(State,
&SecondValue))
{
/* Exception occurred */
- return FALSE;
+ return;
}
/* 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_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 */
- return TRUE;
}
FAST486_OPCODE_HANDLER(Fast486OpcodeTestModrm)
if (!Fast486ParseModRegRm(State, AddressSize, &ModRegRm))
{
/* Exception occurred */
- return FALSE;
+ return;
}
/* Check the operand size */
&SecondValue))
{
/* Exception occurred */
- return FALSE;
+ return;
}
-
+
/* 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
&SecondValue))
{
/* Exception occurred */
- return FALSE;
+ return;
}
-
+
/* 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);
}
-
- /* The result is discarded */
- return TRUE;
}
FAST486_OPCODE_HANDLER(Fast486OpcodeTestAl)
{
/* This opcode doesn't take any prefixes */
Fast486Exception(State, FAST486_EXCEPTION_UD);
- return FALSE;
+ return;
}
if (!Fast486FetchByte(State, &SecondValue))
{
/* Exception occurred */
- return FALSE;
+ return;
}
/* Calculate the result */
/* 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 */
- return TRUE;
}
FAST486_OPCODE_HANDLER(Fast486OpcodeTestEax)
if (!Fast486FetchDword(State, &SecondValue))
{
/* Exception occurred */
- return FALSE;
+ return;
}
/* Calculate the result */
/* 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
if (!Fast486FetchWord(State, &SecondValue))
{
/* Exception occurred */
- return FALSE;
+ return;
}
/* Calculate the result */
/* 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);
}
-
- /* The result is discarded */
- return TRUE;
}
FAST486_OPCODE_HANDLER(Fast486OpcodeXchgByteModrm)
if (!Fast486ParseModRegRm(State, AddressSize, &ModRegRm))
{
/* Exception occurred */
- return FALSE;
+ return;
}
if (!Fast486ReadModrmByteOperands(State,
&SecondValue))
{
/* Exception occurred */
- return FALSE;
+ return;
}
/* Write the value from the register to the R/M */
FirstValue))
{
/* Exception occurred */
- return FALSE;
+ return;
}
/* Write the value from the R/M to the register */
- if (!Fast486WriteModrmByteOperands(State,
- &ModRegRm,
- TRUE,
- SecondValue))
- {
- /* Exception occurred */
- return FALSE;
- }
-
- return TRUE;
+ Fast486WriteModrmByteOperands(State,
+ &ModRegRm,
+ TRUE,
+ SecondValue);
}
FAST486_OPCODE_HANDLER(Fast486OpcodeXchgModrm)
if (!Fast486ParseModRegRm(State, AddressSize, &ModRegRm))
{
/* Exception occurred */
- return FALSE;
+ return;
}
/* Check the operand size */
&SecondValue))
{
/* Exception occurred */
- return FALSE;
+ return;
}
/* Write the value from the register to the R/M */
FirstValue))
{
/* Exception occurred */
- return FALSE;
+ return;
}
/* Write the value from the R/M to the register */
- if (!Fast486WriteModrmDwordOperands(State,
- &ModRegRm,
- TRUE,
- SecondValue))
- {
- /* Exception occurred */
- return FALSE;
- }
+ Fast486WriteModrmDwordOperands(State,
+ &ModRegRm,
+ TRUE,
+ SecondValue);
}
else
{
&SecondValue))
{
/* Exception occurred */
- return FALSE;
+ return;
}
-
+
/* Write the value from the register to the R/M */
if (!Fast486WriteModrmWordOperands(State,
&ModRegRm,
FirstValue))
{
/* Exception occurred */
- return FALSE;
+ return;
}
/* Write the value from the R/M to the register */
- if (!Fast486WriteModrmWordOperands(State,
- &ModRegRm,
- TRUE,
- SecondValue))
- {
- /* Exception occurred */
- return FALSE;
- }
+ Fast486WriteModrmWordOperands(State,
+ &ModRegRm,
+ TRUE,
+ SecondValue);
}
-
- /* The result is discarded */
- return TRUE;
}
FAST486_OPCODE_HANDLER(Fast486OpcodePushEs)
{
/* Call the internal API */
- return Fast486StackPush(State, State->SegmentRegs[FAST486_REG_ES].Selector);
+ Fast486StackPush(State, State->SegmentRegs[FAST486_REG_ES].Selector);
}
FAST486_OPCODE_HANDLER(Fast486OpcodePopEs)
if (!Fast486StackPop(State, &NewSelector))
{
/* Exception occurred */
- return FALSE;
+ return;
}
/* Call the internal API */
- return Fast486LoadSegment(State, FAST486_REG_ES, LOWORD(NewSelector));
+ Fast486LoadSegment(State, FAST486_REG_ES, LOWORD(NewSelector));
}
FAST486_OPCODE_HANDLER(Fast486OpcodePushCs)
{
/* Call the internal API */
- return Fast486StackPush(State, State->SegmentRegs[FAST486_REG_CS].Selector);
+ Fast486StackPush(State, State->SegmentRegs[FAST486_REG_CS].Selector);
}
FAST486_OPCODE_HANDLER(Fast486OpcodeAdcByteModrm)
if (!Fast486ParseModRegRm(State, AddressSize, &ModRegRm))
{
/* Exception occurred */
- return FALSE;
+ return;
}
if (!Fast486ReadModrmByteOperands(State,
&SecondValue))
{
/* Exception occurred */
- return FALSE;
+ return;
}
/* Calculate the result */
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 */
- return Fast486WriteModrmByteOperands(State,
- &ModRegRm,
- Opcode & FAST486_OPCODE_WRITE_REG,
- Result);
+ Fast486WriteModrmByteOperands(State,
+ &ModRegRm,
+ Opcode & FAST486_OPCODE_WRITE_REG,
+ Result);
}
FAST486_OPCODE_HANDLER(Fast486OpcodeAdcModrm)
if (!Fast486ParseModRegRm(State, AddressSize, &ModRegRm))
{
/* Exception occurred */
- return FALSE;
+ return;
}
/* Check the operand size */
&SecondValue))
{
/* Exception occurred */
- return FALSE;
+ return;
}
-
+
/* Calculate the result */
Result = FirstValue + SecondValue + State->Flags.Cf;
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 */
- return Fast486WriteModrmDwordOperands(State,
- &ModRegRm,
- Opcode & FAST486_OPCODE_WRITE_REG,
- Result);
+ Fast486WriteModrmDwordOperands(State,
+ &ModRegRm,
+ Opcode & FAST486_OPCODE_WRITE_REG,
+ Result);
}
else
{
&SecondValue))
{
/* Exception occurred */
- return FALSE;
+ return;
}
-
+
/* Calculate the result */
Result = FirstValue + SecondValue + State->Flags.Cf;
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 */
- return Fast486WriteModrmWordOperands(State,
- &ModRegRm,
- Opcode & FAST486_OPCODE_WRITE_REG,
- Result);
+ Fast486WriteModrmWordOperands(State,
+ &ModRegRm,
+ Opcode & FAST486_OPCODE_WRITE_REG,
+ Result);
}
}
{
/* This opcode doesn't take any prefixes */
Fast486Exception(State, FAST486_EXCEPTION_UD);
- return FALSE;
+ return;
}
if (!Fast486FetchByte(State, &SecondValue))
{
/* Exception occurred */
- return FALSE;
+ return;
}
/* Calculate the result */
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 */
State->GeneralRegs[FAST486_REG_EAX].LowByte = Result;
-
- return TRUE;
}
FAST486_OPCODE_HANDLER(Fast486OpcodeAdcEax)
if (!Fast486FetchDword(State, &SecondValue))
{
/* Exception occurred */
- return FALSE;
+ return;
}
/* Calculate the result */
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 */
if (!Fast486FetchWord(State, &SecondValue))
{
/* Exception occurred */
- return FALSE;
+ return;
}
/* Calculate the result */
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 */
State->GeneralRegs[FAST486_REG_EAX].LowWord = Result;
}
-
- return TRUE;
}
FAST486_OPCODE_HANDLER(Fast486OpcodePushSs)
{
/* Call the internal API */
- return Fast486StackPush(State, State->SegmentRegs[FAST486_REG_SS].Selector);
+ Fast486StackPush(State, State->SegmentRegs[FAST486_REG_SS].Selector);
}
FAST486_OPCODE_HANDLER(Fast486OpcodePopSs)
if (!Fast486StackPop(State, &NewSelector))
{
/* Exception occurred */
- return FALSE;
+ return;
}
/* Call the internal API */
- return Fast486LoadSegment(State, FAST486_REG_SS, LOWORD(NewSelector));
+ Fast486LoadSegment(State, FAST486_REG_SS, LOWORD(NewSelector));
}
FAST486_OPCODE_HANDLER(Fast486OpcodeSbbByteModrm)
if (!Fast486ParseModRegRm(State, AddressSize, &ModRegRm))
{
/* Exception occurred */
- return FALSE;
+ return;
}
if (!Fast486ReadModrmByteOperands(State,
&SecondValue))
{
/* Exception occurred */
- return FALSE;
+ return;
}
/* Check if this is the instruction that writes to R/M */
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 */
- return Fast486WriteModrmByteOperands(State,
- &ModRegRm,
- Opcode & FAST486_OPCODE_WRITE_REG,
- Result);
+ Fast486WriteModrmByteOperands(State,
+ &ModRegRm,
+ Opcode & FAST486_OPCODE_WRITE_REG,
+ Result);
}
FAST486_OPCODE_HANDLER(Fast486OpcodeSbbModrm)
if (!Fast486ParseModRegRm(State, AddressSize, &ModRegRm))
{
/* Exception occurred */
- return FALSE;
+ return;
}
/* Check the operand size */
&SecondValue))
{
/* Exception occurred */
- return FALSE;
+ return;
}
/* Check if this is the instruction that writes to R/M */
/* 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 */
- return Fast486WriteModrmDwordOperands(State,
- &ModRegRm,
- Opcode & FAST486_OPCODE_WRITE_REG,
- Result);
+ Fast486WriteModrmDwordOperands(State,
+ &ModRegRm,
+ Opcode & FAST486_OPCODE_WRITE_REG,
+ Result);
}
else
{
&SecondValue))
{
/* Exception occurred */
- return FALSE;
+ return;
}
-
+
/* 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 */
- return Fast486WriteModrmWordOperands(State,
- &ModRegRm,
- Opcode & FAST486_OPCODE_WRITE_REG,
- Result);
+ Fast486WriteModrmWordOperands(State,
+ &ModRegRm,
+ Opcode & FAST486_OPCODE_WRITE_REG,
+ Result);
}
}
{
/* This opcode doesn't take any prefixes */
Fast486Exception(State, FAST486_EXCEPTION_UD);
- return FALSE;
+ return;
}
if (!Fast486FetchByte(State, &SecondValue))
{
/* Exception occurred */
- return FALSE;
+ return;
}
/* 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_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 */
State->GeneralRegs[FAST486_REG_EAX].LowByte = Result;
-
- return TRUE;
-
}
FAST486_OPCODE_HANDLER(Fast486OpcodeSbbEax)
if (!Fast486FetchDword(State, &SecondValue))
{
/* Exception occurred */
- return FALSE;
+ return;
}
/* 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 + 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 */
if (!Fast486FetchWord(State, &SecondValue))
{
/* Exception occurred */
- return FALSE;
+ return;
}
/* 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 + 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 */
State->GeneralRegs[FAST486_REG_EAX].LowWord = Result;
}
-
- return TRUE;
-
}
FAST486_OPCODE_HANDLER(Fast486OpcodePushDs)
{
/* Call the internal API */
- return Fast486StackPush(State, State->SegmentRegs[FAST486_REG_DS].Selector);
+ Fast486StackPush(State, State->SegmentRegs[FAST486_REG_DS].Selector);
}
FAST486_OPCODE_HANDLER(Fast486OpcodePopDs)
if (!Fast486StackPop(State, &NewSelector))
{
/* Exception occurred */
- return FALSE;
+ return;
}
/* Call the internal API */
- return Fast486LoadSegment(State, FAST486_REG_DS, LOWORD(NewSelector));
+ Fast486LoadSegment(State, FAST486_REG_DS, LOWORD(NewSelector));
}
FAST486_OPCODE_HANDLER(Fast486OpcodeDaa)
State->Flags.Cf = TRUE;
}
- return 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);
}
FAST486_OPCODE_HANDLER(Fast486OpcodeCmpSubByteModrm)
if (!Fast486ParseModRegRm(State, AddressSize, &ModRegRm))
{
/* Exception occurred */
- return FALSE;
+ return;
}
if (!Fast486ReadModrmByteOperands(State,
&SecondValue))
{
/* Exception occurred */
- return FALSE;
+ return;
}
/* Check if this is the instruction that writes to R/M */
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 */
if (!(Opcode & 0x10))
{
/* Write back the result */
- return Fast486WriteModrmByteOperands(State,
- &ModRegRm,
- Opcode & FAST486_OPCODE_WRITE_REG,
- Result);
- }
- else
- {
- /* Discard the result */
- return TRUE;
+ Fast486WriteModrmByteOperands(State,
+ &ModRegRm,
+ Opcode & FAST486_OPCODE_WRITE_REG,
+ Result);
}
}
if (!Fast486ParseModRegRm(State, AddressSize, &ModRegRm))
{
/* Exception occurred */
- return FALSE;
+ return;
}
/* Check the operand size */
&SecondValue))
{
/* Exception occurred */
- return FALSE;
+ return;
}
/* Check if this is the instruction that writes to R/M */
/* 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 */
if (!(Opcode & 0x10))
{
/* Write back the result */
- return Fast486WriteModrmDwordOperands(State,
- &ModRegRm,
- Opcode & FAST486_OPCODE_WRITE_REG,
- Result);
- }
- else
- {
- /* Discard the result */
- return TRUE;
+ Fast486WriteModrmDwordOperands(State,
+ &ModRegRm,
+ Opcode & FAST486_OPCODE_WRITE_REG,
+ Result);
}
}
else
&SecondValue))
{
/* Exception occurred */
- return FALSE;
+ return;
}
-
+
/* 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 */
if (!(Opcode & 0x10))
{
/* Write back the result */
- return Fast486WriteModrmWordOperands(State,
- &ModRegRm,
- Opcode & FAST486_OPCODE_WRITE_REG,
- Result);
- }
- else
- {
- /* Discard the result */
- return TRUE;
+ Fast486WriteModrmWordOperands(State,
+ &ModRegRm,
+ Opcode & FAST486_OPCODE_WRITE_REG,
+ Result);
}
}
}
{
/* This opcode doesn't take any prefixes */
Fast486Exception(State, FAST486_EXCEPTION_UD);
- return FALSE;
+ return;
}
if (!Fast486FetchByte(State, &SecondValue))
{
/* Exception occurred */
- return FALSE;
+ return;
}
/* 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_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 */
/* Write back the result */
State->GeneralRegs[FAST486_REG_EAX].LowByte = Result;
}
-
- return TRUE;
}
FAST486_OPCODE_HANDLER(Fast486OpcodeCmpSubEax)
if (!Fast486FetchDword(State, &SecondValue))
{
/* Exception occurred */
- return FALSE;
+ return;
}
/* 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 */
if (!Fast486FetchWord(State, &SecondValue))
{
/* Exception occurred */
- return FALSE;
+ return;
}
/* 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 */
State->GeneralRegs[FAST486_REG_EAX].LowWord = Result;
}
}
-
- return TRUE;
}
FAST486_OPCODE_HANDLER(Fast486OpcodeDas)
State->Flags.Cf = TRUE;
}
- return 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);
}
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 */
/* Keep only the lowest 4 bits of AL */
State->GeneralRegs[FAST486_REG_EAX].LowByte &= 0x0F;
-
- return TRUE;
}
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 */
/* Keep only the lowest 4 bits of AL */
State->GeneralRegs[FAST486_REG_EAX].LowByte &= 0x0F;
-
- return TRUE;
}
FAST486_OPCODE_HANDLER(Fast486OpcodePushAll)
if (!Fast486StackPush(State, Size ? SavedEsp.Long : SavedEsp.LowWord))
{
/* Exception occurred */
- return FALSE;
+ return;
}
}
else
: State->GeneralRegs[i].LowWord))
{
/* Exception occurred */
- return FALSE;
+ return;
}
}
}
-
- return TRUE;
}
FAST486_OPCODE_HANDLER(Fast486OpcodePopAll)
if (!Fast486StackPop(State, &Value))
{
/* Exception occurred */
- return FALSE;
+ return;
}
/* Don't modify ESP */
else State->GeneralRegs[i].LowWord = LOWORD(Value);
}
}
-
- return TRUE;
}
FAST486_OPCODE_HANDLER(Fast486OpcodeBound)
{
- // TODO: NOT IMPLEMENTED
- UNIMPLEMENTED;
+ BOOLEAN OperandSize, AddressSize;
+ FAST486_MOD_REG_RM ModRegRm;
+ FAST486_SEG_REGS Segment = FAST486_REG_DS;
+
+ 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;
+ }
+
+ if (!ModRegRm.Memory)
+ {
+ /* Invalid */
+ Fast486Exception(State, FAST486_EXCEPTION_UD);
+ return;
+ }
+
+ /* 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;
+ }
+
+ if (!Fast486ReadMemory(State,
+ Segment,
+ ModRegRm.MemoryAddress + sizeof(ULONG),
+ FALSE,
+ &UpperBound,
+ sizeof(ULONG)))
+ {
+ /* Exception occurred */
+ return;
+ }
+
+ if ((Index < LowerBound) || (Index > UpperBound))
+ {
+ /* Out of bounds */
+ Fast486Exception(State, FAST486_EXCEPTION_BR);
+ }
+ }
+ else
+ {
+ SHORT Index, LowerBound, UpperBound;
+
+ /* Read the operands */
+ if (!Fast486ReadModrmWordOperands(State,
+ &ModRegRm,
+ (PUSHORT)&Index,
+ (PUSHORT)&LowerBound))
+ {
+ /* Exception occurred */
+ return;
+ }
+
+ if (!Fast486ReadMemory(State,
+ Segment,
+ ModRegRm.MemoryAddress + sizeof(USHORT),
+ FALSE,
+ &UpperBound,
+ sizeof(USHORT)))
+ {
+ /* Exception occurred */
+ return;
+ }
- return FALSE;
+ if ((Index < LowerBound) || (Index > UpperBound))
+ {
+ /* Out of bounds */
+ Fast486Exception(State, FAST486_EXCEPTION_BR);
+ }
+ }
}
FAST486_OPCODE_HANDLER(Fast486OpcodeArpl)
{
/* Cannot be used in real mode or with a LOCK prefix */
Fast486Exception(State, FAST486_EXCEPTION_UD);
- return FALSE;
+ return;
}
TOGGLE_ADSIZE(AddressSize);
if (!Fast486ParseModRegRm(State, AddressSize, &ModRegRm))
{
/* Exception occurred */
- return FALSE;
+ return;
}
/* Read the operands */
&SecondValue))
{
/* Exception occurred */
- return FALSE;
+ return;
}
/* Check if the RPL needs adjusting */
State->Flags.Zf = TRUE;
/* Write back the result */
- return Fast486WriteModrmWordOperands(State, &ModRegRm, FALSE, SecondValue);
+ Fast486WriteModrmWordOperands(State, &ModRegRm, FALSE, SecondValue);
}
else
{
/* Clear ZF */
State->Flags.Zf = FALSE;
- return TRUE;
}
}
if (!Fast486FetchDword(State, &Data))
{
/* Exception occurred */
- return FALSE;
+ return;
}
/* Call the internal API */
- return Fast486StackPush(State, Data);
+ Fast486StackPush(State, Data);
}
else
{
- USHORT Data;
+ SHORT Data;
- if (!Fast486FetchWord(State, &Data))
+ if (!Fast486FetchWord(State, (PUSHORT)&Data))
{
/* Exception occurred */
- return FALSE;
+ return;
}
/* Call the internal API */
- return Fast486StackPush(State, Data);
+ Fast486StackPush(State, Data);
}
}
BOOLEAN OperandSize, AddressSize;
FAST486_MOD_REG_RM ModRegRm;
LONG Multiplier;
- LONGLONG Product;
/* Make sure this is the right instruction */
ASSERT((Opcode & 0xFD) == 0x69);
if (!Fast486ParseModRegRm(State, AddressSize, &ModRegRm))
{
/* Exception occurred */
- return FALSE;
+ return;
}
if (Opcode == 0x6B)
if (!Fast486FetchByte(State, (PUCHAR)&Byte))
{
/* Exception occurred */
- return FALSE;
+ return;
}
Multiplier = (LONG)Byte;
if (!Fast486FetchDword(State, (PULONG)&Dword))
{
/* Exception occurred */
- return FALSE;
+ return;
}
Multiplier = Dword;
if (!Fast486FetchWord(State, (PUSHORT)&Word))
{
/* Exception occurred */
- return FALSE;
+ return;
}
Multiplier = (LONG)Word;
if (OperandSize)
{
LONG RegValue, Multiplicand;
+ LONGLONG Product;
/* Read the operands */
if (!Fast486ReadModrmDwordOperands(State,
(PULONG)&Multiplicand))
{
/* Exception occurred */
- return FALSE;
+ return;
}
/* Multiply */
Product = (LONGLONG)Multiplicand * (LONGLONG)Multiplier;
+
+ /* Check for carry/overflow */
+ State->Flags.Cf = State->Flags.Of = ((Product < MINLONG) || (Product > MAXLONG));
+
+ /* Write-back the result */
+ Fast486WriteModrmDwordOperands(State,
+ &ModRegRm,
+ TRUE,
+ (ULONG)((LONG)Product));
}
else
{
SHORT RegValue, Multiplicand;
+ LONG Product;
/* Read the operands */
if (!Fast486ReadModrmWordOperands(State,
(PUSHORT)&Multiplicand))
{
/* Exception occurred */
- return FALSE;
+ return;
}
/* 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 */
+ Fast486WriteModrmWordOperands(State,
+ &ModRegRm,
+ TRUE,
+ (USHORT)((SHORT)Product));
+ }
}
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;
+ return;
}
/* Call the internal API */
- return Fast486StackPush(State, Data);
+ Fast486StackPush(State, Data);
}
FAST486_OPCODE_HANDLER(Fast486OpcodeMovByteModrm)
if (!Fast486ParseModRegRm(State, AddressSize, &ModRegRm))
{
/* Exception occurred */
- return FALSE;
+ return;
}
if (!Fast486ReadModrmByteOperands(State,
&SecondValue))
{
/* Exception occurred */
- return FALSE;
+ return;
}
if (Opcode & FAST486_OPCODE_WRITE_REG) Result = SecondValue;
else Result = FirstValue;
/* Write back the result */
- return Fast486WriteModrmByteOperands(State,
- &ModRegRm,
- Opcode & FAST486_OPCODE_WRITE_REG,
- Result);
+ Fast486WriteModrmByteOperands(State,
+ &ModRegRm,
+ Opcode & FAST486_OPCODE_WRITE_REG,
+ Result);
}
if (!Fast486ParseModRegRm(State, AddressSize, &ModRegRm))
{
/* Exception occurred */
- return FALSE;
+ return;
}
/* Check the operand size */
&SecondValue))
{
/* Exception occurred */
- return FALSE;
+ return;
}
if (Opcode & FAST486_OPCODE_WRITE_REG) Result = SecondValue;
else Result = FirstValue;
-
+
/* Write back the result */
- return Fast486WriteModrmDwordOperands(State,
- &ModRegRm,
- Opcode & FAST486_OPCODE_WRITE_REG,
- Result);
+ Fast486WriteModrmDwordOperands(State,
+ &ModRegRm,
+ Opcode & FAST486_OPCODE_WRITE_REG,
+ Result);
}
else
{
&SecondValue))
{
/* Exception occurred */
- return FALSE;
+ return;
}
-
+
if (Opcode & FAST486_OPCODE_WRITE_REG) Result = SecondValue;
else Result = FirstValue;
/* Write back the result */
- return Fast486WriteModrmWordOperands(State,
- &ModRegRm,
- Opcode & FAST486_OPCODE_WRITE_REG,
- Result);
+ Fast486WriteModrmWordOperands(State,
+ &ModRegRm,
+ Opcode & FAST486_OPCODE_WRITE_REG,
+ Result);
}
}
if (!Fast486ParseModRegRm(State, AddressSize, &ModRegRm))
{
/* Exception occurred */
- return FALSE;
+ return;
}
if (ModRegRm.Register >= FAST486_NUM_SEG_REGS)
{
/* Invalid */
Fast486Exception(State, FAST486_EXCEPTION_UD);
- return FALSE;
+ return;
}
if (OperandSize)
{
- return Fast486WriteModrmDwordOperands(State,
- &ModRegRm,
- FALSE,
- State->SegmentRegs[ModRegRm.Register].Selector);
+ Fast486WriteModrmDwordOperands(State,
+ &ModRegRm,
+ FALSE,
+ State->SegmentRegs[ModRegRm.Register].Selector);
}
else
{
- return Fast486WriteModrmWordOperands(State,
- &ModRegRm,
- FALSE,
- State->SegmentRegs[ModRegRm.Register].Selector);
+ Fast486WriteModrmWordOperands(State,
+ &ModRegRm,
+ FALSE,
+ State->SegmentRegs[ModRegRm.Register].Selector);
}
}
if (!Fast486ParseModRegRm(State, AddressSize, &ModRegRm))
{
/* Exception occurred */
- return FALSE;
+ return;
}
/* The second operand must be memory */
{
/* Invalid */
Fast486Exception(State, FAST486_EXCEPTION_UD);
- return FALSE;
+ return;
}
/* Write the address to the register */
if (OperandSize)
{
- return Fast486WriteModrmDwordOperands(State,
- &ModRegRm,
- TRUE,
- ModRegRm.MemoryAddress);
+ Fast486WriteModrmDwordOperands(State,
+ &ModRegRm,
+ TRUE,
+ ModRegRm.MemoryAddress);
}
else
{
- return Fast486WriteModrmWordOperands(State,
- &ModRegRm,
- TRUE,
- ModRegRm.MemoryAddress);
+ Fast486WriteModrmWordOperands(State,
+ &ModRegRm,
+ TRUE,
+ ModRegRm.MemoryAddress);
}
}
if (!Fast486ParseModRegRm(State, AddressSize, &ModRegRm))
{
/* Exception occurred */
- return FALSE;
+ return;
}
if ((ModRegRm.Register >= FAST486_NUM_SEG_REGS)
{
/* Invalid */
Fast486Exception(State, FAST486_EXCEPTION_UD);
- return FALSE;
+ return;
}
if (OperandSize)
{
- ULONG Dummy, Selector;
+ ULONG Selector;
- if (!Fast486ReadModrmDwordOperands(State, &ModRegRm, &Dummy, &Selector))
+ if (!Fast486ReadModrmDwordOperands(State, &ModRegRm, NULL, &Selector))
{
/* Exception occurred */
- return FALSE;
+ return;
}
- return Fast486LoadSegment(State, ModRegRm.Register, LOWORD(Selector));
+ Fast486LoadSegment(State, ModRegRm.Register, LOWORD(Selector));
}
else
{
- USHORT Dummy, Selector;
+ USHORT Selector;
- if (!Fast486ReadModrmWordOperands(State, &ModRegRm, &Dummy, &Selector))
+ if (!Fast486ReadModrmWordOperands(State, &ModRegRm, NULL, &Selector))
{
/* Exception occurred */
- return FALSE;
+ return;
}
- return Fast486LoadSegment(State, ModRegRm.Register, Selector);
+ Fast486LoadSegment(State, ModRegRm.Register, Selector);
}
}
(State->GeneralRegs[FAST486_REG_EAX].LowByte & SIGN_FLAG_BYTE)
? 0xFF : 0x00;
}
-
- return TRUE;
}
FAST486_OPCODE_HANDLER(Fast486OpcodeCdq)
(State->GeneralRegs[FAST486_REG_EAX].LowWord & SIGN_FLAG_WORD)
? 0xFFFF : 0x0000;
}
-
- return TRUE;
}
FAST486_OPCODE_HANDLER(Fast486OpcodeCallAbs)
if (!Fast486FetchDword(State, &Offset))
{
/* Exception occurred */
- return FALSE;
+ return;
}
}
else
if (!Fast486FetchWord(State, (PUSHORT)&Offset))
{
/* Exception occurred */
- return FALSE;
+ return;
}
}
if (!Fast486FetchWord(State, &Segment))
{
/* Exception occurred */
- return FALSE;
+ return;
}
/* Push the current code segment selector */
if (!Fast486StackPush(State, State->SegmentRegs[FAST486_REG_CS].Selector))
{
/* Exception occurred */
- return FALSE;
+ return;
}
/* Push the current value of the instruction pointer */
if (!Fast486StackPush(State, State->InstPtr.Long))
{
/* Exception occurred */
- return FALSE;
+ return;
}
/* Load the new CS */
if (!Fast486LoadSegment(State, FAST486_REG_CS, Segment))
{
/* Exception occurred */
- return FALSE;
+ return;
}
/* Load new (E)IP */
if (Size) State->InstPtr.Long = Offset;
else State->InstPtr.LowWord = LOWORD(Offset);
-
- return TRUE;
}
FAST486_OPCODE_HANDLER(Fast486OpcodeWait)
{
// TODO: NOT IMPLEMENTED
UNIMPLEMENTED;
-
- return FALSE;
}
FAST486_OPCODE_HANDLER(Fast486OpcodePushFlags)
{
/* Call the VM86 monitor */
Fast486ExceptionWithErrorCode(State, FAST486_EXCEPTION_GP, 0);
- return FALSE;
+ return;
}
/* Push the flags */
- if (Size) return Fast486StackPush(State, State->Flags.Long);
- else return Fast486StackPush(State, LOWORD(State->Flags.Long));
+ if (Size) Fast486StackPush(State, State->Flags.Long);
+ else Fast486StackPush(State, LOWORD(State->Flags.Long));
}
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;
+ return;
}
- if (!State->Flags.Vm)
- {
- /* 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;
- }
- }
- }
- else
+ /* Check for VM86 mode when IOPL is not 3 */
+ if (State->Flags.Vm && (State->Flags.Iopl != 3))
{
- /* 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);
- }
-
- }
-
- return TRUE;
+ /* Call the VM86 monitor */
+ Fast486ExceptionWithErrorCode(State, FAST486_EXCEPTION_GP, 0);
+ return;
+ }
+
+ 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;
}
FAST486_OPCODE_HANDLER(Fast486OpcodeSahf)
/* Restore the reserved bits of FLAGS */
State->Flags.AlwaysSet = TRUE;
State->Flags.Reserved0 = State->Flags.Reserved1 = FALSE;
-
- return FALSE;
}
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;
}
FAST486_OPCODE_HANDLER(Fast486OpcodeRet)
if (Opcode == 0xC2)
{
/* Fetch the number of bytes to pop after the return */
- if (!Fast486FetchWord(State, &BytesToPop)) return FALSE;
+ if (!Fast486FetchWord(State, &BytesToPop)) return;
}
/* Pop the return address */
- if (!Fast486StackPop(State, &ReturnAddress)) return FALSE;
+ if (!Fast486StackPop(State, &ReturnAddress)) return;
/* Return to the calling procedure, and if necessary, pop the parameters */
if (Size)
State->InstPtr.LowWord = LOWORD(ReturnAddress);
State->GeneralRegs[FAST486_REG_ESP].LowWord += BytesToPop;
}
-
- return TRUE;
}
FAST486_OPCODE_HANDLER(Fast486OpcodeLdsLes)
OperandSize = AddressSize = State->SegmentRegs[FAST486_REG_CS].Size;
+ TOGGLE_OPSIZE(OperandSize);
TOGGLE_ADSIZE(AddressSize);
/* Get the operands */
if (!Fast486ParseModRegRm(State, AddressSize, &ModRegRm))
{
/* Exception occurred */
- return FALSE;
+ return;
}
if (!ModRegRm.Memory)
&& (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;
+ return;
}
/* Call the BOP handler */
State->BopCallback(State, BopCode);
- /* Return success */
- return TRUE;
+ /*
+ * If an interrupt should occur at this time, delay it.
+ * We must do this because if an interrupt begins and the BOP callback
+ * changes the CS:IP, the interrupt handler won't execute and the
+ * stack pointer will never be restored.
+ */
+ if (State->IntStatus == FAST486_INT_EXECUTE)
+ {
+ State->IntStatus = FAST486_INT_DELAYED;
+ }
+
+ return;
}
/* Invalid */
Fast486Exception(State, FAST486_EXCEPTION_UD);
- return FALSE;
+ return;
}
if (!Fast486ReadMemory(State,
OperandSize ? 6 : 4))
{
/* Exception occurred */
- return FALSE;
+ return;
}
if (OperandSize)
State->GeneralRegs[ModRegRm.Register].Long = Offset;
/* Load the segment */
- return Fast486LoadSegment(State,
- (Opcode == 0xC4)
- ? FAST486_REG_ES : FAST486_REG_DS,
- Segment);
+ Fast486LoadSegment(State,
+ (Opcode == 0xC4)
+ ? FAST486_REG_ES : FAST486_REG_DS,
+ Segment);
}
else
{
State->GeneralRegs[ModRegRm.Register].LowWord = Offset;
/* Load the segment */
- return Fast486LoadSegment(State,
- (Opcode == 0xC4)
- ? FAST486_REG_ES : FAST486_REG_DS,
- Segment);
+ Fast486LoadSegment(State,
+ (Opcode == 0xC4)
+ ? FAST486_REG_ES : FAST486_REG_DS,
+ Segment);
}
}
if (!Fast486FetchWord(State, &FrameSize))
{
/* Exception occurred */
- return FALSE;
+ return;
}
if (!Fast486FetchByte(State, &NestingLevel))
{
/* Exception occurred */
- return FALSE;
+ return;
}
/* Push EBP */
if (!Fast486StackPush(State, State->GeneralRegs[FAST486_REG_EBP].Long))
{
/* Exception occurred */
- return FALSE;
+ return;
}
/* Save ESP */
/* Reserve space for the frame */
if (Size) State->GeneralRegs[FAST486_REG_ESP].Long -= (ULONG)FrameSize;
else State->GeneralRegs[FAST486_REG_ESP].LowWord -= FrameSize;
-
- return TRUE;
}
FAST486_OPCODE_HANDLER(Fast486OpcodeLeave)
State->GeneralRegs[FAST486_REG_ESP].Long = State->GeneralRegs[FAST486_REG_EBP].Long;
/* Pop the saved base pointer from the stack */
- return Fast486StackPop(State, &State->GeneralRegs[FAST486_REG_EBP].Long);
+ Fast486StackPop(State, &State->GeneralRegs[FAST486_REG_EBP].Long);
}
else
{
if (Fast486StackPop(State, &Value))
{
State->GeneralRegs[FAST486_REG_EBP].LowWord = LOWORD(Value);
- return TRUE;
}
- else return FALSE;
}
}
if (Opcode == 0xCA)
{
/* Fetch the number of bytes to pop after the return */
- if (!Fast486FetchWord(State, &BytesToPop)) return FALSE;
+ if (!Fast486FetchWord(State, &BytesToPop)) return;
}
/* Pop the offset */
if (!Fast486StackPop(State, &Offset))
{
/* Exception occurred */
- return FALSE;
+ return;
}
/* Pop the segment */
if (!Fast486StackPop(State, &Segment))
{
/* Exception occurred */
- return FALSE;
+ return;
}
/* Load the new CS */
if (!Fast486LoadSegment(State, FAST486_REG_CS, Segment))
{
/* Exception occurred */
- return FALSE;
+ return;
}
/* Load new (E)IP, and if necessary, pop the parameters */
State->InstPtr.LowWord = LOWORD(Offset);
State->GeneralRegs[FAST486_REG_ESP].LowWord += BytesToPop;
}
-
- return TRUE;
}
FAST486_OPCODE_HANDLER(Fast486OpcodeInt)
{
UCHAR IntNum;
- FAST486_IDT_ENTRY IdtEntry;
switch (Opcode)
{
- case 0xCC:
+ case 0xCC: // INT 3
{
/* This is the INT3 instruction */
IntNum = 3;
break;
}
- case 0xCD:
+ case 0xCD: // INT xx
{
/* Fetch the interrupt number */
if (!Fast486FetchByte(State, &IntNum))
{
/* Exception occurred */
- return FALSE;
+ return;
}
break;
}
- case 0xCE:
+ case 0xCE: // INTO
{
/* Don't do anything if OF is cleared */
- if (!State->Flags.Of) return TRUE;
+ if (!State->Flags.Of) return;
/* Exception #OF */
IntNum = FAST486_EXCEPTION_OF;
}
}
- /* 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;
+ Fast486PerformInterrupt(State, IntNum);
}
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;
if (!Fast486StackPop(State, &InstPtr))
{
/* Exception occurred */
- return FALSE;
+ return;
}
/* Pop CS */
if (!Fast486StackPop(State, &CodeSel))
{
/* Exception occurred */
- return FALSE;
+ return;
}
/* Pop EFLAGS */
if (!Fast486StackPop(State, &NewFlags.Long))
{
/* Exception occurred */
- return FALSE;
+ return;
}
/* Check for protected mode */
if (!Fast486LoadSegment(State, FAST486_REG_CS, CodeSel))
{
/* Exception occurred */
- return FALSE;
+ return;
}
/* Set the new flags */
{
/* Call the VM86 monitor */
Fast486ExceptionWithErrorCode(State, FAST486_EXCEPTION_GP, 0);
- return FALSE;
+ return;
}
- return TRUE;
+ return;
}
if (State->Flags.Nt)
/* Nested task return */
UNIMPLEMENTED;
- return FALSE;
+ return;
}
if (NewFlags.Vm)
ULONG Es, Ds, Fs, Gs;
/* Pop ESP, SS, ES, FS, GS */
- if (!Fast486StackPop(State, &StackPtr)) return FALSE;
- if (!Fast486StackPop(State, &StackSel)) return FALSE;
- if (!Fast486StackPop(State, &Es)) return FALSE;
- if (!Fast486StackPop(State, &Ds)) return FALSE;
- if (!Fast486StackPop(State, &Fs)) return FALSE;
- if (!Fast486StackPop(State, &Gs)) return FALSE;
+ if (!Fast486StackPop(State, &StackPtr)) return;
+ if (!Fast486StackPop(State, &StackSel)) return;
+ if (!Fast486StackPop(State, &Es)) return;
+ if (!Fast486StackPop(State, &Ds)) return;
+ if (!Fast486StackPop(State, &Fs)) return;
+ if (!Fast486StackPop(State, &Gs)) return;
/* Set the new IP */
State->InstPtr.Long = LOWORD(InstPtr);
State->Flags.AlwaysSet = State->Flags.Vm = TRUE;
/* Load the new segments */
- if (!Fast486LoadSegment(State, FAST486_REG_CS, CodeSel)) return FALSE;
- if (!Fast486LoadSegment(State, FAST486_REG_SS, StackSel)) return FALSE;
- if (!Fast486LoadSegment(State, FAST486_REG_ES, Es)) return FALSE;
- if (!Fast486LoadSegment(State, FAST486_REG_DS, Ds)) return FALSE;
- if (!Fast486LoadSegment(State, FAST486_REG_FS, Fs)) return FALSE;
- if (!Fast486LoadSegment(State, FAST486_REG_GS, Gs)) return FALSE;
+ if (!Fast486LoadSegment(State, FAST486_REG_CS, CodeSel)) return;
+ if (!Fast486LoadSegment(State, FAST486_REG_SS, StackSel)) return;
+ if (!Fast486LoadSegment(State, FAST486_REG_ES, Es)) return;
+ if (!Fast486LoadSegment(State, FAST486_REG_DS, Ds)) return;
+ if (!Fast486LoadSegment(State, FAST486_REG_FS, Fs)) return;
+ if (!Fast486LoadSegment(State, FAST486_REG_GS, Gs)) return;
- return TRUE;
+ return;
}
/* Load the new CS */
if (!Fast486LoadSegment(State, FAST486_REG_CS, CodeSel))
{
/* Exception occurred */
- return FALSE;
+ return;
}
/* Set EIP */
if (!Fast486StackPop(State, &StackPtr))
{
/* Exception */
- return FALSE;
+ return;
}
/* Pop SS */
if (!Fast486StackPop(State, &StackSel))
{
/* Exception */
- return FALSE;
+ return;
}
/* Load new SS */
if (!Fast486LoadSegment(State, FAST486_REG_SS, StackSel))
{
/* Exception */
- return FALSE;
+ return;
}
/* Set ESP */
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;
|| !State->SegmentRegs[i].DirConf))
{
/* Load the NULL descriptor in the segment */
- if (!Fast486LoadSegment(State, i, 0)) return FALSE;
+ if (!Fast486LoadSegment(State, i, 0)) return;
}
}
}
{
/* Invalid */
Fast486ExceptionWithErrorCode(State, FAST486_EXCEPTION_GP, 0);
- return FALSE;
+ return;
}
/* Set new EIP */
if (!Fast486LoadSegment(State, FAST486_REG_CS, CodeSel))
{
/* Exception occurred */
- return FALSE;
+ return;
}
/* Set the new flags */
else State->Flags.LowWord = NewFlags.LowWord & REAL_MODE_FLAGS_MASK;
State->Flags.AlwaysSet = TRUE;
}
-
- return TRUE;
}
FAST486_OPCODE_HANDLER(Fast486OpcodeAam)
if (!Fast486FetchByte(State, &Base))
{
/* Exception occurred */
- return FALSE;
+ return;
}
/* Check if the base is zero */
{
/* Divide error */
Fast486Exception(State, FAST486_EXCEPTION_DE);
- return FALSE;
+ return;
}
/* Adjust */
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;
}
FAST486_OPCODE_HANDLER(Fast486OpcodeAad)
if (!Fast486FetchByte(State, &Base))
{
/* Exception occurred */
- return FALSE;
+ return;
}
/* 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;
}
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
+ (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,
FALSE,
&Value,
sizeof(UCHAR)))
{
/* Exception occurred */
- return FALSE;
+ return;
}
/* Set AL to the result */
State->GeneralRegs[FAST486_REG_EAX].LowByte = Value;
-
- /* Return success */
- return TRUE;
}
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);
/* Additional rule for LOOPNZ */
if (State->Flags.Zf) Condition = FALSE;
}
-
- if (Opcode == 0xE1)
+ else if (Opcode == 0xE1)
{
/* Additional rule for LOOPZ */
if (!State->Flags.Zf) Condition = FALSE;
if (!Fast486FetchByte(State, (PUCHAR)&Offset))
{
/* An exception occurred */
- return FALSE;
+ return;
}
if (Condition)
{
/* Move the instruction pointer */
- State->InstPtr.Long += Offset;
+ if (Size) State->InstPtr.Long += Offset;
+ else State->InstPtr.LowWord += Offset;
}
-
- return TRUE;
}
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);
if (!Fast486FetchByte(State, (PUCHAR)&Offset))
{
/* An exception occurred */
- return FALSE;
+ return;
}
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;
}
FAST486_OPCODE_HANDLER(Fast486OpcodeCall)
if (!Fast486FetchDword(State, (PULONG)&Offset))
{
/* An exception occurred */
- return FALSE;
+ return;
}
/* Push the current value of the instruction pointer */
if (!Fast486StackPush(State, State->InstPtr.Long))
{
/* Exception occurred */
- return FALSE;
+ return;
}
- /* Move the instruction pointer */
+ /* Move the instruction pointer */
State->InstPtr.Long += Offset;
}
else
if (!Fast486FetchWord(State, (PUSHORT)&Offset))
{
/* An exception occurred */
- return FALSE;
+ return;
}
/* Push the current value of the instruction pointer */
if (!Fast486StackPush(State, State->InstPtr.Long))
{
/* Exception occurred */
- return FALSE;
+ return;
}
- /* Move the instruction pointer */
+ /* Move the instruction pointer */
State->InstPtr.LowWord += Offset;
}
-
- return TRUE;
}
FAST486_OPCODE_HANDLER(Fast486OpcodeJmp)
if (!Fast486FetchDword(State, (PULONG)&Offset))
{
/* An exception occurred */
- return FALSE;
+ return;
}
- /* Move the instruction pointer */
+ /* Move the instruction pointer */
State->InstPtr.Long += Offset;
}
else
if (!Fast486FetchWord(State, (PUSHORT)&Offset))
{
/* An exception occurred */
- return FALSE;
+ return;
}
- /* Move the instruction pointer */
- State->InstPtr.LowWord += Offset;
- }
+ /* Move the instruction pointer */
+ State->InstPtr.Long += Offset;
- return TRUE;
+ /* Clear the top half of EIP */
+ State->InstPtr.Long &= 0xFFFF;
+ }
}
FAST486_OPCODE_HANDLER(Fast486OpcodeJmpAbs)
if (!Fast486FetchDword(State, &Offset))
{
/* Exception occurred */
- return FALSE;
+ return;
}
}
else
if (!Fast486FetchWord(State, (PUSHORT)&Offset))
{
/* Exception occurred */
- return FALSE;
+ return;
}
}
if (!Fast486FetchWord(State, &Segment))
{
/* Exception occurred */
- return FALSE;
+ return;
}
/* Load the new CS */
if (!Fast486LoadSegment(State, FAST486_REG_CS, Segment))
{
/* Exception occurred */
- return FALSE;
+ return;
}
- /* Load new (E)IP */
- if (Size) State->InstPtr.Long = Offset;
- else State->InstPtr.LowWord = LOWORD(Offset);
-
- return TRUE;
+ /* Load new EIP */
+ State->InstPtr.Long = Offset;
}
FAST486_OPCODE_HANDLER(Fast486OpcodeMovAlOffset)
{
- BOOLEAN Size = State->SegmentRegs[FAST486_REG_CS].Size;
+ BOOLEAN AddressSize = State->SegmentRegs[FAST486_REG_CS].Size;
ULONG Offset;
/* Make sure this is the right instruction */
ASSERT(Opcode == 0xA0);
- TOGGLE_OPSIZE(Size);
+ TOGGLE_ADSIZE(AddressSize);
- if (Size)
+ if (AddressSize)
{
if (!Fast486FetchDword(State, &Offset))
{
/* Exception occurred */
- return FALSE;
+ return;
}
}
else
if (!Fast486FetchWord(State, &WordOffset))
{
/* Exception occurred */
- return FALSE;
+ return;
}
Offset = (ULONG)WordOffset;
}
/* Read from memory */
- return Fast486ReadMemory(State,
- (State->PrefixFlags & FAST486_PREFIX_SEG) ?
- State->SegmentOverride : FAST486_REG_DS,
- Offset,
- FALSE,
- &State->GeneralRegs[FAST486_REG_EAX].LowByte,
- sizeof(UCHAR));
+ Fast486ReadMemory(State,
+ (State->PrefixFlags & FAST486_PREFIX_SEG) ?
+ State->SegmentOverride : FAST486_REG_DS,
+ Offset,
+ FALSE,
+ &State->GeneralRegs[FAST486_REG_EAX].LowByte,
+ sizeof(UCHAR));
}
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;
if (!Fast486FetchDword(State, &Offset))
{
/* Exception occurred */
- return FALSE;
+ return;
}
/* 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)
+ {
+ Fast486ReadMemory(State,
+ (State->PrefixFlags & FAST486_PREFIX_SEG) ?
+ State->SegmentOverride : FAST486_REG_DS,
+ Offset,
+ FALSE,
+ &State->GeneralRegs[FAST486_REG_EAX].Long,
+ sizeof(ULONG));
+ }
+ else
+ {
+ Fast486ReadMemory(State,
+ (State->PrefixFlags & FAST486_PREFIX_SEG) ?
+ State->SegmentOverride : FAST486_REG_DS,
+ Offset,
+ FALSE,
+ &State->GeneralRegs[FAST486_REG_EAX].LowWord,
+ sizeof(USHORT));
+ }
}
else
{
if (!Fast486FetchWord(State, &Offset))
{
/* Exception occurred */
- return FALSE;
+ return;
}
/* 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)
+ {
+ Fast486ReadMemory(State,
+ (State->PrefixFlags & FAST486_PREFIX_SEG) ?
+ State->SegmentOverride : FAST486_REG_DS,
+ Offset,
+ FALSE,
+ &State->GeneralRegs[FAST486_REG_EAX].Long,
+ sizeof(ULONG));
+ }
+ else
+ {
+ 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))
{
/* Exception occurred */
- return FALSE;
+ return;
}
}
else
if (!Fast486FetchWord(State, &WordOffset))
{
/* Exception occurred */
- return FALSE;
+ return;
}
Offset = (ULONG)WordOffset;
}
/* Write to memory */
- return Fast486WriteMemory(State,
- (State->PrefixFlags & FAST486_PREFIX_SEG) ?
- State->SegmentOverride : FAST486_REG_DS,
- Offset,
- &State->GeneralRegs[FAST486_REG_EAX].LowByte,
- sizeof(UCHAR));
+ Fast486WriteMemory(State,
+ (State->PrefixFlags & FAST486_PREFIX_SEG) ?
+ State->SegmentOverride : FAST486_REG_DS,
+ Offset,
+ &State->GeneralRegs[FAST486_REG_EAX].LowByte,
+ sizeof(UCHAR));
}
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;
if (!Fast486FetchDword(State, &Offset))
{
/* Exception occurred */
- return FALSE;
+ return;
}
/* 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)
+ {
+ Fast486WriteMemory(State,
+ (State->PrefixFlags & FAST486_PREFIX_SEG) ?
+ State->SegmentOverride : FAST486_REG_DS,
+ Offset,
+ &State->GeneralRegs[FAST486_REG_EAX].Long,
+ sizeof(ULONG));
+ }
+ else
+ {
+ Fast486WriteMemory(State,
+ (State->PrefixFlags & FAST486_PREFIX_SEG) ?
+ State->SegmentOverride : FAST486_REG_DS,
+ Offset,
+ &State->GeneralRegs[FAST486_REG_EAX].LowWord,
+ sizeof(USHORT));
+ }
}
else
{
if (!Fast486FetchWord(State, &Offset))
{
/* Exception occurred */
- return FALSE;
+ return;
}
/* 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)
+ {
+ Fast486WriteMemory(State,
+ (State->PrefixFlags & FAST486_PREFIX_SEG) ?
+ State->SegmentOverride : FAST486_REG_DS,
+ Offset,
+ &State->GeneralRegs[FAST486_REG_EAX].Long,
+ sizeof(ULONG));
+ }
+ else
+ {
+ Fast486WriteMemory(State,
+ (State->PrefixFlags & FAST486_PREFIX_SEG) ?
+ State->SegmentOverride : FAST486_REG_DS,
+ Offset,
+ &State->GeneralRegs[FAST486_REG_EAX].LowWord,
+ sizeof(USHORT));
+ }
}
}
FAST486_OPCODE_HANDLER(Fast486OpcodeSalc)
{
+ /*
+ * See: http://www.rcollins.org/secrets/opcodes/SALC.html
+ * for more information.
+ */
+
/* Make sure this is the right instruction */
ASSERT(Opcode == 0xD6);
/* Set all the bits of AL to CF */
State->GeneralRegs[FAST486_REG_EAX].LowByte = State->Flags.Cf ? 0xFF : 0x00;
-
- return TRUE;
}
FAST486_OPCODE_HANDLER(Fast486OpcodeMovs)
Segment = State->SegmentOverride;
}
+ 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)))
+ {
+ /* Do nothing */
+ return;
+ }
+ }
+
/* 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;
+ }
- /* 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;
+ }
- /* 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 | FAST486_PREFIX_REPNZ))
+ {
+ if (AddressSize)
{
- if (!State->Flags.Df)
+ if (--State->GeneralRegs[FAST486_REG_ECX].Long)
{
- 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;
+ /* 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;
}
}
}
-
- /* Return success */
- return TRUE;
}
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;
+ }
+ }
+
/* 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,
DataSize))
{
/* Exception occurred */
- return FALSE;
+ return;
}
/* Read from the second source operand */
DataSize))
{
/* Exception occurred */
- return FALSE;
+ return;
}
/* Calculate the result */
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)
{
|| (State->PrefixFlags & FAST486_PREFIX_REPNZ))
{
BOOLEAN Repeat = TRUE;
-
- if (OperandSize)
+
+ if (AddressSize)
{
if ((--State->GeneralRegs[FAST486_REG_ECX].Long) == 0)
{
State->InstPtr = State->SavedInstPtr;
}
}
-
- /* Return success */
- return TRUE;
}
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 = 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 */
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 */
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 */
- return FALSE;
+ return;
}
if (!State->Flags.Df)
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
DataSize))
{
/* Exception occurred */
- return FALSE;
+ return;
}
/* 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;
else State->GeneralRegs[FAST486_REG_EDI].LowWord -= DataSize;
}
}
-
- /* Return success */
- return TRUE;
}
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 = 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 */
- if (Count == 0) return TRUE;
+ if (Count == 0) return;
/* Only the last entry will be loaded */
if (!State->Flags.Df)
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 */
DataSize))
{
/* Exception occurred */
- return FALSE;
+ return;
}
/* 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;
if (!State->Flags.Df) State->GeneralRegs[FAST486_REG_ESI].LowWord += DataSize;
else State->GeneralRegs[FAST486_REG_ESI].LowWord -= DataSize;
}
-
- /* Return success */
- return TRUE;
}
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;
+ }
+ }
+
/* 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,
DataSize))
{
/* Exception occurred */
- return FALSE;
+ return;
}
/* Calculate the result */
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;
|| (State->PrefixFlags & FAST486_PREFIX_REPNZ))
{
BOOLEAN Repeat = TRUE;
-
- if (OperandSize)
+
+ if (AddressSize)
{
if ((--State->GeneralRegs[FAST486_REG_ECX].Long) == 0)
{
State->InstPtr = State->SavedInstPtr;
}
}
-
- /* Return success */
- return TRUE;
}
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 = 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 */
State->IoReadCallback(State,
State->GeneralRegs[FAST486_REG_EDX].LowWord,
Block,
- Processed * DataSize);
+ Processed,
+ DataSize);
if (State->Flags.Df)
{
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 */
- return FALSE;
+ return;
}
if (!State->Flags.Df)
}
/* 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
State->IoReadCallback(State,
State->GeneralRegs[FAST486_REG_EDX].LowWord,
&Data,
+ 1,
DataSize);
/* Write to the destination operand */
DataSize))
{
/* Exception occurred */
- return FALSE;
+ return;
}
/* 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;
else State->GeneralRegs[FAST486_REG_EDI].LowWord -= DataSize;
}
}
-
- /* Return success */
- return TRUE;
}
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 = 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 */
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;
/* 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))
{
/* 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 */
- return FALSE;
+ return;
}
if (State->Flags.Df)
{
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++)
State->IoWriteCallback(State,
State->GeneralRegs[FAST486_REG_EDX].LowWord,
Block,
- Processed * DataSize);
+ Processed,
+ DataSize);
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 */
}
/* 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
/* 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,
DataSize))
{
/* Exception occurred */
- return FALSE;
+ return;
}
/* Write to the I/O port */
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;
else State->GeneralRegs[FAST486_REG_ESI].LowWord -= DataSize;
}
}
-
- /* Return success */
- return TRUE;
}
+
+/* EOF */