PVOID Buffer,
ULONG Size)
{
- INT Cpl = Fast486GetCurrentPrivLevel(State);
-
/* Check if paging is enabled */
if (State->ControlRegisters[FAST486_REG_CR0] & FAST486_CR0_PG)
{
ULONG Page;
FAST486_PAGE_TABLE TableEntry;
+ INT Cpl = Fast486GetCurrentPrivLevel(State);
+ ULONG BufferOffset = 0;
for (Page = PAGE_ALIGN(LinearAddress);
Page <= PAGE_ALIGN(LinearAddress + Size - 1);
/* Check if this is the first page */
if (Page == PAGE_ALIGN(LinearAddress))
{
- /* Start copying from the offset from the beginning of the page */
+ /* Start reading from the offset from the beginning of the page */
PageOffset = PAGE_OFFSET(LinearAddress);
+ PageLength -= PageOffset;
}
/* Check if this is the last page */
if (Page == PAGE_ALIGN(LinearAddress + Size - 1))
{
- /* Copy only a part of the page */
- PageLength = PAGE_OFFSET(LinearAddress + Size) - PageOffset;
+ /* Read only a part of the page */
+ PageLength = PAGE_OFFSET(LinearAddress + Size - 1) - PageOffset + 1;
}
/* Read the memory */
State->MemReadCallback(State,
(TableEntry.Address << 12) | PageOffset,
- Buffer,
+ (PVOID)((ULONG_PTR)Buffer + BufferOffset),
PageLength);
+
+ BufferOffset += PageLength;
}
}
else
PVOID Buffer,
ULONG Size)
{
- INT Cpl = Fast486GetCurrentPrivLevel(State);
-
/* Check if paging is enabled */
if (State->ControlRegisters[FAST486_REG_CR0] & FAST486_CR0_PG)
{
ULONG Page;
FAST486_PAGE_TABLE TableEntry;
+ INT Cpl = Fast486GetCurrentPrivLevel(State);
+ ULONG BufferOffset = 0;
for (Page = PAGE_ALIGN(LinearAddress);
Page <= PAGE_ALIGN(LinearAddress + Size - 1);
/* Check if this is the first page */
if (Page == PAGE_ALIGN(LinearAddress))
{
- /* Start copying from the offset from the beginning of the page */
+ /* Start writing from the offset from the beginning of the page */
PageOffset = PAGE_OFFSET(LinearAddress);
+ PageLength -= PageOffset;
}
/* Check if this is the last page */
if (Page == PAGE_ALIGN(LinearAddress + Size - 1))
{
- /* Copy only a part of the page */
- PageLength = PAGE_OFFSET(LinearAddress + Size) - PageOffset;
+ /* Write only a part of the page */
+ PageLength = PAGE_OFFSET(LinearAddress + Size - 1) - PageOffset + 1;
}
/* Write the memory */
State->MemWriteCallback(State,
(TableEntry.Address << 12) | PageOffset,
- Buffer,
+ (PVOID)((ULONG_PTR)Buffer + BufferOffset),
PageLength);
+
+ BufferOffset += PageLength;
}
}
else
}
/* Subtract ESP by 4 */
- State->GeneralRegs[FAST486_REG_ESP].Long -= 4;
+ State->GeneralRegs[FAST486_REG_ESP].Long -= sizeof(ULONG);
/* Store the value in SS:ESP */
return Fast486WriteMemory(State,
USHORT ShortValue = LOWORD(Value);
/* Check if SP is 1 */
- if (State->GeneralRegs[FAST486_REG_ESP].Long == 1)
+ if (State->GeneralRegs[FAST486_REG_ESP].LowWord == 1)
{
Fast486Exception(State, FAST486_EXCEPTION_SS);
return FALSE;
}
/* Subtract SP by 2 */
- State->GeneralRegs[FAST486_REG_ESP].LowWord -= 2;
+ State->GeneralRegs[FAST486_REG_ESP].LowWord -= sizeof(USHORT);
/* Store the value in SS:SP */
return Fast486WriteMemory(State,
Fast486StackPop(PFAST486_STATE State,
PULONG Value)
{
- ULONG LongValue;
- USHORT ShortValue;
BOOLEAN Size = State->SegmentRegs[FAST486_REG_CS].Size;
/* The OPSIZE prefix toggles the size */
if (Size)
{
/* 32-bit size */
+ ULONG LongValue;
/* Check if ESP is 0xFFFFFFFF */
if (State->GeneralRegs[FAST486_REG_ESP].Long == 0xFFFFFFFF)
}
/* Increment ESP by 4 */
- State->GeneralRegs[FAST486_REG_ESP].Long += 4;
+ State->GeneralRegs[FAST486_REG_ESP].Long += sizeof(ULONG);
/* Store the value in the result */
*Value = LongValue;
else
{
/* 16-bit size */
+ USHORT ShortValue;
/* Check if SP is 0xFFFF */
if (State->GeneralRegs[FAST486_REG_ESP].LowWord == 0xFFFF)
}
/* Increment SP by 2 */
- State->GeneralRegs[FAST486_REG_ESP].LowWord += 2;
+ State->GeneralRegs[FAST486_REG_ESP].LowWord += sizeof(USHORT);
/* Store the value in the result */
*Value = ShortValue;
FORCEINLINE
BOOLEAN
Fast486LoadSegment(PFAST486_STATE State,
- INT Segment,
+ FAST486_SEG_REGS Segment,
USHORT Selector)
{
PFAST486_SEG_REG CachedDescriptor;
else
{
/* Make sure the LDT contains the entry */
- if (GET_SEGMENT_INDEX(Selector) >= (State->Ldtr.Size + 1))
+ if (GET_SEGMENT_INDEX(Selector) >= (State->Ldtr.Limit + 1))
{
Fast486ExceptionWithErrorCode(State, FAST486_EXCEPTION_GP, Selector);
return FALSE;
/* Read the LDT */
if (!Fast486ReadLinearMemory(State,
- State->Ldtr.Address
+ State->Ldtr.Base
+ GET_SEGMENT_INDEX(Selector),
&GdtEntry,
sizeof(GdtEntry)))
{
/* Loading a data segment */
- if (!GdtEntry.SystemType)
+ if (GET_SEGMENT_INDEX(Selector) != 0)
{
- /* This is a special descriptor */
- Fast486ExceptionWithErrorCode(State, FAST486_EXCEPTION_GP, Selector);
- return FALSE;
- }
+ if (!GdtEntry.SystemType)
+ {
+ /* This is a special descriptor */
+ Fast486ExceptionWithErrorCode(State, FAST486_EXCEPTION_GP, Selector);
+ return FALSE;
+ }
- if ((GET_SEGMENT_RPL(Selector) > GdtEntry.Dpl)
- || (Fast486GetCurrentPrivLevel(State) > GdtEntry.Dpl))
- {
- Fast486ExceptionWithErrorCode(State, FAST486_EXCEPTION_GP, Selector);
- return FALSE;
- }
+ if ((GET_SEGMENT_RPL(Selector) > GdtEntry.Dpl)
+ || (Fast486GetCurrentPrivLevel(State) > GdtEntry.Dpl))
+ {
+ Fast486ExceptionWithErrorCode(State, FAST486_EXCEPTION_GP, Selector);
+ return FALSE;
+ }
- if (!GdtEntry.Present)
+ if (!GdtEntry.Present)
+ {
+ Fast486ExceptionWithErrorCode(State, FAST486_EXCEPTION_NP, Selector);
+ return FALSE;
+ }
+ }
+ else
{
- Fast486ExceptionWithErrorCode(State, FAST486_EXCEPTION_NP, Selector);
- return FALSE;
+ /* This is a NULL selector */
+ RtlZeroMemory(&GdtEntry, sizeof(GdtEntry));
}
}
CachedDescriptor->DirConf = GdtEntry.DirConf;
CachedDescriptor->Executable = GdtEntry.Executable;
CachedDescriptor->SystemType = GdtEntry.SystemType;
+ CachedDescriptor->Rpl = GET_SEGMENT_RPL(Selector);
CachedDescriptor->Dpl = GdtEntry.Dpl;
CachedDescriptor->Present = GdtEntry.Present;
CachedDescriptor->Size = GdtEntry.Size;