Modify the flags on the stack instead of the flags register directly.
The flags register is restored during IRET so changing it directly does nothing.


svn path=/branches/ntvdm/; revision=59566
This commit is contained in:
Aleksandar Andrejevic 2013-07-23 21:43:57 +00:00
parent 6be35ef0bb
commit b49476f20c
6 changed files with 127 additions and 111 deletions

View file

@ -57,7 +57,7 @@ static VIDEO_MODE VideoModes[] =
/* PRIVATE FUNCTIONS **********************************************************/ /* PRIVATE FUNCTIONS **********************************************************/
static DWORD BiosGetVideoPageSize() static DWORD BiosGetVideoPageSize(VOID)
{ {
INT i; INT i;
DWORD BufferSize = VideoModes[CurrentVideoMode].Width DWORD BufferSize = VideoModes[CurrentVideoMode].Width
@ -135,7 +135,7 @@ static BOOLEAN BiosKbdBufferTop(LPWORD Data)
return TRUE; return TRUE;
} }
static BOOLEAN BiosKbdBufferPop() static BOOLEAN BiosKbdBufferPop(VOID)
{ {
/* If it's empty, fail */ /* If it's empty, fail */
if (Bda->KeybdBufferHead == Bda->KeybdBufferTail) return FALSE; if (Bda->KeybdBufferHead == Bda->KeybdBufferTail) return FALSE;
@ -214,7 +214,7 @@ static BOOLEAN BiosCreateGraphicsBuffer(BYTE ModeNumber)
return TRUE; return TRUE;
} }
static VOID BiosDestroyGraphicsBuffer() static VOID BiosDestroyGraphicsBuffer(VOID)
{ {
CloseHandle(ConsoleMutex); CloseHandle(ConsoleMutex);
CloseHandle(BiosGraphicsOutput); CloseHandle(BiosGraphicsOutput);
@ -222,7 +222,7 @@ static VOID BiosDestroyGraphicsBuffer()
/* PUBLIC FUNCTIONS ***********************************************************/ /* PUBLIC FUNCTIONS ***********************************************************/
BYTE BiosGetVideoMode() BYTE BiosGetVideoMode(VOID)
{ {
return CurrentVideoMode; return CurrentVideoMode;
} }
@ -335,12 +335,12 @@ BOOLEAN BiosSetVideoPage(BYTE PageNumber)
return TRUE; return TRUE;
} }
inline DWORD BiosGetVideoMemoryStart() inline DWORD BiosGetVideoMemoryStart(VOID)
{ {
return (VideoModes[CurrentVideoMode].Segment << 4); return (VideoModes[CurrentVideoMode].Segment << 4);
} }
inline VOID BiosVerticalRefresh() inline VOID BiosVerticalRefresh(VOID)
{ {
/* Ignore if we're in text mode */ /* Ignore if we're in text mode */
if (VideoModes[CurrentVideoMode].Text) return; if (VideoModes[CurrentVideoMode].Text) return;
@ -355,7 +355,7 @@ inline VOID BiosVerticalRefresh()
VideoNeedsUpdate = FALSE; VideoNeedsUpdate = FALSE;
} }
BOOLEAN BiosInitialize() BOOLEAN BiosInitialize(VOID)
{ {
INT i; INT i;
WORD Offset = 0; WORD Offset = 0;
@ -458,7 +458,7 @@ BOOLEAN BiosInitialize()
return TRUE; return TRUE;
} }
VOID BiosCleanup() VOID BiosCleanup(VOID)
{ {
/* Restore the old screen buffer */ /* Restore the old screen buffer */
SetConsoleActiveScreenBuffer(BiosConsoleOutput); SetConsoleActiveScreenBuffer(BiosConsoleOutput);
@ -611,7 +611,7 @@ VOID BiosUpdateVideoMemory(ULONG StartAddress, ULONG EndAddress)
} }
} }
WORD BiosPeekCharacter() WORD BiosPeekCharacter(VOID)
{ {
WORD CharacterData; WORD CharacterData;
@ -624,7 +624,7 @@ WORD BiosPeekCharacter()
return CharacterData; return CharacterData;
} }
WORD BiosGetCharacter() WORD BiosGetCharacter(VOID)
{ {
WORD CharacterData; WORD CharacterData;
INPUT_RECORD InputRecord; INPUT_RECORD InputRecord;
@ -660,7 +660,7 @@ WORD BiosGetCharacter()
return CharacterData; return CharacterData;
} }
VOID BiosVideoService() VOID BiosVideoService(LPWORD Stack)
{ {
INT i, CursorHeight; INT i, CursorHeight;
BOOLEAN Invisible = FALSE; BOOLEAN Invisible = FALSE;
@ -811,7 +811,8 @@ VOID BiosVideoService()
*((LPWORD)((ULONG_PTR)BaseAddress + Address))); *((LPWORD)((ULONG_PTR)BaseAddress + Address)));
break; break;
} } EmulatorSetFlag(EMULATOR_FLAG_ZF);
/* Write Character And Attribute At Cursor Position */ /* Write Character And Attribute At Cursor Position */
case 0x09: case 0x09:
@ -927,7 +928,7 @@ VOID BiosVideoService()
} }
} }
VOID BiosKeyboardService() VOID BiosKeyboardService(LPWORD Stack)
{ {
DWORD Eax = EmulatorGetRegister(EMULATOR_REG_AX); DWORD Eax = EmulatorGetRegister(EMULATOR_REG_AX);
@ -949,12 +950,12 @@ VOID BiosKeyboardService()
{ {
/* There is a character, clear ZF and return it */ /* There is a character, clear ZF and return it */
EmulatorSetRegister(EMULATOR_REG_AX, Data); EmulatorSetRegister(EMULATOR_REG_AX, Data);
EmulatorClearFlag(EMULATOR_FLAG_ZF); Stack[STACK_FLAGS] &= ~EMULATOR_FLAG_ZF;
} }
else else
{ {
/* No character, set ZF */ /* No character, set ZF */
EmulatorSetFlag(EMULATOR_FLAG_ZF); Stack[STACK_FLAGS] |= EMULATOR_FLAG_ZF;
} }
break; break;
@ -968,7 +969,7 @@ VOID BiosKeyboardService()
} }
} }
VOID BiosTimeService() VOID BiosTimeService(LPWORD Stack)
{ {
DWORD Eax = EmulatorGetRegister(EMULATOR_REG_AX); DWORD Eax = EmulatorGetRegister(EMULATOR_REG_AX);
DWORD Ecx = EmulatorGetRegister(EMULATOR_REG_CX); DWORD Ecx = EmulatorGetRegister(EMULATOR_REG_CX);
@ -1012,19 +1013,19 @@ VOID BiosTimeService()
} }
} }
VOID BiosSystemTimerInterrupt() VOID BiosSystemTimerInterrupt(LPWORD Stack)
{ {
/* Increase the system tick count */ /* Increase the system tick count */
Bda->TickCounter++; Bda->TickCounter++;
} }
VOID BiosEquipmentService() VOID BiosEquipmentService(LPWORD Stack)
{ {
/* Return the equipment list */ /* Return the equipment list */
EmulatorSetRegister(EMULATOR_REG_AX, Bda->EquipmentList); EmulatorSetRegister(EMULATOR_REG_AX, Bda->EquipmentList);
} }
VOID BiosHandleIrq(BYTE IrqNumber) VOID BiosHandleIrq(BYTE IrqNumber, LPWORD Stack)
{ {
switch (IrqNumber) switch (IrqNumber)
{ {

View file

@ -97,19 +97,19 @@ typedef struct
/* FUNCTIONS ******************************************************************/ /* FUNCTIONS ******************************************************************/
BOOLEAN BiosInitialize(); BOOLEAN BiosInitialize(VOID);
VOID BiosCleanup(); VOID BiosCleanup(VOID);
VOID BiosUpdateConsole(ULONG StartAddress, ULONG EndAddress); VOID BiosUpdateConsole(ULONG StartAddress, ULONG EndAddress);
VOID BiosUpdateVideoMemory(ULONG StartAddress, ULONG EndAddress); VOID BiosUpdateVideoMemory(ULONG StartAddress, ULONG EndAddress);
inline DWORD BiosGetVideoMemoryStart(); inline DWORD BiosGetVideoMemoryStart(VOID);
inline VOID BiosVerticalRefresh(); inline VOID BiosVerticalRefresh(VOID);
WORD BiosPeekCharacter(); WORD BiosPeekCharacter(VOID);
WORD BiosGetCharacter(); WORD BiosGetCharacter(VOID);
VOID BiosVideoService(); VOID BiosVideoService(LPWORD Stack);
VOID BiosEquipmentService(); VOID BiosEquipmentService(LPWORD Stack);
VOID BiosKeyboardService(); VOID BiosKeyboardService(LPWORD Stack);
VOID BiosTimeService(); VOID BiosTimeService(LPWORD Stack);
VOID BiosHandleIrq(BYTE IrqNumber); VOID BiosHandleIrq(BYTE IrqNumber, LPWORD Stack);
VOID BiosSystemTimerInterrupt(); VOID BiosSystemTimerInterrupt(LPWORD Stack);
#endif #endif

View file

@ -1161,15 +1161,15 @@ VOID DosPrintCharacter(CHAR Character)
DosWriteFile(DOS_OUTPUT_HANDLE, &Character, sizeof(CHAR), &BytesWritten); DosWriteFile(DOS_OUTPUT_HANDLE, &Character, sizeof(CHAR), &BytesWritten);
} }
VOID DosHandleIoctl(BYTE ControlCode, WORD FileHandle) BOOLEAN DosHandleIoctl(BYTE ControlCode, WORD FileHandle)
{ {
HANDLE Handle = DosGetRealHandle(FileHandle); HANDLE Handle = DosGetRealHandle(FileHandle);
if (Handle == INVALID_HANDLE_VALUE) if (Handle == INVALID_HANDLE_VALUE)
{ {
/* Doesn't exist */ /* Doesn't exist */
EmulatorSetFlag(EMULATOR_FLAG_CF); DosLastError = ERROR_FILE_NOT_FOUND;
EmulatorSetRegister(EMULATOR_REG_AX, ERROR_FILE_NOT_FOUND); return FALSE;
} }
switch (ControlCode) switch (ControlCode)
@ -1194,10 +1194,9 @@ VOID DosHandleIoctl(BYTE ControlCode, WORD FileHandle)
InfoWord |= 1 << 7; InfoWord |= 1 << 7;
/* Return the device information word */ /* Return the device information word */
EmulatorClearFlag(EMULATOR_FLAG_CF);
EmulatorSetRegister(EMULATOR_REG_DX, InfoWord); EmulatorSetRegister(EMULATOR_REG_DX, InfoWord);
break; return TRUE;
} }
/* Unsupported control code */ /* Unsupported control code */
@ -1205,19 +1204,19 @@ VOID DosHandleIoctl(BYTE ControlCode, WORD FileHandle)
{ {
DPRINT1("Unsupported IOCTL: 0x%02X\n", ControlCode); DPRINT1("Unsupported IOCTL: 0x%02X\n", ControlCode);
EmulatorSetFlag(EMULATOR_FLAG_CF); DosLastError = ERROR_INVALID_PARAMETER;
EmulatorSetRegister(EMULATOR_REG_AX, ERROR_INVALID_PARAMETER); return FALSE;
} }
} }
} }
VOID DosInt20h(WORD CodeSegment) VOID DosInt20h(LPWORD Stack)
{ {
/* This is the exit interrupt */ /* This is the exit interrupt */
DosTerminateProcess(CodeSegment, 0); DosTerminateProcess(Stack[STACK_CS], 0);
} }
VOID DosInt21h(WORD CodeSegment) VOID DosInt21h(LPWORD Stack)
{ {
INT i; INT i;
CHAR Character; CHAR Character;
@ -1237,7 +1236,7 @@ VOID DosInt21h(WORD CodeSegment)
/* Terminate Program */ /* Terminate Program */
case 0x00: case 0x00:
{ {
DosTerminateProcess(CodeSegment, 0); DosTerminateProcess(Stack[STACK_CS], 0);
break; break;
} }
@ -1432,11 +1431,11 @@ VOID DosInt21h(WORD CodeSegment)
if (CreateDirectoryA(String, NULL)) if (CreateDirectoryA(String, NULL))
{ {
EmulatorClearFlag(EMULATOR_FLAG_CF); Stack[STACK_FLAGS] &= ~EMULATOR_FLAG_CF;
} }
else else
{ {
EmulatorSetFlag(EMULATOR_FLAG_CF); Stack[STACK_FLAGS] |= EMULATOR_FLAG_CF;
EmulatorSetRegister(EMULATOR_REG_AX, EmulatorSetRegister(EMULATOR_REG_AX,
(Eax & 0xFFFF0000) | LOWORD(GetLastError())); (Eax & 0xFFFF0000) | LOWORD(GetLastError()));
} }
@ -1452,11 +1451,11 @@ VOID DosInt21h(WORD CodeSegment)
if (RemoveDirectoryA(String)) if (RemoveDirectoryA(String))
{ {
EmulatorClearFlag(EMULATOR_FLAG_CF); Stack[STACK_FLAGS] &= ~EMULATOR_FLAG_CF;
} }
else else
{ {
EmulatorSetFlag(EMULATOR_FLAG_CF); Stack[STACK_FLAGS] |= EMULATOR_FLAG_CF;
EmulatorSetRegister(EMULATOR_REG_AX, EmulatorSetRegister(EMULATOR_REG_AX,
(Eax & 0xFFFF0000) | LOWORD(GetLastError())); (Eax & 0xFFFF0000) | LOWORD(GetLastError()));
} }
@ -1473,11 +1472,11 @@ VOID DosInt21h(WORD CodeSegment)
if (SetCurrentDirectoryA(String)) if (SetCurrentDirectoryA(String))
{ {
EmulatorClearFlag(EMULATOR_FLAG_CF); Stack[STACK_FLAGS] &= ~EMULATOR_FLAG_CF;
} }
else else
{ {
EmulatorSetFlag(EMULATOR_FLAG_CF); Stack[STACK_FLAGS] |= EMULATOR_FLAG_CF;
EmulatorSetRegister(EMULATOR_REG_AX, EmulatorSetRegister(EMULATOR_REG_AX,
(Eax & 0xFFFF0000) | LOWORD(GetLastError())); (Eax & 0xFFFF0000) | LOWORD(GetLastError()));
} }
@ -1497,7 +1496,7 @@ VOID DosInt21h(WORD CodeSegment)
if (ErrorCode == 0) if (ErrorCode == 0)
{ {
/* Clear CF */ /* Clear CF */
EmulatorClearFlag(EMULATOR_FLAG_CF); Stack[STACK_FLAGS] &= ~EMULATOR_FLAG_CF;
/* Return the handle in AX */ /* Return the handle in AX */
EmulatorSetRegister(EMULATOR_REG_AX, EmulatorSetRegister(EMULATOR_REG_AX,
@ -1506,7 +1505,7 @@ VOID DosInt21h(WORD CodeSegment)
else else
{ {
/* Set CF */ /* Set CF */
EmulatorSetFlag(EMULATOR_FLAG_CF); Stack[STACK_FLAGS] |= EMULATOR_FLAG_CF;
/* Return the error code in AX */ /* Return the error code in AX */
EmulatorSetRegister(EMULATOR_REG_AX, EmulatorSetRegister(EMULATOR_REG_AX,
@ -1528,7 +1527,7 @@ VOID DosInt21h(WORD CodeSegment)
if (ErrorCode == 0) if (ErrorCode == 0)
{ {
/* Clear CF */ /* Clear CF */
EmulatorClearFlag(EMULATOR_FLAG_CF); Stack[STACK_FLAGS] &= ~EMULATOR_FLAG_CF;
/* Return the handle in AX */ /* Return the handle in AX */
EmulatorSetRegister(EMULATOR_REG_AX, EmulatorSetRegister(EMULATOR_REG_AX,
@ -1537,7 +1536,7 @@ VOID DosInt21h(WORD CodeSegment)
else else
{ {
/* Set CF */ /* Set CF */
EmulatorSetFlag(EMULATOR_FLAG_CF); Stack[STACK_FLAGS] |= EMULATOR_FLAG_CF;
/* Return the error code in AX */ /* Return the error code in AX */
EmulatorSetRegister(EMULATOR_REG_AX, EmulatorSetRegister(EMULATOR_REG_AX,
@ -1553,12 +1552,12 @@ VOID DosInt21h(WORD CodeSegment)
if (DosCloseHandle(LOWORD(Ebx))) if (DosCloseHandle(LOWORD(Ebx)))
{ {
/* Clear CF */ /* Clear CF */
EmulatorClearFlag(EMULATOR_FLAG_CF); Stack[STACK_FLAGS] &= ~EMULATOR_FLAG_CF;
} }
else else
{ {
/* Set CF */ /* Set CF */
EmulatorSetFlag(EMULATOR_FLAG_CF); Stack[STACK_FLAGS] |= EMULATOR_FLAG_CF;
/* Return the error code in AX */ /* Return the error code in AX */
EmulatorSetRegister(EMULATOR_REG_AX, EmulatorSetRegister(EMULATOR_REG_AX,
@ -1581,7 +1580,7 @@ VOID DosInt21h(WORD CodeSegment)
if (ErrorCode == 0) if (ErrorCode == 0)
{ {
/* Clear CF */ /* Clear CF */
EmulatorClearFlag(EMULATOR_FLAG_CF); Stack[STACK_FLAGS] &= ~EMULATOR_FLAG_CF;
/* Return the number of bytes read in AX */ /* Return the number of bytes read in AX */
EmulatorSetRegister(EMULATOR_REG_AX, EmulatorSetRegister(EMULATOR_REG_AX,
@ -1590,7 +1589,7 @@ VOID DosInt21h(WORD CodeSegment)
else else
{ {
/* Set CF */ /* Set CF */
EmulatorSetFlag(EMULATOR_FLAG_CF); Stack[STACK_FLAGS] |= EMULATOR_FLAG_CF;
/* Return the error code in AX */ /* Return the error code in AX */
EmulatorSetRegister(EMULATOR_REG_AX, EmulatorSetRegister(EMULATOR_REG_AX,
@ -1612,7 +1611,7 @@ VOID DosInt21h(WORD CodeSegment)
if (ErrorCode == 0) if (ErrorCode == 0)
{ {
/* Clear CF */ /* Clear CF */
EmulatorClearFlag(EMULATOR_FLAG_CF); Stack[STACK_FLAGS] &= ~EMULATOR_FLAG_CF;
/* Return the number of bytes written in AX */ /* Return the number of bytes written in AX */
EmulatorSetRegister(EMULATOR_REG_AX, EmulatorSetRegister(EMULATOR_REG_AX,
@ -1621,7 +1620,7 @@ VOID DosInt21h(WORD CodeSegment)
else else
{ {
/* Set CF */ /* Set CF */
EmulatorSetFlag(EMULATOR_FLAG_CF); Stack[STACK_FLAGS] |= EMULATOR_FLAG_CF;
/* Return the error code in AX */ /* Return the error code in AX */
EmulatorSetRegister(EMULATOR_REG_AX, EmulatorSetRegister(EMULATOR_REG_AX,
@ -1637,10 +1636,10 @@ VOID DosInt21h(WORD CodeSegment)
LPSTR FileName = (LPSTR)((ULONG_PTR)BaseAddress + TO_LINEAR(DataSegment, Edx)); LPSTR FileName = (LPSTR)((ULONG_PTR)BaseAddress + TO_LINEAR(DataSegment, Edx));
/* Call the API function */ /* Call the API function */
if (DeleteFileA(FileName)) EmulatorClearFlag(EMULATOR_FLAG_CF); if (DeleteFileA(FileName)) Stack[STACK_FLAGS] &= ~EMULATOR_FLAG_CF;
else else
{ {
EmulatorSetFlag(EMULATOR_FLAG_CF); Stack[STACK_FLAGS] |= EMULATOR_FLAG_CF;
EmulatorSetRegister(EMULATOR_REG_AX, GetLastError()); EmulatorSetRegister(EMULATOR_REG_AX, GetLastError());
} }
@ -1659,7 +1658,7 @@ VOID DosInt21h(WORD CodeSegment)
if (ErrorCode == 0) if (ErrorCode == 0)
{ {
/* Clear CF */ /* Clear CF */
EmulatorClearFlag(EMULATOR_FLAG_CF); Stack[STACK_FLAGS] &= ~EMULATOR_FLAG_CF;
/* Return the new offset in DX:AX */ /* Return the new offset in DX:AX */
EmulatorSetRegister(EMULATOR_REG_DX, EmulatorSetRegister(EMULATOR_REG_DX,
@ -1670,7 +1669,7 @@ VOID DosInt21h(WORD CodeSegment)
else else
{ {
/* Set CF */ /* Set CF */
EmulatorSetFlag(EMULATOR_FLAG_CF); Stack[STACK_FLAGS] |= EMULATOR_FLAG_CF;
/* Return the error code in AX */ /* Return the error code in AX */
EmulatorSetRegister(EMULATOR_REG_AX, EmulatorSetRegister(EMULATOR_REG_AX,
@ -1694,14 +1693,14 @@ VOID DosInt21h(WORD CodeSegment)
/* Check if it failed */ /* Check if it failed */
if (Attributes == INVALID_FILE_ATTRIBUTES) if (Attributes == INVALID_FILE_ATTRIBUTES)
{ {
EmulatorSetFlag(EMULATOR_FLAG_CF); Stack[STACK_FLAGS] |= EMULATOR_FLAG_CF;
EmulatorSetRegister(EMULATOR_REG_AX, GetLastError()); EmulatorSetRegister(EMULATOR_REG_AX, GetLastError());
break; break;
} }
/* Return the attributes that DOS can understand */ /* Return the attributes that DOS can understand */
EmulatorClearFlag(EMULATOR_FLAG_CF); Stack[STACK_FLAGS] &= ~EMULATOR_FLAG_CF;
EmulatorSetRegister(EMULATOR_REG_CX, EmulatorSetRegister(EMULATOR_REG_CX,
(Ecx & 0xFFFFFF00) | LOBYTE(Attributes)); (Ecx & 0xFFFFFF00) | LOBYTE(Attributes));
} }
@ -1710,17 +1709,17 @@ VOID DosInt21h(WORD CodeSegment)
/* Try to set the attributes */ /* Try to set the attributes */
if (SetFileAttributesA(FileName, LOBYTE(Ecx))) if (SetFileAttributesA(FileName, LOBYTE(Ecx)))
{ {
EmulatorClearFlag(EMULATOR_FLAG_CF); Stack[STACK_FLAGS] &= ~EMULATOR_FLAG_CF;
} }
else else
{ {
EmulatorSetFlag(EMULATOR_FLAG_CF); Stack[STACK_FLAGS] |= EMULATOR_FLAG_CF;
EmulatorSetRegister(EMULATOR_REG_AX, GetLastError()); EmulatorSetRegister(EMULATOR_REG_AX, GetLastError());
} }
} }
else else
{ {
EmulatorSetFlag(EMULATOR_FLAG_CF); Stack[STACK_FLAGS] |= EMULATOR_FLAG_CF;
EmulatorSetRegister(EMULATOR_REG_AX, ERROR_INVALID_FUNCTION); EmulatorSetRegister(EMULATOR_REG_AX, ERROR_INVALID_FUNCTION);
} }
@ -1730,7 +1729,15 @@ VOID DosInt21h(WORD CodeSegment)
/* IOCTL */ /* IOCTL */
case 0x44: case 0x44:
{ {
DosHandleIoctl(LOBYTE(Eax), LOWORD(Ebx)); if (DosHandleIoctl(LOBYTE(Eax), LOWORD(Ebx)))
{
Stack[STACK_FLAGS] &= ~EMULATOR_FLAG_CF;
}
else
{
Stack[STACK_FLAGS] |= EMULATOR_FLAG_CF;
EmulatorSetRegister(EMULATOR_REG_AX, DosLastError);
}
break; break;
} }
@ -1744,7 +1751,7 @@ VOID DosInt21h(WORD CodeSegment)
if (Handle != INVALID_HANDLE_VALUE) if (Handle != INVALID_HANDLE_VALUE)
{ {
/* The handle is invalid */ /* The handle is invalid */
EmulatorSetFlag(EMULATOR_FLAG_CF); Stack[STACK_FLAGS] |= EMULATOR_FLAG_CF;
EmulatorSetRegister(EMULATOR_REG_AX, ERROR_INVALID_HANDLE); EmulatorSetRegister(EMULATOR_REG_AX, ERROR_INVALID_HANDLE);
break; break;
@ -1756,14 +1763,14 @@ VOID DosInt21h(WORD CodeSegment)
if (NewHandle == INVALID_DOS_HANDLE) if (NewHandle == INVALID_DOS_HANDLE)
{ {
/* Too many files open */ /* Too many files open */
EmulatorSetFlag(EMULATOR_FLAG_CF); Stack[STACK_FLAGS] |= EMULATOR_FLAG_CF;
EmulatorSetRegister(EMULATOR_REG_AX, ERROR_TOO_MANY_OPEN_FILES); EmulatorSetRegister(EMULATOR_REG_AX, ERROR_TOO_MANY_OPEN_FILES);
break; break;
} }
/* Return the result */ /* Return the result */
EmulatorClearFlag(EMULATOR_FLAG_CF); Stack[STACK_FLAGS] &= ~EMULATOR_FLAG_CF;
EmulatorSetRegister(EMULATOR_REG_AX, NewHandle); EmulatorSetRegister(EMULATOR_REG_AX, NewHandle);
break; break;
@ -1774,11 +1781,11 @@ VOID DosInt21h(WORD CodeSegment)
{ {
if (DosDuplicateHandle(LOWORD(Ebx), LOWORD(Ecx))) if (DosDuplicateHandle(LOWORD(Ebx), LOWORD(Ecx)))
{ {
EmulatorClearFlag(EMULATOR_FLAG_CF); Stack[STACK_FLAGS] &= ~EMULATOR_FLAG_CF;
} }
else else
{ {
EmulatorSetFlag(EMULATOR_FLAG_CF); Stack[STACK_FLAGS] |= EMULATOR_FLAG_CF;
EmulatorSetRegister(EMULATOR_REG_AX, ERROR_INVALID_HANDLE); EmulatorSetRegister(EMULATOR_REG_AX, ERROR_INVALID_HANDLE);
} }
@ -1794,13 +1801,13 @@ VOID DosInt21h(WORD CodeSegment)
if (Segment != 0) if (Segment != 0)
{ {
EmulatorSetRegister(EMULATOR_REG_AX, Segment); EmulatorSetRegister(EMULATOR_REG_AX, Segment);
EmulatorClearFlag(EMULATOR_FLAG_CF); Stack[STACK_FLAGS] &= ~EMULATOR_FLAG_CF;
} }
else else
{ {
EmulatorSetRegister(EMULATOR_REG_AX, DosLastError); EmulatorSetRegister(EMULATOR_REG_AX, DosLastError);
EmulatorSetRegister(EMULATOR_REG_BX, MaxAvailable); EmulatorSetRegister(EMULATOR_REG_BX, MaxAvailable);
EmulatorSetFlag(EMULATOR_FLAG_CF); Stack[STACK_FLAGS] |= EMULATOR_FLAG_CF;
} }
break; break;
@ -1811,12 +1818,12 @@ VOID DosInt21h(WORD CodeSegment)
{ {
if (DosFreeMemory(ExtSegment)) if (DosFreeMemory(ExtSegment))
{ {
EmulatorClearFlag(EMULATOR_FLAG_CF); Stack[STACK_FLAGS] &= ~EMULATOR_FLAG_CF;
} }
else else
{ {
EmulatorSetRegister(EMULATOR_REG_AX, ERROR_ARENA_TRASHED); EmulatorSetRegister(EMULATOR_REG_AX, ERROR_ARENA_TRASHED);
EmulatorSetFlag(EMULATOR_FLAG_CF); Stack[STACK_FLAGS] |= EMULATOR_FLAG_CF;
} }
break; break;
@ -1829,12 +1836,12 @@ VOID DosInt21h(WORD CodeSegment)
if (DosResizeMemory(ExtSegment, LOWORD(Ebx), &Size)) if (DosResizeMemory(ExtSegment, LOWORD(Ebx), &Size))
{ {
EmulatorClearFlag(EMULATOR_FLAG_CF); Stack[STACK_FLAGS] &= ~EMULATOR_FLAG_CF;
} }
else else
{ {
EmulatorSetRegister(EMULATOR_REG_AX, DosLastError); EmulatorSetRegister(EMULATOR_REG_AX, DosLastError);
EmulatorSetFlag(EMULATOR_FLAG_CF); Stack[STACK_FLAGS] |= EMULATOR_FLAG_CF;
EmulatorSetRegister(EMULATOR_REG_BX, Size); EmulatorSetRegister(EMULATOR_REG_BX, Size);
} }
@ -1864,7 +1871,7 @@ VOID DosInt21h(WORD CodeSegment)
/* Get allocation strategy */ /* Get allocation strategy */
EmulatorSetRegister(EMULATOR_REG_AX, DosAllocStrategy); EmulatorSetRegister(EMULATOR_REG_AX, DosAllocStrategy);
EmulatorClearFlag(EMULATOR_FLAG_CF); Stack[STACK_FLAGS] &= ~EMULATOR_FLAG_CF;
} }
else if (LOBYTE(Eax) == 0x01) else if (LOBYTE(Eax) == 0x01)
{ {
@ -1875,7 +1882,7 @@ VOID DosInt21h(WORD CodeSegment)
{ {
/* Can't set both */ /* Can't set both */
EmulatorSetRegister(EMULATOR_REG_AX, ERROR_INVALID_PARAMETER); EmulatorSetRegister(EMULATOR_REG_AX, ERROR_INVALID_PARAMETER);
EmulatorSetFlag(EMULATOR_FLAG_CF); Stack[STACK_FLAGS] |= EMULATOR_FLAG_CF;
break; break;
} }
@ -1883,12 +1890,12 @@ VOID DosInt21h(WORD CodeSegment)
{ {
/* Invalid allocation strategy */ /* Invalid allocation strategy */
EmulatorSetRegister(EMULATOR_REG_AX, ERROR_INVALID_PARAMETER); EmulatorSetRegister(EMULATOR_REG_AX, ERROR_INVALID_PARAMETER);
EmulatorSetFlag(EMULATOR_FLAG_CF); Stack[STACK_FLAGS] |= EMULATOR_FLAG_CF;
break; break;
} }
DosAllocStrategy = LOBYTE(Ebx); DosAllocStrategy = LOBYTE(Ebx);
EmulatorClearFlag(EMULATOR_FLAG_CF); Stack[STACK_FLAGS] &= ~EMULATOR_FLAG_CF;
} }
else if (LOBYTE(Eax) == 0x02) else if (LOBYTE(Eax) == 0x02)
{ {
@ -1897,7 +1904,7 @@ VOID DosInt21h(WORD CodeSegment)
Eax &= 0xFFFFFF00; Eax &= 0xFFFFFF00;
if (DosUmbLinked) Eax |= 1; if (DosUmbLinked) Eax |= 1;
EmulatorSetRegister(EMULATOR_REG_AX, Eax); EmulatorSetRegister(EMULATOR_REG_AX, Eax);
EmulatorClearFlag(EMULATOR_FLAG_CF); Stack[STACK_FLAGS] &= ~EMULATOR_FLAG_CF;
} }
else if (LOBYTE(Eax) == 0x03) else if (LOBYTE(Eax) == 0x03)
{ {
@ -1905,13 +1912,13 @@ VOID DosInt21h(WORD CodeSegment)
if (Ebx) DosLinkUmb(); if (Ebx) DosLinkUmb();
else DosUnlinkUmb(); else DosUnlinkUmb();
EmulatorClearFlag(EMULATOR_FLAG_CF); Stack[STACK_FLAGS] &= ~EMULATOR_FLAG_CF;
} }
else else
{ {
/* Invalid or unsupported function */ /* Invalid or unsupported function */
EmulatorSetFlag(EMULATOR_FLAG_CF); Stack[STACK_FLAGS] |= EMULATOR_FLAG_CF;
EmulatorSetRegister(EMULATOR_REG_AX, ERROR_INVALID_FUNCTION); EmulatorSetRegister(EMULATOR_REG_AX, ERROR_INVALID_FUNCTION);
} }
@ -1922,12 +1929,12 @@ VOID DosInt21h(WORD CodeSegment)
default: default:
{ {
DPRINT1("DOS Function INT 0x21, AH = 0x%02X NOT IMPLEMENTED!\n", HIBYTE(Eax)); DPRINT1("DOS Function INT 0x21, AH = 0x%02X NOT IMPLEMENTED!\n", HIBYTE(Eax));
EmulatorSetFlag(EMULATOR_FLAG_CF); Stack[STACK_FLAGS] |= EMULATOR_FLAG_CF;
} }
} }
} }
VOID DosBreakInterrupt(VOID) VOID DosBreakInterrupt(LPWORD Stack)
{ {
VdmRunning = FALSE; VdmRunning = FALSE;
} }

View file

@ -117,9 +117,10 @@ BOOLEAN DosCreateProcess(LPCSTR CommandLine, WORD EnvBlock);
VOID DosTerminateProcess(WORD Psp, BYTE ReturnCode); VOID DosTerminateProcess(WORD Psp, BYTE ReturnCode);
CHAR DosReadCharacter(VOID); CHAR DosReadCharacter(VOID);
VOID DosPrintCharacter(CHAR Character); VOID DosPrintCharacter(CHAR Character);
VOID DosInt20h(WORD CodeSegment); BOOLEAN DosHandleIoctl(BYTE ControlCode, WORD FileHandle);
VOID DosInt21h(WORD CodeSegment); VOID DosInt20h(LPWORD Stack);
VOID DosBreakInterrupt(VOID); VOID DosInt21h(LPWORD Stack);
VOID DosBreakInterrupt(LPWORD Stack);
BOOLEAN DosInitialize(VOID); BOOLEAN DosInitialize(VOID);
#endif #endif

View file

@ -114,6 +114,11 @@ static VOID EmulatorReadIo(PVOID Context, UINT Address, LPBYTE Buffer, INT Size)
*Buffer = KeyboardReadData(); *Buffer = KeyboardReadData();
break; break;
} }
default:
{
DPRINT1("Read from unknown port: 0x%X\n", Address);
}
} }
} }
@ -162,6 +167,11 @@ static VOID EmulatorWriteIo(PVOID Context, UINT Address, LPBYTE Buffer, INT Size
KeyboardWriteData(Byte); KeyboardWriteData(Byte);
break; break;
} }
default:
{
DPRINT1("Write to unknown port: 0x%X\n", Address);
}
} }
} }
@ -186,11 +196,11 @@ static VOID EmulatorBop(WORD Code)
if (Code == EMULATOR_INT_BOP) if (Code == EMULATOR_INT_BOP)
{ {
/* Get the interrupt number */ /* Get the interrupt number */
IntNum = LOBYTE(Stack[0]); IntNum = LOBYTE(Stack[STACK_INT_NUM]);
/* Get the CS:IP */ /* Get the CS:IP */
InstructionPointer = Stack[1]; InstructionPointer = Stack[STACK_IP];
CodeSegment = Stack[2]; CodeSegment = Stack[STACK_CS];
/* Check if this was an exception */ /* Check if this was an exception */
if (IntNum < 8) if (IntNum < 8)
@ -210,13 +220,13 @@ static VOID EmulatorBop(WORD Code)
if (IntNum >= BIOS_PIC_MASTER_INT && IntNum < BIOS_PIC_MASTER_INT + 8) if (IntNum >= BIOS_PIC_MASTER_INT && IntNum < BIOS_PIC_MASTER_INT + 8)
{ {
/* It was an IRQ from the master PIC */ /* It was an IRQ from the master PIC */
BiosHandleIrq(IntNum - BIOS_PIC_MASTER_INT); BiosHandleIrq(IntNum - BIOS_PIC_MASTER_INT, Stack);
return; return;
} }
else if (IntNum >= BIOS_PIC_SLAVE_INT && IntNum < BIOS_PIC_SLAVE_INT + 8) else if (IntNum >= BIOS_PIC_SLAVE_INT && IntNum < BIOS_PIC_SLAVE_INT + 8)
{ {
/* It was an IRQ from the slave PIC */ /* It was an IRQ from the slave PIC */
BiosHandleIrq(IntNum - BIOS_PIC_SLAVE_INT + 8); BiosHandleIrq(IntNum - BIOS_PIC_SLAVE_INT + 8, Stack);
return; return;
} }
@ -225,46 +235,46 @@ static VOID EmulatorBop(WORD Code)
case BIOS_VIDEO_INTERRUPT: case BIOS_VIDEO_INTERRUPT:
{ {
/* This is the video BIOS interrupt, call the BIOS */ /* This is the video BIOS interrupt, call the BIOS */
BiosVideoService(); BiosVideoService(Stack);
break; break;
} }
case BIOS_EQUIPMENT_INTERRUPT: case BIOS_EQUIPMENT_INTERRUPT:
{ {
/* This is the BIOS "get equipment" command, call the BIOS */ /* This is the BIOS "get equipment" command, call the BIOS */
BiosEquipmentService(); BiosEquipmentService(Stack);
break; break;
} }
case BIOS_KBD_INTERRUPT: case BIOS_KBD_INTERRUPT:
{ {
/* This is the keyboard BIOS interrupt, call the BIOS */ /* This is the keyboard BIOS interrupt, call the BIOS */
BiosKeyboardService(); BiosKeyboardService(Stack);
break; break;
} }
case BIOS_TIME_INTERRUPT: case BIOS_TIME_INTERRUPT:
{ {
/* This is the time BIOS interrupt, call the BIOS */ /* This is the time BIOS interrupt, call the BIOS */
BiosTimeService(); BiosTimeService(Stack);
break; break;
} }
case BIOS_SYS_TIMER_INTERRUPT: case BIOS_SYS_TIMER_INTERRUPT:
{ {
/* BIOS timer update */ /* BIOS timer update */
BiosSystemTimerInterrupt(); BiosSystemTimerInterrupt(Stack);
break; break;
} }
case 0x20: case 0x20:
{ {
DosInt20h(CodeSegment); DosInt20h(Stack);
break; break;
} }
case 0x21: case 0x21:
{ {
DosInt21h(CodeSegment); DosInt21h(Stack);
break; break;
} }
case 0x23: case 0x23:
{ {
DosBreakInterrupt(); DosBreakInterrupt(Stack);
break; break;
} }
default: default:
@ -273,13 +283,6 @@ static VOID EmulatorBop(WORD Code)
break; break;
} }
} }
/* Update the flags on the stack */
#ifndef NEW_EMULATOR
Stack[3] = EmulatorContext.state->reg_flags.val;
#else
Stack[3] = EmulatorContext.Flags.LowWord;
#endif
} }
} }

View file

@ -72,6 +72,10 @@
#define MAX_GDT_ENTRIES 8192 #define MAX_GDT_ENTRIES 8192
#define EMULATOR_BOP 0xC4C4 #define EMULATOR_BOP 0xC4C4
#define EMULATOR_INT_BOP 0xBEEF #define EMULATOR_INT_BOP 0xBEEF
#define STACK_INT_NUM 0
#define STACK_IP 1
#define STACK_CS 2
#define STACK_FLAGS 3
enum enum
{ {