mirror of
https://github.com/reactos/reactos.git
synced 2025-08-05 19:52:56 +00:00
[NTVDM]
Move various private DOS variables into the Swappable Data Area. It's still mostly unused though. svn path=/trunk/; revision=67649
This commit is contained in:
parent
f1bf14da62
commit
e4960b02d3
8 changed files with 270 additions and 114 deletions
|
@ -43,16 +43,18 @@
|
||||||
|
|
||||||
CHAR DosReadCharacter(WORD FileHandle)
|
CHAR DosReadCharacter(WORD FileHandle)
|
||||||
{
|
{
|
||||||
PCHAR Character = (PCHAR)FAR_POINTER(CHARACTER_ADDRESS);
|
|
||||||
WORD BytesRead;
|
WORD BytesRead;
|
||||||
|
|
||||||
*Character = '\0';
|
Sda->ByteBuffer = '\0';
|
||||||
DPRINT("DosReadCharacter\n");
|
DPRINT("DosReadCharacter\n");
|
||||||
|
|
||||||
/* Use the file reading function */
|
/* Use the file reading function */
|
||||||
DosReadFile(FileHandle, CHARACTER_ADDRESS, 1, &BytesRead);
|
DosReadFile(FileHandle,
|
||||||
|
MAKELONG(DOS_DATA_OFFSET(Sda.ByteBuffer), DOS_DATA_SEGMENT),
|
||||||
|
1,
|
||||||
|
&BytesRead);
|
||||||
|
|
||||||
return *Character;
|
return Sda->ByteBuffer;
|
||||||
}
|
}
|
||||||
|
|
||||||
BOOLEAN DosCheckInput(VOID)
|
BOOLEAN DosCheckInput(VOID)
|
||||||
|
@ -62,7 +64,7 @@ BOOLEAN DosCheckInput(VOID)
|
||||||
if (Descriptor == NULL)
|
if (Descriptor == NULL)
|
||||||
{
|
{
|
||||||
/* Invalid handle */
|
/* Invalid handle */
|
||||||
DosLastError = ERROR_INVALID_HANDLE; // ERROR_FILE_NOT_FOUND
|
Sda->LastErrorCode = ERROR_INVALID_HANDLE; // ERROR_FILE_NOT_FOUND
|
||||||
return FALSE;
|
return FALSE;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -90,10 +92,14 @@ BOOLEAN DosCheckInput(VOID)
|
||||||
VOID DosPrintCharacter(WORD FileHandle, CHAR Character)
|
VOID DosPrintCharacter(WORD FileHandle, CHAR Character)
|
||||||
{
|
{
|
||||||
WORD BytesWritten;
|
WORD BytesWritten;
|
||||||
*((PCHAR)FAR_POINTER(CHARACTER_ADDRESS)) = Character;
|
|
||||||
|
Sda->ByteBuffer = Character;
|
||||||
|
|
||||||
/* Use the file writing function */
|
/* Use the file writing function */
|
||||||
DosWriteFile(FileHandle, CHARACTER_ADDRESS, 1, &BytesWritten);
|
DosWriteFile(FileHandle,
|
||||||
|
MAKELONG(DOS_DATA_OFFSET(Sda.ByteBuffer), DOS_DATA_SEGMENT),
|
||||||
|
1,
|
||||||
|
&BytesWritten);
|
||||||
}
|
}
|
||||||
|
|
||||||
BOOLEAN DosBIOSInitialize(VOID)
|
BOOLEAN DosBIOSInitialize(VOID)
|
||||||
|
|
|
@ -587,7 +587,7 @@ DWORD DosLoadDriver(LPCSTR DriverFile)
|
||||||
Segment = DosAllocateMemory(FileSize >> 4, NULL);
|
Segment = DosAllocateMemory(FileSize >> 4, NULL);
|
||||||
if (Segment == 0)
|
if (Segment == 0)
|
||||||
{
|
{
|
||||||
Result = DosLastError;
|
Result = Sda->LastErrorCode;
|
||||||
goto Cleanup;
|
goto Cleanup;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -34,26 +34,20 @@
|
||||||
|
|
||||||
/* PRIVATE VARIABLES **********************************************************/
|
/* PRIVATE VARIABLES **********************************************************/
|
||||||
|
|
||||||
#define INDOS_POINTER MAKELONG(0x00FE, 0x0070)
|
|
||||||
|
|
||||||
CALLBACK16 DosContext;
|
CALLBACK16 DosContext;
|
||||||
|
|
||||||
/*static*/ BYTE CurrentDrive = 0x00;
|
/*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 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 PCHAR CurrentDirectories;
|
||||||
static PBYTE InDos;
|
|
||||||
|
|
||||||
/* PUBLIC VARIABLES ***********************************************************/
|
/* PUBLIC VARIABLES ***********************************************************/
|
||||||
|
|
||||||
PDOS_SYSVARS SysVars;
|
PDOS_SYSVARS SysVars;
|
||||||
|
PDOS_SDA Sda;
|
||||||
|
|
||||||
/* Echo state for INT 21h, AH = 01h and AH = 3Fh */
|
/* Echo state for INT 21h, AH = 01h and AH = 3Fh */
|
||||||
BOOLEAN DoEcho = FALSE;
|
BOOLEAN DoEcho = FALSE;
|
||||||
|
|
||||||
DWORD DiskTransferArea;
|
|
||||||
WORD DosErrorLevel = 0x0000;
|
|
||||||
WORD DosLastError = 0;
|
|
||||||
|
|
||||||
/* PRIVATE FUNCTIONS **********************************************************/
|
/* PRIVATE FUNCTIONS **********************************************************/
|
||||||
|
|
||||||
static BOOLEAN DosChangeDrive(BYTE Drive)
|
static BOOLEAN DosChangeDrive(BYTE Drive)
|
||||||
|
@ -64,7 +58,7 @@ static BOOLEAN DosChangeDrive(BYTE Drive)
|
||||||
if (Drive > (LastDrive - 'A')) return FALSE;
|
if (Drive > (LastDrive - 'A')) return FALSE;
|
||||||
|
|
||||||
/* Find the path to the new current directory */
|
/* Find the path to the new current directory */
|
||||||
swprintf(DirectoryPath, L"%c\\%S", Drive + 'A', CurrentDirectories[Drive]);
|
swprintf(DirectoryPath, L"%c\\%S", Drive + 'A', &CurrentDirectories[Drive * DOS_DIR_LENGTH]);
|
||||||
|
|
||||||
/* Change the current directory of the process */
|
/* Change the current directory of the process */
|
||||||
if (!SetCurrentDirectory(DirectoryPath)) return FALSE;
|
if (!SetCurrentDirectory(DirectoryPath)) return FALSE;
|
||||||
|
@ -87,7 +81,7 @@ static BOOLEAN DosChangeDirectory(LPSTR Directory)
|
||||||
/* Make sure the directory path is not too long */
|
/* Make sure the directory path is not too long */
|
||||||
if (strlen(Directory) >= DOS_DIR_LENGTH)
|
if (strlen(Directory) >= DOS_DIR_LENGTH)
|
||||||
{
|
{
|
||||||
DosLastError = ERROR_PATH_NOT_FOUND;
|
Sda->LastErrorCode = ERROR_PATH_NOT_FOUND;
|
||||||
return FALSE;
|
return FALSE;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -100,7 +94,7 @@ static BOOLEAN DosChangeDirectory(LPSTR Directory)
|
||||||
/* Make sure the drive exists */
|
/* Make sure the drive exists */
|
||||||
if (DriveNumber > (LastDrive - 'A'))
|
if (DriveNumber > (LastDrive - 'A'))
|
||||||
{
|
{
|
||||||
DosLastError = ERROR_PATH_NOT_FOUND;
|
Sda->LastErrorCode = ERROR_PATH_NOT_FOUND;
|
||||||
return FALSE;
|
return FALSE;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -117,7 +111,7 @@ static BOOLEAN DosChangeDirectory(LPSTR Directory)
|
||||||
if ((Attributes == INVALID_FILE_ATTRIBUTES)
|
if ((Attributes == INVALID_FILE_ATTRIBUTES)
|
||||||
|| !(Attributes & FILE_ATTRIBUTE_DIRECTORY))
|
|| !(Attributes & FILE_ATTRIBUTE_DIRECTORY))
|
||||||
{
|
{
|
||||||
DosLastError = ERROR_PATH_NOT_FOUND;
|
Sda->LastErrorCode = ERROR_PATH_NOT_FOUND;
|
||||||
return FALSE;
|
return FALSE;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -127,7 +121,7 @@ static BOOLEAN DosChangeDirectory(LPSTR Directory)
|
||||||
/* Change the directory */
|
/* Change the directory */
|
||||||
if (!SetCurrentDirectoryA(Directory))
|
if (!SetCurrentDirectoryA(Directory))
|
||||||
{
|
{
|
||||||
DosLastError = LOWORD(GetLastError());
|
Sda->LastErrorCode = LOWORD(GetLastError());
|
||||||
return FALSE;
|
return FALSE;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -157,11 +151,11 @@ static BOOLEAN DosChangeDirectory(LPSTR Directory)
|
||||||
/* Set the directory for the drive */
|
/* Set the directory for the drive */
|
||||||
if (Path != NULL)
|
if (Path != NULL)
|
||||||
{
|
{
|
||||||
strncpy(CurrentDirectories[DriveNumber], Path, DOS_DIR_LENGTH);
|
strncpy(&CurrentDirectories[DriveNumber * DOS_DIR_LENGTH], Path, DOS_DIR_LENGTH);
|
||||||
}
|
}
|
||||||
else
|
else
|
||||||
{
|
{
|
||||||
CurrentDirectories[DriveNumber][0] = '\0';
|
CurrentDirectories[DriveNumber * DOS_DIR_LENGTH] = '\0';
|
||||||
}
|
}
|
||||||
|
|
||||||
/* Return success */
|
/* Return success */
|
||||||
|
@ -177,7 +171,7 @@ static BOOLEAN DosControlBreak(VOID)
|
||||||
|
|
||||||
if (getCF())
|
if (getCF())
|
||||||
{
|
{
|
||||||
DosTerminateProcess(CurrentPsp, 0, 0);
|
DosTerminateProcess(Sda->CurrentPsp, 0, 0);
|
||||||
return TRUE;
|
return TRUE;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -201,10 +195,10 @@ VOID WINAPI DosInt21h(LPWORD Stack)
|
||||||
PDOS_COUNTRY_CODE_BUFFER CountryCodeBuffer;
|
PDOS_COUNTRY_CODE_BUFFER CountryCodeBuffer;
|
||||||
INT Return;
|
INT Return;
|
||||||
|
|
||||||
(*InDos)++;
|
Sda->InDos++;
|
||||||
|
|
||||||
/* Save the value of SS:SP on entry in the PSP */
|
/* 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());
|
MAKELONG(getSP() + (STACK_FLAGS + 1) * 2, getSS());
|
||||||
|
|
||||||
/* Check the value in the AH register */
|
/* Check the value in the AH register */
|
||||||
|
@ -471,7 +465,7 @@ VOID WINAPI DosInt21h(LPWORD Stack)
|
||||||
/* Disk Reset */
|
/* Disk Reset */
|
||||||
case 0x0D:
|
case 0x0D:
|
||||||
{
|
{
|
||||||
PDOS_PSP PspBlock = SEGMENT_TO_PSP(CurrentPsp);
|
PDOS_PSP PspBlock = SEGMENT_TO_PSP(Sda->CurrentPsp);
|
||||||
|
|
||||||
// TODO: Flush what's needed.
|
// TODO: Flush what's needed.
|
||||||
DPRINT1("INT 21h, 0Dh is UNIMPLEMENTED\n");
|
DPRINT1("INT 21h, 0Dh is UNIMPLEMENTED\n");
|
||||||
|
@ -517,7 +511,7 @@ VOID WINAPI DosInt21h(LPWORD Stack)
|
||||||
/* Set Disk Transfer Area */
|
/* Set Disk Transfer Area */
|
||||||
case 0x1A:
|
case 0x1A:
|
||||||
{
|
{
|
||||||
DiskTransferArea = MAKELONG(getDX(), getDS());
|
Sda->DiskTransferArea = MAKELONG(getDX(), getDS());
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -697,15 +691,15 @@ VOID WINAPI DosInt21h(LPWORD Stack)
|
||||||
/* Get Disk Transfer Area */
|
/* Get Disk Transfer Area */
|
||||||
case 0x2F:
|
case 0x2F:
|
||||||
{
|
{
|
||||||
setES(HIWORD(DiskTransferArea));
|
setES(HIWORD(Sda->DiskTransferArea));
|
||||||
setBX(LOWORD(DiskTransferArea));
|
setBX(LOWORD(Sda->DiskTransferArea));
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
|
|
||||||
/* Get DOS Version */
|
/* Get DOS Version */
|
||||||
case 0x30:
|
case 0x30:
|
||||||
{
|
{
|
||||||
PDOS_PSP PspBlock = SEGMENT_TO_PSP(CurrentPsp);
|
PDOS_PSP PspBlock = SEGMENT_TO_PSP(Sda->CurrentPsp);
|
||||||
|
|
||||||
/*
|
/*
|
||||||
* DOS 2+ - GET DOS VERSION
|
* DOS 2+ - GET DOS VERSION
|
||||||
|
@ -751,7 +745,7 @@ VOID WINAPI DosInt21h(LPWORD Stack)
|
||||||
case 0x31:
|
case 0x31:
|
||||||
{
|
{
|
||||||
DPRINT1("Process going resident: %u paragraphs kept\n", getDX());
|
DPRINT1("Process going resident: %u paragraphs kept\n", getDX());
|
||||||
DosTerminateProcess(CurrentPsp, getAL(), getDX());
|
DosTerminateProcess(Sda->CurrentPsp, getAL(), getDX());
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -792,8 +786,8 @@ VOID WINAPI DosInt21h(LPWORD Stack)
|
||||||
/* Get Address of InDOS flag */
|
/* Get Address of InDOS flag */
|
||||||
case 0x34:
|
case 0x34:
|
||||||
{
|
{
|
||||||
setES(HIWORD(INDOS_POINTER));
|
setES(DOS_DATA_SEGMENT);
|
||||||
setBX(LOWORD(INDOS_POINTER));
|
setBX(DOS_DATA_OFFSET(Sda.InDos));
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -1002,7 +996,7 @@ VOID WINAPI DosInt21h(LPWORD Stack)
|
||||||
else
|
else
|
||||||
{
|
{
|
||||||
Stack[STACK_FLAGS] |= EMULATOR_FLAG_CF;
|
Stack[STACK_FLAGS] |= EMULATOR_FLAG_CF;
|
||||||
setAX(DosLastError);
|
setAX(Sda->LastErrorCode);
|
||||||
}
|
}
|
||||||
|
|
||||||
break;
|
break;
|
||||||
|
@ -1228,7 +1222,7 @@ VOID WINAPI DosInt21h(LPWORD Stack)
|
||||||
else
|
else
|
||||||
{
|
{
|
||||||
Stack[STACK_FLAGS] |= EMULATOR_FLAG_CF;
|
Stack[STACK_FLAGS] |= EMULATOR_FLAG_CF;
|
||||||
setAX(DosLastError);
|
setAX(Sda->LastErrorCode);
|
||||||
}
|
}
|
||||||
|
|
||||||
break;
|
break;
|
||||||
|
@ -1247,7 +1241,7 @@ VOID WINAPI DosInt21h(LPWORD Stack)
|
||||||
else
|
else
|
||||||
{
|
{
|
||||||
Stack[STACK_FLAGS] |= EMULATOR_FLAG_CF;
|
Stack[STACK_FLAGS] |= EMULATOR_FLAG_CF;
|
||||||
setAX(DosLastError);
|
setAX(Sda->LastErrorCode);
|
||||||
}
|
}
|
||||||
|
|
||||||
break;
|
break;
|
||||||
|
@ -1292,7 +1286,7 @@ VOID WINAPI DosInt21h(LPWORD Stack)
|
||||||
* Copy the current directory into the target buffer.
|
* Copy the current directory into the target buffer.
|
||||||
* It doesn't contain the drive letter and the backslash.
|
* It doesn't contain the drive letter and the backslash.
|
||||||
*/
|
*/
|
||||||
strncpy(String, CurrentDirectories[DriveNumber], DOS_DIR_LENGTH);
|
strncpy(String, &CurrentDirectories[DriveNumber * DOS_DIR_LENGTH], DOS_DIR_LENGTH);
|
||||||
Stack[STACK_FLAGS] &= ~EMULATOR_FLAG_CF;
|
Stack[STACK_FLAGS] &= ~EMULATOR_FLAG_CF;
|
||||||
setAX(0x0100); // Undocumented, see Ralf Brown: http://www.ctyme.com/intr/rb-2933.htm
|
setAX(0x0100); // Undocumented, see Ralf Brown: http://www.ctyme.com/intr/rb-2933.htm
|
||||||
}
|
}
|
||||||
|
@ -1319,7 +1313,7 @@ VOID WINAPI DosInt21h(LPWORD Stack)
|
||||||
else
|
else
|
||||||
{
|
{
|
||||||
Stack[STACK_FLAGS] |= EMULATOR_FLAG_CF;
|
Stack[STACK_FLAGS] |= EMULATOR_FLAG_CF;
|
||||||
setAX(DosLastError);
|
setAX(Sda->LastErrorCode);
|
||||||
setBX(MaxAvailable);
|
setBX(MaxAvailable);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -1354,7 +1348,7 @@ VOID WINAPI DosInt21h(LPWORD Stack)
|
||||||
else
|
else
|
||||||
{
|
{
|
||||||
Stack[STACK_FLAGS] |= EMULATOR_FLAG_CF;
|
Stack[STACK_FLAGS] |= EMULATOR_FLAG_CF;
|
||||||
setAX(DosLastError);
|
setAX(Sda->LastErrorCode);
|
||||||
setBX(Size);
|
setBX(Size);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -1417,7 +1411,7 @@ VOID WINAPI DosInt21h(LPWORD Stack)
|
||||||
/* Terminate With Return Code */
|
/* Terminate With Return Code */
|
||||||
case 0x4C:
|
case 0x4C:
|
||||||
{
|
{
|
||||||
DosTerminateProcess(CurrentPsp, getAL(), 0);
|
DosTerminateProcess(Sda->CurrentPsp, getAL(), 0);
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -1429,15 +1423,15 @@ VOID WINAPI DosInt21h(LPWORD Stack)
|
||||||
* DosErrorLevel is cleared after being read by this function.
|
* DosErrorLevel is cleared after being read by this function.
|
||||||
*/
|
*/
|
||||||
Stack[STACK_FLAGS] &= ~EMULATOR_FLAG_CF;
|
Stack[STACK_FLAGS] &= ~EMULATOR_FLAG_CF;
|
||||||
setAX(DosErrorLevel);
|
setAX(Sda->ErrorLevel);
|
||||||
DosErrorLevel = 0x0000; // Clear it
|
Sda->ErrorLevel = 0x0000; // Clear it
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
|
|
||||||
/* Find First File */
|
/* Find First File */
|
||||||
case 0x4E:
|
case 0x4E:
|
||||||
{
|
{
|
||||||
WORD Result = (WORD)demFileFindFirst(FAR_POINTER(DiskTransferArea),
|
WORD Result = (WORD)demFileFindFirst(FAR_POINTER(Sda->DiskTransferArea),
|
||||||
SEG_OFF_TO_PTR(getDS(), getDX()),
|
SEG_OFF_TO_PTR(getDS(), getDX()),
|
||||||
getCX());
|
getCX());
|
||||||
|
|
||||||
|
@ -1454,7 +1448,7 @@ VOID WINAPI DosInt21h(LPWORD Stack)
|
||||||
/* Find Next File */
|
/* Find Next File */
|
||||||
case 0x4F:
|
case 0x4F:
|
||||||
{
|
{
|
||||||
WORD Result = (WORD)demFileFindNext(FAR_POINTER(DiskTransferArea));
|
WORD Result = (WORD)demFileFindNext(FAR_POINTER(Sda->DiskTransferArea));
|
||||||
|
|
||||||
setAX(Result);
|
setAX(Result);
|
||||||
|
|
||||||
|
@ -1484,7 +1478,7 @@ VOID WINAPI DosInt21h(LPWORD Stack)
|
||||||
* and http://www.ctyme.com/intr/rb-3140.htm
|
* and http://www.ctyme.com/intr/rb-3140.htm
|
||||||
* for more information.
|
* for more information.
|
||||||
*/
|
*/
|
||||||
setBX(CurrentPsp);
|
setBX(Sda->CurrentPsp);
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -1542,7 +1536,7 @@ VOID WINAPI DosInt21h(LPWORD Stack)
|
||||||
{
|
{
|
||||||
/* Get allocation strategy */
|
/* Get allocation strategy */
|
||||||
Stack[STACK_FLAGS] &= ~EMULATOR_FLAG_CF;
|
Stack[STACK_FLAGS] &= ~EMULATOR_FLAG_CF;
|
||||||
setAX(DosAllocStrategy);
|
setAX(Sda->AllocStrategy);
|
||||||
}
|
}
|
||||||
else if (getAL() == 0x01)
|
else if (getAL() == 0x01)
|
||||||
{
|
{
|
||||||
|
@ -1565,7 +1559,7 @@ VOID WINAPI DosInt21h(LPWORD Stack)
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
|
|
||||||
DosAllocStrategy = getBL();
|
Sda->AllocStrategy = getBL();
|
||||||
Stack[STACK_FLAGS] &= ~EMULATOR_FLAG_CF;
|
Stack[STACK_FLAGS] &= ~EMULATOR_FLAG_CF;
|
||||||
}
|
}
|
||||||
else if (getAL() == 0x02)
|
else if (getAL() == 0x02)
|
||||||
|
@ -1678,7 +1672,7 @@ VOID WINAPI DosInt21h(LPWORD Stack)
|
||||||
else
|
else
|
||||||
{
|
{
|
||||||
Stack[STACK_FLAGS] |= EMULATOR_FLAG_CF;
|
Stack[STACK_FLAGS] |= EMULATOR_FLAG_CF;
|
||||||
setAX(DosLastError);
|
setAX(Sda->LastErrorCode);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
else if (getAL() == 0x01)
|
else if (getAL() == 0x01)
|
||||||
|
@ -1691,7 +1685,7 @@ VOID WINAPI DosInt21h(LPWORD Stack)
|
||||||
else
|
else
|
||||||
{
|
{
|
||||||
Stack[STACK_FLAGS] |= EMULATOR_FLAG_CF;
|
Stack[STACK_FLAGS] |= EMULATOR_FLAG_CF;
|
||||||
setAX(DosLastError);
|
setAX(Sda->LastErrorCode);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
else
|
else
|
||||||
|
@ -1740,13 +1734,40 @@ VOID WINAPI DosInt21h(LPWORD Stack)
|
||||||
break;
|
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 */
|
/* Set Handle Count */
|
||||||
case 0x67:
|
case 0x67:
|
||||||
{
|
{
|
||||||
if (!DosResizeHandleTable(getBX()))
|
if (!DosResizeHandleTable(getBX()))
|
||||||
{
|
{
|
||||||
Stack[STACK_FLAGS] |= EMULATOR_FLAG_CF;
|
Stack[STACK_FLAGS] |= EMULATOR_FLAG_CF;
|
||||||
setAX(DosLastError);
|
setAX(Sda->LastErrorCode);
|
||||||
}
|
}
|
||||||
else Stack[STACK_FLAGS] &= ~EMULATOR_FLAG_CF;
|
else Stack[STACK_FLAGS] &= ~EMULATOR_FLAG_CF;
|
||||||
|
|
||||||
|
@ -1833,7 +1854,7 @@ VOID WINAPI DosInt21h(LPWORD Stack)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
(*InDos)--;
|
Sda->InDos--;
|
||||||
}
|
}
|
||||||
|
|
||||||
VOID WINAPI DosBreakInterrupt(LPWORD Stack)
|
VOID WINAPI DosBreakInterrupt(LPWORD Stack)
|
||||||
|
@ -1942,9 +1963,9 @@ BOOLEAN DosKRNLInitialize(VOID)
|
||||||
FILE *Stream;
|
FILE *Stream;
|
||||||
WCHAR Buffer[256];
|
WCHAR Buffer[256];
|
||||||
|
|
||||||
/* Setup the InDOS flag */
|
/* Get a pointer to the current directory buffer */
|
||||||
InDos = (PBYTE)FAR_POINTER(INDOS_POINTER);
|
CurrentDirectories = (PCHAR)SEG_OFF_TO_PTR(DOS_DATA_SEGMENT,
|
||||||
*InDos = 0;
|
DOS_DATA_OFFSET(CurrentDirectories));
|
||||||
|
|
||||||
/* Clear the current directory buffer */
|
/* Clear the current directory buffer */
|
||||||
RtlZeroMemory(CurrentDirectories, sizeof(CurrentDirectories));
|
RtlZeroMemory(CurrentDirectories, sizeof(CurrentDirectories));
|
||||||
|
@ -1977,7 +1998,7 @@ BOOLEAN DosKRNLInitialize(VOID)
|
||||||
/* Set the directory */
|
/* Set the directory */
|
||||||
if (Path != NULL)
|
if (Path != NULL)
|
||||||
{
|
{
|
||||||
strncpy(CurrentDirectories[CurrentDrive], Path, DOS_DIR_LENGTH);
|
strncpy(&CurrentDirectories[CurrentDrive * DOS_DIR_LENGTH], Path, DOS_DIR_LENGTH);
|
||||||
}
|
}
|
||||||
|
|
||||||
/* Read CONFIG.SYS */
|
/* Read CONFIG.SYS */
|
||||||
|
@ -1995,7 +2016,9 @@ BOOLEAN DosKRNLInitialize(VOID)
|
||||||
SysVars = (PDOS_SYSVARS)SEG_OFF_TO_PTR(DOS_DATA_SEGMENT, 0);
|
SysVars = (PDOS_SYSVARS)SEG_OFF_TO_PTR(DOS_DATA_SEGMENT, 0);
|
||||||
RtlZeroMemory(SysVars, sizeof(DOS_SYSVARS));
|
RtlZeroMemory(SysVars, sizeof(DOS_SYSVARS));
|
||||||
SysVars->FirstMcb = FIRST_MCB_SEGMENT;
|
SysVars->FirstMcb = FIRST_MCB_SEGMENT;
|
||||||
SysVars->FirstSft = MAKELONG(MASTER_SFT_OFFSET, DOS_DATA_SEGMENT);
|
SysVars->FirstSft = MAKELONG(DOS_DATA_OFFSET(Sft), DOS_DATA_SEGMENT);
|
||||||
|
SysVars->CurrentDirs = MAKELONG(DOS_DATA_OFFSET(CurrentDirectories),
|
||||||
|
DOS_DATA_SEGMENT);
|
||||||
|
|
||||||
/* Initialize the NUL device driver */
|
/* Initialize the NUL device driver */
|
||||||
SysVars->NullDevice.Link = 0xFFFFFFFF;
|
SysVars->NullDevice.Link = 0xFFFFFFFF;
|
||||||
|
@ -2010,6 +2033,16 @@ BOOLEAN DosKRNLInitialize(VOID)
|
||||||
NullDriverRoutine,
|
NullDriverRoutine,
|
||||||
sizeof(NullDriverRoutine));
|
sizeof(NullDriverRoutine));
|
||||||
|
|
||||||
|
/* Initialize the swappable data area */
|
||||||
|
Sda = (PDOS_SDA)SEG_OFF_TO_PTR(DOS_DATA_SEGMENT, sizeof(DOS_SYSVARS));
|
||||||
|
RtlZeroMemory(Sda, sizeof(DOS_SDA));
|
||||||
|
|
||||||
|
/* Set the current PSP to the system PSP */
|
||||||
|
Sda->CurrentPsp = SYSTEM_PSP;
|
||||||
|
|
||||||
|
/* Set the initial allocation strategy to "best fit" */
|
||||||
|
Sda->AllocStrategy = DOS_ALLOC_BEST_FIT;
|
||||||
|
|
||||||
/* Initialize the SFT */
|
/* Initialize the SFT */
|
||||||
Sft = (PDOS_SFT)FAR_POINTER(SysVars->FirstSft);
|
Sft = (PDOS_SFT)FAR_POINTER(SysVars->FirstSft);
|
||||||
Sft->Link = 0xFFFFFFFF;
|
Sft->Link = 0xFFFFFFFF;
|
||||||
|
|
|
@ -32,7 +32,8 @@
|
||||||
#define SYSTEM_ENV_BLOCK 0x800
|
#define SYSTEM_ENV_BLOCK 0x800
|
||||||
#define DOS_CODE_SEGMENT 0x70
|
#define DOS_CODE_SEGMENT 0x70
|
||||||
#define DOS_DATA_SEGMENT 0xA0
|
#define DOS_DATA_SEGMENT 0xA0
|
||||||
#define MASTER_SFT_OFFSET 0x100
|
|
||||||
|
#define DOS_DATA_OFFSET(x) FIELD_OFFSET(DOS_DATA, x)
|
||||||
|
|
||||||
#define INVALID_DOS_HANDLE 0xFFFF
|
#define INVALID_DOS_HANDLE 0xFFFF
|
||||||
#define DOS_INPUT_HANDLE 0
|
#define DOS_INPUT_HANDLE 0
|
||||||
|
@ -92,6 +93,15 @@ typedef struct _DOS_SYSVARS
|
||||||
BYTE NullDriverRoutine[7];
|
BYTE NullDriverRoutine[7];
|
||||||
} DOS_SYSVARS, *PDOS_SYSVARS;
|
} DOS_SYSVARS, *PDOS_SYSVARS;
|
||||||
|
|
||||||
|
typedef struct _DOS_CLOCK_TRANSFER_RECORD
|
||||||
|
{
|
||||||
|
WORD NumberOfDays;
|
||||||
|
BYTE Minutes;
|
||||||
|
BYTE Hours;
|
||||||
|
BYTE Hundredths;
|
||||||
|
BYTE Seconds;
|
||||||
|
} DOS_CLOCK_TRANSFER_RECORD, *PDOS_CLOCK_TRANSFER_RECORD;
|
||||||
|
|
||||||
typedef struct _DOS_INPUT_BUFFER
|
typedef struct _DOS_INPUT_BUFFER
|
||||||
{
|
{
|
||||||
BYTE MaxLength;
|
BYTE MaxLength;
|
||||||
|
@ -123,15 +133,127 @@ typedef struct _DOS_COUNTRY_CODE_BUFFER
|
||||||
WORD DecimalSep;
|
WORD DecimalSep;
|
||||||
} DOS_COUNTRY_CODE_BUFFER, *PDOS_COUNTRY_CODE_BUFFER;
|
} DOS_COUNTRY_CODE_BUFFER, *PDOS_COUNTRY_CODE_BUFFER;
|
||||||
|
|
||||||
|
typedef struct _DOS_SDA
|
||||||
|
{
|
||||||
|
BYTE PrinterEchoFlag;
|
||||||
|
CHAR CurrentSwitchChar;
|
||||||
|
BYTE AllocStrategy;
|
||||||
|
BYTE Unused0[28];
|
||||||
|
|
||||||
|
/* This is where the SDA really starts */
|
||||||
|
BYTE ErrorMode;
|
||||||
|
BYTE InDos;
|
||||||
|
BYTE ErrorDrive;
|
||||||
|
BYTE LastErrorLocus;
|
||||||
|
WORD LastErrorCode;
|
||||||
|
BYTE LastErrorAction;
|
||||||
|
BYTE LastErrorClass;
|
||||||
|
DWORD LastErrorPointer;
|
||||||
|
DWORD DiskTransferArea;
|
||||||
|
WORD CurrentPsp;
|
||||||
|
WORD Int23StackPointer;
|
||||||
|
WORD ErrorLevel;
|
||||||
|
BYTE CurrentDrive;
|
||||||
|
BYTE ExtendedBreakFlag;
|
||||||
|
|
||||||
|
/* This part is only valid while in DOS */
|
||||||
|
WORD LastAX;
|
||||||
|
WORD NetworkPsp;
|
||||||
|
WORD NetworkMachineNumber;
|
||||||
|
WORD FirstFreeMcb;
|
||||||
|
WORD BestFreeMcb;
|
||||||
|
WORD LastFreeMcb;
|
||||||
|
WORD MemorySize;
|
||||||
|
WORD LastSearchDirEntry;
|
||||||
|
BYTE Int24FailFlag;
|
||||||
|
BYTE DirectoryFlag;
|
||||||
|
BYTE CtrlBreakFlag;
|
||||||
|
BYTE AllowFcbBlanks;
|
||||||
|
BYTE Unused1;
|
||||||
|
BYTE DayOfMonth;
|
||||||
|
BYTE Month;
|
||||||
|
WORD Year;
|
||||||
|
WORD NumDays;
|
||||||
|
BYTE DayOfWeek;
|
||||||
|
BYTE ConsoleSwappedFlag;
|
||||||
|
BYTE Int28CallOk;
|
||||||
|
BYTE Int24AbortFlag;
|
||||||
|
DOS_RW_REQUEST ReadWriteRequest;
|
||||||
|
DWORD DriverEntryPoint;
|
||||||
|
DOS_IOCTL_RW_REQUEST IoctlRequest;
|
||||||
|
DOS_PEEK_REQUEST StatusRequest;
|
||||||
|
DWORD DeviceIoBuffer;
|
||||||
|
DWORD Unused2;
|
||||||
|
BYTE PspCopyType;
|
||||||
|
BYTE Unused3;
|
||||||
|
BYTE UserNumber[3];
|
||||||
|
BYTE OemNumber;
|
||||||
|
WORD ErrorCodeTable;
|
||||||
|
DOS_CLOCK_TRANSFER_RECORD ClockTransferRecord;
|
||||||
|
BYTE ByteBuffer;
|
||||||
|
BYTE Unused4;
|
||||||
|
CHAR FileNameBuffer[256];
|
||||||
|
BYTE Unused5[53];
|
||||||
|
CHAR CurrentDirectory[81];
|
||||||
|
CHAR FcbFilename[12];
|
||||||
|
CHAR FcbRenameDest[12];
|
||||||
|
BYTE Unused6[8];
|
||||||
|
BYTE ExtendedAttribute;
|
||||||
|
BYTE FcbType;
|
||||||
|
BYTE DirSearchAttributes;
|
||||||
|
BYTE FileOpenMode;
|
||||||
|
BYTE FileFound;
|
||||||
|
BYTE DeviceNameFound;
|
||||||
|
BYTE SpliceFlag;
|
||||||
|
BYTE DosCallFlag;
|
||||||
|
BYTE Unused7[5];
|
||||||
|
BYTE InsertMode;
|
||||||
|
BYTE ParsedFcbExists;
|
||||||
|
BYTE VolumeIDFlag;
|
||||||
|
BYTE TerminationType;
|
||||||
|
BYTE CreateFileFlag;
|
||||||
|
BYTE FileDeletedChar;
|
||||||
|
DWORD CriticalErrorDpb;
|
||||||
|
DWORD UserRegistersStack;
|
||||||
|
WORD Int24StackPointer;
|
||||||
|
BYTE Unused8[14];
|
||||||
|
DWORD DeviceHeader;
|
||||||
|
DWORD CurrentSft;
|
||||||
|
DWORD CurrentDirPointer;
|
||||||
|
DWORD CallerFcb;
|
||||||
|
WORD SftNumber;
|
||||||
|
WORD TempFileHandle;
|
||||||
|
DWORD JftEntry;
|
||||||
|
WORD FirstArgument;
|
||||||
|
WORD SecondArgument;
|
||||||
|
WORD LastComponent;
|
||||||
|
WORD TransferOffset;
|
||||||
|
BYTE Unused9[38];
|
||||||
|
DWORD WorkingSft;
|
||||||
|
WORD Int21CallerBX;
|
||||||
|
WORD Int21CallerDS;
|
||||||
|
WORD Unused10;
|
||||||
|
DWORD PrevCallFrame;
|
||||||
|
} DOS_SDA, *PDOS_SDA;
|
||||||
|
|
||||||
|
/* This structure is only used for DOS_DATA_OFFSET calculations */
|
||||||
|
typedef struct _DOS_DATA
|
||||||
|
{
|
||||||
|
DOS_SYSVARS SysVars;
|
||||||
|
DOS_SDA Sda;
|
||||||
|
CHAR CurrentDirectories[NUM_DRIVES * DOS_DIR_LENGTH];
|
||||||
|
BYTE Sft[ANYSIZE_ARRAY];
|
||||||
|
} DOS_DATA, *PDOS_DATA;
|
||||||
|
|
||||||
#pragma pack(pop)
|
#pragma pack(pop)
|
||||||
|
|
||||||
/* VARIABLES ******************************************************************/
|
/* VARIABLES ******************************************************************/
|
||||||
|
|
||||||
extern BOOLEAN DoEcho;
|
extern BOOLEAN DoEcho;
|
||||||
extern DWORD DiskTransferArea;
|
|
||||||
extern WORD DosErrorLevel;
|
extern WORD DosErrorLevel;
|
||||||
extern WORD DosLastError;
|
extern WORD DosLastError;
|
||||||
extern PDOS_SYSVARS SysVars;
|
extern PDOS_SYSVARS SysVars;
|
||||||
|
extern PDOS_SDA Sda;
|
||||||
|
|
||||||
/* FUNCTIONS ******************************************************************/
|
/* FUNCTIONS ******************************************************************/
|
||||||
|
|
||||||
|
|
|
@ -376,7 +376,7 @@ WORD DosCreateFileEx(LPWORD Handle,
|
||||||
Descriptor->OpenMode = AccessShareModes;
|
Descriptor->OpenMode = AccessShareModes;
|
||||||
Descriptor->Attributes = LOBYTE(GetFileAttributesA(FilePath));
|
Descriptor->Attributes = LOBYTE(GetFileAttributesA(FilePath));
|
||||||
Descriptor->Size = GetFileSize(FileHandle, NULL);
|
Descriptor->Size = GetFileSize(FileHandle, NULL);
|
||||||
Descriptor->OwnerPsp = CurrentPsp;
|
Descriptor->OwnerPsp = Sda->CurrentPsp;
|
||||||
Descriptor->Win32Handle = FileHandle;
|
Descriptor->Win32Handle = FileHandle;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -451,7 +451,7 @@ WORD DosCreateFile(LPWORD Handle,
|
||||||
{
|
{
|
||||||
Descriptor->Attributes = LOBYTE(GetFileAttributesA(FilePath));
|
Descriptor->Attributes = LOBYTE(GetFileAttributesA(FilePath));
|
||||||
Descriptor->Size = GetFileSize(FileHandle, NULL);
|
Descriptor->Size = GetFileSize(FileHandle, NULL);
|
||||||
Descriptor->OwnerPsp = CurrentPsp;
|
Descriptor->OwnerPsp = Sda->CurrentPsp;
|
||||||
Descriptor->Win32Handle = FileHandle;
|
Descriptor->Win32Handle = FileHandle;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -600,7 +600,7 @@ WORD DosOpenFile(LPWORD Handle,
|
||||||
Descriptor->OpenMode = AccessShareModes;
|
Descriptor->OpenMode = AccessShareModes;
|
||||||
Descriptor->Attributes = LOBYTE(GetFileAttributesA(FilePath));
|
Descriptor->Attributes = LOBYTE(GetFileAttributesA(FilePath));
|
||||||
Descriptor->Size = GetFileSize(FileHandle, NULL);
|
Descriptor->Size = GetFileSize(FileHandle, NULL);
|
||||||
Descriptor->OwnerPsp = CurrentPsp;
|
Descriptor->OwnerPsp = Sda->CurrentPsp;
|
||||||
Descriptor->Win32Handle = FileHandle;
|
Descriptor->Win32Handle = FileHandle;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -793,7 +793,7 @@ BOOL DosFlushFileBuffers(WORD FileHandle)
|
||||||
if (Descriptor == NULL)
|
if (Descriptor == NULL)
|
||||||
{
|
{
|
||||||
/* Invalid handle */
|
/* Invalid handle */
|
||||||
DosLastError = ERROR_INVALID_HANDLE;
|
Sda->LastErrorCode = ERROR_INVALID_HANDLE;
|
||||||
return FALSE;
|
return FALSE;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -819,7 +819,7 @@ BOOLEAN DosLockFile(WORD DosHandle, DWORD Offset, DWORD Size)
|
||||||
if (Descriptor == NULL)
|
if (Descriptor == NULL)
|
||||||
{
|
{
|
||||||
/* Invalid handle */
|
/* Invalid handle */
|
||||||
DosLastError = ERROR_INVALID_HANDLE;
|
Sda->LastErrorCode = ERROR_INVALID_HANDLE;
|
||||||
return FALSE;
|
return FALSE;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -828,7 +828,7 @@ BOOLEAN DosLockFile(WORD DosHandle, DWORD Offset, DWORD Size)
|
||||||
|
|
||||||
if (!LockFile(Descriptor->Win32Handle, Offset, 0, Size, 0))
|
if (!LockFile(Descriptor->Win32Handle, Offset, 0, Size, 0))
|
||||||
{
|
{
|
||||||
DosLastError = GetLastError();
|
Sda->LastErrorCode = GetLastError();
|
||||||
return FALSE;
|
return FALSE;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -842,7 +842,7 @@ BOOLEAN DosUnlockFile(WORD DosHandle, DWORD Offset, DWORD Size)
|
||||||
if (Descriptor == NULL)
|
if (Descriptor == NULL)
|
||||||
{
|
{
|
||||||
/* Invalid handle */
|
/* Invalid handle */
|
||||||
DosLastError = ERROR_INVALID_HANDLE;
|
Sda->LastErrorCode = ERROR_INVALID_HANDLE;
|
||||||
return FALSE;
|
return FALSE;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -851,7 +851,7 @@ BOOLEAN DosUnlockFile(WORD DosHandle, DWORD Offset, DWORD Size)
|
||||||
|
|
||||||
if (!UnlockFile(Descriptor->Win32Handle, Offset, 0, Size, 0))
|
if (!UnlockFile(Descriptor->Win32Handle, Offset, 0, Size, 0))
|
||||||
{
|
{
|
||||||
DosLastError = GetLastError();
|
Sda->LastErrorCode = GetLastError();
|
||||||
return FALSE;
|
return FALSE;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -865,7 +865,7 @@ BOOLEAN DosDeviceIoControl(WORD FileHandle, BYTE ControlCode, DWORD Buffer, PWOR
|
||||||
|
|
||||||
if (!Descriptor)
|
if (!Descriptor)
|
||||||
{
|
{
|
||||||
DosLastError = ERROR_INVALID_HANDLE;
|
Sda->LastErrorCode = ERROR_INVALID_HANDLE;
|
||||||
return FALSE;
|
return FALSE;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -901,7 +901,7 @@ BOOLEAN DosDeviceIoControl(WORD FileHandle, BYTE ControlCode, DWORD Buffer, PWOR
|
||||||
{
|
{
|
||||||
if (Node == NULL || !(Node->DeviceAttributes & DOS_DEVATTR_IOCTL))
|
if (Node == NULL || !(Node->DeviceAttributes & DOS_DEVATTR_IOCTL))
|
||||||
{
|
{
|
||||||
DosLastError = ERROR_INVALID_FUNCTION;
|
Sda->LastErrorCode = ERROR_INVALID_FUNCTION;
|
||||||
return FALSE;
|
return FALSE;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -921,7 +921,7 @@ BOOLEAN DosDeviceIoControl(WORD FileHandle, BYTE ControlCode, DWORD Buffer, PWOR
|
||||||
{
|
{
|
||||||
if (Node == NULL || !(Node->DeviceAttributes & DOS_DEVATTR_IOCTL))
|
if (Node == NULL || !(Node->DeviceAttributes & DOS_DEVATTR_IOCTL))
|
||||||
{
|
{
|
||||||
DosLastError = ERROR_INVALID_FUNCTION;
|
Sda->LastErrorCode = ERROR_INVALID_FUNCTION;
|
||||||
return FALSE;
|
return FALSE;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -941,7 +941,7 @@ BOOLEAN DosDeviceIoControl(WORD FileHandle, BYTE ControlCode, DWORD Buffer, PWOR
|
||||||
{
|
{
|
||||||
DPRINT1("Unsupported IOCTL: 0x%02X\n", ControlCode);
|
DPRINT1("Unsupported IOCTL: 0x%02X\n", ControlCode);
|
||||||
|
|
||||||
DosLastError = ERROR_INVALID_PARAMETER;
|
Sda->LastErrorCode = ERROR_INVALID_PARAMETER;
|
||||||
return FALSE;
|
return FALSE;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
|
@ -59,7 +59,7 @@ VOID DosCopyHandleTable(LPBYTE DestinationTable)
|
||||||
for (i = 0; i < DEFAULT_JFT_SIZE; i++) DestinationTable[i] = 0xFF;
|
for (i = 0; i < DEFAULT_JFT_SIZE; i++) DestinationTable[i] = 0xFF;
|
||||||
|
|
||||||
/* Check if this is the initial process */
|
/* Check if this is the initial process */
|
||||||
if (CurrentPsp == SYSTEM_PSP)
|
if (Sda->CurrentPsp == SYSTEM_PSP)
|
||||||
{
|
{
|
||||||
BYTE DescriptorId;
|
BYTE DescriptorId;
|
||||||
HANDLE StandardHandles[3];
|
HANDLE StandardHandles[3];
|
||||||
|
@ -122,7 +122,7 @@ VOID DosCopyHandleTable(LPBYTE DestinationTable)
|
||||||
else
|
else
|
||||||
{
|
{
|
||||||
/* Get the parent PSP block and handle table */
|
/* Get the parent PSP block and handle table */
|
||||||
PspBlock = SEGMENT_TO_PSP(CurrentPsp);
|
PspBlock = SEGMENT_TO_PSP(Sda->CurrentPsp);
|
||||||
SourceTable = (LPBYTE)FAR_POINTER(PspBlock->HandleTablePtr);
|
SourceTable = (LPBYTE)FAR_POINTER(PspBlock->HandleTablePtr);
|
||||||
|
|
||||||
/* Copy the first 20 handles into the new table */
|
/* Copy the first 20 handles into the new table */
|
||||||
|
@ -144,7 +144,7 @@ BOOLEAN DosResizeHandleTable(WORD NewSize)
|
||||||
WORD Segment;
|
WORD Segment;
|
||||||
|
|
||||||
/* Get the PSP block */
|
/* Get the PSP block */
|
||||||
PspBlock = SEGMENT_TO_PSP(CurrentPsp);
|
PspBlock = SEGMENT_TO_PSP(Sda->CurrentPsp);
|
||||||
|
|
||||||
if (NewSize == PspBlock->HandleTableSize)
|
if (NewSize == PspBlock->HandleTableSize)
|
||||||
{
|
{
|
||||||
|
@ -170,7 +170,7 @@ BOOLEAN DosResizeHandleTable(WORD NewSize)
|
||||||
|
|
||||||
/* Update the handle table pointer and size */
|
/* Update the handle table pointer and size */
|
||||||
PspBlock->HandleTableSize = NewSize;
|
PspBlock->HandleTableSize = NewSize;
|
||||||
PspBlock->HandleTablePtr = MAKELONG(0x18, CurrentPsp);
|
PspBlock->HandleTablePtr = MAKELONG(0x18, Sda->CurrentPsp);
|
||||||
}
|
}
|
||||||
else
|
else
|
||||||
{
|
{
|
||||||
|
@ -232,10 +232,10 @@ WORD DosOpenHandle(BYTE DescriptorId)
|
||||||
if (Descriptor == NULL) return INVALID_DOS_HANDLE;
|
if (Descriptor == NULL) return INVALID_DOS_HANDLE;
|
||||||
|
|
||||||
/* The system PSP has no handle table */
|
/* The system PSP has no handle table */
|
||||||
if (CurrentPsp == SYSTEM_PSP) return INVALID_DOS_HANDLE;
|
if (Sda->CurrentPsp == SYSTEM_PSP) return INVALID_DOS_HANDLE;
|
||||||
|
|
||||||
/* Get a pointer to the handle table */
|
/* Get a pointer to the handle table */
|
||||||
PspBlock = SEGMENT_TO_PSP(CurrentPsp);
|
PspBlock = SEGMENT_TO_PSP(Sda->CurrentPsp);
|
||||||
HandleTable = (LPBYTE)FAR_POINTER(PspBlock->HandleTablePtr);
|
HandleTable = (LPBYTE)FAR_POINTER(PspBlock->HandleTablePtr);
|
||||||
|
|
||||||
/* Find a free entry in the JFT */
|
/* Find a free entry in the JFT */
|
||||||
|
@ -265,10 +265,10 @@ BYTE DosQueryHandle(WORD DosHandle)
|
||||||
DPRINT("DosQueryHandle: DosHandle 0x%04X\n", DosHandle);
|
DPRINT("DosQueryHandle: DosHandle 0x%04X\n", DosHandle);
|
||||||
|
|
||||||
/* The system PSP has no handle table */
|
/* The system PSP has no handle table */
|
||||||
if (CurrentPsp == SYSTEM_PSP) return 0xFF;
|
if (Sda->CurrentPsp == SYSTEM_PSP) return 0xFF;
|
||||||
|
|
||||||
/* Get a pointer to the handle table */
|
/* Get a pointer to the handle table */
|
||||||
PspBlock = SEGMENT_TO_PSP(CurrentPsp);
|
PspBlock = SEGMENT_TO_PSP(Sda->CurrentPsp);
|
||||||
HandleTable = (LPBYTE)FAR_POINTER(PspBlock->HandleTablePtr);
|
HandleTable = (LPBYTE)FAR_POINTER(PspBlock->HandleTablePtr);
|
||||||
|
|
||||||
/* Return the descriptor ID */
|
/* Return the descriptor ID */
|
||||||
|
@ -281,7 +281,7 @@ WORD DosDuplicateHandle(WORD DosHandle)
|
||||||
|
|
||||||
if (DescriptorId == 0xFF)
|
if (DescriptorId == 0xFF)
|
||||||
{
|
{
|
||||||
DosLastError = ERROR_INVALID_HANDLE;
|
Sda->LastErrorCode = ERROR_INVALID_HANDLE;
|
||||||
return INVALID_DOS_HANDLE;
|
return INVALID_DOS_HANDLE;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -300,10 +300,10 @@ BOOLEAN DosForceDuplicateHandle(WORD OldHandle, WORD NewHandle)
|
||||||
NewHandle);
|
NewHandle);
|
||||||
|
|
||||||
/* The system PSP has no handle table */
|
/* The system PSP has no handle table */
|
||||||
if (CurrentPsp == SYSTEM_PSP) return FALSE;
|
if (Sda->CurrentPsp == SYSTEM_PSP) return FALSE;
|
||||||
|
|
||||||
/* Get a pointer to the handle table */
|
/* Get a pointer to the handle table */
|
||||||
PspBlock = SEGMENT_TO_PSP(CurrentPsp);
|
PspBlock = SEGMENT_TO_PSP(Sda->CurrentPsp);
|
||||||
HandleTable = (LPBYTE)FAR_POINTER(PspBlock->HandleTablePtr);
|
HandleTable = (LPBYTE)FAR_POINTER(PspBlock->HandleTablePtr);
|
||||||
|
|
||||||
/* Make sure the old handle is open */
|
/* Make sure the old handle is open */
|
||||||
|
@ -339,10 +339,10 @@ BOOLEAN DosCloseHandle(WORD DosHandle)
|
||||||
DPRINT("DosCloseHandle: DosHandle 0x%04X\n", DosHandle);
|
DPRINT("DosCloseHandle: DosHandle 0x%04X\n", DosHandle);
|
||||||
|
|
||||||
/* The system PSP has no handle table */
|
/* The system PSP has no handle table */
|
||||||
if (CurrentPsp == SYSTEM_PSP) return FALSE;
|
if (Sda->CurrentPsp == SYSTEM_PSP) return FALSE;
|
||||||
|
|
||||||
/* Get a pointer to the handle table */
|
/* Get a pointer to the handle table */
|
||||||
PspBlock = SEGMENT_TO_PSP(CurrentPsp);
|
PspBlock = SEGMENT_TO_PSP(Sda->CurrentPsp);
|
||||||
HandleTable = (LPBYTE)FAR_POINTER(PspBlock->HandleTablePtr);
|
HandleTable = (LPBYTE)FAR_POINTER(PspBlock->HandleTablePtr);
|
||||||
|
|
||||||
/* Make sure the handle is open */
|
/* Make sure the handle is open */
|
||||||
|
|
|
@ -20,7 +20,6 @@
|
||||||
|
|
||||||
/* PUBLIC VARIABLES ***********************************************************/
|
/* PUBLIC VARIABLES ***********************************************************/
|
||||||
|
|
||||||
BYTE DosAllocStrategy = DOS_ALLOC_BEST_FIT;
|
|
||||||
BOOLEAN DosUmbLinked = FALSE;
|
BOOLEAN DosUmbLinked = FALSE;
|
||||||
|
|
||||||
/* PRIVATE FUNCTIONS **********************************************************/
|
/* PRIVATE FUNCTIONS **********************************************************/
|
||||||
|
@ -63,7 +62,7 @@ WORD DosAllocateMemory(WORD Size, WORD *MaxAvailable)
|
||||||
|
|
||||||
DPRINT("DosAllocateMemory: Size 0x%04X\n", Size);
|
DPRINT("DosAllocateMemory: Size 0x%04X\n", Size);
|
||||||
|
|
||||||
if (DosUmbLinked && (DosAllocStrategy & (DOS_ALLOC_HIGH | DOS_ALLOC_HIGH_LOW)))
|
if (DosUmbLinked && (Sda->AllocStrategy & (DOS_ALLOC_HIGH | DOS_ALLOC_HIGH_LOW)))
|
||||||
{
|
{
|
||||||
/* Search UMB first */
|
/* Search UMB first */
|
||||||
Segment = UMB_START_SEGMENT;
|
Segment = UMB_START_SEGMENT;
|
||||||
|
@ -79,7 +78,7 @@ WORD DosAllocateMemory(WORD Size, WORD *MaxAvailable)
|
||||||
if (CurrentMcb->BlockType != 'M' && CurrentMcb->BlockType != 'Z')
|
if (CurrentMcb->BlockType != 'M' && CurrentMcb->BlockType != 'Z')
|
||||||
{
|
{
|
||||||
DPRINT("The DOS memory arena is corrupted!\n");
|
DPRINT("The DOS memory arena is corrupted!\n");
|
||||||
DosLastError = ERROR_ARENA_TRASHED;
|
Sda->LastErrorCode = ERROR_ARENA_TRASHED;
|
||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -95,7 +94,7 @@ WORD DosAllocateMemory(WORD Size, WORD *MaxAvailable)
|
||||||
/* Check if this block is big enough */
|
/* Check if this block is big enough */
|
||||||
if (CurrentMcb->Size < Size) goto Next;
|
if (CurrentMcb->Size < Size) goto Next;
|
||||||
|
|
||||||
switch (DosAllocStrategy & 0x3F)
|
switch (Sda->AllocStrategy & 0x3F)
|
||||||
{
|
{
|
||||||
case DOS_ALLOC_FIRST_FIT:
|
case DOS_ALLOC_FIRST_FIT:
|
||||||
{
|
{
|
||||||
|
@ -128,7 +127,7 @@ Next:
|
||||||
if (CurrentMcb->BlockType == 'Z')
|
if (CurrentMcb->BlockType == 'Z')
|
||||||
{
|
{
|
||||||
/* Check if nothing was found while searching through UMBs */
|
/* Check if nothing was found while searching through UMBs */
|
||||||
if ((Result == 0) && SearchUmb && (DosAllocStrategy & DOS_ALLOC_HIGH_LOW))
|
if ((Result == 0) && SearchUmb && (Sda->AllocStrategy & DOS_ALLOC_HIGH_LOW))
|
||||||
{
|
{
|
||||||
/* Search low memory */
|
/* Search low memory */
|
||||||
Segment = FIRST_MCB_SEGMENT;
|
Segment = FIRST_MCB_SEGMENT;
|
||||||
|
@ -148,7 +147,7 @@ Done:
|
||||||
/* If we didn't find a free block, return 0 */
|
/* If we didn't find a free block, return 0 */
|
||||||
if (Result == 0)
|
if (Result == 0)
|
||||||
{
|
{
|
||||||
DosLastError = ERROR_NOT_ENOUGH_MEMORY;
|
Sda->LastErrorCode = ERROR_NOT_ENOUGH_MEMORY;
|
||||||
if (MaxAvailable) *MaxAvailable = MaxSize;
|
if (MaxAvailable) *MaxAvailable = MaxSize;
|
||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
|
@ -160,7 +159,7 @@ Done:
|
||||||
if (CurrentMcb->Size > Size)
|
if (CurrentMcb->Size > Size)
|
||||||
{
|
{
|
||||||
/* It is, split it into two blocks */
|
/* It is, split it into two blocks */
|
||||||
if ((DosAllocStrategy & 0x3F) != DOS_ALLOC_LAST_FIT)
|
if ((Sda->AllocStrategy & 0x3F) != DOS_ALLOC_LAST_FIT)
|
||||||
{
|
{
|
||||||
PDOS_MCB NextMcb = SEGMENT_TO_MCB(Result + Size + 1);
|
PDOS_MCB NextMcb = SEGMENT_TO_MCB(Result + Size + 1);
|
||||||
|
|
||||||
|
@ -194,7 +193,7 @@ Done:
|
||||||
}
|
}
|
||||||
|
|
||||||
/* Take ownership of the block */
|
/* Take ownership of the block */
|
||||||
CurrentMcb->OwnerPsp = CurrentPsp;
|
CurrentMcb->OwnerPsp = Sda->CurrentPsp;
|
||||||
|
|
||||||
/* Return the segment of the data portion of the block */
|
/* Return the segment of the data portion of the block */
|
||||||
return Result + 1;
|
return Result + 1;
|
||||||
|
@ -216,7 +215,7 @@ BOOLEAN DosResizeMemory(WORD BlockData, WORD NewSize, WORD *MaxAvailable)
|
||||||
|| Mcb->OwnerPsp == 0)
|
|| Mcb->OwnerPsp == 0)
|
||||||
{
|
{
|
||||||
Success = FALSE;
|
Success = FALSE;
|
||||||
DosLastError = ERROR_INVALID_HANDLE;
|
Sda->LastErrorCode = ERROR_INVALID_HANDLE;
|
||||||
goto Done;
|
goto Done;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -240,7 +239,7 @@ BOOLEAN DosResizeMemory(WORD BlockData, WORD NewSize, WORD *MaxAvailable)
|
||||||
if (NextMcb->OwnerPsp != 0)
|
if (NextMcb->OwnerPsp != 0)
|
||||||
{
|
{
|
||||||
DPRINT("Cannot expand memory block: next segment is not free!\n");
|
DPRINT("Cannot expand memory block: next segment is not free!\n");
|
||||||
DosLastError = ERROR_NOT_ENOUGH_MEMORY;
|
Sda->LastErrorCode = ERROR_NOT_ENOUGH_MEMORY;
|
||||||
Success = FALSE;
|
Success = FALSE;
|
||||||
goto Done;
|
goto Done;
|
||||||
}
|
}
|
||||||
|
@ -254,7 +253,7 @@ BOOLEAN DosResizeMemory(WORD BlockData, WORD NewSize, WORD *MaxAvailable)
|
||||||
if (ReturnSize < NewSize)
|
if (ReturnSize < NewSize)
|
||||||
{
|
{
|
||||||
DPRINT("Cannot expand memory block: insufficient free segments available!\n");
|
DPRINT("Cannot expand memory block: insufficient free segments available!\n");
|
||||||
DosLastError = ERROR_NOT_ENOUGH_MEMORY;
|
Sda->LastErrorCode = ERROR_NOT_ENOUGH_MEMORY;
|
||||||
Success = FALSE;
|
Success = FALSE;
|
||||||
goto Done;
|
goto Done;
|
||||||
}
|
}
|
||||||
|
|
|
@ -27,10 +27,6 @@
|
||||||
#include "io.h"
|
#include "io.h"
|
||||||
#include "hardware/ps2.h"
|
#include "hardware/ps2.h"
|
||||||
|
|
||||||
/* PUBLIC VARIABLES ***********************************************************/
|
|
||||||
|
|
||||||
WORD CurrentPsp = SYSTEM_PSP;
|
|
||||||
|
|
||||||
/* PRIVATE FUNCTIONS **********************************************************/
|
/* PRIVATE FUNCTIONS **********************************************************/
|
||||||
|
|
||||||
static inline VOID DosSetPspCommandLine(WORD Segment, LPCSTR CommandLine)
|
static inline VOID DosSetPspCommandLine(WORD Segment, LPCSTR CommandLine)
|
||||||
|
@ -212,7 +208,7 @@ VOID DosCreatePsp(WORD Segment, WORD ProgramSize)
|
||||||
PspBlock->CriticalAddress = IntVecTable[0x24];
|
PspBlock->CriticalAddress = IntVecTable[0x24];
|
||||||
|
|
||||||
/* Set the parent PSP */
|
/* Set the parent PSP */
|
||||||
PspBlock->ParentPsp = CurrentPsp;
|
PspBlock->ParentPsp = Sda->CurrentPsp;
|
||||||
|
|
||||||
/* No environment block yet */
|
/* No environment block yet */
|
||||||
PspBlock->EnvBlock = 0;
|
PspBlock->EnvBlock = 0;
|
||||||
|
@ -235,8 +231,8 @@ VOID DosCreatePsp(WORD Segment, WORD ProgramSize)
|
||||||
|
|
||||||
VOID DosSetProcessContext(WORD Segment)
|
VOID DosSetProcessContext(WORD Segment)
|
||||||
{
|
{
|
||||||
CurrentPsp = Segment;
|
Sda->CurrentPsp = Segment;
|
||||||
DiskTransferArea = MAKELONG(0x80, Segment);
|
Sda->DiskTransferArea = MAKELONG(0x80, Segment);
|
||||||
}
|
}
|
||||||
|
|
||||||
DWORD DosLoadExecutable(IN DOS_EXEC_TYPE LoadType,
|
DWORD DosLoadExecutable(IN DOS_EXEC_TYPE LoadType,
|
||||||
|
@ -439,7 +435,7 @@ DWORD DosLoadExecutable(IN DOS_EXEC_TYPE LoadType,
|
||||||
/* Check if there's at least enough memory for the minimum size */
|
/* Check if there's at least enough memory for the minimum size */
|
||||||
if (MaxAllocSize < (BaseSize + (sizeof(DOS_PSP) >> 4) + Header->e_minalloc))
|
if (MaxAllocSize < (BaseSize + (sizeof(DOS_PSP) >> 4) + Header->e_minalloc))
|
||||||
{
|
{
|
||||||
Result = DosLastError;
|
Result = Sda->LastErrorCode;
|
||||||
goto Cleanup;
|
goto Cleanup;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -496,13 +492,13 @@ DWORD DosLoadExecutable(IN DOS_EXEC_TYPE LoadType,
|
||||||
if (LoadType == DOS_LOAD_AND_EXECUTE)
|
if (LoadType == DOS_LOAD_AND_EXECUTE)
|
||||||
{
|
{
|
||||||
/* Save the program state */
|
/* Save the program state */
|
||||||
if (CurrentPsp != SYSTEM_PSP)
|
if (Sda->CurrentPsp != SYSTEM_PSP)
|
||||||
{
|
{
|
||||||
/* Push the task state */
|
/* Push the task state */
|
||||||
DosSaveState();
|
DosSaveState();
|
||||||
|
|
||||||
/* Update the last stack in the PSP */
|
/* Update the last stack in the PSP */
|
||||||
SEGMENT_TO_PSP(CurrentPsp)->LastStack = MAKELONG(getSP(), getSS());
|
SEGMENT_TO_PSP(Sda->CurrentPsp)->LastStack = MAKELONG(getSP(), getSS());
|
||||||
}
|
}
|
||||||
|
|
||||||
/* Set the initial segment registers */
|
/* Set the initial segment registers */
|
||||||
|
@ -544,7 +540,7 @@ DWORD DosLoadExecutable(IN DOS_EXEC_TYPE LoadType,
|
||||||
Segment = DosAllocateMemory(MaxAllocSize, NULL);
|
Segment = DosAllocateMemory(MaxAllocSize, NULL);
|
||||||
if (Segment == 0)
|
if (Segment == 0)
|
||||||
{
|
{
|
||||||
Result = DosLastError;
|
Result = Sda->LastErrorCode;
|
||||||
goto Cleanup;
|
goto Cleanup;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -577,13 +573,13 @@ DWORD DosLoadExecutable(IN DOS_EXEC_TYPE LoadType,
|
||||||
if (LoadType == DOS_LOAD_AND_EXECUTE)
|
if (LoadType == DOS_LOAD_AND_EXECUTE)
|
||||||
{
|
{
|
||||||
/* Save the program state */
|
/* Save the program state */
|
||||||
if (CurrentPsp != SYSTEM_PSP)
|
if (Sda->CurrentPsp != SYSTEM_PSP)
|
||||||
{
|
{
|
||||||
/* Push the task state */
|
/* Push the task state */
|
||||||
DosSaveState();
|
DosSaveState();
|
||||||
|
|
||||||
/* Update the last stack in the PSP */
|
/* Update the last stack in the PSP */
|
||||||
SEGMENT_TO_PSP(CurrentPsp)->LastStack = MAKELONG(getSP(), getSS());
|
SEGMENT_TO_PSP(Sda->CurrentPsp)->LastStack = MAKELONG(getSP(), getSS());
|
||||||
}
|
}
|
||||||
|
|
||||||
/* Set the initial segment registers */
|
/* Set the initial segment registers */
|
||||||
|
@ -906,10 +902,10 @@ Done:
|
||||||
IntVecTable[0x24] = PspBlock->CriticalAddress;
|
IntVecTable[0x24] = PspBlock->CriticalAddress;
|
||||||
|
|
||||||
/* Update the current PSP */
|
/* Update the current PSP */
|
||||||
if (Psp == CurrentPsp)
|
if (Psp == Sda->CurrentPsp)
|
||||||
{
|
{
|
||||||
CurrentPsp = PspBlock->ParentPsp;
|
Sda->CurrentPsp = PspBlock->ParentPsp;
|
||||||
if (CurrentPsp == SYSTEM_PSP)
|
if (Sda->CurrentPsp == SYSTEM_PSP)
|
||||||
{
|
{
|
||||||
ResetEvent(VdmTaskEvent);
|
ResetEvent(VdmTaskEvent);
|
||||||
CpuUnsimulate();
|
CpuUnsimulate();
|
||||||
|
@ -935,11 +931,11 @@ Done:
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
/* Save the return code - Normal termination */
|
/* Save the return code - Normal termination */
|
||||||
DosErrorLevel = MAKEWORD(ReturnCode, 0x00);
|
Sda->ErrorLevel = MAKEWORD(ReturnCode, 0x00);
|
||||||
|
|
||||||
/* Restore the old stack */
|
/* Restore the old stack */
|
||||||
setSS(HIWORD(SEGMENT_TO_PSP(CurrentPsp)->LastStack));
|
setSS(HIWORD(SEGMENT_TO_PSP(Sda->CurrentPsp)->LastStack));
|
||||||
setSP(LOWORD(SEGMENT_TO_PSP(CurrentPsp)->LastStack));
|
setSP(LOWORD(SEGMENT_TO_PSP(Sda->CurrentPsp)->LastStack));
|
||||||
|
|
||||||
/* Are we returning to DOS code? */
|
/* Are we returning to DOS code? */
|
||||||
if (HIWORD(PspBlock->TerminateAddress) == DOS_CODE_SEGMENT)
|
if (HIWORD(PspBlock->TerminateAddress) == DOS_CODE_SEGMENT)
|
||||||
|
|
Loading…
Add table
Add a link
Reference in a new issue