home *** CD-ROM | disk | FTP | other *** search
/ synchro.net / synchro.net.tar / synchro.net / night.owl.13 / 044A / KBGUID11.ZIP / KBGUIDE.TXT < prev    next >
Encoding:
Text File  |  1994-05-23  |  47.6 KB  |  1,297 lines

  1.  
  2.           Wout Mertens' Guide To Keyboard Programming v1.1
  3.           ────────────────────────────────────────────────
  4.                              23 may 94
  5.  
  6.     Table of Contents
  7.     ─────────────────
  8.  
  9.     0    Legal Info
  10.     0.1 Preface
  11.  
  12.     1    Overall Information
  13.     1.1 Extended ASCII
  14.     1.2 Special Functions
  15.  
  16.     2    DOS Interfacing
  17.     2.1 Functions
  18.  
  19.     3    BIOS Interfacing
  20.     3.1 Functions
  21.     3.2 Keyboard Flags
  22.     3.3 Keyboard Buffer
  23.  
  24.     4    Low-Level Interfacing
  25.     4.1 Interfacing And Configuring
  26.     4.2 Lay-Out
  27.     4.3 Scancodes
  28.     4.4 Int 9
  29.  
  30.     5    Tech Stuff
  31.  
  32.     A    Acknowledgments
  33.     B    How To Contact Me
  34.     C    The Answer To Life, The Universe And All The Rest
  35.     D    History
  36.  
  37.  
  38.     0. Legal Info
  39.     ─────────────
  40.  
  41.     This "Keyboard Guide" is (C) Copyright 1994 Wout Mertens.
  42.     All rights reserved.
  43.  
  44.     THIS DOCUMENT AND  THE ACCOMPANYING SOURCE    CODE FILES ARE    PROVIDED "AS
  45.     IS" WITHOUT  WARRANTY OF  ANY KIND,  EXPRESS OR  IMPLIED, INCLUDING  ANY
  46.     WARRANTY OF MERCHANTABILITY OR FITNESS  FOR A PARTICULAR PURPOSE.    WOUT
  47.     MERTENS WILL NOT BE  HELD LIABLE FOR ANY  DAMAGES OR LOSSES OF  ANY KIND
  48.     THAT  RESULT  FROM    THE  USE  OR  THE  INABILITY  TO USE THE INFORMATION
  49.     PROVIDED IN THIS DOCUMENT OR  THIS SOURCE CODE FILE, INCLUDING,  BUT NOT
  50.     LIMITED TO, LOSS OF PROPERTY OR INCOME.
  51.  
  52.     This document and its accompanying    source code files are freeware,  not
  53.     public domain.  They  may  be distributed  freely provided    that neither
  54.     file is  modified, and  that they  are distributed    together along    with
  55.     FILE_ID.DIZ in  their entirety,  including the  legal notice,  and that:
  56.     If they are distributed by a third party vendor, no more than $5 U.S. is
  57.     charged for the disk on which the archive, containing this document  and
  58.     the accompanying  source code  files, is stored, except when distributed
  59.     on CD-ROM.
  60.     This legal information supersedes all previous notices.
  61.  
  62.  
  63.     0.1. Preface
  64.     ────────────
  65.  
  66.     I wrote this document because I needed info, and thought I could get it
  67.     this way. Boy was I wrong! I ended up finding it all by myself. Anyway,
  68.     I hope you can use it.  It is meant for people who know what interrupts
  69.     are and that 0ah equals 10. Enjoy.
  70.  
  71.     Oh, almost forgot.    I didn't give this text any page formatting  (aside
  72.     from spaces before and room after for ease of reading) because:
  73.  
  74.     - I read ALL my documents on-line
  75.     - People have differing page sizes and then it would look like
  76.       shit for some people and too short for others.
  77.  
  78.     If you want to print this, well, go ahead and format it, BUT DON'T EVEN
  79.     *THINK* OF SPREADING IT !!! (Except when you ask my permission)
  80.  
  81.     Everytime  you  see  something  like  d9h  or  65h,  it is a hexadecimal
  82.     number. No trailing 0 was added for ease of typing.
  83.  
  84.  
  85.     1. Overall Information
  86.     ──────────────────────
  87.  
  88.     On the IBM,  there are three  ways, all alike,  to access the  keyboard.
  89.     Via the operating  system, via BIOS  or via low-level  access. Which way
  90.     you use depends very much on  the application you are writing. Games  do
  91.     not use DOS functions, for example. And a file-compressor is really  not
  92.     interested wether  you are    actually pressing  'Y' or  not. Or how long.
  93.  
  94.     This is the way it works:
  95.  
  96.        Hardware  ├────────────── BIOS ────────────────┤   ├──── DOS ───┤
  97.              ┌─────────────┐
  98.             ┌┤Keyboard Data├─────┐
  99.             │└────────────╥┘     │
  100.        ┌─────┐     ┌─────┐│  ┌────────┐ ║ ┌────┴────────┐   ┌────────────┐
  101.        │key- ├─╥─┤int 9├┴──┤keyboard├───┤BIOS keyboard├───┤DOS keyboard│
  102.        │board│ ║ └─────┘   │buffer  │ ║ │functions    │   │functions   │
  103.        └─────┘ ║       └───╥────┘ ║ └──────╥──────┘   └──────╥─────┘
  104.            ║           ║      ║        ║         ║
  105.            ╚═══════════════╩══════╩╦═══════╩═════════════════╝
  106.                        ║
  107.  
  108.                   Possible tap points
  109.  
  110.     The keyboard triggers  IRQ 1 (Interrupt  Request), also known  as int 9.
  111.     Int 9 then translates the keyboard codes into ASCII, or when  necessary,
  112.     extended ASCII, and places it into the keyboard buffer. Also, the  shift
  113.     and lock states are saved in the BIOS Data Area (seg 40h). The  keyboard
  114.     buffer is then  used by the  BIOS functions to  interface with programs.
  115.     The DOS  functions use  the BIOS  keyboard functions  to interface    with
  116.     programs as  well, but  on a  higher and  more protected  (Ctrl-Brk etc)
  117.     level.
  118.  
  119.  
  120.     1.1. Extended ASCII
  121.     ───────────────────
  122.  
  123.     Extended ASCII is IBM's way  of letting non-ASCII keys be  recognized by
  124.     programs. The BIOS will first send    0 and then the extended ASCII  code.
  125.  
  126.     Here is the table:
  127.     ╓───────────╥─────────────────╥─────────────────╥────────────────╖
  128.     ║Key Hex Dec║Key       Hex Dec║Key         Hex Dec║Key      Hex Dec║
  129.     ╟───────────╫─────────────────╫─────────────────╫────────────────╢
  130.     ║F1   3B  59║Shift-F1   54    84║Ctrl-F1   5E   94║Alt-F1   68  104║
  131.     ║F2   3C  60║Shift-F2   55    85║Ctrl-F2   5F   95║Alt-F2   69  105║
  132.     ║F3   3D  61║Shift-F3   56    86║Ctrl-F3   60   96║Alt-F3   6A  106║
  133.     ║F4   3E  62║Shift-F4   57    87║Ctrl-F4   61   97║Alt-F4   6B  107║
  134.     ║F5   3F  63║Shift-F5   58    88║Ctrl-F5   62   98║Alt-F5   6C  108║
  135.     ║F6   40  64║Shift-F6   59    89║Ctrl-F6   63   99║Alt-F6   6D  109║
  136.     ║F7   41  65║Shift-F7   5A    90║Ctrl-F7   64  100║Alt-F7   6E  110║
  137.     ║F8   42  66║Shift-F8   5B    91║Ctrl-F8   65  101║Alt-F8   6F  111║
  138.     ║F9   43  67║Shift-F9   5C    92║Ctrl-F9   66  102║Alt-F9   70  112║
  139.     ║F10  44  68║Shift-F10  5D    93║Ctrl-F10  67  103║Alt-F10  71  113║
  140.     ╙───────────╨─────────────────╨─────────────────╨────────────────╜
  141.     ╓─────────────╥──────────────╥─────────────────╥─────────────────╖
  142.     ║Key   Hex Dec║Key     Hex  Dec║Key       Hex    Dec║Key      Hex  Dec║
  143.     ╟─────────────╫──────────────╫─────────────────╫─────────────────╢
  144.     ║Alt-A  1E    30║Alt-P  19   25║Alt-3     7A    122║down      50   80║
  145.     ║Alt-B  30    48║Alt-Q  10   16║Alt-4     7B    123║left      4B   75║
  146.     ║Alt-C  2E    46║Alt-R  13   19║Alt-5     7C    124║right     4D   77║
  147.     ║Alt-D  20    32║Alt-S  1F   31║Alt-6     7D    125║up          48   72║
  148.     ║Alt-E  12    18║Alt-T  14   20║Alt-7     7E    126║End       4F   79║
  149.     ║Alt-F  21    33║Alt-U  16   22║Alt-8     7F    127║Home      47   71║
  150.     ║Alt-G  22    34║Alt-V  2F   47║Alt-9     80    128║PgDn      51   81║
  151.     ║Alt-H  23    35║Alt-W  11   17║Alt--     82    130║PgUp      49   73║
  152.     ║Alt-I  17    23║Alt-X  2D   45║Alt-=     83    131║             ║
  153.     ║Alt-J  24    36║Alt-Y  15   21║           ║^left     73  115║
  154.     ║Alt-K  25    37║Alt-Z  2C   44║NUL        03      3║^right    74  116║
  155.     ║Alt-L  26    38║         ║Shift-Tab 0F     15║^End      75  117║
  156.     ║Alt-M  32    50║Alt-0  81  129║Ins        52     82║^Home     77  119║
  157.     ║Alt-N  31    49║Alt-1  78  120║Del        53     83║^PgDn     76  118║
  158.     ║Alt-O  18    24║Alt-2  79  121║^PrtSc    72    114║^PgUp     84  132║
  159.     ╙─────────────╨──────────────╨─────────────────╨─────────────────╜
  160.        ╔═══════════════════════════════════════════════╗
  161.        ║ 101-key Keyboard Extensions Supported by BIOS ║
  162.     ╓──────╨──────────╥─────────────────────╥──────────────╨───────╖
  163.     ║Key      Hex  Dec║Key         Hex Dec║Key       Hex    Dec║
  164.     ╟─────────────────╫─────────────────────╫──────────────────────╢
  165.     ║F11       85  133║Alt-Bksp      0E   14║Alt - K /        A4    164║
  166.     ║F12       86  134║Alt-Enter     1C   28║Alt - K *        37     55║
  167.     ║Shft-F11  87  135║Alt-Esc         01    1║Alt - K -        4A     74║
  168.     ║Shft-F12  88  136║Alt-Tab         A5  165║Alt - K +        4E     78║
  169.     ║Ctrl-F11  89  137║Ctrl-Tab      94  148║Alt - K Enter  A6    166║
  170.     ║Ctrl-F12  8A  138║             ║               ║
  171.     ║Alt-F11   8B  139║Alt-up         98  152║Ctrl- K /        95    149║
  172.     ║Alt-F12   8C  140║Alt-down      A0  160║Ctrl- K *        96    150║
  173.     ║Alt-[     1A   26║Alt-left      9B  155║Ctrl- K -        8E    142║
  174.     ║Alt-]     1B   27║Alt-right     9D  157║Ctrl- K +        90    144║
  175.     ║Alt-;     27   39║             ║               ║
  176.     ║Alt-'     28   40║Alt-Delete    A3  163║Ctrl- K Up [8] 8D    141║
  177.     ║Alt-`     29   41║Alt-End         9F  159║Ctrl- K Cn [5] 8F    143║
  178.     ║Alt-\     2B   43║Alt-Home      97  151║Ctrl- K Dw [2] 91    145║
  179.     ║Alt-,     33   51║Alt-Insert    A2  162║Ctrl- K Ins[0] 92    146║
  180.     ║Alt-.     34   52║Alt-PageUp    99  153║Ctrl- K Del[.] 93    147║
  181.     ║Alt-/     35   53║Alt-PageDown  A1  161║               ║
  182.     ╙─────────────────╨─────────────────────╨──────────────────────╜
  183.     K indicates a key on the numeric keypad (when not in NumLock mode)
  184.  
  185.  
  186.     1.2. Special Functions
  187.     ──────────────────────
  188.  
  189.     There are a few functions and interrupts invoked by int 9:
  190.  
  191.     int 5   - Print Screen Handler
  192.  
  193.     int 15h
  194.     fns 4fh - Check Scancode
  195.           (See int 9)
  196.  
  197.     85h - System Request
  198.           Normally IRET
  199.  
  200.     int 23h - Ctrl-Break handler
  201.  
  202.     Feel free to revector any of them.
  203.  
  204.  
  205.     2. DOS Interfacing
  206.     ──────────────────
  207.  
  208.     One of the ways to use the keyboard is to let DOS handle it.
  209.  
  210.     Pro:
  211.     - The keyboard lay-out is unimportant
  212.     - You can even do strings
  213.     - The user doesn't actually have to type
  214.  
  215.     Contra:
  216.     - You don't  know if you  are actually accessing  the keyboard (like
  217.       in "Really format drive C: ? Y/N" :-)
  218.     - The functions are quite slow
  219.  
  220.  
  221.     2.1. Functions
  222.     ──────────────
  223.  
  224.     DOS provides a set of 7 functions to handle the keyboard:
  225.  
  226.     01h Keyboard Input
  227.     06h Console I/O
  228.     07h No Echo Unfiltered Input
  229.     08h No Echo Filtered Input
  230.     0Ah Buffered Input
  231.     0Bh Input Status
  232.     0Ch Clear Keyboard Buffer & Input
  233.  
  234.     They all expect the keyboard to be    file handle 0. If you want to  let a
  235.     program think  you are  typing something,  you can    replace this  handle
  236.     with  a  file  containing  the  keystrokes    it  must  read. This is what
  237.     happens when you  'pipe' something in  DOS. (Don't forget  to change the
  238.     handle back to the old one!)
  239.  
  240.     This also means you can use:
  241.  
  242.     3Fh Read bytes from handle
  243.  
  244.     Fn 01h: Keyboard Input
  245.     ----------------------
  246.     Expects: AH  01h
  247.  
  248.     Returns: AL  Character fetched from the Standard Input
  249.  
  250.     Description: Reads    (waits    for)  a  character from  the Standard  Input
  251.          Device.   Echoes  that  character  to    the  Standard Output
  252.          Device.  If Ctrl-Break is detected, INT 23h is executed.
  253.  
  254.     Notes:     Extended ASCII keystrokes  (ie, F1-F12, PgUp,    cursor, etc)
  255.          will require two  calls to this  function.  The  first call
  256.          will  return  AL=0.   The  second  will  return AL with the
  257.          extended ASCII code.
  258.  
  259.     Fn 06h: Console I/O
  260.     -------------------
  261.     Expects: AH  06h
  262.          DL  0 to 0FEh  Character to send to the Standard Output
  263.          0FFh        Request for input from the Standard Input
  264.  
  265.     Returns: ZF  Clear (NZ) if character is ready \ on input requests
  266.          AL  Character read, if ZF is clear   / (when DL=0FFh)
  267.  
  268.     Description: If DL    is 0FFh,  this performs  a "no    wait" console input,
  269.          returning  the  Zero  Flag  (ZF)  set    (ZR)  if there is no
  270.          character  ready.   If  a  character  is  ready, returns ZF
  271.          cleared (NZ) with the character that was read in AL.
  272.  
  273.          If DL    is anything  but 0FFh,    DL is  sent to    the Standard
  274.          Output.
  275.  
  276.     Notes:     Does not  check for  Ctrl-Break.   Call twice    for Extended
  277.          ASCII.
  278.  
  279.     Fn 07h: No Echo Unfiltered Console Input
  280.     ----------------------------------------
  281.     Expects: AH  07h
  282.  
  283.     Returns: AL  Character fetched from the Standard Input
  284.  
  285.     Description: Reads    (waits    for)  a  character  from  the Standard Input
  286.          Device, returning that character in AL.
  287.  
  288.          Unfiltered: Does not detect Ctrl-Break, backspace, etc.
  289.  
  290.     Notes:     Call twice for Extended ASCII character input.
  291.          Use Fn 0Bh to check status  (if you don't want to wait  for
  292.          a key).
  293.  
  294.     Fn 08h: No Echo Console Input
  295.     -----------------------------
  296.     Expects: AH  08h
  297.  
  298.     Returns: AL  Character fetched from the Standard Input
  299.  
  300.     Description: Reads    (waits    for)  a  character  from  the Standard Input
  301.          Device, returning that character in AL.
  302.  
  303.          If Ctrl-Break is detected, INT 23h is executed.
  304.  
  305.     Notes:     Call twice for Extended ASCII character input.
  306.  
  307.     Fn 0Ah: Buffered String Input
  308.     -----------------------------
  309.     Expects: AH  0Ah
  310.          DS:DX Address of an input buffer (see below)
  311.  
  312.     Returns:     Buffer contains input terminated with CR (ASCII 13h)
  313.  
  314.     Description: On entry, the buffer at DS:DX must be set up as:
  315.          ┌───┬───┬───┬───┬───┬───┬─ ─ ─
  316.          │max│ ? │ ?   ?   ?   ?   ?     max is maximum acceptable
  317.          └───┴───┴───┴───┴───┴───┴ ─  ─  input (range: 1 to 254)
  318.          On exit, the buffer is filled:
  319.          ┌───┬───┬───┬───┬───┬───┬─ ─ ─  len is actual length of
  320.          │max│len│ T   E   X   T   0Dh     input, less the termina-
  321.          └───┴───┴───┴───┴───┴───┴ ─  ─  ting CR (eg, 4).
  322.  
  323.          Characters are  read from  the Standard  Input up  to a  CR
  324.          (ASCII  13)  or  up  to  the  value  of max-1.  If max-1 is
  325.          reached, the console bell rings (beeps) for each  character
  326.          until Enter (CR) is read.
  327.  
  328.          The second  byte of  the buffer  is filled  with the actual
  329.          length of the    input, less the  terminating CR.   The final
  330.          character in the buffer is always CR (which is not  counted
  331.          in the length byte).
  332.  
  333.          The characters  in the  buffer (including  the len)  before
  334.          the call are used as a "template" and the DOS editing    keys
  335.          are in effect:  [Esc]    displays "\" and restarts the  edit,
  336.          [F3] displays    to the    end of    the template,  [F5] displays
  337.          "@"  and  stores  the    current  line  as the template, etc.
  338.          Most Extended ASCII keystrokes are ignored.
  339.  
  340.          If  Ctrl-Break  is  detected,    INT  23h is executed and the
  341.          buffer is left unchanged.
  342.  
  343.     Fn 0Bh: Check Input Status
  344.     --------------------------
  345.     Expects: AH  0Bh
  346.  
  347.     Returns: AL  0FFh if a character is available from the Standard Input
  348.          0    if no character is available
  349.  
  350.     Description: Checks the status of the Standard Input.
  351.  
  352.          If Ctrl-Break is detected, INT 23h is executed.
  353.  
  354.     Notes:     Use before Fns  01h, 07h and  08h to avoid  having DOS wait
  355.          for a key.
  356.  
  357.          This  is  a  simple,  non-destructive    way  to  check     for
  358.          Ctrl-Break  during  long  calculations  or other processing
  359.          that does not    normally look for  input.  It  lets the user
  360.          abort from such a sequence.
  361.  
  362.     Fn 0Ch: Clear & Input
  363.     ---------------------
  364.     Expects: AH  0Ch
  365.          AL  DOS input function number (01h, 06h, 07h, 08h, or 0Ah)
  366.  
  367.     Returns: none
  368.  
  369.     Description: Clears the  Standard Input  type-ahead buffer    then invokes
  370.          the DOS input    function specified by  AL.  This  forces the
  371.          system to wait for a character to be typed.
  372.  
  373.          These values are allowed for AL:
  374.             01h Keyboard Input
  375.             06h Console I/O
  376.             07h No Echo Unfiltered Input
  377.             08h No Echo Filtered Input
  378.             0Ah Buffered Input
  379.  
  380.  
  381.     In addition to these functions, it    is also possible to read a  selected
  382.     amount  of    characters  from  the  keyboard,  using  DOS's    File  Handle
  383.     functions, as the Keyboard, aka Standard Input, has a pre-set handle  of
  384.     0000h:
  385.  
  386.     Fn 3Fh: Read from keyboard via Handle
  387.     -------------------------------------
  388.     Expects: AH  3Fh
  389.          BX  0000h - Handle for Standard Input (Keyboard)
  390.          DS:DX Address of buffer to receive data
  391.          CX  Number of bytes to read
  392.  
  393.     Returns: AX  Error code if CF is set to CY
  394.          AX  Number of bytes actually read
  395.  
  396.     Description: CX bytes of  data are read from  the keyboard. The data  is
  397.          placed into the caller's buffer pointed to by DS:DX.
  398.  
  399.     Notes:     It  is  handy    to  use  this  function  for reading default
  400.          handles such as  the Standard I/O  handles, instead of  the
  401.          buffered input or character-by-character input functions.
  402.  
  403.          When you read from a  device, AX returns the length  of the
  404.          line up to and including the termination CR (ASCII 13h).
  405.  
  406.  
  407.     3. BIOS Interfacing
  408.     ───────────────────
  409.  
  410.     Pro:
  411.     - You get to know all the statusses and such
  412.     - It's a tad bit faster than DOS
  413.     - You can only read the keyboard
  414.     - It's easier than the really hardcore low level, and the keys
  415.       are translated
  416.  
  417.     Contra:
  418.     - It is still to slow for games or demos
  419.     - You don't have bulk access, like strings
  420.  
  421.     The BIOS has 3 different ways of reading (parts of) the keyboard:
  422.     - functions
  423.     - keyboard flags
  424.     - keyboard buffer
  425.  
  426.     This part describes all of them.
  427.  
  428.  
  429.     3.1. Functions
  430.     ──────────────
  431.  
  432.     These functions can be accessed through int 16h.
  433.  
  434.     Fn 00h: Read (wait for) next keystroke
  435.     --------------------------------------
  436.     Expects: AH  0
  437.  
  438.     Returns: AL  ASCII    character (if  AL=0, AH  is an Extended  ASCII    key-
  439.          stroke)
  440.          AH  Scan Code or Extended ASCII keystroke
  441.  
  442.     Fn 01h: Check if a keystroke is ready (and preview it if so)
  443.     ------------------------------------------------------------
  444.     Expects: AH  1
  445.  
  446.     Returns: ZF  ZR or 1 if no key is ready
  447.          ZF  NZ or 0 if a key is ready.
  448.          AX  is  set  as  for  Fn  00h  (but  the keystroke has not been
  449.          removed from the queue).
  450.  
  451.     Fn 02h: Read the shift-key status
  452.     ---------------------------------
  453.     Expects: AH  2
  454.  
  455.     Returns: AL  shift key and 'lock' status as in 83-keyboard flags
  456.  
  457.     Description: Determine which shift keys are currently being pressed  and
  458.          whether the keyboard is in NumLock state, etc.
  459.  
  460.     Fn 03h Set keyboard typeamatic rate and delay. (11/15/85 BIOS)
  461.     --------------------------------------------------------------
  462.     Expects: AH  3
  463.          AL  05h (eg, AX = 0305h)
  464.          BL  Typeamatic Rate
  465.          0: 30 keys/sec  10: 10
  466.          1: 26.7     13: 9
  467.          2: 24         16: 7.5
  468.          4: 20         20: 5
  469.          8: 15         31: 2
  470.          BH  Delay: 0=250ms 1=500ms 2=750ms 3=1 second)
  471.  
  472.     Returns: none
  473.  
  474.     Description: when a key is pressed, the keyboard will wait during Delay
  475.          before it starts repeating at Typematic Rate.
  476.  
  477.     Fn 05h Place a keystroke into the keyboard buffer. (11/15/85 BIOS)
  478.     ------------------------------------------------------------------
  479.     Expects: AH  5
  480.          CL  ASCII character.
  481.          CH  Scan Code  byte (or 0 if you don't care)
  482.  
  483.     Returns: AL  Status: 0=success; 1=buffer full
  484.  
  485.     Fn 10h Read (wait for) a keystroke; 101-keyboard only (11/15/85 BIOS)
  486.     ---------------------------------------------------------------------
  487.     Expects: AH  10h
  488.  
  489.     Returns: AL  ASCII    character  (if    AL=0,  AH is an  Extended ASCII key-
  490.          stroke)
  491.          AH  Scan Code or Extended ASCII keystroke
  492.  
  493.     Fn 11h Preview keystroke; same as 01; 101-keyboard only (11/15/85 BIOS)
  494.     -----------------------------------------------------------------------
  495.     Expects: AH  11h
  496.  
  497.     Returns: ZF  ZR or 1 if no key is ready
  498.          ZF  NZ or 0 if a key is ready.
  499.          AX  set as for Fn 10 but keystroke is still in the buffer.
  500.  
  501.     12h Read shift-key status; same as 02; 101-keyboard only (11/15/85 BIOS)
  502.     ------------------------------------------------------------------------
  503.     Expects: AH  12H
  504.     Returns: AL  shift key and 'lock' status as in 101-keyboard flags
  505.  
  506.  
  507.     3.2. Keyboard Flags
  508.     ───────────────────
  509.  
  510.     The keyboard flags are found in the BIOS Data Area: segment 40h.
  511.  
  512.     17h: 83-keyboard flags    0=Off, 1=On
  513.     ---------------------------------------
  514.     bit 0: Right shift
  515.     1: Left shift
  516.     2: Ctrl, either side
  517.     3: Alt, either side
  518.     4: Scroll Lock
  519.     5: Num Lock
  520.     6: Caps Lock
  521.     7: Insert state
  522.  
  523.     Do NOT just change one of these and then hope the keyboard follows.  The
  524.     LEDs will definitely get out of sync.
  525.  
  526.     18h: 101-keyboard flags    0=Off, 1=On
  527.     ---------------------------------------
  528.     bit 0┐           : Left ctrl
  529.     1├─At keyb. only   : Left Alt
  530.     2┘           : Sys Req
  531.     3: Pause state
  532.     4: Scroll Lock       ┐
  533.     5: Num Lock       ├─Being pressed
  534.     6: Caps Lock       │
  535.     7: Insert       ┘
  536.  
  537.     Do NOT just change one of these and then hope the keyboard follows.  The
  538.     LEDs will definitely get out of sync.
  539.  
  540.     19h: Pseudokey value
  541.     --------------------
  542.     This is the  accumulating value of    the key being  made with Alt+numeric
  543.     keypad.  Normally 0
  544.  
  545.     71h: Ctrl-break flag    0=Off, 1=On
  546.     ---------------------------------------
  547.     bit 7: Ctrl-Break was pressed. Never gets reset, unless you do.
  548.  
  549.     96h: AT only - keyboard ?    0=Off, 1=On
  550.     ---------------------------------------
  551.     bit 4: 101/102 keyboard is attached
  552.  
  553.     97h: AT only - lock LEDs    0=Off, 1=On
  554.     ---------------------------------------
  555.     bit 0: ScrollLock ┐
  556.     1: NumLock    ├─ keyboard LED is turned on
  557.     2: CapsLock   ┘
  558.  
  559.     Do NOT just change one of these and then hope the keyboard    follows.
  560.     The LEDs will definitely get out of sync.
  561.  
  562.  
  563.     3.3. Keyboard Buffer
  564.     ────────────────────
  565.  
  566.     The keyboard  buffer is  a circular  data area.  This means  that when a
  567.     pointer in the  buffer gets one  larger than the  buffer, it is  wrapped
  568.     around to the beginning.
  569.  
  570.     The keyboard buffer is fed    by int 9 and function  5 of int 16h.   It is
  571.     found at the BIOS data segment, 40h. It is pointed to by 4 variables  in
  572.     the BDA:  The  head (1ah), the tail  (1ch), the Beginning (80h)  and the
  573.     End (82h). They are all words, pointing at locations in the BDA.
  574.  
  575.     The latter    two are  only available  on ATs  and PSs.  They are  used to
  576.     enlarge the keyboard buffer  by mapping it to  another spot in the    BIOS
  577.     data area.    Normally, that spot is 32 bytes long starting from 1eh.
  578.  
  579.     The head is  the pointer to  the next word.  The tail is  the pointer to
  580.     the next available word.  Each code is two bytes, the scan code and  the
  581.     ASCII value.
  582.  
  583.     The buffer is empty if  the Head = the Tail  and it is full if  the Tail
  584.     is two smaller than the Head, both counted circularly.  This means    that
  585.     the storage space equals (length buffer/2)-1.
  586.  
  587.  
  588.     4. Low-Level Interfacing
  589.     ────────────────────────
  590.  
  591.     Pro:
  592.     - Fast
  593.     - Complete control
  594.  
  595.     Contra:
  596.     - Hard to code
  597.     - Totally NO functions at all. It's Handyman work here...
  598.  
  599.     The interfacing is split in two items:
  600.     - Just changing something, such as the LED's
  601.     - Reading out codes: int 9
  602.  
  603.  
  604.     4.1. Interfacing And Configuring
  605.     ────────────────────────────────
  606.  
  607.     The computer and  the AT or  MF II interface  through I/O ports  60h and
  608.     64h, controlled  by a  programmable Intel  8042 (old  ATs), 8741 or 8742
  609.     (newer, allow two  input devices (like  the PS/2 mouse))  microprocessor
  610.     or compatible,  which allows  typematic rate  programming, LEDs lighting
  611.     and some other stuff. It also  has a +-20 byte output buffer  for smooth
  612.     operation and long scancodes.
  613.  
  614.     The  old  XT  keyboard  has  a  8048,  which  is  in essence just a very
  615.     primitive one-way serial interface, so all used is port 61h, to  disable
  616.     and reenable the keyboard on every scancode.
  617.  
  618.     Port 60h: Input & output
  619.     ------------------------
  620.     Read: Scancodes and keyboarddata
  621.     --------------------------------
  622.     This port gives the following output codes:
  623.  
  624.     00h: Keyboard error, too many keys are being pressed at once
  625.     aah: Basic Assurance Test (BAT) end
  626.     abh 41h: The result of requesting keyboard ID on a MF II keyboard
  627.     eeh: The result of the echo command
  628.     fah: ACK(noledge). Sent by every command, except eeh and feh
  629.     fch: BAT failed
  630.     feh: Resend your data please
  631.     ffh: Keyboard error
  632.  
  633.     All the rest are make (press) and break (release) codes of the keys.
  634.  
  635.     Write: Command data
  636.     -------------------
  637.     This is the  place where command  data has to  be sent.   If the command
  638.     consists of two bytes, you must  wait until the outputbuffer is sent  to
  639.     the keyboard.   Check on  it via  bit 1  of port  64h. When  you send  a
  640.     command, the outputbuffer is cleared,  so pending results may not  come.
  641.     During transmission of a two-byte command, the keyboard stops  scanning.
  642.     When you  send something  out of  range or    so, the  keyboard will react
  643.     with feh  (resend).   All commands,  except echo  (eeh) and resend (feh)
  644.     result in ACK (fah) to be sent.
  645.  
  646.     Commands:
  647.  
  648.     edh: Set keyboard LEDs
  649.      Send a second byte with:
  650.  
  651.          bit 0 = Scroll Lock    0=Off 1=On
  652.          1 = Num Lock
  653.          2 = Caps Lock
  654.           rest = 0
  655.  
  656.      Do make an effort to keep the BIOS keyboard flags in sync.
  657.  
  658.     eeh: Great fun. Send it, and get 0eeh right back! :-]
  659.      (Diagnostics)
  660.  
  661.     f0h: Select scancode set.
  662.  
  663.          0: return current set number: 1:'C', 2:'A', 3:'?'
  664.          1: set scancode set no 1
  665.          2: set scancode set no 2 -> standard
  666.          3: set scancode set no 3
  667.  
  668.     f2h: Identify keyboard
  669.          XT: nothing (that is, time-out error :-) (see port 64h)
  670.          AT: ACK
  671.          MF II: ACK abh 41h
  672.  
  673.     f3h: Typematic rate programming
  674.      Send a second byte with:
  675.  
  676.          bit 0 -> 4: rate. Timings:
  677.  
  678.          0: 30 keys/sec   10: 10
  679.          1: 26.7          13: 9
  680.          2: 24          16: 7.5
  681.          4: 20          20: 5
  682.          8: 15          31: 2
  683.  
  684.          bit 5 & 6: pause before repeat:
  685.  
  686.          0: 250 ms
  687.          1: 500
  688.          2: 750
  689.          4: 1000
  690.  
  691.          bit 7: Always 0
  692.  
  693.     The next  three are  doubtfull, since  one of  my sources say they don't
  694.     exist and another says they do. I leave it up to you :)
  695.  
  696.     f4h: Enable keyboard. It clears its buffer and starts scanning.
  697.     f5h: Reset keyboard, disable scanning
  698.     f6h: Reset keyboard, enable scanning
  699.  
  700.     feh: Resend last transmission. I really don't know what it does, since
  701.      it sends something incomprehesible.
  702.  
  703.     ffh: Internal diagnostics: Sends aah if successfull.  Warning! The
  704.      keyboard reacts with ACK and then you have to set the data and
  705.      clock pins high, DURING AT LEAST 500 SECONDS!. Do this via the
  706.      outputport (see 64h). After that, the BAT (Basic Assurance Test)
  707.      starts. This sends aah on success and fch on failure.
  708.  
  709.     Example: Set the keyboard LEDs
  710.  
  711.     start:
  712.       in  al, 64h                     \It would be good
  713.       and al, 02h    ;Test if command buffer is empty |to put this in a
  714.       jnz start                     /macro...
  715.  
  716.       mov al, edh
  717.       out 60h, al    ;Write outputport
  718.  
  719.     wait:
  720.       in  al, 64h
  721.       and al, 02h    ;Test if command came through
  722.       jnz wait
  723.  
  724.       mov al, 0111b
  725.       out 60h, al    ;Set all LED's to ON.
  726.  
  727.  
  728.     Port 61h
  729.     --------
  730.     This  port    is  used  to  acknoledge  the  receival  of  a    scancode, by
  731.     disabling the keyboard  and immediately reenabling    it. This also  means
  732.     that  you  can  read  a  scancode  as  many times as you like, until you
  733.     acknoledge the receival.
  734.  
  735.     bit 0 -> 5: Nothing to do with keyboard, but with the Programmable
  736.         Peripheral Interface (PPI) -> save them!
  737.     bit 6: Hold keyboard clock low -> Keyboard can't send any data.
  738.     bit 7: 0=Enable keyboard; 1=Disable keyboard
  739.  
  740.     Example:
  741.  
  742.       in  al, 61h
  743.       mov ah, al    ;Save keyboard status
  744.       or  al, 80h    ;Disable
  745.       out 61h, al
  746.       mov al, ah    ;Enable (If it was disabled at first, you wouldn't
  747.       out 61h, al    ; be doing this anyway :-)
  748.  
  749.  
  750.     Port 64h: Interface: data and control
  751.     -------------------------------------
  752.     Read: Statusport
  753.     ----------------
  754.     bit 0: 1: Keyboard data is in buffer
  755.            0: Output buffer empty -> use it to check for results
  756.         1: 1: User data is in buffer
  757.            0: Command buffer is empty -> time to send a command
  758.         2: 1: Selftest successful
  759.            0: Reset (?)
  760.         3: 1: 64h was last accessed port
  761.            0: 60h was last accessed port
  762.         4: 1: Keyboard enabled
  763.            0: Keyboard locked
  764.         5: PS/2: Mouse interface
  765.         6: 1: Time-out error occurred: Keyboard or PS/2 mouse didn't
  766.           react. Use the Resend command to retry fetching the data
  767.           byte. This could happen when trying to get a XT keyboard
  768.           to do something :).
  769.         7: 1: Last transmission had a parity error
  770.  
  771.     Write: Control register
  772.     -----------------------
  773.     This is the control room  of the keyboard interface. If  additional data
  774.     is required,  send it  to port  60h after  writing the  command to    64h.
  775.     Also, check 61h bit 2 before sending anything.
  776.  
  777.     Commands:
  778.  
  779.     aah: Keyboard self test. Sends 55h if successfull.
  780.  
  781.     abh: Test interface. Sends:
  782.  
  783.          00h: No error
  784.          01h: Clock low
  785.          02h: Clock high
  786.          03h: Data low
  787.          04h: Data high
  788.          ffh: Total Error
  789.  
  790.     adh: Deactivate keyboard
  791.  
  792.     aeh: Activate keyboard
  793.  
  794.     c0h: Read inputport. This is some highly specialized stuff and I wonder
  795.      why I am typing this. Ok. The inputport is that what the keyboard
  796.      is sending and some more. Layout:
  797.  
  798.          bit 0: Keyboard data in pin
  799.          1: PS/2 mouse in pin
  800.          2->5: reserved
  801.          6: Wether you have a color or mono screen
  802.          7: 1: Keyboard not locked
  803.             0: Keyboard locked
  804.  
  805.      When you issue this command, the inputport is put on the
  806.      outputbuffer, so you have the great priviledge of reading it at
  807.      port 60h.
  808.  
  809.     c1h: Puts the low nibble of the input port over bits 4-7 of the
  810.      statusport, so you can read them out continuously. This lasts
  811.      until bit 2 of the statusport gets set, meaning you are sending
  812.      data to the keyboard.
  813.  
  814.     c2h: Ditto, but it puts the high nibble over bits 0-3 of the
  815.      statusport. Lifespan is the same.
  816.  
  817.     d0h: Puts the outputport on the buffer. Layout:
  818.  
  819.          bit 0: 1: Reset processor
  820.          1: 1: A20 gate enable
  821.          2: PS/2 mouse data out
  822.          3: PS/2 mouse clock signal
  823.          4: 1: Output buffer full
  824.          5: 1: Output buffer PS/2 mouse full
  825.          6: Keyboard clock signal
  826.          7: Keyboard data out
  827.  
  828.      Bit 0 and 1 are quite important for high memory and
  829.      286-extended-memory access.
  830.  
  831.     d1h: Write the following data byte to the outputport
  832.  
  833.     d2h: Write the following data byte to the keyboardbuffer. This is VERY
  834.      handy for TSRs that need to read codes that start with e0h. This
  835.      way, they don't have to pass through the e0h, unless they know for
  836.      sure it isn't their code, which results in correct functioning
  837.      shift keys etc. At least, if it does what I think it
  838.      does... [UNTESTED]
  839.  
  840.     d3h: Ditto, for PS/2 mouse.
  841.  
  842.     d4h: Write byte to PS/2 mouse.
  843.  
  844.     e0h: Reads the keyboards testinputs, T0 and T1. T0 goes to bit 0 and T1
  845.      to bit 1 of the byte that is put on the outputbuffer.
  846.  
  847.     fxh: I think it sends x to the low nibble of the output port. It does
  848.      reset my computer when I send feh, but that doesn't mean anything
  849.      :-). The official explanation says that it keeps the corresponding
  850.      bits in the output port low for 6ms...
  851.  
  852.     Example: Send something to the outputport
  853.  
  854.     start:
  855.       in  al, 64h                    \It would be good
  856.       and al, 02h    ;Test if command buffer is empty|to put this in a
  857.       jnz start                    /macro...
  858.  
  859.       mov al, d1h
  860.       out 64h, al    ;Write outputport
  861.  
  862.     wait:
  863.       in  al, 64h
  864.       and al, 02h    ;Test if command came through
  865.       jnz wait
  866.  
  867.       mov al, 01h
  868.       out 60h, al
  869.  
  870.  
  871.     4.2. Lay-Out
  872.     ────────────
  873.  
  874.     The keyboard first    consisted of 83  keys, which is now known as  the XT
  875.     keyboard.    Then  came  along  the    AT-keyboard,  which  has  84 keys, a
  876.     slightly different layout and an extra SysReq key. The next keyboard  is
  877.     the MF II keyboard.  This one has  101 or 102 keys, and this is the  one
  878.     this section will be babbling about.
  879.  
  880.     The keycaps  change, but    the  most popular  settings are  QWERTY  and
  881.     AZERTY.  Also popular is the Dvorak lay-out, made     by  what's-his-name
  882.     Dvorak, who made  the lay-out so  that both hands  did not have  to move
  883.     that much, resulting in fast (up  to double) typing speed.    This  is it,
  884.     should  you be  interested    (slight  modifications    by  me,  because  it
  885.     actually requires a 12x4 keyboard):
  886.  
  887.         101 - key                  102 - key
  888.  
  889.     ~ ! @ # $ % ^ & * ( ) [ +          ⁿ ! @ # $ % ^ & * ( ) [ +
  890.     ` 1 2 3 4 5 6 7 8 9 0 ] =          ² 1 2 3 4 5 6 7 8 9 0 ] =
  891.  
  892.       " , . P Y F G C R L ? { |     " , . P Y F G C R L ? {
  893.       ' , . p y f g c r l / } \     ' , . p y f g c r l / }
  894.  
  895.       A O E U I D H T N S _ <        A O E U I D H T N S _ ~
  896.       a o e u i d h t n s - >        a o e u i d h t n s - `
  897.  
  898.       : Q J K X B M W V Z          > : Q J K X B M W V Z
  899.       ; q j k x b m w v z          < ; q j k x b m w v z
  900.  
  901.  
  902.     The key lay-out is as follows: (The numbers are internal to the
  903.     keyboard)
  904.  
  905.     US-English Keyboard: 101 keys
  906.     -----------------------------
  907.     ┌──┐┌──┬──┬──┬──┐┌──┬──┬──┬──┐┌──┬──┬──┬──┐┌──┬──┬──┐
  908.     │10││12│13│14│15││16│17│18│19││20│21│22│23││24│25│26│ <── Add 100 to the
  909.     └──┘└──┴──┴──┴──┘└──┴──┴──┴──┘└──┴──┴──┴──┘└──┴──┴──┘     keycodes on
  910.                                   this line
  911.     ┌─┬──┬──┬──┬──┬──┬──┬──┬──┬──┬──┬──┬──┬───┐┌──┬──┬──┐┌──┬──┬───┬───┐
  912.     │1│ 2│ 3│ 4│ 5│ 6│ 7│ 8│ 9│10│11│12│13│ 15││75│80│85││90│95│100│105│
  913.     ├─┴┬─┴┬─┴┬─┴┬─┴┬─┴┬─┴┬─┴┬─┴┬─┴┬─┴┬─┴┬─┴┬──┤├──┼──┼──┤├──┼──┼───┼───┤
  914.     │16│17│18│19│20│21│22│23│24│25│26│27│28│29││76│81│86││91│96│101│   │
  915.     ├──┴┬─┴┬─┴┬─┴┬─┴┬─┴┬─┴┬─┴┬─┴┬─┴┬─┴┬─┴┬─┴──┤└──┴──┴──┘├──┼──┼───┤   │
  916.     │30 │31│32│33│34│35│36│37│38│39│40│41│ 43 │      │92│97│102│106│
  917.     ├───┴─┬┴─┬┴─┬┴─┬┴─┬┴─┬┴─┬┴─┬┴─┬┴─┬┴─┬┴────┤   ┌──┐     ├──┼──┼───┼───┤
  918.     │ 44  │46│47│48│49│50│51│52│53│54│55│  57 │   │83│     │93│98│103│   │
  919.     ├───┬─┼──┴┬─┴──┴──┴──┴──┴──┴──┴─┬┴──┼─┬───┤┌──┼──┼──┐├──┴──┼───┤   │
  920.     │58 │ │60 │      61        │ 62│ │ 64││79│84│89││ 99  │104│108│
  921.     └───┘ └───┴─────────────────────┴───┘ └───┘└──┴──┴──┘└─────┴───┴───┘
  922.  
  923.                   |
  924.     This has the extra 29 key, or \
  925.  
  926.     Other Countries: 102 keys
  927.     -------------------------
  928.     ┌──┐┌──┬──┬──┬──┐┌──┬──┬──┬──┐┌──┬──┬──┬──┐┌──┬──┬──┐
  929.     │10││12│13│14│15││16│17│18│19││20│21│22│23││24│25│26│ <── Add 100 to the
  930.     └──┘└──┴──┴──┴──┘└──┴──┴──┴──┘└──┴──┴──┴──┘└──┴──┴──┘     keycodes on
  931.                                   this line
  932.     ┌─┬──┬──┬──┬──┬──┬──┬──┬──┬──┬──┬──┬──┬───┐┌──┬──┬──┐┌──┬──┬───┬───┐
  933.     │1│ 2│ 3│ 4│ 5│ 6│ 7│ 8│ 9│10│11│12│13│ 15││75│80│85││90│95│100│105│
  934.     ├─┴┬─┴┬─┴┬─┴┬─┴┬─┴┬─┴┬─┴┬─┴┬─┴┬─┴┬─┴┬─┴┬──┤├──┼──┼──┤├──┼──┼───┼───┤
  935.     │16│17│18│19│20│21│22│23│24│25│26│27│28│43││76│81│86││91│96│101│   │
  936.     ├──┴┬─┴┬─┴┬─┴┬─┴┬─┴┬─┴┬─┴┬─┴┬─┴┬─┴┬─┴┬─┴┐ │└──┴──┴──┘├──┼──┼───┤   │
  937.     │30 │31│32│33│34│35│36│37│38│39│40│41│42│ │      │92│97│102│106│
  938.     ├──┬┴─┬┴─┬┴─┬┴─┬┴─┬┴─┬┴─┬┴─┬┴─┬┴─┬┴─┬┴──┴─┤   ┌──┐     ├──┼──┼───┼───┤
  939.     │44│45│46│47│48│49│50│51│52│53│54│55│  57 │   │83│     │93│98│103│   │
  940.     ├──┴┬─┼──┴┬─┴──┴──┴──┴──┴──┴──┴─┬┴──┼─┬───┤┌──┼──┼──┐├──┴──┼───┤   │
  941.     │58 │ │60 │      61        │ 62│ │ 64││79│84│89││ 99  │104│108│
  942.     └───┘ └───┴─────────────────────┴───┘ └───┘└──┴──┴──┘└─────┴───┴───┘
  943.  
  944.     This  has  the  extra  42  and  45    keys.  Their characters change from
  945.     country to country.
  946.  
  947.  
  948.     4.3. Scancodes
  949.     ──────────────
  950.  
  951.     The AT-keyboard has 3 separate scancode settings:     One as we know  it,
  952.     (83 key-mapping, and added codes have an extra e0h added), one  (almost)
  953.     sequential and one with ONE byte codes! Problem with the latter is    that
  954.     only  for  lshift,    caps,  lctrl  and  lalt breakcodes are sent :-(. The
  955.     keyboard starts up in  set 2, the set  can be changed via  port 64h (see
  956.     above).
  957.  
  958.     In set 1 and  2, there are special    codes, namely e0h and  e1h. They are
  959.     used for keys that    have  the same function.   An example:    1dh  for the
  960.     left control  key and  e0h 1dh  for the  right one.   This is  done  for
  961.     lowlevel compatibility with XT programs.  Notice that the only time  e1h
  962.     is used, is when it represents  a temporary control key, which also  has
  963.     a e0h version.
  964.  
  965.     e0h  2ah  is  a  temporary    shift  function, used by for example PrtScr,
  966.     which is  in reality  shift-numkeypad-*, like  on the  XT keyboard.  See
  967.     below for further information.
  968.  
  969.     The code will be sent as shown  further.  The codes listed are the    make
  970.     codes. They are sent when a  key is pressed. Upon release, the  keyboard
  971.     sends a break  code. It is    the make code,    but ORed with  80h. The only
  972.     exception to this are the codes e0h and e1h, which remain the same.   So
  973.     for example  pressing and  releasing the  right ctrl  key would give e0h
  974.     1dh and e0h 9dh. I only give the codes for set 2 because the rest  would
  975.     be too much work  and stupid. If you  want them, look them    up yourself.
  976.     Modify any of the accompanying source codes or so...
  977.  
  978.     °  Only on US-English keyboards
  979.     °° Only on other country versions
  980.  
  981.     Scancodes are in hex.
  982.  
  983.     Key  Scan  Key  Scan  Key  Scan  Key  Scan    Key  Scan  Key    Scan
  984.     no.  code  no.  code  no.  code  no.  code    no.  code  no.    code
  985.     ────┬─────╥────┬─────╥────┬─────╥────┬─────╥────┬─────╥────┬─────
  986.     1    │29   ║19  │12     ║36  │23   ║53  │33   ║86  │e0 51║106 │4e
  987.     2    │02   ║20  │13     ║37  │24   ║54  │34   ║89  │e0 4d║108 │e0 1c
  988.     3    │03   ║21  │14     ║38  │25   ║55  │35   ║90  │45   ║110 │01
  989.     4    │04   ║22  │15     ║39  │26   ║57  │36   ║91  │47   ║112 │3b
  990.     5    │05   ║23  │16     ║40  │27   ║58  │1d   ║92  │4b   ║113 │3c
  991.     6    │06   ║24  │17     ║41  │28   ║60  │38   ║93  │4f   ║114 │3d
  992.     7    │07   ║25  │18     ║42°°│2b   ║61  │39   ║95  │e0 35║115 │3e
  993.     8    │08   ║26  │19     ║43  │1c   ║62  │e0 38║96  │48   ║116 │3f
  994.     9    │09   ║27  │1a     ║44  │2a   ║64  │e0 1d║97  │4c   ║117 │40
  995.     10    │0a   ║28  │1b     ║45°°│56   ║75  │e0 52║98  │50   ║118 │41
  996.     11    │0b   ║29° │2b     ║46  │2c   ║76  │e0 53║99  │52   ║119 │42
  997.     12    │0c   ║30  │3a     ║47  │2d   ║79  │e0 4b║100 │37   ║120 │43
  998.     13    │0d   ║31  │1e     ║48  │2e   ║80  │e0 47║101 │49   ║121 │44
  999.     15    │0e   ║32  │1f     ║49  │2f   ║81  │e0 4f║102 │4d   ║122 │57
  1000.     16    │0f   ║33  │20     ║50  │30   ║83  │e0 48║103 │51   ║123 │58
  1001.     17    │10   ║34  │21     ║51  │31   ║84  │e0 50║104 │53   ║124 │(*)
  1002.     18    │11   ║35  │22     ║52  │32   ║85  │e0 49║105 │4a   ║125 │46
  1003.                               ║126 │(*)
  1004.  
  1005.     (*)
  1006.     Key 124, AKA PrtScr/SysRq, is both. When pressed normally, it will    send
  1007.     (hex) e0 2a e0  37. This is in  fact a special shift-*,  or the original
  1008.     place of that code on the XT keyboard.
  1009.  
  1010.     Used in conjuction with:
  1011.  
  1012.     Normal: e0 2a e0 37
  1013.     Shift : e0 37
  1014.     Ctrl  : e0 37
  1015.     Alt   : e0 54
  1016.  
  1017.     Key 126: Pause/Break. On the  XT keyboard, this used to  be ctrl-NumLock
  1018.     and ctrl-ScrollLock. Now guess the    codes...   Very special  is that the
  1019.     break codes are sent immediately after  the make codes. I think that  is
  1020.     because the codes have odd length.
  1021.  
  1022.     Normal: e1 1d 45   (e0 1d is already used by rightctrl)
  1023.     Ctrl  : e0 46      (46 is the code for ScrollLock...)
  1024.  
  1025.  
  1026.     4.4. Int 9
  1027.     ──────────
  1028.  
  1029.     When a key is pressed or released, or when the 8042 sends an ACK or  NAK
  1030.     the keyboard triggers  IRQ1, or int  9.  This  can be masked  by setting
  1031.     bit 1 on port 21h, the  interrupt controller.  Int 9 gets  the scancode,
  1032.     translates it and puts it in the keyboard buffer.
  1033.  
  1034.     BEWARE: When a scancode consists of more than 1 byte,  it should be read
  1035.     ------  one byte per call. (Took me quite long to find out...)
  1036.  
  1037.     Translating:
  1038.     -----------
  1039.     Int 9 will    first call int    15h, subfunction 4fh,  with the scancode  in
  1040.     al.   If  the  scancode  is  legitimate,  the  carry flag is set, and al
  1041.     contains the  scancode.   If not,  the carry  flag is  reset, and  int 9
  1042.     stops.   (The  carries  are  picked  so  that  if  int 9 thinks the BIOS
  1043.     supports the call and it doesn't, the carry is set by the BIOS, and  the
  1044.     scancode can always be used). This allows the keyboard to be  redefined,
  1045.     by    taking    over  the  function  and  replacing scancodes.
  1046.  
  1047.     If you want to take over int  9, you must remember to let the  interrupt
  1048.     controller    know when  you are  finished, by  writing 20h  to port    20h,
  1049.     since this is a  hardware interrupt.  You  should also disable and    then
  1050.     reenable the keyboard (see port 61h), so the keyboard knows you got  the
  1051.     code. The codes come in one byte per IRQ, so save e0hs.
  1052.  
  1053.     The key will be translated by int 9, with the following special cases:
  1054.  
  1055.     00h:
  1056.     User is pressing too many keys at once: beep or something
  1057.  
  1058.     aah, bah 41h, eeh, fah, feh:
  1059.     Ignore it. Someone is playing with port 60h
  1060.  
  1061.     fch, ffh:
  1062.     Ditto, but now you know the keyboard is screwed up :)
  1063.  
  1064.     e0h 2ah:
  1065.     Well. If you let the keyboard decide what the NumLock state is
  1066.     (nothing to do with the LED), use it to see how the code must be
  1067.     translated (e0h 2ah: NumLock is on). Else, ignore. (Most Smart)
  1068.  
  1069.     Ctrl-NumLock or Pause:
  1070.     Place system in a tight wait loop until next key pressed. It  would
  1071.     be friendly to allow hardware IRQ's... (clock, comms etc) (I think)
  1072.  
  1073.     Ctrl-Break:
  1074.     Clear keyboard buffer  (=Equal Head and  Tail), place word  0000h in
  1075.     buffer, invoke int 23h, and set flag at 0040h:0071h (bit 7=1).
  1076.  
  1077.     Shift-PrtScr:
  1078.     Invoke int 5
  1079.  
  1080.     Ctrl-PrtScr:
  1081.     redirect CON to PRN. (Teletype mode)
  1082.     Never used it, perhaps never will. Doesn't work on my keyboard
  1083.     driver... (DOS) Don't know how to stop it.  Perhaps rehitting
  1084.     Ctrl-PrtScr... This is from hearsay.
  1085.  
  1086.     SysRq:
  1087.     Invoke int 15 subfunction 85h. al->0 when pressed, 1 when released.
  1088.  
  1089.     Ctrl-Alt-Del:
  1090.     Reboot. Here's a sample of how to reboot:
  1091.  
  1092.     mov ah,0Dh             ; Disk Reset
  1093.     int 21h              ; causes SmartDrv 4.x to write cache
  1094.     mov ax, 40h             ; set up segment addressing
  1095.     mov ds,ax
  1096.     or  byte ptr ds:[17h],0Ch    ; equivalent of pressing CTRL+ALT
  1097.     mov ax,4F53h             ; Issue a "DEL" (53h = DEL scan code)
  1098.     int 15h              ; EMM386 sees this & shuts down
  1099.     mov word ptr ds:[72h],1234h  ; Set REBOOT flag to Warm-Boot (0=cold)
  1100.     db 0EAh,0h,0h,0FFh,0FFh      ; JMP FFFF:0000
  1101.  
  1102.     Of course, the int 15h call should already have been done by the
  1103.     handler. It is also used by other caches to flush.
  1104.  
  1105.     Shift-numkeypad:
  1106.     Temporarily reverse the NumLock state, e.g. 8 becomes arrow up and
  1107.     vice versa.
  1108.  
  1109.     Alt+numkeypad:
  1110.     Make the pseudokey in BDA byte 19h until the alt is released, then
  1111.     put it in the keyboard buffer. How? Well, everytime an extra number
  1112.     comes in, multiply BDA:19h with 10 and add the new number.
  1113.  
  1114.     Alt release:
  1115.     See above. Just making sure it is implemented ;-)
  1116.  
  1117.     Ctrl+a->z:
  1118.     Send bytes 1 through 27
  1119.  
  1120.     Foreign keyboards:
  1121.     Some keys are accents, to be placed on the next key.
  1122.  
  1123.     Right alt:
  1124.     Some keys have three keys on it. To access them, the right alt is
  1125.     pressed. So remember to send the right ASCII code...
  1126.  
  1127.     NumLock:
  1128.     Switch numkeypad on/off and light/switch off LED
  1129.  
  1130.     CapsLock:
  1131.     Translate normal letters to caps or vice versa and light/switch off
  1132.     LED. A nice touch would be to have a distinction between CapsLock
  1133.     and Ctrl-CapsLock. The former would shift alfabetic
  1134.     keys only and the latter all keys...
  1135.  
  1136.     ScrollLock:
  1137.     Light/sw. off LED
  1138.  
  1139.     Int  9  also  has  to  adjust  the    BDA  flags  and  keyboard buffer. In
  1140.     addition, the driver should warn when the keyboard buffer is full.
  1141.  
  1142.  
  1143.     5. Tech Stuff
  1144.     ─────────────
  1145.  
  1146.     Interface:
  1147.     Bidirectional,    serial    synchronous.  The  keyboard communicates via
  1148.     clock and data line with the system. The data comes in 11 bit
  1149.     packets, namely start-data-parity-stop. Parity is uneven.
  1150.              =1   8bit  1bit   =0
  1151.     Also, see further.
  1152.  
  1153.     Data Format:
  1154.     Data transfer to and from the keyboard in IBM-compatible format:
  1155.     AT-, PS/2-mode: Idle state - "Data & Clock" high.
  1156.     PC mode:    Idle state - "Data" low, "Clock" high.
  1157.  
  1158.     Data Output:
  1159.     Open drain.
  1160.  
  1161.     Keyboard Sequence:
  1162.     Alpha-N-key-rollover.
  1163.  
  1164.     Automatic repeat function:
  1165.     All  keys  have  auto  repeat.     Delay    and  repeat  sequence can be
  1166.     modified through the system, but  is fixed for PC-mode. (10Hz  after
  1167.     500ms)
  1168.  
  1169.     Keyboard Self-diagnostic test:
  1170.     After  "Power-On"  or  upon  request,  the  keyboard  carries  out a
  1171.     self-diagnostic test. After positive  test, the keyboard sends    AAh.
  1172.     Any other is a failure.
  1173.  
  1174.     Pin assignment:
  1175.       ___             1 Clock
  1176.      /524\             2 Data
  1177.     |3   1|─┐         3 Not used
  1178.      \_∩_/    │chassis gnd     4 Gnd
  1179.         -         5 +5V (This is the place to tap from :-)
  1180.  
  1181.     PS/2 adaptor:         1 Data
  1182.       _ _             2 Not used
  1183.      /5U6\             3 Gnd
  1184.     |3   4|─┐         4 +5V
  1185.      \1_2/    │chassis gnd     5 Clock
  1186.         -         6 Not used
  1187.  
  1188.     The PC-XT keyboard communication protocol
  1189.     -----------------------------------------
  1190.     Below is a drawing of the timing of the data, send to the PC. The  upper
  1191.     line shows    the clock  line, the  lower the  data line.  The text  above
  1192.     indicates the position of the start, data and stop bits (clocked on  the
  1193.     negative edge of the clock line).
  1194.  
  1195.  
  1196.     Start    1       2     3     4     5       6     7     8     Stop
  1197.        │     │       │     │     │     │       │     │     │     │
  1198.     ───┐  ┌──┐    ┌──┐  ┌──┐  ┌──┐  ┌──┐    ┌──┐  ┌──┐  ┌──┐  ┌──┐    ┌───
  1199.     clk└──┘  └──┘  └──┘  └──┘  └──┘  └──┘  └──┘  └──┘  └──┘  └──┘
  1200.     ────────┬─────┬─────┬─────┬─────┬─────┬─────┬─────┬────┐      ┌─
  1201.     dta     └─────┴─────┴─────┴─────┴─────┴─────┴─────┴────┴──────┘
  1202.  
  1203.     The communication abides to the following rules:
  1204.  
  1205.     - On power up or reset, the PC pulls the clock line (normally  high)
  1206.       low for at  least 20 ms.  When it is    released (goes high  again),
  1207.       the keyboard should send the code  0AAh to the PC to indicate  its
  1208.       existance.
  1209.  
  1210.     - The data is clocked in  on the negative edge of the  clock signal.
  1211.       The  clock  line  must  normally  be    high,  the  data line can be
  1212.       anything between transmissions. The  clock line is delayed  two PC
  1213.       clock cycles    in the    PC, so    data changes  and the negative clock
  1214.       edge may take  place at the  same time. It  is safer, however,  to
  1215.       build in a bigger delay.
  1216.  
  1217.     - A transmission starts with  a start bit (high). Then    follow eight
  1218.       data bits, of witch bit 7 (MSB) indicates the release of the    key.
  1219.       After that  normally follows    a stop    bit (low),  but that  may be
  1220.       left out. In fact, due  to the shift register hardware  inside the
  1221.       PC, any number  of stop bits    could be send,    as long as  they are
  1222.       low.     Not 100%  hardware compatibles,  however, may    get confused
  1223.       then.
  1224.  
  1225.     - After a transmission, the PC    pulls the data line low until  it is
  1226.       ready processing the data.  The keyboard should wait    with sending
  1227.       any more data until the PC releases the data line again.
  1228.  
  1229.  
  1230.     A. Acknowledgments
  1231.     ──────────────────
  1232.  
  1233.     This  text    was  made  by  Wout  Mertens,  with the help of Tech Help of
  1234.     Flambeaux software, the tech spex of Cherry and some texts I found.
  1235.  
  1236.     Information on the PC-XT keyboard communication protocol and the
  1237.     kbfunc.c file by Gertjan Klein (Floating somewhere in cyberspace).
  1238.  
  1239.     Cherry is the registered trademark of Cherry Microschalter Gmbh etc.
  1240.     IBM is the registered trademark of the IBM corporation
  1241.     Mertens is the registered trademark of the Mertens Family ;-)
  1242.  
  1243.     Improved copyright notice, thanks & greetings to:
  1244.     Emil Gilliam (Floating in cyberspace as well)
  1245.     Kip Cooley at the Diamond Bar BBS (909) 923-1031 (1:218/101).
  1246.     Ian Remmler at the DownTown BBS (210) 625-4479 (1:387/1001).
  1247.  
  1248.  
  1249.     B. How To Contact Me
  1250.     ────────────────────
  1251.  
  1252.     Please let me know    if something is inaccurate or missing etc.  Also,  I
  1253.     would like    some  feedback on  the quality    and usability  of this text.
  1254.     (Keeps me    writing...) If you think this text is very usefull, you  can
  1255.     always send me a nice postcard from where you live to thank me... I will
  1256.     then try to notify you when a new version arrives.
  1257.  
  1258.     I am usually  reachable through the  Fido 80XXX echo,  but you can    also
  1259.     reach me at the following addresses:
  1260.  
  1261.     Fido 2:292/805.1
  1262.     SBC  14:1900/457
  1263.     DGI  68:320/1.3
  1264.     CDN  94:810/1104
  1265.     CIN  112:913/101.4
  1266.  
  1267.     SnailMail: Wout Mertens
  1268.            Jozef de Bomstr 62
  1269.            2018 Antwerp
  1270.            Belgium - Europe
  1271.  
  1272.  
  1273.     C. The Answer To Life, The Universe And All The Rest
  1274.     ────────────────────────────────────────────────────
  1275.  
  1276.     42.
  1277.  
  1278.     PS: Could anyone tell me the Question?
  1279.  
  1280.     (With thanks to Douglas Adams :-)
  1281.  
  1282.  
  1283.     D. History
  1284.     ──────────
  1285.  
  1286.     20 feb 94: release of v1.0
  1287.     5  apr 94: changed info on rebooting in int 9
  1288.            added info about XT protocol, by Gertjan Klein
  1289.            added C program to interface with keyboard, by Gertjan Klein
  1290.            removed a bug in the copyright: Emil Gilliam was not to be
  1291.            held liable :-):-):-)
  1292.            removed some general typing errors
  1293.     9  apr 94: removed bug in keyboard buffer info: Head and Tail do not
  1294.            point to a location relative to Beginning, but instead
  1295.            directly to the keyboardbuffer
  1296.     23 may 94: v1.1
  1297.