|
|
1.1 ! root 1: #include "u.h" ! 2: #include "lib.h" ! 3: #include "mem.h" ! 4: #include "dat.h" ! 5: #include "fns.h" ! 6: #include "io.h" ! 7: ! 8: #include <libg.h> ! 9: ! 10: enum { ! 11: Data= 0x60, /* data port */ ! 12: ! 13: Status= 0x64, /* status port */ ! 14: Inready= 0x01, /* input character ready */ ! 15: Outbusy= 0x02, /* output busy */ ! 16: Sysflag= 0x04, /* system flag */ ! 17: Cmddata= 0x08, /* cmd==0, data==1 */ ! 18: Inhibit= 0x10, /* keyboard/mouse inhibited */ ! 19: Minready= 0x20, /* mouse character ready */ ! 20: Rtimeout= 0x40, /* general timeout */ ! 21: Parity= 0x80, ! 22: ! 23: Cmd= 0x64, /* command port (write only) */ ! 24: ! 25: Spec= 0x80, ! 26: ! 27: PF= Spec|0x20, /* num pad function key */ ! 28: View= Spec|0x00, /* view (shift window up) */ ! 29: KF= Spec|0x40, /* function key */ ! 30: Shift= Spec|0x60, ! 31: Break= Spec|0x61, ! 32: Ctrl= Spec|0x62, ! 33: Latin= Spec|0x63, ! 34: Caps= Spec|0x64, ! 35: Num= Spec|0x65, ! 36: No= Spec|0x7F, /* no mapping */ ! 37: ! 38: Home= KF|13, ! 39: Up= KF|14, ! 40: Pgup= KF|15, ! 41: Print= KF|16, ! 42: Left= View, ! 43: Right= View, ! 44: End= '\r', ! 45: Down= View, ! 46: Pgdown= View, ! 47: Ins= KF|20, ! 48: Del= 0x7F, ! 49: }; ! 50: ! 51: uchar kbtab[] = ! 52: { ! 53: [0x00] No, 0x1b, '1', '2', '3', '4', '5', '6', ! 54: [0x08] '7', '8', '9', '0', '-', '=', '\b', '\t', ! 55: [0x10] 'q', 'w', 'e', 'r', 't', 'y', 'u', 'i', ! 56: [0x18] 'o', 'p', '[', ']', '\n', Ctrl, 'a', 's', ! 57: [0x20] 'd', 'f', 'g', 'h', 'j', 'k', 'l', ';', ! 58: [0x28] '\'', '`', Shift, '\\', 'z', 'x', 'c', 'v', ! 59: [0x30] 'b', 'n', 'm', ',', '.', '/', Shift, No, ! 60: [0x38] Latin, ' ', Caps, KF|1, KF|2, KF|3, KF|4, KF|5, ! 61: [0x40] KF|6, KF|7, KF|8, KF|9, KF|10, Num, KF|12, Home, ! 62: [0x48] No, No, No, No, No, No, No, No, ! 63: [0x50] No, No, No, No, No, No, No, KF|11, ! 64: [0x58] KF|12, No, No, No, No, No, No, No, ! 65: }; ! 66: ! 67: uchar kbtabshift[] = ! 68: { ! 69: [0x00] No, 0x1b, '!', '@', '#', '$', '%', '^', ! 70: [0x08] '&', '*', '(', ')', '_', '+', '\b', '\t', ! 71: [0x10] 'Q', 'W', 'E', 'R', 'T', 'Y', 'U', 'I', ! 72: [0x18] 'O', 'P', '{', '}', '\n', Ctrl, 'A', 'S', ! 73: [0x20] 'D', 'F', 'G', 'H', 'J', 'K', 'L', ':', ! 74: [0x28] '"', '~', Shift, '|', 'Z', 'X', 'C', 'V', ! 75: [0x30] 'B', 'N', 'M', '<', '>', '?', Shift, No, ! 76: [0x38] Latin, ' ', Caps, KF|1, KF|2, KF|3, KF|4, KF|5, ! 77: [0x40] KF|6, KF|7, KF|8, KF|9, KF|10, Num, KF|12, Home, ! 78: [0x48] No, No, No, No, No, No, No, No, ! 79: [0x50] No, No, No, No, No, No, No, KF|11, ! 80: [0x58] KF|12, No, No, No, No, No, No, No, ! 81: }; ! 82: ! 83: uchar kbtabesc1[] = ! 84: { ! 85: [0x00] No, No, No, No, No, No, No, No, ! 86: [0x08] No, No, No, No, No, No, No, No, ! 87: [0x10] No, No, No, No, No, No, No, No, ! 88: [0x18] No, No, No, No, No, Ctrl, No, No, ! 89: [0x20] No, No, No, No, No, No, No, No, ! 90: [0x28] No, No, No, No, No, No, No, No, ! 91: [0x30] No, No, No, No, No, No, No, Print, ! 92: [0x38] Latin, No, No, No, No, No, No, No, ! 93: [0x40] No, No, No, No, No, No, Break, Home, ! 94: [0x48] Up, Pgup, No, Down, No, Right, No, End, ! 95: [0x50] Left, Pgdown, Ins, Del, No, No, No, No, ! 96: [0x58] No, No, No, No, No, No, No, No, ! 97: }; ! 98: ! 99: struct latin ! 100: { ! 101: uchar l; ! 102: char c[2]; ! 103: }latintab[] = { ! 104: '¡', "!!", /* spanish initial ! */ ! 105: '¢', "c|", /* cent */ ! 106: '¢', "c$", /* cent */ ! 107: '£', "l$", /* pound sterling */ ! 108: '¤', "g$", /* general currency */ ! 109: '¥', "y$", /* yen */ ! 110: '¥', "j$", /* yen */ ! 111: '¦', "||", /* broken vertical bar */ ! 112: '§', "SS", /* section symbol */ ! 113: '¨', "\"\"", /* dieresis */ ! 114: '©', "cr", /* copyright */ ! 115: '©', "cO", /* copyright */ ! 116: 'ª', "sa", /* super a, feminine ordinal */ ! 117: '«', "<<", /* left angle quotation */ ! 118: '¬', "no", /* not sign, hooked overbar */ ! 119: '', "--", /* soft hyphen */ ! 120: '®', "rg", /* registered trademark */ ! 121: '¯', "__", /* macron */ ! 122: '°', "s0", /* degree (sup o) */ ! 123: '±', "+-", /* plus-minus */ ! 124: '²', "s2", /* sup 2 */ ! 125: '³', "s3", /* sup 3 */ ! 126: '´', "''", /* grave accent */ ! 127: 'µ', "mu", /* mu */ ! 128: '¶', "pg", /* paragraph (pilcrow) */ ! 129: '·', "..", /* centered . */ ! 130: '¸', ",,", /* cedilla */ ! 131: '¹', "s1", /* sup 1 */ ! 132: 'º', "so", /* sup o */ ! 133: '»', ">>", /* right angle quotation */ ! 134: '¼', "14", /* 1/4 */ ! 135: '½', "12", /* 1/2 */ ! 136: '¾', "34", /* 3/4 */ ! 137: '¿', "??", /* spanish initial ? */ ! 138: 'À', "A`", /* A grave */ ! 139: 'Á', "A'", /* A acute */ ! 140: 'Â', "A^", /* A circumflex */ ! 141: 'Ã', "A~", /* A tilde */ ! 142: 'Ä', "A\"", /* A dieresis */ ! 143: 'Ä', "A:", /* A dieresis */ ! 144: 'Å', "Ao", /* A circle */ ! 145: 'Å', "AO", /* A circle */ ! 146: 'Æ', "Ae", /* AE ligature */ ! 147: 'Æ', "AE", /* AE ligature */ ! 148: 'Ç', "C,", /* C cedilla */ ! 149: 'È', "E`", /* E grave */ ! 150: 'É', "E'", /* E acute */ ! 151: 'Ê', "E^", /* E circumflex */ ! 152: 'Ë', "E\"", /* E dieresis */ ! 153: 'Ë', "E:", /* E dieresis */ ! 154: 'Ì', "I`", /* I grave */ ! 155: 'Í', "I'", /* I acute */ ! 156: 'Î', "I^", /* I circumflex */ ! 157: 'Ï', "I\"", /* I dieresis */ ! 158: 'Ï', "I:", /* I dieresis */ ! 159: 'Ð', "D-", /* Eth */ ! 160: 'Ñ', "N~", /* N tilde */ ! 161: 'Ò', "O`", /* O grave */ ! 162: 'Ó', "O'", /* O acute */ ! 163: 'Ô', "O^", /* O circumflex */ ! 164: 'Õ', "O~", /* O tilde */ ! 165: 'Ö', "O\"", /* O dieresis */ ! 166: 'Ö', "O:", /* O dieresis */ ! 167: 'Ö', "OE", /* O dieresis */ ! 168: 'Ö', "Oe", /* O dieresis */ ! 169: '×', "xx", /* times sign */ ! 170: 'Ø', "O/", /* O slash */ ! 171: 'Ù', "U`", /* U grave */ ! 172: 'Ú', "U'", /* U acute */ ! 173: 'Û', "U^", /* U circumflex */ ! 174: 'Ü', "U\"", /* U dieresis */ ! 175: 'Ü', "U:", /* U dieresis */ ! 176: 'Ü', "UE", /* U dieresis */ ! 177: 'Ü', "Ue", /* U dieresis */ ! 178: 'Ý', "Y'", /* Y acute */ ! 179: 'Þ', "P|", /* Thorn */ ! 180: 'Þ', "Th", /* Thorn */ ! 181: 'Þ', "TH", /* Thorn */ ! 182: 'ß', "ss", /* sharp s */ ! 183: 'à', "a`", /* a grave */ ! 184: 'á', "a'", /* a acute */ ! 185: 'â', "a^", /* a circumflex */ ! 186: 'ã', "a~", /* a tilde */ ! 187: 'ä', "a\"", /* a dieresis */ ! 188: 'ä', "a:", /* a dieresis */ ! 189: 'å', "ao", /* a circle */ ! 190: 'æ', "ae", /* ae ligature */ ! 191: 'ç', "c,", /* c cedilla */ ! 192: 'è', "e`", /* e grave */ ! 193: 'é', "e'", /* e acute */ ! 194: 'ê', "e^", /* e circumflex */ ! 195: 'ë', "e\"", /* e dieresis */ ! 196: 'ë', "e:", /* e dieresis */ ! 197: 'ì', "i`", /* i grave */ ! 198: 'í', "i'", /* i acute */ ! 199: 'î', "i^", /* i circumflex */ ! 200: 'ï', "i\"", /* i dieresis */ ! 201: 'ï', "i:", /* i dieresis */ ! 202: 'ð', "d-", /* eth */ ! 203: 'ñ', "n~", /* n tilde */ ! 204: 'ò', "o`", /* o grave */ ! 205: 'ó', "o'", /* o acute */ ! 206: 'ô', "o^", /* o circumflex */ ! 207: 'õ', "o~", /* o tilde */ ! 208: 'ö', "o\"", /* o dieresis */ ! 209: 'ö', "o:", /* o dieresis */ ! 210: 'ö', "oe", /* o dieresis */ ! 211: '÷', "-:", /* divide sign */ ! 212: 'ø', "o/", /* o slash */ ! 213: 'ù', "u`", /* u grave */ ! 214: 'ú', "u'", /* u acute */ ! 215: 'û', "u^", /* u circumflex */ ! 216: 'ü', "u\"", /* u dieresis */ ! 217: 'ü', "u:", /* u dieresis */ ! 218: 'ü', "ue", /* u dieresis */ ! 219: 'ý', "y'", /* y acute */ ! 220: 'þ', "th", /* thorn */ ! 221: 'þ', "p|", /* thorn */ ! 222: 'ÿ', "y\"", /* y dieresis */ ! 223: 'ÿ', "y:", /* y dieresis */ ! 224: 0, 0, ! 225: }; ! 226: ! 227: enum ! 228: { ! 229: /* controller command byte */ ! 230: Cscs1= (1<<6), /* scan code set 1 */ ! 231: Cmousedis= (1<<5), /* mouse disable */ ! 232: Ckbddis= (1<<4), /* kbd disable */ ! 233: Csf= (1<<2), /* system flag */ ! 234: Cmouseint= (1<<1), /* mouse interrupt enable */ ! 235: Ckbdint= (1<<0), /* kbd interrupt enable */ ! 236: }; ! 237: ! 238: static uchar ccc; ! 239: ! 240: int ! 241: latin1(int k1, int k2) ! 242: { ! 243: struct latin *l; ! 244: ! 245: for(l=latintab; l->l; l++) ! 246: if(k1==l->c[0] && k2==l->c[1]) ! 247: return l->l; ! 248: return 0; ! 249: } ! 250: ! 251: /* ! 252: * wait for output no longer busy ! 253: */ ! 254: static int ! 255: outready(void) ! 256: { ! 257: int tries; ! 258: ! 259: for(tries = 0; (inb(Status) & Outbusy); tries++){ ! 260: if(tries > 500) ! 261: return -1; ! 262: delay(2); ! 263: } ! 264: return 0; ! 265: } ! 266: ! 267: /* ! 268: * wait for input ! 269: */ ! 270: static int ! 271: inready(void) ! 272: { ! 273: int tries; ! 274: ! 275: for(tries = 0; !(inb(Status) & Inready); tries++){ ! 276: if(tries > 500) ! 277: return -1; ! 278: delay(2); ! 279: } ! 280: return 0; ! 281: } ! 282: ! 283: /* ! 284: * ask 8042 to enable the use of address bit 20 ! 285: */ ! 286: void ! 287: i8042a20(void) ! 288: { ! 289: outready(); ! 290: outb(Cmd, 0xD1); ! 291: outready(); ! 292: outb(Data, 0xDF); ! 293: outready(); ! 294: } ! 295: ! 296: /* ! 297: * ask 8042 to reset the machine ! 298: */ ! 299: void ! 300: i8042reset(void) ! 301: { ! 302: ushort *s = (ushort*)(KZERO|0x472); ! 303: int i, x; ! 304: ! 305: *s = 0x1234; /* BIOS warm-boot flag */ ! 306: ! 307: outready(); ! 308: outb(Cmd, 0xFE); /* pulse reset line (means resend on AT&T machines) */ ! 309: outready(); ! 310: ! 311: /* ! 312: * Pulse it by hand (old somewhat reliable) ! 313: */ ! 314: x = 0xDF; ! 315: for(i = 0; i < 5; i++){ ! 316: x ^= 1; ! 317: outready(); ! 318: outb(Cmd, 0xD1); ! 319: outready(); ! 320: outb(Data, x); /* toggle reset */ ! 321: delay(100); ! 322: } ! 323: } ! 324: ! 325: /* ! 326: * keyboard interrupt ! 327: */ ! 328: int ! 329: kbdintr0(void) ! 330: { ! 331: int s, c; ! 332: static int esc1, esc2; ! 333: static int shift; ! 334: static int caps; ! 335: static int ctl; ! 336: static int num; ! 337: static int lstate, k1, k2; ! 338: int keyup; ! 339: ! 340: /* ! 341: * get status ! 342: */ ! 343: s = inb(Status); ! 344: if(!(s&Inready)) ! 345: return -1; ! 346: ! 347: /* ! 348: * get the character ! 349: */ ! 350: c = inb(Data); ! 351: ! 352: /* ! 353: * e0's is the first of a 2 character sequence ! 354: */ ! 355: if(c == 0xe0){ ! 356: esc1 = 1; ! 357: return 0; ! 358: } else if(c == 0xe1){ ! 359: esc2 = 2; ! 360: return 0; ! 361: } ! 362: ! 363: keyup = c&0x80; ! 364: c &= 0x7f; ! 365: if(c > sizeof kbtab){ ! 366: print("unknown key %ux\n", c|keyup); ! 367: kbdchar(k1); ! 368: return 0; ! 369: } ! 370: ! 371: if(esc1){ ! 372: c = kbtabesc1[c]; ! 373: esc1 = 0; ! 374: kbdchar(c); ! 375: return 0; ! 376: } else if(esc2){ ! 377: esc2--; ! 378: return 0; ! 379: } else if(shift) ! 380: c = kbtabshift[c]; ! 381: else ! 382: c = kbtab[c]; ! 383: ! 384: if(caps && c<='z' && c>='a') ! 385: c += 'A' - 'a'; ! 386: ! 387: /* ! 388: * keyup only important for shifts ! 389: */ ! 390: if(keyup){ ! 391: switch(c){ ! 392: case Shift: ! 393: shift = 0; ! 394: break; ! 395: case Ctrl: ! 396: ctl = 0; ! 397: break; ! 398: } ! 399: return 0; ! 400: } ! 401: ! 402: /* ! 403: * normal character ! 404: */ ! 405: if(!(c & Spec)){ ! 406: if(ctl) ! 407: c &= 0x1f; ! 408: switch(lstate){ ! 409: case 1: ! 410: k1 = c; ! 411: lstate = 2; ! 412: return 0; ! 413: case 2: ! 414: k2 = c; ! 415: lstate = 0; ! 416: c = latin1(k1, k2); ! 417: if(c == 0){ ! 418: kbdchar(k1); ! 419: c = k2; ! 420: } ! 421: /* fall through */ ! 422: default: ! 423: break; ! 424: } ! 425: } else { ! 426: switch(c){ ! 427: case Caps: ! 428: caps ^= 1; ! 429: return 0; ! 430: case Num: ! 431: num ^= 1; ! 432: return 0; ! 433: case Shift: ! 434: shift = 1; ! 435: return 0; ! 436: case Latin: ! 437: lstate = 1; ! 438: return 0; ! 439: case Ctrl: ! 440: ctl = 1; ! 441: return 0; ! 442: } ! 443: } ! 444: kbdchar(c); ! 445: return 0; ! 446: } ! 447: ! 448: static void ! 449: kbdintr(Ureg*, void*) ! 450: { ! 451: while(kbdintr0() == 0) ! 452: ; ! 453: } ! 454: ! 455: void ! 456: kbdinit(void) ! 457: { ! 458: int c; ! 459: ! 460: /* wait for a quiescent controller */ ! 461: while((c = inb(Status)) & (Outbusy | Inready)) ! 462: if(c & Inready) ! 463: inb(Data); ! 464: ! 465: /* get current controller command byte */ ! 466: outb(Cmd, 0x20); ! 467: if(inready() < 0){ ! 468: print("kbdinit: can't read ccc\n"); ! 469: ccc = 0; ! 470: } else ! 471: ccc = inb(Data); ! 472: ! 473: /* enable kbd xfers and interrupts */ ! 474: ccc &= ~Ckbddis; ! 475: ccc |= Csf | Ckbdint | Cscs1; ! 476: if(outready() < 0) ! 477: print("kbd init failed\n"); ! 478: outb(Cmd, 0x60); ! 479: if(outready() < 0) ! 480: print("kbd init failed\n"); ! 481: outb(Data, ccc); ! 482: if(outready() < 0) ! 483: print("kbd init failed\n"); ! 484: ! 485: setvec(Kbdvec, kbdintr, 0); ! 486: }
This archive runs on limited infrastructure. Preserving old code on modern bandwidth. Automated agents are requested to crawl responsibly.