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:
Aleksandar Andrejevic 2015-05-11 02:54:46 +00:00
parent f1bf14da62
commit e4960b02d3
8 changed files with 270 additions and 114 deletions

View file

@ -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)

View file

@ -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;
} }

View file

@ -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;

View file

@ -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 ******************************************************************/

View file

@ -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;
} }
} }

View file

@ -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 */

View file

@ -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;
} }

View file

@ -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)