/* PUBLIC FUNCTIONS ***********************************************************/
BOOLEAN
+FASTCALL
Fast486ReadMemory(PFAST486_STATE State,
FAST486_SEG_REGS SegmentReg,
ULONG Offset,
}
BOOLEAN
+FASTCALL
Fast486WriteMemory(PFAST486_STATE State,
FAST486_SEG_REGS SegmentReg,
ULONG Offset,
if (!Fast486ReadLinearMemory(State,
State->TaskReg.Base,
&Tss,
- State->TaskReg.Limit >= sizeof(FAST486_TSS)
+ State->TaskReg.Limit >= (sizeof(FAST486_TSS) - 1)
? sizeof(FAST486_TSS) : sizeof(FAST486_LEGACY_TSS),
FALSE))
{
{
case 0:
{
- if (State->TaskReg.Limit >= sizeof(FAST486_TSS))
+ if (State->TaskReg.Limit >= (sizeof(FAST486_TSS) - 1))
{
NewSs = Tss.Ss0;
NewEsp = Tss.Esp0;
case 1:
{
- if (State->TaskReg.Limit >= sizeof(FAST486_TSS))
+ if (State->TaskReg.Limit >= (sizeof(FAST486_TSS) - 1))
{
NewSs = Tss.Ss1;
NewEsp = Tss.Esp1;
case 2:
{
- if (State->TaskReg.Limit >= sizeof(FAST486_TSS))
+ if (State->TaskReg.Limit >= (sizeof(FAST486_TSS) - 1))
{
NewSs = Tss.Ss2;
NewEsp = Tss.Esp2;
State->InstPtr.LowWord = IdtEntry->Offset;
}
+ /* Clear NT */
+ State->Flags.Nt = FALSE;
+
if (OldVm)
{
/* Push GS, FS, DS and ES */
State->Flags.If = FALSE;
}
+ /* Clear TF */
+ State->Flags.Tf = FALSE;
+
return TRUE;
}
/* Restore the IP to the saved IP */
State->InstPtr = State->SavedInstPtr;
+ /* Restore the SP to the saved SP */
+ State->GeneralRegs[FAST486_REG_ESP] = State->SavedStackPtr;
+
/* Get the interrupt vector */
if (!Fast486GetIntVector(State, ExceptionCode, &IdtEntry))
{
PFAST486_LEGACY_TSS NewLegacyTss = (PFAST486_LEGACY_TSS)&NewTss;
USHORT NewLdtr, NewEs, NewCs, NewSs, NewDs;
- if (State->TaskReg.Limit < sizeof(FAST486_TSS)
- && State->TaskReg.Limit != sizeof(FAST486_LEGACY_TSS))
+ if (State->TaskReg.Limit < (sizeof(FAST486_TSS) - 1)
+ && State->TaskReg.Limit != (sizeof(FAST486_LEGACY_TSS) - 1))
{
/* Invalid task register limit */
Fast486ExceptionWithErrorCode(State, FAST486_EXCEPTION_TS, State->TaskReg.Selector);
if (!Fast486ReadLinearMemory(State,
State->TaskReg.Base,
&OldTss,
- State->TaskReg.Limit >= sizeof(FAST486_TSS)
+ State->TaskReg.Limit >= (sizeof(FAST486_TSS) - 1)
? sizeof(FAST486_TSS) : sizeof(FAST486_LEGACY_TSS),
FALSE))
{
/* If this is a task return, use the linked previous selector */
if (Type == FAST486_TASK_RETURN)
{
- if (State->TaskReg.Limit >= sizeof(FAST486_TSS)) Selector = LOWORD(OldTss.Link);
+ if (State->TaskReg.Limit >= (sizeof(FAST486_TSS) - 1)) Selector = LOWORD(OldTss.Link);
else Selector = OldLegacyTss->Link;
}
NewTssLimit |= 0x00000FFF;
}
- if (NewTssLimit < sizeof(FAST486_TSS) && NewTssLimit != sizeof(FAST486_LEGACY_TSS))
+ if (NewTssLimit < (sizeof(FAST486_TSS) - 1)
+ && NewTssLimit != (sizeof(FAST486_LEGACY_TSS) - 1))
{
/* TSS limit invalid */
Fast486ExceptionWithErrorCode(State, FAST486_EXCEPTION_TS, Selector);
if (!Fast486ReadLinearMemory(State,
NewTssAddress,
&NewTss,
- NewTssLimit >= sizeof(FAST486_TSS)
+ NewTssLimit >= (sizeof(FAST486_TSS) - 1)
? sizeof(FAST486_TSS) : sizeof(FAST486_LEGACY_TSS),
FALSE))
{
else
{
/* Store the link */
- if (NewTssLimit >= sizeof(FAST486_TSS)) NewTss.Link = State->TaskReg.Selector;
+ if (NewTssLimit >= (sizeof(FAST486_TSS) - 1)) NewTss.Link = State->TaskReg.Selector;
else NewLegacyTss->Link = State->TaskReg.Selector;
}
/* Save the current task into the TSS */
- if (State->TaskReg.Limit >= sizeof(FAST486_TSS))
+ if (State->TaskReg.Limit >= (sizeof(FAST486_TSS) - 1))
{
OldTss.Cr3 = State->ControlRegisters[FAST486_REG_CR3];
OldTss.Eip = State->InstPtr.Long;
if (!Fast486WriteLinearMemory(State,
State->TaskReg.Base,
&OldTss,
- State->TaskReg.Limit >= sizeof(FAST486_TSS)
+ State->TaskReg.Limit >= (sizeof(FAST486_TSS) - 1)
? sizeof(FAST486_TSS) : sizeof(FAST486_LEGACY_TSS),
FALSE))
{
State->TaskReg.Base = NewTssAddress;
State->TaskReg.Limit = NewTssLimit;
- if (NewTssLimit >= sizeof(FAST486_TSS))
+ if (NewTssLimit >= (sizeof(FAST486_TSS) - 1))
{
/* Change the page directory */
State->ControlRegisters[FAST486_REG_CR3] = NewTss.Cr3;
}
/* Flush the TLB */
- if (State->Tlb) RtlZeroMemory(State->Tlb, NUM_TLB_ENTRIES * sizeof(ULONG));
+ Fast486FlushTlb(State);
/* Update the CPL */
- if (NewTssLimit >= sizeof(FAST486_TSS)) State->Cpl = GET_SEGMENT_RPL(NewTss.Cs);
+ if (NewTssLimit >= (sizeof(FAST486_TSS) - 1)) State->Cpl = GET_SEGMENT_RPL(NewTss.Cs);
else State->Cpl = GET_SEGMENT_RPL(NewLegacyTss->Cs);
#ifndef FAST486_NO_PREFETCH
#endif
/* Load the registers */
- if (NewTssLimit >= sizeof(FAST486_TSS))
+ if (NewTssLimit >= (sizeof(FAST486_TSS) - 1))
{
State->InstPtr.Long = State->SavedInstPtr.Long = NewTss.Eip;
State->Flags.Long = NewTss.Eflags;
return FALSE;
}
- if (NewTssLimit >= sizeof(FAST486_TSS))
+ if (NewTssLimit >= (sizeof(FAST486_TSS) - 1))
{
if (!Fast486LoadSegmentInternal(State,
FAST486_REG_FS,
OldEsp,
FALSE,
ParamBuffer,
- Gate->ParamCount * sizeof(ULONG)))
+ Gate->ParamCount * (GateSize ? sizeof(ULONG) : sizeof(USHORT))))
{
/* Exception occurred */
return FALSE;
if (!Fast486ReadLinearMemory(State,
State->TaskReg.Base,
&Tss,
- State->TaskReg.Limit >= sizeof(FAST486_TSS)
+ State->TaskReg.Limit >= (sizeof(FAST486_TSS) - 1)
? sizeof(FAST486_TSS) : sizeof(FAST486_LEGACY_TSS),
FALSE))
{
{
case 0:
{
- if (State->TaskReg.Limit >= sizeof(FAST486_TSS))
+ if (State->TaskReg.Limit >= (sizeof(FAST486_TSS) - 1))
{
NewSs = Tss.Ss0;
NewEsp = Tss.Esp0;
case 1:
{
- if (State->TaskReg.Limit >= sizeof(FAST486_TSS))
+ if (State->TaskReg.Limit >= (sizeof(FAST486_TSS) - 1))
{
NewSs = Tss.Ss1;
NewEsp = Tss.Esp1;
case 2:
{
- if (State->TaskReg.Limit >= sizeof(FAST486_TSS))
+ if (State->TaskReg.Limit >= (sizeof(FAST486_TSS) - 1))
{
NewSs = Tss.Ss2;
NewEsp = Tss.Esp2;