Keyboard Shift Status Flags

 Two bytes at address 0040:0017 and 0040:0018 identify the status of the
 keyboard shift keys and keyboard toggles.

 INT 16H 02H returns one byte in the AL register; it is exactly as found in
 the byte at 0040:0017 in the BIOS Data Area:

 KbdShiftFlagsRec
 ╓7┬6┬5┬4┬3┬2┬1┬0╖
 ║icnsA^SS║
 ╙─┴─┴─┴─┴─┴─┴LRbit mask
  ║ ║ ║ ║ ║ ║ ║ ╚═► 0:  01H alpha-shift (right side) DOWN
  ║ ║ ║ ║ ║ ║ ╚═══► 1:  02H alpha-shift (left side) DOWN
  ║ ║ ║ ║ ║ ╚═════► 2:  04H Ctrl-shift (either side) DOWN
  ║ ║ ║ ║ ╚═══════► 3:  08H Alt-shift  (either side) DOWN
  ║ ║ ║ ╚═════════► 4:  10H ScrollLock state
  ║ ║ ╚═══════════► 5:  20H NumLock state
  ║ ╚═════════════► 6:  40H CapsLock state
  ╚═══════════════► 7:  80H Insert state

 INT 16H 12H returns 16 bits in the AX register.  It is similar to the word
 at 0040:0017:

 KbdShiftFlags101Rec
  1 1 1 1 1 1
 ╓5┬4┬3┬2┬1┬0┬9┬8╥7┬6┬5┬4┬3┬2┬1┬0╖
 ║qcnsA^A^icnsA^SS║
 ╙ddddrrllssss┴─┴─┴LRbit  mask
  ║ ║ ║ ║ ║ ║ ║ ║ ║ ║ ║ ║ ║ ║ ║ ╚═► 0: 0001H alpha-shift (right side) DOWN
  ║ ║ ║ ║ ║ ║ ║ ║ ║ ║ ║ ║ ║ ║ ╚═══► 1: 0002H alpha-shift (left side) DOWN
  ║ ║ ║ ║ ║ ║ ║ ║ ║ ║ ║ ║ ║ ╚═════► 2: 0004H Ctrl-shift (either side) DOWN
  ║ ║ ║ ║ ║ ║ ║ ║ ║ ║ ║ ║ ╚═══════► 3: 0008H Alt-shift  (either side) DOWN
  ║ ║ ║ ║ ║ ║ ║ ║ ║ ║ ║ ╚═════════► 4: 0010H ScrollLock state
  ║ ║ ║ ║ ║ ║ ║ ║ ║ ║ ╚═══════════► 5: 0020H NumLock state
  ║ ║ ║ ║ ║ ║ ║ ║ ║ ╚═════════════► 6: 0040H CapsLock state
  ║ ║ ║ ║ ║ ║ ║ ║ ╚═══════════════► 7: 0080H Insert state
  ║ ║ ║ ║ ║ ║ ║ ╚═════════════════► 8: 0100H Ctrl-shift (left side) DOWN
  ║ ║ ║ ║ ║ ║ ╚═══════════════════► 9: 0200H Alt-shift (left side) DOWN
  ║ ║ ║ ║ ║ ╚═════════════════════►10: 0400H Ctrl-shift (right side) DOWN
  ║ ║ ║ ║ ╚═══════════════════════►11: 0800H Alt-shift (right side) DOWN
  ║ ║ ║ ╚═════════════════════════►12: 1000H ScrollLock DOWN
  ║ ║ ╚═══════════════════════════►13: 2000H NumLock DOWN
  ║ ╚═════════════════════════════►14: 4000H CapsLock DOWN
  ╚═══════════════════════════════►15: 8000H SysReq DOWN

 The byte at 0040:0018 is somewhat different from than that returned in
 AH by INT 16H 12H.  Its layout is::

 KbdShiftFlags0018Rec
 ╓7┬6┬5┬4┬3┬2┬1┬0╖
 ║icnspqA^║
 ╙dddd┴─┴dllbit mask
  ║ ║ ║ ║ ║ ║ ║ ╚═► 0:  01H Ctrl-shift (left side) DOWN
  ║ ║ ║ ║ ║ ║ ╚═══► 1:  02H Alt-shift (left side) DOWN
  ║ ║ ║ ║ ║ ╚═════► 2:  04H SysReq DOWN
  ║ ║ ║ ║ ╚═══════► 3:  08H hold/pause state
  ║ ║ ║ ╚═════════► 4:  10H ScrollLock DOWN
  ║ ║ ╚═══════════► 5:  20H NumLock DOWN
  ║ ╚═════════════► 6:  40H CapsLock DOWN
  ╚═══════════════► 7:  80H Insert DOWN

    Note: Bits 0-2 of 0:0418 are defined only for the 101-key enhanced
          keyboard (older keyboards don't have two copies of Alt and Ctrl).

█▌NumLock and CapsLock Mode▐█
  Bits 5-6 of 0040:0017 affect how the BIOS interprets certain keystrokes.

  Each press of NumLock toggles bit 5.  When set, keys on the numeric keypad
  are interpreted as digits 1-9 and period (.).  When bit 5 is clear, the
  same keys are interpreted as cursor control keystrokes.

  Each press of CapsLock toggles bit 6.  When set, alphabetic keys A-Z are
  interpreted as uppercase (A-Z).  When bit 5 is clear, the same keys are
  interpreted as lowercase (a-z).

  Pressing the SHIFT key reverses the current sense of these "lock bits" so
  that, for instance, in CapsLock mode, Shift+A result in lowercase 'a'.

█▌ScrollLock Mode▐█
  The BIOS doesn't care about 0040:0017 bit 4 other than to toggle the bit
  each time ScrollLock is pressed.  If you want your program to react to the
  ScrollLock setting, you'll need to check this bit each time you process a
  scrolling key.  Most programs don't bother.

█▌Insert Mode▐█
  The BIOS toggles 0040:0017 bit 8 each time the Insert key is pressed.
  Note that the BIOS also places the keycode for insert into the keyboard
  buffer.  Most programs set bit 8 to a known state before processing input.

█▌LED Shift-State Indicators▐█
  Starting with early AT keyboards, the status of CapsLock, NumLock, and
  ScrollLock has been indicated by a light on the keyboard itself.  You can
  program these lights using port I/O to talk to the keyboard controller.
  See AT Keyboard for details.

  However, recent BIOSes periodically update the keyboard LEDs, so just
  setting or clearing bits of 0040:0017 will set the lights automatically.

█▌Detecting the press and release of Alt▐█
  The BIOS does not put the Alt key or other shift keys into the keyboard
  buffer.  If you want to take notice of the press (and release) of say,
  Alt, you will need to either intercept INT 09H an read the raw scan codes,
  or poll the byte at 0040:0017 regularly and watch for changes to the
  keyboard flags.

See Also: AT Keyboard
          BIOS Data Area
          INT 16H
                                    -♦-