INT 16H is a software interrupt used in the IBM PC compatible BIOS to provide low‑level keyboard services to programs executing in real‑mode x86 environments. The interrupt number, 0x16 (hexadecimal), designates a set of functions that allow software to query the keyboard hardware, read keystrokes, and control keyboard LEDs. It is part of the BIOS interrupt vector table located at the beginning of system memory (address 0000:0040h for the INT 16h handler).
Primary Functions
The specific service requested is indicated by the value placed in the AH register before invoking the interrupt. The most commonly used functions include:
| AH value | Function name | Description |
|---|---|---|
| 00h | Read Keyboard Input | Waits until a key is pressed, then returns the BIOS scan code in AH and the ASCII character (if printable) in AL. |
| 01h | Check Keyboard Status | Tests whether a keystroke is available; if so, returns the same registers as function 00h, otherwise the zero flag (ZF) is set. |
| 02h | Get Keyboard Shift Status | Returns the status of shift, control, alt, and toggle keys in AL. |
| 10h | Keyboard Input with Extended Flags | Similar to function 00h but provides extended information such as extended key flags in BH. |
| 11h | Keyboard Input without BIOS Wait | Returns the next keystroke without waiting; if none is pending, ZF is set. |
Additional functions exist for handling the system keyboard buffer, setting the typematic rate, and configuring LED indicators, among others.
Register Usage
Typical register conventions for INT 16h calls are:
- Input: AH = function code; other registers may contain parameters (e.g., AL for initial character in certain functions).
- Output: AH = BIOS scan code; AL = ASCII code; other registers (e.g., BH, BL) may hold extended status depending on the function; the Zero Flag (ZF) may indicate the presence or absence of a keystroke.
Historical Context
INT 16h originated with the original IBM PC BIOS (1981) and was incorporated into virtually all compatible BIOS implementations. It provided a uniform method for accessing the keyboard hardware before the advent of protected‑mode operating systems and standardized driver models. The interrupt remained widely used in:
- MS‑DOS programs and bootloaders that required direct keyboard input during early system initialization.
- BIOS setup utilities and firmware diagnostics.
- Embedded systems employing x86 real‑mode code for minimal operating environments.
With the transition to protected‑mode operating systems (e.g., Windows NT, Linux), higher‑level APIs replaced direct BIOS calls for keyboard handling, but INT 16h remains documented for legacy compatibility and for use in environments that retain real‑mode execution, such as UEFI BIOS compatibility support modules (CSM) and certain virtualization scenarios.
Technical Implementation
The BIOS interrupt handler for INT 16h is typically located at a fixed memory segment:offset pair (e.g., 0000:0045h in many IBM-compatible BIOSes). The handler interacts directly with the keyboard controller (often an Intel 8042 or compatible) using I/O ports 0x60 (data) and 0x64 (status/command). It processes scan codes generated by the hardware, translates them to ASCII where appropriate, buffers them, and updates status flags for the various functions.
Limitations and Compatibility
- Real‑mode constraint: INT 16h functions are only directly accessible while the CPU operates in real mode; protected‑mode applications must revert to real mode (via VM86 or BIOS calls) or use operating‑system‑provided abstractions.
- Keyboard layout dependence: The translation from scan codes to ASCII is based on the BIOS's current keyboard layout; changing the layout may affect the characters returned by functions 00h and 01h.
- Limited to legacy keyboards: Modern USB keyboards are typically abstracted by higher‑level drivers; however, the BIOS often emulates a PS/2‑compatible interface for INT 16h compatibility.
References
- IBM PC BIOS Technical Reference (1981)
- Intel 80386 Programmer’s Reference Manual (1991)
- Ralf Brown’s Interrupt List, entry for INT 16h (comprehensive documentation of BIOS interrupts)