diff --git a/include/reactos/libs/fast486/fast486.h b/include/reactos/libs/fast486/fast486.h index 6076e666b48..f619773aa7f 100644 --- a/include/reactos/libs/fast486/fast486.h +++ b/include/reactos/libs/fast486/fast486.h @@ -389,6 +389,21 @@ struct _FAST486_STATE /* FUNCTIONS ******************************************************************/ +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); @@ -409,10 +424,6 @@ VOID NTAPI Fast486DumpState(PFAST486_STATE State); -VOID -NTAPI -Fast486Reset(PFAST486_STATE State); - VOID NTAPI Fast486Interrupt(PFAST486_STATE State, UCHAR Number); diff --git a/lib/fast486/common.c b/lib/fast486/common.c index 0d3746cad27..db38487a0f3 100644 --- a/lib/fast486/common.c +++ b/lib/fast486/common.c @@ -65,7 +65,6 @@ Fast486ReadMemory(PFAST486_STATE State, { /* Read beyond limit */ Fast486Exception(State, FAST486_EXCEPTION_GP); - return FALSE; } @@ -91,7 +90,6 @@ Fast486ReadMemory(PFAST486_STATE State, if (!CachedDescriptor->Executable) { /* Data segment not executable */ - Fast486Exception(State, FAST486_EXCEPTION_GP); return FALSE; } @@ -101,7 +99,6 @@ Fast486ReadMemory(PFAST486_STATE State, if (CachedDescriptor->Executable && (!CachedDescriptor->ReadWrite)) { /* Code segment not readable */ - Fast486Exception(State, FAST486_EXCEPTION_GP); return FALSE; } @@ -149,37 +146,17 @@ Fast486ReadMemory(PFAST486_STATE State, 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 @@ Fast486WriteMemory(PFAST486_STATE State, 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 @@ Fast486WriteMemory(PFAST486_STATE State, 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 @@ Fast486InterruptInternal(PFAST486_STATE State, { /* 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)) diff --git a/lib/fast486/common.inl b/lib/fast486/common.inl index 394542bae72..63246059739 100644 --- a/lib/fast486/common.inl +++ b/lib/fast486/common.inl @@ -186,21 +186,11 @@ Fast486LoadSegment(PFAST486_STATE State, /* 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 @@ Fast486GetIntVector(PFAST486_STATE State, { /* 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 @@ FORCEINLINE BOOLEAN Fast486CalculateParity(UCHAR Number) { + // See http://graphics.stanford.edu/~seander/bithacks.html#ParityLookupTable too... return (0x9669 >> ((Number & 0x0F) ^ (Number >> 4))) & 1; } diff --git a/lib/fast486/fast486.c b/lib/fast486/fast486.c index 0dec8c195ea..52d93c1540e 100644 --- a/lib/fast486/fast486.c +++ b/lib/fast486/fast486.c @@ -124,38 +124,146 @@ Fast486ExecutionControl(PFAST486_STATE State, INT Command) || (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) +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) { - /* Call the internal function */ - Fast486ExecutionControl(State, FAST486_CONTINUE); + /* 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 -Fast486StepInto(PFAST486_STATE State) +Fast486Reset(PFAST486_STATE State) { - /* Call the internal function */ - Fast486ExecutionControl(State, FAST486_STEP_INTO); -} + USHORT i; -VOID -NTAPI -Fast486StepOver(PFAST486_STATE State) -{ - /* Call the internal function */ - Fast486ExecutionControl(State, FAST486_STEP_OVER); -} + 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; -VOID -NTAPI -Fast486StepOut(PFAST486_STATE State) -{ - /* Call the internal function */ - Fast486ExecutionControl(State, FAST486_STEP_OUT); + /* 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 @@ Fast486DumpState(PFAST486_STATE State) VOID NTAPI -Fast486Reset(PFAST486_STATE State) +Fast486Continue(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; + /* Call the internal function */ + Fast486ExecutionControl(State, FAST486_CONTINUE); +} - /* Clear the entire structure */ - RtlZeroMemory(State, sizeof(*State)); +VOID +NTAPI +Fast486StepInto(PFAST486_STATE State) +{ + /* Call the internal function */ + Fast486ExecutionControl(State, FAST486_STEP_INTO); +} - /* Initialize the registers */ - State->Flags.AlwaysSet = 1; - State->InstPtr.LowWord = 0xFFF0; +VOID +NTAPI +Fast486StepOver(PFAST486_STATE State) +{ + /* Call the internal function */ + Fast486ExecutionControl(State, FAST486_STEP_OVER); +} - /* 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 +NTAPI +Fast486StepOut(PFAST486_STATE State) +{ + /* Call the internal function */ + Fast486ExecutionControl(State, FAST486_STEP_OUT); } VOID diff --git a/lib/fast486/opcodes.c b/lib/fast486/opcodes.c index 81848a9b245..66e1d70aa08 100644 --- a/lib/fast486/opcodes.c +++ b/lib/fast486/opcodes.c @@ -4613,7 +4613,7 @@ FAST486_OPCODE_HANDLER(Fast486OpcodeInt) 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; diff --git a/subsystems/ntvdm/emulator.c b/subsystems/ntvdm/emulator.c index 1b5f4dfb5ab..df2e8434c2e 100644 --- a/subsystems/ntvdm/emulator.c +++ b/subsystems/ntvdm/emulator.c @@ -250,10 +250,6 @@ static VOID WINAPI EmulatorBiosOperation(PFAST486_STATE State, UCHAR BopCode) } } -static VOID WINAPI EmulatorIdle(PFAST486_STATE State) -{ -} - static UCHAR WINAPI EmulatorIntAcknowledge(PFAST486_STATE State) { UNREFERENCED_PARAMETER(State); @@ -264,23 +260,21 @@ static UCHAR WINAPI EmulatorIntAcknowledge(PFAST486_STATE State) /* 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 @@ BOOLEAN EmulatorInitialize() 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 @@ VOID EmulatorStep(VOID) 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; diff --git a/subsystems/ntvdm/emulator.h b/subsystems/ntvdm/emulator.h index b0d8a28347b..ea295ea6654 100644 --- a/subsystems/ntvdm/emulator.h +++ b/subsystems/ntvdm/emulator.h @@ -85,7 +85,7 @@ extern FAST486_STATE EmulatorContext; /* 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 @@ VOID EmulatorSetRegister(ULONG Register, ULONG Value); 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_