Author: aandrejevic
Date: Tue Dec 3 00:12:55 2013
New Revision: 61203
URL:
http://svn.reactos.org/svn/reactos?rev=61203&view=rev
Log:
[FAST486]
The current "fast" method used in MOVS gives incorrect results. It has been
temporarily
replaced with a slow method that works correctly.
The string functions do nothing when CX is 0 on entry, fix CMPS and SCAS.
Modified:
branches/ntvdm/lib/fast486/opcodes.c
Modified: branches/ntvdm/lib/fast486/opcodes.c
URL:
http://svn.reactos.org/svn/reactos/branches/ntvdm/lib/fast486/opcodes.c?rev…
==============================================================================
--- branches/ntvdm/lib/fast486/opcodes.c [iso-8859-1] (original)
+++ branches/ntvdm/lib/fast486/opcodes.c [iso-8859-1] Tue Dec 3 00:12:55 2013
@@ -5363,176 +5363,90 @@
Segment = State->SegmentOverride;
}
+ if (State->PrefixFlags & FAST486_PREFIX_REP)
+ {
+ if ((AddressSize && (State->GeneralRegs[FAST486_REG_ECX].Long == 0))
+ || (!AddressSize && (State->GeneralRegs[FAST486_REG_ECX].LowWord
== 0)))
+ {
+ /* Do nothing */
+ return TRUE;
+ }
+ }
+
/* Calculate the size */
if (Opcode == 0xA4) DataSize = sizeof(UCHAR);
else DataSize = OperandSize ? sizeof(ULONG) : sizeof(USHORT);
+ /* 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))
+ {
+ /* Exception occurred */
+ return FALSE;
+ }
+
+ /* 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 FALSE;
+ }
+
+ /* Increment/decrement ESI and EDI */
+ if (AddressSize)
+ {
+ if (!State->Flags.Df)
+ {
+ 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;
+ }
+ }
+ else
+ {
+ if (!State->Flags.Df)
+ {
+ 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;
+ }
+ }
+
+ // FIXME: This method is slow!
if (State->PrefixFlags & FAST486_PREFIX_REP)
{
- UCHAR Block[STRING_BLOCK_SIZE];
- ULONG Count = AddressSize ? State->GeneralRegs[FAST486_REG_ECX].Long
- : State->GeneralRegs[FAST486_REG_ECX].LowWord;
-
- /* Clear the memory block */
- RtlZeroMemory(Block, sizeof(Block));
-
- /* Transfer until finished */
- while (Count)
- {
- 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)
+ if (AddressSize)
+ {
+ if (--State->GeneralRegs[FAST486_REG_ECX].Long)
{
- 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;
+ /* Repeat the instruction */
+ State->InstPtr = State->SavedInstPtr;
}
-
- if (State->Flags.Df)
+ }
+ else
+ {
+ if (--State->GeneralRegs[FAST486_REG_ECX].LowWord)
{
- /* Move ESI and EDI to the start of the block */
- if (AddressSize)
- {
- State->GeneralRegs[FAST486_REG_ESI].Long -= (Processed - 1) *
DataSize;
- State->GeneralRegs[FAST486_REG_EDI].Long -= (Processed - 1) *
DataSize;
- }
- else
- {
- State->GeneralRegs[FAST486_REG_ESI].LowWord -= (Processed - 1) *
DataSize;
- State->GeneralRegs[FAST486_REG_EDI].LowWord -= (Processed - 1) *
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 (AddressSize) 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 (AddressSize) 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;
- }
- }
- else
- {
- /* Reduce ESI and EDI */
- if (AddressSize)
- {
- State->GeneralRegs[FAST486_REG_ESI].Long -= DataSize;
- State->GeneralRegs[FAST486_REG_EDI].Long -= DataSize;
- }
- else
- {
- State->GeneralRegs[FAST486_REG_ESI].LowWord -= DataSize;
- State->GeneralRegs[FAST486_REG_EDI].LowWord -= DataSize;
- }
- }
-
- /* Reduce the total count by the number processed in this run */
- Count -= Processed;
- }
-
- /* Clear ECX */
- 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,
- AddressSize ? State->GeneralRegs[FAST486_REG_ESI].Long
- :
State->GeneralRegs[FAST486_REG_ESI].LowWord,
- FALSE,
- &Data,
- DataSize))
- {
- /* Exception occurred */
- return FALSE;
- }
-
- /* 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 FALSE;
- }
-
- /* Increment/decrement ESI and EDI */
- if (AddressSize)
- {
- if (!State->Flags.Df)
- {
- 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;
- }
- }
- else
- {
- if (!State->Flags.Df)
- {
- 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;
}
}
}
@@ -5560,6 +5474,17 @@
{
/* Use the override segment instead of DS */
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 TRUE;
+ }
}
/* Calculate the size */
@@ -5909,6 +5834,17 @@
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 TRUE;
+ }
+ }
+
/* Calculate the size */
if (Opcode == 0xAE) DataSize = sizeof(UCHAR);
else DataSize = OperandSize ? sizeof(ULONG) : sizeof(USHORT);