1 /* 2 * Copyright (c) 1988 University of Utah. 3 * Copyright (c) 1990 The Regents of the University of California. 4 * All rights reserved. 5 * 6 * This code is derived from software contributed to Berkeley by 7 * the Systems Programming Group of the University of Utah Computer 8 * Science Department. 9 * 10 * %sccs.include.redist.c% 11 * 12 * from: Utah $Hdr: ite.c 1.22 89/08/17$ 13 * 14 * @(#)ite.c 7.2 (Berkeley) 06/22/90 15 */ 16 17 /* 18 * Bit-mapped display terminal emulator machine independent code. 19 * This is a very rudimentary. Much more can be abstracted out of 20 * the hardware dependent routines. 21 */ 22 #include "ite.h" 23 #if NITE > 0 24 25 #include "grf.h" 26 27 #undef NITE 28 #define NITE NGRF 29 30 #include "param.h" 31 #include "conf.h" 32 #include "user.h" 33 #include "proc.h" 34 #include "ioctl.h" 35 #include "tty.h" 36 #include "systm.h" 37 #include "uio.h" 38 #include "malloc.h" 39 40 #include "itevar.h" 41 #include "iteioctl.h" 42 #include "kbdmap.h" 43 44 #include "machine/cpu.h" 45 46 #define set_attr(ip, attr) ((ip)->attribute |= (attr)) 47 #define clr_attr(ip, attr) ((ip)->attribute &= ~(attr)) 48 49 extern int nodev(); 50 51 int topcat_scroll(), topcat_init(), topcat_deinit(); 52 int topcat_clear(), topcat_putc(), topcat_cursor(); 53 int gatorbox_scroll(), gatorbox_init(), gatorbox_deinit(); 54 int gatorbox_clear(), gatorbox_putc(), gatorbox_cursor(); 55 int rbox_scroll(), rbox_init(), rbox_deinit(); 56 int rbox_clear(), rbox_putc(), rbox_cursor(); 57 int dvbox_scroll(), dvbox_init(), dvbox_deinit(); 58 int dvbox_clear(), dvbox_putc(), dvbox_cursor(); 59 60 struct itesw itesw[] = 61 { 62 topcat_init, topcat_deinit, topcat_clear, 63 topcat_putc, topcat_cursor, topcat_scroll, 64 65 gatorbox_init, gatorbox_deinit, gatorbox_clear, 66 gatorbox_putc, gatorbox_cursor, gatorbox_scroll, 67 68 rbox_init, rbox_deinit, rbox_clear, 69 rbox_putc, rbox_cursor, rbox_scroll, 70 71 dvbox_init, dvbox_deinit, dvbox_clear, 72 dvbox_putc, dvbox_cursor, dvbox_scroll, 73 }; 74 75 /* 76 * # of chars are output in a single itestart() call. 77 * If this is too big, user processes will be blocked out for 78 * long periods of time while we are emptying the queue in itestart(). 79 * If it is too small, console output will be very ragged. 80 */ 81 int iteburst = 64; 82 83 int nite = NITE; 84 struct tty *kbd_tty = NULL; 85 struct tty ite_tty[NITE]; 86 struct ite_softc ite_softc[NITE]; 87 88 int itestart(); 89 extern int ttrstrt(); 90 extern struct tty *constty; 91 92 /* 93 * Primary attribute buffer to be used by the first bitmapped console 94 * found. Secondary displays alloc the attribute buffer as needed. 95 * Size is based on a 68x128 display, which is currently our largest. 96 */ 97 u_char console_attributes[0x2200]; 98 99 /* 100 * Perform functions necessary to setup device as a terminal emulator. 101 */ 102 iteon(dev, flag) 103 dev_t dev; 104 { 105 int unit = UNIT(dev); 106 struct tty *tp = &ite_tty[unit]; 107 struct ite_softc *ip = &ite_softc[unit]; 108 109 if (unit < 0 || unit >= NITE || (ip->flags&ITE_ALIVE) == 0) 110 return(ENXIO); 111 /* force ite active, overriding graphics mode */ 112 if (flag & 1) { 113 ip->flags |= ITE_ACTIVE; 114 ip->flags &= ~(ITE_INGRF|ITE_INITED); 115 } 116 /* leave graphics mode */ 117 if (flag & 2) { 118 ip->flags &= ~ITE_INGRF; 119 if ((ip->flags & ITE_ACTIVE) == 0) 120 return(0); 121 } 122 ip->flags |= ITE_ACTIVE; 123 if (ip->flags & ITE_INGRF) 124 return(0); 125 if (kbd_tty == NULL || kbd_tty == tp) { 126 kbd_tty = tp; 127 kbdenable(); 128 } 129 iteinit(dev); 130 return(0); 131 } 132 133 iteinit(dev) 134 dev_t dev; 135 { 136 int unit = UNIT(dev); 137 struct ite_softc *ip = &ite_softc[unit]; 138 139 if (ip->flags & ITE_INITED) 140 return; 141 142 ip->curx = 0; 143 ip->cury = 0; 144 ip->cursorx = 0; 145 ip->cursory = 0; 146 147 (*itesw[ip->type].ite_init)(ip); 148 (*itesw[ip->type].ite_cursor)(ip, DRAW_CURSOR); 149 150 ip->attribute = 0; 151 if (ip->attrbuf == NULL) 152 ip->attrbuf = (u_char *) 153 malloc(ip->rows * ip->cols, M_DEVBUF, M_WAITOK); 154 bzero(ip->attrbuf, (ip->rows * ip->cols)); 155 156 ip->imode = 0; 157 ip->flags |= ITE_INITED; 158 } 159 160 /* 161 * "Shut down" device as terminal emulator. 162 * Note that we do not deinit the console device unless forced. 163 * Deinit'ing the console every time leads to a very active 164 * screen when processing /etc/rc. 165 */ 166 iteoff(dev, flag) 167 dev_t dev; 168 { 169 register struct ite_softc *ip = &ite_softc[UNIT(dev)]; 170 171 if (flag & 2) 172 ip->flags |= ITE_INGRF; 173 if ((ip->flags & ITE_ACTIVE) == 0) 174 return; 175 if ((flag & 1) || 176 (ip->flags & (ITE_INGRF|ITE_ISCONS|ITE_INITED)) == ITE_INITED) 177 (*itesw[ip->type].ite_deinit)(ip); 178 if ((flag & 2) == 0) 179 ip->flags &= ~ITE_ACTIVE; 180 } 181 182 /*ARGSUSED*/ 183 iteopen(dev, flag) 184 dev_t dev; 185 { 186 int unit = UNIT(dev); 187 register struct tty *tp = &ite_tty[unit]; 188 register struct ite_softc *ip = &ite_softc[unit]; 189 register int error; 190 int first = 0; 191 192 if ((tp->t_state&(TS_ISOPEN|TS_XCLUDE)) == (TS_ISOPEN|TS_XCLUDE) 193 && u.u_uid != 0) 194 return (EBUSY); 195 if ((ip->flags & ITE_ACTIVE) == 0) { 196 error = iteon(dev, 0); 197 if (error) 198 return (error); 199 first = 1; 200 } 201 tp->t_oproc = itestart; 202 tp->t_param = NULL; 203 tp->t_dev = dev; 204 if ((tp->t_state&TS_ISOPEN) == 0) { 205 ttychars(tp); 206 tp->t_iflag = TTYDEF_IFLAG; 207 tp->t_oflag = TTYDEF_OFLAG; 208 tp->t_cflag = CS8|CREAD; 209 tp->t_lflag = TTYDEF_LFLAG; 210 tp->t_ispeed = tp->t_ospeed = TTYDEF_SPEED; 211 tp->t_state = TS_ISOPEN|TS_CARR_ON; 212 ttsetwater(tp); 213 } 214 error = (*linesw[tp->t_line].l_open)(dev, tp); 215 if (error == 0) { 216 tp->t_winsize.ws_row = ip->rows; 217 tp->t_winsize.ws_col = ip->cols; 218 } else if (first) 219 iteoff(dev, 0); 220 return (error); 221 } 222 223 /*ARGSUSED*/ 224 iteclose(dev, flag) 225 dev_t dev; 226 { 227 register struct tty *tp = &ite_tty[UNIT(dev)]; 228 229 (*linesw[tp->t_line].l_close)(tp); 230 ttyclose(tp); 231 iteoff(dev, 0); 232 return(0); 233 } 234 235 iteread(dev, uio, flag) 236 dev_t dev; 237 struct uio *uio; 238 { 239 register struct tty *tp = &ite_tty[UNIT(dev)]; 240 241 return ((*linesw[tp->t_line].l_read)(tp, uio, flag)); 242 } 243 244 itewrite(dev, uio, flag) 245 dev_t dev; 246 struct uio *uio; 247 { 248 int unit = UNIT(dev); 249 register struct tty *tp = &ite_tty[unit]; 250 251 if ((ite_softc[unit].flags & ITE_ISCONS) && constty && 252 (constty->t_state&(TS_CARR_ON|TS_ISOPEN))==(TS_CARR_ON|TS_ISOPEN)) 253 tp = constty; 254 return ((*linesw[tp->t_line].l_write)(tp, uio, flag)); 255 } 256 257 iteioctl(dev, cmd, addr, flag) 258 dev_t dev; 259 caddr_t addr; 260 { 261 register struct tty *tp = &ite_tty[UNIT(dev)]; 262 int error; 263 264 error = (*linesw[tp->t_line].l_ioctl)(tp, cmd, addr, flag); 265 if (error >= 0) 266 return (error); 267 error = ttioctl(tp, cmd, addr, flag); 268 if (error >= 0) 269 return (error); 270 return (ENOTTY); 271 } 272 273 itestart(tp) 274 register struct tty *tp; 275 { 276 register int cc, s; 277 int hiwat = 0; 278 279 s = spltty(); 280 if (tp->t_state & (TS_TIMEOUT|TS_BUSY|TS_TTSTOP)) { 281 splx(s); 282 return; 283 } 284 tp->t_state |= TS_BUSY; 285 cc = tp->t_outq.c_cc; 286 if (cc <= tp->t_lowat) { 287 if (tp->t_state & TS_ASLEEP) { 288 tp->t_state &= ~TS_ASLEEP; 289 wakeup(&tp->t_outq); 290 } 291 if (tp->t_wsel) { 292 selwakeup(tp->t_wsel, tp->t_state & TS_WCOLL); 293 tp->t_wsel = 0; 294 tp->t_state &= ~TS_WCOLL; 295 } 296 } 297 /* 298 * Limit the amount of output we do in one burst 299 * to prevent hogging the CPU. 300 */ 301 if (cc > iteburst) { 302 hiwat++; 303 cc = iteburst; 304 } 305 while (--cc >= 0) { 306 register int c; 307 308 c = getc(&tp->t_outq); 309 /* 310 * iteputchar() may take a long time and we don't want to 311 * block all interrupts for long periods of time. Since 312 * there is no need to stay at high priority while outputing 313 * the character (since we don't have to worry about 314 * interrupts), we don't. We just need to make sure that 315 * we don't reenter iteputchar, which is guarenteed by the 316 * earlier setting of TS_BUSY. 317 */ 318 splx(s); 319 iteputchar(c, tp->t_dev); 320 spltty(); 321 } 322 if (hiwat) { 323 tp->t_state |= TS_TIMEOUT; 324 timeout(ttrstrt, tp, 1); 325 } 326 tp->t_state &= ~TS_BUSY; 327 splx(s); 328 } 329 330 itefilter(stat, c) 331 register char stat, c; 332 { 333 static int capsmode = 0; 334 static int metamode = 0; 335 register char code, *str; 336 337 if (kbd_tty == NULL) 338 return; 339 340 switch (c & 0xFF) { 341 case KBD_CAPSLOCK: 342 capsmode = !capsmode; 343 return; 344 345 case KBD_EXT_LEFT_DOWN: 346 case KBD_EXT_RIGHT_DOWN: 347 metamode = 1; 348 return; 349 350 case KBD_EXT_LEFT_UP: 351 case KBD_EXT_RIGHT_UP: 352 metamode = 0; 353 return; 354 } 355 356 c &= KBD_CHARMASK; 357 switch ((stat>>KBD_SSHIFT) & KBD_SMASK) { 358 359 case KBD_KEY: 360 if (!capsmode) { 361 code = kbd_keymap[c]; 362 break; 363 } 364 /* fall into... */ 365 366 case KBD_SHIFT: 367 code = kbd_shiftmap[c]; 368 break; 369 370 case KBD_CTRL: 371 code = kbd_ctrlmap[c]; 372 break; 373 374 case KBD_CTRLSHIFT: 375 code = kbd_ctrlshiftmap[c]; 376 break; 377 } 378 379 if (code == NULL && (str = kbd_stringmap[c]) != NULL) { 380 while (*str) 381 (*linesw[kbd_tty->t_line].l_rint)(*str++, kbd_tty); 382 } else { 383 if (metamode) 384 code |= 0x80; 385 (*linesw[kbd_tty->t_line].l_rint)(code, kbd_tty); 386 } 387 } 388 389 iteputchar(c, dev) 390 register int c; 391 dev_t dev; 392 { 393 int unit = UNIT(dev); 394 register struct ite_softc *ip = &ite_softc[unit]; 395 register struct itesw *sp = &itesw[ip->type]; 396 register int n; 397 398 if ((ip->flags & (ITE_ACTIVE|ITE_INGRF)) != ITE_ACTIVE) 399 return; 400 401 if (ip->escape) { 402 doesc: 403 switch (ip->escape) { 404 405 case '&': /* Next can be a,d, or s */ 406 if (ip->fpd++) { 407 ip->escape = c; 408 ip->fpd = 0; 409 } 410 return; 411 412 case 'a': /* cursor change */ 413 switch (c) { 414 415 case 'Y': /* Only y coord. */ 416 ip->cury = MIN(ip->pos, ip->rows-1); 417 ip->pos = 0; 418 ip->escape = 0; 419 (*sp->ite_cursor)(ip, MOVE_CURSOR); 420 clr_attr(ip, ATTR_INV); 421 break; 422 423 case 'y': /* y coord first */ 424 ip->cury = MIN(ip->pos, ip->rows-1); 425 ip->pos = 0; 426 ip->fpd = 0; 427 break; 428 429 case 'C': /* x coord */ 430 ip->curx = MIN(ip->pos, ip->cols-1); 431 ip->pos = 0; 432 ip->escape = 0; 433 (*sp->ite_cursor)(ip, MOVE_CURSOR); 434 clr_attr(ip, ATTR_INV); 435 break; 436 437 default: /* Possibly a 3 digit number. */ 438 if (c >= '0' && c <= '9' && ip->fpd < 3) { 439 ip->pos = ip->pos * 10 + (c - '0'); 440 ip->fpd++; 441 } else { 442 ip->pos = 0; 443 ip->escape = 0; 444 } 445 break; 446 } 447 return; 448 449 case 'd': /* attribute change */ 450 switch (c) { 451 452 case 'B': 453 set_attr(ip, ATTR_INV); 454 break; 455 case 'D': 456 /* XXX: we don't do anything for underline */ 457 set_attr(ip, ATTR_UL); 458 break; 459 case '@': 460 clr_attr(ip, ATTR_ALL); 461 break; 462 } 463 ip->escape = 0; 464 return; 465 466 case 's': /* keypad control */ 467 switch (ip->fpd) { 468 469 case 0: 470 ip->hold = c; 471 ip->fpd++; 472 return; 473 474 case 1: 475 if (c == 'A') { 476 switch (ip->hold) { 477 478 case '0': 479 clr_attr(ip, ATTR_KPAD); 480 break; 481 case '1': 482 set_attr(ip, ATTR_KPAD); 483 break; 484 } 485 } 486 ip->hold = 0; 487 } 488 ip->escape = 0; 489 return; 490 491 case 'i': /* back tab */ 492 if (ip->curx > TABSIZE) { 493 n = ip->curx - (ip->curx & (TABSIZE - 1)); 494 ip->curx -= n; 495 } else 496 ip->curx = 0; 497 (*sp->ite_cursor)(ip, MOVE_CURSOR); 498 ip->escape = 0; 499 return; 500 501 case '3': /* clear all tabs */ 502 goto ignore; 503 504 case 'K': /* clear_eol */ 505 ite_clrtoeol(ip, sp, ip->cury, ip->curx); 506 ip->escape = 0; 507 return; 508 509 case 'J': /* clear_eos */ 510 ite_clrtoeos(ip, sp); 511 ip->escape = 0; 512 return; 513 514 case 'B': /* cursor down 1 line */ 515 if (++ip->cury == ip->rows) { 516 --ip->cury; 517 (*sp->ite_scroll)(ip, 1, 0, 1, SCROLL_UP); 518 ite_clrtoeol(ip, sp, ip->cury, 0); 519 } 520 else 521 (*sp->ite_cursor)(ip, MOVE_CURSOR); 522 clr_attr(ip, ATTR_INV); 523 ip->escape = 0; 524 return; 525 526 case 'C': /* cursor forward 1 char */ 527 ip->escape = 0; 528 itecheckwrap(ip, sp); 529 return; 530 531 case 'A': /* cursor up 1 line */ 532 if (ip->cury > 0) { 533 ip->cury--; 534 (*sp->ite_cursor)(ip, MOVE_CURSOR); 535 } 536 ip->escape = 0; 537 clr_attr(ip, ATTR_INV); 538 return; 539 540 case 'P': /* delete character */ 541 ite_dchar(ip, sp); 542 ip->escape = 0; 543 return; 544 545 case 'M': /* delete line */ 546 ite_dline(ip, sp); 547 ip->escape = 0; 548 return; 549 550 case 'Q': /* enter insert mode */ 551 ip->imode = 1; 552 ip->escape = 0; 553 return; 554 555 case 'R': /* exit insert mode */ 556 ip->imode = 0; 557 ip->escape = 0; 558 return; 559 560 case 'L': /* insert blank line */ 561 ite_iline(ip, sp); 562 ip->escape = 0; 563 return; 564 565 case 'h': /* home key */ 566 ip->cury = ip->curx = 0; 567 (*sp->ite_cursor)(ip, MOVE_CURSOR); 568 ip->escape = 0; 569 return; 570 571 case 'D': /* left arrow key */ 572 if (ip->curx > 0) { 573 ip->curx--; 574 (*sp->ite_cursor)(ip, MOVE_CURSOR); 575 } 576 ip->escape = 0; 577 return; 578 579 case '1': /* set tab in all rows */ 580 goto ignore; 581 582 case ESC: 583 if ((ip->escape = c) == ESC) 584 break; 585 ip->fpd = 0; 586 goto doesc; 587 588 default: 589 ignore: 590 ip->escape = 0; 591 return; 592 593 } 594 } 595 596 switch (c &= 0x7F) { 597 598 case '\n': 599 600 if (++ip->cury == ip->rows) { 601 --ip->cury; 602 (*sp->ite_scroll)(ip, 1, 0, 1, SCROLL_UP); 603 ite_clrtoeol(ip, sp, ip->cury, 0); 604 } 605 else 606 (*sp->ite_cursor)(ip, MOVE_CURSOR); 607 clr_attr(ip, ATTR_INV); 608 break; 609 610 case '\r': 611 if (ip->curx) { 612 ip->curx = 0; 613 (*sp->ite_cursor)(ip, MOVE_CURSOR); 614 } 615 break; 616 617 case '\b': 618 if (--ip->curx < 0) 619 ip->curx = 0; 620 else 621 (*sp->ite_cursor)(ip, MOVE_CURSOR); 622 break; 623 624 case '\t': 625 if (ip->curx < TABEND(unit)) { 626 n = TABSIZE - (ip->curx & (TABSIZE - 1)); 627 ip->curx += n; 628 (*sp->ite_cursor)(ip, MOVE_CURSOR); 629 } else 630 itecheckwrap(ip, sp); 631 break; 632 633 case CTRL('G'): 634 if (&ite_tty[unit] == kbd_tty) 635 kbdbell(); 636 break; 637 638 case ESC: 639 ip->escape = ESC; 640 break; 641 642 default: 643 if (c < ' ' || c == DEL) 644 break; 645 if (ip->imode) 646 ite_ichar(ip, sp); 647 if ((ip->attribute & ATTR_INV) || attrtest(ip, ATTR_INV)) { 648 attrset(ip, ATTR_INV); 649 (*sp->ite_putc)(ip, c, ip->cury, ip->curx, ATTR_INV); 650 } 651 else 652 (*sp->ite_putc)(ip, c, ip->cury, ip->curx, ATTR_NOR); 653 (*sp->ite_cursor)(ip, DRAW_CURSOR); 654 itecheckwrap(ip, sp); 655 break; 656 } 657 } 658 659 itecheckwrap(ip, sp) 660 register struct ite_softc *ip; 661 register struct itesw *sp; 662 { 663 if (++ip->curx == ip->cols) { 664 ip->curx = 0; 665 clr_attr(ip, ATTR_INV); 666 if (++ip->cury == ip->rows) { 667 --ip->cury; 668 (*sp->ite_scroll)(ip, 1, 0, 1, SCROLL_UP); 669 ite_clrtoeol(ip, sp, ip->cury, 0); 670 return; 671 } 672 } 673 (*sp->ite_cursor)(ip, MOVE_CURSOR); 674 } 675 676 ite_dchar(ip, sp) 677 register struct ite_softc *ip; 678 register struct itesw *sp; 679 { 680 (*sp->ite_scroll)(ip, ip->cury, ip->curx + 1, 1, SCROLL_LEFT); 681 attrmov(ip, ip->cury, ip->curx + 1, ip->cury, ip->curx, 682 1, ip->cols - ip->curx - 1); 683 attrclr(ip, ip->cury, ip->cols - 1, 1, 1); 684 (*sp->ite_putc)(ip, ' ', ip->cury, ip->cols - 1, ATTR_NOR); 685 (*sp->ite_cursor)(ip, DRAW_CURSOR); 686 } 687 688 ite_ichar(ip, sp) 689 register struct ite_softc *ip; 690 register struct itesw *sp; 691 { 692 (*sp->ite_scroll)(ip, ip->cury, ip->curx, 1, SCROLL_RIGHT); 693 attrmov(ip, ip->cury, ip->curx, ip->cury, ip->curx + 1, 694 1, ip->cols - ip->curx - 1); 695 attrclr(ip, ip->cury, ip->curx, 1, 1); 696 (*sp->ite_putc)(ip, ' ', ip->cury, ip->curx, ATTR_NOR); 697 (*sp->ite_cursor)(ip, DRAW_CURSOR); 698 } 699 700 ite_dline(ip, sp) 701 register struct ite_softc *ip; 702 register struct itesw *sp; 703 { 704 (*sp->ite_scroll)(ip, ip->cury + 1, 0, 1, SCROLL_UP); 705 attrmov(ip, ip->cury + 1, 0, ip->cury, 0, 706 ip->rows - ip->cury - 1, ip->cols); 707 ite_clrtoeol(ip, sp, ip->rows - 1, 0); 708 } 709 710 ite_iline(ip, sp) 711 register struct ite_softc *ip; 712 register struct itesw *sp; 713 { 714 (*sp->ite_scroll)(ip, ip->cury, 0, 1, SCROLL_DOWN); 715 attrmov(ip, ip->cury, 0, ip->cury + 1, 0, 716 ip->rows - ip->cury - 1, ip->cols); 717 ite_clrtoeol(ip, sp, ip->cury, 0); 718 } 719 720 ite_clrtoeol(ip, sp, y, x) 721 register struct ite_softc *ip; 722 register struct itesw *sp; 723 register int y, x; 724 { 725 (*sp->ite_clear)(ip, y, x, 1, ip->cols - x); 726 attrclr(ip, y, x, 1, ip->cols - x); 727 (*sp->ite_cursor)(ip, DRAW_CURSOR); 728 } 729 730 ite_clrtoeos(ip, sp) 731 register struct ite_softc *ip; 732 register struct itesw *sp; 733 { 734 (*sp->ite_clear)(ip, ip->cury, 0, ip->rows - ip->cury, ip->cols); 735 attrclr(ip, ip->cury, 0, ip->rows - ip->cury, ip->cols); 736 (*sp->ite_cursor)(ip, DRAW_CURSOR); 737 } 738 739 /* 740 * Console functions 741 */ 742 #include "machine/cons.h" 743 #include "grfioctl.h" 744 #include "grfvar.h" 745 746 #ifdef DEBUG 747 /* 748 * Minimum ITE number at which to start looking for a console. 749 * Setting to 0 will do normal search, 1 will skip first ITE device, 750 * NITE will skip ITEs and use serial port. 751 */ 752 int whichconsole = 0; 753 #endif 754 755 itecnprobe(cp) 756 struct consdev *cp; 757 { 758 register struct ite_softc *ip; 759 int i, maj, unit, pri; 760 extern int iteopen(); 761 762 /* locate the major number */ 763 for (maj = 0; maj < nchrdev; maj++) 764 if (cdevsw[maj].d_open == iteopen) 765 break; 766 767 /* urk! */ 768 grfconfig(); 769 770 /* check all the individual displays and find the best */ 771 unit = -1; 772 pri = CN_DEAD; 773 for (i = 0; i < NITE; i++) { 774 struct grf_softc *gp = &grf_softc[i]; 775 776 ip = &ite_softc[i]; 777 if ((gp->g_flags & GF_ALIVE) == 0) 778 continue; 779 ip->flags = (ITE_ALIVE|ITE_CONSOLE); 780 781 /* XXX - we need to do something about mapping these */ 782 switch (gp->g_type) { 783 784 case GT_TOPCAT: 785 case GT_LRCATSEYE: 786 case GT_HRCCATSEYE: 787 case GT_HRMCATSEYE: 788 ip->type = ITE_TOPCAT; 789 break; 790 case GT_GATORBOX: 791 ip->type = ITE_GATORBOX; 792 break; 793 case GT_RENAISSANCE: 794 ip->type = ITE_RENAISSANCE; 795 break; 796 case GT_DAVINCI: 797 ip->type = ITE_DAVINCI; 798 break; 799 } 800 #ifdef DEBUG 801 if (i < whichconsole) 802 continue; 803 #endif 804 if ((int)gp->g_display.gd_regaddr == GRFIADDR) { 805 pri = CN_INTERNAL; 806 unit = i; 807 } else if (unit < 0) { 808 pri = CN_NORMAL; 809 unit = i; 810 } 811 } 812 813 /* initialize required fields */ 814 cp->cn_dev = makedev(maj, unit); 815 cp->cn_tp = &ite_tty[unit]; 816 cp->cn_pri = pri; 817 } 818 819 itecninit(cp) 820 struct consdev *cp; 821 { 822 int unit = UNIT(cp->cn_dev); 823 struct ite_softc *ip = &ite_softc[unit]; 824 825 ip->attrbuf = console_attributes; 826 iteinit(cp->cn_dev); 827 ip->flags |= (ITE_ACTIVE|ITE_ISCONS); 828 kbd_tty = &ite_tty[unit]; 829 } 830 831 /*ARGSUSED*/ 832 itecngetc(dev) 833 dev_t dev; 834 { 835 register int c; 836 int stat; 837 838 c = kbdgetc(&stat); 839 switch ((stat >> KBD_SSHIFT) & KBD_SMASK) { 840 case KBD_SHIFT: 841 c = kbd_shiftmap[c & KBD_CHARMASK]; 842 break; 843 case KBD_CTRL: 844 c = kbd_ctrlmap[c & KBD_CHARMASK]; 845 break; 846 case KBD_KEY: 847 c = kbd_keymap[c & KBD_CHARMASK]; 848 break; 849 default: 850 c = 0; 851 break; 852 } 853 return(c); 854 } 855 856 itecnputc(dev, c) 857 dev_t dev; 858 int c; 859 { 860 static int paniced = 0; 861 struct ite_softc *ip = &ite_softc[UNIT(dev)]; 862 extern char *panicstr; 863 864 if (panicstr && !paniced && 865 (ip->flags & (ITE_ACTIVE|ITE_INGRF)) != ITE_ACTIVE) { 866 (void) iteon(dev, 3); 867 paniced = 1; 868 } 869 iteputchar(c, dev); 870 } 871 #endif 872