ReactOS 0.4.16-dev-251-ga17b6e9
cpu.c
Go to the documentation of this file.
1/*
2 * COPYRIGHT: GPL - See COPYING in the top level directory
3 * PROJECT: ReactOS Virtual DOS Machine
4 * FILE: subsystems/mvdm/ntvdm/cpu/cpu.c
5 * PURPOSE: Minimal x86 machine emulator for the VDM
6 * PROGRAMMERS: Aleksandar Andrejevic <theflash AT sdf DOT lonestar DOT org>
7 */
8
9/* INCLUDES *******************************************************************/
10
11#include "ntvdm.h"
12
13#define NDEBUG
14#include <debug.h>
15
16#include "emulator.h"
17#include "cpu.h"
18
19#include "memory.h"
20#include "callback.h"
21#include "bop.h"
22#include <isvbop.h>
23
24#include "clock.h"
25#include "bios/rom.h"
26#include "hardware/cmos.h"
27#include "hardware/keyboard.h"
28#include "hardware/mouse.h"
29#include "hardware/pic.h"
30#include "hardware/ps2.h"
32#include "hardware/pit.h"
33#include "hardware/video/svga.h"
34
35#include "io.h"
36
37/* PRIVATE VARIABLES **********************************************************/
38
39FAST486_STATE EmulatorContext;
41
42/* No more than 'MaxCpuCallLevel' recursive CPU calls are allowed */
43static const INT MaxCpuCallLevel = 32;
44static INT CpuCallLevel = 0; // == 0: CPU stopped; >= 1: CPU running or halted
45
46#if 0
48{
49 L"Division By Zero",
50 L"Debug",
51 L"Unexpected Error",
52 L"Breakpoint",
53 L"Integer Overflow",
54 L"Bound Range Exceeded",
55 L"Invalid Opcode",
56 L"FPU Not Available"
57};
58#endif
59
60// /* BOP Identifiers */
61// #define BOP_DEBUGGER 0x56 // Break into the debugger from a 16-bit app
62
63/* PRIVATE FUNCTIONS **********************************************************/
64
65#if 0
66VOID EmulatorException(BYTE ExceptionNumber, LPWORD Stack)
67{
68 WORD CodeSegment, InstructionPointer;
70
71 ASSERT(ExceptionNumber < 8);
72
73 /* Get the CS:IP */
74 InstructionPointer = Stack[STACK_IP];
75 CodeSegment = Stack[STACK_CS];
76 Opcode = (PBYTE)SEG_OFF_TO_PTR(CodeSegment, InstructionPointer);
77
78 /* Display a message to the user */
79 DisplayMessage(L"Exception: %s occured at %04X:%04X\n"
80 L"Opcode: %02X %02X %02X %02X %02X %02X %02X %02X %02X %02X",
81 ExceptionName[ExceptionNumber],
82 CodeSegment,
83 InstructionPointer,
84 Opcode[0],
85 Opcode[1],
86 Opcode[2],
87 Opcode[3],
88 Opcode[4],
89 Opcode[5],
90 Opcode[6],
91 Opcode[7],
92 Opcode[8],
93 Opcode[9]);
94
95 /* Stop the VDM */
97 return;
98}
99#endif
100
101// FIXME: This function assumes 16-bit mode!!!
103{
104 /* Tell Fast486 to move the instruction pointer */
106}
107
109{
110 /* Dump the state for debugging purposes */
111 // Fast486DumpState(&EmulatorContext);
112
113 /* Execute the next instruction */
115}
116
118{
119 /* Get the exception record */
120 PEXCEPTION_RECORD ExceptionRecord = ExceptionInfo->ExceptionRecord;
121
122 switch (ExceptionRecord->ExceptionCode)
123 {
124 /* We only handle access violations so far */
126 {
127 BOOLEAN Writing = (ExceptionRecord->ExceptionInformation[0] == 1);
128
129 /* Retrieve the address to which a read or write attempt was made */
130 ULONG_PTR Address = ExceptionRecord->ExceptionInformation[1];
131
132 /*
133 * Check whether the access exception was done inside the virtual memory space
134 * (caused by an emulated app) or outside (caused by a bug in ourselves).
135 */
138 {
139 DPRINT1("NTVDM: %s access violation at 0x%p outside the virtual memory space!\n",
140 (Writing ? "Write" : "Read"), Address);
142 }
143
144 /* We are good to go, dispatch to our memory handlers */
145
146 /* Fix the CPU state */
148
149 /* Call the memory handler */
151
152 /* The execution of the CPU opcode handler MUST NOT continue */
154 }
155
156 default:
157 {
158 DPRINT1("NTVDM: Exception 0x%08lx not handled!\n", ExceptionRecord->ExceptionCode);
159 break;
160 }
161 }
162
163 /* Continue to search for a handler */
165}
166
168{
170 {
171 DisplayMessage(L"Too many CPU levels of recursion (%d, expected maximum %d)",
173
174 /* Stop the VDM */
176 return;
177 }
178 CpuCallLevel++;
179 DPRINT("CpuSimulate --> Level %d\n", CpuCallLevel);
180
182 while (VdmRunning && CpuRunning)
183 {
185 {
186 while (VdmRunning && CpuRunning) ClockUpdate();
187 }
189 {
190 DPRINT("VDM exception handler called\n");
191 }
192 _SEH2_END;
193 }
194
195 DPRINT("CpuSimulate <-- Level %d\n", CpuCallLevel);
196 CpuCallLevel--;
197 if (!VdmRunning || CpuCallLevel < 0) CpuCallLevel = 0;
198
199 /* This takes into account for reentrance */
200 if (VdmRunning && (CpuCallLevel > 0)) CpuRunning = TRUE;
201}
202
204{
205 /* Stop simulation */
207}
208
210{
212}
213
214/* PUBLIC FUNCTIONS ***********************************************************/
215
217{
218 // /* Initialize the internal clock */
219 // if (!ClockInitialize())
220 // {
221 // wprintf(L"FATAL: Failed to initialize the clock\n");
222 // return FALSE;
223 // }
224
225 /* Initialize the CPU */
234 NULL /* TODO: Use a TLB */);
235
236 /* Initialize the software callback system and register the emulator BOPs */
237 // RegisterBop(BOP_DEBUGGER , EmulatorDebugBreakBop);
239
240 return TRUE;
241}
242
244{
245 // Fast486Cleanup();
246}
247
248/* EOF */
unsigned char BOOLEAN
#define MAX_ADDRESS
#define DPRINT1
Definition: precomp.h:8
INT __cdecl DisplayMessage(_In_opt_ HWND hWnd, _In_ UINT uType, _In_opt_ PCWSTR pszTitle, _In_opt_ PCWSTR pszFormatMessage,...)
Definition: reactos.c:211
VOID FASTCALL EmulatorBiosOperation(PFAST486_STATE State, UCHAR BopCode)
Definition: bop.c:34
VOID RegisterBop(BYTE BopCode, EMULATOR_BOP_PROC BopHandler)
Definition: bop.c:29
#define NULL
Definition: types.h:112
#define TRUE
Definition: types.h:120
#define FALSE
Definition: types.h:117
#define ULONG_PTR
Definition: config.h:101
VOID EmulatorTerminate(VOID)
Definition: emulator.c:503
LPCWSTR ExceptionName[]
Definition: emulator.c:54
VOID EmulatorException(BYTE ExceptionNumber, LPWORD Stack)
Definition: emulator.c:85
BOOLEAN VdmRunning
Definition: emulator.c:49
UCHAR FASTCALL EmulatorIntAcknowledge(PFAST486_STATE State)
Definition: emulator.c:71
VOID FASTCALL EmulatorFpu(PFAST486_STATE State)
Definition: emulator.c:79
#define PHYS_TO_REAL(ptr)
Definition: emulator.h:38
#define SEG_OFF_TO_PTR(seg, off)
Definition: emulator.h:32
VOID NTAPI Fast486Rewind(PFAST486_STATE State)
Definition: fast486.c:252
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_BOP_PROC BopCallback, FAST486_INT_ACK_PROC IntAckCallback, FAST486_FPU_PROC FpuCallback, PULONG Tlb)
Definition: fast486.c:103
VOID NTAPI Fast486ExecuteAt(PFAST486_STATE State, USHORT Segment, ULONG Offset)
Definition: fast486.c:212
#define _SEH2_END
Definition: filesup.c:22
#define _SEH2_TRY
Definition: filesup.c:19
unsigned short WORD
Definition: ntddk_ex.h:93
_In_ PVOID _In_ ULONG Opcode
Definition: hubbusif.h:331
#define EXCEPTION_EXECUTE_HANDLER
Definition: excpt.h:85
#define EXCEPTION_CONTINUE_SEARCH
Definition: excpt.h:86
#define STACK_IP
Definition: int32.h:33
#define STACK_CS
Definition: int32.h:34
#define BOP_UNSIMULATE
Definition: isvbop.h:31
#define ASSERT(a)
Definition: mode.c:44
_In_ HANDLE _Outptr_result_bytebuffer_ ViewSize PVOID * BaseAddress
Definition: mmfuncs.h:404
_In_ ULONG _In_ ULONG Offset
Definition: ntddpcm.h:101
#define L(x)
Definition: ntvdm.h:50
BYTE * PBYTE
Definition: pedump.c:66
long LONG
Definition: pedump.c:60
static WCHAR Address[46]
Definition: ping.c:68
#define _SEH2_EXCEPT(...)
Definition: pseh2_64.h:66
#define _SEH2_GetExceptionInformation()
Definition: pseh2_64.h:164
VOID NTAPI Fast486StepInto(PFAST486_STATE State)
Definition: debug.c:248
#define DPRINT
Definition: sndvol32.h:73
struct _EXCEPTION_RECORD * ExceptionRecord
Definition: compat.h:210
DWORD ExceptionCode
Definition: compat.h:208
ULONG_PTR ExceptionInformation[EXCEPTION_MAXIMUM_PARAMETERS]
Definition: compat.h:213
VOID ClockUpdate(VOID)
Definition: clock.c:76
VOID CpuStep(VOID)
Definition: cpu.c:108
BOOLEAN CpuRunning
Definition: cpu.c:40
LONG CpuExceptionFilter(IN PEXCEPTION_POINTERS ExceptionInfo)
Definition: cpu.c:117
BOOLEAN CpuInitialize(VOID)
Definition: cpu.c:216
VOID CpuSimulate(VOID)
Definition: cpu.c:167
static INT CpuCallLevel
Definition: cpu.c:44
VOID CpuExecute(WORD Segment, WORD Offset)
Definition: cpu.c:102
VOID CpuCleanup(VOID)
Definition: cpu.c:243
FAST486_STATE EmulatorContext
Definition: cpu.c:39
VOID CpuUnsimulate(VOID)
Definition: cpu.c:203
static VOID WINAPI CpuUnsimulateBop(LPWORD Stack)
Definition: cpu.c:209
static const INT MaxCpuCallLevel
Definition: cpu.c:43
VOID FASTCALL EmulatorReadIo(PFAST486_STATE State, USHORT Port, PVOID Buffer, ULONG DataCount, UCHAR DataSize)
Definition: io.c:349
VOID FASTCALL EmulatorWriteIo(PFAST486_STATE State, USHORT Port, PVOID Buffer, ULONG DataCount, UCHAR DataSize)
Definition: io.c:424
VOID FASTCALL EmulatorReadMemory(PFAST486_STATE State, ULONG Address, PVOID Buffer, ULONG Size)
Definition: memory.c:142
VOID FASTCALL EmulatorWriteMemory(PFAST486_STATE State, ULONG Address, PVOID Buffer, ULONG Size)
Definition: memory.c:186
VOID MemExceptionHandler(ULONG FaultAddress, BOOLEAN Writing)
Definition: memory.c:286
uint16_t * LPWORD
Definition: typedefs.h:56
int32_t INT
Definition: typedefs.h:58
uint32_t ULONG_PTR
Definition: typedefs.h:65
#define IN
Definition: typedefs.h:39
_In_ WDFREQUEST _In_ PIO_STACK_LOCATION Stack
Definition: wdfrequest.h:639
#define EXCEPTION_ACCESS_VIOLATION
Definition: winbase.h:337
#define WINAPI
Definition: msvc.h:6
_Inout_ PVOID Segment
Definition: exfuncs.h:1101
const WCHAR * LPCWSTR
Definition: xmlstorage.h:185
unsigned char BYTE
Definition: xxhash.c:193