mirror of
https://github.com/reactos/reactos.git
synced 2024-11-05 06:09:58 +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
3 changed files with 106 additions and 4 deletions
|
@ -228,6 +228,19 @@ typedef struct
|
|||
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
|
||||
{
|
||||
ULONG Offset : 16;
|
||||
|
|
|
@ -202,15 +202,23 @@ Soft386LoadSegment(PSOFT386_STATE State,
|
|||
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;
|
||||
}
|
||||
|
||||
if (GdtEntry.Executable || !GdtEntry.ReadWrite)
|
||||
{
|
||||
Soft386Exception(State, SOFT386_EXCEPTION_GP);
|
||||
|
@ -230,8 +238,22 @@ Soft386LoadSegment(PSOFT386_STATE State,
|
|||
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))
|
||||
{
|
||||
|
|
|
@ -4612,10 +4612,77 @@ SOFT386_OPCODE_HANDLER(Soft386OpcodeCdq)
|
|||
|
||||
SOFT386_OPCODE_HANDLER(Soft386OpcodeCallAbs)
|
||||
{
|
||||
// TODO: NOT IMPLEMENTED
|
||||
UNIMPLEMENTED;
|
||||
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)
|
||||
|
|
Loading…
Reference in a new issue