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

View file

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

View file

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

View file

@ -669,6 +669,90 @@ WORD DosOpenFile(LPWORD Handle,
return ERROR_SUCCESS;
}
BYTE DosReadLineBuffered(WORD FileHandle, DWORD Buffer, BYTE MaxSize)
{
PDOS_FILE_DESCRIPTOR Descriptor = DosGetHandleFileDescriptor(FileHandle);
PDOS_DEVICE_NODE Node = DosGetDriverNode(Descriptor->DevicePointer);
BYTE LineSize = 0;
PCHAR Pointer = FAR_POINTER(Buffer);
while (TRUE)
{
USHORT Amount = 1;
CHAR Character;
/* Read a character from the device */
Node->ReadRoutine(Node,
MAKELONG(DOS_DATA_OFFSET(Sda.ByteBuffer),
DOS_DATA_SEGMENT),
&Amount);
if (Amount == 0) break;
Character = Sda->ByteBuffer;
if (LineSize == MaxSize - 1 && Character != '\r' && Character != '\b')
{
/* Line buffer full */
// TODO: Should we beep?
continue;
}
switch (Character)
{
/* Extended character */
case '\0':
{
/* Read the scancode and discard it */
Amount = 1;
Node->ReadRoutine(Node,
MAKELONG(DOS_DATA_OFFSET(Sda.ByteBuffer),
DOS_DATA_SEGMENT),
&Amount);
break;
}
/* Ctrl-C */
case 0x03:
{
DosEchoCharacter(Character);
if (DosControlBreak())
{
/* Set the character to CR to end the loop */
Character = '\r';
}
break;
}
case '\b':
{
if (LineSize > 0)
{
LineSize--;
if (Pointer[LineSize] == 0) LineSize--;
DosEchoCharacter(Character);
}
break;
}
default:
{
/* Store the character in the buffer */
Pointer[LineSize++] = Character;
DosEchoCharacter(Character);
}
}
/* Stop on a carriage return */
if (Character == '\r') break;
}
return LineSize - 1;
}
WORD DosReadFile(WORD FileHandle,
DWORD Buffer,
WORD Count,
@ -706,85 +790,11 @@ WORD DosReadFile(WORD FileHandle,
/* 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)
{
USHORT Amount = 1;
CHAR Character;
/* Read a character from the CON device */
Node->ReadRoutine(Node,
MAKELONG(DOS_DATA_OFFSET(Sda.ByteBuffer),
DOS_DATA_SEGMENT),
&Amount);
if (Amount == 0) break;
Character = Sda->ByteBuffer;
if (LineSize == sizeof(DosData->UnreadConInputBuffer)-1 &&
Character != '\r' && Character != '\b')
{
/* Line buffer full */
// TODO: Should we beep?
continue;
}
switch (Character)
{
/* Extended character */
case '\0':
{
/* Read the scancode and discard it */
Amount = 1;
Node->ReadRoutine(Node,
MAKELONG(DOS_DATA_OFFSET(Sda.ByteBuffer),
DOS_DATA_SEGMENT),
&Amount);
break;
}
/* Ctrl-C */
case 0x03:
{
DosEchoCharacter(Character);
if (DosControlBreak())
{
/* Set the character to CR to end the loop */
Character = '\r';
}
break;
}
case '\b':
{
if (LineSize > 0)
{
LineSize--;
if (ConBuffer[LineSize] == 0) LineSize--;
DosEchoCharacter(Character);
}
break;
}
default:
{
/* Store the character in the buffer */
ConBuffer[LineSize++] = Character;
DosEchoCharacter(Character);
}
}
/* Stop on a carriage return */
if (Character == '\r') break;
}
DosReadLineBuffered(FileHandle,
MAKELONG(SysVars->UnreadConInput, DOS_DATA_SEGMENT),
sizeof(DosData->UnreadConInputBuffer));
}
*BytesRead = 0;

View file

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