xref: /csrg-svn/sys/hp/dev/ite.c (revision 49132)
141480Smckusick /*
241480Smckusick  * Copyright (c) 1988 University of Utah.
341480Smckusick  * Copyright (c) 1990 The Regents of the University of California.
441480Smckusick  * All rights reserved.
541480Smckusick  *
641480Smckusick  * This code is derived from software contributed to Berkeley by
741480Smckusick  * the Systems Programming Group of the University of Utah Computer
841480Smckusick  * Science Department.
941480Smckusick  *
1041480Smckusick  * %sccs.include.redist.c%
1141480Smckusick  *
1245503Smckusick  * from: Utah $Hdr: ite.c 1.1 90/07/09$
1341480Smckusick  *
14*49132Skarels  *	@(#)ite.c	7.5 (Berkeley) 05/04/91
1541480Smckusick  */
1641480Smckusick 
1741480Smckusick /*
1841480Smckusick  * Bit-mapped display terminal emulator machine independent code.
1941480Smckusick  * This is a very rudimentary.  Much more can be abstracted out of
2041480Smckusick  * the hardware dependent routines.
2141480Smckusick  */
2241480Smckusick #include "ite.h"
2341480Smckusick #if NITE > 0
2441480Smckusick 
2541480Smckusick #include "grf.h"
2641480Smckusick 
2741480Smckusick #undef NITE
2841480Smckusick #define NITE	NGRF
2941480Smckusick 
30*49132Skarels #include "param.h"
31*49132Skarels #include "conf.h"
32*49132Skarels #include "proc.h"
33*49132Skarels #include "ioctl.h"
34*49132Skarels #include "tty.h"
35*49132Skarels #include "systm.h"
36*49132Skarels #include "malloc.h"
3741480Smckusick 
3841480Smckusick #include "itevar.h"
3941480Smckusick #include "iteioctl.h"
4041480Smckusick #include "kbdmap.h"
4141480Smckusick 
42*49132Skarels #include "machine/cpu.h"
4341480Smckusick 
4441480Smckusick #define set_attr(ip, attr)	((ip)->attribute |= (attr))
4541480Smckusick #define clr_attr(ip, attr)	((ip)->attribute &= ~(attr))
4641480Smckusick 
4741480Smckusick extern  int nodev();
4841480Smckusick 
4941480Smckusick int topcat_scroll(),	topcat_init(),		topcat_deinit();
5041480Smckusick int topcat_clear(),	topcat_putc(),	 	topcat_cursor();
5141480Smckusick int gatorbox_scroll(),	gatorbox_init(),	gatorbox_deinit();
5241480Smckusick int gatorbox_clear(),	gatorbox_putc(), 	gatorbox_cursor();
5341480Smckusick int rbox_scroll(),	rbox_init(),		rbox_deinit();
5441480Smckusick int rbox_clear(),	rbox_putc(), 		rbox_cursor();
5541480Smckusick int dvbox_scroll(),	dvbox_init(),		dvbox_deinit();
5641480Smckusick int dvbox_clear(),	dvbox_putc(), 		dvbox_cursor();
5741480Smckusick 
5841480Smckusick struct itesw itesw[] =
5941480Smckusick {
6041480Smckusick 	topcat_init,		topcat_deinit,		topcat_clear,
6141480Smckusick 	topcat_putc,		topcat_cursor,		topcat_scroll,
6241480Smckusick 
6341480Smckusick 	gatorbox_init,		gatorbox_deinit,	gatorbox_clear,
6441480Smckusick 	gatorbox_putc,		gatorbox_cursor,	gatorbox_scroll,
6541480Smckusick 
6641480Smckusick 	rbox_init,		rbox_deinit,		rbox_clear,
6741480Smckusick 	rbox_putc,		rbox_cursor,		rbox_scroll,
6841480Smckusick 
6941480Smckusick 	dvbox_init,		dvbox_deinit,		dvbox_clear,
7041480Smckusick 	dvbox_putc,		dvbox_cursor,		dvbox_scroll,
7141480Smckusick };
7241480Smckusick 
7341480Smckusick /*
7441480Smckusick  * # of chars are output in a single itestart() call.
7541480Smckusick  * If this is too big, user processes will be blocked out for
7641480Smckusick  * long periods of time while we are emptying the queue in itestart().
7741480Smckusick  * If it is too small, console output will be very ragged.
7841480Smckusick  */
7941480Smckusick int	iteburst = 64;
8041480Smckusick 
8141480Smckusick int	nite = NITE;
8241480Smckusick struct  tty *kbd_tty = NULL;
8341480Smckusick struct	tty ite_tty[NITE];
8441480Smckusick struct  ite_softc ite_softc[NITE];
8541480Smckusick 
8641480Smckusick int	itestart();
8741480Smckusick extern	int ttrstrt();
8841480Smckusick extern	struct tty *constty;
8941480Smckusick 
9041480Smckusick /*
9141480Smckusick  * Primary attribute buffer to be used by the first bitmapped console
9241480Smckusick  * found. Secondary displays alloc the attribute buffer as needed.
9341480Smckusick  * Size is based on a 68x128 display, which is currently our largest.
9441480Smckusick  */
9541480Smckusick u_char  console_attributes[0x2200];
9641480Smckusick 
9741480Smckusick /*
9841480Smckusick  * Perform functions necessary to setup device as a terminal emulator.
9941480Smckusick  */
10041480Smckusick iteon(dev, flag)
10141480Smckusick 	dev_t dev;
10241480Smckusick {
10341480Smckusick 	int unit = UNIT(dev);
10441480Smckusick 	struct tty *tp = &ite_tty[unit];
10541480Smckusick 	struct ite_softc *ip = &ite_softc[unit];
10641480Smckusick 
10741480Smckusick 	if (unit < 0 || unit >= NITE || (ip->flags&ITE_ALIVE) == 0)
10841480Smckusick 		return(ENXIO);
10941480Smckusick 	/* force ite active, overriding graphics mode */
11041480Smckusick 	if (flag & 1) {
11141480Smckusick 		ip->flags |= ITE_ACTIVE;
11241480Smckusick 		ip->flags &= ~(ITE_INGRF|ITE_INITED);
11341480Smckusick 	}
11441480Smckusick 	/* leave graphics mode */
11541480Smckusick 	if (flag & 2) {
11641480Smckusick 		ip->flags &= ~ITE_INGRF;
11741480Smckusick 		if ((ip->flags & ITE_ACTIVE) == 0)
11841480Smckusick 			return(0);
11941480Smckusick 	}
12041480Smckusick 	ip->flags |= ITE_ACTIVE;
12141480Smckusick 	if (ip->flags & ITE_INGRF)
12241480Smckusick 		return(0);
12341480Smckusick 	if (kbd_tty == NULL || kbd_tty == tp) {
12441480Smckusick 		kbd_tty = tp;
12541480Smckusick 		kbdenable();
12641480Smckusick 	}
12741480Smckusick 	iteinit(dev);
12841480Smckusick 	return(0);
12941480Smckusick }
13041480Smckusick 
13141480Smckusick iteinit(dev)
13241480Smckusick      dev_t dev;
13341480Smckusick {
13441480Smckusick 	int unit = UNIT(dev);
13541480Smckusick 	struct ite_softc *ip = &ite_softc[unit];
13641480Smckusick 
13741480Smckusick 	if (ip->flags & ITE_INITED)
13841480Smckusick 		return;
13941480Smckusick 
14041480Smckusick 	ip->curx = 0;
14141480Smckusick 	ip->cury = 0;
14241480Smckusick 	ip->cursorx = 0;
14341480Smckusick 	ip->cursory = 0;
14441480Smckusick 
14541480Smckusick 	(*itesw[ip->type].ite_init)(ip);
14641480Smckusick 	(*itesw[ip->type].ite_cursor)(ip, DRAW_CURSOR);
14741480Smckusick 
14841480Smckusick 	ip->attribute = 0;
14941480Smckusick 	if (ip->attrbuf == NULL)
15041480Smckusick 		ip->attrbuf = (u_char *)
15141480Smckusick 			malloc(ip->rows * ip->cols, M_DEVBUF, M_WAITOK);
15241480Smckusick 	bzero(ip->attrbuf, (ip->rows * ip->cols));
15341480Smckusick 
15441480Smckusick 	ip->imode = 0;
15541480Smckusick 	ip->flags |= ITE_INITED;
15641480Smckusick }
15741480Smckusick 
15841480Smckusick /*
15941480Smckusick  * "Shut down" device as terminal emulator.
16041480Smckusick  * Note that we do not deinit the console device unless forced.
16141480Smckusick  * Deinit'ing the console every time leads to a very active
16241480Smckusick  * screen when processing /etc/rc.
16341480Smckusick  */
16441480Smckusick iteoff(dev, flag)
16541480Smckusick 	dev_t dev;
16641480Smckusick {
16741480Smckusick 	register struct ite_softc *ip = &ite_softc[UNIT(dev)];
16841480Smckusick 
16941480Smckusick 	if (flag & 2)
17041480Smckusick 		ip->flags |= ITE_INGRF;
17141480Smckusick 	if ((ip->flags & ITE_ACTIVE) == 0)
17241480Smckusick 		return;
17341480Smckusick 	if ((flag & 1) ||
17441480Smckusick 	    (ip->flags & (ITE_INGRF|ITE_ISCONS|ITE_INITED)) == ITE_INITED)
17541480Smckusick 		(*itesw[ip->type].ite_deinit)(ip);
17641480Smckusick 	if ((flag & 2) == 0)
17741480Smckusick 		ip->flags &= ~ITE_ACTIVE;
17841480Smckusick }
17941480Smckusick 
180*49132Skarels /* ARGSUSED */
181*49132Skarels #ifdef __STDC__
182*49132Skarels iteopen(dev_t dev, int mode, int devtype, struct proc *p)
183*49132Skarels #else
184*49132Skarels iteopen(dev, mode, devtype, p)
18541480Smckusick 	dev_t dev;
186*49132Skarels 	int mode, devtype;
187*49132Skarels 	struct proc *p;
188*49132Skarels #endif
18941480Smckusick {
19041480Smckusick 	int unit = UNIT(dev);
19141480Smckusick 	register struct tty *tp = &ite_tty[unit];
19241480Smckusick 	register struct ite_softc *ip = &ite_softc[unit];
19341480Smckusick 	register int error;
19441480Smckusick 	int first = 0;
19541480Smckusick 
19643409Shibler 	if ((tp->t_state&(TS_ISOPEN|TS_XCLUDE)) == (TS_ISOPEN|TS_XCLUDE)
197*49132Skarels 	    && p->p_ucred->cr_uid != 0)
19841480Smckusick 		return (EBUSY);
19941480Smckusick 	if ((ip->flags & ITE_ACTIVE) == 0) {
20041480Smckusick 		error = iteon(dev, 0);
20141480Smckusick 		if (error)
20241480Smckusick 			return (error);
20341480Smckusick 		first = 1;
20441480Smckusick 	}
20541480Smckusick 	tp->t_oproc = itestart;
20641480Smckusick 	tp->t_param = NULL;
20741480Smckusick 	tp->t_dev = dev;
20841480Smckusick 	if ((tp->t_state&TS_ISOPEN) == 0) {
20941480Smckusick 		ttychars(tp);
21041480Smckusick 		tp->t_iflag = TTYDEF_IFLAG;
21141480Smckusick 		tp->t_oflag = TTYDEF_OFLAG;
21241480Smckusick 		tp->t_cflag = CS8|CREAD;
21341480Smckusick 		tp->t_lflag = TTYDEF_LFLAG;
21441480Smckusick 		tp->t_ispeed = tp->t_ospeed = TTYDEF_SPEED;
21541480Smckusick 		tp->t_state = TS_ISOPEN|TS_CARR_ON;
21641480Smckusick 		ttsetwater(tp);
21741480Smckusick 	}
21841480Smckusick 	error = (*linesw[tp->t_line].l_open)(dev, tp);
21941480Smckusick 	if (error == 0) {
22041480Smckusick 		tp->t_winsize.ws_row = ip->rows;
22141480Smckusick 		tp->t_winsize.ws_col = ip->cols;
22241480Smckusick 	} else if (first)
22341480Smckusick 		iteoff(dev, 0);
22441480Smckusick 	return (error);
22541480Smckusick }
22641480Smckusick 
22741480Smckusick /*ARGSUSED*/
22841480Smckusick iteclose(dev, flag)
22941480Smckusick 	dev_t dev;
23041480Smckusick {
23141480Smckusick 	register struct tty *tp = &ite_tty[UNIT(dev)];
23241480Smckusick 
23341480Smckusick 	(*linesw[tp->t_line].l_close)(tp);
23441480Smckusick 	ttyclose(tp);
23541480Smckusick 	iteoff(dev, 0);
23641480Smckusick 	return(0);
23741480Smckusick }
23841480Smckusick 
23941480Smckusick iteread(dev, uio, flag)
24041480Smckusick 	dev_t dev;
24141480Smckusick 	struct uio *uio;
24241480Smckusick {
24341480Smckusick 	register struct tty *tp = &ite_tty[UNIT(dev)];
24441480Smckusick 
24541480Smckusick 	return ((*linesw[tp->t_line].l_read)(tp, uio, flag));
24641480Smckusick }
24741480Smckusick 
24841480Smckusick itewrite(dev, uio, flag)
24941480Smckusick 	dev_t dev;
25041480Smckusick 	struct uio *uio;
25141480Smckusick {
25241480Smckusick 	int unit = UNIT(dev);
25341480Smckusick 	register struct tty *tp = &ite_tty[unit];
25441480Smckusick 
25541480Smckusick 	if ((ite_softc[unit].flags & ITE_ISCONS) && constty &&
25641480Smckusick 	    (constty->t_state&(TS_CARR_ON|TS_ISOPEN))==(TS_CARR_ON|TS_ISOPEN))
25741480Smckusick 		tp = constty;
25841480Smckusick 	return ((*linesw[tp->t_line].l_write)(tp, uio, flag));
25941480Smckusick }
26041480Smckusick 
26141480Smckusick iteioctl(dev, cmd, addr, flag)
26241480Smckusick 	dev_t dev;
26341480Smckusick 	caddr_t addr;
26441480Smckusick {
26541480Smckusick 	register struct tty *tp = &ite_tty[UNIT(dev)];
26641480Smckusick 	int error;
26741480Smckusick 
26841480Smckusick 	error = (*linesw[tp->t_line].l_ioctl)(tp, cmd, addr, flag);
26941480Smckusick 	if (error >= 0)
27041480Smckusick 		return (error);
27141480Smckusick 	error = ttioctl(tp, cmd, addr, flag);
27241480Smckusick 	if (error >= 0)
27341480Smckusick 		return (error);
27441480Smckusick 	return (ENOTTY);
27541480Smckusick }
27641480Smckusick 
27741480Smckusick itestart(tp)
27841480Smckusick 	register struct tty *tp;
27941480Smckusick {
28041480Smckusick 	register int cc, s;
28141480Smckusick 	int hiwat = 0;
28241480Smckusick 
28341480Smckusick 	s = spltty();
28441480Smckusick 	if (tp->t_state & (TS_TIMEOUT|TS_BUSY|TS_TTSTOP)) {
28541480Smckusick 		splx(s);
28641480Smckusick 		return;
28741480Smckusick 	}
28841480Smckusick 	tp->t_state |= TS_BUSY;
28941480Smckusick 	cc = tp->t_outq.c_cc;
29041480Smckusick 	if (cc <= tp->t_lowat) {
29141480Smckusick 		if (tp->t_state & TS_ASLEEP) {
29241480Smckusick 			tp->t_state &= ~TS_ASLEEP;
29341480Smckusick 			wakeup(&tp->t_outq);
29441480Smckusick 		}
29541480Smckusick 		if (tp->t_wsel) {
29641480Smckusick 			selwakeup(tp->t_wsel, tp->t_state & TS_WCOLL);
29741480Smckusick 			tp->t_wsel = 0;
29841480Smckusick 			tp->t_state &= ~TS_WCOLL;
29941480Smckusick 		}
30041480Smckusick 	}
30141480Smckusick 	/*
30241480Smckusick 	 * Limit the amount of output we do in one burst
30341480Smckusick 	 * to prevent hogging the CPU.
30441480Smckusick 	 */
30541480Smckusick 	if (cc > iteburst) {
30641480Smckusick 		hiwat++;
30741480Smckusick 		cc = iteburst;
30841480Smckusick 	}
30941480Smckusick 	while (--cc >= 0) {
31041480Smckusick 		register int c;
31141480Smckusick 
31241480Smckusick 		c = getc(&tp->t_outq);
31341480Smckusick 		/*
31441480Smckusick 		 * iteputchar() may take a long time and we don't want to
31541480Smckusick 		 * block all interrupts for long periods of time.  Since
31641480Smckusick 		 * there is no need to stay at high priority while outputing
31741480Smckusick 		 * the character (since we don't have to worry about
31841480Smckusick 		 * interrupts), we don't.  We just need to make sure that
31941480Smckusick 		 * we don't reenter iteputchar, which is guarenteed by the
32041480Smckusick 		 * earlier setting of TS_BUSY.
32141480Smckusick 		 */
32241480Smckusick 		splx(s);
32341480Smckusick 		iteputchar(c, tp->t_dev);
32441480Smckusick 		spltty();
32541480Smckusick 	}
32641480Smckusick 	if (hiwat) {
32741480Smckusick 		tp->t_state |= TS_TIMEOUT;
32841480Smckusick 		timeout(ttrstrt, tp, 1);
32941480Smckusick 	}
33041480Smckusick 	tp->t_state &= ~TS_BUSY;
33141480Smckusick 	splx(s);
33241480Smckusick }
33341480Smckusick 
33441480Smckusick itefilter(stat, c)
33541480Smckusick      register char stat, c;
33641480Smckusick {
33741480Smckusick 	static int capsmode = 0;
33841480Smckusick 	static int metamode = 0;
33941480Smckusick   	register char code, *str;
34041480Smckusick 
34141480Smckusick 	if (kbd_tty == NULL)
34241480Smckusick 		return;
34341480Smckusick 
34441480Smckusick 	switch (c & 0xFF) {
34541480Smckusick 	case KBD_CAPSLOCK:
34641480Smckusick 		capsmode = !capsmode;
34741480Smckusick 		return;
34841480Smckusick 
34941480Smckusick 	case KBD_EXT_LEFT_DOWN:
35041480Smckusick 	case KBD_EXT_RIGHT_DOWN:
35141480Smckusick 		metamode = 1;
35241480Smckusick 		return;
35341480Smckusick 
35441480Smckusick 	case KBD_EXT_LEFT_UP:
35541480Smckusick 	case KBD_EXT_RIGHT_UP:
35641480Smckusick 		metamode = 0;
35741480Smckusick 		return;
35841480Smckusick 	}
35941480Smckusick 
36041480Smckusick 	c &= KBD_CHARMASK;
36141480Smckusick 	switch ((stat>>KBD_SSHIFT) & KBD_SMASK) {
36241480Smckusick 
36341480Smckusick 	case KBD_KEY:
36441480Smckusick 	        if (!capsmode) {
36541480Smckusick 			code = kbd_keymap[c];
36641480Smckusick 			break;
36741480Smckusick 		}
36841480Smckusick 		/* fall into... */
36941480Smckusick 
37041480Smckusick 	case KBD_SHIFT:
37141480Smckusick 		code = kbd_shiftmap[c];
37241480Smckusick 		break;
37341480Smckusick 
37441480Smckusick 	case KBD_CTRL:
37541480Smckusick 		code = kbd_ctrlmap[c];
37641480Smckusick 		break;
37741480Smckusick 
37841480Smckusick 	case KBD_CTRLSHIFT:
37941480Smckusick 		code = kbd_ctrlshiftmap[c];
38041480Smckusick 		break;
38141480Smckusick         }
38241480Smckusick 
38341480Smckusick 	if (code == NULL && (str = kbd_stringmap[c]) != NULL) {
38441480Smckusick 		while (*str)
38541480Smckusick 			(*linesw[kbd_tty->t_line].l_rint)(*str++, kbd_tty);
38641480Smckusick 	} else {
38741480Smckusick 		if (metamode)
38841480Smckusick 			code |= 0x80;
38941480Smckusick 		(*linesw[kbd_tty->t_line].l_rint)(code, kbd_tty);
39041480Smckusick 	}
39141480Smckusick }
39241480Smckusick 
39341480Smckusick iteputchar(c, dev)
39441480Smckusick 	register int c;
39541480Smckusick 	dev_t dev;
39641480Smckusick {
39741480Smckusick 	int unit = UNIT(dev);
39841480Smckusick 	register struct ite_softc *ip = &ite_softc[unit];
39941480Smckusick 	register struct itesw *sp = &itesw[ip->type];
40041480Smckusick 	register int n;
40141480Smckusick 
40241480Smckusick 	if ((ip->flags & (ITE_ACTIVE|ITE_INGRF)) != ITE_ACTIVE)
40341480Smckusick 	  	return;
40441480Smckusick 
40541480Smckusick 	if (ip->escape) {
40641480Smckusick doesc:
40741480Smckusick 		switch (ip->escape) {
40841480Smckusick 
40941480Smckusick 		case '&':			/* Next can be a,d, or s */
41041480Smckusick 			if (ip->fpd++) {
41141480Smckusick 				ip->escape = c;
41241480Smckusick 				ip->fpd = 0;
41341480Smckusick 			}
41441480Smckusick 			return;
41541480Smckusick 
41641480Smckusick 		case 'a':				/* cursor change */
41741480Smckusick 			switch (c) {
41841480Smckusick 
41941480Smckusick 			case 'Y':			/* Only y coord. */
42041480Smckusick 				ip->cury = MIN(ip->pos, ip->rows-1);
42141480Smckusick 				ip->pos = 0;
42241480Smckusick 				ip->escape = 0;
42341480Smckusick 				(*sp->ite_cursor)(ip, MOVE_CURSOR);
42441480Smckusick 				clr_attr(ip, ATTR_INV);
42541480Smckusick 				break;
42641480Smckusick 
42741480Smckusick 			case 'y':			/* y coord first */
42841480Smckusick 				ip->cury = MIN(ip->pos, ip->rows-1);
42941480Smckusick 				ip->pos = 0;
43041480Smckusick 				ip->fpd = 0;
43141480Smckusick 				break;
43241480Smckusick 
43341480Smckusick 			case 'C':			/* x coord */
43441480Smckusick 				ip->curx = MIN(ip->pos, ip->cols-1);
43541480Smckusick 				ip->pos = 0;
43641480Smckusick 				ip->escape = 0;
43741480Smckusick 				(*sp->ite_cursor)(ip, MOVE_CURSOR);
43841480Smckusick 				clr_attr(ip, ATTR_INV);
43941480Smckusick 				break;
44041480Smckusick 
44141480Smckusick 			default:	     /* Possibly a 3 digit number. */
44241480Smckusick 				if (c >= '0' && c <= '9' && ip->fpd < 3) {
44341480Smckusick 					ip->pos = ip->pos * 10 + (c - '0');
44441480Smckusick 					ip->fpd++;
44541480Smckusick 				} else {
44641480Smckusick 					ip->pos = 0;
44741480Smckusick 					ip->escape = 0;
44841480Smckusick 				}
44941480Smckusick 				break;
45041480Smckusick 			}
45141480Smckusick 			return;
45241480Smckusick 
45341480Smckusick 		case 'd':				/* attribute change */
45441480Smckusick 			switch (c) {
45541480Smckusick 
45641480Smckusick 			case 'B':
45741480Smckusick 				set_attr(ip, ATTR_INV);
45841480Smckusick 				break;
45941480Smckusick 		        case 'D':
46041480Smckusick 				/* XXX: we don't do anything for underline */
46141480Smckusick 				set_attr(ip, ATTR_UL);
46241480Smckusick 				break;
46341480Smckusick 		        case '@':
46441480Smckusick 				clr_attr(ip, ATTR_ALL);
46541480Smckusick 				break;
46641480Smckusick 			}
46741480Smckusick 			ip->escape = 0;
46841480Smckusick 			return;
46941480Smckusick 
47041480Smckusick 		case 's':				/* keypad control */
47141480Smckusick 			switch (ip->fpd) {
47241480Smckusick 
47341480Smckusick 			case 0:
47441480Smckusick 				ip->hold = c;
47541480Smckusick 				ip->fpd++;
47641480Smckusick 				return;
47741480Smckusick 
47841480Smckusick 			case 1:
47941480Smckusick 				if (c == 'A') {
48041480Smckusick 					switch (ip->hold) {
48141480Smckusick 
48241480Smckusick 					case '0':
48341480Smckusick 						clr_attr(ip, ATTR_KPAD);
48441480Smckusick 						break;
48541480Smckusick 					case '1':
48641480Smckusick 						set_attr(ip, ATTR_KPAD);
48741480Smckusick 						break;
48841480Smckusick 					}
48941480Smckusick 				}
49041480Smckusick 				ip->hold = 0;
49141480Smckusick 			}
49241480Smckusick 			ip->escape = 0;
49341480Smckusick 			return;
49441480Smckusick 
49541480Smckusick 		case 'i':			/* back tab */
49641480Smckusick 			if (ip->curx > TABSIZE) {
49741480Smckusick 				n = ip->curx - (ip->curx & (TABSIZE - 1));
49841480Smckusick 				ip->curx -= n;
49941480Smckusick 			} else
50041480Smckusick 				ip->curx = 0;
50141480Smckusick 			(*sp->ite_cursor)(ip, MOVE_CURSOR);
50241480Smckusick 			ip->escape = 0;
50341480Smckusick 			return;
50441480Smckusick 
50541480Smckusick 		case '3':			/* clear all tabs */
50641480Smckusick 			goto ignore;
50741480Smckusick 
50841480Smckusick 		case 'K':			/* clear_eol */
50941480Smckusick 			ite_clrtoeol(ip, sp, ip->cury, ip->curx);
51041480Smckusick 			ip->escape = 0;
51141480Smckusick 			return;
51241480Smckusick 
51341480Smckusick 		case 'J':			/* clear_eos */
51441480Smckusick 			ite_clrtoeos(ip, sp);
51541480Smckusick 			ip->escape = 0;
51641480Smckusick 			return;
51741480Smckusick 
51841480Smckusick 		case 'B':			/* cursor down 1 line */
51941480Smckusick 			if (++ip->cury == ip->rows) {
52041480Smckusick 				--ip->cury;
52141480Smckusick 				(*sp->ite_scroll)(ip, 1, 0, 1, SCROLL_UP);
52241480Smckusick 				ite_clrtoeol(ip, sp, ip->cury, 0);
52341480Smckusick 			}
52441480Smckusick 			else
52541480Smckusick 				(*sp->ite_cursor)(ip, MOVE_CURSOR);
52641480Smckusick 			clr_attr(ip, ATTR_INV);
52741480Smckusick 			ip->escape = 0;
52841480Smckusick 			return;
52941480Smckusick 
53041480Smckusick 		case 'C':			/* cursor forward 1 char */
53141480Smckusick 			ip->escape = 0;
53241480Smckusick 			itecheckwrap(ip, sp);
53341480Smckusick 			return;
53441480Smckusick 
53541480Smckusick 		case 'A':			/* cursor up 1 line */
53641480Smckusick 			if (ip->cury > 0) {
53741480Smckusick 				ip->cury--;
53841480Smckusick 				(*sp->ite_cursor)(ip, MOVE_CURSOR);
53941480Smckusick 			}
54041480Smckusick 			ip->escape = 0;
54141480Smckusick 			clr_attr(ip, ATTR_INV);
54241480Smckusick 			return;
54341480Smckusick 
54441480Smckusick 		case 'P':			/* delete character */
54541480Smckusick 			ite_dchar(ip, sp);
54641480Smckusick 			ip->escape = 0;
54741480Smckusick 			return;
54841480Smckusick 
54941480Smckusick 		case 'M':			/* delete line */
55041480Smckusick 			ite_dline(ip, sp);
55141480Smckusick 			ip->escape = 0;
55241480Smckusick 			return;
55341480Smckusick 
55441480Smckusick 		case 'Q':			/* enter insert mode */
55541480Smckusick 			ip->imode = 1;
55641480Smckusick 			ip->escape = 0;
55741480Smckusick 			return;
55841480Smckusick 
55941480Smckusick 		case 'R':			/* exit insert mode */
56041480Smckusick 			ip->imode = 0;
56141480Smckusick 			ip->escape = 0;
56241480Smckusick 			return;
56341480Smckusick 
56441480Smckusick 		case 'L':			/* insert blank line */
56541480Smckusick 			ite_iline(ip, sp);
56641480Smckusick 			ip->escape = 0;
56741480Smckusick 			return;
56841480Smckusick 
56941480Smckusick 		case 'h':			/* home key */
57041480Smckusick 			ip->cury = ip->curx = 0;
57141480Smckusick 			(*sp->ite_cursor)(ip, MOVE_CURSOR);
57241480Smckusick 			ip->escape = 0;
57341480Smckusick 			return;
57441480Smckusick 
57541480Smckusick 		case 'D':			/* left arrow key */
57641480Smckusick 			if (ip->curx > 0) {
57741480Smckusick 				ip->curx--;
57841480Smckusick 				(*sp->ite_cursor)(ip, MOVE_CURSOR);
57941480Smckusick 			}
58041480Smckusick 			ip->escape = 0;
58141480Smckusick 			return;
58241480Smckusick 
58341480Smckusick 		case '1':			/* set tab in all rows */
58441480Smckusick 			goto ignore;
58541480Smckusick 
58641480Smckusick 		case ESC:
58741480Smckusick 			if ((ip->escape = c) == ESC)
58841480Smckusick 				break;
58941480Smckusick 			ip->fpd = 0;
59041480Smckusick 			goto doesc;
59141480Smckusick 
59241480Smckusick 		default:
59341480Smckusick ignore:
59441480Smckusick 			ip->escape = 0;
59541480Smckusick 			return;
59641480Smckusick 
59741480Smckusick 		}
59841480Smckusick 	}
59941480Smckusick 
60041480Smckusick 	switch (c &= 0x7F) {
60141480Smckusick 
60241480Smckusick 	case '\n':
60341480Smckusick 
60441480Smckusick 		if (++ip->cury == ip->rows) {
60541480Smckusick 			--ip->cury;
60641480Smckusick 			(*sp->ite_scroll)(ip, 1, 0, 1, SCROLL_UP);
60741480Smckusick 			ite_clrtoeol(ip, sp, ip->cury, 0);
60841480Smckusick 		}
60941480Smckusick 		else
61041480Smckusick 			(*sp->ite_cursor)(ip, MOVE_CURSOR);
61141480Smckusick 		clr_attr(ip, ATTR_INV);
61241480Smckusick 		break;
61341480Smckusick 
61441480Smckusick 	case '\r':
61541480Smckusick 		if (ip->curx) {
61641480Smckusick 			ip->curx = 0;
61741480Smckusick 			(*sp->ite_cursor)(ip, MOVE_CURSOR);
61841480Smckusick 		}
61941480Smckusick 		break;
62041480Smckusick 
62141480Smckusick 	case '\b':
62241480Smckusick 		if (--ip->curx < 0)
62341480Smckusick 			ip->curx = 0;
62441480Smckusick 		else
62541480Smckusick 			(*sp->ite_cursor)(ip, MOVE_CURSOR);
62641480Smckusick 		break;
62741480Smckusick 
62841480Smckusick 	case '\t':
62941480Smckusick 		if (ip->curx < TABEND(unit)) {
63041480Smckusick 			n = TABSIZE - (ip->curx & (TABSIZE - 1));
63141480Smckusick 			ip->curx += n;
63241480Smckusick 			(*sp->ite_cursor)(ip, MOVE_CURSOR);
63341480Smckusick 		} else
63441480Smckusick 			itecheckwrap(ip, sp);
63541480Smckusick 		break;
63641480Smckusick 
63741480Smckusick 	case CTRL('G'):
63841480Smckusick 		if (&ite_tty[unit] == kbd_tty)
63941480Smckusick 			kbdbell();
64041480Smckusick 		break;
64141480Smckusick 
64241480Smckusick 	case ESC:
64341480Smckusick 		ip->escape = ESC;
64441480Smckusick 		break;
64541480Smckusick 
64641480Smckusick 	default:
64741480Smckusick 		if (c < ' ' || c == DEL)
64841480Smckusick 			break;
64941480Smckusick 		if (ip->imode)
65041480Smckusick 			ite_ichar(ip, sp);
65141480Smckusick 		if ((ip->attribute & ATTR_INV) || attrtest(ip, ATTR_INV)) {
65241480Smckusick 			attrset(ip, ATTR_INV);
65341480Smckusick 			(*sp->ite_putc)(ip, c, ip->cury, ip->curx, ATTR_INV);
65441480Smckusick 		}
65541480Smckusick 		else
65641480Smckusick 			(*sp->ite_putc)(ip, c, ip->cury, ip->curx, ATTR_NOR);
65741480Smckusick 		(*sp->ite_cursor)(ip, DRAW_CURSOR);
65841480Smckusick 		itecheckwrap(ip, sp);
65941480Smckusick 		break;
66041480Smckusick 	}
66141480Smckusick }
66241480Smckusick 
66341480Smckusick itecheckwrap(ip, sp)
66441480Smckusick      register struct ite_softc *ip;
66541480Smckusick      register struct itesw *sp;
66641480Smckusick {
66741480Smckusick 	if (++ip->curx == ip->cols) {
66841480Smckusick 		ip->curx = 0;
66941480Smckusick 		clr_attr(ip, ATTR_INV);
67041480Smckusick 		if (++ip->cury == ip->rows) {
67141480Smckusick 			--ip->cury;
67241480Smckusick 			(*sp->ite_scroll)(ip, 1, 0, 1, SCROLL_UP);
67341480Smckusick 			ite_clrtoeol(ip, sp, ip->cury, 0);
67441480Smckusick 			return;
67541480Smckusick 		}
67641480Smckusick 	}
67741480Smckusick 	(*sp->ite_cursor)(ip, MOVE_CURSOR);
67841480Smckusick }
67941480Smckusick 
68041480Smckusick ite_dchar(ip, sp)
68141480Smckusick      register struct ite_softc *ip;
68241480Smckusick      register struct itesw *sp;
68341480Smckusick {
68441480Smckusick 	(*sp->ite_scroll)(ip, ip->cury, ip->curx + 1, 1, SCROLL_LEFT);
68541480Smckusick 	attrmov(ip, ip->cury, ip->curx + 1, ip->cury, ip->curx,
68641480Smckusick 		1, ip->cols - ip->curx - 1);
68741480Smckusick 	attrclr(ip, ip->cury, ip->cols - 1, 1, 1);
68841480Smckusick 	(*sp->ite_putc)(ip, ' ', ip->cury, ip->cols - 1, ATTR_NOR);
68941480Smckusick 	(*sp->ite_cursor)(ip, DRAW_CURSOR);
69041480Smckusick }
69141480Smckusick 
69241480Smckusick ite_ichar(ip, sp)
69341480Smckusick      register struct ite_softc *ip;
69441480Smckusick      register struct itesw *sp;
69541480Smckusick {
69641480Smckusick 	(*sp->ite_scroll)(ip, ip->cury, ip->curx, 1, SCROLL_RIGHT);
69741480Smckusick 	attrmov(ip, ip->cury, ip->curx, ip->cury, ip->curx + 1,
69841480Smckusick 		1, ip->cols - ip->curx - 1);
69941480Smckusick 	attrclr(ip, ip->cury, ip->curx, 1, 1);
70041480Smckusick 	(*sp->ite_putc)(ip, ' ', ip->cury, ip->curx, ATTR_NOR);
70141480Smckusick 	(*sp->ite_cursor)(ip, DRAW_CURSOR);
70241480Smckusick }
70341480Smckusick 
70441480Smckusick ite_dline(ip, sp)
70541480Smckusick      register struct ite_softc *ip;
70641480Smckusick      register struct itesw *sp;
70741480Smckusick {
70841480Smckusick 	(*sp->ite_scroll)(ip, ip->cury + 1, 0, 1, SCROLL_UP);
70941480Smckusick 	attrmov(ip, ip->cury + 1, 0, ip->cury, 0,
71041480Smckusick 		ip->rows - ip->cury - 1, ip->cols);
71141480Smckusick 	ite_clrtoeol(ip, sp, ip->rows - 1, 0);
71241480Smckusick }
71341480Smckusick 
71441480Smckusick ite_iline(ip, sp)
71541480Smckusick      register struct ite_softc *ip;
71641480Smckusick      register struct itesw *sp;
71741480Smckusick {
71841480Smckusick 	(*sp->ite_scroll)(ip, ip->cury, 0, 1, SCROLL_DOWN);
71941480Smckusick 	attrmov(ip, ip->cury, 0, ip->cury + 1, 0,
72041480Smckusick 		ip->rows - ip->cury - 1, ip->cols);
72141480Smckusick 	ite_clrtoeol(ip, sp, ip->cury, 0);
72241480Smckusick }
72341480Smckusick 
72441480Smckusick ite_clrtoeol(ip, sp, y, x)
72541480Smckusick      register struct ite_softc *ip;
72641480Smckusick      register struct itesw *sp;
72741480Smckusick      register int y, x;
72841480Smckusick {
72941480Smckusick 	(*sp->ite_clear)(ip, y, x, 1, ip->cols - x);
73041480Smckusick 	attrclr(ip, y, x, 1, ip->cols - x);
73141480Smckusick 	(*sp->ite_cursor)(ip, DRAW_CURSOR);
73241480Smckusick }
73341480Smckusick 
73441480Smckusick ite_clrtoeos(ip, sp)
73541480Smckusick      register struct ite_softc *ip;
73641480Smckusick      register struct itesw *sp;
73741480Smckusick {
73841480Smckusick 	(*sp->ite_clear)(ip, ip->cury, 0, ip->rows - ip->cury, ip->cols);
73941480Smckusick 	attrclr(ip, ip->cury, 0, ip->rows - ip->cury, ip->cols);
74041480Smckusick 	(*sp->ite_cursor)(ip, DRAW_CURSOR);
74141480Smckusick }
74241480Smckusick 
74341480Smckusick /*
74441480Smckusick  * Console functions
74541480Smckusick  */
74645788Sbostic #include "../hp300/cons.h"
74741480Smckusick #include "grfioctl.h"
74841480Smckusick #include "grfvar.h"
74941480Smckusick 
75041480Smckusick #ifdef DEBUG
75141480Smckusick /*
75241480Smckusick  * Minimum ITE number at which to start looking for a console.
75341480Smckusick  * Setting to 0 will do normal search, 1 will skip first ITE device,
75441480Smckusick  * NITE will skip ITEs and use serial port.
75541480Smckusick  */
75641480Smckusick int	whichconsole = 0;
75741480Smckusick #endif
75841480Smckusick 
75941480Smckusick itecnprobe(cp)
76041480Smckusick 	struct consdev *cp;
76141480Smckusick {
76241480Smckusick 	register struct ite_softc *ip;
76341480Smckusick 	int i, maj, unit, pri;
76441480Smckusick 
76541480Smckusick 	/* locate the major number */
76641480Smckusick 	for (maj = 0; maj < nchrdev; maj++)
76741480Smckusick 		if (cdevsw[maj].d_open == iteopen)
76841480Smckusick 			break;
76941480Smckusick 
77041480Smckusick 	/* urk! */
77141480Smckusick 	grfconfig();
77241480Smckusick 
77341480Smckusick 	/* check all the individual displays and find the best */
77441480Smckusick 	unit = -1;
77541480Smckusick 	pri = CN_DEAD;
77641480Smckusick 	for (i = 0; i < NITE; i++) {
77741480Smckusick 		struct grf_softc *gp = &grf_softc[i];
77841480Smckusick 
77941480Smckusick 		ip = &ite_softc[i];
78041480Smckusick 		if ((gp->g_flags & GF_ALIVE) == 0)
78141480Smckusick 			continue;
78241480Smckusick 		ip->flags = (ITE_ALIVE|ITE_CONSOLE);
78341480Smckusick 
78441480Smckusick 		/* XXX - we need to do something about mapping these */
78541480Smckusick 		switch (gp->g_type) {
78641480Smckusick 
78741480Smckusick 		case GT_TOPCAT:
78841480Smckusick 		case GT_LRCATSEYE:
78941480Smckusick 		case GT_HRCCATSEYE:
79041480Smckusick 		case GT_HRMCATSEYE:
79141480Smckusick 			ip->type = ITE_TOPCAT;
79241480Smckusick 			break;
79341480Smckusick 		case GT_GATORBOX:
79441480Smckusick 			ip->type = ITE_GATORBOX;
79541480Smckusick 			break;
79641480Smckusick 		case GT_RENAISSANCE:
79741480Smckusick 			ip->type = ITE_RENAISSANCE;
79841480Smckusick 			break;
79941480Smckusick 		case GT_DAVINCI:
80041480Smckusick 			ip->type = ITE_DAVINCI;
80141480Smckusick 			break;
80241480Smckusick 		}
80341480Smckusick #ifdef DEBUG
80441480Smckusick 		if (i < whichconsole)
80541480Smckusick 			continue;
80641480Smckusick #endif
80741480Smckusick 		if ((int)gp->g_display.gd_regaddr == GRFIADDR) {
80841480Smckusick 			pri = CN_INTERNAL;
80941480Smckusick 			unit = i;
81041480Smckusick 		} else if (unit < 0) {
81141480Smckusick 			pri = CN_NORMAL;
81241480Smckusick 			unit = i;
81341480Smckusick 		}
81441480Smckusick 	}
81541480Smckusick 
81641480Smckusick 	/* initialize required fields */
81741480Smckusick 	cp->cn_dev = makedev(maj, unit);
81841480Smckusick 	cp->cn_tp = &ite_tty[unit];
81941480Smckusick 	cp->cn_pri = pri;
82041480Smckusick }
82141480Smckusick 
82241480Smckusick itecninit(cp)
82341480Smckusick 	struct consdev *cp;
82441480Smckusick {
82541480Smckusick 	int unit = UNIT(cp->cn_dev);
82641480Smckusick 	struct ite_softc *ip = &ite_softc[unit];
82741480Smckusick 
82841480Smckusick 	ip->attrbuf = console_attributes;
82941480Smckusick 	iteinit(cp->cn_dev);
83041480Smckusick 	ip->flags |= (ITE_ACTIVE|ITE_ISCONS);
83141480Smckusick 	kbd_tty = &ite_tty[unit];
83241480Smckusick }
83341480Smckusick 
83441480Smckusick /*ARGSUSED*/
83541480Smckusick itecngetc(dev)
83641480Smckusick 	dev_t dev;
83741480Smckusick {
83841480Smckusick 	register int c;
83941480Smckusick 	int stat;
84041480Smckusick 
84141480Smckusick 	c = kbdgetc(&stat);
84241480Smckusick 	switch ((stat >> KBD_SSHIFT) & KBD_SMASK) {
84341480Smckusick 	case KBD_SHIFT:
84441480Smckusick 		c = kbd_shiftmap[c & KBD_CHARMASK];
84541480Smckusick 		break;
84641480Smckusick 	case KBD_CTRL:
84741480Smckusick 		c = kbd_ctrlmap[c & KBD_CHARMASK];
84841480Smckusick 		break;
84941480Smckusick 	case KBD_KEY:
85041480Smckusick 		c = kbd_keymap[c & KBD_CHARMASK];
85141480Smckusick 		break;
85241480Smckusick 	default:
85341480Smckusick 		c = 0;
85441480Smckusick 		break;
85541480Smckusick 	}
85641480Smckusick 	return(c);
85741480Smckusick }
85841480Smckusick 
85941480Smckusick itecnputc(dev, c)
86041480Smckusick 	dev_t dev;
86141480Smckusick 	int c;
86241480Smckusick {
86341480Smckusick 	static int paniced = 0;
86441480Smckusick 	struct ite_softc *ip = &ite_softc[UNIT(dev)];
86541480Smckusick 	extern char *panicstr;
86641480Smckusick 
86741480Smckusick 	if (panicstr && !paniced &&
86841480Smckusick 	    (ip->flags & (ITE_ACTIVE|ITE_INGRF)) != ITE_ACTIVE) {
86941480Smckusick 		(void) iteon(dev, 3);
87041480Smckusick 		paniced = 1;
87141480Smckusick 	}
87241480Smckusick 	iteputchar(c, dev);
87341480Smckusick }
87441480Smckusick #endif
875