Author: aandrejevic
Date: Thu Sep 19 22:48:45 2013
New Revision: 60226
URL:
http://svn.reactos.org/svn/reactos?rev=60226&view=rev
Log:
[SOFT386]
Implement JECXZ, LOOP, LOOPZ and LOOPNZ.
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 Sep 19 22:48:45 2013
@@ -248,8 +248,8 @@
NULL, // TODO: OPCODE 0xDD NOT SUPPORTED
NULL, // TODO: OPCODE 0xDE NOT SUPPORTED
NULL, // TODO: OPCODE 0xDF NOT SUPPORTED
- Soft386OpcodeLoopnz,
- Soft386OpcodeLoopz,
+ Soft386OpcodeLoop,
+ Soft386OpcodeLoop,
Soft386OpcodeLoop,
Soft386OpcodeJecxz,
Soft386OpcodeInByte,
@@ -4323,151 +4323,213 @@
return FALSE;
}
-SOFT386_OPCODE_HANDLER(Soft386OpcodeLoopnz)
+SOFT386_OPCODE_HANDLER(Soft386OpcodeLoop)
+{
+ BOOLEAN Condition;
+ BOOLEAN Size = State->SegmentRegs[SOFT386_REG_CS].Size;
+ CHAR Offset = 0;
+
+ /* Make sure this is the right instruction */
+ ASSERT((Opcode >= 0xE0) && (Opcode <= 0xE2));
+
+ if (State->PrefixFlags & SOFT386_PREFIX_LOCK)
+ {
+ /* Invalid prefix */
+ Soft386Exception(State, SOFT386_EXCEPTION_UD);
+ return FALSE;
+ }
+
+ if (State->PrefixFlags == SOFT386_PREFIX_OPSIZE)
+ {
+ /* The OPSIZE prefix toggles the size */
+ Size = !Size;
+ }
+
+ if (Size) Condition = ((--State->GeneralRegs[SOFT386_REG_ECX].Long) == 0);
+ else Condition = ((--State->GeneralRegs[SOFT386_REG_ECX].LowWord) == 0);
+
+ if (Opcode == 0xE0)
+ {
+ /* Additional rule for LOOPNZ */
+ if (State->Flags.Zf) Condition = FALSE;
+ }
+
+ if (Opcode == 0xE1)
+ {
+ /* Additional rule for LOOPZ */
+ if (!State->Flags.Zf) Condition = FALSE;
+ }
+
+ /* Fetch the offset */
+ if (!Soft386FetchByte(State, (PUCHAR)&Offset))
+ {
+ /* An exception occurred */
+ return FALSE;
+ }
+
+ if (Condition)
+ {
+ /* Move the instruction pointer */
+ State->InstPtr.Long += Offset;
+ }
+
+ return TRUE;
+}
+
+SOFT386_OPCODE_HANDLER(Soft386OpcodeJecxz)
+{
+ BOOLEAN Condition;
+ BOOLEAN Size = State->SegmentRegs[SOFT386_REG_CS].Size;
+ CHAR Offset = 0;
+
+ /* Make sure this is the right instruction */
+ ASSERT(Opcode == 0xE3);
+
+ if (State->PrefixFlags & SOFT386_PREFIX_LOCK)
+ {
+ /* Invalid prefix */
+ Soft386Exception(State, SOFT386_EXCEPTION_UD);
+ return FALSE;
+ }
+
+ if (State->PrefixFlags == SOFT386_PREFIX_OPSIZE)
+ {
+ /* The OPSIZE prefix toggles the size */
+ Size = !Size;
+ }
+
+ if (Size) Condition = (State->GeneralRegs[SOFT386_REG_ECX].Long == 0);
+ else Condition = (State->GeneralRegs[SOFT386_REG_ECX].LowWord == 0);
+
+ /* Fetch the offset */
+ if (!Soft386FetchByte(State, (PUCHAR)&Offset))
+ {
+ /* An exception occurred */
+ return FALSE;
+ }
+
+ if (Condition)
+ {
+ /* Move the instruction pointer */
+ State->InstPtr.Long += Offset;
+ }
+
+ return TRUE;
+}
+
+SOFT386_OPCODE_HANDLER(Soft386OpcodeCall)
+{
+ BOOLEAN Size = State->SegmentRegs[SOFT386_REG_CS].Size;
+
+ /* Make sure this is the right instruction */
+ ASSERT(Opcode == 0xE8);
+
+ if (State->PrefixFlags == SOFT386_PREFIX_OPSIZE)
+ {
+ /* The OPSIZE prefix toggles the size */
+ Size = !Size;
+ }
+ else if (State->PrefixFlags != 0)
+ {
+ /* Invalid prefix */
+ Soft386Exception(State, SOFT386_EXCEPTION_UD);
+ return FALSE;
+ }
+
+ /* Push the current value of the instruction pointer */
+ if (!Soft386StackPush(State, State->InstPtr.Long))
+ {
+ /* Exception occurred */
+ return FALSE;
+ }
+
+ if (Size)
+ {
+ LONG Offset = 0;
+
+ /* Fetch the offset */
+ if (!Soft386FetchDword(State, (PULONG)&Offset))
+ {
+ /* An exception occurred */
+ return FALSE;
+ }
+
+ /* Move the instruction pointer */
+ State->InstPtr.Long += Offset;
+ }
+ else
+ {
+ SHORT Offset = 0;
+
+ /* Fetch the offset */
+ if (!Soft386FetchWord(State, (PUSHORT)&Offset))
+ {
+ /* An exception occurred */
+ return FALSE;
+ }
+
+ /* Move the instruction pointer */
+ State->InstPtr.LowWord += Offset;
+ }
+
+ return TRUE;
+}
+
+SOFT386_OPCODE_HANDLER(Soft386OpcodeJmp)
+{
+ BOOLEAN Size = State->SegmentRegs[SOFT386_REG_CS].Size;
+
+ /* Make sure this is the right instruction */
+ ASSERT(Opcode == 0xE9);
+
+ if (State->PrefixFlags == SOFT386_PREFIX_OPSIZE)
+ {
+ /* The OPSIZE prefix toggles the size */
+ Size = !Size;
+ }
+ else if (State->PrefixFlags != 0)
+ {
+ /* Invalid prefix */
+ Soft386Exception(State, SOFT386_EXCEPTION_UD);
+ return FALSE;
+ }
+
+ if (Size)
+ {
+ LONG Offset = 0;
+
+ /* Fetch the offset */
+ if (!Soft386FetchDword(State, (PULONG)&Offset))
+ {
+ /* An exception occurred */
+ return FALSE;
+ }
+
+ /* Move the instruction pointer */
+ State->InstPtr.Long += Offset;
+ }
+ else
+ {
+ SHORT Offset = 0;
+
+ /* Fetch the offset */
+ if (!Soft386FetchWord(State, (PUSHORT)&Offset))
+ {
+ /* An exception occurred */
+ return FALSE;
+ }
+
+ /* Move the instruction pointer */
+ State->InstPtr.LowWord += Offset;
+ }
+
+ return TRUE;
+}
+
+SOFT386_OPCODE_HANDLER(Soft386OpcodeJmpAbs)
{
// TODO: NOT IMPLEMENTED
UNIMPLEMENTED;
return FALSE;
}
-
-SOFT386_OPCODE_HANDLER(Soft386OpcodeLoopz)
-{
- // TODO: NOT IMPLEMENTED
- UNIMPLEMENTED;
-
- return FALSE;
-}
-
-SOFT386_OPCODE_HANDLER(Soft386OpcodeLoop)
-{
- // TODO: NOT IMPLEMENTED
- UNIMPLEMENTED;
-
- return FALSE;
-}
-
-SOFT386_OPCODE_HANDLER(Soft386OpcodeJecxz)
-{
- // TODO: NOT IMPLEMENTED
- UNIMPLEMENTED;
-
- return FALSE;
-}
-
-SOFT386_OPCODE_HANDLER(Soft386OpcodeCall)
-{
- BOOLEAN Size = State->SegmentRegs[SOFT386_REG_CS].Size;
-
- /* Make sure this is the right instruction */
- ASSERT(Opcode == 0xE8);
-
- if (State->PrefixFlags == SOFT386_PREFIX_OPSIZE)
- {
- /* The OPSIZE prefix toggles the size */
- Size = !Size;
- }
- else if (State->PrefixFlags != 0)
- {
- /* Invalid prefix */
- Soft386Exception(State, SOFT386_EXCEPTION_UD);
- return FALSE;
- }
-
- /* Push the current value of the instruction pointer */
- if (!Soft386StackPush(State, State->InstPtr.Long))
- {
- /* Exception occurred */
- return FALSE;
- }
-
- if (Size)
- {
- LONG Offset = 0;
-
- /* Fetch the offset */
- if (!Soft386FetchDword(State, (PULONG)&Offset))
- {
- /* An exception occurred */
- return FALSE;
- }
-
- /* Move the instruction pointer */
- State->InstPtr.Long += Offset;
- }
- else
- {
- SHORT Offset = 0;
-
- /* Fetch the offset */
- if (!Soft386FetchWord(State, (PUSHORT)&Offset))
- {
- /* An exception occurred */
- return FALSE;
- }
-
- /* Move the instruction pointer */
- State->InstPtr.LowWord += Offset;
- }
-
- return TRUE;
-}
-
-SOFT386_OPCODE_HANDLER(Soft386OpcodeJmp)
-{
- BOOLEAN Size = State->SegmentRegs[SOFT386_REG_CS].Size;
-
- /* Make sure this is the right instruction */
- ASSERT(Opcode == 0xE9);
-
- if (State->PrefixFlags == SOFT386_PREFIX_OPSIZE)
- {
- /* The OPSIZE prefix toggles the size */
- Size = !Size;
- }
- else if (State->PrefixFlags != 0)
- {
- /* Invalid prefix */
- Soft386Exception(State, SOFT386_EXCEPTION_UD);
- return FALSE;
- }
-
- if (Size)
- {
- LONG Offset = 0;
-
- /* Fetch the offset */
- if (!Soft386FetchDword(State, (PULONG)&Offset))
- {
- /* An exception occurred */
- return FALSE;
- }
-
- /* Move the instruction pointer */
- State->InstPtr.Long += Offset;
- }
- else
- {
- SHORT Offset = 0;
-
- /* Fetch the offset */
- if (!Soft386FetchWord(State, (PUSHORT)&Offset))
- {
- /* An exception occurred */
- return FALSE;
- }
-
- /* Move the instruction pointer */
- State->InstPtr.LowWord += Offset;
- }
-
- return TRUE;
-}
-
-SOFT386_OPCODE_HANDLER(Soft386OpcodeJmpAbs)
-{
- // TODO: NOT IMPLEMENTED
- UNIMPLEMENTED;
-
- return FALSE;
-}
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 Sep 19 22:48:45 2013
@@ -130,8 +130,6 @@
SOFT386_OPCODE_HANDLER(Soft386OpcodeAam);
SOFT386_OPCODE_HANDLER(Soft386OpcodeAad);
SOFT386_OPCODE_HANDLER(Soft386OpcodeXlat);
-SOFT386_OPCODE_HANDLER(Soft386OpcodeLoopnz);
-SOFT386_OPCODE_HANDLER(Soft386OpcodeLoopz);
SOFT386_OPCODE_HANDLER(Soft386OpcodeLoop);
SOFT386_OPCODE_HANDLER(Soft386OpcodeJecxz);
SOFT386_OPCODE_HANDLER(Soft386OpcodeCall);