mirror of
https://github.com/reactos/reactos.git
synced 2024-12-29 10:35:28 +00:00
[NTVDM]
- Remove some hardcoded values. - Reshuffle again DOS initialization to better reflect how it is done in the real world (see "Advanced MS-DOS Programming" by Ray Duncan, Chapter 2 "MS-DOS in Operation"): split DOS data stuff into DOS BIOS data, and DOS kernel data areas. In preparation for an upcoming commit. svn path=/trunk/; revision=68585
This commit is contained in:
parent
88adae5ab6
commit
4d6da0ec7a
5 changed files with 143 additions and 127 deletions
|
@ -32,6 +32,13 @@
|
|||
|
||||
/* PRIVATE VARIABLES **********************************************************/
|
||||
|
||||
// CALLBACK16 BiosContext;
|
||||
|
||||
/* PUBLIC VARIABLES ***********************************************************/
|
||||
|
||||
/* Global DOS BIOS data area */
|
||||
PBIOS_DATA BiosData;
|
||||
|
||||
/* PRIVATE FUNCTIONS **********************************************************/
|
||||
|
||||
/* PUBLIC FUNCTIONS ***********************************************************/
|
||||
|
@ -63,7 +70,7 @@ BOOLEAN DosCheckInput(VOID)
|
|||
return FALSE;
|
||||
}
|
||||
|
||||
if (Descriptor->DeviceInfo & (1 << 7))
|
||||
if (Descriptor->DeviceInfo & FILE_INFO_DEVICE)
|
||||
{
|
||||
WORD Result;
|
||||
PDOS_DEVICE_NODE Node = DosGetDriverNode(Descriptor->DevicePointer);
|
||||
|
@ -155,28 +162,61 @@ BOOLEAN DosBuildSysEnvBlock(VOID)
|
|||
|
||||
BOOLEAN DosBIOSInitialize(VOID)
|
||||
{
|
||||
#if 0
|
||||
UCHAR i;
|
||||
CHAR CurrentDirectory[MAX_PATH];
|
||||
CHAR DosDirectory[DOS_DIR_LENGTH];
|
||||
LPSTR Path;
|
||||
|
||||
FILE *Stream;
|
||||
WCHAR Buffer[256];
|
||||
#endif
|
||||
|
||||
/* Set the data segment */
|
||||
setDS(DOS_DATA_SEGMENT);
|
||||
setDS(BIOS_DATA_SEGMENT);
|
||||
|
||||
/* Initialize the DOS stack */
|
||||
// Stack just before FIRST_MCB_SEGMENT and after SYSTEM_ENV_BLOCK
|
||||
// FIXME: Add a block of fixed size for the stack in DOS_DATA instead!
|
||||
/* Initialize the global DOS BIOS data area */
|
||||
BiosData = (PBIOS_DATA)SEG_OFF_TO_PTR(BIOS_DATA_SEGMENT, 0x0000);
|
||||
|
||||
/* Initialize the DOS BIOS stack */
|
||||
// FIXME: Add a block of fixed size for the stack in BIOS/DOS_DATA instead!
|
||||
setSS(0x0F00);
|
||||
setSP(0x0FF0);
|
||||
setBP(0x091E); // DOS base stack pointer relic value
|
||||
|
||||
/* Initialize memory management */
|
||||
DosInitializeMemory();
|
||||
/*
|
||||
* Initialize the INT 13h (BIOS Disk Services) handler chain support.
|
||||
*
|
||||
* The INT 13h handler chain is some functionality that allows DOS
|
||||
* to insert disk filter drivers in between the (hooked) INT 13h handler
|
||||
* and its original handler.
|
||||
* Typically, those are:
|
||||
* - filter for detecting disk changes (for floppy disks),
|
||||
* - filter for tracking formatting calls and correcting DMA boundary errors,
|
||||
* - a possible filter to work around a bug in a particular version of PC-AT's
|
||||
* IBM's ROM BIOS (on systems with model byte FCh and BIOS date "01/10/84" only)
|
||||
* (see http://www.ctyme.com/intr/rb-4453.htm for more details).
|
||||
*
|
||||
* This functionality is known to be used by some legitimate programs,
|
||||
* by Windows 3.x, as well as some illegitimate ones (aka. virii).
|
||||
*
|
||||
* See extra information about this support in dos.h
|
||||
*/
|
||||
// FIXME: Should be done by the DOS BIOS
|
||||
BiosData->RomBiosInt13 = ((PULONG)BaseAddress)[0x13];
|
||||
BiosData->PrevInt13 = BiosData->RomBiosInt13;
|
||||
// RegisterDosInt32(0x13, DosInt13h); // Unused at the moment!
|
||||
|
||||
//
|
||||
// HERE: Do all hardware initialization needed for DOS
|
||||
//
|
||||
|
||||
/*
|
||||
* SysInit part...
|
||||
*/
|
||||
|
||||
// InitializeContext(&DosContext, BIOS_CODE_SEGMENT, 0x0010);
|
||||
|
||||
/* Initialize the DOS kernel (DosInit) */
|
||||
if (!DosKRNLInitialize())
|
||||
{
|
||||
DisplayMessage(L"Failed to load the DOS kernel! Exiting...");
|
||||
return FALSE;
|
||||
}
|
||||
|
||||
/* DOS kernel loading succeeded, we can finish the initialization */
|
||||
|
||||
/* Build the system master environment block (inherited by the shell) */
|
||||
if (!DosBuildSysEnvBlock())
|
||||
|
@ -184,44 +224,7 @@ BOOLEAN DosBIOSInitialize(VOID)
|
|||
DPRINT1("An error occurred when setting up the system environment block.\n");
|
||||
}
|
||||
|
||||
|
||||
#if 0
|
||||
|
||||
/* Clear the current directory buffer */
|
||||
RtlZeroMemory(CurrentDirectories, sizeof(CurrentDirectories));
|
||||
|
||||
/* Get the current directory */
|
||||
if (!GetCurrentDirectoryA(MAX_PATH, CurrentDirectory))
|
||||
{
|
||||
// TODO: Use some kind of default path?
|
||||
return FALSE;
|
||||
}
|
||||
|
||||
/* Convert that to a DOS path */
|
||||
if (!GetShortPathNameA(CurrentDirectory, DosDirectory, DOS_DIR_LENGTH))
|
||||
{
|
||||
// TODO: Use some kind of default path?
|
||||
return FALSE;
|
||||
}
|
||||
|
||||
/* Set the drive */
|
||||
Sda->CurrentDrive = DosDirectory[0] - 'A';
|
||||
|
||||
/* Get the directory part of the path */
|
||||
Path = strchr(DosDirectory, '\\');
|
||||
if (Path != NULL)
|
||||
{
|
||||
/* Skip the backslash */
|
||||
Path++;
|
||||
}
|
||||
|
||||
/* Set the directory */
|
||||
if (Path != NULL)
|
||||
{
|
||||
strncpy(CurrentDirectories[Sda->CurrentDrive], Path, DOS_DIR_LENGTH);
|
||||
}
|
||||
|
||||
/* Read CONFIG.SYS */
|
||||
/* TODO: Read CONFIG.NT/SYS */
|
||||
Stream = _wfopen(DOS_CONFIG_PATH, L"r");
|
||||
if (Stream != NULL)
|
||||
{
|
||||
|
@ -232,10 +235,7 @@ BOOLEAN DosBIOSInitialize(VOID)
|
|||
fclose(Stream);
|
||||
}
|
||||
|
||||
#endif
|
||||
|
||||
/* Initialize the DOS kernel */
|
||||
return DosKRNLInitialize();
|
||||
return TRUE;
|
||||
}
|
||||
|
||||
/* EOF */
|
||||
|
|
|
@ -191,7 +191,6 @@ VOID WINAPI DosInt21h(LPWORD Stack)
|
|||
BYTE Character;
|
||||
SYSTEMTIME SystemTime;
|
||||
PCHAR String;
|
||||
PDOS_INPUT_BUFFER InputBuffer;
|
||||
|
||||
Sda->InDos++;
|
||||
|
||||
|
@ -351,7 +350,7 @@ VOID WINAPI DosInt21h(LPWORD Stack)
|
|||
case 0x0A:
|
||||
{
|
||||
WORD Count = 0;
|
||||
InputBuffer = (PDOS_INPUT_BUFFER)SEG_OFF_TO_PTR(getDS(), getDX());
|
||||
PDOS_INPUT_BUFFER InputBuffer = (PDOS_INPUT_BUFFER)SEG_OFF_TO_PTR(getDS(), getDX());
|
||||
|
||||
DPRINT("Read Buffered Input\n");
|
||||
|
||||
|
@ -2199,12 +2198,12 @@ VOID WINAPI DosInt2Fh(LPWORD Stack)
|
|||
case 0x13:
|
||||
{
|
||||
/* Save the old values of PrevInt13 and RomBiosInt13 */
|
||||
ULONG OldInt13 = DosData->PrevInt13;
|
||||
ULONG OldBiosInt13 = DosData->RomBiosInt13;
|
||||
ULONG OldInt13 = BiosData->PrevInt13;
|
||||
ULONG OldBiosInt13 = BiosData->RomBiosInt13;
|
||||
|
||||
/* Set PrevInt13 and RomBiosInt13 to their new values */
|
||||
DosData->PrevInt13 = MAKELONG(getDX(), getDS());
|
||||
DosData->RomBiosInt13 = MAKELONG(getBX(), getES());
|
||||
BiosData->PrevInt13 = MAKELONG(getDX(), getDS());
|
||||
BiosData->RomBiosInt13 = MAKELONG(getBX(), getES());
|
||||
|
||||
/* Return in DS:DX the old value of PrevInt13 */
|
||||
setDS(HIWORD(OldInt13));
|
||||
|
@ -2271,8 +2270,6 @@ VOID WINAPI DosInt2Fh(LPWORD Stack)
|
|||
|
||||
BOOLEAN DosKRNLInitialize(VOID)
|
||||
{
|
||||
#if 1
|
||||
|
||||
UCHAR i;
|
||||
PDOS_SFT Sft;
|
||||
LPSTR Path;
|
||||
|
@ -2281,7 +2278,8 @@ BOOLEAN DosKRNLInitialize(VOID)
|
|||
CHAR CurrentDirectory[MAX_PATH];
|
||||
CHAR DosDirectory[DOS_DIR_LENGTH];
|
||||
|
||||
const BYTE NullDriverRoutine[] = {
|
||||
static const BYTE NullDriverRoutine[] =
|
||||
{
|
||||
/* Strategy routine entry */
|
||||
0x26, // mov [Request.Status], DOS_DEVSTAT_DONE
|
||||
0xC7,
|
||||
|
@ -2294,13 +2292,17 @@ BOOLEAN DosKRNLInitialize(VOID)
|
|||
0xCB, // retf
|
||||
};
|
||||
|
||||
FILE *Stream;
|
||||
WCHAR Buffer[256];
|
||||
/* Set the data segment */
|
||||
setDS(DOS_DATA_SEGMENT);
|
||||
|
||||
/* Initialize the global DOS data area */
|
||||
DosData = (PDOS_DATA)SEG_OFF_TO_PTR(DOS_DATA_SEGMENT, 0x0000);
|
||||
RtlZeroMemory(DosData, sizeof(*DosData));
|
||||
|
||||
/* Initialize the DOS stack */
|
||||
setSS(DOS_DATA_SEGMENT);
|
||||
setSP(DOS_DATA_OFFSET(DosStack) + sizeof(DosData->DosStack) - sizeof(WORD));
|
||||
|
||||
/* Initialize the list of lists */
|
||||
SysVars = &DosData->SysVars;
|
||||
RtlZeroMemory(SysVars, sizeof(*SysVars));
|
||||
|
@ -2409,18 +2411,8 @@ BOOLEAN DosKRNLInitialize(VOID)
|
|||
RtlZeroMemory(&Sft->FileDescriptors[i], sizeof(DOS_FILE_DESCRIPTOR));
|
||||
}
|
||||
|
||||
/* Read CONFIG.SYS */
|
||||
Stream = _wfopen(DOS_CONFIG_PATH, L"r");
|
||||
if (Stream != NULL)
|
||||
{
|
||||
while (fgetws(Buffer, 256, Stream))
|
||||
{
|
||||
// TODO: Parse the line
|
||||
}
|
||||
fclose(Stream);
|
||||
}
|
||||
|
||||
#endif
|
||||
/* Initialize memory management */
|
||||
DosInitializeMemory();
|
||||
|
||||
/* Initialize the callback context */
|
||||
InitializeContext(&DosContext, DOS_CODE_SEGMENT, 0x0000);
|
||||
|
@ -2449,29 +2441,6 @@ BOOLEAN DosKRNLInitialize(VOID)
|
|||
RegisterDosInt32(0x2C, NULL);
|
||||
RegisterDosInt32(0x2D, NULL);
|
||||
|
||||
/*
|
||||
* Initialize the INT 13h (BIOS Disk Services) handler chain support.
|
||||
*
|
||||
* The INT 13h handler chain is some functionality that allows DOS
|
||||
* to insert disk filter drivers in between the (hooked) INT 13h handler
|
||||
* and its original handler.
|
||||
* Typically, those are:
|
||||
* - filter for detecting disk changes (for floppy disks),
|
||||
* - filter for tracking formatting calls and correcting DMA boundary errors,
|
||||
* - a possible filter to work around a bug in a particular version of PC-AT's
|
||||
* IBM's ROM BIOS (on systems with model byte FCh and BIOS date "01/10/84" only)
|
||||
* (see http://www.ctyme.com/intr/rb-4453.htm for more details).
|
||||
*
|
||||
* This functionality is known to be used by some legitimate programs,
|
||||
* by Windows 3.x, as well as some illegitimate ones (aka. virii).
|
||||
*
|
||||
* See extra information about this support in dos.h
|
||||
*/
|
||||
// FIXME: Should be done by the DOS BIOS
|
||||
DosData->RomBiosInt13 = ((PULONG)BaseAddress)[0x13];
|
||||
DosData->PrevInt13 = DosData->RomBiosInt13;
|
||||
// RegisterDosInt32(0x13, DosInt13h); // Unused at the moment!
|
||||
|
||||
/* Initialize country data */
|
||||
DosCountryInitialize();
|
||||
|
||||
|
|
|
@ -27,22 +27,26 @@
|
|||
#define DOS_CONFIG_PATH L"%SystemRoot%\\system32\\CONFIG.NT"
|
||||
#define DOS_COMMAND_INTERPRETER L"%SystemRoot%\\system32\\COMMAND.COM /k %SystemRoot%\\system32\\AUTOEXEC.NT"
|
||||
|
||||
#define SYSTEM_PSP 0x08
|
||||
#define SYSTEM_ENV_BLOCK 0x800
|
||||
#define DOS_CODE_SEGMENT 0x70
|
||||
#define DOS_DATA_SEGMENT 0xA0
|
||||
#define BIOS_CODE_SEGMENT 0x70
|
||||
#define BIOS_DATA_SEGMENT 0x70
|
||||
#define DOS_CODE_SEGMENT 0x80
|
||||
#define DOS_DATA_SEGMENT 0xA5
|
||||
|
||||
#define DOS_DATA_OFFSET(x) FIELD_OFFSET(DOS_DATA, x)
|
||||
|
||||
#define SYSTEM_ENV_BLOCK 0x600 // FIXME: Should be dynamic
|
||||
|
||||
#define SYSTEM_PSP 0x0008
|
||||
|
||||
#define INVALID_DOS_HANDLE 0xFFFF
|
||||
#define DOS_INPUT_HANDLE 0
|
||||
#define DOS_OUTPUT_HANDLE 1
|
||||
#define DOS_ERROR_HANDLE 2
|
||||
|
||||
#define DOS_SFT_SIZE 255
|
||||
#define DOS_DIR_LENGTH 64
|
||||
#define NUM_DRIVES ('Z' - 'A' + 1)
|
||||
#define DOS_CHAR_ATTRIBUTE 0x07
|
||||
#define DOS_SFT_SIZE 255 // Value of the 'FILES=' command; maximum 255
|
||||
#define DOS_DIR_LENGTH 64
|
||||
#define NUM_DRIVES ('Z' - 'A' + 1)
|
||||
#define DOS_CHAR_ATTRIBUTE 0x07
|
||||
|
||||
#pragma pack(push, 1)
|
||||
|
||||
|
@ -230,8 +234,27 @@ typedef struct _DOS_SDA
|
|||
DWORD PrevCallFrame;
|
||||
} DOS_SDA, *PDOS_SDA;
|
||||
|
||||
/*
|
||||
* DOS kernel data structure
|
||||
*/
|
||||
typedef struct _DOS_DATA
|
||||
{
|
||||
DOS_SYSVARS SysVars;
|
||||
BYTE NullDriverRoutine[7];
|
||||
WORD DosVersion; // DOS version to report to programs (can be different from the true one)
|
||||
DOS_SDA Sda;
|
||||
CHAR CurrentDirectories[NUM_DRIVES][DOS_DIR_LENGTH];
|
||||
BYTE DosStack[384];
|
||||
BYTE Sft[ANYSIZE_ARRAY];
|
||||
} DOS_DATA, *PDOS_DATA;
|
||||
|
||||
/*
|
||||
* DOS BIOS data structure at segment 70h
|
||||
*/
|
||||
typedef struct _BIOS_DATA
|
||||
{
|
||||
BYTE StartupCode[20]; // 0x00 - 20 bytes: large enough for now!
|
||||
|
||||
/*
|
||||
* INT 13h (BIOS Disk Services) handler chain support.
|
||||
*
|
||||
|
@ -256,22 +279,20 @@ typedef struct _DOS_DATA
|
|||
* http://repo.hackerzvoice.net/depot_madchat/vxdevl/vdat/tuvd0001.htm
|
||||
* http://vxheaven.org/lib/vsm01.html
|
||||
*/
|
||||
DWORD RomBiosInt13;
|
||||
DWORD PrevInt13; // FIXME: Put it at 0070:00B4
|
||||
BYTE Padding0[0xB0 - /*FIELD_OFFSET(BIOS_DATA, StartupCode)*/ 20];
|
||||
DWORD RomBiosInt13; // 0xb0
|
||||
DWORD PrevInt13; // 0xb4
|
||||
BYTE Padding1[0x100 - 0xB8]; // 0xb8
|
||||
} BIOS_DATA, *PBIOS_DATA;
|
||||
|
||||
DOS_SYSVARS SysVars;
|
||||
BYTE NullDriverRoutine[7];
|
||||
WORD DosVersion; // DOS version to report to programs (can be different from the true one)
|
||||
DOS_SDA Sda;
|
||||
CHAR CurrentDirectories[NUM_DRIVES][DOS_DIR_LENGTH];
|
||||
BYTE Sft[ANYSIZE_ARRAY];
|
||||
} DOS_DATA, *PDOS_DATA;
|
||||
C_ASSERT(sizeof(BIOS_DATA) == 0x100);
|
||||
|
||||
#pragma pack(pop)
|
||||
|
||||
/* VARIABLES ******************************************************************/
|
||||
|
||||
extern BOOLEAN DoEcho;
|
||||
extern BOOLEAN DoEcho; // FIXME: Maybe move inside BiosData? (it's set by BIOS but used by CON driver in DOS BIOS)
|
||||
extern PBIOS_DATA BiosData;
|
||||
extern PDOS_DATA DosData;
|
||||
extern PDOS_SYSVARS SysVars;
|
||||
extern PDOS_SDA Sda;
|
||||
|
@ -279,11 +300,13 @@ extern PDOS_SDA Sda;
|
|||
/* FUNCTIONS ******************************************************************/
|
||||
|
||||
extern CALLBACK16 DosContext;
|
||||
#define RegisterDosInt32(IntNumber, IntHandler) \
|
||||
#define RegisterDosInt32(IntNumber, IntHandler) \
|
||||
do { \
|
||||
DosContext.NextOffset += RegisterInt32(MAKELONG(DosContext.NextOffset, \
|
||||
DosContext.Segment), \
|
||||
(IntNumber), (IntHandler), NULL); \
|
||||
ASSERT((0x20 <= IntNumber) && (IntNumber <= 0x2F)); \
|
||||
RegisterInt32(DosContext.TrampolineFarPtr + \
|
||||
DosContext.TrampolineSize + \
|
||||
(IntNumber - 0x20) * Int16To32StubSize, \
|
||||
(IntNumber), (IntHandler), NULL); \
|
||||
} while(0);
|
||||
|
||||
/*
|
||||
|
|
|
@ -12,6 +12,30 @@
|
|||
|
||||
#pragma pack(push, 1)
|
||||
|
||||
#if 0 // Real DOS-5 SFT entry, for reference only
|
||||
typedef struct _DOS_FILE_DESCRIPTOR_DOS5
|
||||
{
|
||||
WORD RefCount; // 0x00
|
||||
WORD OpenMode; // 0x02
|
||||
BYTE Attributes; // 0x04
|
||||
WORD DeviceInfo; // 0x05
|
||||
DWORD DevicePointer; // 0x07
|
||||
WORD StartCluster; // 0x0b
|
||||
WORD Time; // 0x0d
|
||||
WORD Date; // 0x0f
|
||||
DWORD Size; // 0x11
|
||||
DWORD Position; // 0x15
|
||||
BYTE Reserved0[7]; // 0x19
|
||||
CHAR FileName[11]; // 0x20
|
||||
BYTE Reserved1[6]; // 0x2b
|
||||
WORD OwnerPsp; // 0x31
|
||||
BYTE Reserved2[8]; // 0x33
|
||||
} DOS_FILE_DESCRIPTOR_DOS5, *PDOS_FILE_DESCRIPTOR_DOS5;
|
||||
|
||||
C_ASSERT(sizeof(DOS_FILE_DESCRIPTOR_DOS5) == 0x3B);
|
||||
#endif
|
||||
|
||||
// Modified DOS SFT entry, compatible for NTVDM only
|
||||
typedef struct _DOS_FILE_DESCRIPTOR
|
||||
{
|
||||
WORD RefCount;
|
||||
|
|
|
@ -360,7 +360,7 @@ BOOLEAN DosCloseHandle(WORD DosHandle)
|
|||
/* Check if the reference count fell to zero */
|
||||
if (!Descriptor->RefCount)
|
||||
{
|
||||
if (Descriptor->DeviceInfo & (1 << 7))
|
||||
if (Descriptor->DeviceInfo & FILE_INFO_DEVICE)
|
||||
{
|
||||
PDOS_DEVICE_NODE Node = DosGetDriverNode(Descriptor->DevicePointer);
|
||||
|
||||
|
@ -369,7 +369,7 @@ BOOLEAN DosCloseHandle(WORD DosHandle)
|
|||
}
|
||||
else
|
||||
{
|
||||
/* Close the win32 handle */
|
||||
/* Close the Win32 handle */
|
||||
CloseHandle(Descriptor->Win32Handle);
|
||||
}
|
||||
}
|
||||
|
|
Loading…
Reference in a new issue