{
BOOLEAN OperandSize, AddressSize;
FAST486_MOD_REG_RM ModRegRm;
+ BOOLEAN Valid;
USHORT Selector;
FAST486_GDT_ENTRY GdtEntry;
DWORD AccessRights;
}
}
- if (!(Selector & SEGMENT_TABLE_INDICATOR))
+ if (!Fast486ReadDescriptorEntry(State, Selector, &Valid, &GdtEntry))
{
- /* Check if the GDT contains the entry */
- if (GET_SEGMENT_INDEX(Selector) >= (State->Gdtr.Size + 1))
- {
- State->Flags.Zf = FALSE;
- return;
- }
-
- /* Read the GDT */
- if (!Fast486ReadLinearMemory(State,
- State->Gdtr.Address
- + GET_SEGMENT_INDEX(Selector),
- &GdtEntry,
- sizeof(GdtEntry)))
- {
- /* Exception occurred */
- return;
- }
+ /* Exception occurred */
+ return;
}
- else
- {
- /* Check if the LDT contains the entry */
- if (GET_SEGMENT_INDEX(Selector) >= (State->Ldtr.Limit + 1))
- {
- State->Flags.Zf = FALSE;
- return;
- }
- /* Read the LDT */
- if (!Fast486ReadLinearMemory(State,
- State->Ldtr.Base
- + GET_SEGMENT_INDEX(Selector),
- &GdtEntry,
- sizeof(GdtEntry)))
- {
- /* Exception occurred */
- return;
- }
+ if (!Valid)
+ {
+ State->Flags.Zf = FALSE;
+ return;
}
/* Privilege check */
{
BOOLEAN OperandSize, AddressSize;
FAST486_MOD_REG_RM ModRegRm;
+ BOOLEAN Valid;
USHORT Selector;
ULONG Limit;
FAST486_GDT_ENTRY GdtEntry;
}
}
- if (!(Selector & SEGMENT_TABLE_INDICATOR))
+ if (!Fast486ReadDescriptorEntry(State, Selector, &Valid, &GdtEntry))
{
- /* Check if the GDT contains the entry */
- if (GET_SEGMENT_INDEX(Selector) >= (State->Gdtr.Size + 1))
- {
- State->Flags.Zf = FALSE;
- return;
- }
-
- /* Read the GDT */
- if (!Fast486ReadLinearMemory(State,
- State->Gdtr.Address
- + GET_SEGMENT_INDEX(Selector),
- &GdtEntry,
- sizeof(GdtEntry)))
- {
- /* Exception occurred */
- return;
- }
+ /* Exception occurred */
+ return;
}
- else
- {
- /* Check if the LDT contains the entry */
- if (GET_SEGMENT_INDEX(Selector) >= (State->Ldtr.Limit + 1))
- {
- State->Flags.Zf = FALSE;
- return;
- }
- /* Read the LDT */
- if (!Fast486ReadLinearMemory(State,
- State->Ldtr.Base
- + GET_SEGMENT_INDEX(Selector),
- &GdtEntry,
- sizeof(GdtEntry)))
- {
- /* Exception occurred */
- return;
- }
+ if (!Valid)
+ {
+ State->Flags.Zf = FALSE;
+ return;
}
/* Privilege check */
/* Calculate the limit */
Limit = GdtEntry.Limit | (GdtEntry.LimitHigh << 16);
- if (GdtEntry.Granularity) Limit <<= 12;
+
+ if (GdtEntry.Granularity)
+ {
+ Limit <<= 12;
+ Limit |= 0x00000FFF;
+ }
/* Set ZF */
State->Flags.Zf = TRUE;
}
}
+#ifndef FAST486_NO_PREFETCH
+ /* Changing CR0 or CR3 can interfere with prefetching (because of paging) */
+ State->PrefetchValid = FALSE;
+#endif
+
+ if (State->Tlb && (ModRegRm.Register == (INT)FAST486_REG_CR3))
+ {
+ /* Flush the TLB */
+ RtlZeroMemory(State->Tlb, NUM_TLB_ENTRIES * sizeof(ULONG));
+ }
+
/* Load a value to the control register */
State->ControlRegisters[ModRegRm.Register] = Value;
}
for (i = 0; i < DataSize; i++)
{
- if(Value & (1 << i))
+ if (Value & (1 << i))
{
/* Save the bit number */
BitNumber = i;
for (i = DataSize - 1; i >= 0; i--)
{
- if(Value & (1 << i))
+ if (Value & (1 << i))
{
/* Save the bit number */
BitNumber = i;