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)