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