Author: aandrejevic
Date: Sun Oct 13 23:59:52 2013
New Revision: 60658
URL:
http://svn.reactos.org/svn/reactos?rev=60658&view=rev
Log:
[SOFT386]
Halfplement REPZ/REPNZ for CMPS and SCAS.
Modified:
branches/ntvdm/lib/soft386/opcodes.c
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] Sun Oct 13 23:59:52 2013
@@ -6200,6 +6200,43 @@
}
}
+ // FIXME: This method is slow!
+ if ((State->PrefixFlags & SOFT386_PREFIX_REP)
+ || (State->PrefixFlags & SOFT386_PREFIX_REPNZ))
+ {
+ BOOLEAN Repeat = TRUE;
+
+ if (OperandSize)
+ {
+ if ((--State->GeneralRegs[SOFT386_REG_ECX].Long) == 0)
+ {
+ /* ECX is 0 */
+ Repeat = FALSE;
+ }
+ }
+ else
+ {
+ if ((--State->GeneralRegs[SOFT386_REG_ECX].LowWord) == 0)
+ {
+ /* CX is 0 */
+ Repeat = FALSE;
+ }
+ }
+
+ if (((State->PrefixFlags & SOFT386_PREFIX_REP) &&
!State->Flags.Zf)
+ || ((State->PrefixFlags & SOFT386_PREFIX_REPNZ) &&
State->Flags.Zf))
+ {
+ /* REPZ with ZF = 0 or REPNZ with ZF = 1 */
+ Repeat = FALSE;
+ }
+
+ if (Repeat)
+ {
+ /* Repeat the instruction */
+ State->InstPtr = State->SavedInstPtr;
+ }
+ }
+
/* Return success */
return TRUE;
}
@@ -6444,16 +6481,8 @@
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 == 0xA6) DataSize = sizeof(UCHAR);
+ if (Opcode == 0xAE) DataSize = sizeof(UCHAR);
else DataSize = OperandSize ? sizeof(ULONG) : sizeof(USHORT);
/* Calculate the mask and sign flag */
@@ -6497,6 +6526,43 @@
{
if (!State->Flags.Df) State->GeneralRegs[SOFT386_REG_EDI].LowWord +=
DataSize;
else State->GeneralRegs[SOFT386_REG_EDI].LowWord -= DataSize;
+ }
+
+ // FIXME: This method is slow!
+ if ((State->PrefixFlags & SOFT386_PREFIX_REP)
+ || (State->PrefixFlags & SOFT386_PREFIX_REPNZ))
+ {
+ BOOLEAN Repeat = TRUE;
+
+ if (OperandSize)
+ {
+ if ((--State->GeneralRegs[SOFT386_REG_ECX].Long) == 0)
+ {
+ /* ECX is 0 */
+ Repeat = FALSE;
+ }
+ }
+ else
+ {
+ if ((--State->GeneralRegs[SOFT386_REG_ECX].LowWord) == 0)
+ {
+ /* CX is 0 */
+ Repeat = FALSE;
+ }
+ }
+
+ if (((State->PrefixFlags & SOFT386_PREFIX_REP) &&
!State->Flags.Zf)
+ || ((State->PrefixFlags & SOFT386_PREFIX_REPNZ) &&
State->Flags.Zf))
+ {
+ /* REPZ with ZF = 0 or REPNZ with ZF = 1 */
+ Repeat = FALSE;
+ }
+
+ if (Repeat)
+ {
+ /* Repeat the instruction */
+ State->InstPtr = State->SavedInstPtr;
+ }
}
/* Return success */