Author: aandrejevic
Date: Wed Sep 25 18:34:57 2013
New Revision: 60350
URL:
http://svn.reactos.org/svn/reactos?rev=60350&view=rev
Log:
[SOFT386]
Implement the ENTER 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 25 18:34:57 2013
@@ -4492,10 +4492,75 @@
SOFT386_OPCODE_HANDLER(Soft386OpcodeEnter)
{
- // TODO: NOT IMPLEMENTED
- UNIMPLEMENTED;
-
- return FALSE;
+ INT i;
+ BOOLEAN Size = State->SegmentRegs[SOFT386_REG_CS].Size;
+ USHORT FrameSize;
+ UCHAR NestingLevel;
+ SOFT386_REG FramePointer;
+
+ /* Make sure this is the right instruction */
+ ASSERT(Opcode == 0xC8);
+
+ 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 (!Soft386FetchWord(State, &FrameSize))
+ {
+ /* Exception occurred */
+ return FALSE;
+ }
+
+ if (!Soft386FetchByte(State, &NestingLevel))
+ {
+ /* Exception occurred */
+ return FALSE;
+ }
+
+ /* Push EBP */
+ if (!Soft386StackPush(State, State->GeneralRegs[SOFT386_REG_EBP].Long))
+ {
+ /* Exception occurred */
+ return FALSE;
+ }
+
+ /* Save ESP */
+ FramePointer = State->GeneralRegs[SOFT386_REG_ESP];
+
+ /* Set up the nested procedure stacks */
+ for (i = 1; i < NestingLevel; i++)
+ {
+ if (Size)
+ {
+ State->GeneralRegs[SOFT386_REG_EBP].Long -= 4;
+ Soft386StackPush(State, State->GeneralRegs[SOFT386_REG_EBP].Long);
+ }
+ else
+ {
+ State->GeneralRegs[SOFT386_REG_EBP].LowWord -= 2;
+ Soft386StackPush(State, State->GeneralRegs[SOFT386_REG_EBP].LowWord);
+ }
+ }
+
+ if (NestingLevel > 0) Soft386StackPush(State, FramePointer.Long);
+
+ /* Set EBP to the frame pointer */
+ State->GeneralRegs[SOFT386_REG_EBP] = FramePointer;
+
+ /* Reserve space for the frame */
+ if (Size) State->GeneralRegs[SOFT386_REG_ESP].Long -= (ULONG)FrameSize;
+ else State->GeneralRegs[SOFT386_REG_ESP].LowWord -= FrameSize;
+
+ return TRUE;
}
SOFT386_OPCODE_HANDLER(Soft386OpcodeLeave)