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