Fix INT 21h/0Ah.
DosReadCharacter shouldn't echo all the time.


svn path=/trunk/; revision=69359
This commit is contained in:
Aleksandar Andrejevic 2015-09-26 00:05:10 +00:00
parent ac8f71fc86
commit acfe187655
5 changed files with 104 additions and 96 deletions

View file

@ -79,16 +79,14 @@ VOID DosEchoCharacter(CHAR Character)
DosPrintCharacter(DOS_OUTPUT_HANDLE, '^'); DosPrintCharacter(DOS_OUTPUT_HANDLE, '^');
Character += 'A' - 1; Character += 'A' - 1;
} }
else
{
/* Echo the character */ /* Echo the character */
DosPrintCharacter(DOS_OUTPUT_HANDLE, Character); DosPrintCharacter(DOS_OUTPUT_HANDLE, Character);
} }
} }
} }
}
CHAR DosReadCharacter(WORD FileHandle) CHAR DosReadCharacter(WORD FileHandle, BOOLEAN Echo)
{ {
WORD BytesRead; WORD BytesRead;
PDOS_FILE_DESCRIPTOR Descriptor = NULL; PDOS_FILE_DESCRIPTOR Descriptor = NULL;
@ -111,8 +109,8 @@ CHAR DosReadCharacter(WORD FileHandle)
1, 1,
&BytesRead); &BytesRead);
/* Check if the file is actually the CON device */ /* Check if we should echo and the file is actually the CON device */
if (Descriptor && Descriptor->DeviceInfo & FILE_INFO_DEVICE) if (Echo && Descriptor && Descriptor->DeviceInfo & FILE_INFO_DEVICE)
{ {
/* Echo the character */ /* Echo the character */
DosEchoCharacter(Sda->ByteBuffer); DosEchoCharacter(Sda->ByteBuffer);

View file

@ -214,7 +214,7 @@ VOID WINAPI DosInt21h(LPWORD Stack)
{ {
DPRINT("INT 21h, AH = 01h\n"); DPRINT("INT 21h, AH = 01h\n");
Character = DosReadCharacter(DOS_INPUT_HANDLE); Character = DosReadCharacter(DOS_INPUT_HANDLE, TRUE);
if (Character == 0x03 && DosControlBreak()) break; if (Character == 0x03 && DosControlBreak()) break;
setAL(Character); setAL(Character);
@ -292,7 +292,7 @@ VOID WINAPI DosInt21h(LPWORD Stack)
if (DosCheckInput()) if (DosCheckInput())
{ {
Stack[STACK_FLAGS] &= ~EMULATOR_FLAG_ZF; Stack[STACK_FLAGS] &= ~EMULATOR_FLAG_ZF;
setAL(DosReadCharacter(DOS_INPUT_HANDLE)); setAL(DosReadCharacter(DOS_INPUT_HANDLE, FALSE));
} }
else else
{ {
@ -309,7 +309,7 @@ VOID WINAPI DosInt21h(LPWORD Stack)
case 0x07: case 0x07:
{ {
DPRINT("Direct char input without echo\n"); DPRINT("Direct char input without echo\n");
setAL(DosReadCharacter(DOS_INPUT_HANDLE)); setAL(DosReadCharacter(DOS_INPUT_HANDLE, FALSE));
break; break;
} }
@ -318,7 +318,7 @@ VOID WINAPI DosInt21h(LPWORD Stack)
{ {
DPRINT("Char input without echo\n"); DPRINT("Char input without echo\n");
Character = DosReadCharacter(DOS_INPUT_HANDLE); Character = DosReadCharacter(DOS_INPUT_HANDLE, FALSE);
if (Character == 0x03 && DosControlBreak()) break; if (Character == 0x03 && DosControlBreak()) break;
setAL(Character); setAL(Character);
@ -348,19 +348,18 @@ VOID WINAPI DosInt21h(LPWORD Stack)
/* Read Buffered Input */ /* Read Buffered Input */
case 0x0A: case 0x0A:
{ {
WORD BytesRead;
PDOS_INPUT_BUFFER InputBuffer = (PDOS_INPUT_BUFFER)SEG_OFF_TO_PTR(getDS(), getDX()); PDOS_INPUT_BUFFER InputBuffer = (PDOS_INPUT_BUFFER)SEG_OFF_TO_PTR(getDS(), getDX());
DPRINT("Read Buffered Input\n"); DPRINT("Read Buffered Input\n");
if (InputBuffer->MaxLength == 0) break; if (InputBuffer->MaxLength == 0) break;
/* Read from standard input */ /* Read from standard input */
DosReadFile(DOS_INPUT_HANDLE, InputBuffer->Length = DosReadLineBuffered(
DOS_INPUT_HANDLE,
MAKELONG(getDX() + FIELD_OFFSET(DOS_INPUT_BUFFER, Buffer), getDS()), MAKELONG(getDX() + FIELD_OFFSET(DOS_INPUT_BUFFER, Buffer), getDS()),
InputBuffer->MaxLength, InputBuffer->MaxLength
&BytesRead); );
InputBuffer->Length = LOBYTE(BytesRead);
break; break;
} }

View file

@ -318,7 +318,7 @@ VOID ConDrvCleanup(VOID);
* DOS BIOS Functions * DOS BIOS Functions
* See bios.c * See bios.c
*/ */
CHAR DosReadCharacter(WORD FileHandle); CHAR DosReadCharacter(WORD FileHandle, BOOLEAN Echo);
BOOLEAN DosCheckInput(VOID); BOOLEAN DosCheckInput(VOID);
VOID DosPrintCharacter(WORD FileHandle, CHAR Character); VOID DosPrintCharacter(WORD FileHandle, CHAR Character);

View file

@ -669,54 +669,19 @@ WORD DosOpenFile(LPWORD Handle,
return ERROR_SUCCESS; return ERROR_SUCCESS;
} }
WORD DosReadFile(WORD FileHandle, BYTE DosReadLineBuffered(WORD FileHandle, DWORD Buffer, BYTE MaxSize)
DWORD Buffer,
WORD Count,
LPWORD BytesRead)
{ {
WORD Result = ERROR_SUCCESS;
PDOS_FILE_DESCRIPTOR Descriptor = DosGetHandleFileDescriptor(FileHandle); PDOS_FILE_DESCRIPTOR Descriptor = DosGetHandleFileDescriptor(FileHandle);
BYTE StaticBuffer[8192];
DPRINT("DosReadFile: FileHandle 0x%04X, Count 0x%04X\n", FileHandle, Count);
if (Descriptor == NULL)
{
/* Invalid handle */
return ERROR_INVALID_HANDLE;
}
if (Descriptor->DeviceInfo & FILE_INFO_DEVICE)
{
PDOS_DEVICE_NODE Node = DosGetDriverNode(Descriptor->DevicePointer); PDOS_DEVICE_NODE Node = DosGetDriverNode(Descriptor->DevicePointer);
if (!Node->ReadRoutine) return ERROR_INVALID_FUNCTION; BYTE LineSize = 0;
if (Descriptor->DeviceInfo & FILE_INFO_BINARY)
{
/* Read from the device directly */
Node->ReadRoutine(Node, Buffer, &Count);
*BytesRead = Count;
}
else if (Descriptor->DeviceInfo & FILE_INFO_STDIN)
{
/* Line-buffered CON input */
PCHAR ConBuffer = NULL;
PCHAR Pointer = FAR_POINTER(Buffer); PCHAR Pointer = FAR_POINTER(Buffer);
/* Check if the buffer is empty */
if (!SysVars->UnreadConInput)
{
ULONG LineSize = 0;
SysVars->UnreadConInput = FIELD_OFFSET(DOS_DATA, UnreadConInputBuffer);
ConBuffer = (PCHAR)SEG_OFF_TO_PTR(DOS_DATA_SEGMENT, SysVars->UnreadConInput);
while (TRUE) while (TRUE)
{ {
USHORT Amount = 1; USHORT Amount = 1;
CHAR Character; CHAR Character;
/* Read a character from the CON device */ /* Read a character from the device */
Node->ReadRoutine(Node, Node->ReadRoutine(Node,
MAKELONG(DOS_DATA_OFFSET(Sda.ByteBuffer), MAKELONG(DOS_DATA_OFFSET(Sda.ByteBuffer),
DOS_DATA_SEGMENT), DOS_DATA_SEGMENT),
@ -725,8 +690,7 @@ WORD DosReadFile(WORD FileHandle,
Character = Sda->ByteBuffer; Character = Sda->ByteBuffer;
if (LineSize == sizeof(DosData->UnreadConInputBuffer)-1 && if (LineSize == MaxSize - 1 && Character != '\r' && Character != '\b')
Character != '\r' && Character != '\b')
{ {
/* Line buffer full */ /* Line buffer full */
// TODO: Should we beep? // TODO: Should we beep?
@ -766,7 +730,7 @@ WORD DosReadFile(WORD FileHandle,
if (LineSize > 0) if (LineSize > 0)
{ {
LineSize--; LineSize--;
if (ConBuffer[LineSize] == 0) LineSize--; if (Pointer[LineSize] == 0) LineSize--;
DosEchoCharacter(Character); DosEchoCharacter(Character);
} }
@ -777,7 +741,7 @@ WORD DosReadFile(WORD FileHandle,
default: default:
{ {
/* Store the character in the buffer */ /* Store the character in the buffer */
ConBuffer[LineSize++] = Character; Pointer[LineSize++] = Character;
DosEchoCharacter(Character); DosEchoCharacter(Character);
} }
} }
@ -785,6 +749,52 @@ WORD DosReadFile(WORD FileHandle,
/* Stop on a carriage return */ /* Stop on a carriage return */
if (Character == '\r') break; if (Character == '\r') break;
} }
return LineSize - 1;
}
WORD DosReadFile(WORD FileHandle,
DWORD Buffer,
WORD Count,
LPWORD BytesRead)
{
WORD Result = ERROR_SUCCESS;
PDOS_FILE_DESCRIPTOR Descriptor = DosGetHandleFileDescriptor(FileHandle);
BYTE StaticBuffer[8192];
DPRINT("DosReadFile: FileHandle 0x%04X, Count 0x%04X\n", FileHandle, Count);
if (Descriptor == NULL)
{
/* Invalid handle */
return ERROR_INVALID_HANDLE;
}
if (Descriptor->DeviceInfo & FILE_INFO_DEVICE)
{
PDOS_DEVICE_NODE Node = DosGetDriverNode(Descriptor->DevicePointer);
if (!Node->ReadRoutine) return ERROR_INVALID_FUNCTION;
if (Descriptor->DeviceInfo & FILE_INFO_BINARY)
{
/* Read from the device directly */
Node->ReadRoutine(Node, Buffer, &Count);
*BytesRead = Count;
}
else if (Descriptor->DeviceInfo & FILE_INFO_STDIN)
{
/* Line-buffered CON input */
PCHAR ConBuffer = NULL;
PCHAR Pointer = FAR_POINTER(Buffer);
/* Check if the buffer is empty */
if (!SysVars->UnreadConInput)
{
SysVars->UnreadConInput = FIELD_OFFSET(DOS_DATA, UnreadConInputBuffer);
DosReadLineBuffered(FileHandle,
MAKELONG(SysVars->UnreadConInput, DOS_DATA_SEGMENT),
sizeof(DosData->UnreadConInputBuffer));
} }
*BytesRead = 0; *BytesRead = 0;

View file

@ -123,6 +123,7 @@ WORD DosSeekFile
LPDWORD NewOffset LPDWORD NewOffset
); );
BYTE DosReadLineBuffered(WORD FileHandle, DWORD Buffer, BYTE MaxSize);
BOOL DosFlushFileBuffers(WORD FileHandle); BOOL DosFlushFileBuffers(WORD FileHandle);
BOOLEAN DosLockFile(WORD DosHandle, DWORD Offset, DWORD Size); BOOLEAN DosLockFile(WORD DosHandle, DWORD Offset, DWORD Size);
BOOLEAN DosUnlockFile(WORD DosHandle, DWORD Offset, DWORD Size); BOOLEAN DosUnlockFile(WORD DosHandle, DWORD Offset, DWORD Size);