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