|
|
1.1 ! root 1: /* netboot ! 2: * ! 3: * kbd.c,v ! 4: * Revision 1.1 1993/07/08 16:04:00 brezak ! 5: * Diskless boot prom code from Jim McKim ([email protected]) ! 6: * ! 7: * Revision 1.2 1993/06/30 20:16:13 mckim ! 8: * Clean up compiler error msg. ! 9: * ! 10: * Revision 1.1.1.1 1993/05/28 11:41:07 mckim ! 11: * Initial version. ! 12: * ! 13: * ! 14: * source in this file came from ! 15: * the original 386BSD boot blocks. ! 16: * ! 17: * Copyright (c) 1990 The Regents of the University of California. ! 18: * All rights reserved. ! 19: * ! 20: * This code is derived from software contributed to Berkeley by ! 21: * William Jolitz. ! 22: * ! 23: * Redistribution and use in source and binary forms, with or without ! 24: * modification, are permitted provided that the following conditions ! 25: * are met: ! 26: * 1. Redistributions of source code must retain the above copyright ! 27: * notice, this list of conditions and the following disclaimer. ! 28: * 2. Redistributions in binary form must reproduce the above copyright ! 29: * notice, this list of conditions and the following disclaimer in the ! 30: * documentation and/or other materials provided with the distribution. ! 31: * 3. All advertising materials mentioning features or use of this software ! 32: * must display the following acknowledgement: ! 33: * This product includes software developed by the University of ! 34: * California, Berkeley and its contributors. ! 35: * 4. Neither the name of the University nor the names of its contributors ! 36: * may be used to endorse or promote products derived from this software ! 37: * without specific prior written permission. ! 38: * ! 39: * THIS SOFTWARE IS PROVIDED BY THE REGENTS AND CONTRIBUTORS ``AS IS'' AND ! 40: * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE ! 41: * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ! 42: * ARE DISCLAIMED. IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE ! 43: * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL ! 44: * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS ! 45: * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) ! 46: * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT ! 47: * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY ! 48: * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF ! 49: * SUCH DAMAGE. ! 50: * ! 51: * @(#)kbd.c 7.4 (Berkeley) 5/4/91 ! 52: */ ! 53: ! 54: #include "proto.h" ! 55: ! 56: #define KBSTATP 0x64 /* kbd status port */ ! 57: #define KBS_INP_BUF_FUL 0x02 /* kbd char ready */ ! 58: #define KBDATAP 0x60 /* kbd data port */ ! 59: ! 60: #define K_RDWR 0x60 /* keyboard data & cmds (read/write) */ ! 61: #define K_STATUS 0x64 /* keyboard status */ ! 62: #define K_CMD 0x64 /* keybd ctlr command (write-only) */ ! 63: ! 64: #define K_OBUF_FUL 0x01 /* output buffer full */ ! 65: #define K_IBUF_FUL 0x02 /* input buffer full */ ! 66: ! 67: #define KC_CMD_WIN 0xd0 /* read output port */ ! 68: #define KC_CMD_WOUT 0xd1 /* write output port */ ! 69: #define KB_A20 0x9f /* enable A20, ! 70: enable output buffer full interrupt ! 71: enable data line ! 72: disable clock line */ ! 73: ! 74: #define L 0x01 /* locking function */ ! 75: #define SHF 0x02 /* keyboard shift */ ! 76: #define ALT 0x04 /* alternate shift -- alternate chars */ ! 77: #define NUM 0x08 /* numeric shift cursors vs. numeric */ ! 78: #define CTL 0x10 /* control shift -- allows ctl function */ ! 79: #define CPS 0x20 /* caps shift -- swaps case of letter */ ! 80: #define ASCII 0x40 /* ascii code for this key */ ! 81: #define STP 0x80 /* stop output */ ! 82: ! 83: static u_char action[128] = { ! 84: 0, ASCII, ASCII, ASCII, ASCII, ASCII, ASCII, ASCII, /* scan 0- 7 */ ! 85: ASCII, ASCII, ASCII, ASCII, ASCII, ASCII, ASCII, ASCII, /* scan 8-15 */ ! 86: ASCII, ASCII, ASCII, ASCII, ASCII, ASCII, ASCII, ASCII, /* scan 16-23 */ ! 87: ASCII, ASCII, ASCII, ASCII, ASCII, CTL, ASCII, ASCII, /* scan 24-31 */ ! 88: ASCII, ASCII, ASCII, ASCII, ASCII, ASCII, ASCII, ASCII, /* scan 32-39 */ ! 89: ASCII, ASCII, SHF , ASCII, ASCII, ASCII, ASCII, ASCII, /* scan 40-47 */ ! 90: ASCII, ASCII, ASCII, ASCII, ASCII, ASCII, SHF, ASCII, /* scan 48-55 */ ! 91: ALT, ASCII, CPS|L, 0, 0, ASCII, 0, 0, /* scan 56-63 */ ! 92: 0, 0, 0, 0, 0, NUM|L, STP|L, ASCII, /* scan 64-71 */ ! 93: ASCII, ASCII, ASCII, ASCII, ASCII, ASCII, ASCII, ASCII, /* scan 72-79 */ ! 94: ASCII, ASCII, ASCII, ASCII, 0, 0, 0, 0, /* scan 80-87 */ ! 95: 0,0,0,0,0,0,0,0, ! 96: 0,0,0,0,0,0,0,0, 0,0,0,0,0,0,0,0, ! 97: 0,0,0,0,0,0,0,0, 0,0,0,0,0,0,0,0, } ; ! 98: ! 99: static u_char unshift[128] = { /* no shift */ ! 100: 0, 033 , '1' , '2' , '3' , '4' , '5' , '6' , /* scan 0- 7 */ ! 101: '7' , '8' , '9' , '0' , '-' , '=' , 0177 ,'\t' , /* scan 8-15 */ ! 102: ! 103: 'q' , 'w' , 'e' , 'r' , 't' , 'y' , 'u' , 'i' , /* scan 16-23 */ ! 104: 'o' , 'p' , '[' , ']' , '\r' , CTL , 'a' , 's' , /* scan 24-31 */ ! 105: ! 106: 'd' , 'f' , 'g' , 'h' , 'j' , 'k' , 'l' , ';' , /* scan 32-39 */ ! 107: '\'' , '`' , SHF , '\\' , 'z' , 'x' , 'c' , 'v' , /* scan 40-47 */ ! 108: ! 109: 'b' , 'n' , 'm' , ',' , '.' , '/' , SHF , '*', /* scan 48-55 */ ! 110: ALT , ' ' , CPS|L, 0, 0, ' ' , 0, 0, /* scan 56-63 */ ! 111: ! 112: 0, 0, 0, 0, 0, NUM|L, STP|L, '7', /* scan 64-71 */ ! 113: '8', '9', '-', '4', '5', '6', '+', '1', /* scan 72-79 */ ! 114: ! 115: '2', '3', '0', '.', 0, 0, 0, 0, /* scan 80-87 */ ! 116: 0,0,0,0,0,0,0,0, ! 117: 0,0,0,0,0,0,0,0, 0,0,0,0,0,0,0,0, ! 118: 0,0,0,0,0,0,0,0, 0,0,0,0,0,0,0,0, } ; ! 119: ! 120: static u_char shift[128] = { /* shift shift */ ! 121: 0, 033 , '!' , '@' , '#' , '$' , '%' , '^' , /* scan 0- 7 */ ! 122: '&' , '*' , '(' , ')' , '_' , '+' , 0177 ,'\t' , /* scan 8-15 */ ! 123: 'Q' , 'W' , 'E' , 'R' , 'T' , 'Y' , 'U' , 'I' , /* scan 16-23 */ ! 124: 'O' , 'P' , '[' , ']' , '\r' , CTL , 'A' , 'S' , /* scan 24-31 */ ! 125: 'D' , 'F' , 'G' , 'H' , 'J' , 'K' , 'L' , ':' , /* scan 32-39 */ ! 126: '"' , '~' , SHF , '|' , 'Z' , 'X' , 'C' , 'V' , /* scan 40-47 */ ! 127: 'B' , 'N' , 'M' , '<' , '>' , '?' , SHF , '*', /* scan 48-55 */ ! 128: ALT , ' ' , CPS|L, 0, 0, ' ' , 0, 0, /* scan 56-63 */ ! 129: 0, 0, 0, 0, 0, NUM|L, STP|L, '7', /* scan 64-71 */ ! 130: '8', '9', '-', '4', '5', '6', '+', '1', /* scan 72-79 */ ! 131: '2', '3', '0', '.', 0, 0, 0, 0, /* scan 80-87 */ ! 132: 0,0,0,0,0,0,0,0, ! 133: 0,0,0,0,0,0,0,0, 0,0,0,0,0,0,0,0, ! 134: 0,0,0,0,0,0,0,0, 0,0,0,0,0,0,0,0, } ; ! 135: ! 136: static u_char ctl[128] = { /* CTL shift */ ! 137: 0, 033 , '!' , 000 , '#' , '$' , '%' , 036 , /* scan 0- 7 */ ! 138: '&' , '*' , '(' , ')' , 037 , '+' , 034 ,'\177', /* scan 8-15 */ ! 139: 021 , 027 , 005 , 022 , 024 , 031 , 025 , 011 , /* scan 16-23 */ ! 140: 017 , 020 , 033 , 035 , '\r' , CTL , 001 , 013 , /* scan 24-31 */ ! 141: 004 , 006 , 007 , 010 , 012 , 013 , 014 , ';' , /* scan 32-39 */ ! 142: '\'' , '`' , SHF , 034 , 032 , 030 , 003 , 026 , /* scan 40-47 */ ! 143: 002 , 016 , 015 , '<' , '>' , '?' , SHF , '*', /* scan 48-55 */ ! 144: ALT , ' ' , CPS|L, 0, 0, ' ' , 0, 0, /* scan 56-63 */ ! 145: CPS|L, 0, 0, 0, 0, 0, 0, 0, /* scan 64-71 */ ! 146: 0, 0, 0, 0, 0, 0, 0, 0, /* scan 72-79 */ ! 147: 0, 0, 0, 0, 0, 0, 0, 0, /* scan 80-87 */ ! 148: 0, 0, 033, '7' , '4' , '1' , 0, NUM|L, /* scan 88-95 */ ! 149: '8' , '5' , '2' , 0, STP|L, '9' , '6' , '3' , /*scan 96-103*/ ! 150: '.' , 0, '*' , '-' , '+' , 0, 0, 0, /*scan 104-111*/ ! 151: 0,0,0,0,0,0,0,0, 0,0,0,0,0,0,0,0, } ; ! 152: ! 153: static u_char shfts, ctls, alts, caps, num, stp; ! 154: static u_char chr; ! 155: static int is_chr_queued = 0; ! 156: ! 157: static int ! 158: ProcessKbdEvent(void) { ! 159: /* Returns 1 if event result is an ascii char, 0 otherwise (or no event). ! 160: * As a side effect, it digests keyboard events and queues bona fide ! 161: * characters for subsequent reading. ! 162: */ ! 163: u_char dt, brk, act; ! 164: if ((inb(KBSTATP) & 0x01) == 0) ! 165: return is_chr_queued; ! 166: dt = inb(KBDATAP); ! 167: brk = dt & 0x80; ! 168: dt = dt & 0x7f; ! 169: ! 170: act = action[dt]; ! 171: if (act & SHF) { ! 172: if (brk) ! 173: shfts = 0; ! 174: else ! 175: shfts = 1; ! 176: } ! 177: if (act & ALT) { ! 178: if (brk) ! 179: alts = 0; ! 180: else ! 181: alts = 1; ! 182: } ! 183: if (act & NUM) { ! 184: if (act & L) { ! 185: if (!brk) ! 186: num ^= 1; ! 187: } else ! 188: if(brk) ! 189: num = 0; ! 190: else ! 191: num = 1; ! 192: } ! 193: if (act & CTL) { ! 194: if (brk) ! 195: ctls = 0; ! 196: else ! 197: ctls = 1; ! 198: } ! 199: if (act & CPS) { ! 200: if (act & L) { ! 201: if (!brk) ! 202: caps ^= 1; ! 203: } else ! 204: if (brk) ! 205: caps = 0; ! 206: else ! 207: caps = 1; ! 208: } ! 209: if (act & STP) { ! 210: if (act & L) { ! 211: if (!brk) ! 212: stp ^= 1; ! 213: } else ! 214: if (brk) ! 215: stp = 0; ! 216: else ! 217: stp = 1; ! 218: } ! 219: if (ctls && alts && dt == 83) ! 220: exit(1); ! 221: if ((act & ASCII) && !brk) { ! 222: if (shfts) { ! 223: chr = shift[dt]; ! 224: } else { ! 225: if (ctls) { ! 226: chr = ctl[dt]; ! 227: } else { ! 228: chr = unshift[dt]; ! 229: } ! 230: } ! 231: if (caps && (chr >= 'a' && chr <= 'z')) { ! 232: chr -= 'a' - 'A' ; ! 233: } ! 234: is_chr_queued = 1; ! 235: } ! 236: return is_chr_queued; ! 237: } ! 238: ! 239: int ! 240: IsKbdCharReady(void) { ! 241: #ifdef USE_BIOS ! 242: int result; ! 243: asm(" ! 244: push %%ebx ! 245: call _prot_to_real ! 246: mov $1, %%ax ! 247: int $0x16 ! 248: setz %%bl ! 249: .byte 0x66 ! 250: call _real_to_prot ! 251: movsbl %%bl, %0 ! 252: pop %%ebx ! 253: " : "=g" (result)); ! 254: return result; ! 255: #else ! 256: return ProcessKbdEvent(); ! 257: #endif ! 258: } ! 259: ! 260: static int ! 261: scankbd(void) { ! 262: ! 263: #ifdef notdef ! 264: u_char c; ! 265: c = inb(KBDATAP); ! 266: if (c == 83) exit(); ! 267: /*if (c == 0xaa) return (0); ! 268: if (c == 0xfa) return (0);*/ ! 269: ! 270: if (bdt == 0) { bdt = c&0x7f; return(0); } ! 271: ! 272: if(odt) return(1); ! 273: ! 274: c &= 0x7f; ! 275: ! 276: if (bdt == c) return(0); ! 277: odt = c; ! 278: #endif ! 279: return 1; ! 280: } ! 281: ! 282: static void ! 283: kbdreset(void) { ! 284: u_char c; ! 285: ! 286: /* Enable interrupts and keyboard controller */ ! 287: while (inb(KBSTATP)&2); outb(KBSTATP,0x60); ! 288: while (inb(KBSTATP)&2); outb(KBDATAP,0x4D); ! 289: ! 290: /* Start keyboard stuff RESET */ ! 291: while (inb(KBSTATP)&2); /* wait input ready */ ! 292: outb(KBDATAP,0xFF); /* RESET */ ! 293: ! 294: while((c=inb(KBDATAP))!=0xFA) ; ! 295: ! 296: /* While we are here, defeat gatea20 */ ! 297: while (inb(KBSTATP)&2); /* wait input ready */ ! 298: outb(KBSTATP,0xd1); ! 299: while (inb(KBSTATP)&2); /* wait input ready */ ! 300: outb(KBDATAP,0xdf); ! 301: while (inb(KBSTATP)&2); /* wait input ready */ ! 302: inb(KBDATAP); ! 303: } ! 304: ! 305: /* TBD - what does this do?, used by ResetCpu() */ ! 306: void ! 307: KbdWait(int n) { ! 308: int v; ! 309: ! 310: v = 0; ! 311: while(n-- && (v = scankbd()) == 0); ! 312: if (v) kbdreset(); ! 313: } ! 314: ! 315: /* ! 316: * Gate A20 for high memory ! 317: */ ! 318: u_char x_20 = KB_A20; ! 319: ! 320: void ! 321: gateA20(void) { ! 322: while (inb(K_STATUS) & K_IBUF_FUL); ! 323: while (inb(K_STATUS) & K_OBUF_FUL) ! 324: (void)inb(K_RDWR); ! 325: ! 326: outb(K_CMD, KC_CMD_WOUT); ! 327: while (inb(K_STATUS) & K_IBUF_FUL); ! 328: outb(K_RDWR, x_20); ! 329: while (inb(K_STATUS) & K_IBUF_FUL); ! 330: } ! 331: ! 332: int ! 333: getc(void) { ! 334: #ifdef USE_BIOS ! 335: int rslt; ! 336: asm(" ! 337: push %%ebx ! 338: call _prot_to_real ! 339: movb $0x0, %%ah ! 340: sti ! 341: int $0x16 ! 342: cli ! 343: movb %%al, %%bl ! 344: .byte 0x66 ! 345: call _real_to_prot ! 346: xor %%eax, %%eax ! 347: movb %%bl, %0 ! 348: pop %%ebx ! 349: " : "=g" (rslt)); ! 350: return rslt; ! 351: #else ! 352: while (!is_chr_queued) { ! 353: ProcessKbdEvent(); ! 354: } ! 355: is_chr_queued = 0; ! 356: return chr; ! 357: #endif ! 358: } ! 359: ! 360: int ! 361: getchar(void) { ! 362: int c; ! 363: ! 364: if ((c=getc()) == '\r') ! 365: c = '\n'; ! 366: if (c == '\b') { ! 367: putchar('\b'); ! 368: putchar(' '); ! 369: } ! 370: putchar(c); ! 371: return c; ! 372: }
This archive runs on limited infrastructure. Preserving old code on modern bandwidth. Automated agents are requested to crawl responsibly.