CALLBACK16 DosContext;
-/*static*/ BYTE CurrentDrive;
-static CHAR LastDrive = 'E';
+/*static*/ BYTE CurrentDrive = 0x00;
+static CHAR LastDrive = 'Z'; // The last drive can be redefined with the LASTDRIVE command. At the moment, set the real maximum possible, 'Z'.
static CHAR CurrentDirectories[NUM_DRIVES][DOS_DIR_LENGTH];
static PBYTE InDos;
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)
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 > (LastDrive - 'A'))
+ {
+ DosLastError = ERROR_PATH_NOT_FOUND;
+ return FALSE;
+ }
+ }
+ else
{
- DosLastError = ERROR_PATH_NOT_FOUND;
- return FALSE;
+ /* Keep the current drive number */
+ DriveNumber = CurrentDrive;
}
/* Get the file attributes */
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 */
(*InDos)++;
+ /* Save the value of SS:SP on entry in the PSP */
+ SEGMENT_TO_PSP(CurrentPsp)->LastStack =
+ MAKELONG(getSP() + (STACK_FLAGS + 1) * 2, getSS());
+
/* Check the value in the AH register */
switch (getAH())
{
}
if (Character == '\r') break;
+ if (Character == '\b') continue;
Count++; /* Carriage returns are NOT counted */
}
{
setES(HIWORD(INDOS_POINTER));
setBX(LOWORD(INDOS_POINTER));
-
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[3] = "?:\\";
DWORD SectorsPerCluster;
DWORD BytesPerSector;
DWORD NumberOfFreeClusters;
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)
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 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;
}
Stack[STACK_FLAGS] |= EMULATOR_FLAG_CF;
}
+VOID WINAPI DosInt27h(LPWORD Stack)
+{
+ DosTerminateProcess(getCS(), 0, (getDX() + 0x0F) >> 4);
+}
+
VOID WINAPI DosFastConOut(LPWORD Stack)
{
/*
#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 */
RtlZeroMemory(CurrentDirectories, sizeof(CurrentDirectories));
/* 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';
+ CurrentDrive = RtlUpperChar(DosDirectory[0]) - 'A';
/* Get the directory part of the path */
Path = strchr(DosDirectory, '\\');
#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(0x27, DosInt27h ); // Terminate and Stay Resident
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;
}