home *** CD-ROM | disk | FTP | other *** search
- The Keyboard Interface Tutorial
- By: Inbar Raz
-
- Preface:
-
- The Keyboard on the IBM PC and compatible is connected to the PPI -
- Programmable Peripheral Interface, which generally takes care of Keyboard
- functions, equipment information and timer functions. The PPI is addressable
- via port reads and writes, to addresses 060h thru 063h.
-
- There are several type of keyboards available. The main difference between the
- various types is the key count. Existing sizez are:
-
- 83 Key (Original PC)
- 84 Key (XT and clones)
- 101 Key (Usually on AT's and up, called Enhanced Keyboard)
-
- In addition to those standard types, there are numerous non-standard types,
- which varry from manufacturer to manufacturer. There are 102 Key keyboards,
- keyboards with two F-Key sets (upper and left), keyboards with weird
- hardly-used keys like 'Macro' and 'Turbo' (which DO have a scan code, though)
- etcetera.
-
- The IBM AT and up provides a better way of negotiating the keyboard, by
- allowing the user to directly access and command the keyboard, as it will be
- demonstrated later.
-
- Using assembly language, there are two major ways to handle the keyboard and
- keystrokes:
-
- 1. Using DOS functions:
-
- DOS provides a useful set of functions to use in context with the keyboard.
- This includes one-key-input and string input.
-
- 2. Using BIOS interrupts:
-
- The IBM PC BIOS (Basic Input Output System) provides an interrupt to handle
- the keyboard - Interrupt 016h (022d). These functions, titles KEYBOARD I/O,
- are an efficient medium level way of using the keyboard
-
- In addition to the Interrupt 016h interface, there is the Keyboard
- Interrupt, Interrupt 009h. As opposed to the other interrupt, Interrupt
- 009h is an IRQ - Interrupt Request, which means that it is never called by
- software. Only hardware, when certain conditions are met, calls IRQ
- interrupts. Naturally, the user is able to invoke them himself, but that is
- not commonly done.
-
- 3. Direct port access:
-
- It is possible to access the keyboard using direct port reads and writes.
- As mentioned before, this is usually done by addressing the PPI. On AT's
- and up, however, it is possible to directly access the keyboard itself.
-
-
- The BIOS also supplies a certain amount of information about the keyboard
- within it's BDA - BIOS Data Area, aka BDS - BIOS Data Segment - which is the
- segment that lies at paragraph 040h (0040h:XXXXh or 0000h:04XXh):
-
- Address Size Contents
- ▀▀▀▀▀▀▀ ▀▀▀▀ ▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀
- 0:0412 1 Errors in PCjr InfraRed keyboard link
-
- 0:0417 2 Keyboard status bits. See Keyboard Flags
- 0:0419 1 Current (accumulating) value of Alt+numpad pseudo-key input.
- Normally 0. When [Alt] is released, value is stored in kbd buf.
- 0:041A 2 Address of keyboard buffer head (keystroke at that addr is next)
- 0:041C 2 Address of keyboard buffer tail
- 0:041E 32 Keyboard buffer. BIOS stores keystrokes here (head and tail
- point to addresses from 041Eh to 043Dh inclusive).
-
- 0:0480 2 ▌AT▐ ≡PS/2≡ Keyboard buffer offset start address (usually 01Eh)
- 0:0482 2 end address (usually 03Eh)
-
- 0:0496 1 ▌AT▐ Keyboard flag bit 4=1 (10h) if 101-key keyboard is attached
- 0:0497 1 ▌AT▐ Keyboard flag for LED 'key lock' display
- bits 0-2 are ScrollLock, NumLock, CapsLock respectively
-
- ******************************************************************************
- ******************************************************************************
- ******************************************************************************
-
- Using DOS functions:
- --------------------
-
- DOS provides a set of 7 functions to handle the keyboard:
-
- 01h Keyboard Input
- 06h Console I/O
- 07h No Echo Unfiltered Input
- 08h No Echo Filtered Input
- 0Ah Buffered Input
- 0Bh Input Status
- 0Ch Clear Keyboard Buffer & Input
-
-
- DOS Fn 01h: Keyboard Input
- ══════════════════════════════════════════════════════════════════════════════
- ┌─────────╥───────╥───────────────────────────────────────────────────────────
- │ Expects ║ AH ║ 01h
- ├─────────╫───────╫───────────────────────────────────────────────────────────
- │ Returns ║ AL ║ Character fetched from the Standard Input
- └─────────╨───────╨───────────────────────────────────────────────────────────
-
- Description: Reads (waits for) a character from the Standard Input Device.
- Echoes that character to the Standard Output Device.
- If Ctrl-Break is detected, INT 23h is executed.
-
- Notes: Extended ASCII keystrokes (ie, F1-F12, PgUp, cursor, etc) will
- require two calls to this function. The first call will return
- AL=0. The second will return AL with the extended ASCII code.
-
-
- DOS Fn 02h: Display Output
- ══════════════════════════════════════════════════════════════════════════════
- ┌─────────╥───────╥───────────────────────────────────────────────────────────
- │ Expects ║ AH ║ 02h
- └─────────╢ DL ║ Character to send to the Standard Output
- ┌─────────╫───────╫───────────────────────────────────────────────────────────
- │ Returns ║ none ║
- └─────────╨───────╨───────────────────────────────────────────────────────────
-
- Description: Sends the character in DL to the Standard Output.
-
- Handles backspace (ASCII 8) by moving the cursor left and leaving
- the cursor there.
-
- If Ctrl-Break is detected, INT 23h is executed.
-
-
- DOS Fn 06h: Console I/O
- ══════════════════════════════════════════════════════════════════════════════
- ┌─────────╥───────╥───────────────────────────────────────────────────────────
- │ Expects ║ AH ║ 06h
- └─────────╢ DL ║ 0 to 0FEh Character to send to the Standard Output
- ║ ║ 0FFh Request for input from the Standard Input
- ┌─────────╫───────╫───────────────────────────────────────────────────────────
- │ Returns ║ ZF ║ Clear (NZ) if character is ready ══╦═ on input requests
- └─────────╢ AL ║ Character read, if ZF is clear ════╝ (when DL=0FFh)
- ╙───────╨───────────────────────────────────────────────────────────
-
- Description: If DL is 0FFh, this performs a "no wait" console input, returning
- the Zero Flag (ZF) set (ZR) if there is no character ready.
- If a character is ready, returns ZF cleared (NZ) with the
- character that was read in AL.
-
- If DL is anything but 0FFh, DL is sent to the Standard Output.
-
- Notes: Does not check for Ctrl-Break. Call twice for Extended ASCII.
-
-
- DOS Fn 07h: No Echo Unfiltered Console Input
- ══════════════════════════════════════════════════════════════════════════════
- ┌─────────╥───────╥───────────────────────────────────────────────────────────
- │ Expects ║ AH ║ 07h
- ├─────────╫───────╫───────────────────────────────────────────────────────────
- │ Returns ║ AL ║ Character fetched from the Standard Input
- └─────────╨───────╨───────────────────────────────────────────────────────────
-
- Description: Reads (waits for) a character from the Standard Input Device,
- returning that character in AL.
-
- Unfiltered: Does not detect Ctrl-Break, backspace, etc.
-
- Notes: Call twice for Extended ASCII character input.
- Use Fn 0Bh to check status (if you don't want to wait for a key).
-
-
- DOS Fn 08h: No Echo Console Input
- ══════════════════════════════════════════════════════════════════════════════
- ┌─────────╥───────╥───────────────────────────────────────────────────────────
- │ Expects ║ AH ║ 08h
- ├─────────╫───────╫───────────────────────────────────────────────────────────
- │ Returns ║ AL ║ Character fetched from the Standard Input
- └─────────╨───────╨───────────────────────────────────────────────────────────
-
- Description: Reads (waits for) a character from the Standard Input Device,
- returning that character in AL.
-
- If Ctrl-Break is detected, INT 23h is executed.
-
- Notes: Call twice for Extended ASCII character input.
-
-
- DOS Fn 0Ah: Buffered String Input
- ══════════════════════════════════════════════════════════════════════════════
- ┌─────────╥───────╥───────────────────────────────────────────────────────────
- │ Expects ║ AH ║ 0Ah
- └─────────╢ DS:DX ║ Address of an input buffer (see below)
- ┌─────────╫───────╫───────────────────────────────────────────────────────────
- │ Returns ║ none ║ Buffer contains input terminated with CR (ASCII 13h)
- └─────────╨───────╨───────────────────────────────────────────────────────────
-
- Description: On entry, the buffer at DS:DX must be set up as:
- ┌───┬───┬───┬───┬───┬───┬─ ─ ─
- │max│ ? │ ? ? ? ? ? max is maximum acceptable input
- └───┴───┴───┴───┴───┴───┴ ─ ─ (range: 1 to 254)
- On exit, the buffer is filled:
- ┌───┬───┬───┬───┬───┬───┬─ ─ ─
- │max│len│ T E X T 0Dh len is actual length of input,
- └───┴───┴───┴───┴───┴───┴ ─ ─ less the terminating CR (eg, 4).
-
- Characters are read from the Standard Input up to a CR (ASCII 13)
- or up to the value of max-1. If max-1 is reached, the console
- bell rings (beeps) for each character until Enter (CR) is read.
-
- The second byte of the buffer is filled with the actual length of
- the input, less the terminating CR. The final character in the
- buffer is always CR (which is not counted in the length byte).
-
- The characters in the buffer (including the len) before the call
- are used as a "template" and the DOS editing keys are in effect:
- [Esc] displays "\" and restarts the edit, [F3] displays to the
- end of the template, [F5] displays "@" and stores the current
- line as the template, etc. Most Extended ASCII keystrokes are
- ignored.
-
- If Ctrl-Break is detected, INT 23h is executed and the buffer is
- left unchanged.
-
-
- DOS Fn 0Bh: Check Input Status
- ══════════════════════════════════════════════════════════════════════════════
- ┌─────────╥───────╥───────────────────────────────────────────────────────────
- │ Expects ║ AH ║ 0Bh
- ├─────────╫───────╫───────────────────────────────────────────────────────────
- │ Returns ║ AL ║ 0FFh if a character is available from the Standard Input
- └─────────╢ ║ 0 if no character is available
- ╙───────╨───────────────────────────────────────────────────────────
-
- Description: Checks the status of the Standard Input.
-
- If Ctrl-Break is detected, INT 23h is executed.
-
- Notes: Use before Fns 01h, 07h and 08h to avoid having DOS wait for a
- key.
-
- This is a simple, non-destructive way to check for Ctrl-Break
- during long calculations or other processing that does not
- normally look for input. It lets the user abort from such a
- sequence.
-
-
- DOS Fn 0Ch: Clear & Input
- ══════════════════════════════════════════════════════════════════════════════
- ┌─────────╥───────╥───────────────────────────────────────────────────────────
- │ Expects ║ AH ║ 0Ch
- └─────────╢ AL ║ DOS input function number (01h, 06h, 07h, 08h, or 0Ah)
- ┌─────────╫───────╫───────────────────────────────────────────────────────────
- │ Returns ║ none ║
- └─────────╨───────╨───────────────────────────────────────────────────────────
-
- Description: Clears the Standard Input type-ahead buffer then invokes the DOS
- input function specified by AL. This forces the system to wait
- for a character to be typed.
-
- These values are allowed for AL: 01h Keyboard Input
- 06h Console I/O
- 07h No Echo Unfiltered Input
- 08h No Echo Filtered Input
- 0Ah Buffered Input
-
- ──────────────────────────────────────────────────────────────────────────────
-
- In addition to these functions, it is also possible to read a selected amount
- of characters from the keyboard, using DOS's File Handle functions, as the
- Keyboard, aka Standard Input, has a pre-set handle of 0000h:
-
- DOS Fn 3Fh: Read from keyboard via Handle
- ══════════════════════════════════════════════════════════════════════════════
- ┌─────────╥───────╥───────────────────────────────────────────────────────────
- │ Expects ║ AH ║ 3Fh
- └─────────╢ BX ║ 0000h - Handle for Standard Input (Keyboard)
- ║ DS:DX ║ Address of buffer to receive data
- ║ CX ║ Number of bytes to read
- ┌─────────╫───────╫───────────────────────────────────────────────────────────
- │ Returns ║ AX ║ Error code if CF is set to CY
- └─────────╢ AX ║ Number of bytes actually read
- ╙───────╨───────────────────────────────────────────────────────────
-
- Description: CX bytes of data are read from the keyboard. The data is placed
- into the caller's buffer pointed to by DS:DX.
-
- Notes: It is handy to use this function for reading default handles
- such as the Standard I/O handles, instead of the buffered input
- or character-by-character input functions.
-
- When you read from a device, AX returns the length of the line
- up to and including the termination CR (ASCII 13h).
-
- ******************************************************************************
- ******************************************************************************
- ******************************************************************************
-
- Using BIOS Interrupts:
- ----------------------
-
- As mentioned before, there are two ways to use interrupts to access the
- keyboard.
-
- The first is Interrupt 016h - Keyboard I/O.
-
- INT 16h: Keyboard Services
- ══════════════════════════════════════════════════════════════════════════════
- This is the application-level interface to the keyboard. Keystrokes are
- actually processed asynchronously in the background. As each keystroke is
- received from the keyboard, it is processed by INT 09h and placed into a
- circular queue.
-
- See AT Keyboard for ways to speed up the keyboard and other hardware info.
-
- AH Service
- ▀▀▀ ▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀
- 00h Read (wait for) next keystroke
- Output: AL = ASCII character (if AL=0, AH is an Extended ASCII keystroke)
- AH = Scan Code or Extended ASCII keystroke
-
- 01h Check if a keystroke is ready (and preview it if so)
- Output: ZF = ZR = 1 if no key is ready
- ZF = NZ = 0 if a key is ready.
- AX is set as for SubFn 00h (but the keystroke has not
- been removed from the queue).
-
- 02h Read the shift-key status. Determine which shift keys are currently being
- pressed and whether the keyboard is in NumLock state, etc.
- Output: AL = shift key and 'lock' status as in Keyboard Flags
-
- 03h Set keyboard typeamatic rate and delay. (11/15/85 BIOS)
- Input: AL = 05h (eg, AX = 0305h)
- BL = Typeamatic rate 0=30 rpts/sec, 1=26...1Fh=2. See AT Keyboard
- BH = Delay (0=250ms, 1=500ms, 2=750ms, 3=1 second)
- Output: (none)
-
- 04h (reserved)
-
- 05h Place a keystroke into the keyboard buffer. (11/15/85 BIOS)
- Input: CL = ASCII character.
- CH = Scan Code byte (or 0 if you don't care).
- Output: AL = Status: 0=success; 1=buffer full
-
- 06h-0Fh (reserved)
-
- 10h Read (wait for) a keystroke; specific for 101-key 'board (11/15/85 BIOS)
- Output: AL = ASCII character (if AL=0, AH is an Extended ASCII keystroke)
- AH = Scan Code or translated Extended ASCII keystroke
-
- 11h Preview keystroke; same as 01, but for 101-key 'board (11/15/85 BIOS)
- Output: ZF = ZR = 1 if no key is ready
- ZF = NZ = 0 if a key is ready.
- AX is set as for SubFn 10f but keystroke is still in the buffer.
-
- 12h Read shift-key status; same as 02, but for 101-key 'board (11/15/85 BIOS)
- Output: AL = shift key and 'lock' status. See 101-key Keyboard Flags
- ──────────────────────────────────────────────────────────────────────────────
-
-
- The second is Interrupt 009h - Keyboard Interrupt, IRQ 1
-
- INT 09h: Keyboard Interrupt
- ══════════════════════════════════════════════════════════════════════════════
- This hardware-generated interrupt (IRQ 1) is executed upon each press and
- release of a key. The ROM-BIOS code interprets the keystroke, storing values
- into the keyboard buffer at 0:041Eh. It also handles the special cases of the
- PrtSc and SysReq keys, and tracks the status of the shift and case-lock keys.
-
- See: INT 16h .......... BIOS service to access the keys stored in the buffer
- and obtain status of the certain shift keys.
- Scan Codes ....... a list of the values of each possible keystroke as
- it is received by INT 09h.
- Extended ASCII ... for a summary of the values that BIOS stores into the
- the keyboard buffer after it translates a scan code.
- Keyboard Flags ... for a summary of how to obtain, test for, and modify
- the bit-settings of shift and case-lock flags.
-
- TSRs (RAM-resident programs) that have a hot-key to trigger a popup usually
- intercept INT 09h and test for a certain key with a sequence such as this:
-
- push ax
- in al,60h ; Read the key
- cmp al,POP_KEY ; Is this the hot key?
- je do_pop ; Yes, trigger the popup
- ; No, drop through to original driver
- pop ax
- jmp cs:[int9_vect] ; Just hop out to original int handler
-
- do_pop: ;------ the following housekeeping is needed to satisfy the hdwr int
-
- in al,61h ; Get value of keyboard control lines
- mov ah,al ; Save it
- or al,80h ; Set the "enable kbd" bit
- out 61h,al ; And write it out the control port
- xchg ah,al ; Fetch the original control port value
- out 61h,al ; And write it back
-
- mov al,20h ; Send End-Of-Interrupt signal
- out 20h,al ; to the 8259 Interrupt Controller
-
- ;------ other code handles other tests and finally the popup code
-
- ******************************************************************************
- ******************************************************************************
- ******************************************************************************
-
- Direct port access:
- -------------------
-
- The keyboard is addressable in two manners.
-
- The first, available on all IBM PCs of all types, is by addressing the PPI -
- Programmable Peripheral Interface.
-
- Port Description
- ▀▀▀▀ ▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀
- 060h ■PC/XT■ PPI port A. Read keyboard scan code:
-
- IN al,60h ; Fetche most recent scan code. See INT 09h and Scan Code
-
- ▌AT▐ keyboard data register. See AT Keyboard
-
- 061h ■PC/XT■ PPI (Programmable Peripheral Interface) port B.
- ╓7┬6┬5┬4┬3┬2┬1┬0╖
- ║ │ │ │ │ │0│ │ ║
- ╙╥┴╥┴╥┴╥┴╥┴─┴╥┴╥╜ bit
- ║ ║ ║ ║ ║ ║ ╚═ 0: Timer 2 gate (speaker) ═╦═ OR 03h=speaker ON
- ║ ║ ║ ║ ║ ╚═══ 1: Timer 2 data ═══════════╝ AND 0FCh=speaker OFF
- ║ ║ ║ ║ ╚═══════ 3: 1=Read high switches; 0=read low switches(see 62h)
- ║ ║ ║ ╚═════════ 4: 0=Enable RAM parity checking; 1=disable
- ║ ║ ╚═══════════ 5: 0=Enable I/O channel check
- ║ ╚═════════════ 6: 0=Hold keyboard clock low
- ╚═══════════════ 7: 0=Enable keyboard; 1=disable keyboard
-
- ──────────────────────────────────────────────────────────────────────────────
-
- The second, available only on IBM PC/ATs and up, is by directly commanding the
- keyboard itself. -= This is for the AT keyboard only. =-
-
- Port Description
- ▀▀▀▀ ▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀
- 064h ▌AT▐ keyboard command register. This port communicates with the 8042
- which runs an on-chip control program for the keyboard. It accepts
- command codes and data bytes.
-
- The keyboard of the ▌AT▐ (and its Intel 8042 microcomputer interface) is
- programmable and a lot more interesting than the old-style PC keyboards.
- Using the information below, you can set the key repeat speed and play
- games with the "lock" key LED display.
-
- Note: This is not a comprehensive coverage of the details of keyboard and
- 8042 operation, but it should provide some food for thought.
-
- Port 60h is for writing data and is maintained for compatibility with
- earlier models. If the examples using port 64h don't work, try using 60h.
-
- Port 64h is for writing commands and data and for reading keyboard status.
- Before sending a command to the keyboard, the BIOS tests its status
- (IN al,64h) and makes sure a key isn't being pressed or the internal buffer
- isn't full, etc. There's a small risk if you just go ahead and send the
- command:
-
- mov al,cmd_code
- out 64h,al
-
- For a two-part command such as setting the typeamatic rate, it's wise to
- delay a little while between OUTs:
-
- mov al,cmd_code
- out 64h,al
- mov cx,2000h ;arbitrary ≈ 10ms+
- delay: loop delay
- mov al,data_value
- out 64h,al
-
- Cmd Description
- ▀▀▀▀ ▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀
- 0FFh Reset the keyboard and start internal diagnostics
- 0FEh Resend the last transmission
- 0FDh-0F7h (NOP)
- 0F6h Set keyboard to defaults and continue scanning
- 0F5h Set keyboard to defaults and disable keyboard scanning
- 0F4h Enable the keyboard. Kybd sends 'ACK', clears buffer, and starts scanning
-
- 0F3h Set typeamatic rate and delay. First send 0F3h, then send data byte:
-
- ╓7┬6┬5┬4┬3┬2┬1┬0╖
- ║0│dly│rept rate║
- ╙╥┴─┴─┴─┴─┴─┴─┴─╜
- ║ ╚╦╝ ╚═══════╩═ bits 0-4 set the repeat rate (see below)
- ║ ╚════════════ bits 5-6 set initial delay before first repeat:
- ║ 00=250ms; 01=500ms; 10=750ms; 11=1000ms
- ╚═══════════════ bit 7 is always 0
- Value Rate Value Rate
- This chart is a partial guide for the repeat 0 = 30.0 0Ah = 10.0
- rate (bits 0-4). You can interpolate for 1 = 26.7 0Dh = 9.2
- values not shown, but let's face it, you're 2 = 24.0 10h = 7.5
- only interested in the fastest rates. 4 = 20.0 14h = 5.0
- 8 = 15.0 1Fh = 2.0
-
- The keyboard is initially set to begin repeating after 1/2-second and
- repeat at a rate of 10 repeats per second. This is much too slow. A
- data byte of 01h sets the delay to 1/4-second with 26 repeats per second.
-
- 0F2h-0EFh (NOP)
- 0EEh Echo. Diagnostics aid. Simply sends 0EEh right back.
-
- 0EDh Turn LED 'lock key' lights on or off. First send 0EDh, then send byte:
-
- ╓7┬6┬5┬4┬3┬2┬1┬0╖
- ║ not used│c│n│s║
- ╙─┴─┴─┴─┴─┴╥┴╥┴╥╜
- ║ ║ ╚═ ScrollLock light 01h=turn on
- ║ ╚═══ NumLock light 02h=turn on
- ╚═════ CapsLock light 04h=turn on
-
- The bit positions 0-3 correspond to bits 4-6 of the keyboard flags
- variable in the BIOS Data area. You should make an effort to keep the
- flags in sync with the lights. For instance, if you do a big favor for
- the user and set his ten-key pad into NumLock mode (by setting bit 5 of
- 0:0417h) then be sure to turn on the corresponding LED (eg, bit 1).
-
- ******************************************************************************
- ******************************************************************************
- ******************************************************************************
-
- Additional Information
- ----------------------
-
- Keyboard Shift Status Flags
- ══════════════════════════════════════════════════════════════════════════════
- Two bytes at address 0:0417h and 0:0418h identify the status of the keyboard
- shift keys and keyboard toggles. INT 16h returns the first byte in AL.
-
- ╓─7┬─6┬─5┬─4┬─3┬─2┬─1┬─0╖ Perform INT 16h Fn 02h
- ║I │C │N │S │a │c │sL│sR║ or fetch AL=byte at 0:0417h
- ╙─╥┴─╥┴─╥┴─╥┴─╥┴─╥┴─╥┴─╥╜ bit
- ║ ║ ║ ║ ║ ║ ║ ╚═ 0: Alpha-shift (right side) DOWN (AL & 01h)
- ║ ║ ║ ║ ║ ║ ╚════ 1: Alpha-shift (left side) DOWN (AL & 02h)
- ║ ║ ║ ║ ║ ╚═══════ 2: Ctrl-shift (either side) DOWN (AL & 04h)
- ║ ║ ║ ║ ╚══════════ 3: Alt-shift (either side) DOWN (AL & 08h)
- ║ ║ ║ ╚═════════════ 4: ScrollLock state (AL & 10h)
- ║ ║ ╚════════════════ 5: NumLock state (AL & 20h)
- ║ ╚═══════════════════ 6: CapsLock state (AL & 40h)
- ╚══════════════════════ 7: Insert state (AL & 80h)
-
- ╓─7┬─6┬─5┬─4┬─3┬─2┬─1┬─0╖
- ║i │c │n │s │ │sy│aL│cL║ fetch AL=byte at 0:0418h
- ╙─╥┴─╥┴─╥┴─╥┴─╥┴─╥┴─╥┴─╥╜ bit
- ║ ║ ║ ║ ║ ║ ║ ╚═ 0: Ctrl-shift (left side) DOWN (AL & 01h)
- ║ ║ ║ ║ ║ ║ ╚════ 1: Alt-shift (left side) DOWN (AL & 02h)
- ║ ║ ║ ║ ║ ╚═══════ 2: SysReq DOWN (AL & 04h)
- ║ ║ ║ ║ ╚══════════ 3: hold/pause state (AL & 08h)
- ║ ║ ║ ╚═════════════ 4: ScrollLock DOWN (AL & 10h)
- ║ ║ ╚════════════════ 5: NumLock DOWN (AL & 20h)
- ║ ╚═══════════════════ 6: CapsLock DOWN (AL & 40h)
- ╚══════════════════════ 7: Insert DOWN (AL & 80h)
-
- Notes: Bits 0-2 of 0:0418h are defined only for the 101-key enhanced keyboard.
-
- The 101-key BIOS INT 16h Fn 12h returns AL as with Fn 02, but AH is
- returned with the following bit-flag layout:
-
- ╓─7┬─6┬─5┬─4┬─3┬─2┬─1┬─0╖
- ║sy│c │n │s │aR│cR│aL│cL║ Perform INT 16h Fn 12h (101-key BIOS only)
- ╙─╥┴─╥┴─╥┴─╥┴─╥┴─╥┴─╥┴─╥╜ bit
- ║ ║ ║ ║ ║ ║ ║ ╚═ 0: Ctrl-shift (left side) DOWN (AH & 01h)
- ║ ║ ║ ║ ║ ║ ╚════ 1: Alt-shift (left side) DOWN (AH & 02h)
- ║ ║ ║ ║ ║ ╚═══════ 2: Ctrl-shift (right side) DOWN (AH & 04h)
- ║ ║ ║ ║ ╚══════════ 3: Alt-shift (right side) DOWN (AH & 08h)
- ║ ║ ║ ╚═════════════ 4: ScrollLock DOWN (AH & 10h)
- ║ ║ ╚════════════════ 5: NumLock DOWN (AH & 20h)
- ║ ╚═══════════════════ 6: CapsLock DOWN (AH & 40h)
- ╚══════════════════════ 7: SysReq DOWN (AH & 80h)
-
- Some older programs change the values of NumLock and CapsLock state
- bits (at 0:0417h) to force a known status. This is unwise because
- modern keyboards have indicator lights which will get out of sync with
- the status. See AT Keyboard for more information on the lock-key LEDs.
-
- PCjr status bytes at 0:0488 are omitted for lack of interest.
-
-
- Keyboard Scan Codes
- ══════════════════════════════════════════════════════════════════════════════
- When the keyboard forces a hardware interrupt, it passes a Scan Code to the
- interrupt handler. The handler converts this to an ASCII or Extended ASCII
- value. For compatibility across the various keyboards, it is wise to avoid
- using scan codes and stick to the BIOS translation of a keystroke.
-
- ┌─────────────────────────┐
- │ Original PC/XT Keyboard │ When a key is released, the keyboard sends the
- └─────────────────────────┘ same value, ORed with 80h (eg, [Ctrl] sends 1Dh
- when pressed and 9Dh when released).
-
- ────────────╥─────────────╥───────────────╥────────────────╥──────────────────
- Hex Dec Key ║Hex Dec Key ║Hex Dec Key ║Hex Dec Key ║Hex Dec Key
- ────────────╫─────────────╫───────────────╫────────────────╫──────────────────
- 01 1 Esc ║12 18 E ║23 35 H ║34 52 . > ║45 69 NumLock
- 02 2 1 ! ║13 19 R ║24 36 J ║35 53 / ? ║46 70 ScrollLock
- 03 3 2 @ ║14 20 T ║25 37 K ║36 54 Shft(Rt)║47 71 Home [7]
- 04 4 3 # ║15 21 Y ║26 38 L ║37 55 * PrtSc ║48 72 Up [8]
- 05 5 4 $ ║16 22 U ║27 39 ; : ║38 56 Alt ║49 73 PgUp [9]
- 06 6 5 % ║17 23 I ║28 40 " ' ║39 57 spacebar║4a 74 K -
- 07 7 6 ^ ║18 24 O ║29 41 ` ~ ║3a 58 CapsLock║4b 75 Left [4]
- 08 8 7 & ║19 25 P ║2a 42 Shft(L)║3b 59 F1 ║4c 76 Cntr [5]
- 09 9 8 * ║1a 26 [ { ║2b 43 \ | ║3c 60 F2 ║4d 77 Rght [6]
- 0a 10 9 ( ║1b 27 ] } ║2c 44 Z ║3d 61 F3 ║4e 78 K +
- 0b 11 0 ) ║1c 28 Enter║2d 45 X ║3e 62 F4 ║4f 79 End [1]
- 0c 12 - _ ║1d 29 Ctrl ║2e 46 C ║3f 63 F5 ║50 80 Down [2]
- 0d 13 + = ║1e 30 A ║2f 47 V ║40 64 F6 ║51 81 PgDn [3]
- 0e 14 bksp║1f 31 S ║30 48 B ║41 65 F7 ║52 82 Ins [0]
- 0f 15 Tab ║20 32 D ║31 49 N ║42 66 F8 ║53 83 Del [.]
- 10 16 Q ║21 33 F ║32 50 M ║43 67 F9 ║
- 11 17 W ║22 34 G ║33 51 , < ║44 68 F10 ║
- ────────────╨─────────────╨───────────────╨────────────────╨──────────────────
- K indicates a key on the numeric keypad
-
- ┌────────────────────┐
- │ 84-Key AT Keyboard │ The 84-key keyboard sends the same scan codes as the
- └────────────────────┘ 83-key (original PC) keyboard with the addition that
- [SysReq] sends scan code 54h (84 decimal).
-
- However, the BIOS never lets an application program see this scan code.
- Instead, it invokes INT 15h SubFn 85h on make or break of the SysReq key.
-
- The 'break' (release of a key) is handled differently. Upon a break, the
- keyboard sends a two-byte sequence: 0F0h, followed by the 'make' scan code.
- See AT Keyboard Functions for information on programming this keyboard.
-
- ┌──────────────────┐
- │ 101-Key Keyboard │ This keyboard has three separate mappings of the scan
- └──────────────────┘ codes, selected by communication through port 64h. The
- keyboard comes to life with scan code set 2 (which is wildly different from
- the 84-key mapping. However, the scan codes are translated by the hardware
- keyboard interface before they are made available to programs that read the
- keyboard.
-
- The result is that all of the scan codes identified in the above table are
- valid when the 101-key 'board comes up naturally. The following table
- lists the additional scan-codes that are sent by the 101-key 'board. Note
- that all keys mentioned here refer to the keys that are unique to this
- keyboard; eg, [Insert] is the dedicated insert key (not KeyPad Ins).
-
- ────────────────────────────────────────────╥───────────────────────────
- Key Hex Sequence ║ Key Hex Sequence
- ────────────────────────────────────────────╫───────────────────────────
- F11 ..................... 57 ║ Home ........ E0 47
- F12 ..................... 58 ║ Shift-Home .. E0 AA E0 47
- Right-Alt ............... E0 38 ║ End ......... E0 4f
- Right-Ctrl .............. E0 1D ║ Shift-End ... E0 AA E0 4f
- PrintScreen ............. E0 2A E0 37 ║ Up........... E0 48
- Shft-PrintScreen (SysReq) E0 37 ║ Shift-Up .... E0 AA E0 48
- Ctrl-PrintScreen (SysReq) E0 37 ║ Down ........ E0 50
- Alt-PrintScreen ......... 54 ║ Shift-Down .. E0 AA E0 50
- Pause ................... E1 1D 45 E1 9D C5 ║ PageUp ...... E0 49
- Ctrl-Pause (Break) ...... E0 46 E0 C6 ║ Shft-PageUp . E0 AA E0 49
- Insert .................. E0 53 ║ PageDown .... E0 51
- Shift-Insert ............ E0 AA E0 52 ║ Shft-PageDown E0 AA E0 51
- Delete .................. E0 53 ║ Right ....... E0 4D
- Shift-Delete ............ E0 AA E0 53 ║ Shift-Right . E0 AA E0 4D
- Left .................... E0 4B ║ K Enter ..... E0 1C
- Shift-Left .............. E0 AA E0 4B ║ K / ......... E0 35
- ║ Shift-K / ... E0 AA E0 35
- ────────────────────────────────────────────╨───────────────────────────
- K indicates a key on the numeric keypad
-
- Note that in cases where a key is similar to another (pre-101) key, the
- second scan code byte is the same as the original key. Thus, some programs
- that work at the scan-code level can get away with simply ignoring the E0h
- prefix.
-
-
- Extended ASCII Keystrokes
- ══════════════════════════════════════════════════════════════════════════════
-
- When INT 16h Fn 00h returns AL=0, then AH will contain an extended ASCII
- keystroke as listed in these tables. When a DOS Character I/O function
- returns a character of 00h, you should make a second call to obtain the
- extended ASCII value.
-
- ╓─────────────╥───────────────────╥───────────────────╥──────────────────╖
- ║ Key Hex Dec ║ Key Hex Dec ║ Key Hex Dec ║ Key Hex Dec ║
- ╟─────────────╫───────────────────╫───────────────────╫──────────────────╢
- ║ F1 3B 59 ║ Shift-F1 54 84 ║ Ctrl-F1 5E 94 ║ Alt-F1 68 104 ║
- ║ F2 3C 60 ║ Shift-F2 55 85 ║ Ctrl-F2 5F 95 ║ Alt-F2 69 105 ║
- ║ F3 3D 61 ║ Shift-F3 56 86 ║ Ctrl-F3 60 96 ║ Alt-F3 6A 106 ║
- ║ F4 3E 62 ║ Shift-F4 57 87 ║ Ctrl-F4 61 97 ║ Alt-F4 6B 107 ║
- ║ F5 3F 63 ║ Shift-F5 58 88 ║ Ctrl-F5 62 98 ║ Alt-F5 6C 108 ║
- ║ F6 40 64 ║ Shift-F6 59 89 ║ Ctrl-F6 63 99 ║ Alt-F6 6D 109 ║
- ║ F7 41 65 ║ Shift-F7 5A 90 ║ Ctrl-F7 64 100 ║ Alt-F7 6E 110 ║
- ║ F8 42 66 ║ Shift-F8 5B 91 ║ Ctrl-F8 65 101 ║ Alt-F8 6F 111 ║
- ║ F9 43 67 ║ Shift-F9 5C 92 ║ Ctrl-F9 66 102 ║ Alt-F9 70 112 ║
- ║ F10 44 68 ║ Shift-F10 5D 93 ║ Ctrl-F10 67 103 ║ Alt-F10 71 113 ║
- ╙─────────────╨───────────────────╨───────────────────╨──────────────────╜
- ╓───────────────╥────────────────╥───────────────────╥───────────────────╖
- ║ Key Hex Dec║ Key Hex Dec ║ Key Hex Dec ║ Key Hex Dec ║
- ╟───────────────╫────────────────╫───────────────────╫───────────────────╢
- ║ Alt-A 1E 30 ║ Alt-P 19 25 ║ Alt-3 7A 122 ║ down 50 80 ║
- ║ Alt-B 30 48 ║ Alt-Q 10 16 ║ Alt-4 7B 123 ║ left 4B 75 ║
- ║ Alt-C 2E 46 ║ Alt-R 13 19 ║ Alt-5 7C 124 ║ right 4D 77 ║
- ║ Alt-D 20 32 ║ Alt-S 1F 31 ║ Alt-6 7D 125 ║ up 48 72 ║
- ║ Alt-E 12 18 ║ Alt-T 14 20 ║ Alt-7 7E 126 ║ End 4F 79 ║
- ║ Alt-F 21 33 ║ Alt-U 16 22 ║ Alt-8 7F 127 ║ Home 47 71 ║
- ║ Alt-G 22 34 ║ Alt-V 2F 47 ║ Alt-9 80 128 ║ PgDn 51 81 ║
- ║ Alt-H 23 35 ║ Alt-W 11 17 ║ Alt-- 82 130 ║ PgUp 49 73 ║
- ║ Alt-I 17 23 ║ Alt-X 2D 45 ║ Alt-= 83 131 ║ ║
- ║ Alt-J 24 36 ║ Alt-Y 15 21 ║ ║ ^left 73 115 ║
- ║ Alt-K 25 37 ║ Alt-Z 2C 44 ║ NUL 03 3 ║ ^right 74 116 ║
- ║ Alt-L 26 38 ║ ║ Shift-Tab 0F 15 ║ ^End 75 117 ║
- ║ Alt-M 32 50 ║ Alt-0 81 129 ║ Ins 52 82 ║ ^Home 77 119 ║
- ║ Alt-N 31 49 ║ Alt-1 78 120 ║ Del 53 83 ║ ^PgDn 76 118 ║
- ║ Alt-O 18 24 ║ Alt-2 79 121 ║ ^PrtSc 72 114 ║ ^PgUp 84 132 ║
- ╙───────────────╨────────────────╨───────────────────╨───────────────────╜
- ╔═══════════════════════════════════════════════╗
- ║ 101-key Keyboard Extensions Supported by BIOS ║
- ╓─────────╨─────────╥───────────────────────╥─────────────╨──────────╖
- ║ Key Hex Dec ║ Key Hex Dec ║ Key Hex Dec ║
- ╟───────────────────╫───────────────────────╫────────────────────────╢
- ║ F11 85 133 ║ Alt-Bksp 0E 14 ║ Alt- K / A4 164 ║
- ║ F12 86 134 ║ Alt-Enter 1C 28 ║ Alt- K * 37 55 ║
- ║ Shft-F11 87 135 ║ Alt-Esc 01 1 ║ Alt- K - 4A 74 ║
- ║ Shft-F12 88 136 ║ Alt-Tab A5 165 ║ Alt- K + 4E 78 ║
- ║ Ctrl-F11 89 137 ║ Ctrl-Tab 94 148 ║ Alt- K Enter A6 166 ║
- ║ Ctrl-F12 8A 138 ║ ║ ║
- ║ Alt-F11 8B 139 ║ Alt-up 98 152 ║ Ctrl- K / 95 149 ║
- ║ Alt-F12 8C 140 ║ Alt-down A0 160 ║ Ctrl- K * 96 150 ║
- ║ Alt-[ 1A 26 ║ Alt-left 9B 155 ║ Ctrl- K - 8E 142 ║
- ║ Alt-] 1B 27 ║ Alt-right 9D 157 ║ Ctrl- K + 90 144 ║
- ║ Alt-; 27 39 ║ ║ ║
- ║ Alt-' 28 40 ║ Alt-Delete A3 163 ║ Ctrl- K Up [8] 8D 141 ║
- ║ Alt-` 29 41 ║ Alt-End 9F 159 ║ Ctrl- K Cn [5] 8F 143 ║
- ║ Alt-\ 2B 43 ║ Alt-Home 97 151 ║ Ctrl- K Dw [2] 91 145 ║
- ║ Alt-, 33 51 ║ Alt-Insert A2 162 ║ Ctrl- K Ins[0] 92 146 ║
- ║ Alt-. 34 52 ║ Alt-PageUp 99 153 ║ Ctrl- K Del[.] 93 147 ║
- ║ Alt-/ 35 53 ║ Alt-PageDown A1 161 ║ ║
- ╙───────────────────╨───────────────────────╨────────────────────────╜
- K indicates a key on the numeric keypad (when not in NumLock mode)
-
- ==============================================================================
-
- For any ideas, requests, corrections ("There is always one more bug") or
- whatever, contant the author at:
-
- Fido:
-
- Inbar Raz, 2:401/100.1
- Inbar Raz, 2:403/100.42
-
- Internet:
-
- nyvirus@weizmann.weizmann.ac.il
- Inbar.Raz@p1.f100.n401.z2.fidonet.org
- Inbar.Raz@p42.f100.n403.z2.fidonet.org
-
- Snailmail:
-
- Inbar Raz
- 5 Hanegev Street
- Yavne 70600
-