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