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.7 (Berkeley) 11/05/91 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 int 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) 264 dev_t dev; 265 caddr_t addr; 266 { 267 register struct tty *tp = &ite_tty[UNIT(dev)]; 268 int error; 269 270 error = (*linesw[tp->t_line].l_ioctl)(tp, cmd, addr, flag); 271 if (error >= 0) 272 return (error); 273 error = ttioctl(tp, cmd, addr, flag); 274 if (error >= 0) 275 return (error); 276 return (ENOTTY); 277 } 278 279 itestart(tp) 280 register struct tty *tp; 281 { 282 register int cc, s; 283 int hiwat = 0; 284 285 s = spltty(); 286 if (tp->t_state & (TS_TIMEOUT|TS_BUSY|TS_TTSTOP)) { 287 splx(s); 288 return; 289 } 290 tp->t_state |= TS_BUSY; 291 cc = tp->t_outq.c_cc; 292 if (cc <= tp->t_lowat) { 293 if (tp->t_state & TS_ASLEEP) { 294 tp->t_state &= ~TS_ASLEEP; 295 wakeup(&tp->t_outq); 296 } 297 if (tp->t_wsel) { 298 selwakeup(tp->t_wsel, tp->t_state & TS_WCOLL); 299 tp->t_wsel = 0; 300 tp->t_state &= ~TS_WCOLL; 301 } 302 } 303 /* 304 * Limit the amount of output we do in one burst 305 * to prevent hogging the CPU. 306 */ 307 if (cc > iteburst) { 308 hiwat++; 309 cc = iteburst; 310 } 311 while (--cc >= 0) { 312 register int c; 313 314 c = getc(&tp->t_outq); 315 /* 316 * iteputchar() may take a long time and we don't want to 317 * block all interrupts for long periods of time. Since 318 * there is no need to stay at high priority while outputing 319 * the character (since we don't have to worry about 320 * interrupts), we don't. We just need to make sure that 321 * we don't reenter iteputchar, which is guarenteed by the 322 * earlier setting of TS_BUSY. 323 */ 324 splx(s); 325 iteputchar(c, tp->t_dev); 326 spltty(); 327 } 328 if (hiwat) { 329 tp->t_state |= TS_TIMEOUT; 330 timeout(ttrstrt, tp, 1); 331 } 332 tp->t_state &= ~TS_BUSY; 333 splx(s); 334 } 335 336 itefilter(stat, c) 337 register char stat, c; 338 { 339 static int capsmode = 0; 340 static int metamode = 0; 341 register char code, *str; 342 343 if (kbd_tty == NULL) 344 return; 345 346 switch (c & 0xFF) { 347 case KBD_CAPSLOCK: 348 capsmode = !capsmode; 349 return; 350 351 case KBD_EXT_LEFT_DOWN: 352 case KBD_EXT_RIGHT_DOWN: 353 metamode = 1; 354 return; 355 356 case KBD_EXT_LEFT_UP: 357 case KBD_EXT_RIGHT_UP: 358 metamode = 0; 359 return; 360 } 361 362 c &= KBD_CHARMASK; 363 switch ((stat>>KBD_SSHIFT) & KBD_SMASK) { 364 365 case KBD_KEY: 366 if (!capsmode) { 367 code = kbd_keymap[c]; 368 break; 369 } 370 /* fall into... */ 371 372 case KBD_SHIFT: 373 code = kbd_shiftmap[c]; 374 break; 375 376 case KBD_CTRL: 377 code = kbd_ctrlmap[c]; 378 break; 379 380 case KBD_CTRLSHIFT: 381 code = kbd_ctrlshiftmap[c]; 382 break; 383 } 384 385 if (code == NULL && (str = kbd_stringmap[c]) != NULL) { 386 while (*str) 387 (*linesw[kbd_tty->t_line].l_rint)(*str++, kbd_tty); 388 } else { 389 if (metamode) 390 code |= 0x80; 391 (*linesw[kbd_tty->t_line].l_rint)(code, kbd_tty); 392 } 393 } 394 395 iteputchar(c, dev) 396 register int c; 397 dev_t dev; 398 { 399 int unit = UNIT(dev); 400 register struct ite_softc *ip = &ite_softc[unit]; 401 register struct itesw *sp = &itesw[ip->type]; 402 register int n; 403 404 if ((ip->flags & (ITE_ACTIVE|ITE_INGRF)) != ITE_ACTIVE) 405 return; 406 407 if (ip->escape) { 408 doesc: 409 switch (ip->escape) { 410 411 case '&': /* Next can be a,d, or s */ 412 if (ip->fpd++) { 413 ip->escape = c; 414 ip->fpd = 0; 415 } 416 return; 417 418 case 'a': /* cursor change */ 419 switch (c) { 420 421 case 'Y': /* Only y coord. */ 422 ip->cury = MIN(ip->pos, ip->rows-1); 423 ip->pos = 0; 424 ip->escape = 0; 425 (*sp->ite_cursor)(ip, MOVE_CURSOR); 426 clr_attr(ip, ATTR_INV); 427 break; 428 429 case 'y': /* y coord first */ 430 ip->cury = MIN(ip->pos, ip->rows-1); 431 ip->pos = 0; 432 ip->fpd = 0; 433 break; 434 435 case 'C': /* x coord */ 436 ip->curx = MIN(ip->pos, ip->cols-1); 437 ip->pos = 0; 438 ip->escape = 0; 439 (*sp->ite_cursor)(ip, MOVE_CURSOR); 440 clr_attr(ip, ATTR_INV); 441 break; 442 443 default: /* Possibly a 3 digit number. */ 444 if (c >= '0' && c <= '9' && ip->fpd < 3) { 445 ip->pos = ip->pos * 10 + (c - '0'); 446 ip->fpd++; 447 } else { 448 ip->pos = 0; 449 ip->escape = 0; 450 } 451 break; 452 } 453 return; 454 455 case 'd': /* attribute change */ 456 switch (c) { 457 458 case 'B': 459 set_attr(ip, ATTR_INV); 460 break; 461 case 'D': 462 /* XXX: we don't do anything for underline */ 463 set_attr(ip, ATTR_UL); 464 break; 465 case '@': 466 clr_attr(ip, ATTR_ALL); 467 break; 468 } 469 ip->escape = 0; 470 return; 471 472 case 's': /* keypad control */ 473 switch (ip->fpd) { 474 475 case 0: 476 ip->hold = c; 477 ip->fpd++; 478 return; 479 480 case 1: 481 if (c == 'A') { 482 switch (ip->hold) { 483 484 case '0': 485 clr_attr(ip, ATTR_KPAD); 486 break; 487 case '1': 488 set_attr(ip, ATTR_KPAD); 489 break; 490 } 491 } 492 ip->hold = 0; 493 } 494 ip->escape = 0; 495 return; 496 497 case 'i': /* back tab */ 498 if (ip->curx > TABSIZE) { 499 n = ip->curx - (ip->curx & (TABSIZE - 1)); 500 ip->curx -= n; 501 } else 502 ip->curx = 0; 503 (*sp->ite_cursor)(ip, MOVE_CURSOR); 504 ip->escape = 0; 505 return; 506 507 case '3': /* clear all tabs */ 508 goto ignore; 509 510 case 'K': /* clear_eol */ 511 ite_clrtoeol(ip, sp, ip->cury, ip->curx); 512 ip->escape = 0; 513 return; 514 515 case 'J': /* clear_eos */ 516 ite_clrtoeos(ip, sp); 517 ip->escape = 0; 518 return; 519 520 case 'B': /* cursor down 1 line */ 521 if (++ip->cury == ip->rows) { 522 --ip->cury; 523 (*sp->ite_scroll)(ip, 1, 0, 1, SCROLL_UP); 524 ite_clrtoeol(ip, sp, ip->cury, 0); 525 } 526 else 527 (*sp->ite_cursor)(ip, MOVE_CURSOR); 528 clr_attr(ip, ATTR_INV); 529 ip->escape = 0; 530 return; 531 532 case 'C': /* cursor forward 1 char */ 533 ip->escape = 0; 534 itecheckwrap(ip, sp); 535 return; 536 537 case 'A': /* cursor up 1 line */ 538 if (ip->cury > 0) { 539 ip->cury--; 540 (*sp->ite_cursor)(ip, MOVE_CURSOR); 541 } 542 ip->escape = 0; 543 clr_attr(ip, ATTR_INV); 544 return; 545 546 case 'P': /* delete character */ 547 ite_dchar(ip, sp); 548 ip->escape = 0; 549 return; 550 551 case 'M': /* delete line */ 552 ite_dline(ip, sp); 553 ip->escape = 0; 554 return; 555 556 case 'Q': /* enter insert mode */ 557 ip->imode = 1; 558 ip->escape = 0; 559 return; 560 561 case 'R': /* exit insert mode */ 562 ip->imode = 0; 563 ip->escape = 0; 564 return; 565 566 case 'L': /* insert blank line */ 567 ite_iline(ip, sp); 568 ip->escape = 0; 569 return; 570 571 case 'h': /* home key */ 572 ip->cury = ip->curx = 0; 573 (*sp->ite_cursor)(ip, MOVE_CURSOR); 574 ip->escape = 0; 575 return; 576 577 case 'D': /* left arrow key */ 578 if (ip->curx > 0) { 579 ip->curx--; 580 (*sp->ite_cursor)(ip, MOVE_CURSOR); 581 } 582 ip->escape = 0; 583 return; 584 585 case '1': /* set tab in all rows */ 586 goto ignore; 587 588 case ESC: 589 if ((ip->escape = c) == ESC) 590 break; 591 ip->fpd = 0; 592 goto doesc; 593 594 default: 595 ignore: 596 ip->escape = 0; 597 return; 598 599 } 600 } 601 602 switch (c &= 0x7F) { 603 604 case '\n': 605 606 if (++ip->cury == ip->rows) { 607 --ip->cury; 608 (*sp->ite_scroll)(ip, 1, 0, 1, SCROLL_UP); 609 ite_clrtoeol(ip, sp, ip->cury, 0); 610 } 611 else 612 (*sp->ite_cursor)(ip, MOVE_CURSOR); 613 clr_attr(ip, ATTR_INV); 614 break; 615 616 case '\r': 617 if (ip->curx) { 618 ip->curx = 0; 619 (*sp->ite_cursor)(ip, MOVE_CURSOR); 620 } 621 break; 622 623 case '\b': 624 if (--ip->curx < 0) 625 ip->curx = 0; 626 else 627 (*sp->ite_cursor)(ip, MOVE_CURSOR); 628 break; 629 630 case '\t': 631 if (ip->curx < TABEND(unit)) { 632 n = TABSIZE - (ip->curx & (TABSIZE - 1)); 633 ip->curx += n; 634 (*sp->ite_cursor)(ip, MOVE_CURSOR); 635 } else 636 itecheckwrap(ip, sp); 637 break; 638 639 case CTRL('G'): 640 if (&ite_tty[unit] == kbd_tty) 641 kbdbell(); 642 break; 643 644 case ESC: 645 ip->escape = ESC; 646 break; 647 648 default: 649 if (c < ' ' || c == DEL) 650 break; 651 if (ip->imode) 652 ite_ichar(ip, sp); 653 if ((ip->attribute & ATTR_INV) || attrtest(ip, ATTR_INV)) { 654 attrset(ip, ATTR_INV); 655 (*sp->ite_putc)(ip, c, ip->cury, ip->curx, ATTR_INV); 656 } 657 else 658 (*sp->ite_putc)(ip, c, ip->cury, ip->curx, ATTR_NOR); 659 (*sp->ite_cursor)(ip, DRAW_CURSOR); 660 itecheckwrap(ip, sp); 661 break; 662 } 663 } 664 665 itecheckwrap(ip, sp) 666 register struct ite_softc *ip; 667 register struct itesw *sp; 668 { 669 if (++ip->curx == ip->cols) { 670 ip->curx = 0; 671 clr_attr(ip, ATTR_INV); 672 if (++ip->cury == ip->rows) { 673 --ip->cury; 674 (*sp->ite_scroll)(ip, 1, 0, 1, SCROLL_UP); 675 ite_clrtoeol(ip, sp, ip->cury, 0); 676 return; 677 } 678 } 679 (*sp->ite_cursor)(ip, MOVE_CURSOR); 680 } 681 682 ite_dchar(ip, sp) 683 register struct ite_softc *ip; 684 register struct itesw *sp; 685 { 686 (*sp->ite_scroll)(ip, ip->cury, ip->curx + 1, 1, SCROLL_LEFT); 687 attrmov(ip, ip->cury, ip->curx + 1, ip->cury, ip->curx, 688 1, ip->cols - ip->curx - 1); 689 attrclr(ip, ip->cury, ip->cols - 1, 1, 1); 690 (*sp->ite_putc)(ip, ' ', ip->cury, ip->cols - 1, ATTR_NOR); 691 (*sp->ite_cursor)(ip, DRAW_CURSOR); 692 } 693 694 ite_ichar(ip, sp) 695 register struct ite_softc *ip; 696 register struct itesw *sp; 697 { 698 (*sp->ite_scroll)(ip, ip->cury, ip->curx, 1, SCROLL_RIGHT); 699 attrmov(ip, ip->cury, ip->curx, ip->cury, ip->curx + 1, 700 1, ip->cols - ip->curx - 1); 701 attrclr(ip, ip->cury, ip->curx, 1, 1); 702 (*sp->ite_putc)(ip, ' ', ip->cury, ip->curx, ATTR_NOR); 703 (*sp->ite_cursor)(ip, DRAW_CURSOR); 704 } 705 706 ite_dline(ip, sp) 707 register struct ite_softc *ip; 708 register struct itesw *sp; 709 { 710 (*sp->ite_scroll)(ip, ip->cury + 1, 0, 1, SCROLL_UP); 711 attrmov(ip, ip->cury + 1, 0, ip->cury, 0, 712 ip->rows - ip->cury - 1, ip->cols); 713 ite_clrtoeol(ip, sp, ip->rows - 1, 0); 714 } 715 716 ite_iline(ip, sp) 717 register struct ite_softc *ip; 718 register struct itesw *sp; 719 { 720 (*sp->ite_scroll)(ip, ip->cury, 0, 1, SCROLL_DOWN); 721 attrmov(ip, ip->cury, 0, ip->cury + 1, 0, 722 ip->rows - ip->cury - 1, ip->cols); 723 ite_clrtoeol(ip, sp, ip->cury, 0); 724 } 725 726 ite_clrtoeol(ip, sp, y, x) 727 register struct ite_softc *ip; 728 register struct itesw *sp; 729 register int y, x; 730 { 731 (*sp->ite_clear)(ip, y, x, 1, ip->cols - x); 732 attrclr(ip, y, x, 1, ip->cols - x); 733 (*sp->ite_cursor)(ip, DRAW_CURSOR); 734 } 735 736 ite_clrtoeos(ip, sp) 737 register struct ite_softc *ip; 738 register struct itesw *sp; 739 { 740 (*sp->ite_clear)(ip, ip->cury, 0, ip->rows - ip->cury, ip->cols); 741 attrclr(ip, ip->cury, 0, ip->rows - ip->cury, ip->cols); 742 (*sp->ite_cursor)(ip, DRAW_CURSOR); 743 } 744 745 /* 746 * Console functions 747 */ 748 #include "../hp300/cons.h" 749 #include "grfioctl.h" 750 #include "grfvar.h" 751 752 #ifdef DEBUG 753 /* 754 * Minimum ITE number at which to start looking for a console. 755 * Setting to 0 will do normal search, 1 will skip first ITE device, 756 * NITE will skip ITEs and use serial port. 757 */ 758 int whichconsole = 0; 759 #endif 760 761 itecnprobe(cp) 762 struct consdev *cp; 763 { 764 register struct ite_softc *ip; 765 int i, maj, unit, pri; 766 767 /* locate the major number */ 768 for (maj = 0; maj < nchrdev; maj++) 769 if (cdevsw[maj].d_open == iteopen) 770 break; 771 772 /* urk! */ 773 grfconfig(); 774 775 /* check all the individual displays and find the best */ 776 unit = -1; 777 pri = CN_DEAD; 778 for (i = 0; i < NITE; i++) { 779 struct grf_softc *gp = &grf_softc[i]; 780 781 ip = &ite_softc[i]; 782 if ((gp->g_flags & GF_ALIVE) == 0) 783 continue; 784 ip->flags = (ITE_ALIVE|ITE_CONSOLE); 785 786 /* XXX - we need to do something about mapping these */ 787 switch (gp->g_type) { 788 789 case GT_TOPCAT: 790 case GT_LRCATSEYE: 791 case GT_HRCCATSEYE: 792 case GT_HRMCATSEYE: 793 ip->type = ITE_TOPCAT; 794 break; 795 case GT_GATORBOX: 796 ip->type = ITE_GATORBOX; 797 break; 798 case GT_RENAISSANCE: 799 ip->type = ITE_RENAISSANCE; 800 break; 801 case GT_DAVINCI: 802 ip->type = ITE_DAVINCI; 803 break; 804 } 805 #ifdef DEBUG 806 if (i < whichconsole) 807 continue; 808 #endif 809 if ((int)gp->g_display.gd_regaddr == GRFIADDR) { 810 pri = CN_INTERNAL; 811 unit = i; 812 } else if (unit < 0) { 813 pri = CN_NORMAL; 814 unit = i; 815 } 816 } 817 818 /* initialize required fields */ 819 cp->cn_dev = makedev(maj, unit); 820 cp->cn_tp = &ite_tty[unit]; 821 cp->cn_pri = pri; 822 } 823 824 itecninit(cp) 825 struct consdev *cp; 826 { 827 int unit = UNIT(cp->cn_dev); 828 struct ite_softc *ip = &ite_softc[unit]; 829 830 ip->attrbuf = console_attributes; 831 iteinit(cp->cn_dev); 832 ip->flags |= (ITE_ACTIVE|ITE_ISCONS); 833 kbd_tty = &ite_tty[unit]; 834 } 835 836 /*ARGSUSED*/ 837 itecngetc(dev) 838 dev_t dev; 839 { 840 register int c; 841 int stat; 842 843 c = kbdgetc(&stat); 844 switch ((stat >> KBD_SSHIFT) & KBD_SMASK) { 845 case KBD_SHIFT: 846 c = kbd_shiftmap[c & KBD_CHARMASK]; 847 break; 848 case KBD_CTRL: 849 c = kbd_ctrlmap[c & KBD_CHARMASK]; 850 break; 851 case KBD_KEY: 852 c = kbd_keymap[c & KBD_CHARMASK]; 853 break; 854 default: 855 c = 0; 856 break; 857 } 858 return(c); 859 } 860 861 itecnputc(dev, c) 862 dev_t dev; 863 int c; 864 { 865 static int paniced = 0; 866 struct ite_softc *ip = &ite_softc[UNIT(dev)]; 867 868 if (panicstr && !paniced && 869 (ip->flags & (ITE_ACTIVE|ITE_INGRF)) != ITE_ACTIVE) { 870 (void) iteon(dev, 3); 871 paniced = 1; 872 } 873 iteputchar(c, dev); 874 } 875 #endif 876