mirror of
https://github.com/reactos/reactos.git
synced 2024-07-11 15:15:27 +00:00
[NTVDM]
- Use callbacks in BIOS/DOS (and disable int32.c) - Move DOS bops to dem.c svn path=/branches/ntvdm/; revision=62306
This commit is contained in:
parent
0c3c1170ab
commit
b33a34bec1
|
@ -22,7 +22,7 @@ list(APPEND SOURCE
|
||||||
bop.c
|
bop.c
|
||||||
clock.c
|
clock.c
|
||||||
emulator.c
|
emulator.c
|
||||||
int32.c
|
callback.c
|
||||||
io.c
|
io.c
|
||||||
registers.c
|
registers.c
|
||||||
vddsup.c
|
vddsup.c
|
||||||
|
|
|
@ -11,6 +11,8 @@
|
||||||
#define NDEBUG
|
#define NDEBUG
|
||||||
|
|
||||||
#include "emulator.h"
|
#include "emulator.h"
|
||||||
|
#include "callback.h"
|
||||||
|
|
||||||
#include "bios32.h"
|
#include "bios32.h"
|
||||||
|
|
||||||
#include "io.h"
|
#include "io.h"
|
||||||
|
@ -18,10 +20,9 @@
|
||||||
#include "hardware/pic.h"
|
#include "hardware/pic.h"
|
||||||
#include "hardware/timer.h"
|
#include "hardware/timer.h"
|
||||||
|
|
||||||
#include "int32.h"
|
|
||||||
|
|
||||||
/* PRIVATE VARIABLES **********************************************************/
|
/* PRIVATE VARIABLES **********************************************************/
|
||||||
|
|
||||||
|
CALLBACK16 BiosContext;
|
||||||
PBIOS_DATA_AREA Bda;
|
PBIOS_DATA_AREA Bda;
|
||||||
|
|
||||||
/* PRIVATE FUNCTIONS **********************************************************/
|
/* PRIVATE FUNCTIONS **********************************************************/
|
||||||
|
@ -190,7 +191,7 @@ VOID EnableHwIRQ(UCHAR hwirq, EMULATOR_INT32_PROC func)
|
||||||
else
|
else
|
||||||
vector = BIOS_PIC_SLAVE_INT + hwirq - 8;
|
vector = BIOS_PIC_SLAVE_INT + hwirq - 8;
|
||||||
|
|
||||||
RegisterInt32(vector, func);
|
RegisterBiosInt32(vector, func);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
|
@ -250,7 +251,8 @@ static VOID WINAPI BiosTimerIrq(LPWORD Stack)
|
||||||
* because some programs may hook only BIOS_SYS_TIMER_INTERRUPT
|
* because some programs may hook only BIOS_SYS_TIMER_INTERRUPT
|
||||||
* for their purpose...
|
* for their purpose...
|
||||||
*/
|
*/
|
||||||
EmulatorInterrupt(BIOS_SYS_TIMER_INTERRUPT);
|
/** EmulatorInterrupt(BIOS_SYS_TIMER_INTERRUPT); **/
|
||||||
|
Int32Call(&BiosContext, BIOS_SYS_TIMER_INTERRUPT);
|
||||||
PicIRQComplete(Stack);
|
PicIRQComplete(Stack);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -303,6 +305,48 @@ static VOID BiosHwSetup(VOID)
|
||||||
EnableHwIRQ(0, BiosTimerIrq);
|
EnableHwIRQ(0, BiosTimerIrq);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
static VOID InitializeBiosInt32(VOID)
|
||||||
|
{
|
||||||
|
USHORT i;
|
||||||
|
// USHORT Offset = 0;
|
||||||
|
|
||||||
|
/* Initialize the callback context */
|
||||||
|
InitializeContext(&BiosContext, BIOS_SEGMENT, 0x0000);
|
||||||
|
|
||||||
|
/* Register the BIOS 32-bit Interrupts */
|
||||||
|
for (i = 0x00; i <= 0xFF; i++)
|
||||||
|
{
|
||||||
|
// Offset += RegisterInt32(MAKELONG(Offset, BIOS_SEGMENT), i, NULL, NULL);
|
||||||
|
BiosContext.NextOffset += RegisterInt32(MAKELONG(BiosContext.NextOffset,
|
||||||
|
BiosContext.Segment),
|
||||||
|
i, NULL, NULL);
|
||||||
|
}
|
||||||
|
|
||||||
|
/* Initialize the exception vector interrupts to a default Exception handler */
|
||||||
|
for (i = 0; i < 8; i++)
|
||||||
|
RegisterBiosInt32(i, BiosException);
|
||||||
|
|
||||||
|
/* Initialize HW vector interrupts to a default HW handler */
|
||||||
|
for (i = BIOS_PIC_MASTER_INT; i < BIOS_PIC_MASTER_INT + 8; i++)
|
||||||
|
RegisterBiosInt32(i, BiosHandleMasterPicIRQ);
|
||||||
|
for (i = BIOS_PIC_SLAVE_INT ; i < BIOS_PIC_SLAVE_INT + 8; i++)
|
||||||
|
RegisterBiosInt32(i, BiosHandleSlavePicIRQ);
|
||||||
|
|
||||||
|
/* Initialize software vector handlers */
|
||||||
|
RegisterBiosInt32(BIOS_EQUIPMENT_INTERRUPT, BiosEquipmentService );
|
||||||
|
RegisterBiosInt32(BIOS_MEMORY_SIZE , BiosGetMemorySize );
|
||||||
|
RegisterBiosInt32(BIOS_MISC_INTERRUPT , BiosMiscService );
|
||||||
|
RegisterBiosInt32(BIOS_TIME_INTERRUPT , BiosTimeService );
|
||||||
|
RegisterBiosInt32(BIOS_SYS_TIMER_INTERRUPT, BiosSystemTimerInterrupt);
|
||||||
|
|
||||||
|
/* Some interrupts are in fact addresses to tables */
|
||||||
|
((PULONG)BaseAddress)[0x1E] = (ULONG)NULL;
|
||||||
|
((PULONG)BaseAddress)[0x41] = (ULONG)NULL;
|
||||||
|
((PULONG)BaseAddress)[0x46] = (ULONG)NULL;
|
||||||
|
((PULONG)BaseAddress)[0x48] = (ULONG)NULL;
|
||||||
|
((PULONG)BaseAddress)[0x49] = (ULONG)NULL;
|
||||||
|
}
|
||||||
|
|
||||||
/* PUBLIC FUNCTIONS ***********************************************************/
|
/* PUBLIC FUNCTIONS ***********************************************************/
|
||||||
|
|
||||||
/*
|
/*
|
||||||
|
@ -312,7 +356,6 @@ BOOLEAN Bios32Initialize(IN HANDLE ConsoleInput,
|
||||||
IN HANDLE ConsoleOutput)
|
IN HANDLE ConsoleOutput)
|
||||||
{
|
{
|
||||||
UCHAR Low, High;
|
UCHAR Low, High;
|
||||||
UCHAR i;
|
|
||||||
|
|
||||||
/* Initialize the BDA */
|
/* Initialize the BDA */
|
||||||
Bda = (PBIOS_DATA_AREA)SEG_OFF_TO_PTR(BDA_SEGMENT, 0);
|
Bda = (PBIOS_DATA_AREA)SEG_OFF_TO_PTR(BDA_SEGMENT, 0);
|
||||||
|
@ -328,34 +371,8 @@ BOOLEAN Bios32Initialize(IN HANDLE ConsoleInput,
|
||||||
High = IOReadB(CMOS_DATA_PORT);
|
High = IOReadB(CMOS_DATA_PORT);
|
||||||
Bda->MemorySize = MAKEWORD(Low, High);
|
Bda->MemorySize = MAKEWORD(Low, High);
|
||||||
|
|
||||||
/* Initialize the 32-bit Interrupt system */
|
|
||||||
InitializeInt32(BIOS_SEGMENT);
|
|
||||||
|
|
||||||
/* Register the BIOS 32-bit Interrupts */
|
/* Register the BIOS 32-bit Interrupts */
|
||||||
|
InitializeBiosInt32();
|
||||||
/* Initialize the exception vector interrupts to a default Exception handler */
|
|
||||||
for (i = 0; i < 8; i++)
|
|
||||||
RegisterInt32(i, BiosException);
|
|
||||||
|
|
||||||
/* Initialize HW vector interrupts to a default HW handler */
|
|
||||||
for (i = BIOS_PIC_MASTER_INT; i < BIOS_PIC_MASTER_INT + 8; i++)
|
|
||||||
RegisterInt32(i, BiosHandleMasterPicIRQ);
|
|
||||||
for (i = BIOS_PIC_SLAVE_INT ; i < BIOS_PIC_SLAVE_INT + 8; i++)
|
|
||||||
RegisterInt32(i, BiosHandleSlavePicIRQ);
|
|
||||||
|
|
||||||
/* Initialize software vector handlers */
|
|
||||||
RegisterInt32(BIOS_EQUIPMENT_INTERRUPT, BiosEquipmentService );
|
|
||||||
RegisterInt32(BIOS_MEMORY_SIZE , BiosGetMemorySize );
|
|
||||||
RegisterInt32(BIOS_MISC_INTERRUPT , BiosMiscService );
|
|
||||||
RegisterInt32(BIOS_TIME_INTERRUPT , BiosTimeService );
|
|
||||||
RegisterInt32(BIOS_SYS_TIMER_INTERRUPT, BiosSystemTimerInterrupt);
|
|
||||||
|
|
||||||
/* Some interrupts are in fact addresses to tables */
|
|
||||||
((PDWORD)BaseAddress)[0x1E] = (DWORD)NULL;
|
|
||||||
((PDWORD)BaseAddress)[0x41] = (DWORD)NULL;
|
|
||||||
((PDWORD)BaseAddress)[0x46] = (DWORD)NULL;
|
|
||||||
((PDWORD)BaseAddress)[0x48] = (DWORD)NULL;
|
|
||||||
((PDWORD)BaseAddress)[0x49] = (DWORD)NULL;
|
|
||||||
|
|
||||||
/* Initialize platform hardware (PIC/PIT chips, ...) */
|
/* Initialize platform hardware (PIC/PIT chips, ...) */
|
||||||
BiosHwSetup();
|
BiosHwSetup();
|
||||||
|
|
|
@ -15,6 +15,8 @@
|
||||||
#include "kbdbios32.h"
|
#include "kbdbios32.h"
|
||||||
#include "vidbios32.h"
|
#include "vidbios32.h"
|
||||||
|
|
||||||
|
/**/ #include "callback.h" /**/
|
||||||
|
|
||||||
/* DEFINES ********************************************************************/
|
/* DEFINES ********************************************************************/
|
||||||
|
|
||||||
#define BIOS_PIC_MASTER_INT 0x08
|
#define BIOS_PIC_MASTER_INT 0x08
|
||||||
|
@ -115,6 +117,14 @@ C_ASSERT(sizeof(BIOS_DATA_AREA) == 0x133);
|
||||||
|
|
||||||
/* FUNCTIONS ******************************************************************/
|
/* FUNCTIONS ******************************************************************/
|
||||||
|
|
||||||
|
extern CALLBACK16 BiosContext;
|
||||||
|
#define RegisterBiosInt32(IntNumber, IntHandler) \
|
||||||
|
do { \
|
||||||
|
BiosContext.NextOffset += RegisterInt32(MAKELONG(BiosContext.NextOffset, \
|
||||||
|
BiosContext.Segment), \
|
||||||
|
(IntNumber), (IntHandler), NULL); \
|
||||||
|
} while(0);
|
||||||
|
|
||||||
extern PBIOS_DATA_AREA Bda;
|
extern PBIOS_DATA_AREA Bda;
|
||||||
|
|
||||||
/**HACK!!**/typedef VOID (WINAPI *EMULATOR_INT32_PROC)(LPWORD Stack);/**HACK!!**/
|
/**HACK!!**/typedef VOID (WINAPI *EMULATOR_INT32_PROC)(LPWORD Stack);/**HACK!!**/
|
||||||
|
|
|
@ -11,14 +11,14 @@
|
||||||
#define NDEBUG
|
#define NDEBUG
|
||||||
|
|
||||||
#include "emulator.h"
|
#include "emulator.h"
|
||||||
|
#include "callback.h"
|
||||||
|
|
||||||
// #include "kbdbios32.h"
|
// #include "kbdbios32.h"
|
||||||
#include "bios32.h"
|
#include "bios32.h"
|
||||||
|
|
||||||
#include "io.h"
|
#include "io.h"
|
||||||
#include "hardware/ps2.h"
|
#include "hardware/ps2.h"
|
||||||
|
|
||||||
#include "int32.h"
|
|
||||||
|
|
||||||
/* PRIVATE VARIABLES **********************************************************/
|
/* PRIVATE VARIABLES **********************************************************/
|
||||||
|
|
||||||
static BYTE BiosKeyboardMap[256];
|
static BYTE BiosKeyboardMap[256];
|
||||||
|
@ -271,7 +271,7 @@ BOOLEAN KbdBios32Initialize(HANDLE ConsoleInput)
|
||||||
/* Register the BIOS 32-bit Interrupts */
|
/* Register the BIOS 32-bit Interrupts */
|
||||||
|
|
||||||
/* Initialize software vector handlers */
|
/* Initialize software vector handlers */
|
||||||
RegisterInt32(BIOS_KBD_INTERRUPT, BiosKeyboardService);
|
RegisterBiosInt32(BIOS_KBD_INTERRUPT, BiosKeyboardService);
|
||||||
|
|
||||||
/* Set up the HW vector interrupts */
|
/* Set up the HW vector interrupts */
|
||||||
EnableHwIRQ(1, BiosKeyboardIrq);
|
EnableHwIRQ(1, BiosKeyboardIrq);
|
||||||
|
|
|
@ -11,14 +11,14 @@
|
||||||
#define NDEBUG
|
#define NDEBUG
|
||||||
|
|
||||||
#include "emulator.h"
|
#include "emulator.h"
|
||||||
|
#include "callback.h"
|
||||||
|
|
||||||
// #include "vidbios32.h"
|
// #include "vidbios32.h"
|
||||||
#include "bios32.h"
|
#include "bios32.h"
|
||||||
|
|
||||||
#include "io.h"
|
#include "io.h"
|
||||||
#include "hardware/vga.h"
|
#include "hardware/vga.h"
|
||||||
|
|
||||||
#include "int32.h"
|
|
||||||
|
|
||||||
/* MACROS *********************************************************************/
|
/* MACROS *********************************************************************/
|
||||||
|
|
||||||
//
|
//
|
||||||
|
@ -1536,11 +1536,11 @@ static VOID WINAPI VidBiosVideoService(LPWORD Stack)
|
||||||
BOOLEAN VidBios32Initialize(HANDLE ConsoleOutput)
|
BOOLEAN VidBios32Initialize(HANDLE ConsoleOutput)
|
||||||
{
|
{
|
||||||
/* Some interrupts are in fact addresses to tables */
|
/* Some interrupts are in fact addresses to tables */
|
||||||
((PDWORD)BaseAddress)[0x1D] = (DWORD)NULL;
|
((PULONG)BaseAddress)[0x1D] = (ULONG)NULL;
|
||||||
((PDWORD)BaseAddress)[0x1F] = (DWORD)NULL;
|
((PULONG)BaseAddress)[0x1F] = (ULONG)NULL;
|
||||||
// ((PDWORD)BaseAddress)[0x42] = (DWORD)NULL;
|
// ((PULONG)BaseAddress)[0x42] = (ULONG)NULL;
|
||||||
((PDWORD)BaseAddress)[0x43] = (DWORD)NULL;
|
((PULONG)BaseAddress)[0x43] = (ULONG)NULL;
|
||||||
((PDWORD)BaseAddress)[0x44] = (DWORD)NULL;
|
((PULONG)BaseAddress)[0x44] = (ULONG)NULL;
|
||||||
|
|
||||||
/* Set the default video mode */
|
/* Set the default video mode */
|
||||||
VidBiosSetVideoMode(BIOS_DEFAULT_VIDEO_MODE);
|
VidBiosSetVideoMode(BIOS_DEFAULT_VIDEO_MODE);
|
||||||
|
@ -1562,7 +1562,7 @@ BOOLEAN VidBios32Initialize(HANDLE ConsoleOutput)
|
||||||
}
|
}
|
||||||
|
|
||||||
/* Register the BIOS 32-bit Interrupts */
|
/* Register the BIOS 32-bit Interrupts */
|
||||||
RegisterInt32(BIOS_VIDEO_INTERRUPT, VidBiosVideoService);
|
RegisterBiosInt32(BIOS_VIDEO_INTERRUPT, VidBiosVideoService);
|
||||||
|
|
||||||
return TRUE;
|
return TRUE;
|
||||||
}
|
}
|
||||||
|
|
|
@ -14,17 +14,130 @@
|
||||||
|
|
||||||
#define NDEBUG
|
#define NDEBUG
|
||||||
|
|
||||||
|
#include "emulator.h"
|
||||||
|
|
||||||
#include "dem.h"
|
#include "dem.h"
|
||||||
|
#include "bop.h"
|
||||||
|
|
||||||
/* Extra PSDK/NDK Headers */
|
/* Extra PSDK/NDK Headers */
|
||||||
#include <ndk/obtypes.h>
|
#include <ndk/obtypes.h>
|
||||||
|
|
||||||
|
/* PRIVATE VARIABLES **********************************************************/
|
||||||
|
|
||||||
/**/extern BYTE CurrentDrive;/**/
|
/**/extern BYTE CurrentDrive;/**/
|
||||||
|
|
||||||
|
/* DEFINES ********************************************************************/
|
||||||
|
|
||||||
|
/* BOP Identifiers */
|
||||||
|
#define BOP_DOS 0x50 // DOS System BOP (for NTIO.SYS and NTDOS.SYS)
|
||||||
|
#define BOP_CMD 0x54 // DOS Command Interpreter BOP (for COMMAND.COM)
|
||||||
|
|
||||||
|
/* PRIVATE FUNCTIONS **********************************************************/
|
||||||
|
|
||||||
|
static VOID WINAPI DosSystemBop(LPWORD Stack)
|
||||||
|
{
|
||||||
|
/* Get the Function Number and skip it */
|
||||||
|
BYTE FuncNum = *(PBYTE)SEG_OFF_TO_PTR(getCS(), getIP());
|
||||||
|
setIP(getIP() + 1);
|
||||||
|
|
||||||
|
DPRINT1("Unknown DOS System BOP Function: 0x%02X\n", FuncNum);
|
||||||
|
}
|
||||||
|
|
||||||
|
static VOID WINAPI DosCmdInterpreterBop(LPWORD Stack)
|
||||||
|
{
|
||||||
|
/* Get the Function Number and skip it */
|
||||||
|
BYTE FuncNum = *(PBYTE)SEG_OFF_TO_PTR(getCS(), getIP());
|
||||||
|
setIP(getIP() + 1);
|
||||||
|
|
||||||
|
switch (FuncNum)
|
||||||
|
{
|
||||||
|
case 0x08: // Launch external command
|
||||||
|
{
|
||||||
|
#define CMDLINE_LENGTH 1024
|
||||||
|
|
||||||
|
BOOL Result;
|
||||||
|
DWORD dwExitCode;
|
||||||
|
|
||||||
|
LPSTR Command = (LPSTR)SEG_OFF_TO_PTR(getDS(), getSI());
|
||||||
|
LPSTR CmdPtr = Command;
|
||||||
|
CHAR CommandLine[CMDLINE_LENGTH] = "";
|
||||||
|
STARTUPINFOA StartupInfo;
|
||||||
|
PROCESS_INFORMATION ProcessInformation;
|
||||||
|
|
||||||
|
/* Remove return carriage character */
|
||||||
|
while (*CmdPtr != '\r') CmdPtr++;
|
||||||
|
*CmdPtr = '\0';
|
||||||
|
|
||||||
|
DPRINT1("CMD Run Command '%s'\n", Command);
|
||||||
|
|
||||||
|
/* Spawn a user-defined 32-bit command preprocessor */
|
||||||
|
|
||||||
|
/* Build the command line */
|
||||||
|
// FIXME: Use COMSPEC env var!!
|
||||||
|
strcpy(CommandLine, "cmd.exe /c ");
|
||||||
|
strcat(CommandLine, Command);
|
||||||
|
|
||||||
|
ZeroMemory(&StartupInfo, sizeof(StartupInfo));
|
||||||
|
ZeroMemory(&ProcessInformation, sizeof(ProcessInformation));
|
||||||
|
|
||||||
|
StartupInfo.cb = sizeof(StartupInfo);
|
||||||
|
|
||||||
|
DosPrintCharacter('\n');
|
||||||
|
|
||||||
|
Result = CreateProcessA(NULL,
|
||||||
|
CommandLine,
|
||||||
|
NULL,
|
||||||
|
NULL,
|
||||||
|
TRUE,
|
||||||
|
0,
|
||||||
|
NULL,
|
||||||
|
NULL,
|
||||||
|
&StartupInfo,
|
||||||
|
&ProcessInformation);
|
||||||
|
if (Result)
|
||||||
|
{
|
||||||
|
DPRINT1("Command '%s' launched successfully\n", Command);
|
||||||
|
|
||||||
|
/* Wait for process termination */
|
||||||
|
WaitForSingleObject(ProcessInformation.hProcess, INFINITE);
|
||||||
|
|
||||||
|
/* Get the exit code */
|
||||||
|
GetExitCodeProcess(ProcessInformation.hProcess, &dwExitCode);
|
||||||
|
|
||||||
|
/* Close handles */
|
||||||
|
CloseHandle(ProcessInformation.hThread);
|
||||||
|
CloseHandle(ProcessInformation.hProcess);
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
DPRINT1("Failed when launched command '%s'\n");
|
||||||
|
dwExitCode = GetLastError();
|
||||||
|
}
|
||||||
|
|
||||||
|
DosPrintCharacter('\n');
|
||||||
|
|
||||||
|
setAL((UCHAR)dwExitCode);
|
||||||
|
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
|
||||||
|
default:
|
||||||
|
{
|
||||||
|
DPRINT1("Unknown DOS CMD Interpreter BOP Function: 0x%02X\n", FuncNum);
|
||||||
|
// setCF(1); // Disable, otherwise we enter an infinite loop
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
/* PUBLIC FUNCTIONS ***********************************************************/
|
/* PUBLIC FUNCTIONS ***********************************************************/
|
||||||
|
|
||||||
BOOLEAN DosInitialize(IN LPCSTR DosKernelFileNames)
|
BOOLEAN DosInitialize(IN LPCSTR DosKernelFileNames)
|
||||||
{
|
{
|
||||||
|
/* Register the DOS BOPs */
|
||||||
|
RegisterBop(BOP_DOS, DosSystemBop );
|
||||||
|
RegisterBop(BOP_CMD, DosCmdInterpreterBop);
|
||||||
|
|
||||||
if (DosKernelFileNames)
|
if (DosKernelFileNames)
|
||||||
{
|
{
|
||||||
DisplayMessage(L"NTVDM: Loading DOS kernel from external files is currently unsupported");
|
DisplayMessage(L"NTVDM: Loading DOS kernel from external files is currently unsupported");
|
||||||
|
@ -35,7 +148,7 @@ BOOLEAN DosInitialize(IN LPCSTR DosKernelFileNames)
|
||||||
BOOLEAN Result;
|
BOOLEAN Result;
|
||||||
|
|
||||||
Result = DosBIOSInitialize();
|
Result = DosBIOSInitialize();
|
||||||
Result &= DosKRNLInitialize();
|
// Result &= DosKRNLInitialize();
|
||||||
|
|
||||||
return Result;
|
return Result;
|
||||||
}
|
}
|
||||||
|
|
|
@ -11,21 +11,17 @@
|
||||||
#define NDEBUG
|
#define NDEBUG
|
||||||
|
|
||||||
#include "emulator.h"
|
#include "emulator.h"
|
||||||
|
#include "callback.h"
|
||||||
|
|
||||||
#include "dos.h"
|
#include "dos.h"
|
||||||
|
|
||||||
#include "bios/bios.h"
|
#include "bios/bios.h"
|
||||||
#include "bop.h"
|
|
||||||
// #include "int32.h"
|
|
||||||
|
|
||||||
/* PRIVATE VARIABLES **********************************************************/
|
/* PRIVATE VARIABLES **********************************************************/
|
||||||
|
|
||||||
// static BYTE CurrentDrive;
|
// static BYTE CurrentDrive;
|
||||||
// static CHAR CurrentDirectories[NUM_DRIVES][DOS_DIR_LENGTH];
|
// static CHAR CurrentDirectories[NUM_DRIVES][DOS_DIR_LENGTH];
|
||||||
|
|
||||||
/* BOP Identifiers */
|
|
||||||
#define BOP_DOS 0x50 // DOS System BOP (for NTIO.SYS and NTDOS.SYS)
|
|
||||||
#define BOP_CMD 0x54 // DOS Command Interpreter BOP (for COMMAND.COM)
|
|
||||||
|
|
||||||
/* PRIVATE FUNCTIONS **********************************************************/
|
/* PRIVATE FUNCTIONS **********************************************************/
|
||||||
|
|
||||||
#if 0
|
#if 0
|
||||||
|
@ -119,94 +115,6 @@ VOID DosPrintCharacter(CHAR Character)
|
||||||
DosWriteFile(DOS_OUTPUT_HANDLE, &Character, sizeof(CHAR), &BytesWritten);
|
DosWriteFile(DOS_OUTPUT_HANDLE, &Character, sizeof(CHAR), &BytesWritten);
|
||||||
}
|
}
|
||||||
|
|
||||||
VOID WINAPI DosSystemBop(LPWORD Stack)
|
|
||||||
{
|
|
||||||
/* Get the Function Number and skip it */
|
|
||||||
BYTE FuncNum = *(PBYTE)SEG_OFF_TO_PTR(getCS(), getIP());
|
|
||||||
setIP(getIP() + 1);
|
|
||||||
|
|
||||||
DPRINT1("Unknown DOS System BOP Function: 0x%02X\n", FuncNum);
|
|
||||||
}
|
|
||||||
|
|
||||||
VOID WINAPI DosCmdInterpreterBop(LPWORD Stack)
|
|
||||||
{
|
|
||||||
/* Get the Function Number and skip it */
|
|
||||||
BYTE FuncNum = *(PBYTE)SEG_OFF_TO_PTR(getCS(), getIP());
|
|
||||||
setIP(getIP() + 1);
|
|
||||||
|
|
||||||
switch (FuncNum)
|
|
||||||
{
|
|
||||||
case 0x08: // Launch external command
|
|
||||||
{
|
|
||||||
#define CMDLINE_LENGTH 1024
|
|
||||||
|
|
||||||
BOOL Result;
|
|
||||||
DWORD dwExitCode;
|
|
||||||
|
|
||||||
LPSTR Command = (LPSTR)SEG_OFF_TO_PTR(getDS(), getSI());
|
|
||||||
CHAR CommandLine[CMDLINE_LENGTH] = "";
|
|
||||||
STARTUPINFOA StartupInfo;
|
|
||||||
PROCESS_INFORMATION ProcessInformation;
|
|
||||||
DPRINT1("CMD Run Command '%s'\n", Command);
|
|
||||||
|
|
||||||
Command[strlen(Command)-1] = 0;
|
|
||||||
|
|
||||||
strcpy(CommandLine, "cmd.exe /c ");
|
|
||||||
strcat(CommandLine, Command);
|
|
||||||
|
|
||||||
ZeroMemory(&StartupInfo, sizeof(StartupInfo));
|
|
||||||
ZeroMemory(&ProcessInformation, sizeof(ProcessInformation));
|
|
||||||
|
|
||||||
StartupInfo.cb = sizeof(StartupInfo);
|
|
||||||
|
|
||||||
DosPrintCharacter('\n');
|
|
||||||
|
|
||||||
Result = CreateProcessA(NULL,
|
|
||||||
CommandLine,
|
|
||||||
NULL,
|
|
||||||
NULL,
|
|
||||||
TRUE,
|
|
||||||
0,
|
|
||||||
NULL,
|
|
||||||
NULL,
|
|
||||||
&StartupInfo,
|
|
||||||
&ProcessInformation);
|
|
||||||
if (Result)
|
|
||||||
{
|
|
||||||
DPRINT1("Command '%s' launched successfully\n");
|
|
||||||
|
|
||||||
/* Wait for process termination */
|
|
||||||
WaitForSingleObject(ProcessInformation.hProcess, INFINITE);
|
|
||||||
|
|
||||||
/* Get the exit code */
|
|
||||||
GetExitCodeProcess(ProcessInformation.hProcess, &dwExitCode);
|
|
||||||
|
|
||||||
/* Close handles */
|
|
||||||
CloseHandle(ProcessInformation.hThread);
|
|
||||||
CloseHandle(ProcessInformation.hProcess);
|
|
||||||
}
|
|
||||||
else
|
|
||||||
{
|
|
||||||
DPRINT1("Failed when launched command '%s'\n");
|
|
||||||
dwExitCode = GetLastError();
|
|
||||||
}
|
|
||||||
|
|
||||||
DosPrintCharacter('\n');
|
|
||||||
|
|
||||||
setAL((UCHAR)dwExitCode);
|
|
||||||
|
|
||||||
break;
|
|
||||||
}
|
|
||||||
|
|
||||||
default:
|
|
||||||
{
|
|
||||||
DPRINT1("Unknown DOS CMD Interpreter BOP Function: 0x%02X\n", FuncNum);
|
|
||||||
// setCF(1); // Disable, otherwise we enter an infinite loop
|
|
||||||
break;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
BOOLEAN DosBIOSInitialize(VOID)
|
BOOLEAN DosBIOSInitialize(VOID)
|
||||||
{
|
{
|
||||||
PDOS_MCB Mcb = SEGMENT_TO_MCB(FIRST_MCB_SEGMENT);
|
PDOS_MCB Mcb = SEGMENT_TO_MCB(FIRST_MCB_SEGMENT);
|
||||||
|
@ -345,16 +253,11 @@ BOOLEAN DosBIOSInitialize(VOID)
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
|
|
||||||
/* Register the DOS BOPs */
|
|
||||||
RegisterBop(BOP_DOS, DosSystemBop );
|
|
||||||
RegisterBop(BOP_CMD, DosCmdInterpreterBop);
|
|
||||||
|
|
||||||
/* Register the DOS 32-bit Interrupts */
|
/* Register the DOS 32-bit Interrupts */
|
||||||
// RegisterInt32(0x20, DosInt20h);
|
// RegisterDosInt32(0x20, DosInt20h);
|
||||||
|
|
||||||
/* TODO: Initialize the DOS kernel */
|
/* Initialize the DOS kernel */
|
||||||
|
return DosKRNLInitialize();
|
||||||
return TRUE;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
/* EOF */
|
/* EOF */
|
||||||
|
|
|
@ -11,15 +11,18 @@
|
||||||
#define NDEBUG
|
#define NDEBUG
|
||||||
|
|
||||||
#include "emulator.h"
|
#include "emulator.h"
|
||||||
|
#include "callback.h"
|
||||||
|
|
||||||
#include "dos.h"
|
#include "dos.h"
|
||||||
#include "dos/dem.h"
|
#include "dos/dem.h"
|
||||||
|
|
||||||
#include "bios/bios.h"
|
#include "bios/bios.h"
|
||||||
#include "int32.h"
|
|
||||||
#include "registers.h"
|
#include "registers.h"
|
||||||
|
|
||||||
/* PRIVATE VARIABLES **********************************************************/
|
/* PRIVATE VARIABLES **********************************************************/
|
||||||
|
|
||||||
|
CALLBACK16 DosContext;
|
||||||
|
|
||||||
static WORD CurrentPsp = SYSTEM_PSP;
|
static WORD CurrentPsp = SYSTEM_PSP;
|
||||||
static WORD DosLastError = 0;
|
static WORD DosLastError = 0;
|
||||||
static DWORD DiskTransferArea;
|
static DWORD DiskTransferArea;
|
||||||
|
@ -1669,11 +1672,11 @@ VOID WINAPI DosInt21h(LPWORD Stack)
|
||||||
/* Set Interrupt Vector */
|
/* Set Interrupt Vector */
|
||||||
case 0x25:
|
case 0x25:
|
||||||
{
|
{
|
||||||
DWORD FarPointer = MAKELONG(getDX(), getDS());
|
ULONG FarPointer = MAKELONG(getDX(), getDS());
|
||||||
DPRINT1("Setting interrupt 0x%x ...\n", getAL());
|
DPRINT1("Setting interrupt 0x%x ...\n", getAL());
|
||||||
|
|
||||||
/* Write the new far pointer to the IDT */
|
/* Write the new far pointer to the IDT */
|
||||||
((PDWORD)BaseAddress)[getAL()] = FarPointer;
|
((PULONG)BaseAddress)[getAL()] = FarPointer;
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -2480,6 +2483,7 @@ VOID WINAPI DosFastConOut(LPWORD Stack)
|
||||||
* for more information.
|
* for more information.
|
||||||
*/
|
*/
|
||||||
|
|
||||||
|
#if 0
|
||||||
if (Stack[STACK_COUNTER] == 0)
|
if (Stack[STACK_COUNTER] == 0)
|
||||||
{
|
{
|
||||||
Stack[STACK_COUNTER]++;
|
Stack[STACK_COUNTER]++;
|
||||||
|
@ -2504,6 +2508,20 @@ VOID WINAPI DosFastConOut(LPWORD Stack)
|
||||||
setAX(Stack[STACK_VAR_A]);
|
setAX(Stack[STACK_VAR_A]);
|
||||||
setBX(Stack[STACK_VAR_B]);
|
setBX(Stack[STACK_VAR_B]);
|
||||||
}
|
}
|
||||||
|
#else
|
||||||
|
/* Save AX and BX */
|
||||||
|
USHORT AX = getAX();
|
||||||
|
USHORT BX = getBX();
|
||||||
|
|
||||||
|
setBL(DOS_CHAR_ATTRIBUTE);
|
||||||
|
setBH(Bda->VideoPage);
|
||||||
|
setAH(0x0E);
|
||||||
|
Int32Call(&DosContext, 0x10);
|
||||||
|
|
||||||
|
/* Restore AX and BX */
|
||||||
|
setAX(AX);
|
||||||
|
setBX(BX);
|
||||||
|
#endif
|
||||||
}
|
}
|
||||||
|
|
||||||
VOID WINAPI DosInt2Fh(LPWORD Stack)
|
VOID WINAPI DosInt2Fh(LPWORD Stack)
|
||||||
|
@ -2585,15 +2603,17 @@ BOOLEAN DosKRNLInitialize(VOID)
|
||||||
|
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
|
/* Initialize the callback context */
|
||||||
|
InitializeContext(&DosContext, 0x0070, 0x0000);
|
||||||
|
|
||||||
/* Register the DOS 32-bit Interrupts */
|
/* Register the DOS 32-bit Interrupts */
|
||||||
RegisterInt32(0x20, DosInt20h );
|
RegisterDosInt32(0x20, DosInt20h );
|
||||||
RegisterInt32(0x21, DosInt21h );
|
RegisterDosInt32(0x21, DosInt21h );
|
||||||
// RegisterInt32(0x22, DosInt22h ); // Termination
|
// RegisterDosInt32(0x22, DosInt22h ); // Termination
|
||||||
RegisterInt32(0x23, DosBreakInterrupt); // Ctrl-C / Ctrl-Break
|
RegisterDosInt32(0x23, DosBreakInterrupt); // Ctrl-C / Ctrl-Break
|
||||||
// RegisterInt32(0x24, DosInt24h ); // Critical Error
|
// RegisterDosInt32(0x24, DosInt24h ); // Critical Error
|
||||||
RegisterInt32(0x29, DosFastConOut ); // DOS 2+ Fast Console Output
|
RegisterDosInt32(0x29, DosFastConOut ); // DOS 2+ Fast Console Output
|
||||||
RegisterInt32(0x2F, DosInt2Fh );
|
RegisterDosInt32(0x2F, DosInt2Fh );
|
||||||
|
|
||||||
return TRUE;
|
return TRUE;
|
||||||
}
|
}
|
||||||
|
|
|
@ -13,6 +13,8 @@
|
||||||
|
|
||||||
#include "ntvdm.h"
|
#include "ntvdm.h"
|
||||||
|
|
||||||
|
/**/ #include "callback.h" /**/
|
||||||
|
|
||||||
/* DEFINES ********************************************************************/
|
/* DEFINES ********************************************************************/
|
||||||
|
|
||||||
//
|
//
|
||||||
|
@ -138,6 +140,14 @@ typedef struct _DOS_FIND_FILE_BLOCK
|
||||||
|
|
||||||
/* FUNCTIONS ******************************************************************/
|
/* FUNCTIONS ******************************************************************/
|
||||||
|
|
||||||
|
extern CALLBACK16 DosContext;
|
||||||
|
#define RegisterDosInt32(IntNumber, IntHandler) \
|
||||||
|
do { \
|
||||||
|
DosContext.NextOffset += RegisterInt32(MAKELONG(DosContext.NextOffset, \
|
||||||
|
DosContext.Segment), \
|
||||||
|
(IntNumber), (IntHandler), NULL); \
|
||||||
|
} while(0);
|
||||||
|
|
||||||
/*
|
/*
|
||||||
* DOS BIOS Functions
|
* DOS BIOS Functions
|
||||||
* See bios.c
|
* See bios.c
|
||||||
|
|
|
@ -388,7 +388,8 @@ BOOLEAN EmulatorInitialize(HANDLE ConsoleInput, HANDLE ConsoleOutput)
|
||||||
// if (!VgaInitialize(ConsoleOutput)) return FALSE;
|
// if (!VgaInitialize(ConsoleOutput)) return FALSE;
|
||||||
VgaInitialize(ConsoleOutput);
|
VgaInitialize(ConsoleOutput);
|
||||||
|
|
||||||
/* Register the emulator BOPs */
|
/* Initialize the software callback system and register the emulator BOPs */
|
||||||
|
InitializeCallbacks();
|
||||||
RegisterBop(BOP_DEBUGGER , EmulatorDebugBreakBop);
|
RegisterBop(BOP_DEBUGGER , EmulatorDebugBreakBop);
|
||||||
RegisterBop(BOP_UNSIMULATE, EmulatorUnsimulateBop);
|
RegisterBop(BOP_UNSIMULATE, EmulatorUnsimulateBop);
|
||||||
|
|
||||||
|
|
Loading…
Reference in a new issue