Author: aandrejevic
Date: Sun Sep 15 18:26:25 2013
New Revision: 60147
URL:
http://svn.reactos.org/svn/reactos?rev=60147&view=rev
Log:
[SOFT386]
Implement the direct relative near call (CALL rel16/32) instruction.
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 Sep 15 18:26:25 2013
@@ -4204,67 +4204,117 @@
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(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;
-}