[SOFT386]
authorAleksandar Andrejevic <aandrejevic@reactos.org>
Tue, 17 Sep 2013 20:28:26 +0000 (20:28 +0000)
committerAleksandar Andrejevic <aandrejevic@reactos.org>
Tue, 17 Sep 2013 20:28:26 +0000 (20:28 +0000)
Implement Soft386OpcodeTestAl and Soft386OpcodeTestEax.
These functions were declared and referenced, but never defined.
Why the compiler allowed that without even a warning remains a mystery.

svn path=/branches/ntvdm/; revision=60183

lib/soft386/opcodes.c

index 5fbc14d..feda378 100644 (file)
@@ -2436,6 +2436,107 @@ SOFT386_OPCODE_HANDLER(Soft386OpcodeTestModrm)
     return TRUE;
 }
 
+SOFT386_OPCODE_HANDLER(Soft386OpcodeTestAl)
+{
+    UCHAR FirstValue = State->GeneralRegs[SOFT386_REG_EAX].LowByte;
+    UCHAR SecondValue, Result;
+
+    /* Make sure this is the right instruction */
+    ASSERT(Opcode == 0xA8);
+
+    if (State->PrefixFlags)
+    {
+        /* This opcode doesn't take any prefixes */
+        Soft386Exception(State, SOFT386_EXCEPTION_UD);
+        return FALSE;
+    }
+
+    if (!Soft386FetchByte(State, &SecondValue))
+    {
+        /* Exception occurred */
+        return FALSE;
+    }
+
+    /* Calculate the result */
+    Result = FirstValue & SecondValue;
+
+    /* Update the flags */
+    State->Flags.Cf = FALSE;
+    State->Flags.Of = FALSE;
+    State->Flags.Zf = (Result == 0) ? TRUE : FALSE;
+    State->Flags.Sf = (Result & SIGN_FLAG_BYTE) ? TRUE : FALSE;
+    State->Flags.Pf = Soft386CalculateParity(Result);
+
+    /* The result is discarded */
+    return TRUE;
+}
+
+SOFT386_OPCODE_HANDLER(Soft386OpcodeTestEax)
+{
+    BOOLEAN Size = State->SegmentRegs[SOFT386_REG_CS].Size;
+
+    /* Make sure this is the right instruction */
+    ASSERT(Opcode == 0xA9);
+
+    if (State->PrefixFlags == SOFT386_PREFIX_OPSIZE)
+    {
+        /* The OPSIZE prefix toggles the size */
+        Size = !Size;
+    }
+    else
+    {
+        /* Invalid prefix */
+        Soft386Exception(State, SOFT386_EXCEPTION_UD);
+        return FALSE;
+    }
+
+    if (Size)
+    {
+        ULONG FirstValue = State->GeneralRegs[SOFT386_REG_EAX].Long;
+        ULONG SecondValue, Result;
+
+        if (!Soft386FetchDword(State, &SecondValue))
+        {
+            /* Exception occurred */
+            return FALSE;
+        }
+
+        /* Calculate the result */
+        Result = FirstValue & SecondValue;
+
+        /* Update the flags */
+        State->Flags.Cf = FALSE;
+        State->Flags.Of = FALSE;
+        State->Flags.Zf = (Result == 0) ? TRUE : FALSE;
+        State->Flags.Sf = (Result & SIGN_FLAG_LONG) ? TRUE : FALSE;
+        State->Flags.Pf = Soft386CalculateParity(Result);
+    }
+    else
+    {
+        USHORT FirstValue = State->GeneralRegs[SOFT386_REG_EAX].LowWord;
+        USHORT SecondValue, Result;
+
+        if (!Soft386FetchWord(State, &SecondValue))
+        {
+            /* Exception occurred */
+            return FALSE;
+        }
+
+        /* Calculate the result */
+        Result = FirstValue & SecondValue;
+
+        /* Update the flags */
+        State->Flags.Cf = FALSE;
+        State->Flags.Of = FALSE;
+        State->Flags.Zf = (Result == 0) ? TRUE : FALSE;
+        State->Flags.Sf = (Result & SIGN_FLAG_WORD) ? TRUE : FALSE;
+        State->Flags.Pf = Soft386CalculateParity(Result);
+    }
+
+    /* The result is discarded */
+    return TRUE;
+}
+
 SOFT386_OPCODE_HANDLER(Soft386OpcodeXchgByteModrm)
 {
     UCHAR FirstValue, SecondValue;