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