Author: aandrejevic Date: Wed Oct 16 00:41:24 2013 New Revision: 60685
URL: http://svn.reactos.org/svn/reactos?rev=60685&view=rev Log: [SOFT386] Start implementing call gate support. Implement the direct far call opcode (0x9A).
Modified: branches/ntvdm/include/reactos/libs/soft386/soft386.h branches/ntvdm/lib/soft386/common.inl branches/ntvdm/lib/soft386/opcodes.c
Modified: branches/ntvdm/include/reactos/libs/soft386/soft386.h URL: http://svn.reactos.org/svn/reactos/branches/ntvdm/include/reactos/libs/soft3... ============================================================================== --- branches/ntvdm/include/reactos/libs/soft386/soft386.h [iso-8859-1] (original) +++ branches/ntvdm/include/reactos/libs/soft386/soft386.h [iso-8859-1] Wed Oct 16 00:41:24 2013 @@ -227,6 +227,19 @@ ULONG Granularity : 1; ULONG BaseHigh : 8; } SOFT386_GDT_ENTRY, *PSOFT386_GDT_ENTRY; + +typedef struct +{ + ULONG Offset : 16; + ULONG Selector : 16; + ULONG ParamCount : 5; + ULONG Reserved : 3; + ULONG Type : 4; + ULONG SystemType : 1; + ULONG Dpl : 2; + ULONG Present : 1; + ULONG OffsetHigh : 16; +} SOFT386_CALL_GATE, *PSOFT386_CALL_GATE;
typedef struct {
Modified: branches/ntvdm/lib/soft386/common.inl URL: http://svn.reactos.org/svn/reactos/branches/ntvdm/lib/soft386/common.inl?rev... ============================================================================== --- branches/ntvdm/lib/soft386/common.inl [iso-8859-1] (original) +++ branches/ntvdm/lib/soft386/common.inl [iso-8859-1] Wed Oct 16 00:41:24 2013 @@ -202,11 +202,19 @@ sizeof(GdtEntry)); }
- /* Check if we are loading SS */ if (Segment == SOFT386_REG_SS) { + /* Loading the stack segment */ + if (GET_SEGMENT_INDEX(Selector) == 0) { + Soft386Exception(State, SOFT386_EXCEPTION_GP); + return FALSE; + } + + if (!GdtEntry.SystemType) + { + /* This is a special descriptor */ Soft386Exception(State, SOFT386_EXCEPTION_GP); return FALSE; } @@ -230,8 +238,22 @@ return FALSE; } } + else if (Segment == SOFT386_REG_CS) + { + /* Loading the code segment */ + // TODO: NOT IMPLEMENTED + } else { + /* Loading a data segment */ + + if (!GdtEntry.SystemType) + { + /* This is a special descriptor */ + Soft386Exception(State, SOFT386_EXCEPTION_GP); + return FALSE; + } + if ((GET_SEGMENT_RPL(Selector) > GdtEntry.Dpl) && (Soft386GetCurrentPrivLevel(State) > GdtEntry.Dpl)) {
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 Oct 16 00:41:24 2013 @@ -4612,10 +4612,77 @@
SOFT386_OPCODE_HANDLER(Soft386OpcodeCallAbs) { - // TODO: NOT IMPLEMENTED - UNIMPLEMENTED; - - return FALSE; + USHORT Segment = 0; + ULONG Offset = 0; + BOOLEAN Size = State->SegmentRegs[SOFT386_REG_CS].Size; + + /* Make sure this is the right instruction */ + ASSERT(Opcode == 0x9A); + + if (State->PrefixFlags & SOFT386_PREFIX_OPSIZE) + { + /* The OPSIZE prefix toggles the size */ + Size = !Size; + } + + if (State->PrefixFlags & SOFT386_PREFIX_LOCK) + { + /* Invalid prefix */ + Soft386Exception(State, SOFT386_EXCEPTION_UD); + return FALSE; + } + + /* Fetch the offset */ + if (Size) + { + if (!Soft386FetchDword(State, &Offset)) + { + /* Exception occurred */ + return FALSE; + } + } + else + { + if (!Soft386FetchWord(State, (PUSHORT)&Offset)) + { + /* Exception occurred */ + return FALSE; + } + } + + /* Fetch the segment */ + if (!Soft386FetchWord(State, &Segment)) + { + /* Exception occurred */ + return FALSE; + } + + /* Push the current code segment selector */ + if (!Soft386StackPush(State, State->SegmentRegs[SOFT386_REG_CS].Selector)) + { + /* Exception occurred */ + return FALSE; + } + + /* Push the current value of the instruction pointer */ + if (!Soft386StackPush(State, State->InstPtr.Long)) + { + /* Exception occurred */ + return FALSE; + } + + /* Load the new CS */ + if (!Soft386LoadSegment(State, SOFT386_REG_CS, Segment)) + { + /* Exception occurred */ + return FALSE; + } + + /* Load new (E)IP */ + if (Size) State->InstPtr.Long = Offset; + else State->InstPtr.LowWord = LOWORD(Offset); + + return TRUE; }
SOFT386_OPCODE_HANDLER(Soft386OpcodeWait)