mirror of
https://github.com/reactos/reactos.git
synced 2024-08-01 00:58:16 +00:00
[SOFT386]
Start implementing call gate support. Implement the direct far call opcode (0x9A). svn path=/branches/ntvdm/; revision=60685
This commit is contained in:
parent
2f4594cf30
commit
4b14d9a672
|
@ -228,6 +228,19 @@ typedef struct
|
||||||
ULONG BaseHigh : 8;
|
ULONG BaseHigh : 8;
|
||||||
} SOFT386_GDT_ENTRY, *PSOFT386_GDT_ENTRY;
|
} 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
|
typedef struct
|
||||||
{
|
{
|
||||||
ULONG Offset : 16;
|
ULONG Offset : 16;
|
||||||
|
|
|
@ -202,15 +202,23 @@ Soft386LoadSegment(PSOFT386_STATE State,
|
||||||
sizeof(GdtEntry));
|
sizeof(GdtEntry));
|
||||||
}
|
}
|
||||||
|
|
||||||
/* Check if we are loading SS */
|
|
||||||
if (Segment == SOFT386_REG_SS)
|
if (Segment == SOFT386_REG_SS)
|
||||||
{
|
{
|
||||||
|
/* Loading the stack segment */
|
||||||
|
|
||||||
if (GET_SEGMENT_INDEX(Selector) == 0)
|
if (GET_SEGMENT_INDEX(Selector) == 0)
|
||||||
{
|
{
|
||||||
Soft386Exception(State, SOFT386_EXCEPTION_GP);
|
Soft386Exception(State, SOFT386_EXCEPTION_GP);
|
||||||
return FALSE;
|
return FALSE;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
if (!GdtEntry.SystemType)
|
||||||
|
{
|
||||||
|
/* This is a special descriptor */
|
||||||
|
Soft386Exception(State, SOFT386_EXCEPTION_GP);
|
||||||
|
return FALSE;
|
||||||
|
}
|
||||||
|
|
||||||
if (GdtEntry.Executable || !GdtEntry.ReadWrite)
|
if (GdtEntry.Executable || !GdtEntry.ReadWrite)
|
||||||
{
|
{
|
||||||
Soft386Exception(State, SOFT386_EXCEPTION_GP);
|
Soft386Exception(State, SOFT386_EXCEPTION_GP);
|
||||||
|
@ -230,8 +238,22 @@ Soft386LoadSegment(PSOFT386_STATE State,
|
||||||
return FALSE;
|
return FALSE;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
else if (Segment == SOFT386_REG_CS)
|
||||||
|
{
|
||||||
|
/* Loading the code segment */
|
||||||
|
// TODO: NOT IMPLEMENTED
|
||||||
|
}
|
||||||
else
|
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)
|
if ((GET_SEGMENT_RPL(Selector) > GdtEntry.Dpl)
|
||||||
&& (Soft386GetCurrentPrivLevel(State) > GdtEntry.Dpl))
|
&& (Soft386GetCurrentPrivLevel(State) > GdtEntry.Dpl))
|
||||||
{
|
{
|
||||||
|
|
|
@ -4612,10 +4612,77 @@ SOFT386_OPCODE_HANDLER(Soft386OpcodeCdq)
|
||||||
|
|
||||||
SOFT386_OPCODE_HANDLER(Soft386OpcodeCallAbs)
|
SOFT386_OPCODE_HANDLER(Soft386OpcodeCallAbs)
|
||||||
{
|
{
|
||||||
// TODO: NOT IMPLEMENTED
|
USHORT Segment = 0;
|
||||||
UNIMPLEMENTED;
|
ULONG Offset = 0;
|
||||||
|
BOOLEAN Size = State->SegmentRegs[SOFT386_REG_CS].Size;
|
||||||
|
|
||||||
return FALSE;
|
/* 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)
|
SOFT386_OPCODE_HANDLER(Soft386OpcodeWait)
|
||||||
|
|
Loading…
Reference in a new issue