mirror of
https://github.com/reactos/reactos.git
synced 2025-02-23 17:05:46 +00:00
[SOFT386]
Implement the OR, AND and XOR instructions. svn path=/branches/ntvdm/; revision=59991
This commit is contained in:
parent
9fd42c0f7d
commit
f0040c12e8
2 changed files with 830 additions and 18 deletions
|
@ -32,12 +32,12 @@ Soft386OpcodeHandlers[SOFT386_NUM_OPCODE_HANDLERS] =
|
|||
Soft386OpcodeAddEax,
|
||||
NULL, // TODO: OPCODE 0x06 NOT SUPPORTED
|
||||
NULL, // TODO: OPCODE 0x07 NOT SUPPORTED
|
||||
NULL, // TODO: OPCODE 0x08 NOT SUPPORTED
|
||||
NULL, // TODO: OPCODE 0x09 NOT SUPPORTED
|
||||
NULL, // TODO: OPCODE 0x0A NOT SUPPORTED
|
||||
NULL, // TODO: OPCODE 0x0B NOT SUPPORTED
|
||||
NULL, // TODO: OPCODE 0x0C NOT SUPPORTED
|
||||
NULL, // TODO: OPCODE 0x0D NOT SUPPORTED
|
||||
Soft386OpcodeOrByteModrm,
|
||||
Soft386OpcodeOrModrm,
|
||||
Soft386OpcodeOrByteModrm,
|
||||
Soft386OpcodeOrModrm,
|
||||
Soft386OpcodeOrAl,
|
||||
Soft386OpcodeOrEax,
|
||||
NULL, // TODO: OPCODE 0x0E NOT SUPPORTED
|
||||
NULL, // TODO: OPCODE 0x0F NOT SUPPORTED
|
||||
NULL, // TODO: OPCODE 0x10 NOT SUPPORTED
|
||||
|
@ -56,12 +56,12 @@ Soft386OpcodeHandlers[SOFT386_NUM_OPCODE_HANDLERS] =
|
|||
NULL, // TODO: OPCODE 0x1D NOT SUPPORTED
|
||||
NULL, // TODO: OPCODE 0x1E NOT SUPPORTED
|
||||
NULL, // TODO: OPCODE 0x1F NOT SUPPORTED
|
||||
NULL, // TODO: OPCODE 0x20 NOT SUPPORTED
|
||||
NULL, // TODO: OPCODE 0x21 NOT SUPPORTED
|
||||
NULL, // TODO: OPCODE 0x22 NOT SUPPORTED
|
||||
NULL, // TODO: OPCODE 0x23 NOT SUPPORTED
|
||||
NULL, // TODO: OPCODE 0x24 NOT SUPPORTED
|
||||
NULL, // TODO: OPCODE 0x25 NOT SUPPORTED
|
||||
Soft386OpcodeAndByteModrm,
|
||||
Soft386OpcodeAndModrm,
|
||||
Soft386OpcodeAndByteModrm,
|
||||
Soft386OpcodeAndModrm,
|
||||
Soft386OpcodeAndAl,
|
||||
Soft386OpcodeAndEax,
|
||||
Soft386OpcodePrefix,
|
||||
NULL, // TODO: OPCODE 0x27 NOT SUPPORTED
|
||||
NULL, // TODO: OPCODE 0x28 NOT SUPPORTED
|
||||
|
@ -72,12 +72,12 @@ Soft386OpcodeHandlers[SOFT386_NUM_OPCODE_HANDLERS] =
|
|||
NULL, // TODO: OPCODE 0x2D NOT SUPPORTED
|
||||
Soft386OpcodePrefix,
|
||||
NULL, // TODO: OPCODE 0x2F NOT SUPPORTED
|
||||
NULL, // TODO: OPCODE 0x30 NOT SUPPORTED
|
||||
NULL, // TODO: OPCODE 0x31 NOT SUPPORTED
|
||||
NULL, // TODO: OPCODE 0x32 NOT SUPPORTED
|
||||
NULL, // TODO: OPCODE 0x33 NOT SUPPORTED
|
||||
NULL, // TODO: OPCODE 0x34 NOT SUPPORTED
|
||||
NULL, // TODO: OPCODE 0x35 NOT SUPPORTED
|
||||
Soft386OpcodeXorByteModrm,
|
||||
Soft386OpcodeXorModrm,
|
||||
Soft386OpcodeXorByteModrm,
|
||||
Soft386OpcodeXorModrm,
|
||||
Soft386OpcodeXorAl,
|
||||
Soft386OpcodeXorEax,
|
||||
Soft386OpcodePrefix,
|
||||
NULL, // TODO: OPCODE 0x37 NOT SUPPORTED
|
||||
NULL, // TODO: OPCODE 0x38 NOT SUPPORTED
|
||||
|
@ -282,6 +282,8 @@ Soft386OpcodeHandlers[SOFT386_NUM_OPCODE_HANDLERS] =
|
|||
NULL, // TODO: OPCODE 0xFF NOT SUPPORTED
|
||||
};
|
||||
|
||||
/* PUBLIC FUNCTIONS ***********************************************************/
|
||||
|
||||
SOFT386_OPCODE_HANDLER(Soft386OpcodePrefix)
|
||||
{
|
||||
BOOLEAN Valid = FALSE;
|
||||
|
@ -1490,3 +1492,801 @@ SOFT386_OPCODE_HANDLER(Soft386OpcodeAddEax)
|
|||
|
||||
return TRUE;
|
||||
}
|
||||
|
||||
SOFT386_OPCODE_HANDLER(Soft386OpcodeOrByteModrm)
|
||||
{
|
||||
UCHAR FirstValue, SecondValue, Result;
|
||||
SOFT386_MOD_REG_RM ModRegRm;
|
||||
BOOLEAN AddressSize = State->SegmentRegs[SOFT386_REG_CS].Size;
|
||||
|
||||
/* Make sure this is the right instruction */
|
||||
ASSERT((Opcode & 0xFD) == 0x08);
|
||||
|
||||
if (State->PrefixFlags & SOFT386_PREFIX_ADSIZE)
|
||||
{
|
||||
/* The ADSIZE prefix toggles the size */
|
||||
AddressSize = !AddressSize;
|
||||
}
|
||||
else if (State->PrefixFlags
|
||||
& ~(SOFT386_PREFIX_ADSIZE
|
||||
| SOFT386_PREFIX_SEG
|
||||
| SOFT386_PREFIX_LOCK))
|
||||
{
|
||||
/* Invalid prefix */
|
||||
Soft386Exception(State, SOFT386_EXCEPTION_UD);
|
||||
return FALSE;
|
||||
}
|
||||
|
||||
/* Get the operands */
|
||||
if (!Soft386ParseModRegRm(State, AddressSize, &ModRegRm))
|
||||
{
|
||||
/* Exception occurred */
|
||||
return FALSE;
|
||||
}
|
||||
|
||||
if (!Soft386ReadModrmByteOperands(State,
|
||||
&ModRegRm,
|
||||
&FirstValue,
|
||||
&SecondValue))
|
||||
{
|
||||
/* Exception occurred */
|
||||
return FALSE;
|
||||
}
|
||||
|
||||
/* Calculate the result */
|
||||
Result = FirstValue | SecondValue;
|
||||
|
||||
/* Update the flags */
|
||||
State->Flags.Cf = FALSE;
|
||||
State->Flags.Of = FALSE;
|
||||
State->Flags.Zf = (Result == 0) ? TRUE : FALSE;
|
||||
State->Flags.Sf = (Result & SIGN_FLAG_BYTE) ? TRUE : FALSE;
|
||||
State->Flags.Pf = Soft386CalculateParity(Result);
|
||||
|
||||
/* Write back the result */
|
||||
return Soft386WriteModrmByteOperands(State,
|
||||
&ModRegRm,
|
||||
Opcode & SOFT386_OPCODE_WRITE_REG,
|
||||
Result);
|
||||
}
|
||||
|
||||
SOFT386_OPCODE_HANDLER(Soft386OpcodeOrModrm)
|
||||
{
|
||||
SOFT386_MOD_REG_RM ModRegRm;
|
||||
BOOLEAN OperandSize, AddressSize;
|
||||
|
||||
/* Make sure this is the right instruction */
|
||||
ASSERT((Opcode & 0xFD) == 0x09);
|
||||
|
||||
OperandSize = AddressSize = State->SegmentRegs[SOFT386_REG_CS].Size;
|
||||
|
||||
if (State->PrefixFlags & SOFT386_PREFIX_ADSIZE)
|
||||
{
|
||||
/* The ADSIZE prefix toggles the address size */
|
||||
AddressSize = !AddressSize;
|
||||
}
|
||||
|
||||
if (State->PrefixFlags & SOFT386_PREFIX_OPSIZE)
|
||||
{
|
||||
/* The OPSIZE prefix toggles the operand size */
|
||||
OperandSize = !OperandSize;
|
||||
}
|
||||
|
||||
if (State->PrefixFlags
|
||||
& ~(SOFT386_PREFIX_ADSIZE
|
||||
| SOFT386_PREFIX_OPSIZE
|
||||
| SOFT386_PREFIX_SEG
|
||||
| SOFT386_PREFIX_LOCK))
|
||||
{
|
||||
/* Invalid prefix */
|
||||
Soft386Exception(State, SOFT386_EXCEPTION_UD);
|
||||
return FALSE;
|
||||
}
|
||||
|
||||
/* Get the operands */
|
||||
if (!Soft386ParseModRegRm(State, AddressSize, &ModRegRm))
|
||||
{
|
||||
/* Exception occurred */
|
||||
return FALSE;
|
||||
}
|
||||
|
||||
/* Check the operand size */
|
||||
if (OperandSize)
|
||||
{
|
||||
ULONG FirstValue, SecondValue, Result;
|
||||
|
||||
if (!Soft386ReadModrmDwordOperands(State,
|
||||
&ModRegRm,
|
||||
&FirstValue,
|
||||
&SecondValue))
|
||||
{
|
||||
/* Exception occurred */
|
||||
return FALSE;
|
||||
}
|
||||
|
||||
/* Calculate the result */
|
||||
Result = FirstValue | SecondValue;
|
||||
|
||||
/* Update the flags */
|
||||
State->Flags.Cf = FALSE;
|
||||
State->Flags.Of = FALSE;
|
||||
State->Flags.Zf = (Result == 0) ? TRUE : FALSE;
|
||||
State->Flags.Sf = (Result & SIGN_FLAG_LONG) ? TRUE : FALSE;
|
||||
State->Flags.Pf = Soft386CalculateParity(Result);
|
||||
|
||||
/* Write back the result */
|
||||
return Soft386WriteModrmDwordOperands(State,
|
||||
&ModRegRm,
|
||||
Opcode & SOFT386_OPCODE_WRITE_REG,
|
||||
Result);
|
||||
}
|
||||
else
|
||||
{
|
||||
USHORT FirstValue, SecondValue, Result;
|
||||
|
||||
if (!Soft386ReadModrmWordOperands(State,
|
||||
&ModRegRm,
|
||||
&FirstValue,
|
||||
&SecondValue))
|
||||
{
|
||||
/* Exception occurred */
|
||||
return FALSE;
|
||||
}
|
||||
|
||||
/* Calculate the result */
|
||||
Result = FirstValue | SecondValue;
|
||||
|
||||
/* Update the flags */
|
||||
State->Flags.Cf = FALSE;
|
||||
State->Flags.Of = FALSE;
|
||||
State->Flags.Zf = (Result == 0) ? TRUE : FALSE;
|
||||
State->Flags.Sf = (Result & SIGN_FLAG_LONG) ? TRUE : FALSE;
|
||||
State->Flags.Pf = Soft386CalculateParity(Result);
|
||||
|
||||
/* Write back the result */
|
||||
return Soft386WriteModrmWordOperands(State,
|
||||
&ModRegRm,
|
||||
Opcode & SOFT386_OPCODE_WRITE_REG,
|
||||
Result);
|
||||
}
|
||||
}
|
||||
|
||||
SOFT386_OPCODE_HANDLER(Soft386OpcodeOrAl)
|
||||
{
|
||||
UCHAR FirstValue = State->GeneralRegs[SOFT386_REG_EAX].LowByte;
|
||||
UCHAR SecondValue, Result;
|
||||
|
||||
/* Make sure this is the right instruction */
|
||||
ASSERT(Opcode == 0x0C);
|
||||
|
||||
if (State->PrefixFlags)
|
||||
{
|
||||
/* This opcode doesn't take any prefixes */
|
||||
Soft386Exception(State, SOFT386_EXCEPTION_UD);
|
||||
return FALSE;
|
||||
}
|
||||
|
||||
if (!Soft386FetchByte(State, &SecondValue))
|
||||
{
|
||||
/* Exception occurred */
|
||||
return FALSE;
|
||||
}
|
||||
|
||||
/* Calculate the result */
|
||||
Result = FirstValue | SecondValue;
|
||||
|
||||
/* Update the flags */
|
||||
State->Flags.Cf = FALSE;
|
||||
State->Flags.Of = FALSE;
|
||||
State->Flags.Zf = (Result == 0) ? TRUE : FALSE;
|
||||
State->Flags.Sf = (Result & SIGN_FLAG_BYTE) ? TRUE : FALSE;
|
||||
State->Flags.Pf = Soft386CalculateParity(Result);
|
||||
|
||||
/* Write back the result */
|
||||
State->GeneralRegs[SOFT386_REG_EAX].LowByte = Result;
|
||||
|
||||
return TRUE;
|
||||
}
|
||||
|
||||
SOFT386_OPCODE_HANDLER(Soft386OpcodeOrEax)
|
||||
{
|
||||
BOOLEAN Size = State->SegmentRegs[SOFT386_REG_CS].Size;
|
||||
|
||||
/* Make sure this is the right instruction */
|
||||
ASSERT(Opcode == 0x0D);
|
||||
|
||||
if (State->PrefixFlags == SOFT386_PREFIX_OPSIZE)
|
||||
{
|
||||
/* The OPSIZE prefix toggles the size */
|
||||
Size = !Size;
|
||||
}
|
||||
else
|
||||
{
|
||||
/* Invalid prefix */
|
||||
Soft386Exception(State, SOFT386_EXCEPTION_UD);
|
||||
return FALSE;
|
||||
}
|
||||
|
||||
if (Size)
|
||||
{
|
||||
ULONG FirstValue = State->GeneralRegs[SOFT386_REG_EAX].Long;
|
||||
ULONG SecondValue, Result;
|
||||
|
||||
if (!Soft386FetchDword(State, &SecondValue))
|
||||
{
|
||||
/* Exception occurred */
|
||||
return FALSE;
|
||||
}
|
||||
|
||||
/* Calculate the result */
|
||||
Result = FirstValue | SecondValue;
|
||||
|
||||
/* Update the flags */
|
||||
State->Flags.Cf = FALSE;
|
||||
State->Flags.Of = FALSE;
|
||||
State->Flags.Zf = (Result == 0) ? TRUE : FALSE;
|
||||
State->Flags.Sf = (Result & SIGN_FLAG_LONG) ? TRUE : FALSE;
|
||||
State->Flags.Pf = Soft386CalculateParity(Result);
|
||||
|
||||
/* Write back the result */
|
||||
State->GeneralRegs[SOFT386_REG_EAX].Long = Result;
|
||||
}
|
||||
else
|
||||
{
|
||||
USHORT FirstValue = State->GeneralRegs[SOFT386_REG_EAX].LowWord;
|
||||
USHORT SecondValue, Result;
|
||||
|
||||
if (!Soft386FetchWord(State, &SecondValue))
|
||||
{
|
||||
/* Exception occurred */
|
||||
return FALSE;
|
||||
}
|
||||
|
||||
/* Calculate the result */
|
||||
Result = FirstValue | SecondValue;
|
||||
|
||||
/* Update the flags */
|
||||
State->Flags.Cf = FALSE;
|
||||
State->Flags.Of = FALSE;
|
||||
State->Flags.Zf = (Result == 0) ? TRUE : FALSE;
|
||||
State->Flags.Sf = (Result & SIGN_FLAG_WORD) ? TRUE : FALSE;
|
||||
State->Flags.Pf = Soft386CalculateParity(Result);
|
||||
|
||||
/* Write back the result */
|
||||
State->GeneralRegs[SOFT386_REG_EAX].LowWord = Result;
|
||||
}
|
||||
|
||||
return TRUE;
|
||||
}
|
||||
|
||||
SOFT386_OPCODE_HANDLER(Soft386OpcodeAndByteModrm)
|
||||
{
|
||||
UCHAR FirstValue, SecondValue, Result;
|
||||
SOFT386_MOD_REG_RM ModRegRm;
|
||||
BOOLEAN AddressSize = State->SegmentRegs[SOFT386_REG_CS].Size;
|
||||
|
||||
/* Make sure this is the right instruction */
|
||||
ASSERT((Opcode & 0xFD) == 0x20);
|
||||
|
||||
if (State->PrefixFlags & SOFT386_PREFIX_ADSIZE)
|
||||
{
|
||||
/* The ADSIZE prefix toggles the size */
|
||||
AddressSize = !AddressSize;
|
||||
}
|
||||
else if (State->PrefixFlags
|
||||
& ~(SOFT386_PREFIX_ADSIZE
|
||||
| SOFT386_PREFIX_SEG
|
||||
| SOFT386_PREFIX_LOCK))
|
||||
{
|
||||
/* Invalid prefix */
|
||||
Soft386Exception(State, SOFT386_EXCEPTION_UD);
|
||||
return FALSE;
|
||||
}
|
||||
|
||||
/* Get the operands */
|
||||
if (!Soft386ParseModRegRm(State, AddressSize, &ModRegRm))
|
||||
{
|
||||
/* Exception occurred */
|
||||
return FALSE;
|
||||
}
|
||||
|
||||
if (!Soft386ReadModrmByteOperands(State,
|
||||
&ModRegRm,
|
||||
&FirstValue,
|
||||
&SecondValue))
|
||||
{
|
||||
/* Exception occurred */
|
||||
return FALSE;
|
||||
}
|
||||
|
||||
/* Calculate the result */
|
||||
Result = FirstValue & SecondValue;
|
||||
|
||||
/* Update the flags */
|
||||
State->Flags.Cf = FALSE;
|
||||
State->Flags.Of = FALSE;
|
||||
State->Flags.Zf = (Result == 0) ? TRUE : FALSE;
|
||||
State->Flags.Sf = (Result & SIGN_FLAG_BYTE) ? TRUE : FALSE;
|
||||
State->Flags.Pf = Soft386CalculateParity(Result);
|
||||
|
||||
/* Write back the result */
|
||||
return Soft386WriteModrmByteOperands(State,
|
||||
&ModRegRm,
|
||||
Opcode & SOFT386_OPCODE_WRITE_REG,
|
||||
Result);
|
||||
}
|
||||
|
||||
SOFT386_OPCODE_HANDLER(Soft386OpcodeAndModrm)
|
||||
{
|
||||
SOFT386_MOD_REG_RM ModRegRm;
|
||||
BOOLEAN OperandSize, AddressSize;
|
||||
|
||||
/* Make sure this is the right instruction */
|
||||
ASSERT((Opcode & 0xFD) == 0x21);
|
||||
|
||||
OperandSize = AddressSize = State->SegmentRegs[SOFT386_REG_CS].Size;
|
||||
|
||||
if (State->PrefixFlags & SOFT386_PREFIX_ADSIZE)
|
||||
{
|
||||
/* The ADSIZE prefix toggles the address size */
|
||||
AddressSize = !AddressSize;
|
||||
}
|
||||
|
||||
if (State->PrefixFlags & SOFT386_PREFIX_OPSIZE)
|
||||
{
|
||||
/* The OPSIZE prefix toggles the operand size */
|
||||
OperandSize = !OperandSize;
|
||||
}
|
||||
|
||||
if (State->PrefixFlags
|
||||
& ~(SOFT386_PREFIX_ADSIZE
|
||||
| SOFT386_PREFIX_OPSIZE
|
||||
| SOFT386_PREFIX_SEG
|
||||
| SOFT386_PREFIX_LOCK))
|
||||
{
|
||||
/* Invalid prefix */
|
||||
Soft386Exception(State, SOFT386_EXCEPTION_UD);
|
||||
return FALSE;
|
||||
}
|
||||
|
||||
/* Get the operands */
|
||||
if (!Soft386ParseModRegRm(State, AddressSize, &ModRegRm))
|
||||
{
|
||||
/* Exception occurred */
|
||||
return FALSE;
|
||||
}
|
||||
|
||||
/* Check the operand size */
|
||||
if (OperandSize)
|
||||
{
|
||||
ULONG FirstValue, SecondValue, Result;
|
||||
|
||||
if (!Soft386ReadModrmDwordOperands(State,
|
||||
&ModRegRm,
|
||||
&FirstValue,
|
||||
&SecondValue))
|
||||
{
|
||||
/* Exception occurred */
|
||||
return FALSE;
|
||||
}
|
||||
|
||||
/* Calculate the result */
|
||||
Result = FirstValue & SecondValue;
|
||||
|
||||
/* Update the flags */
|
||||
State->Flags.Cf = FALSE;
|
||||
State->Flags.Of = FALSE;
|
||||
State->Flags.Zf = (Result == 0) ? TRUE : FALSE;
|
||||
State->Flags.Sf = (Result & SIGN_FLAG_LONG) ? TRUE : FALSE;
|
||||
State->Flags.Pf = Soft386CalculateParity(Result);
|
||||
|
||||
/* Write back the result */
|
||||
return Soft386WriteModrmDwordOperands(State,
|
||||
&ModRegRm,
|
||||
Opcode & SOFT386_OPCODE_WRITE_REG,
|
||||
Result);
|
||||
}
|
||||
else
|
||||
{
|
||||
USHORT FirstValue, SecondValue, Result;
|
||||
|
||||
if (!Soft386ReadModrmWordOperands(State,
|
||||
&ModRegRm,
|
||||
&FirstValue,
|
||||
&SecondValue))
|
||||
{
|
||||
/* Exception occurred */
|
||||
return FALSE;
|
||||
}
|
||||
|
||||
/* Calculate the result */
|
||||
Result = FirstValue & SecondValue;
|
||||
|
||||
/* Update the flags */
|
||||
State->Flags.Cf = FALSE;
|
||||
State->Flags.Of = FALSE;
|
||||
State->Flags.Zf = (Result == 0) ? TRUE : FALSE;
|
||||
State->Flags.Sf = (Result & SIGN_FLAG_LONG) ? TRUE : FALSE;
|
||||
State->Flags.Pf = Soft386CalculateParity(Result);
|
||||
|
||||
/* Write back the result */
|
||||
return Soft386WriteModrmWordOperands(State,
|
||||
&ModRegRm,
|
||||
Opcode & SOFT386_OPCODE_WRITE_REG,
|
||||
Result);
|
||||
}
|
||||
}
|
||||
|
||||
SOFT386_OPCODE_HANDLER(Soft386OpcodeAndAl)
|
||||
{
|
||||
UCHAR FirstValue = State->GeneralRegs[SOFT386_REG_EAX].LowByte;
|
||||
UCHAR SecondValue, Result;
|
||||
|
||||
/* Make sure this is the right instruction */
|
||||
ASSERT(Opcode == 0x24);
|
||||
|
||||
if (State->PrefixFlags)
|
||||
{
|
||||
/* This opcode doesn't take any prefixes */
|
||||
Soft386Exception(State, SOFT386_EXCEPTION_UD);
|
||||
return FALSE;
|
||||
}
|
||||
|
||||
if (!Soft386FetchByte(State, &SecondValue))
|
||||
{
|
||||
/* Exception occurred */
|
||||
return FALSE;
|
||||
}
|
||||
|
||||
/* Calculate the result */
|
||||
Result = FirstValue & SecondValue;
|
||||
|
||||
/* Update the flags */
|
||||
State->Flags.Cf = FALSE;
|
||||
State->Flags.Of = FALSE;
|
||||
State->Flags.Zf = (Result == 0) ? TRUE : FALSE;
|
||||
State->Flags.Sf = (Result & SIGN_FLAG_BYTE) ? TRUE : FALSE;
|
||||
State->Flags.Pf = Soft386CalculateParity(Result);
|
||||
|
||||
/* Write back the result */
|
||||
State->GeneralRegs[SOFT386_REG_EAX].LowByte = Result;
|
||||
|
||||
return TRUE;
|
||||
}
|
||||
|
||||
SOFT386_OPCODE_HANDLER(Soft386OpcodeAndEax)
|
||||
{
|
||||
BOOLEAN Size = State->SegmentRegs[SOFT386_REG_CS].Size;
|
||||
|
||||
/* Make sure this is the right instruction */
|
||||
ASSERT(Opcode == 0x25);
|
||||
|
||||
if (State->PrefixFlags == SOFT386_PREFIX_OPSIZE)
|
||||
{
|
||||
/* The OPSIZE prefix toggles the size */
|
||||
Size = !Size;
|
||||
}
|
||||
else
|
||||
{
|
||||
/* Invalid prefix */
|
||||
Soft386Exception(State, SOFT386_EXCEPTION_UD);
|
||||
return FALSE;
|
||||
}
|
||||
|
||||
if (Size)
|
||||
{
|
||||
ULONG FirstValue = State->GeneralRegs[SOFT386_REG_EAX].Long;
|
||||
ULONG SecondValue, Result;
|
||||
|
||||
if (!Soft386FetchDword(State, &SecondValue))
|
||||
{
|
||||
/* Exception occurred */
|
||||
return FALSE;
|
||||
}
|
||||
|
||||
/* Calculate the result */
|
||||
Result = FirstValue & SecondValue;
|
||||
|
||||
/* Update the flags */
|
||||
State->Flags.Cf = FALSE;
|
||||
State->Flags.Of = FALSE;
|
||||
State->Flags.Zf = (Result == 0) ? TRUE : FALSE;
|
||||
State->Flags.Sf = (Result & SIGN_FLAG_LONG) ? TRUE : FALSE;
|
||||
State->Flags.Pf = Soft386CalculateParity(Result);
|
||||
|
||||
/* Write back the result */
|
||||
State->GeneralRegs[SOFT386_REG_EAX].Long = Result;
|
||||
}
|
||||
else
|
||||
{
|
||||
USHORT FirstValue = State->GeneralRegs[SOFT386_REG_EAX].LowWord;
|
||||
USHORT SecondValue, Result;
|
||||
|
||||
if (!Soft386FetchWord(State, &SecondValue))
|
||||
{
|
||||
/* Exception occurred */
|
||||
return FALSE;
|
||||
}
|
||||
|
||||
/* Calculate the result */
|
||||
Result = FirstValue & SecondValue;
|
||||
|
||||
/* Update the flags */
|
||||
State->Flags.Cf = FALSE;
|
||||
State->Flags.Of = FALSE;
|
||||
State->Flags.Zf = (Result == 0) ? TRUE : FALSE;
|
||||
State->Flags.Sf = (Result & SIGN_FLAG_WORD) ? TRUE : FALSE;
|
||||
State->Flags.Pf = Soft386CalculateParity(Result);
|
||||
|
||||
/* Write back the result */
|
||||
State->GeneralRegs[SOFT386_REG_EAX].LowWord = Result;
|
||||
}
|
||||
|
||||
return TRUE;
|
||||
}
|
||||
|
||||
SOFT386_OPCODE_HANDLER(Soft386OpcodeXorByteModrm)
|
||||
{
|
||||
UCHAR FirstValue, SecondValue, Result;
|
||||
SOFT386_MOD_REG_RM ModRegRm;
|
||||
BOOLEAN AddressSize = State->SegmentRegs[SOFT386_REG_CS].Size;
|
||||
|
||||
/* Make sure this is the right instruction */
|
||||
ASSERT((Opcode & 0xFD) == 0x30);
|
||||
|
||||
if (State->PrefixFlags & SOFT386_PREFIX_ADSIZE)
|
||||
{
|
||||
/* The ADSIZE prefix toggles the size */
|
||||
AddressSize = !AddressSize;
|
||||
}
|
||||
else if (State->PrefixFlags
|
||||
& ~(SOFT386_PREFIX_ADSIZE
|
||||
| SOFT386_PREFIX_SEG
|
||||
| SOFT386_PREFIX_LOCK))
|
||||
{
|
||||
/* Invalid prefix */
|
||||
Soft386Exception(State, SOFT386_EXCEPTION_UD);
|
||||
return FALSE;
|
||||
}
|
||||
|
||||
/* Get the operands */
|
||||
if (!Soft386ParseModRegRm(State, AddressSize, &ModRegRm))
|
||||
{
|
||||
/* Exception occurred */
|
||||
return FALSE;
|
||||
}
|
||||
|
||||
if (!Soft386ReadModrmByteOperands(State,
|
||||
&ModRegRm,
|
||||
&FirstValue,
|
||||
&SecondValue))
|
||||
{
|
||||
/* Exception occurred */
|
||||
return FALSE;
|
||||
}
|
||||
|
||||
/* Calculate the result */
|
||||
Result = FirstValue ^ SecondValue;
|
||||
|
||||
/* Update the flags */
|
||||
State->Flags.Cf = FALSE;
|
||||
State->Flags.Of = FALSE;
|
||||
State->Flags.Zf = (Result == 0) ? TRUE : FALSE;
|
||||
State->Flags.Sf = (Result & SIGN_FLAG_BYTE) ? TRUE : FALSE;
|
||||
State->Flags.Pf = Soft386CalculateParity(Result);
|
||||
|
||||
/* Write back the result */
|
||||
return Soft386WriteModrmByteOperands(State,
|
||||
&ModRegRm,
|
||||
Opcode & SOFT386_OPCODE_WRITE_REG,
|
||||
Result);
|
||||
}
|
||||
|
||||
SOFT386_OPCODE_HANDLER(Soft386OpcodeXorModrm)
|
||||
{
|
||||
SOFT386_MOD_REG_RM ModRegRm;
|
||||
BOOLEAN OperandSize, AddressSize;
|
||||
|
||||
/* Make sure this is the right instruction */
|
||||
ASSERT((Opcode & 0xFD) == 0x31);
|
||||
|
||||
OperandSize = AddressSize = State->SegmentRegs[SOFT386_REG_CS].Size;
|
||||
|
||||
if (State->PrefixFlags & SOFT386_PREFIX_ADSIZE)
|
||||
{
|
||||
/* The ADSIZE prefix toggles the address size */
|
||||
AddressSize = !AddressSize;
|
||||
}
|
||||
|
||||
if (State->PrefixFlags & SOFT386_PREFIX_OPSIZE)
|
||||
{
|
||||
/* The OPSIZE prefix toggles the operand size */
|
||||
OperandSize = !OperandSize;
|
||||
}
|
||||
|
||||
if (State->PrefixFlags
|
||||
& ~(SOFT386_PREFIX_ADSIZE
|
||||
| SOFT386_PREFIX_OPSIZE
|
||||
| SOFT386_PREFIX_SEG
|
||||
| SOFT386_PREFIX_LOCK))
|
||||
{
|
||||
/* Invalid prefix */
|
||||
Soft386Exception(State, SOFT386_EXCEPTION_UD);
|
||||
return FALSE;
|
||||
}
|
||||
|
||||
/* Get the operands */
|
||||
if (!Soft386ParseModRegRm(State, AddressSize, &ModRegRm))
|
||||
{
|
||||
/* Exception occurred */
|
||||
return FALSE;
|
||||
}
|
||||
|
||||
/* Check the operand size */
|
||||
if (OperandSize)
|
||||
{
|
||||
ULONG FirstValue, SecondValue, Result;
|
||||
|
||||
if (!Soft386ReadModrmDwordOperands(State,
|
||||
&ModRegRm,
|
||||
&FirstValue,
|
||||
&SecondValue))
|
||||
{
|
||||
/* Exception occurred */
|
||||
return FALSE;
|
||||
}
|
||||
|
||||
/* Calculate the result */
|
||||
Result = FirstValue ^ SecondValue;
|
||||
|
||||
/* Update the flags */
|
||||
State->Flags.Cf = FALSE;
|
||||
State->Flags.Of = FALSE;
|
||||
State->Flags.Zf = (Result == 0) ? TRUE : FALSE;
|
||||
State->Flags.Sf = (Result & SIGN_FLAG_LONG) ? TRUE : FALSE;
|
||||
State->Flags.Pf = Soft386CalculateParity(Result);
|
||||
|
||||
/* Write back the result */
|
||||
return Soft386WriteModrmDwordOperands(State,
|
||||
&ModRegRm,
|
||||
Opcode & SOFT386_OPCODE_WRITE_REG,
|
||||
Result);
|
||||
}
|
||||
else
|
||||
{
|
||||
USHORT FirstValue, SecondValue, Result;
|
||||
|
||||
if (!Soft386ReadModrmWordOperands(State,
|
||||
&ModRegRm,
|
||||
&FirstValue,
|
||||
&SecondValue))
|
||||
{
|
||||
/* Exception occurred */
|
||||
return FALSE;
|
||||
}
|
||||
|
||||
/* Calculate the result */
|
||||
Result = FirstValue ^ SecondValue;
|
||||
|
||||
/* Update the flags */
|
||||
State->Flags.Cf = FALSE;
|
||||
State->Flags.Of = FALSE;
|
||||
State->Flags.Zf = (Result == 0) ? TRUE : FALSE;
|
||||
State->Flags.Sf = (Result & SIGN_FLAG_LONG) ? TRUE : FALSE;
|
||||
State->Flags.Pf = Soft386CalculateParity(Result);
|
||||
|
||||
/* Write back the result */
|
||||
return Soft386WriteModrmWordOperands(State,
|
||||
&ModRegRm,
|
||||
Opcode & SOFT386_OPCODE_WRITE_REG,
|
||||
Result);
|
||||
}
|
||||
}
|
||||
|
||||
SOFT386_OPCODE_HANDLER(Soft386OpcodeXorAl)
|
||||
{
|
||||
UCHAR FirstValue = State->GeneralRegs[SOFT386_REG_EAX].LowByte;
|
||||
UCHAR SecondValue, Result;
|
||||
|
||||
/* Make sure this is the right instruction */
|
||||
ASSERT(Opcode == 0x34);
|
||||
|
||||
if (State->PrefixFlags)
|
||||
{
|
||||
/* This opcode doesn't take any prefixes */
|
||||
Soft386Exception(State, SOFT386_EXCEPTION_UD);
|
||||
return FALSE;
|
||||
}
|
||||
|
||||
if (!Soft386FetchByte(State, &SecondValue))
|
||||
{
|
||||
/* Exception occurred */
|
||||
return FALSE;
|
||||
}
|
||||
|
||||
/* Calculate the result */
|
||||
Result = FirstValue ^ SecondValue;
|
||||
|
||||
/* Update the flags */
|
||||
State->Flags.Cf = FALSE;
|
||||
State->Flags.Of = FALSE;
|
||||
State->Flags.Zf = (Result == 0) ? TRUE : FALSE;
|
||||
State->Flags.Sf = (Result & SIGN_FLAG_BYTE) ? TRUE : FALSE;
|
||||
State->Flags.Pf = Soft386CalculateParity(Result);
|
||||
|
||||
/* Write back the result */
|
||||
State->GeneralRegs[SOFT386_REG_EAX].LowByte = Result;
|
||||
|
||||
return TRUE;
|
||||
}
|
||||
|
||||
SOFT386_OPCODE_HANDLER(Soft386OpcodeXorEax)
|
||||
{
|
||||
BOOLEAN Size = State->SegmentRegs[SOFT386_REG_CS].Size;
|
||||
|
||||
/* Make sure this is the right instruction */
|
||||
ASSERT(Opcode == 0x35);
|
||||
|
||||
if (State->PrefixFlags == SOFT386_PREFIX_OPSIZE)
|
||||
{
|
||||
/* The OPSIZE prefix toggles the size */
|
||||
Size = !Size;
|
||||
}
|
||||
else
|
||||
{
|
||||
/* Invalid prefix */
|
||||
Soft386Exception(State, SOFT386_EXCEPTION_UD);
|
||||
return FALSE;
|
||||
}
|
||||
|
||||
if (Size)
|
||||
{
|
||||
ULONG FirstValue = State->GeneralRegs[SOFT386_REG_EAX].Long;
|
||||
ULONG SecondValue, Result;
|
||||
|
||||
if (!Soft386FetchDword(State, &SecondValue))
|
||||
{
|
||||
/* Exception occurred */
|
||||
return FALSE;
|
||||
}
|
||||
|
||||
/* Calculate the result */
|
||||
Result = FirstValue ^ SecondValue;
|
||||
|
||||
/* Update the flags */
|
||||
State->Flags.Cf = FALSE;
|
||||
State->Flags.Of = FALSE;
|
||||
State->Flags.Zf = (Result == 0) ? TRUE : FALSE;
|
||||
State->Flags.Sf = (Result & SIGN_FLAG_LONG) ? TRUE : FALSE;
|
||||
State->Flags.Pf = Soft386CalculateParity(Result);
|
||||
|
||||
/* Write back the result */
|
||||
State->GeneralRegs[SOFT386_REG_EAX].Long = Result;
|
||||
}
|
||||
else
|
||||
{
|
||||
USHORT FirstValue = State->GeneralRegs[SOFT386_REG_EAX].LowWord;
|
||||
USHORT SecondValue, Result;
|
||||
|
||||
if (!Soft386FetchWord(State, &SecondValue))
|
||||
{
|
||||
/* Exception occurred */
|
||||
return FALSE;
|
||||
}
|
||||
|
||||
/* Calculate the result */
|
||||
Result = FirstValue ^ SecondValue;
|
||||
|
||||
/* Update the flags */
|
||||
State->Flags.Cf = FALSE;
|
||||
State->Flags.Of = FALSE;
|
||||
State->Flags.Zf = (Result == 0) ? TRUE : FALSE;
|
||||
State->Flags.Sf = (Result & SIGN_FLAG_WORD) ? TRUE : FALSE;
|
||||
State->Flags.Pf = Soft386CalculateParity(Result);
|
||||
|
||||
/* Write back the result */
|
||||
State->GeneralRegs[SOFT386_REG_EAX].LowWord = Result;
|
||||
}
|
||||
|
||||
return TRUE;
|
||||
}
|
||||
|
|
|
@ -54,5 +54,17 @@ SOFT386_OPCODE_HANDLER(Soft386OpcodeAddByteModrm);
|
|||
SOFT386_OPCODE_HANDLER(Soft386OpcodeAddModrm);
|
||||
SOFT386_OPCODE_HANDLER(Soft386OpcodeAddAl);
|
||||
SOFT386_OPCODE_HANDLER(Soft386OpcodeAddEax);
|
||||
SOFT386_OPCODE_HANDLER(Soft386OpcodeOrByteModrm);
|
||||
SOFT386_OPCODE_HANDLER(Soft386OpcodeOrModrm);
|
||||
SOFT386_OPCODE_HANDLER(Soft386OpcodeOrAl);
|
||||
SOFT386_OPCODE_HANDLER(Soft386OpcodeOrEax);
|
||||
SOFT386_OPCODE_HANDLER(Soft386OpcodeAndByteModrm);
|
||||
SOFT386_OPCODE_HANDLER(Soft386OpcodeAndModrm);
|
||||
SOFT386_OPCODE_HANDLER(Soft386OpcodeAndAl);
|
||||
SOFT386_OPCODE_HANDLER(Soft386OpcodeAndEax);
|
||||
SOFT386_OPCODE_HANDLER(Soft386OpcodeXorByteModrm);
|
||||
SOFT386_OPCODE_HANDLER(Soft386OpcodeXorModrm);
|
||||
SOFT386_OPCODE_HANDLER(Soft386OpcodeXorAl);
|
||||
SOFT386_OPCODE_HANDLER(Soft386OpcodeXorEax);
|
||||
|
||||
#endif // _OPCODES_H_
|
||||
|
|
Loading…
Reference in a new issue