xref: /csrg-svn/sys/hp/dev/ite.c (revision 52390)
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.8 (Berkeley) 02/05/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 "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 void	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 void
280 itestart(tp)
281 	register struct tty *tp;
282 {
283 	register int cc, s;
284 	int hiwat = 0;
285 
286 	s = spltty();
287 	if (tp->t_state & (TS_TIMEOUT|TS_BUSY|TS_TTSTOP)) {
288 		splx(s);
289 		return;
290 	}
291 	tp->t_state |= TS_BUSY;
292 	cc = tp->t_outq.c_cc;
293 	if (cc <= tp->t_lowat) {
294 		if (tp->t_state & TS_ASLEEP) {
295 			tp->t_state &= ~TS_ASLEEP;
296 			wakeup((caddr_t)&tp->t_outq);
297 		}
298 		if (tp->t_wsel) {
299 			selwakeup(tp->t_wsel, tp->t_state & TS_WCOLL);
300 			tp->t_wsel = 0;
301 			tp->t_state &= ~TS_WCOLL;
302 		}
303 	}
304 	/*
305 	 * Limit the amount of output we do in one burst
306 	 * to prevent hogging the CPU.
307 	 */
308 	if (cc > iteburst) {
309 		hiwat++;
310 		cc = iteburst;
311 	}
312 	while (--cc >= 0) {
313 		register int c;
314 
315 		c = getc(&tp->t_outq);
316 		/*
317 		 * iteputchar() may take a long time and we don't want to
318 		 * block all interrupts for long periods of time.  Since
319 		 * there is no need to stay at high priority while outputing
320 		 * the character (since we don't have to worry about
321 		 * interrupts), we don't.  We just need to make sure that
322 		 * we don't reenter iteputchar, which is guarenteed by the
323 		 * earlier setting of TS_BUSY.
324 		 */
325 		splx(s);
326 		iteputchar(c, tp->t_dev);
327 		spltty();
328 	}
329 	if (hiwat) {
330 		tp->t_state |= TS_TIMEOUT;
331 		timeout(ttrstrt, tp, 1);
332 	}
333 	tp->t_state &= ~TS_BUSY;
334 	splx(s);
335 }
336 
337 itefilter(stat, c)
338      register char stat, c;
339 {
340 	static int capsmode = 0;
341 	static int metamode = 0;
342   	register char code, *str;
343 
344 	if (kbd_tty == NULL)
345 		return;
346 
347 	switch (c & 0xFF) {
348 	case KBD_CAPSLOCK:
349 		capsmode = !capsmode;
350 		return;
351 
352 	case KBD_EXT_LEFT_DOWN:
353 	case KBD_EXT_RIGHT_DOWN:
354 		metamode = 1;
355 		return;
356 
357 	case KBD_EXT_LEFT_UP:
358 	case KBD_EXT_RIGHT_UP:
359 		metamode = 0;
360 		return;
361 	}
362 
363 	c &= KBD_CHARMASK;
364 	switch ((stat>>KBD_SSHIFT) & KBD_SMASK) {
365 
366 	case KBD_KEY:
367 	        if (!capsmode) {
368 			code = kbd_keymap[c];
369 			break;
370 		}
371 		/* fall into... */
372 
373 	case KBD_SHIFT:
374 		code = kbd_shiftmap[c];
375 		break;
376 
377 	case KBD_CTRL:
378 		code = kbd_ctrlmap[c];
379 		break;
380 
381 	case KBD_CTRLSHIFT:
382 		code = kbd_ctrlshiftmap[c];
383 		break;
384         }
385 
386 	if (code == NULL && (str = kbd_stringmap[c]) != NULL) {
387 		while (*str)
388 			(*linesw[kbd_tty->t_line].l_rint)(*str++, kbd_tty);
389 	} else {
390 		if (metamode)
391 			code |= 0x80;
392 		(*linesw[kbd_tty->t_line].l_rint)(code, kbd_tty);
393 	}
394 }
395 
396 iteputchar(c, dev)
397 	register int c;
398 	dev_t dev;
399 {
400 	int unit = UNIT(dev);
401 	register struct ite_softc *ip = &ite_softc[unit];
402 	register struct itesw *sp = &itesw[ip->type];
403 	register int n;
404 
405 	if ((ip->flags & (ITE_ACTIVE|ITE_INGRF)) != ITE_ACTIVE)
406 	  	return;
407 
408 	if (ip->escape) {
409 doesc:
410 		switch (ip->escape) {
411 
412 		case '&':			/* Next can be a,d, or s */
413 			if (ip->fpd++) {
414 				ip->escape = c;
415 				ip->fpd = 0;
416 			}
417 			return;
418 
419 		case 'a':				/* cursor change */
420 			switch (c) {
421 
422 			case 'Y':			/* Only y coord. */
423 				ip->cury = MIN(ip->pos, ip->rows-1);
424 				ip->pos = 0;
425 				ip->escape = 0;
426 				(*sp->ite_cursor)(ip, MOVE_CURSOR);
427 				clr_attr(ip, ATTR_INV);
428 				break;
429 
430 			case 'y':			/* y coord first */
431 				ip->cury = MIN(ip->pos, ip->rows-1);
432 				ip->pos = 0;
433 				ip->fpd = 0;
434 				break;
435 
436 			case 'C':			/* x coord */
437 				ip->curx = MIN(ip->pos, ip->cols-1);
438 				ip->pos = 0;
439 				ip->escape = 0;
440 				(*sp->ite_cursor)(ip, MOVE_CURSOR);
441 				clr_attr(ip, ATTR_INV);
442 				break;
443 
444 			default:	     /* Possibly a 3 digit number. */
445 				if (c >= '0' && c <= '9' && ip->fpd < 3) {
446 					ip->pos = ip->pos * 10 + (c - '0');
447 					ip->fpd++;
448 				} else {
449 					ip->pos = 0;
450 					ip->escape = 0;
451 				}
452 				break;
453 			}
454 			return;
455 
456 		case 'd':				/* attribute change */
457 			switch (c) {
458 
459 			case 'B':
460 				set_attr(ip, ATTR_INV);
461 				break;
462 		        case 'D':
463 				/* XXX: we don't do anything for underline */
464 				set_attr(ip, ATTR_UL);
465 				break;
466 		        case '@':
467 				clr_attr(ip, ATTR_ALL);
468 				break;
469 			}
470 			ip->escape = 0;
471 			return;
472 
473 		case 's':				/* keypad control */
474 			switch (ip->fpd) {
475 
476 			case 0:
477 				ip->hold = c;
478 				ip->fpd++;
479 				return;
480 
481 			case 1:
482 				if (c == 'A') {
483 					switch (ip->hold) {
484 
485 					case '0':
486 						clr_attr(ip, ATTR_KPAD);
487 						break;
488 					case '1':
489 						set_attr(ip, ATTR_KPAD);
490 						break;
491 					}
492 				}
493 				ip->hold = 0;
494 			}
495 			ip->escape = 0;
496 			return;
497 
498 		case 'i':			/* back tab */
499 			if (ip->curx > TABSIZE) {
500 				n = ip->curx - (ip->curx & (TABSIZE - 1));
501 				ip->curx -= n;
502 			} else
503 				ip->curx = 0;
504 			(*sp->ite_cursor)(ip, MOVE_CURSOR);
505 			ip->escape = 0;
506 			return;
507 
508 		case '3':			/* clear all tabs */
509 			goto ignore;
510 
511 		case 'K':			/* clear_eol */
512 			ite_clrtoeol(ip, sp, ip->cury, ip->curx);
513 			ip->escape = 0;
514 			return;
515 
516 		case 'J':			/* clear_eos */
517 			ite_clrtoeos(ip, sp);
518 			ip->escape = 0;
519 			return;
520 
521 		case 'B':			/* cursor down 1 line */
522 			if (++ip->cury == ip->rows) {
523 				--ip->cury;
524 				(*sp->ite_scroll)(ip, 1, 0, 1, SCROLL_UP);
525 				ite_clrtoeol(ip, sp, ip->cury, 0);
526 			}
527 			else
528 				(*sp->ite_cursor)(ip, MOVE_CURSOR);
529 			clr_attr(ip, ATTR_INV);
530 			ip->escape = 0;
531 			return;
532 
533 		case 'C':			/* cursor forward 1 char */
534 			ip->escape = 0;
535 			itecheckwrap(ip, sp);
536 			return;
537 
538 		case 'A':			/* cursor up 1 line */
539 			if (ip->cury > 0) {
540 				ip->cury--;
541 				(*sp->ite_cursor)(ip, MOVE_CURSOR);
542 			}
543 			ip->escape = 0;
544 			clr_attr(ip, ATTR_INV);
545 			return;
546 
547 		case 'P':			/* delete character */
548 			ite_dchar(ip, sp);
549 			ip->escape = 0;
550 			return;
551 
552 		case 'M':			/* delete line */
553 			ite_dline(ip, sp);
554 			ip->escape = 0;
555 			return;
556 
557 		case 'Q':			/* enter insert mode */
558 			ip->imode = 1;
559 			ip->escape = 0;
560 			return;
561 
562 		case 'R':			/* exit insert mode */
563 			ip->imode = 0;
564 			ip->escape = 0;
565 			return;
566 
567 		case 'L':			/* insert blank line */
568 			ite_iline(ip, sp);
569 			ip->escape = 0;
570 			return;
571 
572 		case 'h':			/* home key */
573 			ip->cury = ip->curx = 0;
574 			(*sp->ite_cursor)(ip, MOVE_CURSOR);
575 			ip->escape = 0;
576 			return;
577 
578 		case 'D':			/* left arrow key */
579 			if (ip->curx > 0) {
580 				ip->curx--;
581 				(*sp->ite_cursor)(ip, MOVE_CURSOR);
582 			}
583 			ip->escape = 0;
584 			return;
585 
586 		case '1':			/* set tab in all rows */
587 			goto ignore;
588 
589 		case ESC:
590 			if ((ip->escape = c) == ESC)
591 				break;
592 			ip->fpd = 0;
593 			goto doesc;
594 
595 		default:
596 ignore:
597 			ip->escape = 0;
598 			return;
599 
600 		}
601 	}
602 
603 	switch (c &= 0x7F) {
604 
605 	case '\n':
606 
607 		if (++ip->cury == ip->rows) {
608 			--ip->cury;
609 			(*sp->ite_scroll)(ip, 1, 0, 1, SCROLL_UP);
610 			ite_clrtoeol(ip, sp, ip->cury, 0);
611 		}
612 		else
613 			(*sp->ite_cursor)(ip, MOVE_CURSOR);
614 		clr_attr(ip, ATTR_INV);
615 		break;
616 
617 	case '\r':
618 		if (ip->curx) {
619 			ip->curx = 0;
620 			(*sp->ite_cursor)(ip, MOVE_CURSOR);
621 		}
622 		break;
623 
624 	case '\b':
625 		if (--ip->curx < 0)
626 			ip->curx = 0;
627 		else
628 			(*sp->ite_cursor)(ip, MOVE_CURSOR);
629 		break;
630 
631 	case '\t':
632 		if (ip->curx < TABEND(unit)) {
633 			n = TABSIZE - (ip->curx & (TABSIZE - 1));
634 			ip->curx += n;
635 			(*sp->ite_cursor)(ip, MOVE_CURSOR);
636 		} else
637 			itecheckwrap(ip, sp);
638 		break;
639 
640 	case CTRL('G'):
641 		if (&ite_tty[unit] == kbd_tty)
642 			kbdbell();
643 		break;
644 
645 	case ESC:
646 		ip->escape = ESC;
647 		break;
648 
649 	default:
650 		if (c < ' ' || c == DEL)
651 			break;
652 		if (ip->imode)
653 			ite_ichar(ip, sp);
654 		if ((ip->attribute & ATTR_INV) || attrtest(ip, ATTR_INV)) {
655 			attrset(ip, ATTR_INV);
656 			(*sp->ite_putc)(ip, c, ip->cury, ip->curx, ATTR_INV);
657 		}
658 		else
659 			(*sp->ite_putc)(ip, c, ip->cury, ip->curx, ATTR_NOR);
660 		(*sp->ite_cursor)(ip, DRAW_CURSOR);
661 		itecheckwrap(ip, sp);
662 		break;
663 	}
664 }
665 
666 itecheckwrap(ip, sp)
667      register struct ite_softc *ip;
668      register struct itesw *sp;
669 {
670 	if (++ip->curx == ip->cols) {
671 		ip->curx = 0;
672 		clr_attr(ip, ATTR_INV);
673 		if (++ip->cury == ip->rows) {
674 			--ip->cury;
675 			(*sp->ite_scroll)(ip, 1, 0, 1, SCROLL_UP);
676 			ite_clrtoeol(ip, sp, ip->cury, 0);
677 			return;
678 		}
679 	}
680 	(*sp->ite_cursor)(ip, MOVE_CURSOR);
681 }
682 
683 ite_dchar(ip, sp)
684      register struct ite_softc *ip;
685      register struct itesw *sp;
686 {
687 	(*sp->ite_scroll)(ip, ip->cury, ip->curx + 1, 1, SCROLL_LEFT);
688 	attrmov(ip, ip->cury, ip->curx + 1, ip->cury, ip->curx,
689 		1, ip->cols - ip->curx - 1);
690 	attrclr(ip, ip->cury, ip->cols - 1, 1, 1);
691 	(*sp->ite_putc)(ip, ' ', ip->cury, ip->cols - 1, ATTR_NOR);
692 	(*sp->ite_cursor)(ip, DRAW_CURSOR);
693 }
694 
695 ite_ichar(ip, sp)
696      register struct ite_softc *ip;
697      register struct itesw *sp;
698 {
699 	(*sp->ite_scroll)(ip, ip->cury, ip->curx, 1, SCROLL_RIGHT);
700 	attrmov(ip, ip->cury, ip->curx, ip->cury, ip->curx + 1,
701 		1, ip->cols - ip->curx - 1);
702 	attrclr(ip, ip->cury, ip->curx, 1, 1);
703 	(*sp->ite_putc)(ip, ' ', ip->cury, ip->curx, ATTR_NOR);
704 	(*sp->ite_cursor)(ip, DRAW_CURSOR);
705 }
706 
707 ite_dline(ip, sp)
708      register struct ite_softc *ip;
709      register struct itesw *sp;
710 {
711 	(*sp->ite_scroll)(ip, ip->cury + 1, 0, 1, SCROLL_UP);
712 	attrmov(ip, ip->cury + 1, 0, ip->cury, 0,
713 		ip->rows - ip->cury - 1, ip->cols);
714 	ite_clrtoeol(ip, sp, ip->rows - 1, 0);
715 }
716 
717 ite_iline(ip, sp)
718      register struct ite_softc *ip;
719      register struct itesw *sp;
720 {
721 	(*sp->ite_scroll)(ip, ip->cury, 0, 1, SCROLL_DOWN);
722 	attrmov(ip, ip->cury, 0, ip->cury + 1, 0,
723 		ip->rows - ip->cury - 1, ip->cols);
724 	ite_clrtoeol(ip, sp, ip->cury, 0);
725 }
726 
727 ite_clrtoeol(ip, sp, y, x)
728      register struct ite_softc *ip;
729      register struct itesw *sp;
730      register int y, x;
731 {
732 	(*sp->ite_clear)(ip, y, x, 1, ip->cols - x);
733 	attrclr(ip, y, x, 1, ip->cols - x);
734 	(*sp->ite_cursor)(ip, DRAW_CURSOR);
735 }
736 
737 ite_clrtoeos(ip, sp)
738      register struct ite_softc *ip;
739      register struct itesw *sp;
740 {
741 	(*sp->ite_clear)(ip, ip->cury, 0, ip->rows - ip->cury, ip->cols);
742 	attrclr(ip, ip->cury, 0, ip->rows - ip->cury, ip->cols);
743 	(*sp->ite_cursor)(ip, DRAW_CURSOR);
744 }
745 
746 /*
747  * Console functions
748  */
749 #include "../hp300/cons.h"
750 #include "grfioctl.h"
751 #include "grfvar.h"
752 
753 #ifdef DEBUG
754 /*
755  * Minimum ITE number at which to start looking for a console.
756  * Setting to 0 will do normal search, 1 will skip first ITE device,
757  * NITE will skip ITEs and use serial port.
758  */
759 int	whichconsole = 0;
760 #endif
761 
762 itecnprobe(cp)
763 	struct consdev *cp;
764 {
765 	register struct ite_softc *ip;
766 	int i, maj, unit, pri;
767 
768 	/* locate the major number */
769 	for (maj = 0; maj < nchrdev; maj++)
770 		if (cdevsw[maj].d_open == iteopen)
771 			break;
772 
773 	/* urk! */
774 	grfconfig();
775 
776 	/* check all the individual displays and find the best */
777 	unit = -1;
778 	pri = CN_DEAD;
779 	for (i = 0; i < NITE; i++) {
780 		struct grf_softc *gp = &grf_softc[i];
781 
782 		ip = &ite_softc[i];
783 		if ((gp->g_flags & GF_ALIVE) == 0)
784 			continue;
785 		ip->flags = (ITE_ALIVE|ITE_CONSOLE);
786 
787 		/* XXX - we need to do something about mapping these */
788 		switch (gp->g_type) {
789 
790 		case GT_TOPCAT:
791 		case GT_LRCATSEYE:
792 		case GT_HRCCATSEYE:
793 		case GT_HRMCATSEYE:
794 			ip->type = ITE_TOPCAT;
795 			break;
796 		case GT_GATORBOX:
797 			ip->type = ITE_GATORBOX;
798 			break;
799 		case GT_RENAISSANCE:
800 			ip->type = ITE_RENAISSANCE;
801 			break;
802 		case GT_DAVINCI:
803 			ip->type = ITE_DAVINCI;
804 			break;
805 		}
806 #ifdef DEBUG
807 		if (i < whichconsole)
808 			continue;
809 #endif
810 		if ((int)gp->g_display.gd_regaddr == GRFIADDR) {
811 			pri = CN_INTERNAL;
812 			unit = i;
813 		} else if (unit < 0) {
814 			pri = CN_NORMAL;
815 			unit = i;
816 		}
817 	}
818 
819 	/* initialize required fields */
820 	cp->cn_dev = makedev(maj, unit);
821 	cp->cn_tp = &ite_tty[unit];
822 	cp->cn_pri = pri;
823 }
824 
825 itecninit(cp)
826 	struct consdev *cp;
827 {
828 	int unit = UNIT(cp->cn_dev);
829 	struct ite_softc *ip = &ite_softc[unit];
830 
831 	ip->attrbuf = console_attributes;
832 	iteinit(cp->cn_dev);
833 	ip->flags |= (ITE_ACTIVE|ITE_ISCONS);
834 	kbd_tty = &ite_tty[unit];
835 }
836 
837 /*ARGSUSED*/
838 itecngetc(dev)
839 	dev_t dev;
840 {
841 	register int c;
842 	int stat;
843 
844 	c = kbdgetc(&stat);
845 	switch ((stat >> KBD_SSHIFT) & KBD_SMASK) {
846 	case KBD_SHIFT:
847 		c = kbd_shiftmap[c & KBD_CHARMASK];
848 		break;
849 	case KBD_CTRL:
850 		c = kbd_ctrlmap[c & KBD_CHARMASK];
851 		break;
852 	case KBD_KEY:
853 		c = kbd_keymap[c & KBD_CHARMASK];
854 		break;
855 	default:
856 		c = 0;
857 		break;
858 	}
859 	return(c);
860 }
861 
862 itecnputc(dev, c)
863 	dev_t dev;
864 	int c;
865 {
866 	static int paniced = 0;
867 	struct ite_softc *ip = &ite_softc[UNIT(dev)];
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