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