Author: aandrejevic
Date: Wed Sep 18 21:13:40 2013
New Revision: 60201
URL:
http://svn.reactos.org/svn/reactos?rev=60201&view=rev
Log:
[SOFT386]
Implement the LEAVE 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] Wed Sep 18 21:13:40 2013
@@ -4208,13 +4208,58 @@
SOFT386_OPCODE_HANDLER(Soft386OpcodeLeave)
{
+ BOOLEAN Size = State->SegmentRegs[SOFT386_REG_CS].Size;
+
+ /* Make sure this is the right instruction */
+ ASSERT(Opcode == 0xC9);
+
+ 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)
+ {
+ /* Set the stack pointer (ESP) to the base pointer (EBP) */
+ State->GeneralRegs[SOFT386_REG_ESP].Long =
State->GeneralRegs[SOFT386_REG_EBP].Long;
+
+ /* Pop the saved base pointer from the stack */
+ return Soft386StackPop(State, &State->GeneralRegs[SOFT386_REG_EBP].Long);
+ }
+ else
+ {
+ ULONG Value;
+
+ /* Set the stack pointer (SP) to the base pointer (BP) */
+ State->GeneralRegs[SOFT386_REG_ESP].LowWord =
State->GeneralRegs[SOFT386_REG_EBP].LowWord;
+
+ /* Pop the saved base pointer from the stack */
+ if (Soft386StackPop(State, &Value))
+ {
+ State->GeneralRegs[SOFT386_REG_EBP].LowWord = LOWORD(Value);
+ return TRUE;
+ }
+ else return FALSE;
+ }
+}
+
+SOFT386_OPCODE_HANDLER(Soft386OpcodeRetFarImm)
+{
// TODO: NOT IMPLEMENTED
UNIMPLEMENTED;
return FALSE;
}
-SOFT386_OPCODE_HANDLER(Soft386OpcodeRetFarImm)
+SOFT386_OPCODE_HANDLER(Soft386OpcodeRetFar)
{
// TODO: NOT IMPLEMENTED
UNIMPLEMENTED;
@@ -4222,7 +4267,7 @@
return FALSE;
}
-SOFT386_OPCODE_HANDLER(Soft386OpcodeRetFar)
+SOFT386_OPCODE_HANDLER(Soft386OpcodeInt3)
{
// TODO: NOT IMPLEMENTED
UNIMPLEMENTED;
@@ -4230,7 +4275,7 @@
return FALSE;
}
-SOFT386_OPCODE_HANDLER(Soft386OpcodeInt3)
+SOFT386_OPCODE_HANDLER(Soft386OpcodeInt)
{
// TODO: NOT IMPLEMENTED
UNIMPLEMENTED;
@@ -4238,7 +4283,7 @@
return FALSE;
}
-SOFT386_OPCODE_HANDLER(Soft386OpcodeInt)
+SOFT386_OPCODE_HANDLER(Soft386OpcodeIntOverflow)
{
// TODO: NOT IMPLEMENTED
UNIMPLEMENTED;
@@ -4246,7 +4291,7 @@
return FALSE;
}
-SOFT386_OPCODE_HANDLER(Soft386OpcodeIntOverflow)
+SOFT386_OPCODE_HANDLER(Soft386OpcodeIret)
{
// TODO: NOT IMPLEMENTED
UNIMPLEMENTED;
@@ -4254,7 +4299,7 @@
return FALSE;
}
-SOFT386_OPCODE_HANDLER(Soft386OpcodeIret)
+SOFT386_OPCODE_HANDLER(Soft386OpcodeAam)
{
// TODO: NOT IMPLEMENTED
UNIMPLEMENTED;
@@ -4262,7 +4307,7 @@
return FALSE;
}
-SOFT386_OPCODE_HANDLER(Soft386OpcodeAam)
+SOFT386_OPCODE_HANDLER(Soft386OpcodeAad)
{
// TODO: NOT IMPLEMENTED
UNIMPLEMENTED;
@@ -4270,7 +4315,7 @@
return FALSE;
}
-SOFT386_OPCODE_HANDLER(Soft386OpcodeAad)
+SOFT386_OPCODE_HANDLER(Soft386OpcodeXlat)
{
// TODO: NOT IMPLEMENTED
UNIMPLEMENTED;
@@ -4278,7 +4323,7 @@
return FALSE;
}
-SOFT386_OPCODE_HANDLER(Soft386OpcodeXlat)
+SOFT386_OPCODE_HANDLER(Soft386OpcodeLoopnz)
{
// TODO: NOT IMPLEMENTED
UNIMPLEMENTED;
@@ -4286,7 +4331,7 @@
return FALSE;
}
-SOFT386_OPCODE_HANDLER(Soft386OpcodeLoopnz)
+SOFT386_OPCODE_HANDLER(Soft386OpcodeLoopz)
{
// TODO: NOT IMPLEMENTED
UNIMPLEMENTED;
@@ -4294,7 +4339,7 @@
return FALSE;
}
-SOFT386_OPCODE_HANDLER(Soft386OpcodeLoopz)
+SOFT386_OPCODE_HANDLER(Soft386OpcodeLoop)
{
// TODO: NOT IMPLEMENTED
UNIMPLEMENTED;
@@ -4302,7 +4347,7 @@
return FALSE;
}
-SOFT386_OPCODE_HANDLER(Soft386OpcodeLoop)
+SOFT386_OPCODE_HANDLER(Soft386OpcodeJecxz)
{
// TODO: NOT IMPLEMENTED
UNIMPLEMENTED;
@@ -4310,127 +4355,119 @@
return FALSE;
}
-SOFT386_OPCODE_HANDLER(Soft386OpcodeJecxz)
+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(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;
-}