Keyboard Input with Handles

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.