diff --git a/reactos/subsystems/ntvdm/CMakeLists.txt b/reactos/subsystems/ntvdm/CMakeLists.txt index 2793b0b5415..29b0c6c2498 100644 --- a/reactos/subsystems/ntvdm/CMakeLists.txt +++ b/reactos/subsystems/ntvdm/CMakeLists.txt @@ -17,6 +17,7 @@ list(APPEND SOURCE cpu/bop.c cpu/callback.c cpu/cpu.c + cpu/registers.c hardware/cmos.c hardware/keyboard.c hardware/mouse.c @@ -34,7 +35,6 @@ list(APPEND SOURCE emulator.c int32.c io.c - registers.c utils.c vddsup.c ntvdm.c diff --git a/reactos/subsystems/ntvdm/registers.c b/reactos/subsystems/ntvdm/cpu/registers.c similarity index 71% rename from reactos/subsystems/ntvdm/registers.c rename to reactos/subsystems/ntvdm/cpu/registers.c index 57aca7faae4..a326fda00d1 100644 --- a/reactos/subsystems/ntvdm/registers.c +++ b/reactos/subsystems/ntvdm/cpu/registers.c @@ -11,23 +11,83 @@ #define NDEBUG #include "emulator.h" -#include "cpu/cpu.h" +#include "cpu.h" +#include "x86context.h" + +/* PRIVATE VARIABLES **********************************************************/ + +// This structure must by synced with our CPU context +X86CONTEXT IntelRegPtr; /* PUBLIC FUNCTIONS ***********************************************************/ -VOID EmulatorSetStack(WORD Segment, DWORD Offset) -{ - Fast486SetStack(&EmulatorContext, Segment, Offset); -} - - - PVOID WINAPI getIntelRegistersPointer(VOID) { - UNIMPLEMENTED; - return NULL; + /* + * Sync the Intel Registers x86 Context with our CPU context + */ + + if (IntelRegPtr.ContextFlags & CONTEXT_DEBUG_REGISTERS) + { + IntelRegPtr.Dr0 = EmulatorContext.DebugRegisters[FAST486_REG_DR0]; + IntelRegPtr.Dr1 = EmulatorContext.DebugRegisters[FAST486_REG_DR1]; + IntelRegPtr.Dr2 = EmulatorContext.DebugRegisters[FAST486_REG_DR2]; + IntelRegPtr.Dr3 = EmulatorContext.DebugRegisters[FAST486_REG_DR3]; + IntelRegPtr.Dr6 = EmulatorContext.DebugRegisters[FAST486_REG_DR6]; + IntelRegPtr.Dr7 = EmulatorContext.DebugRegisters[FAST486_REG_DR7]; + } + + if (IntelRegPtr.ContextFlags & CONTEXT_FLOATING_POINT) + { + // IntelRegPtr.FloatSave = ; + IntelRegPtr.FloatSave.ControlWord = EmulatorContext.FpuControl.Value; + IntelRegPtr.FloatSave.StatusWord = EmulatorContext.FpuStatus.Value; + // IntelRegPtr.FloatSave.TagWord = ; + // IntelRegPtr.FloatSave.ErrorOffset = ; + // IntelRegPtr.FloatSave.ErrorSelector = ; + // IntelRegPtr.FloatSave.DataOffset = ; + // IntelRegPtr.FloatSave.DataSelector = ; + // IntelRegPtr.FloatSave.RegisterArea = ; // This is a region of size SIZE_OF_80387_REGISTERS == 80 bytes + // IntelRegPtr.FloatSave.Cr0NpxState = ; + } + + if (IntelRegPtr.ContextFlags & CONTEXT_SEGMENTS) + { + IntelRegPtr.SegGs = EmulatorContext.SegmentRegs[FAST486_REG_GS].Selector; + IntelRegPtr.SegFs = EmulatorContext.SegmentRegs[FAST486_REG_FS].Selector; + IntelRegPtr.SegEs = EmulatorContext.SegmentRegs[FAST486_REG_ES].Selector; + IntelRegPtr.SegDs = EmulatorContext.SegmentRegs[FAST486_REG_DS].Selector; + } + + if (IntelRegPtr.ContextFlags & CONTEXT_INTEGER) + { + IntelRegPtr.Edi = EmulatorContext.GeneralRegs[FAST486_REG_EDI].Long; + IntelRegPtr.Esi = EmulatorContext.GeneralRegs[FAST486_REG_ESI].Long; + IntelRegPtr.Ebx = EmulatorContext.GeneralRegs[FAST486_REG_EBX].Long; + IntelRegPtr.Edx = EmulatorContext.GeneralRegs[FAST486_REG_EDX].Long; + IntelRegPtr.Ecx = EmulatorContext.GeneralRegs[FAST486_REG_ECX].Long; + IntelRegPtr.Eax = EmulatorContext.GeneralRegs[FAST486_REG_EAX].Long; + } + + if (IntelRegPtr.ContextFlags & CONTEXT_CONTROL) + { + IntelRegPtr.Ebp = EmulatorContext.GeneralRegs[FAST486_REG_EBP].Long; + IntelRegPtr.Eip = EmulatorContext.InstPtr.Long; + IntelRegPtr.SegCs = EmulatorContext.SegmentRegs[FAST486_REG_CS].Selector; + IntelRegPtr.EFlags = EmulatorContext.Flags.Long; + IntelRegPtr.Esp = EmulatorContext.GeneralRegs[FAST486_REG_ESP].Long; + IntelRegPtr.SegSs = EmulatorContext.SegmentRegs[FAST486_REG_SS].Selector; + } + + if (IntelRegPtr.ContextFlags & CONTEXT_EXTENDED_REGISTERS) + { + // IntelRegPtr.ExtendedRegisters = ; + } + + /* Return the address of the Intel Registers x86 Context */ + return &IntelRegPtr; } ULONG @@ -271,7 +331,7 @@ VOID WINAPI setESP(ULONG Value) { - EmulatorSetStack(getSS(), Value); + Fast486SetStack(&EmulatorContext, getSS(), Value); } USHORT @@ -285,7 +345,7 @@ VOID WINAPI setSP(USHORT Value) { - EmulatorSetStack(getSS(), Value); + Fast486SetStack(&EmulatorContext, getSS(), Value); } diff --git a/reactos/subsystems/ntvdm/registers.h b/reactos/subsystems/ntvdm/cpu/registers.h similarity index 98% rename from reactos/subsystems/ntvdm/registers.h rename to reactos/subsystems/ntvdm/cpu/registers.h index 09568f3b7a8..1f78a9a4a21 100644 --- a/reactos/subsystems/ntvdm/registers.h +++ b/reactos/subsystems/ntvdm/cpu/registers.h @@ -11,8 +11,6 @@ /* INCLUDES *******************************************************************/ -VOID EmulatorSetStack(WORD Segment, DWORD Offset); - #if 0 // Those function prototypes are already included via ddk/vddsvc.h PVOID WINAPI getIntelRegistersPointer(VOID); diff --git a/reactos/subsystems/ntvdm/cpu/x86context.h b/reactos/subsystems/ntvdm/cpu/x86context.h new file mode 100644 index 00000000000..9c996cee744 --- /dev/null +++ b/reactos/subsystems/ntvdm/cpu/x86context.h @@ -0,0 +1,139 @@ +/* + * COPYRIGHT: GPL - See COPYING in the top level directory + * PROJECT: ReactOS Virtual DOS Machine + * FILE: x86context.h + * PURPOSE: x86 CPU Context Frame definitions + * PROGRAMMERS: Hermes Belusca-Maito (hermes.belusca@sfr.fr) + * + * NOTE: Taken from the PSDK. + */ + +#ifndef __X86CONTEXT_H__ +#define __X86CONTEXT_H__ + +#pragma once + +/* Clean everything that may have been defined before */ +#undef SIZE_OF_80387_REGISTERS +#undef MAXIMUM_SUPPORTED_EXTENSION +#undef CONTEXT_i386 +#undef CONTEXT_i486 +#undef CONTEXT_CONTROL +#undef CONTEXT_INTEGER +#undef CONTEXT_SEGMENTS +#undef CONTEXT_FLOATING_POINT +#undef CONTEXT_DEBUG_REGISTERS +#undef CONTEXT_EXTENDED_REGISTERS +#undef CONTEXT_FULL +#undef CONTEXT_ALL +#undef CONTEXT_DEBUGGER +#undef CONTEXT_XSTATE + + + +#define SIZE_OF_80387_REGISTERS 80 +#define MAXIMUM_SUPPORTED_EXTENSION 512 + +#define CONTEXT_i386 0x00010000 +#define CONTEXT_i486 0x00010000 + +#define CONTEXT_CONTROL (CONTEXT_i386|0x00000001L) // SS:SP, CS:IP, FLAGS, BP +#define CONTEXT_INTEGER (CONTEXT_i386|0x00000002L) // AX, BX, CX, DX, SI, DI +#define CONTEXT_SEGMENTS (CONTEXT_i386|0x00000004L) // DS, ES, FS, GS +#define CONTEXT_FLOATING_POINT (CONTEXT_i386|0x00000008L) // 387 state +#define CONTEXT_DEBUG_REGISTERS (CONTEXT_i386|0x00000010L) // DB 0-3,6,7 +#define CONTEXT_EXTENDED_REGISTERS (CONTEXT_i386|0x00000020L) // CPU-specific extensions + +#define CONTEXT_FULL (CONTEXT_CONTROL|CONTEXT_INTEGER|CONTEXT_SEGMENTS) +#define CONTEXT_ALL (CONTEXT_CONTROL | CONTEXT_INTEGER | CONTEXT_SEGMENTS | \ + CONTEXT_FLOATING_POINT | CONTEXT_DEBUG_REGISTERS | \ + CONTEXT_EXTENDED_REGISTERS) + +#define CONTEXT_DEBUGGER (CONTEXT_FULL | CONTEXT_FLOATING_POINT) +#define CONTEXT_XSTATE (CONTEXT_i386 | 0x00000040L) + + +typedef struct _X87FLOATING_SAVE_AREA +{ + ULONG ControlWord; + ULONG StatusWord; + ULONG TagWord; + ULONG ErrorOffset; + ULONG ErrorSelector; + ULONG DataOffset; + ULONG DataSelector; + UCHAR RegisterArea[SIZE_OF_80387_REGISTERS]; + ULONG Cr0NpxState; +} X87FLOATING_SAVE_AREA, *PX87FLOATING_SAVE_AREA; + +#include "pshpack4.h" +/* + * x86 CPU Context Frame + */ +typedef struct _X86CONTEXT +{ + /* + * The flags values within this flag control the contents of + * a CONTEXT record. + */ + ULONG ContextFlags; + + /* + * Section specified/returned if CONTEXT_DEBUG_REGISTERS + * is set in ContextFlags. + */ + ULONG Dr0; + ULONG Dr1; + ULONG Dr2; + ULONG Dr3; + ULONG Dr6; + ULONG Dr7; + + /* + * Section specified/returned if CONTEXT_FLOATING_POINT + * is set in ContextFlags. + */ + X87FLOATING_SAVE_AREA FloatSave; + + /* + * Section specified/returned if CONTEXT_SEGMENTS + * is set in ContextFlags. + */ + ULONG SegGs; + ULONG SegFs; + ULONG SegEs; + ULONG SegDs; + + /* + * Section specified/returned if CONTEXT_INTEGER + * is set in ContextFlags. + */ + ULONG Edi; + ULONG Esi; + ULONG Ebx; + ULONG Edx; + ULONG Ecx; + ULONG Eax; + + /* + * Section specified/returned if CONTEXT_CONTROL + * is set in ContextFlags. + */ + ULONG Ebp; + ULONG Eip; + ULONG SegCs; + ULONG EFlags; + ULONG Esp; + ULONG SegSs; + + /* + * Section specified/returned if CONTEXT_EXTENDED_REGISTERS + * is set in ContextFlags. The format and contexts are processor specific. + */ + UCHAR ExtendedRegisters[MAXIMUM_SUPPORTED_EXTENSION]; +} X86CONTEXT; +#include "poppack.h" + +#endif // __X86CONTEXT_H__ + +/* EOF */ diff --git a/reactos/subsystems/ntvdm/dos/dos32krnl/dos.c b/reactos/subsystems/ntvdm/dos/dos32krnl/dos.c index db5bc14f85a..3b9620589a8 100644 --- a/reactos/subsystems/ntvdm/dos/dos32krnl/dos.c +++ b/reactos/subsystems/ntvdm/dos/dos32krnl/dos.c @@ -19,7 +19,6 @@ #include "dos/dem.h" #include "bios/bios.h" -#include "registers.h" /* PRIVATE VARIABLES **********************************************************/ @@ -1057,8 +1056,8 @@ DWORD DosLoadExecutable(IN DOS_EXEC_TYPE LoadType, setES(Segment); /* Set the stack to the location from the header */ - EmulatorSetStack(Segment + (sizeof(DOS_PSP) >> 4) + Header->e_ss, - Header->e_sp); + setSS(Segment + (sizeof(DOS_PSP) >> 4) + Header->e_ss); + setSP(Header->e_sp); /* Execute */ CurrentPsp = Segment; @@ -1111,7 +1110,8 @@ DWORD DosLoadExecutable(IN DOS_EXEC_TYPE LoadType, setES(Segment); /* Set the stack to the last word of the segment */ - EmulatorSetStack(Segment, 0xFFFE); + setSS(Segment); + setSP(0xFFFE); /* * Set the value on the stack to 0, so that a near return