/* PRIVATE VARIABLES **********************************************************/
-#define INDOS_POINTER MAKELONG(0x00FE, 0x0070)
-
CALLBACK16 DosContext;
-/*static*/ BYTE CurrentDrive;
-static CHAR LastDrive = 'E';
-static CHAR CurrentDirectories[NUM_DRIVES][DOS_DIR_LENGTH];
-static PBYTE InDos;
-
/* PUBLIC VARIABLES ***********************************************************/
+/* Global DOS data area contained in guest memory */
+PDOS_DATA DosData;
+/* Easy accessors to useful DOS data area parts */
PDOS_SYSVARS SysVars;
+PDOS_SDA Sda;
/* Echo state for INT 21h, AH = 01h and AH = 3Fh */
BOOLEAN DoEcho = FALSE;
-DWORD DiskTransferArea;
-WORD DosErrorLevel = 0x0000;
-WORD DosLastError = 0;
-
/* PRIVATE FUNCTIONS **********************************************************/
static BOOLEAN DosChangeDrive(BYTE Drive)
{
- WCHAR DirectoryPath[DOS_CMDLINE_LENGTH];
+ CHAR DirectoryPath[DOS_CMDLINE_LENGTH + 1];
/* Make sure the drive exists */
- if (Drive > (LastDrive - 'A')) return FALSE;
+ if (Drive >= SysVars->NumLocalDrives) return FALSE;
+
+ RtlZeroMemory(DirectoryPath, sizeof(DirectoryPath));
/* Find the path to the new current directory */
- swprintf(DirectoryPath, L"%c\\%S", Drive + 'A', CurrentDirectories[Drive]);
+ snprintf(DirectoryPath,
+ DOS_CMDLINE_LENGTH,
+ "%c:\\%s",
+ 'A' + Drive,
+ DosData->CurrentDirectories[Drive]);
/* Change the current directory of the process */
- if (!SetCurrentDirectory(DirectoryPath)) return FALSE;
+ if (!SetCurrentDirectoryA(DirectoryPath)) return FALSE;
/* Set the current drive */
- CurrentDrive = Drive;
+ Sda->CurrentDrive = Drive;
/* Return success */
return TRUE;
BYTE DriveNumber;
DWORD Attributes;
LPSTR Path;
+ CHAR CurrentDirectory[MAX_PATH];
+ CHAR DosDirectory[DOS_DIR_LENGTH];
/* Make sure the directory path is not too long */
if (strlen(Directory) >= DOS_DIR_LENGTH)
{
- DosLastError = ERROR_PATH_NOT_FOUND;
+ Sda->LastErrorCode = ERROR_PATH_NOT_FOUND;
return FALSE;
}
- /* Get the drive number */
- DriveNumber = Directory[0] - 'A';
+ /* Check whether the directory string is of format "?:..." */
+ if (strlen(Directory) >= 2 && Directory[1] == ':')
+ {
+ /* Get the drive number */
+ DriveNumber = RtlUpperChar(Directory[0]) - 'A';
- /* Make sure the drive exists */
- if (DriveNumber > (LastDrive - 'A'))
+ /* Make sure the drive exists */
+ if (DriveNumber >= SysVars->NumLocalDrives)
+ {
+ Sda->LastErrorCode = ERROR_PATH_NOT_FOUND;
+ return FALSE;
+ }
+ }
+ else
{
- DosLastError = ERROR_PATH_NOT_FOUND;
- return FALSE;
+ /* Keep the current drive number */
+ DriveNumber = Sda->CurrentDrive;
}
/* Get the file attributes */
if ((Attributes == INVALID_FILE_ATTRIBUTES)
|| !(Attributes & FILE_ATTRIBUTE_DIRECTORY))
{
- DosLastError = ERROR_PATH_NOT_FOUND;
+ Sda->LastErrorCode = ERROR_PATH_NOT_FOUND;
return FALSE;
}
/* Check if this is the current drive */
- if (DriveNumber == CurrentDrive)
+ if (DriveNumber == Sda->CurrentDrive)
{
/* Change the directory */
if (!SetCurrentDirectoryA(Directory))
{
- DosLastError = LOWORD(GetLastError());
+ Sda->LastErrorCode = LOWORD(GetLastError());
return FALSE;
}
}
+ /* Get the (possibly new) current directory (needed if we specified a relative directory) */
+ if (!GetCurrentDirectoryA(sizeof(CurrentDirectory), CurrentDirectory))
+ {
+ // TODO: Use some kind of default path?
+ return FALSE;
+ }
+
+ /* Convert it to a DOS path */
+ if (!GetShortPathNameA(CurrentDirectory, DosDirectory, sizeof(DosDirectory)))
+ {
+ // TODO: Use some kind of default path?
+ return FALSE;
+ }
+
/* Get the directory part of the path */
- Path = strchr(Directory, '\\');
+ Path = strchr(DosDirectory, '\\');
if (Path != NULL)
{
/* Skip the backslash */
/* Set the directory for the drive */
if (Path != NULL)
{
- strncpy(CurrentDirectories[DriveNumber], Path, DOS_DIR_LENGTH);
+ strncpy(DosData->CurrentDirectories[DriveNumber], Path, DOS_DIR_LENGTH);
}
else
{
- CurrentDirectories[DriveNumber][0] = '\0';
+ DosData->CurrentDirectories[DriveNumber][0] = '\0';
}
/* Return success */
if (getCF())
{
- DosTerminateProcess(CurrentPsp, 0, 0);
+ DosTerminateProcess(Sda->CurrentPsp, 0, 0);
return TRUE;
}
SYSTEMTIME SystemTime;
PCHAR String;
PDOS_INPUT_BUFFER InputBuffer;
- PDOS_COUNTRY_CODE_BUFFER CountryCodeBuffer;
- INT Return;
- (*InDos)++;
+ Sda->InDos++;
/* Save the value of SS:SP on entry in the PSP */
- SEGMENT_TO_PSP(CurrentPsp)->LastStack =
+ SEGMENT_TO_PSP(Sda->CurrentPsp)->LastStack =
MAKELONG(getSP() + (STACK_FLAGS + 1) * 2, getSS());
/* Check the value in the AH register */
}
if (Character == '\r') break;
+ if (Character == '\b') continue;
Count++; /* Carriage returns are NOT counted */
}
/* Disk Reset */
case 0x0D:
{
- PDOS_PSP PspBlock = SEGMENT_TO_PSP(CurrentPsp);
+ PDOS_PSP PspBlock = SEGMENT_TO_PSP(Sda->CurrentPsp);
// TODO: Flush what's needed.
DPRINT1("INT 21h, 0Dh is UNIMPLEMENTED\n");
case 0x0E:
{
DosChangeDrive(getDL());
- setAL(LastDrive - 'A' + 1);
+ setAL(SysVars->NumLocalDrives);
break;
}
/* Get Default Drive */
case 0x19:
{
- setAL(CurrentDrive);
+ setAL(Sda->CurrentDrive);
break;
}
/* Set Disk Transfer Area */
case 0x1A:
{
- DiskTransferArea = MAKELONG(getDX(), getDS());
+ Sda->DiskTransferArea = MAKELONG(getDX(), getDS());
break;
}
PCHAR FileName = (PCHAR)SEG_OFF_TO_PTR(getDS(), getSI());
PDOS_FCB Fcb = (PDOS_FCB)SEG_OFF_TO_PTR(getES(), getDI());
BYTE Options = getAL();
- INT i;
CHAR FillChar = ' ';
+ UINT i;
if (FileName[1] == ':')
{
else
{
/* No drive number specified */
- if (Options & (1 << 1)) Fcb->DriveNumber = CurrentDrive + 1;
+ if (Options & (1 << 1)) Fcb->DriveNumber = Sda->CurrentDrive + 1;
else Fcb->DriveNumber = 0;
}
/* Get Disk Transfer Area */
case 0x2F:
{
- setES(HIWORD(DiskTransferArea));
- setBX(LOWORD(DiskTransferArea));
+ setES(HIWORD(Sda->DiskTransferArea));
+ setBX(LOWORD(Sda->DiskTransferArea));
break;
}
/* Get DOS Version */
case 0x30:
{
- PDOS_PSP PspBlock = SEGMENT_TO_PSP(CurrentPsp);
+ PDOS_PSP PspBlock = SEGMENT_TO_PSP(Sda->CurrentPsp);
/*
* DOS 2+ - GET DOS VERSION
case 0x31:
{
DPRINT1("Process going resident: %u paragraphs kept\n", getDX());
- DosTerminateProcess(CurrentPsp, getAL(), getDX());
+ DosTerminateProcess(Sda->CurrentPsp, getAL(), getDX());
break;
}
/* Get Address of InDOS flag */
case 0x34:
{
- setES(HIWORD(INDOS_POINTER));
- setBX(LOWORD(INDOS_POINTER));
-
+ setES(DOS_DATA_SEGMENT);
+ setBX(DOS_DATA_OFFSET(Sda.InDos));
break;
}
/* Get Interrupt Vector */
case 0x35:
{
- DWORD FarPointer = ((PDWORD)BaseAddress)[getAL()];
+ ULONG FarPointer = ((PULONG)BaseAddress)[getAL()];
/* Read the address from the IDT into ES:BX */
setES(HIWORD(FarPointer));
/* Get Free Disk Space */
case 0x36:
{
- CHAR RootPath[3] = "X:\\";
+ CHAR RootPath[] = "?:\\";
DWORD SectorsPerCluster;
DWORD BytesPerSector;
DWORD NumberOfFreeClusters;
DWORD TotalNumberOfClusters;
- if (getDL() == 0) RootPath[0] = 'A' + CurrentDrive;
+ if (getDL() == 0x00) RootPath[0] = 'A' + Sda->CurrentDrive;
else RootPath[0] = 'A' + getDL() - 1;
if (GetDiskFreeSpaceA(RootPath,
{
setAX(LOWORD(SectorsPerCluster));
setCX(LOWORD(BytesPerSector));
- setBX(LOWORD(NumberOfFreeClusters));
- setDX(LOWORD(TotalNumberOfClusters));
+ setBX(min(NumberOfFreeClusters, 0xFFFF));
+ setDX(min(TotalNumberOfClusters, 0xFFFF));
}
else
{
/* Get/Set Country-dependent Information */
case 0x38:
{
- CountryCodeBuffer = (PDOS_COUNTRY_CODE_BUFFER)SEG_OFF_TO_PTR(getDS(), getDX());
+ INT Return;
+ PDOS_COUNTRY_CODE_BUFFER CountryCodeBuffer =
+ (PDOS_COUNTRY_CODE_BUFFER)SEG_OFF_TO_PTR(getDS(), getDX());
if (getAL() == 0x00)
{
/* Get */
- Return = GetLocaleInfo(LOCALE_USER_DEFAULT, LOCALE_IDATE,
- &CountryCodeBuffer->TimeFormat,
- sizeof(CountryCodeBuffer->TimeFormat) / sizeof(TCHAR));
+ Return = GetLocaleInfoA(LOCALE_USER_DEFAULT, LOCALE_IDATE,
+ (LPSTR)&CountryCodeBuffer->TimeFormat,
+ sizeof(CountryCodeBuffer->TimeFormat));
if (Return == 0)
{
Stack[STACK_FLAGS] |= EMULATOR_FLAG_CF;
break;
}
- Return = GetLocaleInfo(LOCALE_USER_DEFAULT, LOCALE_SCURRENCY,
- &CountryCodeBuffer->CurrencySymbol,
- sizeof(CountryCodeBuffer->CurrencySymbol) / sizeof(TCHAR));
+ Return = GetLocaleInfoA(LOCALE_USER_DEFAULT, LOCALE_SCURRENCY,
+ (LPSTR)&CountryCodeBuffer->CurrencySymbol,
+ sizeof(CountryCodeBuffer->CurrencySymbol));
if (Return == 0)
{
Stack[STACK_FLAGS] |= EMULATOR_FLAG_CF;
break;
}
- Return = GetLocaleInfo(LOCALE_USER_DEFAULT, LOCALE_STHOUSAND,
- &CountryCodeBuffer->ThousandSep,
- sizeof(CountryCodeBuffer->ThousandSep) / sizeof(TCHAR));
+ Return = GetLocaleInfoA(LOCALE_USER_DEFAULT, LOCALE_STHOUSAND,
+ (LPSTR)&CountryCodeBuffer->ThousandSep,
+ sizeof(CountryCodeBuffer->ThousandSep));
if (Return == 0)
{
Stack[STACK_FLAGS] |= EMULATOR_FLAG_CF;
break;
}
- Return = GetLocaleInfo(LOCALE_USER_DEFAULT, LOCALE_SDECIMAL,
- &CountryCodeBuffer->DecimalSep,
- sizeof(CountryCodeBuffer->DecimalSep) / sizeof(TCHAR));
+ Return = GetLocaleInfoA(LOCALE_USER_DEFAULT, LOCALE_SDECIMAL,
+ (LPSTR)&CountryCodeBuffer->DecimalSep,
+ sizeof(CountryCodeBuffer->DecimalSep));
if (Return == 0)
{
Stack[STACK_FLAGS] |= EMULATOR_FLAG_CF;
else
{
Stack[STACK_FLAGS] |= EMULATOR_FLAG_CF;
- setAX(DosLastError);
+ setAX(Sda->LastErrorCode);
}
break;
else
{
Stack[STACK_FLAGS] |= EMULATOR_FLAG_CF;
- setAX(DosLastError);
+ setAX(Sda->LastErrorCode);
}
break;
else
{
Stack[STACK_FLAGS] |= EMULATOR_FLAG_CF;
- setAX(DosLastError);
+ setAX(Sda->LastErrorCode);
}
break;
/* Get the real drive number */
if (DriveNumber == 0)
{
- DriveNumber = CurrentDrive;
+ DriveNumber = Sda->CurrentDrive;
}
else
{
DriveNumber--;
}
- if (DriveNumber <= LastDrive - 'A')
+ if (DriveNumber < SysVars->NumLocalDrives)
{
/*
* Copy the current directory into the target buffer.
* It doesn't contain the drive letter and the backslash.
*/
- strncpy(String, CurrentDirectories[DriveNumber], DOS_DIR_LENGTH);
+ strncpy(String, DosData->CurrentDirectories[DriveNumber], DOS_DIR_LENGTH);
Stack[STACK_FLAGS] &= ~EMULATOR_FLAG_CF;
setAX(0x0100); // Undocumented, see Ralf Brown: http://www.ctyme.com/intr/rb-2933.htm
}
else
{
Stack[STACK_FLAGS] |= EMULATOR_FLAG_CF;
- setAX(DosLastError);
+ setAX(Sda->LastErrorCode);
setBX(MaxAvailable);
}
else
{
Stack[STACK_FLAGS] |= EMULATOR_FLAG_CF;
- setAX(DosLastError);
+ setAX(Sda->LastErrorCode);
setBX(Size);
}
BYTE OrgAL = getAL();
LPSTR ProgramName = SEG_OFF_TO_PTR(getDS(), getDX());
PDOS_EXEC_PARAM_BLOCK ParamBlock = SEG_OFF_TO_PTR(getES(), getBX());
- DWORD ReturnAddress = MAKELONG(Stack[STACK_IP], Stack[STACK_CS]);
WORD ErrorCode;
if (OrgAL <= DOS_LOAD_OVERLAY)
if (LoadType == DOS_LOAD_AND_EXECUTE)
{
/* Create a new process */
- ErrorCode = DosCreateProcess(ProgramName,
- ParamBlock,
- ReturnAddress);
+ ErrorCode = DosCreateProcess(ProgramName, ParamBlock);
}
else
#endif
ProgramName,
ParamBlock,
NULL,
- NULL,
- ReturnAddress);
+ NULL);
}
}
else if (OrgAL == 0x05)
/* Terminate With Return Code */
case 0x4C:
{
- DosTerminateProcess(CurrentPsp, getAL(), 0);
+ DosTerminateProcess(Sda->CurrentPsp, getAL(), 0);
break;
}
* DosErrorLevel is cleared after being read by this function.
*/
Stack[STACK_FLAGS] &= ~EMULATOR_FLAG_CF;
- setAX(DosErrorLevel);
- DosErrorLevel = 0x0000; // Clear it
+ setAX(Sda->ErrorLevel);
+ Sda->ErrorLevel = 0x0000; // Clear it
break;
}
/* Find First File */
case 0x4E:
{
- WORD Result = (WORD)demFileFindFirst(FAR_POINTER(DiskTransferArea),
+ WORD Result = (WORD)demFileFindFirst(FAR_POINTER(Sda->DiskTransferArea),
SEG_OFF_TO_PTR(getDS(), getDX()),
getCX());
/* Find Next File */
case 0x4F:
{
- WORD Result = (WORD)demFileFindNext(FAR_POINTER(DiskTransferArea));
+ WORD Result = (WORD)demFileFindNext(FAR_POINTER(Sda->DiskTransferArea));
setAX(Result);
* and http://www.ctyme.com/intr/rb-3140.htm
* for more information.
*/
- setBX(CurrentPsp);
+ setBX(Sda->CurrentPsp);
break;
}
/* Return the DOS "list of lists" in ES:BX */
setES(DOS_DATA_SEGMENT);
- setBX(FIELD_OFFSET(DOS_SYSVARS, FirstDpb));
+ setBX(DOS_DATA_OFFSET(SysVars.FirstDpb));
break;
}
{
/* Get allocation strategy */
Stack[STACK_FLAGS] &= ~EMULATOR_FLAG_CF;
- setAX(DosAllocStrategy);
+ setAX(Sda->AllocStrategy);
}
else if (getAL() == 0x01)
{
break;
}
- DosAllocStrategy = getBL();
+ Sda->AllocStrategy = getBL();
Stack[STACK_FLAGS] &= ~EMULATOR_FLAG_CF;
}
else if (getAL() == 0x02)
if (getAL() == 0x00)
{
/* Lock region of file */
- if (DosLockFile(getBX(), MAKELONG(getCX(), getDX()), MAKELONG(getSI(), getDI())))
+ if (DosLockFile(getBX(), MAKELONG(getDX(), getCX()), MAKELONG(getDI(), getSI())))
{
Stack[STACK_FLAGS] &= ~EMULATOR_FLAG_CF;
}
else
{
Stack[STACK_FLAGS] |= EMULATOR_FLAG_CF;
- setAX(DosLastError);
+ setAX(Sda->LastErrorCode);
}
}
else if (getAL() == 0x01)
{
/* Unlock region of file */
- if (DosUnlockFile(getBX(), MAKELONG(getCX(), getDX()), MAKELONG(getSI(), getDI())))
+ if (DosUnlockFile(getBX(), MAKELONG(getDX(), getCX()), MAKELONG(getDI(), getSI())))
{
Stack[STACK_FLAGS] &= ~EMULATOR_FLAG_CF;
}
else
{
Stack[STACK_FLAGS] |= EMULATOR_FLAG_CF;
- setAX(DosLastError);
+ setAX(Sda->LastErrorCode);
}
}
else
break;
}
+ /* Miscellaneous Internal Functions */
+ case 0x5D:
+ {
+ switch (getAL())
+ {
+ /* Get Swappable Data Area */
+ case 0x06:
+ {
+ setDS(DOS_DATA_SEGMENT);
+ setSI(DOS_DATA_OFFSET(Sda.ErrorMode));
+ setCX(sizeof(DOS_SDA));
+ setDX(FIELD_OFFSET(DOS_SDA, LastAX));
+
+ Stack[STACK_FLAGS] &= ~EMULATOR_FLAG_CF;
+ break;
+ }
+
+ default:
+ {
+ DPRINT1("INT 21h, AH = 5Dh, subfunction AL = %Xh NOT IMPLEMENTED\n",
+ getAL());
+ }
+ }
+
+ break;
+ }
+
/* Set Handle Count */
case 0x67:
{
if (!DosResizeHandleTable(getBX()))
{
Stack[STACK_FLAGS] |= EMULATOR_FLAG_CF;
- setAX(DosLastError);
+ setAX(Sda->LastErrorCode);
}
else Stack[STACK_FLAGS] &= ~EMULATOR_FLAG_CF;
}
}
- (*InDos)--;
+ Sda->InDos--;
}
VOID WINAPI DosBreakInterrupt(LPWORD Stack)
Stack[STACK_FLAGS] |= EMULATOR_FLAG_CF;
}
+VOID WINAPI DosAbsoluteRead(LPWORD Stack)
+{
+ /*
+ * This call should leave the flags on the stack for some reason,
+ * so move the stack by one word.
+ */
+ Stack[STACK_INT_NUM] = Stack[STACK_IP];
+ Stack[STACK_IP] = Stack[STACK_CS];
+ Stack[STACK_CS] = Stack[STACK_FLAGS];
+ setSP(LOWORD(getSP() - 2));
+
+ // TODO: NOT IMPLEMENTED;
+ UNIMPLEMENTED;
+
+ /* General failure */
+ setAX(0x800C);
+ Stack[STACK_FLAGS - 1] |= EMULATOR_FLAG_CF;
+}
+
+VOID WINAPI DosAbsoluteWrite(LPWORD Stack)
+{
+ /*
+ * This call should leave the flags on the stack for some reason,
+ * so move the stack by one word.
+ */
+ Stack[STACK_INT_NUM] = Stack[STACK_IP];
+ Stack[STACK_IP] = Stack[STACK_CS];
+ Stack[STACK_CS] = Stack[STACK_FLAGS];
+ setSP(LOWORD(getSP() - 2));
+
+ // TODO: NOT IMPLEMENTED;
+ UNIMPLEMENTED;
+
+ /* General failure */
+ setAX(0x800C);
+ Stack[STACK_FLAGS - 1] |= EMULATOR_FLAG_CF;
+}
+
VOID WINAPI DosInt27h(LPWORD Stack)
{
DosTerminateProcess(getCS(), 0, (getDX() + 0x0F) >> 4);
}
+VOID WINAPI DosIdle(LPWORD Stack)
+{
+ /*
+ * This will set the carry flag on the first call (to repeat the BOP),
+ * and clear it in the next, so that exactly one HLT occurs.
+ */
+ setCF(!getCF());
+}
+
VOID WINAPI DosFastConOut(LPWORD Stack)
{
/*
break;
}
-
+
default:
{
DPRINT1("DOS Internal System Function INT 0x2F, AH = %xh, AL = %xh NOT IMPLEMENTED!\n",
#if 1
UCHAR i;
+ PDOS_SFT Sft;
+ LPSTR Path;
CHAR CurrentDirectory[MAX_PATH];
CHAR DosDirectory[DOS_DIR_LENGTH];
- LPSTR Path;
- PDOS_SFT Sft;
const BYTE NullDriverRoutine[] = {
/* Strategy routine entry */
FILE *Stream;
WCHAR Buffer[256];
- /* Setup the InDOS flag */
- InDos = (PBYTE)FAR_POINTER(INDOS_POINTER);
- *InDos = 0;
+ /* Initialize the global DOS data area */
+ DosData = (PDOS_DATA)SEG_OFF_TO_PTR(DOS_DATA_SEGMENT, 0x0000);
+ RtlZeroMemory(DosData, sizeof(*DosData));
+
+ /* Initialize the list of lists */
+ SysVars = &DosData->SysVars;
+ RtlZeroMemory(SysVars, sizeof(*SysVars));
+ SysVars->FirstMcb = FIRST_MCB_SEGMENT;
+ SysVars->FirstSft = MAKELONG(DOS_DATA_OFFSET(Sft), DOS_DATA_SEGMENT);
+ SysVars->CurrentDirs = MAKELONG(DOS_DATA_OFFSET(CurrentDirectories),
+ DOS_DATA_SEGMENT);
+ /* The last drive can be redefined with the LASTDRIVE command. At the moment, set the real maximum possible, 'Z'. */
+ SysVars->NumLocalDrives = 'Z' - 'A' + 1;
+
+ /* Initialize the NUL device driver */
+ SysVars->NullDevice.Link = 0xFFFFFFFF;
+ SysVars->NullDevice.DeviceAttributes = DOS_DEVATTR_NUL | DOS_DEVATTR_CHARACTER;
+ SysVars->NullDevice.StrategyRoutine = FIELD_OFFSET(DOS_SYSVARS, NullDriverRoutine);
+ SysVars->NullDevice.InterruptRoutine = SysVars->NullDevice.StrategyRoutine + 6;
+ RtlFillMemory(SysVars->NullDevice.DeviceName,
+ sizeof(SysVars->NullDevice.DeviceName),
+ ' ');
+ RtlCopyMemory(SysVars->NullDevice.DeviceName, "NUL", strlen("NUL"));
+ RtlCopyMemory(SysVars->NullDriverRoutine,
+ NullDriverRoutine,
+ sizeof(NullDriverRoutine));
- /* Clear the current directory buffer */
- RtlZeroMemory(CurrentDirectories, sizeof(CurrentDirectories));
+ /* Initialize the swappable data area */
+ Sda = &DosData->Sda;
+ RtlZeroMemory(Sda, sizeof(*Sda));
/* Get the current directory */
- if (!GetCurrentDirectoryA(MAX_PATH, CurrentDirectory))
+ if (!GetCurrentDirectoryA(sizeof(CurrentDirectory), CurrentDirectory))
{
// TODO: Use some kind of default path?
return FALSE;
}
- /* Convert that to a DOS path */
- if (!GetShortPathNameA(CurrentDirectory, DosDirectory, DOS_DIR_LENGTH))
+ /* Convert it to a DOS path */
+ if (!GetShortPathNameA(CurrentDirectory, DosDirectory, sizeof(DosDirectory)))
{
// TODO: Use some kind of default path?
return FALSE;
}
/* Set the drive */
- CurrentDrive = DosDirectory[0] - 'A';
+ Sda->CurrentDrive = RtlUpperChar(DosDirectory[0]) - 'A';
/* Get the directory part of the path */
Path = strchr(DosDirectory, '\\');
/* Set the directory */
if (Path != NULL)
{
- strncpy(CurrentDirectories[CurrentDrive], Path, DOS_DIR_LENGTH);
+ strncpy(DosData->CurrentDirectories[Sda->CurrentDrive], Path, DOS_DIR_LENGTH);
}
- /* Read CONFIG.SYS */
- Stream = _wfopen(DOS_CONFIG_PATH, L"r");
- if (Stream != NULL)
- {
- while (fgetws(Buffer, 256, Stream))
- {
- // TODO: Parse the line
- }
- fclose(Stream);
- }
-
- /* Initialize the list of lists */
- SysVars = (PDOS_SYSVARS)SEG_OFF_TO_PTR(DOS_DATA_SEGMENT, 0);
- RtlZeroMemory(SysVars, sizeof(DOS_SYSVARS));
- SysVars->FirstMcb = FIRST_MCB_SEGMENT;
- SysVars->FirstSft = MAKELONG(MASTER_SFT_OFFSET, DOS_DATA_SEGMENT);
+ /* Set the current PSP to the system PSP */
+ Sda->CurrentPsp = SYSTEM_PSP;
- /* Initialize the NUL device driver */
- SysVars->NullDevice.Link = 0xFFFFFFFF;
- SysVars->NullDevice.DeviceAttributes = DOS_DEVATTR_NUL | DOS_DEVATTR_CHARACTER;
- SysVars->NullDevice.StrategyRoutine = FIELD_OFFSET(DOS_SYSVARS, NullDriverRoutine);
- SysVars->NullDevice.InterruptRoutine = SysVars->NullDevice.StrategyRoutine + 6;
- RtlFillMemory(SysVars->NullDevice.DeviceName,
- sizeof(SysVars->NullDevice.DeviceName),
- ' ');
- RtlCopyMemory(SysVars->NullDevice.DeviceName, "NUL", strlen("NUL"));
- RtlCopyMemory(SysVars->NullDriverRoutine,
- NullDriverRoutine,
- sizeof(NullDriverRoutine));
+ /* Set the initial allocation strategy to "best fit" */
+ Sda->AllocStrategy = DOS_ALLOC_BEST_FIT;
/* Initialize the SFT */
Sft = (PDOS_SFT)FAR_POINTER(SysVars->FirstSft);
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 the callback context */
- InitializeContext(&DosContext, 0x0070, 0x0000);
+ InitializeContext(&DosContext, DOS_CODE_SEGMENT, 0x0000);
/* Register the DOS 32-bit Interrupts */
RegisterDosInt32(0x20, DosInt20h );
// RegisterDosInt32(0x22, DosInt22h ); // Termination
RegisterDosInt32(0x23, DosBreakInterrupt); // Ctrl-C / Ctrl-Break
// RegisterDosInt32(0x24, DosInt24h ); // Critical Error
+ RegisterDosInt32(0x25, DosAbsoluteRead ); // Absolute Disk Read
+ RegisterDosInt32(0x26, DosAbsoluteWrite ); // Absolute Disk Write
RegisterDosInt32(0x27, DosInt27h ); // Terminate and Stay Resident
+ RegisterDosInt32(0x28, DosIdle ); // DOS Idle Interrupt
RegisterDosInt32(0x29, DosFastConOut ); // DOS 2+ Fast Console Output
RegisterDosInt32(0x2F, DosInt2Fh );
+ /* Unimplemented DOS interrupts */
+ RegisterDosInt32(0x2A, NULL); // Network - Installation Check
+
+ /* Load the CON driver */
+ ConDrvInitialize();
+
+ /* Load the XMS driver (HIMEM) */
+ XmsInitialize();
+
/* Load the EMS driver */
if (!EmsDrvInitialize(EMS_TOTAL_PAGES))
{
"Try reducing the number of EMS pages.\n");
}
- /* Load the XMS driver (HIMEM) */
- XmsInitialize();
-
- /* Load the CON driver */
- ConDrvInitialize();
-
return TRUE;
}