[DDK:NT_VDD]

Declare some VDM memory services.

[NTVDM]
- Almost all of the XXXInitialize functions just return TRUE always, so VOIDify them instead (since they always succeed).
- Move almost all of the hardware initialization inside EmulatorInitialize.
- Move pure console initialization/mode-saving/cleanup code into ConsoleInit/Cleanup functions in ntvdm.c instead of in bios.c.

svn path=/branches/ntvdm/; revision=61588
This commit is contained in:
Hermès Bélusca-Maïto 2014-01-11 20:59:27 +00:00
parent 25105f6bec
commit 40f773b96b
13 changed files with 239 additions and 172 deletions

View file

@ -36,6 +36,7 @@ VOID
WINAPI
VDDTerminateVDM(VOID);
/*
* I/O Port services
*/
@ -86,6 +87,69 @@ VDDDeInstallIOHook
PVDD_IO_PORTRANGE pPortRange
);
/*
* Memory services
*/
typedef enum
{
VDM_V86,
VDM_PM
} VDM_MODE;
#ifndef MSW_PE
#define MSW_PE 0x0001
#endif
#define getMODE() ((getMSW() & MSW_PE) ? VDM_PM : VDM_V86)
PBYTE
WINAPI
Sim32pGetVDMPointer
(
IN ULONG Address,
IN BOOLEAN ProtectedMode
);
PBYTE
WINAPI
MGetVdmPointer
(
IN ULONG Address,
IN ULONG Size,
IN BOOLEAN ProtectedMode
);
PVOID
WINAPI
VdmMapFlat
(
IN USHORT Segment,
IN ULONG Offset,
IN VDM_MODE Mode
);
BOOL
WINAPI
VdmFlushCache
(
IN USHORT Segment,
IN ULONG Offset,
IN ULONG Size,
IN VDM_MODE Mode
);
BOOL
WINAPI
VdmUnmapFlat
(
IN USHORT Segment,
IN ULONG Offset,
IN PVOID Buffer,
IN VDM_MODE Mode
);
#ifdef __cplusplus
}
#endif

View file

@ -25,11 +25,6 @@
PBIOS_DATA_AREA Bda;
static BYTE BiosKeyboardMap[256];
static HANDLE BiosConsoleInput = INVALID_HANDLE_VALUE;
static HANDLE BiosConsoleOutput = INVALID_HANDLE_VALUE;
static DWORD BiosSavedConInMode, BiosSavedConOutMode;
static CONSOLE_CURSOR_INFO BiosSavedCursorInfo;
static CONSOLE_SCREEN_BUFFER_INFO BiosSavedBufferInfo;
/* PRIVATE FUNCTIONS **********************************************************/
@ -314,7 +309,7 @@ WORD BiosGetCharacter(VOID)
return CharacterData;
}
BOOLEAN BiosInitialize(VOID)
BOOLEAN BiosInitialize(HANDLE ConsoleInput, HANDLE ConsoleOutput)
{
/* Initialize the BDA */
Bda = (PBIOS_DATA_AREA)SEG_OFF_TO_PTR(BDA_SEGMENT, 0);
@ -353,64 +348,18 @@ BOOLEAN BiosInitialize(VOID)
((PDWORD)BaseAddress)[0x48] = (DWORD)NULL;
((PDWORD)BaseAddress)[0x49] = (DWORD)NULL;
/* Get the input handle to the real console, and check for success */
BiosConsoleInput = CreateFileW(L"CONIN$",
GENERIC_READ | GENERIC_WRITE,
FILE_SHARE_READ | FILE_SHARE_WRITE,
NULL,
OPEN_EXISTING,
0,
NULL);
if (BiosConsoleInput == INVALID_HANDLE_VALUE)
{
return FALSE;
}
/* Get the output handle to the real console, and check for success */
BiosConsoleOutput = CreateFileW(L"CONOUT$",
GENERIC_READ | GENERIC_WRITE,
FILE_SHARE_READ | FILE_SHARE_WRITE,
NULL,
OPEN_EXISTING,
0,
NULL);
if (BiosConsoleOutput == INVALID_HANDLE_VALUE)
{
CloseHandle(BiosConsoleInput);
return FALSE;
}
/* Save the original input and output console modes */
if (!GetConsoleMode(BiosConsoleInput , &BiosSavedConInMode ) ||
!GetConsoleMode(BiosConsoleOutput, &BiosSavedConOutMode))
{
CloseHandle(BiosConsoleOutput);
CloseHandle(BiosConsoleInput);
return FALSE;
}
/* Save the original cursor and console screen buffer information */
if (!GetConsoleCursorInfo(BiosConsoleOutput, &BiosSavedCursorInfo) ||
!GetConsoleScreenBufferInfo(BiosConsoleOutput, &BiosSavedBufferInfo))
{
CloseHandle(BiosConsoleOutput);
CloseHandle(BiosConsoleInput);
return FALSE;
}
/* Initialize the Video BIOS */
if (!VidBiosInitialize(BiosConsoleOutput))
{
CloseHandle(BiosConsoleOutput);
CloseHandle(BiosConsoleInput);
return FALSE;
}
if (!VidBiosInitialize(ConsoleOutput)) return FALSE;
/* Set the console input mode */
SetConsoleMode(BiosConsoleInput, ENABLE_MOUSE_INPUT | ENABLE_PROCESSED_INPUT);
SetConsoleMode(ConsoleInput, ENABLE_MOUSE_INPUT | ENABLE_PROCESSED_INPUT);
/* Initialize PS2 */
PS2Initialize(BiosConsoleInput);
PS2Initialize(ConsoleInput);
/*
* The POST (Power On-Self Test)
*/
/* Initialize the PIC */
IOWriteB(PIC_MASTER_CMD, PIC_ICW1 | PIC_ICW1_ICW4);
@ -441,39 +390,8 @@ BOOLEAN BiosInitialize(VOID)
VOID BiosCleanup(VOID)
{
SMALL_RECT ConRect;
CONSOLE_SCREEN_BUFFER_INFO ConsoleInfo;
PS2Cleanup();
VidBiosCleanup();
/* Restore the old screen buffer */
SetConsoleActiveScreenBuffer(BiosConsoleOutput);
/* Restore the original console size */
GetConsoleScreenBufferInfo(BiosConsoleOutput, &ConsoleInfo);
ConRect.Left = 0; // BiosSavedBufferInfo.srWindow.Left;
// ConRect.Top = ConsoleInfo.dwCursorPosition.Y / (BiosSavedBufferInfo.srWindow.Bottom - BiosSavedBufferInfo.srWindow.Top + 1);
// ConRect.Top *= (BiosSavedBufferInfo.srWindow.Bottom - BiosSavedBufferInfo.srWindow.Top + 1);
ConRect.Top = ConsoleInfo.dwCursorPosition.Y;
ConRect.Right = ConRect.Left + BiosSavedBufferInfo.srWindow.Right - BiosSavedBufferInfo.srWindow.Left;
ConRect.Bottom = ConRect.Top + BiosSavedBufferInfo.srWindow.Bottom - BiosSavedBufferInfo.srWindow.Top ;
/* See the following trick explanation in vga.c:VgaEnterTextMode() */
SetConsoleScreenBufferSize(BiosConsoleOutput, BiosSavedBufferInfo.dwSize);
SetConsoleWindowInfo(BiosConsoleOutput, TRUE, &ConRect);
// SetConsoleWindowInfo(BiosConsoleOutput, TRUE, &BiosSavedBufferInfo.srWindow);
SetConsoleScreenBufferSize(BiosConsoleOutput, BiosSavedBufferInfo.dwSize);
/* Restore the original cursor shape */
SetConsoleCursorInfo(BiosConsoleOutput, &BiosSavedCursorInfo);
/* Restore the original input and output console modes */
SetConsoleMode(BiosConsoleOutput, BiosSavedConOutMode);
SetConsoleMode(BiosConsoleInput , BiosSavedConInMode );
/* Close the console handles */
if (BiosConsoleOutput != INVALID_HANDLE_VALUE) CloseHandle(BiosConsoleOutput);
if (BiosConsoleInput != INVALID_HANDLE_VALUE) CloseHandle(BiosConsoleInput);
}
VOID BiosHandleIrq(BYTE IrqNumber, LPWORD Stack)

View file

@ -137,7 +137,7 @@ extern PBIOS_DATA_AREA Bda;
WORD BiosPeekCharacter(VOID);
WORD BiosGetCharacter(VOID);
BOOLEAN BiosInitialize(VOID);
BOOLEAN BiosInitialize(HANDLE ConsoleInput, HANDLE ConsoleOutput);
VOID BiosCleanup(VOID);
VOID BiosHandleIrq(BYTE IrqNumber, LPWORD Stack);

View file

@ -11,20 +11,24 @@
#define NDEBUG
#include "emulator.h"
#include "bios/bios.h"
#include "hardware/cmos.h"
#include "hardware/pic.h"
#include "hardware/speaker.h"
#include "hardware/timer.h"
#include "hardware/vga.h"
#include "bop.h"
#include "vddsup.h"
#include "io.h"
#include "registers.h"
#include "hardware/vga.h"
#include "hardware/pic.h"
// HACK
typedef INT VDM_MODE;
/* PRIVATE VARIABLES **********************************************************/
FAST486_STATE EmulatorContext;
LPVOID BaseAddress = NULL;
BOOLEAN VdmRunning = TRUE;
static BOOLEAN A20Line = FALSE;
@ -115,7 +119,14 @@ BOOLEAN EmulatorInitialize(VOID)
{
/* Allocate memory for the 16-bit address space */
BaseAddress = HeapAlloc(GetProcessHeap(), HEAP_ZERO_MEMORY, MAX_ADDRESS);
if (BaseAddress == NULL) return FALSE;
if (BaseAddress == NULL)
{
wprintf(L"FATAL: Failed to allocate VDM memory.\n");
return FALSE;
}
/* Initialize I/O ports */
/* Initialize RAM */
/* Initialize the CPU */
Fast486Initialize(&EmulatorContext,
@ -131,17 +142,30 @@ BOOLEAN EmulatorInitialize(VOID)
/* Enable interrupts */
setIF(1);
/* Initialize VDD support */
VDDSupInitialize();
/* Initialize the PIC, the PIT, the CMOS and the PC Speaker */
PicInitialize();
PitInitialize();
CmosInitialize();
SpeakerInitialize();
/* Register the DebugBreak BOP */
RegisterBop(BOP_DEBUGGER, EmulatorDebugBreak);
/* Initialize VDD support */
VDDSupInitialize();
return TRUE;
}
VOID EmulatorCleanup(VOID)
{
SpeakerCleanup();
CmosCleanup();
// PitCleanup();
// PicCleanup();
// Fast486Cleanup();
/* Free the memory allocated for the 16-bit address space */
if (BaseAddress != NULL) HeapFree(GetProcessHeap(), 0, BaseAddress);
}
@ -227,7 +251,7 @@ VdmMapFlat(IN USHORT Segment,
return SEG_OFF_TO_PTR(Segment, Offset);
}
BOOL
BOOL
WINAPI
VdmFlushCache(IN USHORT Segment,
IN ULONG Offset,

View file

@ -40,6 +40,25 @@
#define STACK_CS 3
#define STACK_FLAGS 4
/* Basic Memory Management */
#define TO_LINEAR(seg, off) (((seg) << 4) + (off))
#define MAX_SEGMENT 0xFFFF
#define MAX_OFFSET 0xFFFF
#define MAX_ADDRESS 0x1000000 // 16 MB of RAM
#define FAR_POINTER(x) \
(PVOID)((ULONG_PTR)BaseAddress + TO_LINEAR(HIWORD(x), LOWORD(x)))
#define SEG_OFF_TO_PTR(seg, off) \
(PVOID)((ULONG_PTR)BaseAddress + TO_LINEAR((seg), (off)))
/* BCD-Binary conversion */
#define BINARY_TO_BCD(x) ((((x) / 1000) << 12) + (((x) / 100) << 8) + (((x) / 10) << 4) + ((x) % 10))
#define BCD_TO_BINARY(x) (((x) >> 12) * 1000 + ((x) >> 8) * 100 + ((x) >> 4) * 10 + ((x) & 0x0F))
enum
{
EMULATOR_EXCEPTION_DIVISION_BY_ZERO,
@ -60,6 +79,8 @@ enum
};
extern FAST486_STATE EmulatorContext;
extern LPVOID BaseAddress;
extern BOOLEAN VdmRunning;
/* FUNCTIONS ******************************************************************/

View file

@ -384,7 +384,7 @@ VOID RtcTimeUpdate(VOID)
}
}
BOOLEAN CmosInitialize(VOID)
VOID CmosInitialize(VOID)
{
DWORD CmosSize = sizeof(CmosMemory);
@ -433,8 +433,6 @@ BOOLEAN CmosInitialize(VOID)
/* Register the I/O Ports */
RegisterIoPort(CMOS_ADDRESS_PORT, NULL , CmosWritePort);
RegisterIoPort(CMOS_DATA_PORT , CmosReadPort, CmosWritePort);
return TRUE;
}
VOID CmosCleanup(VOID)

View file

@ -129,7 +129,7 @@ DWORD RtcGetTicksPerSecond(VOID);
VOID RtcPeriodicTick(VOID);
VOID RtcTimeUpdate(VOID);
BOOLEAN CmosInitialize(VOID);
VOID CmosInitialize(VOID);
VOID CmosCleanup(VOID);
#endif // _CMOS_H_

View file

@ -293,15 +293,13 @@ BYTE PicGetInterrupt(VOID)
else return MasterPic.IntOffset + 7;
}
BOOLEAN PicInitialize(VOID)
VOID PicInitialize(VOID)
{
/* Register the I/O Ports */
RegisterIoPort(PIC_MASTER_CMD , PicReadPort, PicWritePort);
RegisterIoPort(PIC_SLAVE_CMD , PicReadPort, PicWritePort);
RegisterIoPort(PIC_MASTER_DATA, PicReadPort, PicWritePort);
RegisterIoPort(PIC_SLAVE_DATA , PicReadPort, PicWritePort);
return TRUE;
}

View file

@ -50,7 +50,7 @@ typedef struct _PIC
VOID PicInterruptRequest(BYTE Number);
BYTE PicGetInterrupt(VOID);
BOOLEAN PicInitialize(VOID);
VOID PicInitialize(VOID);
#endif // _PIC_H_

View file

@ -350,15 +350,13 @@ DWORD PitGetResolution(VOID)
return PIT_BASE_FREQUENCY / MinReloadValue;
}
BOOLEAN PitInitialize(VOID)
VOID PitInitialize(VOID)
{
/* Register the I/O Ports */
RegisterIoPort(PIT_COMMAND_PORT, NULL , PitWritePort);
RegisterIoPort(PIT_DATA_PORT(0), PitReadPort, PitWritePort);
RegisterIoPort(PIT_DATA_PORT(1), PitReadPort, PitWritePort);
RegisterIoPort(PIT_DATA_PORT(2), PitReadPort, PitWritePort);
return TRUE;
}
/* EOF */

View file

@ -52,7 +52,7 @@ VOID PitWriteData(BYTE Channel, BYTE Value);
VOID PitDecrementCount(DWORD Count);
DWORD PitGetResolution(VOID);
BOOLEAN PitInitialize(VOID);
VOID PitInitialize(VOID);
#endif // _TIMER_H_

View file

@ -15,9 +15,7 @@
#include "bios/bios.h"
#include "hardware/cmos.h"
#include "hardware/pic.h"
#include "hardware/ps2.h"
#include "hardware/speaker.h"
#include "hardware/timer.h"
#include "hardware/vga.h"
#include "dos/dos.h"
@ -30,8 +28,11 @@
/* PUBLIC VARIABLES ***********************************************************/
BOOLEAN VdmRunning = TRUE;
LPVOID BaseAddress = NULL;
static HANDLE ConsoleInput = INVALID_HANDLE_VALUE;
static HANDLE ConsoleOutput = INVALID_HANDLE_VALUE;
static DWORD OrgConsoleInputMode, OrgConsoleOutputMode;
static CONSOLE_CURSOR_INFO OrgConsoleCursorInfo;
static CONSOLE_SCREEN_BUFFER_INFO OrgConsoleBufferInfo;
/* PUBLIC FUNCTIONS ***********************************************************/
@ -67,6 +68,97 @@ BOOL WINAPI ConsoleCtrlHandler(DWORD ControlType)
return TRUE;
}
BOOL ConsoleInit(VOID)
{
/* Set the handler routine */
SetConsoleCtrlHandler(ConsoleCtrlHandler, TRUE);
/* Get the input handle to the real console, and check for success */
ConsoleInput = CreateFileW(L"CONIN$",
GENERIC_READ | GENERIC_WRITE,
FILE_SHARE_READ | FILE_SHARE_WRITE,
NULL,
OPEN_EXISTING,
0,
NULL);
if (ConsoleInput == INVALID_HANDLE_VALUE)
{
wprintf(L"FATAL: Cannot retrieve a handle to the console input\n");
return FALSE;
}
/* Get the output handle to the real console, and check for success */
ConsoleOutput = CreateFileW(L"CONOUT$",
GENERIC_READ | GENERIC_WRITE,
FILE_SHARE_READ | FILE_SHARE_WRITE,
NULL,
OPEN_EXISTING,
0,
NULL);
if (ConsoleOutput == INVALID_HANDLE_VALUE)
{
CloseHandle(ConsoleInput);
wprintf(L"FATAL: Cannot retrieve a handle to the console output\n");
return FALSE;
}
/* Save the original input and output console modes */
if (!GetConsoleMode(ConsoleInput , &OrgConsoleInputMode ) ||
!GetConsoleMode(ConsoleOutput, &OrgConsoleOutputMode))
{
CloseHandle(ConsoleOutput);
CloseHandle(ConsoleInput);
wprintf(L"FATAL: Cannot save console in/out modes\n");
return FALSE;
}
/* Save the original cursor and console screen buffer information */
if (!GetConsoleCursorInfo(ConsoleOutput, &OrgConsoleCursorInfo) ||
!GetConsoleScreenBufferInfo(ConsoleOutput, &OrgConsoleBufferInfo))
{
CloseHandle(ConsoleOutput);
CloseHandle(ConsoleInput);
wprintf(L"FATAL: Cannot save console cursor/screen-buffer info\n");
return FALSE;
}
return TRUE;
}
VOID ConsoleCleanup(VOID)
{
SMALL_RECT ConRect;
CONSOLE_SCREEN_BUFFER_INFO ConsoleInfo;
/* Restore the old screen buffer */
SetConsoleActiveScreenBuffer(ConsoleOutput);
/* Restore the original console size */
GetConsoleScreenBufferInfo(ConsoleOutput, &ConsoleInfo);
ConRect.Left = 0; // OrgConsoleBufferInfo.srWindow.Left;
// ConRect.Top = ConsoleInfo.dwCursorPosition.Y / (OrgConsoleBufferInfo.srWindow.Bottom - OrgConsoleBufferInfo.srWindow.Top + 1);
// ConRect.Top *= (OrgConsoleBufferInfo.srWindow.Bottom - OrgConsoleBufferInfo.srWindow.Top + 1);
ConRect.Top = ConsoleInfo.dwCursorPosition.Y;
ConRect.Right = ConRect.Left + OrgConsoleBufferInfo.srWindow.Right - OrgConsoleBufferInfo.srWindow.Left;
ConRect.Bottom = ConRect.Top + OrgConsoleBufferInfo.srWindow.Bottom - OrgConsoleBufferInfo.srWindow.Top ;
/* See the following trick explanation in vga.c:VgaEnterTextMode() */
SetConsoleScreenBufferSize(ConsoleOutput, OrgConsoleBufferInfo.dwSize);
SetConsoleWindowInfo(ConsoleOutput, TRUE, &ConRect);
// SetConsoleWindowInfo(ConsoleOutput, TRUE, &OrgConsoleBufferInfo.srWindow);
SetConsoleScreenBufferSize(ConsoleOutput, OrgConsoleBufferInfo.dwSize);
/* Restore the original cursor shape */
SetConsoleCursorInfo(ConsoleOutput, &OrgConsoleCursorInfo);
/* Restore the original input and output console modes */
SetConsoleMode(ConsoleOutput, OrgConsoleOutputMode);
SetConsoleMode(ConsoleInput , OrgConsoleInputMode );
/* Close the console handles */
if (ConsoleOutput != INVALID_HANDLE_VALUE) CloseHandle(ConsoleOutput);
if (ConsoleInput != INVALID_HANDLE_VALUE) CloseHandle(ConsoleInput);
}
INT wmain(INT argc, WCHAR *argv[])
{
INT i;
@ -81,9 +173,6 @@ INT wmain(INT argc, WCHAR *argv[])
DWORD Cycles = 0;
INT KeyboardIntCounter = 0;
/* Set the handler routine */
SetConsoleCtrlHandler(ConsoleCtrlHandler, TRUE);
#ifndef TESTING
UNREFERENCED_PARAMETER(argc);
UNREFERENCED_PARAMETER(argv);
@ -105,10 +194,17 @@ INT wmain(INT argc, WCHAR *argv[])
DPRINT1("\n\n\nNTVDM - Starting '%s'...\n\n\n", CommandLine);
/* Initialize the console */
if (!ConsoleInit())
{
wprintf(L"FATAL: A problem occurred when trying to initialize the console\n");
goto Cleanup;
}
/* Initialize the emulator */
if (!EmulatorInitialize())
{
wprintf(L"FATAL: Failed to initialize the CPU emulator\n");
wprintf(L"FATAL: Failed to initialize the emulator\n");
goto Cleanup;
}
@ -119,38 +215,8 @@ INT wmain(INT argc, WCHAR *argv[])
goto Cleanup;
}
/* Initialize the PIC */
if (!PicInitialize())
{
wprintf(L"FATAL: Failed to initialize the PIC.\n");
goto Cleanup;
}
/* Initialize the PIT */
if (!PitInitialize())
{
wprintf(L"FATAL: Failed to initialize the PIT.\n");
goto Cleanup;
}
/* Initialize the CMOS */
if (!CmosInitialize())
{
wprintf(L"FATAL: Failed to initialize the VDM CMOS.\n");
goto Cleanup;
}
/* Initialize the PC Speaker */
SpeakerInitialize();
/* Initialize the system BIOS */
if (!BiosInitialize())
if (!BiosInitialize(ConsoleInput, ConsoleOutput))
{
wprintf(L"FATAL: Failed to initialize the VDM BIOS.\n");
goto Cleanup;
@ -264,10 +330,9 @@ INT wmain(INT argc, WCHAR *argv[])
VgaRefreshDisplay();
Cleanup:
SpeakerCleanup();
BiosCleanup();
CmosCleanup();
EmulatorCleanup();
ConsoleCleanup();
DPRINT1("\n\n\nNTVDM - Exiting...\n\n\n");

View file

@ -30,31 +30,12 @@
/* DEFINES ********************************************************************/
/* Basic Memory Management */
#define TO_LINEAR(seg, off) (((seg) << 4) + (off))
#define MAX_SEGMENT 0xFFFF
#define MAX_OFFSET 0xFFFF
#define MAX_ADDRESS 0x1000000 // 16 MB of RAM
#define FAR_POINTER(x) \
(PVOID)((ULONG_PTR)BaseAddress + TO_LINEAR(HIWORD(x), LOWORD(x)))
#define SEG_OFF_TO_PTR(seg, off) \
(PVOID)((ULONG_PTR)BaseAddress + TO_LINEAR((seg), (off)))
/* BCD-Binary conversion */
#define BINARY_TO_BCD(x) ((((x) / 1000) << 12) + (((x) / 100) << 8) + (((x) / 10) << 4) + ((x) % 10))
#define BCD_TO_BINARY(x) (((x) >> 12) * 1000 + ((x) >> 8) * 100 + ((x) >> 4) * 10 + ((x) & 0x0F))
/* Processor speed */
#define STEPS_PER_CYCLE 256
#define KBD_INT_CYCLES 16
/* FUNCTIONS ******************************************************************/
extern LPVOID BaseAddress;
extern BOOLEAN VdmRunning;
VOID DisplayMessage(LPCWSTR Format, ...);
#endif // _NTVDM_H_