mirror of
https://github.com/reactos/reactos.git
synced 2025-08-03 22:36:23 +00:00
[NTVDM]
Fix INT 21h/0Ah. DosReadCharacter shouldn't echo all the time. svn path=/trunk/; revision=69359
This commit is contained in:
parent
ac8f71fc86
commit
acfe187655
5 changed files with 104 additions and 96 deletions
|
@ -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);
|
||||
|
|
|
@ -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;
|
||||
}
|
||||
|
||||
|
|
|
@ -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);
|
||||
|
||||
|
|
|
@ -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;
|
||||
|
|
|
@ -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);
|
||||
|
|
Loading…
Add table
Add a link
Reference in a new issue