home *** CD-ROM | disk | FTP | other *** search
/ InfoMagic Source Code 1993 July / THE_SOURCE_CODE_CD_ROM.iso / bsd_srcs / sys / i386 / stand / kbd.c < prev    next >
Encoding:
C/C++ Source or Header  |  1991-05-04  |  8.5 KB  |  248 lines

  1. /*-
  2.  * Copyright (c) 1990 The Regents of the University of California.
  3.  * All rights reserved.
  4.  *
  5.  * This code is derived from software contributed to Berkeley by
  6.  * William Jolitz.
  7.  *
  8.  * Redistribution and use in source and binary forms, with or without
  9.  * modification, are permitted provided that the following conditions
  10.  * are met:
  11.  * 1. Redistributions of source code must retain the above copyright
  12.  *    notice, this list of conditions and the following disclaimer.
  13.  * 2. Redistributions in binary form must reproduce the above copyright
  14.  *    notice, this list of conditions and the following disclaimer in the
  15.  *    documentation and/or other materials provided with the distribution.
  16.  * 3. All advertising materials mentioning features or use of this software
  17.  *    must display the following acknowledgement:
  18.  *    This product includes software developed by the University of
  19.  *    California, Berkeley and its contributors.
  20.  * 4. Neither the name of the University nor the names of its contributors
  21.  *    may be used to endorse or promote products derived from this software
  22.  *    without specific prior written permission.
  23.  *
  24.  * THIS SOFTWARE IS PROVIDED BY THE REGENTS AND CONTRIBUTORS ``AS IS'' AND
  25.  * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
  26.  * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
  27.  * ARE DISCLAIMED.  IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE
  28.  * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
  29.  * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
  30.  * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
  31.  * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
  32.  * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
  33.  * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
  34.  * SUCH DAMAGE.
  35.  *
  36.  *    @(#)kbd.c    7.4 (Berkeley) 5/4/91
  37.  */
  38.  
  39. #define    L        0x01    /* locking function */
  40. #define    SHF        0x02    /* keyboard shift */
  41. #define    ALT        0x04    /* alternate shift -- alternate chars */
  42. #define    NUM        0x08    /* numeric shift  cursors vs. numeric */
  43. #define    CTL        0x10    /* control shift  -- allows ctl function */
  44. #define    CPS        0x20    /* caps shift -- swaps case of letter */
  45. #define    ASCII        0x40    /* ascii code for this key */
  46. #define    STP        0x80    /* stop output */
  47.  
  48. typedef unsigned char u_char;
  49.  
  50. u_char inb();
  51.  
  52. u_char action[] = {
  53. 0,     ASCII, ASCII, ASCII, ASCII, ASCII, ASCII, ASCII,        /* scan  0- 7 */
  54. ASCII, ASCII, ASCII, ASCII, ASCII, ASCII, ASCII, ASCII,        /* scan  8-15 */
  55. ASCII, ASCII, ASCII, ASCII, ASCII, ASCII, ASCII, ASCII,        /* scan 16-23 */
  56. ASCII, ASCII, ASCII, ASCII, ASCII,   CTL, ASCII, ASCII,        /* scan 24-31 */
  57. ASCII, ASCII, ASCII, ASCII, ASCII, ASCII, ASCII, ASCII,        /* scan 32-39 */
  58. ASCII, ASCII, SHF  , ASCII, ASCII, ASCII, ASCII, ASCII,        /* scan 40-47 */
  59. ASCII, ASCII, ASCII, ASCII, ASCII, ASCII,  SHF,  ASCII,        /* scan 48-55 */
  60.   ALT, ASCII, CPS|L,     0,     0, ASCII,     0,     0,        /* scan 56-63 */
  61.     0,     0,     0,     0,     0, NUM|L, STP|L, ASCII,        /* scan 64-71 */
  62. ASCII, ASCII, ASCII, ASCII, ASCII, ASCII, ASCII, ASCII,        /* scan 72-79 */
  63. ASCII, ASCII, ASCII, ASCII,     0,     0,     0,     0,        /* scan 80-87 */
  64. 0,0,0,0,0,0,0,0,
  65. 0,0,0,0,0,0,0,0, 0,0,0,0,0,0,0,0,
  66. 0,0,0,0,0,0,0,0, 0,0,0,0,0,0,0,0,    } ;
  67.  
  68. u_char unshift[] = {    /* no shift */
  69. 0,     033  , '1'  , '2'  , '3'  , '4'  , '5'  , '6'  ,        /* scan  0- 7 */
  70. '7'  , '8'  , '9'  , '0'  , '-'  , '='  , 0177 ,'\t'  ,        /* scan  8-15 */
  71.  
  72. 'q'  , 'w'  , 'e'  , 'r'  , 't'  , 'y'  , 'u'  , 'i'  ,        /* scan 16-23 */
  73. 'o'  , 'p'  , '['  , ']'  , '\r' , CTL  , 'a'  , 's'  ,        /* scan 24-31 */
  74.  
  75. 'd'  , 'f'  , 'g'  , 'h'  , 'j'  , 'k'  , 'l'  , ';'  ,        /* scan 32-39 */
  76. '\'' , '`'  , SHF  , '\\' , 'z'  , 'x'  , 'c'  , 'v'  ,        /* scan 40-47 */
  77.  
  78. 'b'  , 'n'  , 'm'  , ','  , '.'  , '/'  , SHF  ,   '*',        /* scan 48-55 */
  79. ALT  , ' '  , CPS|L,     0,     0, ' '  ,     0,     0,        /* scan 56-63 */
  80.  
  81.     0,     0,     0,     0,     0, NUM|L, STP|L,   '7',        /* scan 64-71 */
  82.   '8',   '9',   '-',   '4',   '5',   '6',   '+',   '1',        /* scan 72-79 */
  83.  
  84.   '2',   '3',   '0',   '.',     0,     0,     0,     0,        /* scan 80-87 */
  85. 0,0,0,0,0,0,0,0,
  86. 0,0,0,0,0,0,0,0, 0,0,0,0,0,0,0,0,
  87. 0,0,0,0,0,0,0,0, 0,0,0,0,0,0,0,0,    } ;
  88.  
  89. u_char shift[] = {    /* shift shift */
  90. 0,     033  , '!'  , '@'  , '#'  , '$'  , '%'  , '^'  ,        /* scan  0- 7 */
  91. '&'  , '*'  , '('  , ')'  , '_'  , '+'  , 0177 ,'\t'  ,        /* scan  8-15 */
  92. 'Q'  , 'W'  , 'E'  , 'R'  , 'T'  , 'Y'  , 'U'  , 'I'  ,        /* scan 16-23 */
  93. 'O'  , 'P'  , '['  , ']'  , '\r' , CTL  , 'A'  , 'S'  ,        /* scan 24-31 */
  94. 'D'  , 'F'  , 'G'  , 'H'  , 'J'  , 'K'  , 'L'  , ':'  ,        /* scan 32-39 */
  95. '"'  , '~'  , SHF  , '|'  , 'Z'  , 'X'  , 'C'  , 'V'  ,        /* scan 40-47 */
  96. 'B'  , 'N'  , 'M'  , '<'  , '>'  , '?'  , SHF  ,   '*',        /* scan 48-55 */
  97. ALT  , ' '  , CPS|L,     0,     0, ' '  ,     0,     0,        /* scan 56-63 */
  98.     0,     0,     0,     0,     0, NUM|L, STP|L,   '7',        /* scan 64-71 */
  99.   '8',   '9',   '-',   '4',   '5',   '6',   '+',   '1',        /* scan 72-79 */
  100.   '2',   '3',   '0',   '.',     0,     0,     0,     0,        /* scan 80-87 */
  101. 0,0,0,0,0,0,0,0,
  102. 0,0,0,0,0,0,0,0, 0,0,0,0,0,0,0,0,
  103. 0,0,0,0,0,0,0,0, 0,0,0,0,0,0,0,0,    } ;
  104.  
  105. u_char ctl[] = {    /* CTL shift */
  106. 0,     033  , '!'  , 000  , '#'  , '$'  , '%'  , 036  ,        /* scan  0- 7 */
  107. '&'  , '*'  , '('  , ')'  , 037  , '+'  , 034  ,'\177',        /* scan  8-15 */
  108. 021  , 027  , 005  , 022  , 024  , 031  , 025  , 011  ,        /* scan 16-23 */
  109. 017  , 020  , 033  , 035  , '\r' , CTL  , 001  , 013  ,        /* scan 24-31 */
  110. 004  , 006  , 007  , 010  , 012  , 013  , 014  , ';'  ,        /* scan 32-39 */
  111. '\'' , '`'  , SHF  , 034  , 032  , 030  , 003  , 026  ,        /* scan 40-47 */
  112. 002  , 016  , 015  , '<'  , '>'  , '?'  , SHF  ,   '*',        /* scan 48-55 */
  113. ALT  , ' '  , CPS|L,     0,     0, ' '  ,     0,     0,        /* scan 56-63 */
  114. CPS|L,     0,     0,     0,     0,     0,     0,     0,        /* scan 64-71 */
  115.     0,     0,     0,     0,     0,     0,     0,     0,        /* scan 72-79 */
  116.     0,     0,     0,     0,     0,     0,     0,     0,        /* scan 80-87 */
  117.     0,     0,   033, '7'  , '4'  , '1'  ,     0, NUM|L,        /* scan 88-95 */
  118. '8'  , '5'  , '2'  ,     0, STP|L, '9'  , '6'  , '3'  ,        /*scan  96-103*/
  119. '.'  ,     0, '*'  , '-'  , '+'  ,     0,     0,     0,        /*scan 104-111*/
  120. 0,0,0,0,0,0,0,0, 0,0,0,0,0,0,0,0,    } ;
  121.  
  122. #ifdef notdef
  123. struct key {
  124.     u_short action;        /* how this key functions */
  125.     char    ascii[8];    /* ascii result character indexed by shifts */
  126. };
  127. #endif
  128.  
  129. u_char shfts, ctls, alts, caps, num, stp;
  130.  
  131. #define    KBSTATP    0x64    /* kbd status port */
  132. #define        KBS_INP_BUF_FUL    0x02    /* kbd char ready */
  133. #define    KBDATAP    0x60    /* kbd data port */
  134. #define    KBSTATUSPORT    0x61    /* kbd status */
  135.  
  136. u_char odt;
  137.  
  138. u_char kbd() {
  139.     u_char dt, brk, act;
  140.     
  141. loop:
  142.     while(inb(0x64)&1 == 0);
  143.     dt = inb(0x60);
  144.     do {
  145.         while(inb(0x64)&1 == 0);
  146.     } while(dt == inb(0x60));
  147.     odt = dt;
  148.  
  149.     brk = dt & 0x80 ; dt = dt & 0x7f ;
  150.  
  151.     act = action[dt];
  152.     if (act&SHF) {
  153.         if(brk)    shfts = 0; else shfts = 1;
  154.     }
  155.     if (act&ALT) {
  156.         if(brk)    alts = 0; else alts = 1;
  157.     }
  158.     if (act&NUM) {
  159.         if (act&L) {
  160.             if(!brk) num ^= 1;
  161.         } else if(brk)    num = 0; else num = 1;
  162.     }
  163.     if (act&CTL) {
  164.         if(brk)    ctls = 0; else ctls = 1;
  165.     }
  166.     if (act&CPS) {
  167.         if (act&L) {
  168.             if(!brk) caps ^= 1;
  169.         } else if(brk)    caps = 0; else caps = 1;
  170.     }
  171.     if (act&STP) {
  172.         if (act&L) {
  173.             if(!brk) stp ^= 1;
  174.         } else if(brk)    stp = 0; else stp = 1;
  175.     }
  176.     if(ctl && alts && dt == 83) exit();
  177.     if ((act&ASCII) && !brk) {
  178.         u_char chr;
  179.  
  180.         if (shfts){
  181.              chr = shift[dt] ; } else {
  182.         if (ctls) {
  183.             chr = ctl[dt] ; } else {
  184.         chr = unshift[dt] ; } }
  185.         if (caps && (chr >= 'a' && chr <= 'z')) {
  186.             chr -= 'a' - 'A' ;
  187.         }
  188.         /*do
  189.             while(inb(0x64)&1 == 0) ;
  190.         while (inb(0x60) == (chr | 0x80));
  191.         while(inb(0x64)&1 == 1) inb(0x60);A*/
  192.         return(chr);
  193.     }
  194.     goto loop;
  195. }
  196.  
  197. scankbd() {
  198. u_char c;
  199.     
  200.     c = inb(0x60);
  201.     if (c == 0xaa) { odt = 0x2a; return (0); }
  202.     if (c == 0xfa) { odt = 0x7a; return (0); }
  203.     c &= 0x7f;
  204.     
  205.     if ( (odt&0x7f) == c )return(0);
  206.     if(odt == 0) { odt = c;  return(0); }
  207.     return(kbd());
  208. }
  209.  
  210. kbdreset()
  211. {
  212.     u_char c;
  213.  
  214.     /* Enable interrupts and keyboard controller */
  215.     while (inb(0x64)&2); outb(0x64,0x60);
  216.     while (inb(0x64)&2); outb(0x60,0x4D);
  217.  
  218.     /* Start keyboard stuff RESET */
  219.     while (inb(0x64)&2);    /* wait input ready */
  220.     outb(0x60,0xFF);    /* RESET */
  221.  
  222.     while((c=inb(0x60))!=0xFA) ;
  223.  
  224.     /* While we are here, defeat gatea20 */
  225.     while (inb(0x64)&2);    /* wait input ready */
  226.     outb(0x64,0xd1);    
  227.     while (inb(0x64)&2);    /* wait input ready */
  228.     outb(0x60,0xdf);    
  229. }
  230.  
  231. u_char getchar() {
  232.     u_char c;
  233.  
  234.     c = kbd();
  235.     if (c == '\b' || c == '\177') return(c);
  236.     if (c == '\r') c = '\n';
  237.     putchar(c);
  238.     return(c);
  239. }
  240.  
  241. reset_cpu() {
  242.  
  243.     while (inb(0x64)&2);    /* wait input ready */
  244.     outb(0x64,0xFE);    /* Reset Command */
  245.     wait(4000000);
  246.     /* NOTREACHED */
  247. }
  248.