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