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