1 /*
2 * COPYRIGHT: GPL - See COPYING in the top level directory
3 * PROJECT: ReactOS Virtual DOS Machine
4 * FILE: subsystems/mvdm/ntvdm/emulator.h
5 * PURPOSE: Minimal x86 machine emulator for the VDM
6 * PROGRAMMERS: Aleksandar Andrejevic <theflash AT sdf DOT lonestar DOT org>
7 */
8
9 #ifndef _EMULATOR_H_
10 #define _EMULATOR_H_
11
12 /* INCLUDES *******************************************************************/
13
14 #include <fast486.h>
15
16 /* DEFINES ********************************************************************/
17
18 /*
19 * Basic Memory Management
20 */
21 #define NULL32 ((ULONG)0)
22
23 #define MEM_ALIGN_DOWN(ptr, align) (PVOID)((ULONG_PTR)(ptr) & ~((align) - 1l))
24 #define MEM_ALIGN_UP(ptr, align) MEM_ALIGN_DOWN((ULONG_PTR)(ptr) + (align) - 1l, (align))
25
26 #define TO_LINEAR(seg, off) (((seg) << 4) + (off))
27 #define MAX_SEGMENT 0xFFFF
28 #define MAX_OFFSET 0xFFFF
29 #define MAX_ADDRESS 0x1000000 // 16 MB of RAM; see also: kernel32/client/vdm.c!BaseGetVdmConfigInfo
30 C_ASSERT(0x100000 <= MAX_ADDRESS); // A minimum of 1 MB is required for PC emulation.
31
32 #define SEG_OFF_TO_PTR(seg, off) \
33 (PVOID)((ULONG_PTR)BaseAddress + TO_LINEAR((seg), (off)))
34
35 #define FAR_POINTER(x) SEG_OFF_TO_PTR(HIWORD(x), LOWORD(x))
36
37 #define REAL_TO_PHYS(ptr) (PVOID)((ULONG_PTR)(ptr) + (ULONG_PTR)BaseAddress)
38 #define PHYS_TO_REAL(ptr) (PVOID)((ULONG_PTR)(ptr) - (ULONG_PTR)BaseAddress)
39
40 #define ARRAY_INDEX(ptr, array) ((ULONG)(((ULONG_PTR)(ptr) - (ULONG_PTR)(array)) / sizeof(*array)))
41
42 /*
43 * BCD-Binary conversion
44 */
45
46 FORCEINLINE
47 USHORT
BINARY_TO_BCD(USHORT Value)48 BINARY_TO_BCD(USHORT Value)
49 {
50 USHORT Result;
51
52 Result = (Value / 1000) << 12;
53 Value %= 1000;
54 Result |= (Value / 100) << 8;
55 Value %= 100;
56 Result |= (Value / 10) << 4;
57 Value %= 10;
58 Result |= Value;
59
60 return Result;
61 }
62
63 FORCEINLINE
64 USHORT
BCD_TO_BINARY(USHORT Value)65 BCD_TO_BINARY(USHORT Value)
66 {
67 USHORT Result;
68
69 Result = Value & 0xF;
70 Value >>= 4;
71 Result += (Value & 0xF) * 10;
72 Value >>= 4;
73 Result += (Value & 0xF) * 100;
74 Value >>= 4;
75 Result += Value * 1000;
76
77 return Result;
78 }
79
80
81 /*
82 * Emulator state
83 */
84
85 enum
86 {
87 EMULATOR_EXCEPTION_DIVISION_BY_ZERO,
88 EMULATOR_EXCEPTION_DEBUG,
89 EMULATOR_EXCEPTION_NMI,
90 EMULATOR_EXCEPTION_BREAKPOINT,
91 EMULATOR_EXCEPTION_OVERFLOW,
92 EMULATOR_EXCEPTION_BOUND,
93 EMULATOR_EXCEPTION_INVALID_OPCODE,
94 EMULATOR_EXCEPTION_NO_FPU,
95 EMULATOR_EXCEPTION_DOUBLE_FAULT,
96 EMULATOR_EXCEPTION_FPU_SEGMENT,
97 EMULATOR_EXCEPTION_INVALID_TSS,
98 EMULATOR_EXCEPTION_NO_SEGMENT,
99 EMULATOR_EXCEPTION_STACK_SEGMENT,
100 EMULATOR_EXCEPTION_GPF,
101 EMULATOR_EXCEPTION_PAGE_FAULT
102 };
103
104 extern FAST486_STATE EmulatorContext;
105 extern LPVOID BaseAddress;
106 extern BOOLEAN VdmRunning;
107
108
109 /* FUNCTIONS ******************************************************************/
110
111 VOID DumpMemory(BOOLEAN TextFormat);
112
113 VOID MountFloppy(IN ULONG DiskNumber);
114 VOID EjectFloppy(IN ULONG DiskNumber);
115
116 UCHAR FASTCALL EmulatorIntAcknowledge
117 (
118 PFAST486_STATE State
119 );
120
121 VOID FASTCALL EmulatorFpu
122 (
123 PFAST486_STATE State
124 );
125
126 VOID EmulatorInterruptSignal(VOID);
127 VOID EmulatorException(BYTE ExceptionNumber, LPWORD Stack);
128
129 VOID EmulatorPause(VOID);
130 VOID EmulatorResume(VOID);
131 VOID EmulatorTerminate(VOID);
132
133 BOOLEAN EmulatorInitialize(HANDLE ConsoleInput, HANDLE ConsoleOutput);
134 VOID EmulatorCleanup(VOID);
135
136 #endif // _EMULATOR_H_
137
138 /* EOF */
139