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 and Don Ahn. 7 * 8 * %sccs.include.redist.c% 9 * 10 * @(#)pccons.c 5.14 (Berkeley) 05/20/92 11 */ 12 13 /* 14 * code to work keyboard & display for PC-style console 15 */ 16 #include "param.h" 17 #include "conf.h" 18 #include "ioctl.h" 19 #include "proc.h" 20 #include "user.h" 21 #include "tty.h" 22 #include "uio.h" 23 #include "i386/isa/isa_device.h" 24 #include "callout.h" 25 #include "systm.h" 26 #include "kernel.h" 27 #include "syslog.h" 28 #include "i386/isa/icu.h" 29 #include "i386/i386/cons.h" 30 31 struct tty pccons; 32 33 struct pcconsoftc { 34 char cs_flags; 35 #define CSF_ACTIVE 0x1 /* timeout active */ 36 #define CSF_POLLING 0x2 /* polling for input */ 37 char cs_lastc; /* last char sent */ 38 int cs_timo; /* timeouts since interrupt */ 39 u_long cs_wedgecnt; /* times restarted */ 40 } pcconsoftc; 41 42 int pcprobe(), pcattach(); 43 44 struct isa_driver pcdriver = { 45 pcprobe, pcattach, "pc", 46 }; 47 48 #define COL 80 49 #define ROW 25 50 #define CHR 2 51 #define MONO_BASE 0x3B4 52 #define MONO_BUF 0xfe0B0000 53 #define CGA_BASE 0x3D4 54 #define CGA_BUF 0xfe0B8000 55 #define IOPHYSMEM 0xA0000 56 57 u_char color = 0xe ; 58 static unsigned int addr_6845 = MONO_BASE; 59 u_short *Crtat = (u_short *)MONO_BUF; 60 static openf; 61 62 /* 63 * We check the console periodically to make sure 64 * that it hasn't wedged. Unfortunately, if an XOFF 65 * is typed on the console, that can't be distinguished 66 * from more catastrophic failure. 67 */ 68 #define CN_TIMERVAL (hz) /* frequency at which to check cons */ 69 #define CN_TIMO (2*60) /* intervals to allow for output char */ 70 71 int pcstart(); 72 int pcparam(); 73 int ttrstrt(); 74 char partab[]; 75 76 /* 77 * Wait for CP to accept last CP command sent 78 * before setting up next command. 79 */ 80 #define waitforlast(timo) { \ 81 if (pclast) { \ 82 (timo) = 10000; \ 83 do \ 84 uncache((char *)&pclast->cp_unit); \ 85 while ((pclast->cp_unit&CPTAKE) == 0 && --(timo)); \ 86 } \ 87 } 88 89 u_char inb(); 90 91 pcprobe(dev) 92 struct isa_device *dev; 93 { 94 u_char c; 95 int again = 0; 96 97 /* Enable interrupts and keyboard controller */ 98 while (inb(0x64)&2); outb(0x64,0x60); 99 while (inb(0x64)&2); outb(0x60,0x4D); 100 101 /* Start keyboard stuff RESET */ 102 while (inb(0x64)&2); /* wait input ready */ 103 outb(0x60,0xFF); /* RESET */ 104 while((c=inb(0x60))!=0xFA) { 105 if ((c == 0xFE) || (c == 0xFF)) { 106 if(!again)printf("KEYBOARD disconnected: RECONNECT \n"); 107 while (inb(0x64)&2); /* wait input ready */ 108 outb(0x60,0xFF); /* RESET */ 109 again = 1; 110 } 111 } 112 /* pick up keyboard reset return code */ 113 while((c=inb(0x60))!=0xAA); 114 return 1; 115 } 116 117 pcattach(dev) 118 struct isa_device *dev; 119 { 120 u_short *cp = Crtat + (CGA_BUF-MONO_BUF)/CHR; 121 u_short was; 122 123 /* Crtat initialized to point to MONO buffer */ 124 /* if not present change to CGA_BUF offset */ 125 /* ONLY ADD the difference since locore.s adds */ 126 /* in the remapped offset at the right time */ 127 128 was = *Crtat; 129 *Crtat = (u_short) 0xA55A; 130 if (*Crtat != 0xA55A) 131 printf("<mono>"); 132 else printf("<color>"); 133 *Crtat = was; 134 cursor(); 135 } 136 137 /* ARGSUSED */ 138 #ifdef __STDC__ 139 pcopen(dev_t dev, int flag, int mode, struct proc *p) 140 #else 141 pcopen(dev, flag, mode, p) 142 dev_t dev; 143 int flag, mode; 144 struct proc *p; 145 #endif 146 { 147 register struct tty *tp; 148 149 tp = &pccons; 150 tp->t_oproc = pcstart; 151 tp->t_param = pcparam; 152 tp->t_dev = dev; 153 openf++; 154 if ((tp->t_state & TS_ISOPEN) == 0) { 155 tp->t_state |= TS_WOPEN; 156 ttychars(tp); 157 tp->t_iflag = TTYDEF_IFLAG; 158 tp->t_oflag = TTYDEF_OFLAG; 159 tp->t_cflag = TTYDEF_CFLAG; 160 tp->t_lflag = TTYDEF_LFLAG; 161 tp->t_ispeed = tp->t_ospeed = TTYDEF_SPEED; 162 pcparam(tp, &tp->t_termios); 163 ttsetwater(tp); 164 } else if (tp->t_state&TS_XCLUDE && p->p_ucred->cr_uid != 0) 165 return (EBUSY); 166 tp->t_state |= TS_CARR_ON; 167 return ((*linesw[tp->t_line].l_open)(dev, tp)); 168 } 169 170 pcclose(dev, flag, mode, p) 171 dev_t dev; 172 int flag, mode; 173 struct proc *p; 174 { 175 (*linesw[pccons.t_line].l_close)(&pccons, flag); 176 ttyclose(&pccons); 177 return(0); 178 } 179 180 /*ARGSUSED*/ 181 pcread(dev, uio, flag) 182 dev_t dev; 183 struct uio *uio; 184 { 185 return ((*linesw[pccons.t_line].l_read)(&pccons, uio, flag)); 186 } 187 188 /*ARGSUSED*/ 189 pcwrite(dev, uio, flag) 190 dev_t dev; 191 struct uio *uio; 192 { 193 return ((*linesw[pccons.t_line].l_write)(&pccons, uio, flag)); 194 } 195 196 /* 197 * Got a console receive interrupt - 198 * the console processor wants to give us a character. 199 * Catch the character, and see who it goes to. 200 */ 201 pcrint(dev, irq, cpl) 202 dev_t dev; 203 { 204 int c; 205 206 c = sgetc(1); 207 if (c&0x100) return; 208 if (pcconsoftc.cs_flags&CSF_POLLING) 209 return; 210 #ifdef KDB 211 if (kdbrintr(c, &pccons)) 212 return; 213 #endif 214 if (openf) /* 386bsd */ 215 (*linesw[pccons.t_line].l_rint)(c&0xff, &pccons); 216 } 217 218 pcioctl(dev, cmd, data, flag, p) 219 dev_t dev; 220 int cmd, flag; 221 caddr_t data; 222 struct proc *p; 223 { 224 register struct tty *tp = &pccons; 225 register error; 226 227 error = (*linesw[tp->t_line].l_ioctl)(tp, cmd, data, flag, p); 228 if (error >= 0) 229 return (error); 230 error = ttioctl(tp, cmd, data, flag); 231 if (error >= 0) 232 return (error); 233 return (ENOTTY); 234 } 235 236 int pcconsintr = 1; 237 /* 238 * Got a console transmission interrupt - 239 * the console processor wants another character. 240 */ 241 pcxint(dev) 242 dev_t dev; 243 { 244 register struct tty *tp; 245 register int unit; 246 247 if (!pcconsintr) 248 return; 249 pccons.t_state &= ~TS_BUSY; 250 pcconsoftc.cs_timo = 0; 251 if (pccons.t_line) 252 (*linesw[pccons.t_line].l_start)(&pccons); 253 else 254 pcstart(&pccons); 255 } 256 257 pcstart(tp) 258 register struct tty *tp; 259 { 260 register c, s; 261 262 s = spltty(); 263 if (tp->t_state & (TS_TIMEOUT|TS_BUSY|TS_TTSTOP)) 264 goto out; 265 do { 266 if (tp->t_outq.c_cc <= tp->t_lowat) { 267 if (tp->t_state&TS_ASLEEP) { 268 tp->t_state &= ~TS_ASLEEP; 269 wakeup((caddr_t)&tp->t_outq); 270 } 271 selwakeup(&tp->t_wsel); 272 } 273 if (tp->t_outq.c_cc == 0) 274 goto out; 275 c = getc(&tp->t_outq); 276 splx(s); 277 sput(c, 0x7); 278 s = spltty(); 279 } while(1); 280 out: 281 splx(s); 282 } 283 284 pccnprobe(cp) 285 struct consdev *cp; 286 { 287 int maj; 288 extern int pcopen(); 289 290 /* locate the major number */ 291 for (maj = 0; maj < nchrdev; maj++) 292 if (cdevsw[maj].d_open == pcopen) 293 break; 294 295 /* initialize required fields */ 296 cp->cn_dev = makedev(maj, 0); 297 cp->cn_tp = &pccons; 298 cp->cn_pri = CN_INTERNAL; 299 } 300 301 /* ARGSUSED */ 302 pccninit(cp) 303 struct consdev *cp; 304 { 305 /* 306 * For now, don't screw with it. 307 */ 308 /* crtat = 0; */ 309 } 310 311 static __color; 312 313 /* ARGSUSED */ 314 pccnputc(dev, c) 315 dev_t dev; 316 char c; 317 { 318 int clr = __color; 319 320 if (clr == 0) 321 clr = 0x30; 322 else 323 clr |= 0x60; 324 if (c == '\n') 325 sput('\r', clr); 326 sput(c, clr); 327 } 328 329 /* 330 * Print a character on console. 331 */ 332 pcputchar(c, tp) 333 char c; 334 register struct tty *tp; 335 { 336 sput(c,0x2); 337 if (c=='\n') getchar(); 338 } 339 340 341 /* ARGSUSED */ 342 pccngetc(dev) 343 dev_t dev; 344 { 345 register int c, s; 346 347 s = spltty(); /* block pcrint while we poll */ 348 c = sgetc(0); 349 if (c == '\r') c = '\n'; 350 splx(s); 351 return (c); 352 } 353 354 pcgetchar(tp) 355 register struct tty *tp; 356 { 357 int c; 358 359 c = sgetc(0); 360 return (c&0xff); 361 } 362 363 /* 364 * Set line parameters 365 */ 366 pcparam(tp, t) 367 register struct tty *tp; 368 register struct termios *t; 369 { 370 register int cflag = t->c_cflag; 371 /* and copy to tty */ 372 tp->t_ispeed = t->c_ispeed; 373 tp->t_ospeed = t->c_ospeed; 374 tp->t_cflag = cflag; 375 376 return(0); 377 } 378 379 #ifdef KDB 380 /* 381 * Turn input polling on/off (used by debugger). 382 */ 383 pcpoll(onoff) 384 int onoff; 385 { 386 } 387 #endif 388 389 extern int hz; 390 391 static beeping; 392 sysbeepstop() 393 { 394 /* disable counter 2 */ 395 outb(0x61,inb(0x61)&0xFC); 396 beeping = 0; 397 } 398 399 sysbeep() 400 { 401 402 /* enable counter 2 */ 403 outb(0x61,inb(0x61)|3); 404 /* set command for counter 2, 2 byte write */ 405 outb(0x43,0xB6); 406 /* send 0x637 for 750 HZ */ 407 outb(0x42,0x37); 408 outb(0x42,0x06); 409 if(!beeping)timeout(sysbeepstop,0,hz/4); 410 beeping = 1; 411 } 412 413 /* cursor() sets an offset (0-1999) into the 80x25 text area */ 414 415 static u_short *crtat = 0; 416 char bg_at = 0x0f; 417 char so_at = 0x70; 418 419 cursor() 420 { int pos = crtat - Crtat; 421 422 outb(addr_6845,14); 423 outb(addr_6845+1,pos >> 8); 424 outb(addr_6845,15); 425 outb(addr_6845+1,pos&0xff); 426 timeout(cursor,0,hz/10); 427 } 428 429 u_char shfts, ctls, alts, caps, num, stp, scroll; 430 431 /* 432 * Compensate for abysmally stupid frame buffer aribitration with macro 433 */ 434 #define wrtchar(c) { do *crtat = (c); while ((c) != *crtat); crtat++; row++; } 435 436 /* sput has support for emulation of the 'ibmpc' termcap entry. */ 437 /* This is a bare-bones implementation of a bare-bones entry */ 438 /* One modification: Change li#24 to li#25 to reflect 25 lines */ 439 440 sput(c, ca) 441 u_char c, ca; 442 { 443 444 static int esc,ebrac,eparm,cx,cy,row,so; 445 446 if (crtat == 0) { 447 u_short *cp = Crtat + (CGA_BUF-MONO_BUF)/CHR, was; 448 unsigned cursorat; 449 450 /* Crtat initialized to point to MONO buffer */ 451 /* if not present change to CGA_BUF offset */ 452 /* ONLY ADD the difference since locore.s adds */ 453 /* in the remapped offset at the right time */ 454 455 was = *cp; 456 *cp = (u_short) 0xA55A; 457 if (*cp != 0xA55A) { 458 addr_6845 = MONO_BASE; 459 } else { 460 *cp = was; 461 addr_6845 = CGA_BASE; 462 Crtat = Crtat + (CGA_BUF-MONO_BUF)/CHR; 463 } 464 /* Extract cursor location */ 465 outb(addr_6845,14); 466 cursorat = inb(addr_6845+1)<<8 ; 467 outb(addr_6845,15); 468 cursorat |= inb(addr_6845+1); 469 470 crtat = Crtat + cursorat; 471 fillw((bg_at<<8)|' ', crtat, COL*ROW-cursorat); 472 } 473 switch(c) { 474 case 0x1B: 475 esc = 1; ebrac = 0; eparm = 0; 476 break; 477 478 case '\t': 479 do { 480 wrtchar((ca<<8)| ' '); 481 } while (row % 8); 482 break; 483 484 case '\010': 485 crtat--; row--; 486 if (row < 0) row += COL; /* non-destructive backspace */ 487 break; 488 489 case '\r': 490 crtat -= row ; row = 0; 491 break; 492 493 case '\n': 494 crtat += COL ; 495 break; 496 497 default: 498 if (esc) { 499 if (ebrac) { 500 switch(c) { 501 case 'm': /* no support for standout */ 502 if (!cx) so = 0; 503 else so = 1; 504 esc = 0; ebrac = 0; eparm = 0; 505 break; 506 case 'A': /* back one row */ 507 crtat -= COL; 508 esc = 0; ebrac = 0; eparm = 0; 509 break; 510 case 'B': /* down one row */ 511 crtat += COL; 512 esc = 0; ebrac = 0; eparm = 0; 513 break; 514 case 'C': /* right cursor */ 515 crtat++; row++; 516 esc = 0; ebrac = 0; eparm = 0; 517 break; 518 case 'J': /* Clear to end of display */ 519 fillw((bg_at<<8)+' ', crtat, 520 Crtat+COL*ROW-crtat); 521 esc = 0; ebrac = 0; eparm = 0; 522 break; 523 case 'K': /* Clear to EOL */ 524 fillw((bg_at<<8)+' ', crtat, 525 COL-(crtat-Crtat)%COL); 526 esc = 0; ebrac = 0; eparm = 0; 527 break; 528 case 'H': /* Cursor move */ 529 if ((!cx)||(!cy)) { 530 crtat = Crtat; 531 row = 0; 532 } else { 533 crtat = Crtat+(cx-1)*COL+cy-1; 534 row = cy-1; 535 } 536 esc = 0; ebrac = 0; eparm = 0; 537 break; 538 case ';': /* Switch params in cursor def */ 539 eparm = 1; 540 return; 541 default: /* Only numbers valid here */ 542 if ((c >= '0')&&(c <= '9')) { 543 if (eparm) { 544 cy *= 10; 545 cy += c - '0'; 546 } else { 547 cx *= 10; 548 cx += c - '0'; 549 } 550 } else { 551 esc = 0; ebrac = 0; eparm = 0; 552 } 553 return; 554 } 555 break; 556 } else if (c == 'c') { /* Clear screen & home */ 557 fillw((bg_at<<8)+' ', Crtat,COL*ROW); 558 crtat = Crtat; row = 0; 559 esc = 0; ebrac = 0; eparm = 0; 560 } else if (c == '[') { /* Start ESC [ sequence */ 561 ebrac = 1; cx = 0; cy = 0; eparm = 0; 562 } else { /* Invalid, clear state */ 563 esc = 0; ebrac = 0; eparm = 0; 564 } 565 } else { 566 if (c == 7) 567 sysbeep(); 568 /* Print only printables */ 569 else /*if (c >= ' ') */ { 570 if (so) { 571 wrtchar((so_at<<8)| c); 572 } else { 573 wrtchar((ca<<8)| c); 574 } 575 if (row >= COL) row = 0; 576 break ; 577 } 578 } 579 } 580 if (crtat >= Crtat+COL*(ROW)) { /* scroll check */ 581 if (openf) do sgetc(1); while (scroll); 582 bcopy(Crtat+COL,Crtat,COL*(ROW-1)*CHR); 583 fillw ((bg_at<<8) + ' ', Crtat+COL*(ROW-1),COL) ; 584 crtat -= COL ; 585 } 586 } 587 588 #define L 0x0001 /* locking function */ 589 #define SHF 0x0002 /* keyboard shift */ 590 #define ALT 0x0004 /* alternate shift -- alternate chars */ 591 #define NUM 0x0008 /* numeric shift cursors vs. numeric */ 592 #define CTL 0x0010 /* control shift -- allows ctl function */ 593 #define CPS 0x0020 /* caps shift -- swaps case of letter */ 594 #define ASCII 0x0040 /* ascii code for this key */ 595 #define STP 0x0080 /* stop output */ 596 #define FUNC 0x0100 /* function key */ 597 #define SCROLL 0x0200 /* scroll lock key */ 598 599 unsigned __debug = 0; /*0xffe */; 600 u_short action[] = { 601 0, ASCII, ASCII, ASCII, ASCII, ASCII, ASCII, ASCII, /* scan 0- 7 */ 602 ASCII, ASCII, ASCII, ASCII, ASCII, ASCII, ASCII, ASCII, /* scan 8-15 */ 603 ASCII, ASCII, ASCII, ASCII, ASCII, ASCII, ASCII, ASCII, /* scan 16-23 */ 604 ASCII, ASCII, ASCII, ASCII, ASCII, CTL, ASCII, ASCII, /* scan 24-31 */ 605 ASCII, ASCII, ASCII, ASCII, ASCII, ASCII, ASCII, ASCII, /* scan 32-39 */ 606 ASCII, ASCII, SHF , ASCII, ASCII, ASCII, ASCII, ASCII, /* scan 40-47 */ 607 ASCII, ASCII, ASCII, ASCII, ASCII, ASCII, SHF, ASCII, /* scan 48-55 */ 608 ALT, ASCII, CPS , FUNC , FUNC , FUNC , FUNC , FUNC , /* scan 56-63 */ 609 FUNC , FUNC , FUNC , FUNC , FUNC , NUM, SCROLL, ASCII, /* scan 64-71 */ 610 ASCII, ASCII, ASCII, ASCII, ASCII, ASCII, ASCII, ASCII, /* scan 72-79 */ 611 ASCII, ASCII, ASCII, ASCII, 0, 0, 0, 0, /* scan 80-87 */ 612 0,0,0,0,0,0,0,0, 613 0,0,0,0,0,0,0,0, 0,0,0,0,0,0,0,0, 614 0,0,0,0,0,0,0,0, 0,0,0,0,0,0,0,0, } ; 615 616 u_char unshift[] = { /* no shift */ 617 0, 033 , '1' , '2' , '3' , '4' , '5' , '6' , /* scan 0- 7 */ 618 '7' , '8' , '9' , '0' , '-' , '=' , 0177 ,'\t' , /* scan 8-15 */ 619 620 'q' , 'w' , 'e' , 'r' , 't' , 'y' , 'u' , 'i' , /* scan 16-23 */ 621 'o' , 'p' , '[' , ']' , '\r' , CTL , 'a' , 's' , /* scan 24-31 */ 622 623 'd' , 'f' , 'g' , 'h' , 'j' , 'k' , 'l' , ';' , /* scan 32-39 */ 624 '\'' , '`' , SHF , '\\' , 'z' , 'x' , 'c' , 'v' , /* scan 40-47 */ 625 626 'b' , 'n' , 'm' , ',' , '.' , '/' , SHF , '*', /* scan 48-55 */ 627 ALT , ' ' , CPS, 1, 2, 3 , 4, 5, /* scan 56-63 */ 628 629 6, 7, 8, 9, 10, NUM, STP, '7', /* scan 64-71 */ 630 '8', '9', '-', '4', '5', '6', '+', '1', /* scan 72-79 */ 631 632 '2', '3', '0', '.', 0, 0, 0, 0, /* scan 80-87 */ 633 0,0,0,0,0,0,0,0, 634 0,0,0,0,0,0,0,0, 0,0,0,0,0,0,0,0, 635 0,0,0,0,0,0,0,0, 0,0,0,0,0,0,0,0, } ; 636 637 u_char shift[] = { /* shift shift */ 638 0, 033 , '!' , '@' , '#' , '$' , '%' , '^' , /* scan 0- 7 */ 639 '&' , '*' , '(' , ')' , '_' , '+' , 0177 ,'\t' , /* scan 8-15 */ 640 'Q' , 'W' , 'E' , 'R' , 'T' , 'Y' , 'U' , 'I' , /* scan 16-23 */ 641 'O' , 'P' , '{' , '}' , '\r' , CTL , 'A' , 'S' , /* scan 24-31 */ 642 'D' , 'F' , 'G' , 'H' , 'J' , 'K' , 'L' , ':' , /* scan 32-39 */ 643 '"' , '~' , SHF , '|' , 'Z' , 'X' , 'C' , 'V' , /* scan 40-47 */ 644 'B' , 'N' , 'M' , '<' , '>' , '?' , SHF , '*', /* scan 48-55 */ 645 ALT , ' ' , CPS, 0, 0, ' ' , 0, 0, /* scan 56-63 */ 646 0, 0, 0, 0, 0, NUM, STP, '7', /* scan 64-71 */ 647 '8', '9', '-', '4', '5', '6', '+', '1', /* scan 72-79 */ 648 '2', '3', '0', '.', 0, 0, 0, 0, /* scan 80-87 */ 649 0,0,0,0,0,0,0,0, 650 0,0,0,0,0,0,0,0, 0,0,0,0,0,0,0,0, 651 0,0,0,0,0,0,0,0, 0,0,0,0,0,0,0,0, } ; 652 653 u_char ctl[] = { /* CTL shift */ 654 0, 033 , '!' , 000 , '#' , '$' , '%' , 036 , /* scan 0- 7 */ 655 '&' , '*' , '(' , ')' , 037 , '+' , 034 ,'\177', /* scan 8-15 */ 656 021 , 027 , 005 , 022 , 024 , 031 , 025 , 011 , /* scan 16-23 */ 657 017 , 020 , 033 , 035 , '\r' , CTL , 001 , 023 , /* scan 24-31 */ 658 004 , 006 , 007 , 010 , 012 , 013 , 014 , ';' , /* scan 32-39 */ 659 '\'' , '`' , SHF , 034 , 032 , 030 , 003 , 026 , /* scan 40-47 */ 660 002 , 016 , 015 , '<' , '>' , '?' , SHF , '*', /* scan 48-55 */ 661 ALT , ' ' , CPS, 0, 0, ' ' , 0, 0, /* scan 56-63 */ 662 CPS, 0, 0, 0, 0, 0, 0, 0, /* scan 64-71 */ 663 0, 0, 0, 0, 0, 0, 0, 0, /* scan 72-79 */ 664 0, 0, 0, 0, 0, 0, 0, 0, /* scan 80-87 */ 665 0, 0, 033, '7' , '4' , '1' , 0, NUM, /* scan 88-95 */ 666 '8' , '5' , '2' , 0, STP, '9' , '6' , '3' , /*scan 96-103*/ 667 '.' , 0, '*' , '-' , '+' , 0, 0, 0, /*scan 104-111*/ 668 0,0,0,0,0,0,0,0, 0,0,0,0,0,0,0,0, } ; 669 670 #ifdef notdef 671 struct key { 672 u_short action; /* how this key functions */ 673 char ascii[8]; /* ascii result character indexed by shifts */ 674 }; 675 #endif 676 677 678 #define KBSTAT 0x64 /* kbd status port */ 679 #define KBS_INP_BUF_FUL 0x02 /* kbd char ready */ 680 #define KBDATA 0x60 /* kbd data port */ 681 #define KBSTATUSPORT 0x61 /* kbd status */ 682 683 update_led() 684 { 685 while (inb(0x64)&2); /* wait input ready */ 686 outb(0x60,0xED); /* LED Command */ 687 while (inb(0x64)&2); /* wait input ready */ 688 outb(0x60,scroll | 2*num | 4*caps); 689 } 690 691 reset_cpu() { 692 while(1) { 693 while (inb(0x64)&2); /* wait input ready */ 694 outb(0x64,0xFE); /* Reset Command */ 695 DELAY(4000000); 696 while (inb(0x64)&2); /* wait input ready */ 697 outb(0x64,0xFF); /* Keyboard Reset Command */ 698 } 699 /* NOTREACHED */ 700 } 701 702 /* 703 sgetc(noblock) : get a character from the keyboard. If noblock = 0 wait until 704 a key is gotten. Otherwise return a 0x100 (256). 705 */ 706 int sgetc(noblock) 707 { 708 u_char dt; unsigned key; 709 loop: 710 /* First see if there is something in the keyboard port */ 711 if (inb(KBSTAT)&1) dt = inb(KBDATA); 712 else { if (noblock) return (0x100); else goto loop; } 713 714 /* Check for cntl-alt-del */ 715 if ((dt == 83)&&ctls&&alts) _exit(); 716 717 /* Check for make/break */ 718 if (dt & 0x80) { 719 /* break */ 720 dt = dt & 0x7f ; 721 switch (action[dt]) { 722 case SHF: shfts = 0; break; 723 case ALT: alts = 0; break; 724 case CTL: ctls = 0; break; 725 case FUNC: 726 /* Toggle debug flags */ 727 key = unshift[dt]; 728 if(__debug & (1<<key)) __debug &= ~(1<<key) ; 729 else __debug |= (1<<key) ; 730 break; 731 } 732 } else { 733 /* make */ 734 dt = dt & 0x7f ; 735 switch (action[dt]) { 736 /* LOCKING KEYS */ 737 case NUM: num ^= 1; update_led(); break; 738 case CPS: caps ^= 1; update_led(); break; 739 case SCROLL: scroll ^= 1; update_led(); break; 740 case STP: stp ^= 1; if(stp) goto loop; break; 741 742 /* NON-LOCKING KEYS */ 743 case SHF: shfts = 1; break; 744 case ALT: alts = 1; break; 745 case CTL: ctls = 1; break; 746 case ASCII: 747 if (shfts) dt = shift[dt]; 748 else if (ctls) dt = ctl[dt]; 749 else dt = unshift[dt]; 750 if (caps && (dt >= 'a' && dt <= 'z')) dt -= 'a' - 'A'; 751 return(dt); 752 } 753 } 754 if (noblock) return (0x100); else goto loop; 755 } 756 757 pg(p,q,r,s,t,u,v,w,x,y,z) char *p; { 758 printf(p,q,r,s,t,u,v,w,x,y,z); 759 printf("\n"); 760 return(getchar()); 761 } 762 763 /* special characters */ 764 #define bs 8 765 #define lf 10 766 #define cr 13 767 #define cntlc 3 768 #define del 0177 769 #define cntld 4 770 771 getchar() 772 { 773 register char thechar; 774 register delay; 775 int x; 776 777 pcconsoftc.cs_flags |= CSF_POLLING; 778 x=splhigh(); 779 sput('>',0x6); 780 /*while (1) {*/ 781 thechar = (char) sgetc(0); 782 pcconsoftc.cs_flags &= ~CSF_POLLING; 783 splx(x); 784 switch (thechar) { 785 default: if (thechar >= ' ') 786 sput(thechar,0x6); 787 return(thechar); 788 case cr: 789 case lf: sput(cr,0x6); 790 sput(lf,0x6); 791 return(lf); 792 case bs: 793 case del: 794 sput(bs,0x6); 795 sput(' ',0x6); 796 sput(bs,0x6); 797 return(thechar); 798 /*case cntlc: 799 sput('^',0xe) ; sput('C',0xe) ; sput('\r',0xe) ; sput('\n',0xe) ; 800 _exit(-2) ; */ 801 case cntld: 802 sput('^',0x6) ; sput('D',0x6) ; sput('\r',0x6) ; sput('\n',0x6) ; 803 return(0); 804 } 805 /*}*/ 806 } 807 808 #include "machine/dbg.h" 809 #include "machine/stdarg.h" 810 static nrow; 811 812 void 813 #ifdef __STDC__ 814 dprintf(unsigned flgs, const char *fmt, ...) 815 #else 816 dprintf(flgs, fmt /*, va_alist */) 817 char *fmt; 818 unsigned flgs; 819 #endif 820 { extern unsigned __debug; 821 va_list ap; 822 823 if((flgs&__debug) > DPAUSE) { 824 __color = ffs(flgs&__debug)+1; 825 va_start(ap,fmt); 826 kprintf(fmt, 1, (struct tty *)0, ap); 827 va_end(ap); 828 if (flgs&DPAUSE || nrow%24 == 23) { 829 int x; 830 x = splhigh(); 831 if (nrow%24 == 23) nrow = 0; 832 sgetc(0); 833 splx(x); 834 } 835 } 836 __color = 0; 837 } 838 839 consinit() {} 840