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