141078Swilliam /*- 241078Swilliam * Copyright (c) 1990 The Regents of the University of California. 341078Swilliam * All rights reserved. 441078Swilliam * 541078Swilliam * This code is derived from software contributed to Berkeley by 641078Swilliam * William Jolitz. 741078Swilliam * 8*48818Swilliam * %sccs.include.redist.c% 941078Swilliam * 10*48818Swilliam * @(#)kbd.c 7.2 (Berkeley) 04/28/91 1141078Swilliam */ 1241078Swilliam 1341078Swilliam #define L 0x01 /* locking function */ 1441078Swilliam #define SHF 0x02 /* keyboard shift */ 1541078Swilliam #define ALT 0x04 /* alternate shift -- alternate chars */ 1641078Swilliam #define NUM 0x08 /* numeric shift cursors vs. numeric */ 1741078Swilliam #define CTL 0x10 /* control shift -- allows ctl function */ 1841078Swilliam #define CPS 0x20 /* caps shift -- swaps case of letter */ 1941078Swilliam #define ASCII 0x40 /* ascii code for this key */ 2041078Swilliam #define STP 0x80 /* stop output */ 2141078Swilliam 2241078Swilliam typedef unsigned char u_char; 2341078Swilliam 2441078Swilliam u_char inb(); 2541078Swilliam 2641078Swilliam u_char action[] = { 2741078Swilliam 0, ASCII, ASCII, ASCII, ASCII, ASCII, ASCII, ASCII, /* scan 0- 7 */ 2841078Swilliam ASCII, ASCII, ASCII, ASCII, ASCII, ASCII, ASCII, ASCII, /* scan 8-15 */ 2941078Swilliam ASCII, ASCII, ASCII, ASCII, ASCII, ASCII, ASCII, ASCII, /* scan 16-23 */ 3041078Swilliam ASCII, ASCII, ASCII, ASCII, ASCII, CTL, ASCII, ASCII, /* scan 24-31 */ 3141078Swilliam ASCII, ASCII, ASCII, ASCII, ASCII, ASCII, ASCII, ASCII, /* scan 32-39 */ 3241078Swilliam ASCII, ASCII, SHF , ASCII, ASCII, ASCII, ASCII, ASCII, /* scan 40-47 */ 3341078Swilliam ASCII, ASCII, ASCII, ASCII, ASCII, ASCII, SHF, ASCII, /* scan 48-55 */ 3441078Swilliam ALT, ASCII, CPS|L, 0, 0, ASCII, 0, 0, /* scan 56-63 */ 3541078Swilliam 0, 0, 0, 0, 0, NUM|L, STP|L, ASCII, /* scan 64-71 */ 3641078Swilliam ASCII, ASCII, ASCII, ASCII, ASCII, ASCII, ASCII, ASCII, /* scan 72-79 */ 3741078Swilliam ASCII, ASCII, ASCII, ASCII, 0, 0, 0, 0, /* scan 80-87 */ 3841078Swilliam 0,0,0,0,0,0,0,0, 3941078Swilliam 0,0,0,0,0,0,0,0, 0,0,0,0,0,0,0,0, 4041078Swilliam 0,0,0,0,0,0,0,0, 0,0,0,0,0,0,0,0, } ; 4141078Swilliam 4241078Swilliam u_char unshift[] = { /* no shift */ 4341078Swilliam 0, 033 , '1' , '2' , '3' , '4' , '5' , '6' , /* scan 0- 7 */ 4441078Swilliam '7' , '8' , '9' , '0' , '-' , '=' , 0177 ,'\t' , /* scan 8-15 */ 4541078Swilliam 4641078Swilliam 'q' , 'w' , 'e' , 'r' , 't' , 'y' , 'u' , 'i' , /* scan 16-23 */ 4741078Swilliam 'o' , 'p' , '[' , ']' , '\r' , CTL , 'a' , 's' , /* scan 24-31 */ 4841078Swilliam 4941078Swilliam 'd' , 'f' , 'g' , 'h' , 'j' , 'k' , 'l' , ';' , /* scan 32-39 */ 5041078Swilliam '\'' , '`' , SHF , '\\' , 'z' , 'x' , 'c' , 'v' , /* scan 40-47 */ 5141078Swilliam 5241078Swilliam 'b' , 'n' , 'm' , ',' , '.' , '/' , SHF , '*', /* scan 48-55 */ 5341078Swilliam ALT , ' ' , CPS|L, 0, 0, ' ' , 0, 0, /* scan 56-63 */ 5441078Swilliam 5541078Swilliam 0, 0, 0, 0, 0, NUM|L, STP|L, '7', /* scan 64-71 */ 5641078Swilliam '8', '9', '-', '4', '5', '6', '+', '1', /* scan 72-79 */ 5741078Swilliam 5841078Swilliam '2', '3', '0', '.', 0, 0, 0, 0, /* scan 80-87 */ 5941078Swilliam 0,0,0,0,0,0,0,0, 6041078Swilliam 0,0,0,0,0,0,0,0, 0,0,0,0,0,0,0,0, 6141078Swilliam 0,0,0,0,0,0,0,0, 0,0,0,0,0,0,0,0, } ; 6241078Swilliam 6341078Swilliam u_char shift[] = { /* shift shift */ 6441078Swilliam 0, 033 , '!' , '@' , '#' , '$' , '%' , '^' , /* scan 0- 7 */ 6541078Swilliam '&' , '*' , '(' , ')' , '_' , '+' , 0177 ,'\t' , /* scan 8-15 */ 6641078Swilliam 'Q' , 'W' , 'E' , 'R' , 'T' , 'Y' , 'U' , 'I' , /* scan 16-23 */ 6741078Swilliam 'O' , 'P' , '[' , ']' , '\r' , CTL , 'A' , 'S' , /* scan 24-31 */ 6841078Swilliam 'D' , 'F' , 'G' , 'H' , 'J' , 'K' , 'L' , ':' , /* scan 32-39 */ 6941078Swilliam '"' , '~' , SHF , '|' , 'Z' , 'X' , 'C' , 'V' , /* scan 40-47 */ 7041078Swilliam 'B' , 'N' , 'M' , '<' , '>' , '?' , SHF , '*', /* scan 48-55 */ 7141078Swilliam ALT , ' ' , CPS|L, 0, 0, ' ' , 0, 0, /* scan 56-63 */ 7241078Swilliam 0, 0, 0, 0, 0, NUM|L, STP|L, '7', /* scan 64-71 */ 7341078Swilliam '8', '9', '-', '4', '5', '6', '+', '1', /* scan 72-79 */ 7441078Swilliam '2', '3', '0', '.', 0, 0, 0, 0, /* scan 80-87 */ 7541078Swilliam 0,0,0,0,0,0,0,0, 7641078Swilliam 0,0,0,0,0,0,0,0, 0,0,0,0,0,0,0,0, 7741078Swilliam 0,0,0,0,0,0,0,0, 0,0,0,0,0,0,0,0, } ; 7841078Swilliam 7941078Swilliam u_char ctl[] = { /* CTL shift */ 8041078Swilliam 0, 033 , '!' , 000 , '#' , '$' , '%' , 036 , /* scan 0- 7 */ 8141078Swilliam '&' , '*' , '(' , ')' , 037 , '+' , 034 ,'\177', /* scan 8-15 */ 8241078Swilliam 021 , 027 , 005 , 022 , 024 , 031 , 025 , 011 , /* scan 16-23 */ 8341078Swilliam 017 , 020 , 033 , 035 , '\r' , CTL , 001 , 013 , /* scan 24-31 */ 8441078Swilliam 004 , 006 , 007 , 010 , 012 , 013 , 014 , ';' , /* scan 32-39 */ 8541078Swilliam '\'' , '`' , SHF , 034 , 032 , 030 , 003 , 026 , /* scan 40-47 */ 8641078Swilliam 002 , 016 , 015 , '<' , '>' , '?' , SHF , '*', /* scan 48-55 */ 8741078Swilliam ALT , ' ' , CPS|L, 0, 0, ' ' , 0, 0, /* scan 56-63 */ 8841078Swilliam CPS|L, 0, 0, 0, 0, 0, 0, 0, /* scan 64-71 */ 8941078Swilliam 0, 0, 0, 0, 0, 0, 0, 0, /* scan 72-79 */ 9041078Swilliam 0, 0, 0, 0, 0, 0, 0, 0, /* scan 80-87 */ 9141078Swilliam 0, 0, 033, '7' , '4' , '1' , 0, NUM|L, /* scan 88-95 */ 9241078Swilliam '8' , '5' , '2' , 0, STP|L, '9' , '6' , '3' , /*scan 96-103*/ 9341078Swilliam '.' , 0, '*' , '-' , '+' , 0, 0, 0, /*scan 104-111*/ 9441078Swilliam 0,0,0,0,0,0,0,0, 0,0,0,0,0,0,0,0, } ; 9541078Swilliam 9641078Swilliam #ifdef notdef 9741078Swilliam struct key { 9841078Swilliam u_short action; /* how this key functions */ 9941078Swilliam char ascii[8]; /* ascii result character indexed by shifts */ 10041078Swilliam }; 10141078Swilliam #endif 10241078Swilliam 10341078Swilliam u_char shfts, ctls, alts, caps, num, stp; 10441078Swilliam 10541078Swilliam #define KBSTATP 0x64 /* kbd status port */ 10641078Swilliam #define KBS_INP_BUF_FUL 0x02 /* kbd char ready */ 10741078Swilliam #define KBDATAP 0x60 /* kbd data port */ 10841078Swilliam #define KBSTATUSPORT 0x61 /* kbd status */ 10941078Swilliam 11041078Swilliam u_char odt; 11141078Swilliam 11241078Swilliam u_char kbd() { 11341078Swilliam u_char dt, brk, act; 11441078Swilliam 11541078Swilliam loop: 116*48818Swilliam while(inb(0x64)&1 == 0); 117*48818Swilliam dt = inb(0x60); 11841078Swilliam do { 119*48818Swilliam while(inb(0x64)&1 == 0); 120*48818Swilliam } while(dt == inb(0x60)); 12141078Swilliam odt = dt; 12241078Swilliam 12341078Swilliam brk = dt & 0x80 ; dt = dt & 0x7f ; 12441078Swilliam 12541078Swilliam act = action[dt]; 12641078Swilliam if (act&SHF) { 12741078Swilliam if(brk) shfts = 0; else shfts = 1; 12841078Swilliam } 12941078Swilliam if (act&ALT) { 13041078Swilliam if(brk) alts = 0; else alts = 1; 13141078Swilliam } 13241078Swilliam if (act&NUM) { 13341078Swilliam if (act&L) { 13441078Swilliam if(!brk) num ^= 1; 13541078Swilliam } else if(brk) num = 0; else num = 1; 13641078Swilliam } 13741078Swilliam if (act&CTL) { 13841078Swilliam if(brk) ctls = 0; else ctls = 1; 13941078Swilliam } 14041078Swilliam if (act&CPS) { 14141078Swilliam if (act&L) { 14241078Swilliam if(!brk) caps ^= 1; 14341078Swilliam } else if(brk) caps = 0; else caps = 1; 14441078Swilliam } 14541078Swilliam if (act&STP) { 14641078Swilliam if (act&L) { 14741078Swilliam if(!brk) stp ^= 1; 14841078Swilliam } else if(brk) stp = 0; else stp = 1; 14941078Swilliam } 150*48818Swilliam if(ctl && alts && dt == 83) exit(); 15141078Swilliam if ((act&ASCII) && !brk) { 15241078Swilliam u_char chr; 15341078Swilliam 15441078Swilliam if (shfts){ 15541078Swilliam chr = shift[dt] ; } else { 15641078Swilliam if (ctls) { 15741078Swilliam chr = ctl[dt] ; } else { 15841078Swilliam chr = unshift[dt] ; } } 15941078Swilliam if (caps && (chr >= 'a' && chr <= 'z')) { 16041078Swilliam chr -= 'a' - 'A' ; 16141078Swilliam } 162*48818Swilliam /*do 163*48818Swilliam while(inb(0x64)&1 == 0) ; 164*48818Swilliam while (inb(0x60) == (chr | 0x80)); 165*48818Swilliam while(inb(0x64)&1 == 1) inb(0x60);A*/ 16641078Swilliam return(chr); 16741078Swilliam } 16841078Swilliam goto loop; 16941078Swilliam } 170*48818Swilliam 171*48818Swilliam scankbd() { 172*48818Swilliam u_char c; 173*48818Swilliam 174*48818Swilliam c = inb(0x60); 175*48818Swilliam if (c == 0xaa) { odt = 0x2a; return (0); } 176*48818Swilliam if (c == 0xfa) { odt = 0x7a; return (0); } 177*48818Swilliam c &= 0x7f; 178*48818Swilliam 179*48818Swilliam if ( (odt&0x7f) == c )return(0); 180*48818Swilliam if(odt == 0) { odt = c; return(0); } 181*48818Swilliam return(kbd()); 182*48818Swilliam } 183*48818Swilliam 184*48818Swilliam kbdreset() 185*48818Swilliam { 186*48818Swilliam u_char c; 187*48818Swilliam 188*48818Swilliam /* Enable interrupts and keyboard controller */ 189*48818Swilliam while (inb(0x64)&2); outb(0x64,0x60); 190*48818Swilliam while (inb(0x64)&2); outb(0x60,0x4D); 191*48818Swilliam 192*48818Swilliam /* Start keyboard stuff RESET */ 193*48818Swilliam while (inb(0x64)&2); /* wait input ready */ 194*48818Swilliam outb(0x60,0xFF); /* RESET */ 195*48818Swilliam 196*48818Swilliam while((c=inb(0x60))!=0xFA) ; 197*48818Swilliam 198*48818Swilliam /* While we are here, defeat gatea20 */ 199*48818Swilliam while (inb(0x64)&2); /* wait input ready */ 200*48818Swilliam outb(0x64,0xd1); 201*48818Swilliam while (inb(0x64)&2); /* wait input ready */ 202*48818Swilliam outb(0x60,0xdf); 203*48818Swilliam } 204*48818Swilliam 205*48818Swilliam u_char getchar() { 206*48818Swilliam u_char c; 207*48818Swilliam 208*48818Swilliam c = kbd(); 209*48818Swilliam if (c == '\r') c = '\n'; 210*48818Swilliam putchar(c); 211*48818Swilliam return(c); 212*48818Swilliam } 213*48818Swilliam 214*48818Swilliam reset_cpu() { 215*48818Swilliam 216*48818Swilliam while (inb(0x64)&2); /* wait input ready */ 217*48818Swilliam outb(0x64,0xFE); /* Reset Command */ 218*48818Swilliam wait(4000000); 219*48818Swilliam /* NOTREACHED */ 220*48818Swilliam } 221