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