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