#define NDEBUG
#include "emulator.h"
-#include "callback.h"
+#include "cpu/cpu.h"
+#include "int32.h"
#include "dos.h"
#include "dos/dem.h"
#include "bios/bios.h"
-#include "registers.h"
/* PRIVATE VARIABLES **********************************************************/
/* Add the string buffer size */
TotalSize += strlen(ProgramName) + 1;
+ /* Add the two extra bytes */
+ TotalSize += 2;
+
/* Allocate the memory for the environment block */
DestSegment = DosAllocateMemory((WORD)((TotalSize + 0x0F) >> 4), NULL);
if (!DestSegment) return 0;
/* Set the final zero */
*(DestBuffer++) = 0;
+ /* Store the special program name tag */
+ *(DestBuffer++) = LOBYTE(DOS_PROGRAM_NAME_TAG);
+ *(DestBuffer++) = HIBYTE(DOS_PROGRAM_NAME_TAG);
+
/* Copy the program name after the environment block */
strcpy(DestBuffer, ProgramName);
PDOS_PSP PspBlock = SEGMENT_TO_PSP(PspSegment);
LPDWORD IntVecTable = (LPDWORD)((ULONG_PTR)BaseAddress);
- ZeroMemory(PspBlock, sizeof(DOS_PSP));
+ RtlZeroMemory(PspBlock, sizeof(*PspBlock));
/* Set the exit interrupt */
PspBlock->Exit[0] = 0xCD; // int 0x20
PIMAGE_DOS_HEADER Header;
PDWORD RelocationTable;
PWORD RelocWord;
+ LPSTR CmdLinePtr = (LPSTR)CommandLine;
DPRINT1("DosLoadExecutable(%d, %s, %s, %s, 0x%08X, 0x%08X)\n",
LoadType,
return ERROR_NOT_SUPPORTED;
}
+ /* NULL-terminate the command line by removing the return carriage character */
+ while (*CmdLinePtr && *CmdLinePtr != '\r') CmdLinePtr++;
+ *CmdLinePtr = '\0';
+
/* Open a handle to the executable */
FileHandle = CreateFileA(ExecutablePath,
GENERIC_READ,
/* Check if at least the lowest allocation was successful */
if (Segment == 0)
{
- Result = ERROR_NOT_ENOUGH_MEMORY;
+ Result = DosLastError;
goto Cleanup;
}
setES(Segment);
/* Set the stack to the location from the header */
- EmulatorSetStack(Segment + (sizeof(DOS_PSP) >> 4) + Header->e_ss,
- Header->e_sp);
+ setSS(Segment + (sizeof(DOS_PSP) >> 4) + Header->e_ss);
+ setSP(Header->e_sp);
/* Execute */
CurrentPsp = Segment;
DiskTransferArea = MAKELONG(0x80, Segment);
- EmulatorExecute(Segment + Header->e_cs + (sizeof(DOS_PSP) >> 4),
- Header->e_ip);
+ CpuExecute(Segment + Header->e_cs + (sizeof(DOS_PSP) >> 4),
+ Header->e_ip);
}
}
else
Segment = DosAllocateMemory(MaxAllocSize, NULL);
if (Segment == 0)
{
- Result = ERROR_ARENA_TRASHED;
+ Result = DosLastError;
goto Cleanup;
}
setES(Segment);
/* Set the stack to the last word of the segment */
- EmulatorSetStack(Segment, 0xFFFE);
+ setSS(Segment);
+ setSP(0xFFFE);
/*
* Set the value on the stack to 0, so that a near return
/* Execute */
CurrentPsp = Segment;
DiskTransferArea = MAKELONG(0x80, Segment);
- EmulatorExecute(Segment, 0x100);
+ CpuExecute(Segment, 0x100);
}
}
/* Start simulation */
SetEvent(VdmTaskEvent);
- EmulatorSimulate();
+ CpuSimulate();
/* Detach from the console */
VidBiosDetachFromConsole(); // FIXME: And in fact, detach the full NTVDM UI from the console
}
/* Set up the startup info structure */
- ZeroMemory(&StartupInfo, sizeof(STARTUPINFOA));
- StartupInfo.cb = sizeof(STARTUPINFOA);
+ RtlZeroMemory(&StartupInfo, sizeof(StartupInfo));
+ StartupInfo.cb = sizeof(StartupInfo);
/* Create the process */
if (!CreateProcessA(ProgramName,
case SCS_WOW_BINARY:
{
/* Clear the structure */
- ZeroMemory(&CommandInfo, sizeof(CommandInfo));
+ RtlZeroMemory(&CommandInfo, sizeof(CommandInfo));
/* Initialize the structure members */
CommandInfo.TaskId = SessionId;
if (CurrentPsp == SYSTEM_PSP)
{
ResetEvent(VdmTaskEvent);
- EmulatorUnsimulate();
+ CpuUnsimulate();
}
}
GetNextVDMCommand(&CommandInfo);
/* Clear the structure */
- ZeroMemory(&CommandInfo, sizeof(CommandInfo));
+ RtlZeroMemory(&CommandInfo, sizeof(CommandInfo));
/* Update the VDM state of the task */
CommandInfo.TaskId = SessionId;
DosErrorLevel = MAKEWORD(ReturnCode, 0x00);
/* Return control to the parent process */
- EmulatorExecute(HIWORD(PspBlock->TerminateAddress),
- LOWORD(PspBlock->TerminateAddress));
+ CpuExecute(HIWORD(PspBlock->TerminateAddress),
+ LOWORD(PspBlock->TerminateAddress));
}
BOOLEAN DosHandleIoctl(BYTE ControlCode, WORD FileHandle)
{
/* Console input */
InfoWord |= 1 << 0;
+
+ /* It is a device */
+ InfoWord |= 1 << 7;
}
else if (Handle == DosSystemFileTable[DOS_OUTPUT_HANDLE].Handle)
{
/* Console output */
InfoWord |= 1 << 1;
- }
- /* It is a device */
- InfoWord |= 1 << 7;
+ /* It is a device */
+ InfoWord |= 1 << 7;
+ }
/* Return the device information word */
setDX(InfoWord);
case 0x25:
{
ULONG FarPointer = MAKELONG(getDX(), getDS());
- DPRINT1("Setting interrupt 0x%x ...\n", getAL());
+ DPRINT1("Setting interrupt 0x%02X to %04X:%04X ...\n",
+ getAL(), HIWORD(FarPointer), LOWORD(FarPointer));
/* Write the new far pointer to the IDT */
((PULONG)BaseAddress)[getAL()] = FarPointer;
* Return DOS OEM number:
* 0x00 for IBM PC-DOS
* 0x02 for packaged MS-DOS
+ * 0xFF for NT DOS
*/
- setBH(0x02);
+ setBH(0xFF);
}
if (LOBYTE(PspBlock->DosVersion) >= 5 && getAL() == 0x01)
break;
}
+ /* Get Extended Error Information */
+ case 0x59:
+ {
+ DPRINT1("INT 21h, AH = 59h, BX = %04Xh - Get Extended Error Information is UNIMPLEMENTED\n",
+ getBX());
+ break;
+ }
+
/* Create Temporary File */
case 0x5A:
{
/* Extended Open/Create */
case 0x6C:
{
+ WORD FileHandle;
+ WORD CreationStatus;
+ WORD ErrorCode;
+
/* Check for AL == 00 */
if (getAL() != 0x00)
{
break;
}
- // TODO!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!
- // FIXME: Extend and merge DosOpenFile and DosCreateFile into
- // a single wrapper around CreateFileA, which acts as:
- // http://www.ctyme.com/intr/rb-3179.htm
+ /*
+ * See Ralf Brown: http://www.ctyme.com/intr/rb-3179.htm
+ * for the full detailed description.
+ *
+ * WARNING: BH contains some extended flags that are NOT SUPPORTED.
+ */
+
+ ErrorCode = DosCreateFileEx(&FileHandle,
+ &CreationStatus,
+ (LPCSTR)SEG_OFF_TO_PTR(getDS(), getSI()),
+ getBL(),
+ getDL(),
+ getCX());
+
+ if (ErrorCode == ERROR_SUCCESS)
+ {
+ Stack[STACK_FLAGS] &= ~EMULATOR_FLAG_CF;
+ setCX(CreationStatus);
+ setAX(FileHandle);
+ }
+ else
+ {
+ Stack[STACK_FLAGS] |= EMULATOR_FLAG_CF;
+ setAX(ErrorCode);
+ }
break;
}
/* Stop the VDM task */
ResetEvent(VdmTaskEvent);
- EmulatorUnsimulate();
+ CpuUnsimulate();
}
VOID WINAPI DosFastConOut(LPWORD Stack)
WCHAR Buffer[256];
/* Clear the current directory buffer */
- ZeroMemory(CurrentDirectories, sizeof(CurrentDirectories));
+ RtlZeroMemory(CurrentDirectories, sizeof(CurrentDirectories));
/* Get the current directory */
if (!GetCurrentDirectoryA(MAX_PATH, CurrentDirectory))