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