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=61203&r1=61202&r2=61203&view=diff
==============================================================================
--- 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);


Reply via email to