i8042Kbd.c
上传用户:luoyougen
上传日期:2008-05-12
资源大小:23136k
文件大小:30k
源码类别:

VxWorks

开发平台:

C/C++

  1. /* i8042Kbd.c - Intel 8042 keyboard driver routines */
  2. /* Copyright 1993-2001 Wind River System, Inc. */
  3. #include "copyright_wrs.h"
  4. /*
  5. modification history
  6. --------------------
  7. 01f,06dec01,jlb  added option to send scan codes and set LEDs
  8. 01e,11jun96,wlf  doc: cleanup.
  9. 01d,14jun95,hdn  removed function declarations defined in sysLib.h.
  10. 01c,27oct94,hdn  rewritten the interface to the keyboard with WDOG.
  11. 01b,05may94,hdn  fixed a bug in kbdLedSet() by checking ACK in kbdIntr().
  12.  removed RESET command in kbdHrdInit() because ROMBIOS does it.
  13. 01a,20oct93,vin  created
  14. */
  15. /*
  16. DESCRIPTION
  17. This is the driver for the Intel 8042 Keyboard Controller Chip used on a 
  18. personal computer 386 / 486. This driver handles the standard 101 key board.
  19. This driver does not change the defaults set by the BIOS. The BIOS initializes
  20. the scan code set to 1 which make the PS/2 keyboard compatabile with the PC
  21. and PC XT keyboard. 
  22. USER CALLABLE ROUTINES
  23. The routines in this driver are accessed from external modules
  24. through the hook routine, the pointer to which is initialized
  25. in the KBD_CON_DEV structure at the time of initialization.
  26. This makes the access to these routines more generic without declaring
  27. these functions as external. 
  28. The routines in this driver which are accessed from an external module
  29. are kbdIntr() and kbdHrdInit(). kbdIntr() is installed as an interrupt
  30. service routine through the intConnect call in sysHwInit2(). 
  31. kbdHrdInit() is called to initialize the device descriptors and the 
  32. key board. 
  33. The kbdIntr() is the interrupt handler which handles the key board interrupt
  34. and is responsible for the handing the character received to whichever
  35. console the kbdDv.currCon is initialized to. By default this is initialized
  36. to PC_CONSOLE. If the user has to change the current console he will have
  37. to make an ioctl call with the option CONIOCURCONSOLE and the argument 
  38. as the console number which he wants to change to. To return to the console
  39. owned by the shell the user has to do an ioctl call back to the console number
  40. owned the shell from his application. 
  41.  
  42. Before using the driver, it must be initialized by calling kbdHrdInit(). 
  43. This routine should be called exactly once. Normally, it is called from 
  44. a generic driver for eg. from tyCoDrv() which is called before tyCoDevCreate.
  45. SEE ALSO
  46. conLib
  47. NOTES
  48. The following macros should be defined in <target>.h file
  49. COMMAND_8042, DATA_8042,STATUS_8042. These refer to the io base addresses
  50. of the various key board controller registers. The macros N_VIRTUAL_CONSOLES
  51. and PC_CONSOLE should be defined in config.h file.
  52. */
  53. /* includes */
  54. #include "vxWorks.h"
  55. #include "iv.h"
  56. #include "ioLib.h"
  57. #include "iosLib.h"
  58. #include "memLib.h"
  59. #include "tyLib.h"
  60. #include "errnoLib.h"
  61. #include "wdLib.h"
  62. #include "config.h"
  63. #include "drv/serial/pcConsole.h"
  64. /* externals */
  65. IMPORT PC_CON_DEV pcConDv [N_VIRTUAL_CONSOLES] ;
  66. /* globals */
  67. int kbdIntCnt = 0;
  68. int kbdTimeoutCnt = 0;
  69. BOOL kbdTimeout = FALSE;
  70. /* locals */
  71. LOCAL WDOG_ID kbdWdid;
  72. LOCAL int kbdWdsec = 2;
  73. LOCAL KBD_CON_DEV kbdConDv; /* key board device descriptor */
  74. LOCAL UCHAR oldLedStat = 0;
  75. LOCAL BOOL kbdAcknowledge = FALSE;
  76. LOCAL unsigned char enhancedKeys[] =  /* 16 extended keys */
  77.     {
  78.     0x1c,   /* keypad enter */
  79.     0x1d,   /* right control */
  80.     0x35,   /* keypad slash */
  81.     0x37,   /* print screen */
  82.     0x38,   /* right alt */
  83.     0x46,   /* break (control-pause) */
  84.     0x47,   /* editpad home */
  85.     0x48,   /* editpad up */
  86.     0x49,   /* editpad pgup */
  87.     0x4b,   /* editpad left */
  88.     0x4d,   /* editpad right */
  89.     0x4f,   /* editpad end */
  90.     0x50,   /* editpad dn */
  91.     0x51,   /* editpad pgdn */
  92.     0x52,   /* editpad ins */
  93.     0x53    /* editpad del */
  94.     };
  95. /* action table*/
  96. LOCAL UCHAR action [144] =
  97.     { /* Action table for scanCode */
  98.     0,   AS,   AS,   AS,   AS,   AS,   AS,   AS, /* scan  0- 7 */
  99.    AS,   AS,   AS,   AS,   AS,   AS,   AS,   AS, /* scan  8- F */
  100.    AS,   AS,   AS,   AS,   AS,   AS,   AS,   AS, /* scan 10-17 */
  101.    AS,   AS,   AS,   AS,   AS,   CN,   AS,   AS, /* scan 18-1F */
  102.    AS,   AS,   AS,   AS,   AS,   AS,   AS,   AS, /* scan 20-27 */
  103.    AS,   AS,   SH,   AS,   AS,   AS,   AS,   AS, /* scan 28-2F */
  104.    AS,   AS,   AS,   AS,   AS,   AS,   SH,   AS, /* scan 30-37 */
  105.    AS,   AS,   CP,   0,    0,    0,    0,     0, /* scan 38-3F */
  106.     0,   0,    0,    0,    0,    NM,   ST,   ES, /* scan 40-47 */
  107.    ES,   ES,   ES,   ES,   ES,   ES,   ES,   ES, /* scan 48-4F */
  108.    ES,   ES,   ES,   ES,   0,    0,    0,     0, /* scan 50-57 */
  109.     0,   0,    0,    0,    0,    0,    0,     0, /* scan 58-5F */
  110.     0,   0,    0,    0,    0,    0,    0,     0, /* scan 60-67 */
  111.     0,   0,    0,    0,    0,    0,    0,     0, /* scan 68-6F */
  112.    AS,   0,    0,    AS,   0,    0,    AS,    0, /* scan 70-77 */
  113.     0,   AS,   0,    0,    0,    AS,   0,     0, /* scan 78-7F */
  114.    AS,   CN,   AS,   AS,   AS,   ST,   EX,   EX, /* enhanced   */
  115.    AS,   EX,   EX,   AS,   EX,   AS,   EX,   EX  /* enhanced   */
  116.     };
  117. /*  key board Maps Japanese and english */
  118. LOCAL UCHAR keyMap [2][4][144] =
  119.     { 
  120.     { /* Japanese Enhanced keyboard */
  121.     { /* unshift code */
  122.     0,  0x1b,   '1',   '2',   '3',   '4',   '5',   '6', /* scan  0- 7 */
  123.   '7',   '8',   '9',   '0',   '-',   '^',  0x08,  't', /* scan  8- F */
  124.   'q',   'w',   'e',   'r',   't',   'y',   'u',   'i', /* scan 10-17 */
  125.   'o',   'p',   '@',   '[',  'r',   CN,    'a',   's', /* scan 18-1F */
  126.   'd',   'f',   'g',   'h',   'j',   'k',   'l',   ';', /* scan 20-27 */
  127.   ':',     0,   SH,    ']',   'z',   'x',   'c',   'v', /* scan 28-2F */
  128.   'b',   'n',   'm',   ',',   '.',   '/',   SH,    '*', /* scan 30-37 */
  129.   ' ',   ' ',   CP,     0,     0,     0,     0,     0, /* scan 38-3F */
  130.     0,     0,     0,     0,     0,   NM,    ST,    '7', /* scan 40-47 */
  131.   '8',   '9',   '-',   '4',   '5',   '6',   '+',   '1', /* scan 48-4F */
  132.   '2',   '3',   '0',   '.',     0,     0,     0,     0, /* scan 50-57 */
  133.     0,     0,     0,     0,     0,     0,     0,     0, /* scan 58-5F */
  134.     0,     0,     0,     0,     0,     0,     0,     0, /* scan 60-67 */
  135.     0,     0,     0,     0,     0,     0,     0,     0, /* scan 68-6F */
  136.   ' ',     0,     0,  '\',     0,     0,   ' ',     0, /* scan 70-77 */
  137.     0,   ' ',     0,     0,     0,  '\',     0,     0, /* scan 78-7F */
  138.   'r',   CN,   '/',   '*',   ' ',    ST,    'F',   'A', /* extended */
  139.     0,   'D',   'C',     0,   'B',     0,    '@',   'P'  /* extended */
  140.     },
  141.     { /* shift code */
  142.     0,  0x1b,   '!',   '"',   '#',   '$',   '%',   '&', /* scan  0- 7 */
  143.  ''',   '(',   ')',     0,   '=',   '~',  0x08,  't', /* scan  8- F */
  144.   'Q',   'W',   'E',   'R',   'T',   'Y',   'U',   'I', /* scan 10-17 */
  145.   'O',   'P',   '`',   '{',  'r',   CN,    'A',   'S', /* scan 18-1F */
  146.   'D',   'F',   'G',   'H',   'J',   'K',   'L',   '+', /* scan 20-27 */
  147.   '*',     0,   SH,    '}',   'Z',   'X',   'C',   'V', /* scan 28-2F */
  148.   'B',   'N',   'M',   '<',   '>',   '?',   SH,    '*', /* scan 30-37 */
  149.   ' ',   ' ',   CP,      0,     0,     0,     0,     0, /* scan 38-3F */
  150.     0,     0,     0,     0,     0,   NM,    ST,    '7', /* scan 40-47 */
  151.   '8',   '9',   '-',   '4',   '5',   '6',   '+',   '1', /* scan 48-4F */
  152.   '2',   '3',   '0',   '.',     0,     0,     0,     0, /* scan 50-57 */
  153.     0,     0,     0,     0,     0,     0,     0,     0, /* scan 58-5F */
  154.     0,     0,     0,     0,     0,     0,     0,     0, /* scan 60-67 */
  155.     0,     0,     0,     0,     0,     0,     0,     0, /* scan 68-6F */
  156.   ' ',     0,     0,   '_',     0,     0,   ' ',     0, /* scan 70-77 */
  157.     0,   ' ',     0,     0,     0,   '|',     0,     0, /* scan 78-7F */
  158.   'r',   CN,   '/',   '*',   ' ',    ST,    'F',   'A', /* extended */
  159.     0,   'D',   'C',     0,   'B',     0,    '@',   'P'  /* extended */
  160.     },
  161.     { /* Control code */
  162.  0xff,  0x1b,  0xff,  0xff,  0xff,  0xff,  0xff,  0xff, /* scan  0- 7 */
  163.  0xff,  0xff,  0xff,  0xff,  0xff,  0x1e,  0xff,  't', /* scan  8- F */
  164.  0x11,  0x17,  0x05,  0x12,  0x14,  0x19,  0x15,  0x09, /* scan 10-17 */
  165.  0x0f,  0x10,  0x00,  0x1b,  'r',   CN,  0x01,   0x13, /* scan 18-1F */
  166.  0x04,  0x06,  0x07,  0x08,  0x0a,  0x0b,  0x0c,  0xff, /* scan 20-27 */
  167.  0xff,  0xff,   SH,   0x1d,  0x1a,  0x18,  0x03,  0x16, /* scan 28-2F */
  168.  0x02,  0x0e,  0x0d,  0xff,  0xff,  0xff,  SH,    0xff, /* scan 30-37 */
  169.  0xff,  0xff,   CP,   0xff,  0xff,  0xff,  0xff,  0xff, /* scan 38-3F */
  170.  0xff,  0xff,  0xff,  0xff,  0xff,   NM,   ST,    0xff, /* scan 40-47 */
  171.  0xff,  0xff,  0xff,  0xff,  0xff,  0xff,  0xff,  0xff, /* scan 48-4F */
  172.  0xff,  0xff,  0xff,  0xff,  0xff,  0xff,  0xff,  0xff, /* scan 50-57 */
  173.  0xff,  0xff,  0xff,  0xff,  0xff,  0xff,  0xff,  0xff, /* scan 58-5F */
  174.  0xff,  0xff,  0xff,  0xff,  0xff,  0xff,  0xff,  0xff, /* scan 60-67 */
  175.  0xff,  0xff,  0xff,  0xff,  0xff,  0xff,  0xff,  0xff, /* scan 68-6F */
  176.  0xff,  0xff,  0xff,  0x1f,  0xff,  0xff,  0xff,  0xff, /* scan 70-77 */
  177.  0xff,  0xff,  0xff,  0xff,  0xff,  0x1c,  0xff,  0xff, /* scan 78-7F */
  178.   'r',   CN,   '/',   '*',   ' ',    ST,  0x0c,  0xff, /* extended */
  179.  0xff,  0xff,  0xff,  0xff,  0xff,  0xff,  0xff,  0xff  /* extended */
  180.     },
  181.     { /* non numeric code */
  182.     0,  0x1b,   '1',   '2',   '3',   '4',   '5',   '6', /* scan  0- 7 */
  183.   '7',   '8',   '9',   '0',   '-',   '^',  0x08,  't', /* scan  8- F */
  184.   'q',   'w',   'e',   'r',   't',   'y',   'u',   'i', /* scan 10-17 */
  185.   'o',   'p',   '@',   '[',  'r',   CN,    'a',   's', /* scan 18-1F */
  186.   'd',   'f',   'g',   'h',   'j',   'k',   'l',   ';', /* scan 20-27 */
  187.   ':',     0,   SH,    ']',   'z',   'x',   'c',   'v', /* scan 28-2F */
  188.   'b',   'n',   'm',   ',',   '.',   '/',   SH,    '*', /* scan 30-37 */
  189.   ' ',   ' ',   CP,     0,     0,     0,     0,     0, /* scan 38-3F */
  190.     0,     0,     0,     0,     0,   NM,    ST,    'w', /* scan 40-47 */
  191.   'x',   'y',   'l',   't',   'u',   'v',   'm',   'q', /* scan 48-4F */
  192.   'r',   's',   'p',   'n',     0,     0,     0,     0, /* scan 50-57 */
  193.     0,     0,     0,     0,     0,     0,     0,     0, /* scan 58-5F */
  194.     0,     0,     0,     0,     0,     0,     0,     0, /* scan 60-67 */
  195.     0,     0,     0,     0,     0,     0,     0,     0, /* scan 68-6F */
  196.   ' ',     0,     0,  '\',     0,     0,   ' ',     0, /* scan 70-77 */
  197.     0,   ' ',     0,     0,     0,  '\',     0,     0, /* scan 78-7F */
  198.   'r',   CN,   '/',   '*',   ' ',    ST,    'F',   'A', /* extended */
  199.     0,   'D',   'C',     0,   'B',     0,    '@',   'P'  /* extended */
  200.     }
  201.     },
  202.     { /* English Enhanced keyboard */
  203.     { /* unshift code */
  204.     0,  0x1b,   '1',   '2',   '3',   '4',   '5',   '6', /* scan  0- 7 */
  205.   '7',   '8',   '9',   '0',   '-',   '=',  0x08,  't', /* scan  8- F */
  206.   'q',   'w',   'e',   'r',   't',   'y',   'u',   'i', /* scan 10-17 */
  207.   'o',   'p',   '[',   ']',  'r',   CN,    'a',   's', /* scan 18-1F */
  208.   'd',   'f',   'g',   'h',   'j',   'k',   'l',   ';', /* scan 20-27 */
  209.  ''',   '`',   SH,   '\',   'z',   'x',   'c',   'v', /* scan 28-2F */
  210.   'b',   'n',   'm',   ',',   '.',   '/',   SH,    '*', /* scan 30-37 */
  211.   ' ',   ' ',   CP,      0,     0,     0,     0,     0, /* scan 38-3F */
  212.     0,     0,     0,     0,     0,   NM,    ST,    '7', /* scan 40-47 */
  213.   '8',   '9',   '-',   '4',   '5',   '6',   '+',   '1', /* scan 48-4F */
  214.   '2',   '3',   '0',   '.',     0,     0,     0,     0, /* scan 50-57 */
  215.     0,     0,     0,     0,     0,     0,     0,     0, /* scan 58-5F */
  216.     0,     0,     0,     0,     0,     0,     0,     0, /* scan 60-67 */
  217.     0,     0,     0,     0,     0,     0,     0,     0, /* scan 68-6F */
  218.     0,     0,     0,     0,     0,     0,     0,     0, /* scan 70-77 */
  219.     0,     0,     0,     0,     0,     0,     0,     0, /* scan 78-7F */
  220.   'r',   CN,   '/',   '*',   ' ',    ST,   'F',   'A', /* extended */
  221.     0,   'D',   'C',     0,   'B',     0,    '@',  'P'  /* extended */
  222.     },
  223.     { /* shift code */
  224.     0,  0x1b,   '!',   '@',   '#',   '$',   '%',   '^', /* scan  0- 7 */
  225.   '&',   '*',   '(',   ')',   '_',   '+',  0x08,  't', /* scan  8- F */
  226.   'Q',   'W',   'E',   'R',   'T',   'Y',   'U',   'I', /* scan 10-17 */
  227.   'O',   'P',   '{',   '}',  'r',   CN,    'A',   'S', /* scan 18-1F */
  228.   'D',   'F',   'G',   'H',   'J',   'K',   'L',   ':', /* scan 20-27 */
  229.   '"',   '~',   SH,    '|',   'Z',   'X',   'C',   'V', /* scan 28-2F */
  230.   'B',   'N',   'M',   '<',   '>',   '?',   SH,    '*', /* scan 30-37 */
  231.   ' ',   ' ',   CP,      0,     0,     0,     0,     0, /* scan 38-3F */
  232.     0,     0,     0,     0,     0,   NM,    ST,    '7', /* scan 40-47 */
  233.   '8',   '9',   '-',   '4',   '5',   '6',   '+',   '1', /* scan 48-4F */
  234.   '2',   '3',   '0',   '.',     0,     0,     0,     0, /* scan 50-57 */
  235.     0,     0,     0,     0,     0,     0,     0,     0, /* scan 58-5F */
  236.     0,     0,     0,     0,     0,     0,     0,     0, /* scan 60-67 */
  237.     0,     0,     0,     0,     0,     0,     0,     0, /* scan 68-6F */
  238.     0,     0,     0,     0,     0,     0,     0,     0, /* scan 70-77 */
  239.     0,     0,     0,     0,     0,     0,     0,     0, /* scan 78-7F */
  240.   'r',   CN,   '/',   '*',   ' ',    ST,   'F',   'A', /* extended */
  241.     0,   'D',   'C',     0,   'B',     0,   '@',   'P'  /* extended */
  242.     },
  243.     { /* Control code */
  244.  0xff,  0x1b,  0xff,  0x00,  0xff,  0xff,  0xff,  0xff, /* scan  0- 7 */
  245.  0x1e,  0xff,  0xff,  0xff,  0x1f,  0xff,  0xff,  't', /* scan  8- F */
  246.  0x11,  0x17,  0x05,  0x12,  0x14,  0x19,  0x15,  0x09, /* scan 10-17 */
  247.  0x0f,  0x10,  0x1b,  0x1d,  'r',   CN,   0x01,  0x13, /* scan 18-1F */
  248.  0x04,  0x06,  0x07,  0x08,  0x0a,  0x0b,  0x0c,  0xff, /* scan 20-27 */
  249.  0xff,  0x1c,   SH,   0xff,  0x1a,  0x18,  0x03,  0x16, /* scan 28-2F */
  250.  0x02,  0x0e,  0x0d,  0xff,  0xff,  0xff,   SH,   0xff, /* scan 30-37 */
  251.  0xff,  0xff,   CP,   0xff,  0xff,  0xff,  0xff,  0xff, /* scan 38-3F */
  252.  0xff,  0xff,  0xff,  0xff,  0xff,   NM,    ST,   0xff, /* scan 40-47 */
  253.  0xff,  0xff,  0xff,  0xff,  0xff,  0xff,  0xff,  0xff, /* scan 48-4F */
  254.  0xff,  0xff,  0xff,  0xff,  0xff,  0xff,  0xff,  0xff, /* scan 50-57 */
  255.  0xff,  0xff,  0xff,  0xff,  0xff,  0xff,  0xff,  0xff, /* scan 58-5F */
  256.  0xff,  0xff,  0xff,  0xff,  0xff,  0xff,  0xff,  0xff, /* scan 60-67 */
  257.  0xff,  0xff,  0xff,  0xff,  0xff,  0xff,  0xff,  0xff, /* scan 68-6F */
  258.  0xff,  0xff,  0xff,  0xff,  0xff,  0xff,  0xff,  0xff, /* scan 70-77 */
  259.  0xff,  0xff,  0xff,  0xff,  0xff,  0xff,  0xff,  0xff, /* scan 78-7F */
  260.   'r',   CN,   '/',   '*',   ' ',    ST,  0xff,  0xff, /* extended */
  261.  0xff,  0xff,  0xff,  0xff,  0xff,  0xff,  0xff,  0xff  /* extended */
  262.     },
  263.     { /* non numeric code */
  264.     0,  0x1b,   '1',   '2',   '3',   '4',   '5',   '6', /* scan  0- 7 */
  265.   '7',   '8',   '9',   '0',   '-',   '=',  0x08,  't', /* scan  8- F */
  266.   'q',   'w',   'e',   'r',   't',   'y',   'u',   'i', /* scan 10-17 */
  267.   'o',   'p',   '[',   ']',  'r',   CN,    'a',   's', /* scan 18-1F */
  268.   'd',   'f',   'g',   'h',   'j',   'k',   'l',   ';', /* scan 20-27 */
  269.  ''',   '`',   SH,   '\',   'z',   'x',   'c',   'v', /* scan 28-2F */
  270.   'b',   'n',   'm',   ',',   '.',   '/',   SH,    '*', /* scan 30-37 */
  271.   ' ',   ' ',   CP,      0,     0,     0,     0,     0, /* scan 38-3F */
  272.     0,     0,     0,     0,     0,   NM,    ST,    'w', /* scan 40-47 */
  273.   'x',   'y',   'l',   't',   'u',   'v',   'm',   'q', /* scan 48-4F */
  274.   'r',   's',   'p',   'n',     0,     0,     0,     0, /* scan 50-57 */
  275.     0,     0,     0,     0,     0,     0,     0,     0, /* scan 58-5F */
  276.     0,     0,     0,     0,     0,     0,     0,     0, /* scan 60-67 */
  277.     0,     0,     0,     0,     0,     0,     0,     0, /* scan 68-6F */
  278.     0,     0,     0,     0,     0,     0,     0,     0, /* scan 70-77 */
  279.     0,     0,     0,     0,     0,     0,     0,     0, /* scan 78-7F */
  280.   'r',   CN,   '/',   '*',   ' ',    ST,   'F',   'A', /* extended */
  281.     0,   'D',   'C',     0,   'B',     0,    '@',  'P'  /* extended */
  282.     }
  283.     }
  284.     };
  285. /* forward declarations */
  286. LOCAL void kbdStatInit (void);
  287. LOCAL void kbdConvChar(unsigned char scanCode);
  288. LOCAL void kbdLedSet (void);
  289. LOCAL void kbdNormal (unsigned char scanCode);
  290. LOCAL void kbdShift (unsigned char scanCode);
  291. LOCAL void kbdCtrl (unsigned char scanCode);
  292. LOCAL void kbdNum (unsigned char scanCode);
  293. LOCAL void kbdCaps (unsigned char scanCode);
  294. LOCAL void kbdStp (unsigned char scanCode);
  295. LOCAL void kbdExt (unsigned char scanCode);
  296. LOCAL void kbdEs (unsigned char scanCode);
  297. LOCAL void  (*keyHandler[]) (unsigned char scanCode)  =
  298.     {
  299.     kbdNormal,   kbdShift,   kbdCtrl,   kbdNum,   kbdCaps,
  300.     kbdStp,      kbdExt,     kbdEs
  301.     };
  302. LOCAL void kbdHook (int opCode);
  303. LOCAL void kbdWdog (void);
  304. LOCAL STATUS kbdWrite (char data);
  305. LOCAL STATUS kbdRead (char *data);
  306. LOCAL STATUS kbdCommand (char data);
  307.       void kbdReset (void); /* for debugging */
  308. /*******************************************************************************
  309. *
  310. * kbdHrdInit - initialize the Keyboard
  311. * This routine is called to do the key board initialization from an external
  312. * routine
  313. *
  314. * RETURNS: N/A
  315. *
  316. * NOMANUAL
  317. */
  318. void kbdHrdInit (void)
  319.     {
  320.     char temp;
  321.     kbdWdid = wdCreate ();
  322.     do {
  323. if (kbdTimeoutCnt > 3) /* try 3 times then give up */
  324.     break;
  325. if (kbdTimeout) /* reset if we got timeout */
  326.     kbdReset ();
  327.         if (kbdCommand (0x60) == ERROR)
  328.     continue;
  329.         if (kbdWrite (0x44) == ERROR)
  330.     continue;
  331.         while (sysInByte (STATUS_8042) & 0x01)
  332.     if (kbdRead (&temp) == ERROR)
  333. break;
  334.     
  335.         if (kbdCommand (0x60) == ERROR)
  336.     continue;
  337.         if (kbdWrite (0x45) == ERROR)
  338.     continue;
  339.         if (kbdCommand (0xae) == ERROR)
  340.     continue;
  341. } while (kbdTimeout);
  342.     kbdStatInit ();
  343.     } 
  344. /*******************************************************************************
  345. *
  346. * kbdStatInit - initialize the Keyboard state
  347. *
  348. * This routine initializes the keyboard descriptor in the virtual consoles.
  349. * The same keybaord descriptor is used for all the virtual consoles.
  350. *
  351. * RETURNS: N/A
  352. */
  353. LOCAL void kbdStatInit (void)
  354.     {
  355.     int ix; /* to hold temp variable */
  356.     UCHAR stat;
  357.     /* initialize all the key board descriptors in the virtual consoles */
  358.     for ( ix = 0; ix < N_VIRTUAL_CONSOLES; ix++)
  359. {
  360. pcConDv [ix].ks = &kbdConDv; /* kbd device descriptor */
  361. }
  362.     kbdConDv.curMode = TRUE; /* default mode is normal */
  363.     kbdConDv.convertChar = TRUE; /* default to convert to ASCII */
  364.     
  365.     /* default keyboard is English Enhanced key */
  366.     
  367.     kbdConDv.kbdMode  = ENGLISH_KBD; 
  368.     kbdConDv.kbdFlags = NORMAL|NUM; /* Numeric mode on */
  369.     kbdConDv.kbdState = 0;  /* unshift state */
  370.     kbdConDv.kbdHook  = (FUNCPTR) kbdHook; /* hook routine */
  371.     kbdConDv.currCon  = PC_CONSOLE;      /* console tty */
  372.     
  373.     stat = (UCHAR) (kbdConDv.kbdFlags & 0x07);
  374.     if (oldLedStat == stat)
  375. return;
  376.     oldLedStat = stat;
  377.     do {
  378. if (kbdTimeoutCnt > 3) /* try 3 times then give up */
  379.     break;
  380. if (kbdTimeout) /* reset if we got timeout */
  381.     kbdReset ();
  382.         if (kbdWrite (0xed) == ERROR)
  383.     continue;
  384.         if (kbdWrite (stat) == ERROR)
  385.     continue;
  386. } while (kbdTimeout);
  387.     }
  388. /*******************************************************************************
  389. *
  390. * kbdIntr - interrupt level processing
  391. *
  392. * This routine handles the keyboard interrupts
  393. *
  394. * RETURNS: N/A
  395. *
  396. * NOMANUAL
  397. */
  398. void kbdIntr (void)
  399.     {
  400.     FAST UCHAR scanCode; /* to hold the scanCode */
  401.     kbdIntCnt++;
  402.     if (sysInByte (STATUS_8042) & 0x01)
  403.         {
  404. scanCode = sysInByte (DATA_8042);
  405. /* keyboard acknowledge to any valid input, so just return */
  406. if (scanCode == 0xfa) 
  407.     {
  408.     kbdAcknowledge = TRUE;
  409.     return;
  410.     }
  411. if (kbdConDv.convertChar) 
  412.     kbdConvChar (scanCode);
  413. else
  414.     tyIRd (&(pcConDv[kbdConDv.currCon].tyDev), scanCode);
  415.         }
  416.     }
  417. /*******************************************************************************
  418. *
  419. * kbdConvChar - Convert scan code to character
  420. *
  421. * This routine convert scanCode to ASCII character
  422. *
  423. * RETURNS: N/A
  424. */
  425. LOCAL void kbdConvChar 
  426.     (
  427.     UCHAR scanCode /* scan Code from the keyboard */
  428.     )
  429.     {
  430.     if (scanCode == 0xe0)
  431. {
  432. kbdConDv.kbdFlags |= EXT;
  433. return;
  434. }
  435.     /* if high bit of scanCode,set break flag */
  436.     if (((scanCode & 0x80) << 2) == BRK)  
  437.        kbdConDv.kbdFlags |=  BRK;
  438.     else
  439.        kbdConDv.kbdFlags &= ~BRK;
  440.     if ((scanCode == 0xe1) || (kbdConDv.kbdFlags & E1))
  441. {
  442. if (scanCode == 0xe1)
  443.     {
  444.     kbdConDv.kbdFlags ^= BRK;  /* reset the break flag */
  445.     kbdConDv.kbdFlags ^= E1;   /* bitwise EXOR with E1 flag */
  446.     }
  447. return;
  448. }
  449.     scanCode &= 0x7f;
  450.     if ((kbdConDv.kbdFlags & EXT) == EXT)
  451. {
  452. int  ix;
  453. for (ix = 0; ix < EXTND_SIZE; ix++)
  454.     {
  455.     if (scanCode == enhancedKeys [ix])
  456. {
  457. scanCode = E0_BASE + ix;
  458. ix = -1;
  459. break;
  460. }
  461.     }
  462. kbdConDv.kbdFlags ^= EXT;  /* reset the extended flag */
  463. if (ix != -1)
  464.     {
  465.     return ;  /* unknown scancode */
  466.     }
  467. }
  468.     /* invoke the respective handler */
  469.     (*keyHandler [action [scanCode]]) (scanCode);
  470.     }
  471. /******************************************************************************
  472. *
  473. * kbdNormal - Normal key
  474. *
  475. * This routine does the normal key processing
  476. *
  477. * RETURNS: N/A
  478. */
  479. LOCAL void kbdNormal
  480.     (
  481.     UCHAR scanCode /* scan code recieved */
  482.     )
  483.     {
  484.     FAST UCHAR chr;
  485.     FAST int ix = kbdConDv.currCon; /* to hold the console no. */
  486.     if ((kbdConDv.kbdFlags & BRK) == NORMAL) 
  487. {
  488. chr = keyMap [kbdConDv.kbdMode][kbdConDv.kbdState][scanCode];
  489. if ((chr == 0xff) || (chr == 0x00))
  490.     {
  491.     return;
  492.     }
  493. /* if caps lock convert upper to lower */
  494. if (((kbdConDv.kbdFlags & CAPS) == CAPS) && 
  495.     (chr >= 'a' && chr <= 'z'))
  496.     { 
  497.     chr -= 'a' - 'A';
  498.     } 
  499. tyIRd (&(pcConDv [ix].tyDev), chr); /* give input to buffer */
  500. }
  501.     }
  502. /******************************************************************************
  503. *
  504. * kbdShift - Shift key operation
  505. *
  506. * This routine sets the shift state of the key board
  507. *
  508. * RETURNS: N/A
  509. */
  510. LOCAL void kbdShift
  511.     (
  512.     UCHAR scanCode /* scan code recieved */
  513.     )
  514.     {
  515.     if ((kbdConDv.kbdFlags & BRK) == BRK) 
  516. {
  517. kbdConDv.kbdState = AS;
  518. kbdConDv.kbdFlags &= (~SHIFT);
  519. }
  520.     else
  521. {
  522. kbdConDv.kbdState = SH;
  523. kbdConDv.kbdFlags |= SHIFT;
  524. }
  525.     }
  526. /******************************************************************************
  527. *
  528. * kbdCtrl - Control key operation
  529. *
  530. * This routine sets the shift state of key board to control state
  531. *
  532. * RETURNS: N/A
  533. */
  534. LOCAL void kbdCtrl
  535.     (
  536.     UCHAR scanCode /* scan code recieved */
  537.     )
  538.     {
  539.     if ((kbdConDv.kbdFlags & BRK) == BRK) 
  540. {
  541. kbdConDv.kbdState = AS;
  542. kbdConDv.kbdFlags &= (~CTRL);
  543. }
  544.     else
  545. {
  546. kbdConDv.kbdState = CN;
  547. kbdConDv.kbdFlags |= CTRL;
  548. }
  549.     }
  550. /******************************************************************************
  551. *
  552. * kbdCaps - Capslock key operation
  553. *
  554. * This routine sets the capslock state and the key board flags. 
  555. *
  556. * RETURNS: N/A
  557. */
  558. LOCAL void kbdCaps
  559.     (
  560.     UCHAR scanCode /* scan code recieved */
  561.     )
  562.     {
  563.     if ((kbdConDv.kbdFlags & BRK) == NORMAL) 
  564. {
  565. kbdConDv.kbdFlags ^= CAPS;
  566. kbdLedSet ();  /* Set the relevant LED on the Key board */
  567. }
  568.     }
  569. /******************************************************************************
  570. *
  571. * kbdNum - Numerlock set key operation
  572. *
  573. * This routine sets the numeric lock state of the key board.
  574. * The keyboard state is numeric by default. If the numeric lock is off
  575. * then this routine initializes the keyboard state to non numeric state.
  576. *
  577. * RETURNS: N/A
  578. */
  579. LOCAL void kbdNum
  580.     (
  581.     UCHAR scanCode /* scan code recieved */
  582.     )
  583.     {
  584.     if ((kbdConDv.kbdFlags & BRK) == NORMAL) 
  585. {
  586. kbdConDv.kbdFlags ^= NUM;
  587. kbdConDv.kbdState = (kbdConDv.kbdFlags & NUM) ? AS : NM;
  588. kbdLedSet ();  /* set the relevant key board led */
  589. }
  590.     }
  591. /******************************************************************************
  592. *
  593. * kbdStp - Scroll lock set key operation
  594. * This routine sets the scroll lock state of the key board. 
  595. * This routine outputs 0x13 if ^S is pressed or 0x11 if ^Q is pressed.
  596. *
  597. * RETURNS: N/A
  598. */
  599. LOCAL void kbdStp
  600.     (
  601.     UCHAR scanCode /* scan code recieved */
  602.     )
  603.     {
  604.     FAST int ix = kbdConDv.currCon; /* to hold the console no. */
  605.     if ((kbdConDv.kbdFlags & BRK) == NORMAL) 
  606. {
  607. kbdConDv.kbdFlags ^= STP;
  608. (kbdConDv.kbdFlags & STP) ? tyIRd (&(pcConDv [ix].tyDev),0x13) : 
  609.                               tyIRd (&(pcConDv [ix].tyDev),0x11);
  610. kbdLedSet ();  /* set the relevant key board led */
  611. }
  612.     }
  613. /******************************************************************************
  614. *
  615. * kbdExt - Extended key board operation
  616. *
  617. * This routine processes the extended scan code operations
  618. * and ouputs an escape sequence. ESC [ <chr> . The character is for example
  619. * one of the following. (A, B, C, D, F, L, P)
  620. *
  621. * RETURNS: N/A
  622. */
  623. LOCAL void kbdExt
  624.     (
  625.     UCHAR  scanCode /* scan code recieved */
  626.     )
  627.     {
  628.     FAST UCHAR chr;
  629.     FAST int ix = kbdConDv.currCon; /* to hold the console no. */
  630.     if ((kbdConDv.kbdFlags & BRK) == NORMAL) 
  631. {
  632. chr = keyMap [kbdConDv.kbdMode][kbdConDv.kbdState][scanCode];
  633. tyIRd (&pcConDv [ix].tyDev, 0x1b);  /* escape character */
  634. kbdConDv.curMode ? tyIRd (&pcConDv [ix].tyDev, '[') : 
  635.                      tyIRd (&pcConDv [ix].tyDev, 'O');
  636. tyIRd (&pcConDv [ix].tyDev, chr);
  637. }
  638.     }
  639. /******************************************************************************
  640. *
  641. * kbdEs - Non Numeric key board operation
  642. *
  643. * This routine processes the non numeric scan code operations
  644. *
  645. * RETURNS: N/A
  646. */
  647. LOCAL void kbdEs
  648.     (
  649.     UCHAR scanCode /* scan code recieved */
  650.     )
  651.     {
  652.     FAST UCHAR chr;
  653.     FAST int ix = kbdConDv.currCon; /* to hold the console no. */
  654.     if ((kbdConDv.kbdFlags & BRK) == NORMAL) 
  655. {
  656. chr = keyMap [kbdConDv.kbdMode][kbdConDv.kbdState][scanCode];
  657. if ((kbdConDv.kbdFlags & NUM) == NORMAL)
  658.     {
  659.     tyIRd (&pcConDv [ix].tyDev, 0x1b);  /* escape character */
  660.     tyIRd (&pcConDv [ix].tyDev, 'O');
  661.     }
  662. tyIRd (&pcConDv [ix].tyDev, chr);
  663. }
  664.     }
  665. /******************************************************************************
  666. *
  667. * kbdLedSet - Keybord LED Set
  668. *
  669. * This routine Keyboad LED control on kbdConDv.kbdFlags numeric, caps and
  670. * stps
  671. *
  672. * RETURNS: N/A
  673. */
  674. LOCAL void kbdLedSet (void)
  675.     {
  676.     int ix;
  677.     UCHAR  stat = 0;
  678.     /* bits 0 1 2 for scroll numlock & capslock */
  679.     stat = (UCHAR) (kbdConDv.kbdFlags & 0x07);
  680.     if (oldLedStat == stat)
  681. return;
  682.     oldLedStat = stat;
  683.     for (ix=0; ix<WAIT_MAX; ix++) /* wait for input buf empty */
  684. if ((sysInByte (STATUS_8042) & 0x02) == 0)
  685.     break;
  686.     sysOutByte (DATA_8042, 0xed); /* SET LEDS command */
  687.     for (ix=0; ix<WAIT_MAX; ix++) /* wait for input buf empty */
  688. if ((sysInByte (STATUS_8042) & 0x02) == 0)
  689.     break;
  690.     sysOutByte (DATA_8042, stat); /* set LEDs */
  691.     }
  692. /******************************************************************************
  693. *
  694. * kbdHook - key board function called from an external routine
  695. *
  696. * This function does the respective key board operation according to the
  697. * opCode. The user can extend this function to perform any key board 
  698. * operation called as a hook from any external function for eg
  699. * from the vga driver. 
  700. *
  701. * RETURNS: N/A
  702. */
  703. LOCAL void kbdHook
  704.     (
  705.     int opCode /* operation to perform */
  706.     )
  707.     {
  708.     switch (opCode)
  709. {
  710. case 0:
  711.       kbdStatInit ();
  712.       break;
  713.         case 1:
  714.       kbdLedSet ();
  715.       break;
  716. default:
  717.       break;
  718. }
  719.     }
  720. /******************************************************************************
  721. *
  722. * kbdRead - read data from the key board.
  723. *
  724. * Read data from the key board.
  725. *
  726. * RETURNS: OK or ERROR if timed out
  727. */
  728. LOCAL STATUS kbdRead
  729.     (
  730.     char *pData
  731.     )
  732.     {
  733.     kbdTimeout = FALSE;
  734.     wdStart (kbdWdid, (sysClkRateGet() * kbdWdsec), (FUNCPTR)kbdWdog, 0);
  735.     while (((sysInByte (STATUS_8042) & 0x01) == 0) && !kbdTimeout)
  736. ;
  737.     wdCancel (kbdWdid);
  738.     taskDelay (sysClkRateGet () >> 4);
  739.     *pData = sysInByte (DATA_8042);
  740.     return (kbdTimeout ? ERROR : OK);
  741.     }
  742. /******************************************************************************
  743. *
  744. * kbdWrite - write data to the key board.
  745. *
  746. * Write data to the key board.
  747. *
  748. * RETURNS: OK or ERROR if timed out
  749. */
  750. LOCAL STATUS kbdWrite
  751.     (
  752.     char data
  753.     )
  754.     {
  755.     kbdTimeout = FALSE;
  756.     wdStart (kbdWdid, (sysClkRateGet() * kbdWdsec), (FUNCPTR)kbdWdog, 0);
  757.     while ((sysInByte (STATUS_8042) & 0x02) && !kbdTimeout)
  758. ;
  759.     wdCancel (kbdWdid);
  760.     sysOutByte (DATA_8042, data);
  761.     return (kbdTimeout ? ERROR : OK);
  762.     }
  763. /******************************************************************************
  764. *
  765. * kbdCommand - write command to the key board.
  766. *
  767. * Write command to the key board.
  768. *
  769. * RETURNS: OK or ERROR if timed out
  770. */
  771. LOCAL STATUS kbdCommand
  772.     (
  773.     char command
  774.     )
  775.     {
  776.     kbdTimeout = FALSE;
  777.     wdStart (kbdWdid, (sysClkRateGet() * kbdWdsec), (FUNCPTR)kbdWdog, 0);
  778.     while ((sysInByte (STATUS_8042) & 0x02) && !kbdTimeout)
  779. ;
  780.     sysOutByte (COMMAND_8042, command);
  781.     while ((sysInByte (STATUS_8042) & 0x02) && !kbdTimeout)
  782. ;
  783.     wdCancel (kbdWdid);
  784.     return (kbdTimeout ? ERROR : OK);
  785.     }
  786. /******************************************************************************
  787. *
  788. * kbdReset - reset a keyboard
  789. *
  790. * This routine resets the keyboard.
  791. *
  792. * RETURNS: N/A
  793. */
  794. void kbdReset (void)
  795.     {
  796.     int ix;
  797.     for (ix=0; ix<WAIT_MAX; ix++) /* wait for input buf empty */
  798. if ((sysInByte (STATUS_8042) & 0x02) == 0)
  799.     break;
  800.     sysOutByte (DATA_8042, 0xff);
  801.     taskDelay (sysClkRateGet () >> 4);
  802.     for (ix=0; ix<WAIT_MAX; ix++) /* wait for input buf empty */
  803. if ((sysInByte (STATUS_8042) & 0x02) == 0)
  804.     break;
  805.     sysOutByte (DATA_8042, 0x60);
  806.     for (ix=0; ix<WAIT_MAX; ix++) /* wait for input buf empty */
  807. if ((sysInByte (STATUS_8042) & 0x02) == 0)
  808.     break;
  809.     sysOutByte (DATA_8042, 0x45);
  810.     for (ix=0; ix<WAIT_MAX; ix++) /* wait for input buf empty */
  811. if ((sysInByte (STATUS_8042) & 0x02) == 0)
  812.     break;
  813.     sysOutByte (COMMAND_8042, 0xae);
  814.     for (ix=0; ix<WAIT_MAX; ix++) /* wait for input buf empty */
  815. if ((sysInByte (STATUS_8042) & 0x02) == 0)
  816.     break;
  817.     }
  818. /******************************************************************************
  819. *
  820. * kbdWdog - KBD driver watchdog handler.
  821. *
  822. * KBD driver watchdog handler.
  823. *
  824. * RETURNS: N/A
  825. */
  826. LOCAL void kbdWdog
  827.     (
  828.     void
  829.     )
  830.     {
  831.     kbdTimeout = TRUE;
  832.     kbdTimeoutCnt++;
  833.     }