Author: hbelusca
Date: Fri Nov 1 01:46:58 2013
New Revision: 60814
URL:
http://svn.reactos.org/svn/reactos?rev=60814&view=rev
Log:
[FAST486][NTVDM]
- Introduce a Fast486Initialize which is used to set up the CPU callbacks (and use default
ones if some of the given callbacks are NULL), and to reset it the first time. Now
Fast486Reset is meant to be used for only resetting the CPU to a safe state.
- Hence we are now sure that State->WhateverCallback is never NULL (and is
theoretically valid), so don't do NULL-checks when calling them, but call them
directly. The default cases for those checks become the default calls for the default
callbacks.
- Remove the now-unneeded EmulatorIdle function.
Modified:
branches/ntvdm/include/reactos/libs/fast486/fast486.h
branches/ntvdm/lib/fast486/common.c
branches/ntvdm/lib/fast486/common.inl
branches/ntvdm/lib/fast486/fast486.c
branches/ntvdm/lib/fast486/opcodes.c
branches/ntvdm/subsystems/ntvdm/emulator.c
branches/ntvdm/subsystems/ntvdm/emulator.h
Modified: branches/ntvdm/include/reactos/libs/fast486/fast486.h
URL:
http://svn.reactos.org/svn/reactos/branches/ntvdm/include/reactos/libs/fast…
==============================================================================
--- branches/ntvdm/include/reactos/libs/fast486/fast486.h [iso-8859-1] (original)
+++ branches/ntvdm/include/reactos/libs/fast486/fast486.h [iso-8859-1] Fri Nov 1 01:46:58
2013
@@ -391,6 +391,21 @@
VOID
NTAPI
+Fast486Initialize(PFAST486_STATE State,
+ FAST486_MEM_READ_PROC MemReadCallback,
+ FAST486_MEM_WRITE_PROC MemWriteCallback,
+ FAST486_IO_READ_PROC IoReadCallback,
+ FAST486_IO_WRITE_PROC IoWriteCallback,
+ FAST486_IDLE_PROC IdleCallback,
+ FAST486_BOP_PROC BopCallback,
+ FAST486_INT_ACK_PROC IntAckCallback);
+
+VOID
+NTAPI
+Fast486Reset(PFAST486_STATE State);
+
+VOID
+NTAPI
Fast486Continue(PFAST486_STATE State);
VOID
@@ -408,10 +423,6 @@
VOID
NTAPI
Fast486DumpState(PFAST486_STATE State);
-
-VOID
-NTAPI
-Fast486Reset(PFAST486_STATE State);
VOID
NTAPI
Modified: branches/ntvdm/lib/fast486/common.c
URL:
http://svn.reactos.org/svn/reactos/branches/ntvdm/lib/fast486/common.c?rev=…
==============================================================================
--- branches/ntvdm/lib/fast486/common.c [iso-8859-1] (original)
+++ branches/ntvdm/lib/fast486/common.c [iso-8859-1] Fri Nov 1 01:46:58 2013
@@ -65,7 +65,6 @@
{
/* Read beyond limit */
Fast486Exception(State, FAST486_EXCEPTION_GP);
-
return FALSE;
}
@@ -91,7 +90,6 @@
if (!CachedDescriptor->Executable)
{
/* Data segment not executable */
-
Fast486Exception(State, FAST486_EXCEPTION_GP);
return FALSE;
}
@@ -101,7 +99,6 @@
if (CachedDescriptor->Executable &&
(!CachedDescriptor->ReadWrite))
{
/* Code segment not readable */
-
Fast486Exception(State, FAST486_EXCEPTION_GP);
return FALSE;
}
@@ -149,37 +146,17 @@
PageLength = PAGE_OFFSET(LinearAddress + Size);
}
- /* Did the host provide a memory hook? */
- if (State->MemReadCallback)
- {
- /* Yes, call the host */
- State->MemReadCallback(State,
- (TableEntry.Address << 12) | PageOffset,
- Buffer,
- PageLength);
- }
- else
- {
- /* Read the memory directly */
- RtlMoveMemory(Buffer,
- (PVOID)((TableEntry.Address << 12) | PageOffset),
- PageLength);
- }
+ /* Read the entry */
+ State->MemReadCallback(State,
+ (TableEntry.Address << 12) | PageOffset,
+ Buffer,
+ PageLength);
}
}
else
{
- /* Did the host provide a memory hook? */
- if (State->MemReadCallback)
- {
- /* Yes, call the host */
- State->MemReadCallback(State, LinearAddress, Buffer, Size);
- }
- else
- {
- /* Read the memory directly */
- RtlMoveMemory(Buffer, (PVOID)LinearAddress, Size);
- }
+ /* Read the entry */
+ State->MemReadCallback(State, LinearAddress, Buffer, Size);
}
return TRUE;
@@ -229,14 +206,12 @@
if (CachedDescriptor->Executable)
{
/* Code segment not writable */
-
Fast486Exception(State, FAST486_EXCEPTION_GP);
return FALSE;
}
else if (!CachedDescriptor->ReadWrite)
{
/* Data segment not writeable */
-
Fast486Exception(State, FAST486_EXCEPTION_GP);
return FALSE;
}
@@ -285,37 +260,17 @@
PageLength = PAGE_OFFSET(LinearAddress + Size);
}
- /* Did the host provide a memory hook? */
- if (State->MemWriteCallback)
- {
- /* Yes, call the host */
- State->MemWriteCallback(State,
- (TableEntry.Address << 12) | PageOffset,
- Buffer,
- PageLength);
- }
- else
- {
- /* Read the memory directly */
- RtlMoveMemory((PVOID)((TableEntry.Address << 12) | PageOffset),
- Buffer,
- PageLength);
- }
+ /* Write the entry */
+ State->MemWriteCallback(State,
+ (TableEntry.Address << 12) | PageOffset,
+ Buffer,
+ PageLength);
}
}
else
{
- /* Did the host provide a memory hook? */
- if (State->MemWriteCallback)
- {
- /* Yes, call the host */
- State->MemWriteCallback(State, LinearAddress, Buffer, Size);
- }
- else
- {
- /* Write the memory directly */
- RtlMoveMemory((PVOID)LinearAddress, Buffer, Size);
- }
+ /* Write the entry */
+ State->MemWriteCallback(State, LinearAddress, Buffer, Size);
}
return TRUE;
@@ -339,17 +294,10 @@
{
/* Read the TSS */
// FIXME: This code is only correct when paging is disabled!!!
- if (State->MemReadCallback)
- {
- State->MemReadCallback(State,
- State->Tss.Address,
- &Tss,
- sizeof(Tss));
- }
- else
- {
- RtlMoveMemory(&Tss, (PVOID)State->Tss.Address, sizeof(Tss));
- }
+ State->MemReadCallback(State,
+ State->Tss.Address,
+ &Tss,
+ sizeof(Tss));
/* Check the new (higher) privilege level */
switch (GET_SEGMENT_RPL(SegmentSelector))
Modified: branches/ntvdm/lib/fast486/common.inl
URL:
http://svn.reactos.org/svn/reactos/branches/ntvdm/lib/fast486/common.inl?re…
==============================================================================
--- branches/ntvdm/lib/fast486/common.inl [iso-8859-1] (original)
+++ branches/ntvdm/lib/fast486/common.inl [iso-8859-1] Fri Nov 1 01:46:58 2013
@@ -186,21 +186,11 @@
/* Read the GDT */
// FIXME: This code is only correct when paging is disabled!!!
- if (State->MemReadCallback)
- {
- State->MemReadCallback(State,
- State->Gdtr.Address
- + GET_SEGMENT_INDEX(Selector),
- &GdtEntry,
- sizeof(GdtEntry));
- }
- else
- {
- RtlMoveMemory(&GdtEntry,
- (PVOID)(State->Gdtr.Address
- + GET_SEGMENT_INDEX(Selector)),
- sizeof(GdtEntry));
- }
+ State->MemReadCallback(State,
+ State->Gdtr.Address
+ + GET_SEGMENT_INDEX(Selector),
+ &GdtEntry,
+ sizeof(GdtEntry));
if (Segment == FAST486_REG_SS)
{
@@ -399,42 +389,22 @@
{
/* Read from the IDT */
// FIXME: This code is only correct when paging is disabled!!!
- if (State->MemReadCallback)
- {
- State->MemReadCallback(State,
- State->Idtr.Address
- + Number * sizeof(*IdtEntry),
- IdtEntry,
- sizeof(*IdtEntry));
- }
- else
- {
- RtlMoveMemory(IdtEntry,
- (PVOID)(State->Idtr.Address
- + Number * sizeof(*IdtEntry)),
- sizeof(*IdtEntry));
- }
+ State->MemReadCallback(State,
+ State->Idtr.Address
+ + Number * sizeof(*IdtEntry),
+ IdtEntry,
+ sizeof(*IdtEntry));
}
else
{
/* Read from the real-mode IVT */
/* Paging is always disabled in real mode */
- if (State->MemReadCallback)
- {
- State->MemReadCallback(State,
- State->Idtr.Address
- + Number * sizeof(FarPointer),
- &FarPointer,
- sizeof(FarPointer));
- }
- else
- {
- RtlMoveMemory(&FarPointer,
- (PVOID)(State->Idtr.Address
- + Number * sizeof(FarPointer)),
- sizeof(FarPointer));
- }
+ State->MemReadCallback(State,
+ State->Idtr.Address
+ + Number * sizeof(FarPointer),
+ &FarPointer,
+ sizeof(FarPointer));
/* Fill a fake IDT entry */
IdtEntry->Offset = LOWORD(FarPointer);
@@ -458,6 +428,7 @@
BOOLEAN
Fast486CalculateParity(UCHAR Number)
{
+ // See
http://graphics.stanford.edu/~seander/bithacks.html#ParityLookupTable too...
return (0x9669 >> ((Number & 0x0F) ^ (Number >> 4))) & 1;
}
Modified: branches/ntvdm/lib/fast486/fast486.c
URL:
http://svn.reactos.org/svn/reactos/branches/ntvdm/lib/fast486/fast486.c?rev…
==============================================================================
--- branches/ntvdm/lib/fast486/fast486.c [iso-8859-1] (original)
+++ branches/ntvdm/lib/fast486/fast486.c [iso-8859-1] Fri Nov 1 01:46:58 2013
@@ -124,38 +124,146 @@
|| (Fast486OpcodeHandlers[Opcode] == Fast486OpcodePrefix));
}
+/* DEFAULT CALLBACKS **********************************************************/
+
+static VOID
+NTAPI
+Fast486MemReadCallback(PFAST486_STATE State, ULONG Address, PVOID Buffer, ULONG Size)
+{
+ UNREFERENCED_PARAMETER(State);
+
+ RtlMoveMemory(Buffer, (PVOID)Address, Size);
+}
+
+static VOID
+NTAPI
+Fast486MemWriteCallback(PFAST486_STATE State, ULONG Address, PVOID Buffer, ULONG Size)
+{
+ UNREFERENCED_PARAMETER(State);
+
+ RtlMoveMemory((PVOID)Address, Buffer, Size);
+}
+
+static VOID
+NTAPI
+Fast486IoReadCallback(PFAST486_STATE State, ULONG Port, PVOID Buffer, ULONG Size)
+{
+ UNREFERENCED_PARAMETER(State);
+ UNREFERENCED_PARAMETER(Port);
+ UNREFERENCED_PARAMETER(Buffer);
+ UNREFERENCED_PARAMETER(Size);
+}
+
+static VOID
+NTAPI
+Fast486IoWriteCallback(PFAST486_STATE State, ULONG Port, PVOID Buffer, ULONG Size)
+{
+ UNREFERENCED_PARAMETER(State);
+ UNREFERENCED_PARAMETER(Port);
+ UNREFERENCED_PARAMETER(Buffer);
+ UNREFERENCED_PARAMETER(Size);
+}
+
+static VOID
+NTAPI
+Fast486IdleCallback(PFAST486_STATE State)
+{
+ UNREFERENCED_PARAMETER(State);
+}
+
+static VOID
+NTAPI
+Fast486BopCallback(PFAST486_STATE State, UCHAR BopCode)
+{
+ UNREFERENCED_PARAMETER(State);
+ UNREFERENCED_PARAMETER(BopCode);
+}
+
+static UCHAR
+NTAPI
+Fast486IntAckCallback(PFAST486_STATE State)
+{
+ UNREFERENCED_PARAMETER(State);
+
+ /* Return something... */
+ return 0;
+}
+
/* PUBLIC FUNCTIONS ***********************************************************/
VOID
NTAPI
-Fast486Continue(PFAST486_STATE State)
-{
- /* Call the internal function */
- Fast486ExecutionControl(State, FAST486_CONTINUE);
-}
-
-VOID
-NTAPI
-Fast486StepInto(PFAST486_STATE State)
-{
- /* Call the internal function */
- Fast486ExecutionControl(State, FAST486_STEP_INTO);
-}
-
-VOID
-NTAPI
-Fast486StepOver(PFAST486_STATE State)
-{
- /* Call the internal function */
- Fast486ExecutionControl(State, FAST486_STEP_OVER);
-}
-
-VOID
-NTAPI
-Fast486StepOut(PFAST486_STATE State)
-{
- /* Call the internal function */
- Fast486ExecutionControl(State, FAST486_STEP_OUT);
+Fast486Initialize(PFAST486_STATE State,
+ FAST486_MEM_READ_PROC MemReadCallback,
+ FAST486_MEM_WRITE_PROC MemWriteCallback,
+ FAST486_IO_READ_PROC IoReadCallback,
+ FAST486_IO_WRITE_PROC IoWriteCallback,
+ FAST486_IDLE_PROC IdleCallback,
+ FAST486_BOP_PROC BopCallback,
+ FAST486_INT_ACK_PROC IntAckCallback)
+{
+ /* Set the callbacks (or use default ones if some are NULL) */
+ State->MemReadCallback = (MemReadCallback ? MemReadCallback :
Fast486MemReadCallback );
+ State->MemWriteCallback = (MemWriteCallback ? MemWriteCallback :
Fast486MemWriteCallback);
+ State->IoReadCallback = (IoReadCallback ? IoReadCallback :
Fast486IoReadCallback );
+ State->IoWriteCallback = (IoWriteCallback ? IoWriteCallback :
Fast486IoWriteCallback );
+ State->IdleCallback = (IdleCallback ? IdleCallback :
Fast486IdleCallback );
+ State->BopCallback = (BopCallback ? BopCallback :
Fast486BopCallback );
+ State->IntAckCallback = (IntAckCallback ? IntAckCallback :
Fast486IntAckCallback );
+
+ /* Reset the CPU */
+ Fast486Reset(State);
+}
+
+VOID
+NTAPI
+Fast486Reset(PFAST486_STATE State)
+{
+ USHORT i;
+
+ FAST486_MEM_READ_PROC MemReadCallback = State->MemReadCallback;
+ FAST486_MEM_WRITE_PROC MemWriteCallback = State->MemWriteCallback;
+ FAST486_IO_READ_PROC IoReadCallback = State->IoReadCallback;
+ FAST486_IO_WRITE_PROC IoWriteCallback = State->IoWriteCallback;
+ FAST486_IDLE_PROC IdleCallback = State->IdleCallback;
+ FAST486_BOP_PROC BopCallback = State->BopCallback;
+ FAST486_INT_ACK_PROC IntAckCallback = State->IntAckCallback;
+
+ /* Clear the entire structure */
+ RtlZeroMemory(State, sizeof(*State));
+
+ /* Initialize the registers */
+ State->Flags.AlwaysSet = 1;
+ State->InstPtr.LowWord = 0xFFF0;
+
+ /* Initialize segments */
+ for (i = 0; i < FAST486_NUM_SEG_REGS; i++)
+ {
+ /* Set the selector, base and limit, other values don't apply in real mode
*/
+ State->SegmentRegs[i].Selector = 0;
+ State->SegmentRegs[i].Base = 0;
+ State->SegmentRegs[i].Limit = 0xFFFF;
+ }
+
+ /* Initialize the code segment */
+ State->SegmentRegs[FAST486_REG_CS].Selector = 0xF000;
+ State->SegmentRegs[FAST486_REG_CS].Base = 0xFFFF0000;
+
+ /* Initialize the IDT */
+ State->Idtr.Size = 0x3FF;
+ State->Idtr.Address = 0;
+
+ /* Initialize CR0 */
+ State->ControlRegisters[FAST486_REG_CR0] |= FAST486_CR0_ET;
+
+ /* Restore the callbacks */
+ State->MemReadCallback = MemReadCallback;
+ State->MemWriteCallback = MemWriteCallback;
+ State->IoReadCallback = IoReadCallback;
+ State->IoWriteCallback = IoWriteCallback;
+ State->IdleCallback = IdleCallback;
+ State->BopCallback = BopCallback;
+ State->IntAckCallback = IntAckCallback;
}
VOID
@@ -244,52 +352,34 @@
VOID
NTAPI
-Fast486Reset(PFAST486_STATE State)
-{
- INT i;
- FAST486_MEM_READ_PROC MemReadCallback = State->MemReadCallback;
- FAST486_MEM_WRITE_PROC MemWriteCallback = State->MemWriteCallback;
- FAST486_IO_READ_PROC IoReadCallback = State->IoReadCallback;
- FAST486_IO_WRITE_PROC IoWriteCallback = State->IoWriteCallback;
- FAST486_IDLE_PROC IdleCallback = State->IdleCallback;
- FAST486_BOP_PROC BopCallback = State->BopCallback;
- FAST486_INT_ACK_PROC IntAckCallback = State->IntAckCallback;
-
- /* Clear the entire structure */
- RtlZeroMemory(State, sizeof(*State));
-
- /* Initialize the registers */
- State->Flags.AlwaysSet = 1;
- State->InstPtr.LowWord = 0xFFF0;
-
- /* Initialize segments */
- for (i = 0; i < FAST486_NUM_SEG_REGS; i++)
- {
- /* Set the selector, base and limit, other values don't apply in real mode
*/
- State->SegmentRegs[i].Selector = 0;
- State->SegmentRegs[i].Base = 0;
- State->SegmentRegs[i].Limit = 0xFFFF;
- }
-
- /* Initialize the code segment */
- State->SegmentRegs[FAST486_REG_CS].Selector = 0xF000;
- State->SegmentRegs[FAST486_REG_CS].Base = 0xFFFF0000;
-
- /* Initialize the IDT */
- State->Idtr.Size = 0x3FF;
- State->Idtr.Address = 0;
-
- /* Initialize CR0 */
- State->ControlRegisters[FAST486_REG_CR0] |= FAST486_CR0_ET;
-
- /* Restore the callbacks */
- State->MemReadCallback = MemReadCallback;
- State->MemWriteCallback = MemWriteCallback;
- State->IoReadCallback = IoReadCallback;
- State->IoWriteCallback = IoWriteCallback;
- State->IdleCallback = IdleCallback;
- State->BopCallback = BopCallback;
- State->IntAckCallback = IntAckCallback;
+Fast486Continue(PFAST486_STATE State)
+{
+ /* Call the internal function */
+ Fast486ExecutionControl(State, FAST486_CONTINUE);
+}
+
+VOID
+NTAPI
+Fast486StepInto(PFAST486_STATE State)
+{
+ /* Call the internal function */
+ Fast486ExecutionControl(State, FAST486_STEP_INTO);
+}
+
+VOID
+NTAPI
+Fast486StepOver(PFAST486_STATE State)
+{
+ /* Call the internal function */
+ Fast486ExecutionControl(State, FAST486_STEP_OVER);
+}
+
+VOID
+NTAPI
+Fast486StepOut(PFAST486_STATE State)
+{
+ /* Call the internal function */
+ Fast486ExecutionControl(State, FAST486_STEP_OUT);
}
VOID
Modified: branches/ntvdm/lib/fast486/opcodes.c
URL:
http://svn.reactos.org/svn/reactos/branches/ntvdm/lib/fast486/opcodes.c?rev…
==============================================================================
--- branches/ntvdm/lib/fast486/opcodes.c [iso-8859-1] (original)
+++ branches/ntvdm/lib/fast486/opcodes.c [iso-8859-1] Fri Nov 1 01:46:58 2013
@@ -4613,7 +4613,7 @@
FAST486_OPCODE_HANDLER(Fast486OpcodeIret)
{
- INT i;
+ USHORT i;
ULONG InstPtr, CodeSel, StackPtr, StackSel;
FAST486_FLAGS_REG NewFlags;
BOOLEAN Size = State->SegmentRegs[FAST486_REG_CS].Size;
Modified: branches/ntvdm/subsystems/ntvdm/emulator.c
URL:
http://svn.reactos.org/svn/reactos/branches/ntvdm/subsystems/ntvdm/emulator…
==============================================================================
--- branches/ntvdm/subsystems/ntvdm/emulator.c [iso-8859-1] (original)
+++ branches/ntvdm/subsystems/ntvdm/emulator.c [iso-8859-1] Fri Nov 1 01:46:58 2013
@@ -250,10 +250,6 @@
}
}
-static VOID WINAPI EmulatorIdle(PFAST486_STATE State)
-{
-}
-
static UCHAR WINAPI EmulatorIntAcknowledge(PFAST486_STATE State)
{
UNREFERENCED_PARAMETER(State);
@@ -264,23 +260,21 @@
/* PUBLIC FUNCTIONS ***********************************************************/
-BOOLEAN EmulatorInitialize()
+BOOLEAN EmulatorInitialize(VOID)
{
/* Allocate memory for the 16-bit address space */
BaseAddress = HeapAlloc(GetProcessHeap(), HEAP_ZERO_MEMORY, MAX_ADDRESS);
if (BaseAddress == NULL) return FALSE;
- /* Set the callbacks */
- EmulatorContext.MemReadCallback = EmulatorReadMemory;
- EmulatorContext.MemWriteCallback = EmulatorWriteMemory;
- EmulatorContext.IoReadCallback = EmulatorReadIo; // Must be != NULL
- EmulatorContext.IoWriteCallback = EmulatorWriteIo; // Must be != NULL
- EmulatorContext.IdleCallback = EmulatorIdle; // Must be != NULL
- EmulatorContext.BopCallback = EmulatorBiosOperation;
- EmulatorContext.IntAckCallback = EmulatorIntAcknowledge;
-
- /* Reset the CPU */
- Fast486Reset(&EmulatorContext);
+ /* Initialize the CPU */
+ Fast486Initialize(&EmulatorContext,
+ EmulatorReadMemory,
+ EmulatorWriteMemory,
+ EmulatorReadIo,
+ EmulatorWriteIo,
+ NULL,
+ EmulatorBiosOperation,
+ EmulatorIntAcknowledge);
/* Enable interrupts */
EmulatorSetFlag(EMULATOR_FLAG_IF);
@@ -288,6 +282,12 @@
return TRUE;
}
+VOID EmulatorCleanup(VOID)
+{
+ /* Free the memory allocated for the 16-bit address space */
+ if (BaseAddress != NULL) HeapFree(GetProcessHeap(), 0, BaseAddress);
+}
+
VOID EmulatorSetStack(WORD Segment, DWORD Offset)
{
Fast486SetStack(&EmulatorContext, Segment, Offset);
@@ -365,12 +365,6 @@
Fast486StepInto(&EmulatorContext);
}
-VOID EmulatorCleanup(VOID)
-{
- /* Free the memory allocated for the 16-bit address space */
- if (BaseAddress != NULL) HeapFree(GetProcessHeap(), 0, BaseAddress);
-}
-
VOID EmulatorSetA20(BOOLEAN Enabled)
{
A20Line = Enabled;
Modified: branches/ntvdm/subsystems/ntvdm/emulator.h
URL:
http://svn.reactos.org/svn/reactos/branches/ntvdm/subsystems/ntvdm/emulator…
==============================================================================
--- branches/ntvdm/subsystems/ntvdm/emulator.h [iso-8859-1] (original)
+++ branches/ntvdm/subsystems/ntvdm/emulator.h [iso-8859-1] Fri Nov 1 01:46:58 2013
@@ -85,7 +85,7 @@
/* FUNCTIONS ******************************************************************/
-BOOLEAN EmulatorInitialize();
+BOOLEAN EmulatorInitialize(VOID);
VOID EmulatorSetStack(WORD Segment, DWORD Offset);
VOID EmulatorExecute(WORD Segment, WORD Offset);
VOID EmulatorInterrupt(BYTE Number);
@@ -96,8 +96,8 @@
BOOLEAN EmulatorGetFlag(ULONG Flag);
VOID EmulatorSetFlag(ULONG Flag);
VOID EmulatorClearFlag(ULONG Flag);
-VOID EmulatorStep();
-VOID EmulatorCleanup();
+VOID EmulatorStep(VOID);
+VOID EmulatorCleanup(VOID);
VOID EmulatorSetA20(BOOLEAN Enabled);
#endif // _EMULATOR_H_