mirror of
https://github.com/reactos/reactos.git
synced 2024-10-15 05:37:44 +00:00
[SOFT386]
Halfplement MOVS, STOS and LODS. Stubplement CMPS and SCAS. svn path=/branches/ntvdm/; revision=60515
This commit is contained in:
parent
c2e98bca7f
commit
c190ca817c
|
@ -203,18 +203,18 @@ Soft386OpcodeHandlers[SOFT386_NUM_OPCODE_HANDLERS] =
|
|||
Soft386OpcodeMovEaxOffset,
|
||||
Soft386OpcodeMovOffsetAl,
|
||||
Soft386OpcodeMovOffsetEax,
|
||||
NULL, // TODO: OPCODE 0xA4 NOT SUPPORTED
|
||||
NULL, // TODO: OPCODE 0xA5 NOT SUPPORTED
|
||||
NULL, // TODO: OPCODE 0xA6 NOT SUPPORTED
|
||||
NULL, // TODO: OPCODE 0xA7 NOT SUPPORTED
|
||||
Soft386OpcodeMovs,
|
||||
Soft386OpcodeMovs,
|
||||
Soft386OpcodeCmps,
|
||||
Soft386OpcodeCmps,
|
||||
Soft386OpcodeTestAl,
|
||||
Soft386OpcodeTestEax,
|
||||
NULL, // TODO: OPCODE 0xAA NOT SUPPORTED
|
||||
NULL, // TODO: OPCODE 0xAB NOT SUPPORTED
|
||||
NULL, // TODO: OPCODE 0xAC NOT SUPPORTED
|
||||
NULL, // TODO: OPCODE 0xAD NOT SUPPORTED
|
||||
NULL, // TODO: OPCODE 0xAE NOT SUPPORTED
|
||||
NULL, // TODO: OPCODE 0xAF NOT SUPPORTED
|
||||
Soft386OpcodeStos,
|
||||
Soft386OpcodeStos,
|
||||
Soft386OpcodeLods,
|
||||
Soft386OpcodeLods,
|
||||
Soft386OpcodeScas,
|
||||
Soft386OpcodeScas,
|
||||
Soft386OpcodeMovByteRegImm,
|
||||
Soft386OpcodeMovByteRegImm,
|
||||
Soft386OpcodeMovByteRegImm,
|
||||
|
@ -5606,3 +5606,263 @@ SOFT386_OPCODE_HANDLER(Soft386OpcodeSalc)
|
|||
|
||||
return TRUE;
|
||||
}
|
||||
|
||||
SOFT386_OPCODE_HANDLER(Soft386OpcodeMovs)
|
||||
{
|
||||
ULONG Data, DataSize;
|
||||
BOOLEAN OperandSize, AddressSize;
|
||||
|
||||
OperandSize = AddressSize = State->SegmentRegs[SOFT386_REG_CS].Size;
|
||||
|
||||
/* Make sure this is the right instruction */
|
||||
ASSERT((Opcode & 0xFE) == 0xA4);
|
||||
|
||||
if (State->PrefixFlags & SOFT386_PREFIX_OPSIZE)
|
||||
{
|
||||
/* The OPSIZE prefix toggles the size */
|
||||
OperandSize = !OperandSize;
|
||||
}
|
||||
|
||||
if (State->PrefixFlags & SOFT386_PREFIX_ADSIZE)
|
||||
{
|
||||
/* The ADSIZE prefix toggles the size */
|
||||
AddressSize = !AddressSize;
|
||||
}
|
||||
|
||||
if ((State->PrefixFlags & SOFT386_PREFIX_REP)
|
||||
|| (State->PrefixFlags & SOFT386_PREFIX_REPNZ))
|
||||
{
|
||||
// TODO: The REP/REPZ/REPNZ prefixes need to be implemented!
|
||||
Soft386Exception(State, SOFT386_EXCEPTION_UD);
|
||||
return FALSE;
|
||||
}
|
||||
|
||||
/* Calculate the size */
|
||||
if (Opcode == 0xA4) DataSize = sizeof(UCHAR);
|
||||
else DataSize = OperandSize ? sizeof(ULONG) : sizeof(USHORT);
|
||||
|
||||
/* Read from the source operand */
|
||||
if (!Soft386ReadMemory(State,
|
||||
SOFT386_REG_DS,
|
||||
AddressSize ? State->GeneralRegs[SOFT386_REG_ESI].Long
|
||||
: State->GeneralRegs[SOFT386_REG_ESI].LowWord,
|
||||
FALSE,
|
||||
&Data,
|
||||
DataSize))
|
||||
{
|
||||
/* Exception occurred */
|
||||
return FALSE;
|
||||
}
|
||||
|
||||
/* Write to the destination operand */
|
||||
if (!Soft386WriteMemory(State,
|
||||
SOFT386_REG_ES,
|
||||
AddressSize ? State->GeneralRegs[SOFT386_REG_EDI].Long
|
||||
: State->GeneralRegs[SOFT386_REG_EDI].LowWord,
|
||||
&Data,
|
||||
DataSize))
|
||||
{
|
||||
/* Exception occurred */
|
||||
return FALSE;
|
||||
}
|
||||
|
||||
/* Increment/decrement ESI and EDI */
|
||||
if (OperandSize)
|
||||
{
|
||||
if (State->Flags.Df)
|
||||
{
|
||||
State->GeneralRegs[SOFT386_REG_ESI].Long += DataSize;
|
||||
State->GeneralRegs[SOFT386_REG_EDI].Long += DataSize;
|
||||
}
|
||||
else
|
||||
{
|
||||
State->GeneralRegs[SOFT386_REG_ESI].Long -= DataSize;
|
||||
State->GeneralRegs[SOFT386_REG_EDI].Long -= DataSize;
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
if (State->Flags.Df)
|
||||
{
|
||||
State->GeneralRegs[SOFT386_REG_ESI].LowWord += DataSize;
|
||||
State->GeneralRegs[SOFT386_REG_EDI].LowWord += DataSize;
|
||||
}
|
||||
else
|
||||
{
|
||||
State->GeneralRegs[SOFT386_REG_ESI].LowWord -= DataSize;
|
||||
State->GeneralRegs[SOFT386_REG_EDI].LowWord -= DataSize;
|
||||
}
|
||||
}
|
||||
|
||||
/* Return success */
|
||||
return TRUE;
|
||||
}
|
||||
|
||||
SOFT386_OPCODE_HANDLER(Soft386OpcodeCmps)
|
||||
{
|
||||
UNIMPLEMENTED;
|
||||
return FALSE; // TODO: NOT IMPLEMENTED
|
||||
}
|
||||
|
||||
SOFT386_OPCODE_HANDLER(Soft386OpcodeStos)
|
||||
{
|
||||
ULONG DataSize;
|
||||
BOOLEAN OperandSize, AddressSize;
|
||||
|
||||
OperandSize = AddressSize = State->SegmentRegs[SOFT386_REG_CS].Size;
|
||||
|
||||
/* Make sure this is the right instruction */
|
||||
ASSERT((Opcode & 0xFE) == 0xAA);
|
||||
|
||||
if (State->PrefixFlags & SOFT386_PREFIX_OPSIZE)
|
||||
{
|
||||
/* The OPSIZE prefix toggles the size */
|
||||
OperandSize = !OperandSize;
|
||||
}
|
||||
|
||||
if (State->PrefixFlags & SOFT386_PREFIX_ADSIZE)
|
||||
{
|
||||
/* The ADSIZE prefix toggles the size */
|
||||
AddressSize = !AddressSize;
|
||||
}
|
||||
|
||||
if ((State->PrefixFlags & SOFT386_PREFIX_REP)
|
||||
|| (State->PrefixFlags & SOFT386_PREFIX_REPNZ))
|
||||
{
|
||||
// TODO: The REP/REPZ/REPNZ prefixes need to be implemented!
|
||||
Soft386Exception(State, SOFT386_EXCEPTION_UD);
|
||||
return FALSE;
|
||||
}
|
||||
|
||||
/* Calculate the size */
|
||||
if (Opcode == 0xAA) DataSize = sizeof(UCHAR);
|
||||
else DataSize = OperandSize ? sizeof(ULONG) : sizeof(USHORT);
|
||||
|
||||
/* Write to the destination operand */
|
||||
if (!Soft386WriteMemory(State,
|
||||
SOFT386_REG_ES,
|
||||
AddressSize ? State->GeneralRegs[SOFT386_REG_EDI].Long
|
||||
: State->GeneralRegs[SOFT386_REG_EDI].LowWord,
|
||||
&State->GeneralRegs[SOFT386_REG_EAX].Long,
|
||||
DataSize))
|
||||
{
|
||||
/* Exception occurred */
|
||||
return FALSE;
|
||||
}
|
||||
|
||||
/* Increment/decrement ESI and EDI */
|
||||
if (OperandSize)
|
||||
{
|
||||
if (State->Flags.Df)
|
||||
{
|
||||
State->GeneralRegs[SOFT386_REG_ESI].Long += DataSize;
|
||||
State->GeneralRegs[SOFT386_REG_EDI].Long += DataSize;
|
||||
}
|
||||
else
|
||||
{
|
||||
State->GeneralRegs[SOFT386_REG_ESI].Long -= DataSize;
|
||||
State->GeneralRegs[SOFT386_REG_EDI].Long -= DataSize;
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
if (State->Flags.Df)
|
||||
{
|
||||
State->GeneralRegs[SOFT386_REG_ESI].LowWord += DataSize;
|
||||
State->GeneralRegs[SOFT386_REG_EDI].LowWord += DataSize;
|
||||
}
|
||||
else
|
||||
{
|
||||
State->GeneralRegs[SOFT386_REG_ESI].LowWord -= DataSize;
|
||||
State->GeneralRegs[SOFT386_REG_EDI].LowWord -= DataSize;
|
||||
}
|
||||
}
|
||||
|
||||
/* Return success */
|
||||
return TRUE;
|
||||
}
|
||||
|
||||
SOFT386_OPCODE_HANDLER(Soft386OpcodeLods)
|
||||
{
|
||||
ULONG DataSize;
|
||||
BOOLEAN OperandSize, AddressSize;
|
||||
|
||||
OperandSize = AddressSize = State->SegmentRegs[SOFT386_REG_CS].Size;
|
||||
|
||||
/* Make sure this is the right instruction */
|
||||
ASSERT((Opcode & 0xFE) == 0xAC);
|
||||
|
||||
if (State->PrefixFlags & SOFT386_PREFIX_OPSIZE)
|
||||
{
|
||||
/* The OPSIZE prefix toggles the size */
|
||||
OperandSize = !OperandSize;
|
||||
}
|
||||
|
||||
if (State->PrefixFlags & SOFT386_PREFIX_ADSIZE)
|
||||
{
|
||||
/* The ADSIZE prefix toggles the size */
|
||||
AddressSize = !AddressSize;
|
||||
}
|
||||
|
||||
if ((State->PrefixFlags & SOFT386_PREFIX_REP)
|
||||
|| (State->PrefixFlags & SOFT386_PREFIX_REPNZ))
|
||||
{
|
||||
// TODO: The REP/REPZ/REPNZ prefixes need to be implemented!
|
||||
Soft386Exception(State, SOFT386_EXCEPTION_UD);
|
||||
return FALSE;
|
||||
}
|
||||
|
||||
/* Calculate the size */
|
||||
if (Opcode == 0xAC) DataSize = sizeof(UCHAR);
|
||||
else DataSize = OperandSize ? sizeof(ULONG) : sizeof(USHORT);
|
||||
|
||||
/* Read from the source operand */
|
||||
if (!Soft386ReadMemory(State,
|
||||
SOFT386_REG_DS,
|
||||
AddressSize ? State->GeneralRegs[SOFT386_REG_ESI].Long
|
||||
: State->GeneralRegs[SOFT386_REG_ESI].LowWord,
|
||||
FALSE,
|
||||
&State->GeneralRegs[SOFT386_REG_EAX].Long,
|
||||
DataSize))
|
||||
{
|
||||
/* Exception occurred */
|
||||
return FALSE;
|
||||
}
|
||||
|
||||
/* Increment/decrement ESI and EDI */
|
||||
if (OperandSize)
|
||||
{
|
||||
if (State->Flags.Df)
|
||||
{
|
||||
State->GeneralRegs[SOFT386_REG_ESI].Long += DataSize;
|
||||
State->GeneralRegs[SOFT386_REG_EDI].Long += DataSize;
|
||||
}
|
||||
else
|
||||
{
|
||||
State->GeneralRegs[SOFT386_REG_ESI].Long -= DataSize;
|
||||
State->GeneralRegs[SOFT386_REG_EDI].Long -= DataSize;
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
if (State->Flags.Df)
|
||||
{
|
||||
State->GeneralRegs[SOFT386_REG_ESI].LowWord += DataSize;
|
||||
State->GeneralRegs[SOFT386_REG_EDI].LowWord += DataSize;
|
||||
}
|
||||
else
|
||||
{
|
||||
State->GeneralRegs[SOFT386_REG_ESI].LowWord -= DataSize;
|
||||
State->GeneralRegs[SOFT386_REG_EDI].LowWord -= DataSize;
|
||||
}
|
||||
}
|
||||
|
||||
/* Return success */
|
||||
return TRUE;
|
||||
}
|
||||
|
||||
SOFT386_OPCODE_HANDLER(Soft386OpcodeScas)
|
||||
{
|
||||
UNIMPLEMENTED;
|
||||
return FALSE; // TODO: NOT IMPLEMENTED
|
||||
}
|
||||
|
|
|
@ -148,5 +148,10 @@ SOFT386_OPCODE_HANDLER(Soft386OpcodeMovEaxOffset);
|
|||
SOFT386_OPCODE_HANDLER(Soft386OpcodeMovOffsetAl);
|
||||
SOFT386_OPCODE_HANDLER(Soft386OpcodeMovOffsetEax);
|
||||
SOFT386_OPCODE_HANDLER(Soft386OpcodeSalc);
|
||||
SOFT386_OPCODE_HANDLER(Soft386OpcodeMovs);
|
||||
SOFT386_OPCODE_HANDLER(Soft386OpcodeCmps);
|
||||
SOFT386_OPCODE_HANDLER(Soft386OpcodeStos);
|
||||
SOFT386_OPCODE_HANDLER(Soft386OpcodeLods);
|
||||
SOFT386_OPCODE_HANDLER(Soft386OpcodeScas);
|
||||
|
||||
#endif // _OPCODES_H_
|
||||
|
|
Loading…
Reference in a new issue