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/soft…
==============================================================================
--- 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?re…
==============================================================================
--- 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)