xref: /original-bsd/sys/hp/dev/ite.c (revision 3705696b)
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