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