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.3 (Berkeley) 01/09/95
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 */
iteon(dev,flag)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
iteinit(dev)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 */
iteoff(dev,flag)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__
iteopen(dev_t dev,int mode,int devtype,struct proc * p)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*/
iteclose(dev,flag,mode,p)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
iteread(dev,uio,flag)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
itewrite(dev,uio,flag)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
iteioctl(dev,cmd,addr,flag,p)262 iteioctl(dev, cmd, addr, flag, p)
263 dev_t dev;
264 u_long 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
iterestart(tp)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
itestart(tp)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
itefilter(stat,c)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
iteputchar(c,dev)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
itecheckwrap(ip,sp)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
ite_dchar(ip,sp)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
ite_ichar(ip,sp)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
ite_dline(ip,sp)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
ite_iline(ip,sp)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
ite_clrtoeol(ip,sp,y,x)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
ite_clrtoeos(ip,sp)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*/
itecngetc(dev)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
itecnputc(dev,c)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