The principal MS-DOS function for keyboard input using handles is Int 21H Function 3FH (Read File or Device). The parameters for this function are a handle, the segment and offset of a buffer, and the length of the buffer. (For a more detailed explanation of this function, see Section II of this book, "MS-DOS Functions Reference.")
As an example, let's use the predefined standard input handle (0) and Int 21H Function 3FH to read a line from the keyboard:
buffer db 80 dup (?) ; keyboard input buffer
.
.
.
mov ah,3fh ; function 3fh = read file or device
mov bx,0 ; handle for standard input
mov cx,80 ; maximum bytes to read
mov dx,seg buffer ; DS:DX = buffer address
mov ds,dx
mov dx,offset buffer
int 21h ; transfer to MS-DOS
jc error ; jump if error detected
.
.
.
When control returns from Int 21H Function 3FH, the carry flag is clear if the function was successful, and AX contains the number of characters read. If there was an error, the carry flag is set and AX contains an error code; however, this should never occur when reading the keyboard.
The standard input is redirectable, so the code just shown is not a foolproof way of obtaining input from the keyboard. Depending upon whether a redirection parameter was included in the command line by the user, program input might be coming from the keyboard, a file, another character device, or even the bit bucket (NUL device). To bypass redirection and be absolutely certain where your input is coming from, you can ignore the predefined standard input handle and open the console as though it were a file, using the handle obtained from that open operation to perform your keyboard input, as in the following example:
buffer db 80 dup (?) ; keyboard input buffer
fname db 'CON',0 ; keyboard device name
handle dw 0 ; keyboard device handle
.
.
.
mov ah,3dh ; function 3dh = open
mov al,0 ; mode = read
mov dx,seg fname ; DS:DX = device name
mov ds,dx
mov dx,offset fname
int 21h ; transfer to MS-DOS
jc error ; jump if open failed
mov handle,ax ; save handle for CON
.
.
.
mov ah,3fh ; function 3fh = read file or device
mov bx,handle ; BX = handle for CON
mov cx,80 ; maximum bytes to read
mov dx,offset buffer ; DS:DX = buffer address
int 21h ; transfer to MS-DOS
jc error ; jump if error detected
.
.
.
When a programmer uses Int 21H Function 3FH to read from the keyboard, the exact result depends on whether MS-DOS regards the handle to be in ASCII mode or binary mode (sometimes known as cooked mode and raw mode). ASCII mode is the default, although binary mode can be selected with Int 21H Function 44H (IOCTL) when necessary.
In ASCII mode, MS-DOS initially places characters obtained from the keyboard in a 128-byte internal buffer, and the user can edit the input with the Backspace key and the special function keys. MS-DOS automatically echoes the characters to the standard output, expanding tab characters to spaces (although they are left as the ASCII code 09H in the buffer). The Ctrl-C, Ctrl-S, and Ctrl-P key combinations receive special handling, and the Enter key is translated to a carriage return—linefeed pair. When the user presses Enter or Ctrl-Z, MS-DOS copies the requested number of characters (or the actual number of characters entered, if less than the number requested) out of the internal buffer into the calling program's buffer.
In binary mode, MS-DOS never echoes input characters. It passes the Ctrl-C, Ctrl-S, Ctrl-P, and Ctrl-Z key combinations and the Enter key through to the application unchanged, and Int 21H Function 3FH does not return control to the application until the exact number of characters requested has been received.
Ctrl-C checking is discussed in more detail at the end of this chapter. For now, simply note that the application programmer can substitute a custom handler for the default MS-DOS Ctrl-C handler and thereby avoid having the application program lose control of the machine when the user enters a Ctrl-C or Ctrl-Break.