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