Author: hbelusca
Date: Sat Aug 1 12:41:22 2015
New Revision: 68585
URL: http://svn.reactos.org/svn/reactos?rev=68585&view=rev
Log:
[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.
Modified:
trunk/reactos/subsystems/mvdm/ntvdm/dos/dos32krnl/bios.c
trunk/reactos/subsystems/mvdm/ntvdm/dos/dos32krnl/dos.c
trunk/reactos/subsystems/mvdm/ntvdm/dos/dos32krnl/dos.h
trunk/reactos/subsystems/mvdm/ntvdm/dos/dos32krnl/dosfiles.h
trunk/reactos/subsystems/mvdm/ntvdm/dos/dos32krnl/handle.c
Modified: trunk/reactos/subsystems/mvdm/ntvdm/dos/dos32krnl/bios.c
URL: http://svn.reactos.org/svn/reactos/trunk/reactos/subsystems/mvdm/ntvdm/dos/…
==============================================================================
--- trunk/reactos/subsystems/mvdm/ntvdm/dos/dos32krnl/bios.c [iso-8859-1] (original)
+++ trunk/reactos/subsystems/mvdm/ntvdm/dos/dos32krnl/bios.c [iso-8859-1] Sat Aug 1 12:41:22 2015
@@ -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 @@
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 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);
-
- /* 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!
+ setDS(BIOS_DATA_SEGMENT);
+
+ /* 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 @@
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 @@
fclose(Stream);
}
-#endif
-
- /* Initialize the DOS kernel */
- return DosKRNLInitialize();
+ return TRUE;
}
/* EOF */
Modified: trunk/reactos/subsystems/mvdm/ntvdm/dos/dos32krnl/dos.c
URL: http://svn.reactos.org/svn/reactos/trunk/reactos/subsystems/mvdm/ntvdm/dos/…
==============================================================================
--- trunk/reactos/subsystems/mvdm/ntvdm/dos/dos32krnl/dos.c [iso-8859-1] (original)
+++ trunk/reactos/subsystems/mvdm/ntvdm/dos/dos32krnl/dos.c [iso-8859-1] Sat Aug 1 12:41:22 2015
@@ -191,7 +191,6 @@
BYTE Character;
SYSTEMTIME SystemTime;
PCHAR String;
- PDOS_INPUT_BUFFER InputBuffer;
Sda->InDos++;
@@ -351,7 +350,7 @@
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 @@
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 @@
BOOLEAN DosKRNLInitialize(VOID)
{
-#if 1
-
UCHAR i;
PDOS_SFT Sft;
LPSTR Path;
@@ -2281,7 +2278,8 @@
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,12 +2292,16 @@
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;
@@ -2409,18 +2411,8 @@
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 @@
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();
Modified: trunk/reactos/subsystems/mvdm/ntvdm/dos/dos32krnl/dos.h
URL: http://svn.reactos.org/svn/reactos/trunk/reactos/subsystems/mvdm/ntvdm/dos/…
==============================================================================
--- trunk/reactos/subsystems/mvdm/ntvdm/dos/dos32krnl/dos.h [iso-8859-1] (original)
+++ trunk/reactos/subsystems/mvdm/ntvdm/dos/dos32krnl/dos.h [iso-8859-1] Sat Aug 1 12:41:22 2015
@@ -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 @@
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 @@
* 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
-
- 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;
+ BYTE Padding0[0xB0 - /*FIELD_OFFSET(BIOS_DATA, StartupCode)*/ 20];
+ DWORD RomBiosInt13; // 0xb0
+ DWORD PrevInt13; // 0xb4
+ BYTE Padding1[0x100 - 0xB8]; // 0xb8
+} BIOS_DATA, *PBIOS_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 @@
/* 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);
/*
Modified: trunk/reactos/subsystems/mvdm/ntvdm/dos/dos32krnl/dosfiles.h
URL: http://svn.reactos.org/svn/reactos/trunk/reactos/subsystems/mvdm/ntvdm/dos/…
==============================================================================
--- trunk/reactos/subsystems/mvdm/ntvdm/dos/dos32krnl/dosfiles.h [iso-8859-1] (original)
+++ trunk/reactos/subsystems/mvdm/ntvdm/dos/dos32krnl/dosfiles.h [iso-8859-1] Sat Aug 1 12:41:22 2015
@@ -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;
Modified: trunk/reactos/subsystems/mvdm/ntvdm/dos/dos32krnl/handle.c
URL: http://svn.reactos.org/svn/reactos/trunk/reactos/subsystems/mvdm/ntvdm/dos/…
==============================================================================
--- trunk/reactos/subsystems/mvdm/ntvdm/dos/dos32krnl/handle.c [iso-8859-1] (original)
+++ trunk/reactos/subsystems/mvdm/ntvdm/dos/dos32krnl/handle.c [iso-8859-1] Sat Aug 1 12:41:22 2015
@@ -360,7 +360,7 @@
/* 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 @@
}
else
{
- /* Close the win32 handle */
+ /* Close the Win32 handle */
CloseHandle(Descriptor->Win32Handle);
}
}