Author: aandrejevic
Date: Thu Oct 3 20:56:36 2013
New Revision: 60515
URL:
http://svn.reactos.org/svn/reactos?rev=60515&view=rev
Log:
[SOFT386]
Halfplement MOVS, STOS and LODS.
Stubplement CMPS and SCAS.
Modified:
branches/ntvdm/lib/soft386/opcodes.c
branches/ntvdm/lib/soft386/opcodes.h
Modified: branches/ntvdm/lib/soft386/opcodes.c
URL:
http://svn.reactos.org/svn/reactos/branches/ntvdm/lib/soft386/opcodes.c?rev…
==============================================================================
--- branches/ntvdm/lib/soft386/opcodes.c [iso-8859-1] (original)
+++ branches/ntvdm/lib/soft386/opcodes.c [iso-8859-1] Thu Oct 3 20:56:36 2013
@@ -203,18 +203,18 @@
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 @@
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
+}
Modified: branches/ntvdm/lib/soft386/opcodes.h
URL:
http://svn.reactos.org/svn/reactos/branches/ntvdm/lib/soft386/opcodes.h?rev…
==============================================================================
--- branches/ntvdm/lib/soft386/opcodes.h [iso-8859-1] (original)
+++ branches/ntvdm/lib/soft386/opcodes.h [iso-8859-1] Thu Oct 3 20:56:36 2013
@@ -148,5 +148,10 @@
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_