141480Smckusick /*
241480Smckusick * Copyright (c) 1988 University of Utah.
363148Sbostic * Copyright (c) 1990, 1993
463148Sbostic * The Regents of the University of California. 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 *
1257311Shibler * from: Utah $Hdr: ite.c 1.28 92/12/20$
1341480Smckusick *
14*68159Scgd * @(#)ite.c 8.3 (Berkeley) 01/09/95
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
3056504Sbostic #include <sys/param.h>
3156504Sbostic #include <sys/conf.h>
3256504Sbostic #include <sys/proc.h>
3356504Sbostic #include <sys/ioctl.h>
3456504Sbostic #include <sys/tty.h>
3556504Sbostic #include <sys/systm.h>
3656504Sbostic #include <sys/malloc.h>
3741480Smckusick
3856504Sbostic #include <hp/dev/grfioctl.h>
3956504Sbostic #include <hp/dev/grfvar.h>
4056504Sbostic #include <hp/dev/itevar.h>
4156504Sbostic #include <hp/dev/kbdmap.h>
4241480Smckusick
4341480Smckusick #define set_attr(ip, attr) ((ip)->attribute |= (attr))
4441480Smckusick #define clr_attr(ip, attr) ((ip)->attribute &= ~(attr))
4541480Smckusick
4641480Smckusick /*
4757311Shibler * No need to raise SPL above the HIL (the only thing that can
4857311Shibler * affect our state.
4957311Shibler */
5057311Shibler #include <hp/dev/hilreg.h>
5157311Shibler #define splite() splhil()
5257311Shibler
5357311Shibler /*
5441480Smckusick * # of chars are output in a single itestart() call.
5541480Smckusick * If this is too big, user processes will be blocked out for
5641480Smckusick * long periods of time while we are emptying the queue in itestart().
5741480Smckusick * If it is too small, console output will be very ragged.
5841480Smckusick */
5941480Smckusick int iteburst = 64;
6041480Smckusick
6141480Smckusick int nite = NITE;
6241480Smckusick struct tty *kbd_tty = NULL;
6341480Smckusick struct tty ite_tty[NITE];
6441480Smckusick struct ite_softc ite_softc[NITE];
6541480Smckusick
6657311Shibler void itestart(), iterestart();
6741480Smckusick extern struct tty *constty;
6841480Smckusick
6941480Smckusick /*
7041480Smckusick * Primary attribute buffer to be used by the first bitmapped console
7141480Smckusick * found. Secondary displays alloc the attribute buffer as needed.
7241480Smckusick * Size is based on a 68x128 display, which is currently our largest.
7341480Smckusick */
7441480Smckusick u_char console_attributes[0x2200];
7541480Smckusick
7657311Shibler #define ite_erasecursor(ip, sp) { \
7757311Shibler if ((ip)->flags & ITE_CURSORON) \
7857311Shibler (*(sp)->ite_cursor)((ip), ERASE_CURSOR); \
7957311Shibler }
8057311Shibler #define ite_drawcursor(ip, sp) { \
8157311Shibler if ((ip)->flags & ITE_CURSORON) \
8257311Shibler (*(sp)->ite_cursor)((ip), DRAW_CURSOR); \
8357311Shibler }
8457311Shibler #define ite_movecursor(ip, sp) { \
8557311Shibler if ((ip)->flags & ITE_CURSORON) \
8657311Shibler (*(sp)->ite_cursor)((ip), MOVE_CURSOR); \
8757311Shibler }
8857311Shibler
8941480Smckusick /*
9041480Smckusick * Perform functions necessary to setup device as a terminal emulator.
9141480Smckusick */
iteon(dev,flag)9241480Smckusick iteon(dev, flag)
9341480Smckusick dev_t dev;
9465645Sbostic int flag;
9541480Smckusick {
9641480Smckusick int unit = UNIT(dev);
9741480Smckusick struct tty *tp = &ite_tty[unit];
9841480Smckusick struct ite_softc *ip = &ite_softc[unit];
9941480Smckusick
10041480Smckusick if (unit < 0 || unit >= NITE || (ip->flags&ITE_ALIVE) == 0)
10141480Smckusick return(ENXIO);
10241480Smckusick /* force ite active, overriding graphics mode */
10341480Smckusick if (flag & 1) {
10441480Smckusick ip->flags |= ITE_ACTIVE;
10541480Smckusick ip->flags &= ~(ITE_INGRF|ITE_INITED);
10641480Smckusick }
10741480Smckusick /* leave graphics mode */
10841480Smckusick if (flag & 2) {
10941480Smckusick ip->flags &= ~ITE_INGRF;
11041480Smckusick if ((ip->flags & ITE_ACTIVE) == 0)
11141480Smckusick return(0);
11241480Smckusick }
11341480Smckusick ip->flags |= ITE_ACTIVE;
11441480Smckusick if (ip->flags & ITE_INGRF)
11541480Smckusick return(0);
11641480Smckusick if (kbd_tty == NULL || kbd_tty == tp) {
11741480Smckusick kbd_tty = tp;
11853923Shibler kbdenable(unit);
11941480Smckusick }
12041480Smckusick iteinit(dev);
12141480Smckusick return(0);
12241480Smckusick }
12341480Smckusick
iteinit(dev)12441480Smckusick iteinit(dev)
12541480Smckusick dev_t dev;
12641480Smckusick {
12741480Smckusick int unit = UNIT(dev);
12841480Smckusick struct ite_softc *ip = &ite_softc[unit];
12941480Smckusick
13041480Smckusick if (ip->flags & ITE_INITED)
13141480Smckusick return;
13241480Smckusick
13341480Smckusick ip->curx = 0;
13441480Smckusick ip->cury = 0;
13541480Smckusick ip->cursorx = 0;
13641480Smckusick ip->cursory = 0;
13741480Smckusick
13853923Shibler (*ip->isw->ite_init)(ip);
13957311Shibler ip->flags |= ITE_CURSORON;
14057311Shibler ite_drawcursor(ip, ip->isw);
14141480Smckusick
14241480Smckusick ip->attribute = 0;
14341480Smckusick if (ip->attrbuf == NULL)
14441480Smckusick ip->attrbuf = (u_char *)
14541480Smckusick malloc(ip->rows * ip->cols, M_DEVBUF, M_WAITOK);
14641480Smckusick bzero(ip->attrbuf, (ip->rows * ip->cols));
14741480Smckusick
14841480Smckusick ip->imode = 0;
14941480Smckusick ip->flags |= ITE_INITED;
15041480Smckusick }
15141480Smckusick
15241480Smckusick /*
15341480Smckusick * "Shut down" device as terminal emulator.
15441480Smckusick * Note that we do not deinit the console device unless forced.
15541480Smckusick * Deinit'ing the console every time leads to a very active
15641480Smckusick * screen when processing /etc/rc.
15741480Smckusick */
iteoff(dev,flag)15841480Smckusick iteoff(dev, flag)
15941480Smckusick dev_t dev;
16065645Sbostic int flag;
16141480Smckusick {
16241480Smckusick register struct ite_softc *ip = &ite_softc[UNIT(dev)];
16341480Smckusick
16458052Shibler if (flag & 2) {
16541480Smckusick ip->flags |= ITE_INGRF;
16658052Shibler ip->flags &= ~ITE_CURSORON;
16758052Shibler }
16841480Smckusick if ((ip->flags & ITE_ACTIVE) == 0)
16941480Smckusick return;
17041480Smckusick if ((flag & 1) ||
17158052Shibler (ip->flags & (ITE_INGRF|ITE_ISCONS|ITE_INITED)) == ITE_INITED)
17253923Shibler (*ip->isw->ite_deinit)(ip);
17341480Smckusick if ((flag & 2) == 0)
17441480Smckusick ip->flags &= ~ITE_ACTIVE;
17541480Smckusick }
17641480Smckusick
17749132Skarels /* ARGSUSED */
17849132Skarels #ifdef __STDC__
iteopen(dev_t dev,int mode,int devtype,struct proc * p)17949132Skarels iteopen(dev_t dev, int mode, int devtype, struct proc *p)
18049132Skarels #else
18149132Skarels iteopen(dev, mode, devtype, p)
18241480Smckusick dev_t dev;
18349132Skarels int mode, devtype;
18449132Skarels struct proc *p;
18549132Skarels #endif
18641480Smckusick {
18741480Smckusick int unit = UNIT(dev);
18841480Smckusick register struct tty *tp = &ite_tty[unit];
18941480Smckusick register struct ite_softc *ip = &ite_softc[unit];
19041480Smckusick register int error;
19141480Smckusick int first = 0;
19241480Smckusick
19343409Shibler if ((tp->t_state&(TS_ISOPEN|TS_XCLUDE)) == (TS_ISOPEN|TS_XCLUDE)
19449132Skarels && p->p_ucred->cr_uid != 0)
19541480Smckusick return (EBUSY);
19641480Smckusick if ((ip->flags & ITE_ACTIVE) == 0) {
19741480Smckusick error = iteon(dev, 0);
19841480Smckusick if (error)
19941480Smckusick return (error);
20041480Smckusick first = 1;
20141480Smckusick }
20241480Smckusick tp->t_oproc = itestart;
20341480Smckusick tp->t_param = NULL;
20441480Smckusick tp->t_dev = dev;
20541480Smckusick if ((tp->t_state&TS_ISOPEN) == 0) {
20641480Smckusick ttychars(tp);
20741480Smckusick tp->t_iflag = TTYDEF_IFLAG;
20841480Smckusick tp->t_oflag = TTYDEF_OFLAG;
20941480Smckusick tp->t_cflag = CS8|CREAD;
21041480Smckusick tp->t_lflag = TTYDEF_LFLAG;
21141480Smckusick tp->t_ispeed = tp->t_ospeed = TTYDEF_SPEED;
21241480Smckusick tp->t_state = TS_ISOPEN|TS_CARR_ON;
21341480Smckusick ttsetwater(tp);
21441480Smckusick }
21541480Smckusick error = (*linesw[tp->t_line].l_open)(dev, tp);
21641480Smckusick if (error == 0) {
21741480Smckusick tp->t_winsize.ws_row = ip->rows;
21841480Smckusick tp->t_winsize.ws_col = ip->cols;
21941480Smckusick } else if (first)
22041480Smckusick iteoff(dev, 0);
22141480Smckusick return (error);
22241480Smckusick }
22341480Smckusick
22441480Smckusick /*ARGSUSED*/
iteclose(dev,flag,mode,p)22549750Smarc iteclose(dev, flag, mode, p)
22641480Smckusick dev_t dev;
22749750Smarc int flag, mode;
22849750Smarc struct proc *p;
22941480Smckusick {
23041480Smckusick register struct tty *tp = &ite_tty[UNIT(dev)];
23141480Smckusick
23249750Smarc (*linesw[tp->t_line].l_close)(tp, flag);
23341480Smckusick ttyclose(tp);
23441480Smckusick iteoff(dev, 0);
23541480Smckusick return(0);
23641480Smckusick }
23741480Smckusick
iteread(dev,uio,flag)23841480Smckusick iteread(dev, uio, flag)
23941480Smckusick dev_t dev;
24041480Smckusick struct uio *uio;
24165645Sbostic int flag;
24241480Smckusick {
24341480Smckusick register struct tty *tp = &ite_tty[UNIT(dev)];
24441480Smckusick
24541480Smckusick return ((*linesw[tp->t_line].l_read)(tp, uio, flag));
24641480Smckusick }
24741480Smckusick
itewrite(dev,uio,flag)24841480Smckusick itewrite(dev, uio, flag)
24941480Smckusick dev_t dev;
25041480Smckusick struct uio *uio;
25165645Sbostic int flag;
25241480Smckusick {
25341480Smckusick int unit = UNIT(dev);
25441480Smckusick register struct tty *tp = &ite_tty[unit];
25541480Smckusick
25641480Smckusick if ((ite_softc[unit].flags & ITE_ISCONS) && constty &&
25741480Smckusick (constty->t_state&(TS_CARR_ON|TS_ISOPEN))==(TS_CARR_ON|TS_ISOPEN))
25841480Smckusick tp = constty;
25941480Smckusick return ((*linesw[tp->t_line].l_write)(tp, uio, flag));
26041480Smckusick }
26141480Smckusick
iteioctl(dev,cmd,addr,flag,p)26252417Smckusick iteioctl(dev, cmd, addr, flag, p)
26341480Smckusick dev_t dev;
264*68159Scgd u_long cmd;
26541480Smckusick caddr_t addr;
26652417Smckusick int flag;
26752417Smckusick struct proc *p;
26841480Smckusick {
26941480Smckusick register struct tty *tp = &ite_tty[UNIT(dev)];
27041480Smckusick int error;
27141480Smckusick
27252417Smckusick error = (*linesw[tp->t_line].l_ioctl)(tp, cmd, addr, flag, p);
27341480Smckusick if (error >= 0)
27441480Smckusick return (error);
27541480Smckusick error = ttioctl(tp, cmd, addr, flag);
27641480Smckusick if (error >= 0)
27741480Smckusick return (error);
27841480Smckusick return (ENOTTY);
27941480Smckusick }
28041480Smckusick
28152390Smckusick void
iterestart(tp)28257311Shibler iterestart(tp)
28357311Shibler register struct tty *tp;
28457311Shibler {
28557311Shibler register int s = splite();
28657311Shibler
28757311Shibler tp->t_state &= ~TS_TIMEOUT;
28857311Shibler itestart(tp);
28957311Shibler splx(s);
29057311Shibler }
29157311Shibler
29257311Shibler void
itestart(tp)29341480Smckusick itestart(tp)
29441480Smckusick register struct tty *tp;
29541480Smckusick {
29641480Smckusick register int cc, s;
29758052Shibler int hiwat = 0, hadcursor = 0;
29857311Shibler struct ite_softc *ip;
29941480Smckusick
30057311Shibler /*
30157311Shibler * (Potentially) lower priority. We only need to protect ourselves
30257311Shibler * from keyboard interrupts since that is all that can affect the
30357311Shibler * state of our tty (kernel printf doesn't go through this routine).
30457311Shibler */
30557311Shibler s = splite();
30641480Smckusick if (tp->t_state & (TS_TIMEOUT|TS_BUSY|TS_TTSTOP)) {
30741480Smckusick splx(s);
30841480Smckusick return;
30941480Smckusick }
31041480Smckusick tp->t_state |= TS_BUSY;
31141480Smckusick cc = tp->t_outq.c_cc;
31241480Smckusick if (cc <= tp->t_lowat) {
31341480Smckusick if (tp->t_state & TS_ASLEEP) {
31441480Smckusick tp->t_state &= ~TS_ASLEEP;
31552390Smckusick wakeup((caddr_t)&tp->t_outq);
31641480Smckusick }
31752530Storek selwakeup(&tp->t_wsel);
31841480Smckusick }
31941480Smckusick /*
32057311Shibler * Handle common (?) case
32141480Smckusick */
32257311Shibler if (cc == 1) {
32357311Shibler iteputchar(getc(&tp->t_outq), tp->t_dev);
32457311Shibler } else if (cc) {
32541480Smckusick /*
32657311Shibler * Limit the amount of output we do in one burst
32757311Shibler * to prevent hogging the CPU.
32841480Smckusick */
32957311Shibler if (cc > iteburst) {
33057311Shibler hiwat++;
33157311Shibler cc = iteburst;
33257311Shibler }
33357311Shibler /*
33457311Shibler * Turn off cursor while we output multiple characters.
33557311Shibler * Saves a lot of expensive window move operations.
33657311Shibler */
33757311Shibler ip = &ite_softc[UNIT(tp->t_dev)];
33858052Shibler if (ip->flags & ITE_CURSORON) {
33958052Shibler ite_erasecursor(ip, ip->isw);
34058052Shibler ip->flags &= ~ITE_CURSORON;
34158052Shibler hadcursor = 1;
34258052Shibler }
34357311Shibler while (--cc >= 0)
34457311Shibler iteputchar(getc(&tp->t_outq), tp->t_dev);
34558052Shibler if (hadcursor) {
34658052Shibler ip->flags |= ITE_CURSORON;
34758052Shibler ite_drawcursor(ip, ip->isw);
34858052Shibler }
34957311Shibler if (hiwat) {
35057311Shibler tp->t_state |= TS_TIMEOUT;
35157311Shibler timeout(iterestart, tp, 1);
35257311Shibler }
35341480Smckusick }
35441480Smckusick tp->t_state &= ~TS_BUSY;
35541480Smckusick splx(s);
35641480Smckusick }
35741480Smckusick
itefilter(stat,c)35841480Smckusick itefilter(stat, c)
35965645Sbostic register char stat, c;
36041480Smckusick {
36141480Smckusick static int capsmode = 0;
36241480Smckusick static int metamode = 0;
36341480Smckusick register char code, *str;
36441480Smckusick
36541480Smckusick if (kbd_tty == NULL)
36641480Smckusick return;
36741480Smckusick
36841480Smckusick switch (c & 0xFF) {
36941480Smckusick case KBD_CAPSLOCK:
37041480Smckusick capsmode = !capsmode;
37141480Smckusick return;
37241480Smckusick
37341480Smckusick case KBD_EXT_LEFT_DOWN:
37441480Smckusick case KBD_EXT_RIGHT_DOWN:
37541480Smckusick metamode = 1;
37641480Smckusick return;
37741480Smckusick
37841480Smckusick case KBD_EXT_LEFT_UP:
37941480Smckusick case KBD_EXT_RIGHT_UP:
38041480Smckusick metamode = 0;
38141480Smckusick return;
38241480Smckusick }
38341480Smckusick
38441480Smckusick c &= KBD_CHARMASK;
38541480Smckusick switch ((stat>>KBD_SSHIFT) & KBD_SMASK) {
38641480Smckusick
38741480Smckusick case KBD_KEY:
38841480Smckusick if (!capsmode) {
38941480Smckusick code = kbd_keymap[c];
39041480Smckusick break;
39141480Smckusick }
39265645Sbostic /* FALLTHROUGH */
39341480Smckusick
39441480Smckusick case KBD_SHIFT:
39541480Smckusick code = kbd_shiftmap[c];
39641480Smckusick break;
39741480Smckusick
39841480Smckusick case KBD_CTRL:
39941480Smckusick code = kbd_ctrlmap[c];
40041480Smckusick break;
40141480Smckusick
40241480Smckusick case KBD_CTRLSHIFT:
40341480Smckusick code = kbd_ctrlshiftmap[c];
40441480Smckusick break;
40541480Smckusick }
40641480Smckusick
40741480Smckusick if (code == NULL && (str = kbd_stringmap[c]) != NULL) {
40841480Smckusick while (*str)
40941480Smckusick (*linesw[kbd_tty->t_line].l_rint)(*str++, kbd_tty);
41041480Smckusick } else {
41141480Smckusick if (metamode)
41241480Smckusick code |= 0x80;
41341480Smckusick (*linesw[kbd_tty->t_line].l_rint)(code, kbd_tty);
41441480Smckusick }
41541480Smckusick }
41641480Smckusick
iteputchar(c,dev)41741480Smckusick iteputchar(c, dev)
41841480Smckusick register int c;
41941480Smckusick dev_t dev;
42041480Smckusick {
42141480Smckusick int unit = UNIT(dev);
42241480Smckusick register struct ite_softc *ip = &ite_softc[unit];
42353923Shibler register struct itesw *sp = ip->isw;
42441480Smckusick register int n;
42541480Smckusick
42641480Smckusick if ((ip->flags & (ITE_ACTIVE|ITE_INGRF)) != ITE_ACTIVE)
42741480Smckusick return;
42841480Smckusick
42941480Smckusick if (ip->escape) {
43041480Smckusick doesc:
43141480Smckusick switch (ip->escape) {
43241480Smckusick
43341480Smckusick case '&': /* Next can be a,d, or s */
43441480Smckusick if (ip->fpd++) {
43541480Smckusick ip->escape = c;
43641480Smckusick ip->fpd = 0;
43741480Smckusick }
43841480Smckusick return;
43941480Smckusick
44041480Smckusick case 'a': /* cursor change */
44141480Smckusick switch (c) {
44241480Smckusick
44341480Smckusick case 'Y': /* Only y coord. */
44455069Spendry ip->cury = min(ip->pos, ip->rows-1);
44541480Smckusick ip->pos = 0;
44641480Smckusick ip->escape = 0;
44757311Shibler ite_movecursor(ip, sp);
44841480Smckusick clr_attr(ip, ATTR_INV);
44941480Smckusick break;
45041480Smckusick
45141480Smckusick case 'y': /* y coord first */
45255069Spendry ip->cury = min(ip->pos, ip->rows-1);
45341480Smckusick ip->pos = 0;
45441480Smckusick ip->fpd = 0;
45541480Smckusick break;
45641480Smckusick
45741480Smckusick case 'C': /* x coord */
45855069Spendry ip->curx = min(ip->pos, ip->cols-1);
45941480Smckusick ip->pos = 0;
46041480Smckusick ip->escape = 0;
46157311Shibler ite_movecursor(ip, sp);
46241480Smckusick clr_attr(ip, ATTR_INV);
46341480Smckusick break;
46441480Smckusick
46541480Smckusick default: /* Possibly a 3 digit number. */
46641480Smckusick if (c >= '0' && c <= '9' && ip->fpd < 3) {
46741480Smckusick ip->pos = ip->pos * 10 + (c - '0');
46841480Smckusick ip->fpd++;
46941480Smckusick } else {
47041480Smckusick ip->pos = 0;
47141480Smckusick ip->escape = 0;
47241480Smckusick }
47341480Smckusick break;
47441480Smckusick }
47541480Smckusick return;
47641480Smckusick
47741480Smckusick case 'd': /* attribute change */
47841480Smckusick switch (c) {
47941480Smckusick
48041480Smckusick case 'B':
48141480Smckusick set_attr(ip, ATTR_INV);
48241480Smckusick break;
48341480Smckusick case 'D':
48441480Smckusick /* XXX: we don't do anything for underline */
48541480Smckusick set_attr(ip, ATTR_UL);
48641480Smckusick break;
48741480Smckusick case '@':
48841480Smckusick clr_attr(ip, ATTR_ALL);
48941480Smckusick break;
49041480Smckusick }
49141480Smckusick ip->escape = 0;
49241480Smckusick return;
49341480Smckusick
49441480Smckusick case 's': /* keypad control */
49541480Smckusick switch (ip->fpd) {
49641480Smckusick
49741480Smckusick case 0:
49841480Smckusick ip->hold = c;
49941480Smckusick ip->fpd++;
50041480Smckusick return;
50141480Smckusick
50241480Smckusick case 1:
50341480Smckusick if (c == 'A') {
50441480Smckusick switch (ip->hold) {
50541480Smckusick
50641480Smckusick case '0':
50741480Smckusick clr_attr(ip, ATTR_KPAD);
50841480Smckusick break;
50941480Smckusick case '1':
51041480Smckusick set_attr(ip, ATTR_KPAD);
51141480Smckusick break;
51241480Smckusick }
51341480Smckusick }
51441480Smckusick ip->hold = 0;
51541480Smckusick }
51641480Smckusick ip->escape = 0;
51741480Smckusick return;
51841480Smckusick
51941480Smckusick case 'i': /* back tab */
52041480Smckusick if (ip->curx > TABSIZE) {
52141480Smckusick n = ip->curx - (ip->curx & (TABSIZE - 1));
52241480Smckusick ip->curx -= n;
52341480Smckusick } else
52441480Smckusick ip->curx = 0;
52557311Shibler ite_movecursor(ip, sp);
52641480Smckusick ip->escape = 0;
52741480Smckusick return;
52841480Smckusick
52941480Smckusick case '3': /* clear all tabs */
53041480Smckusick goto ignore;
53141480Smckusick
53241480Smckusick case 'K': /* clear_eol */
53341480Smckusick ite_clrtoeol(ip, sp, ip->cury, ip->curx);
53441480Smckusick ip->escape = 0;
53541480Smckusick return;
53641480Smckusick
53741480Smckusick case 'J': /* clear_eos */
53841480Smckusick ite_clrtoeos(ip, sp);
53941480Smckusick ip->escape = 0;
54041480Smckusick return;
54141480Smckusick
54241480Smckusick case 'B': /* cursor down 1 line */
54341480Smckusick if (++ip->cury == ip->rows) {
54441480Smckusick --ip->cury;
54557311Shibler ite_erasecursor(ip, sp);
54641480Smckusick (*sp->ite_scroll)(ip, 1, 0, 1, SCROLL_UP);
54741480Smckusick ite_clrtoeol(ip, sp, ip->cury, 0);
54841480Smckusick }
54941480Smckusick else
55057311Shibler ite_movecursor(ip, sp);
55141480Smckusick clr_attr(ip, ATTR_INV);
55241480Smckusick ip->escape = 0;
55341480Smckusick return;
55441480Smckusick
55541480Smckusick case 'C': /* cursor forward 1 char */
55641480Smckusick ip->escape = 0;
55741480Smckusick itecheckwrap(ip, sp);
55841480Smckusick return;
55941480Smckusick
56041480Smckusick case 'A': /* cursor up 1 line */
56141480Smckusick if (ip->cury > 0) {
56241480Smckusick ip->cury--;
56357311Shibler ite_movecursor(ip, sp);
56441480Smckusick }
56541480Smckusick ip->escape = 0;
56641480Smckusick clr_attr(ip, ATTR_INV);
56741480Smckusick return;
56841480Smckusick
56941480Smckusick case 'P': /* delete character */
57041480Smckusick ite_dchar(ip, sp);
57141480Smckusick ip->escape = 0;
57241480Smckusick return;
57341480Smckusick
57441480Smckusick case 'M': /* delete line */
57541480Smckusick ite_dline(ip, sp);
57641480Smckusick ip->escape = 0;
57741480Smckusick return;
57841480Smckusick
57941480Smckusick case 'Q': /* enter insert mode */
58041480Smckusick ip->imode = 1;
58141480Smckusick ip->escape = 0;
58241480Smckusick return;
58341480Smckusick
58441480Smckusick case 'R': /* exit insert mode */
58541480Smckusick ip->imode = 0;
58641480Smckusick ip->escape = 0;
58741480Smckusick return;
58841480Smckusick
58941480Smckusick case 'L': /* insert blank line */
59041480Smckusick ite_iline(ip, sp);
59141480Smckusick ip->escape = 0;
59241480Smckusick return;
59341480Smckusick
59441480Smckusick case 'h': /* home key */
59541480Smckusick ip->cury = ip->curx = 0;
59657311Shibler ite_movecursor(ip, sp);
59741480Smckusick ip->escape = 0;
59841480Smckusick return;
59941480Smckusick
60041480Smckusick case 'D': /* left arrow key */
60141480Smckusick if (ip->curx > 0) {
60241480Smckusick ip->curx--;
60357311Shibler ite_movecursor(ip, sp);
60441480Smckusick }
60541480Smckusick ip->escape = 0;
60641480Smckusick return;
60741480Smckusick
60841480Smckusick case '1': /* set tab in all rows */
60941480Smckusick goto ignore;
61041480Smckusick
61141480Smckusick case ESC:
61241480Smckusick if ((ip->escape = c) == ESC)
61341480Smckusick break;
61441480Smckusick ip->fpd = 0;
61541480Smckusick goto doesc;
61641480Smckusick
61741480Smckusick default:
61841480Smckusick ignore:
61941480Smckusick ip->escape = 0;
62041480Smckusick return;
62141480Smckusick
62241480Smckusick }
62341480Smckusick }
62441480Smckusick
62541480Smckusick switch (c &= 0x7F) {
62641480Smckusick
62741480Smckusick case '\n':
62841480Smckusick
62941480Smckusick if (++ip->cury == ip->rows) {
63041480Smckusick --ip->cury;
63157311Shibler ite_erasecursor(ip, sp);
63241480Smckusick (*sp->ite_scroll)(ip, 1, 0, 1, SCROLL_UP);
63341480Smckusick ite_clrtoeol(ip, sp, ip->cury, 0);
63457311Shibler } else
63557311Shibler ite_movecursor(ip, sp);
63641480Smckusick clr_attr(ip, ATTR_INV);
63741480Smckusick break;
63841480Smckusick
63941480Smckusick case '\r':
64041480Smckusick if (ip->curx) {
64141480Smckusick ip->curx = 0;
64257311Shibler ite_movecursor(ip, sp);
64341480Smckusick }
64441480Smckusick break;
64541480Smckusick
64641480Smckusick case '\b':
64741480Smckusick if (--ip->curx < 0)
64841480Smckusick ip->curx = 0;
64941480Smckusick else
65057311Shibler ite_movecursor(ip, sp);
65141480Smckusick break;
65241480Smckusick
65341480Smckusick case '\t':
65441480Smckusick if (ip->curx < TABEND(unit)) {
65541480Smckusick n = TABSIZE - (ip->curx & (TABSIZE - 1));
65641480Smckusick ip->curx += n;
65757311Shibler ite_movecursor(ip, sp);
65841480Smckusick } else
65941480Smckusick itecheckwrap(ip, sp);
66041480Smckusick break;
66141480Smckusick
66241480Smckusick case CTRL('G'):
66341480Smckusick if (&ite_tty[unit] == kbd_tty)
66453923Shibler kbdbell(unit);
66541480Smckusick break;
66641480Smckusick
66741480Smckusick case ESC:
66841480Smckusick ip->escape = ESC;
66941480Smckusick break;
67041480Smckusick
67141480Smckusick default:
67241480Smckusick if (c < ' ' || c == DEL)
67341480Smckusick break;
67441480Smckusick if (ip->imode)
67541480Smckusick ite_ichar(ip, sp);
67641480Smckusick if ((ip->attribute & ATTR_INV) || attrtest(ip, ATTR_INV)) {
67741480Smckusick attrset(ip, ATTR_INV);
67841480Smckusick (*sp->ite_putc)(ip, c, ip->cury, ip->curx, ATTR_INV);
67957311Shibler } else
68041480Smckusick (*sp->ite_putc)(ip, c, ip->cury, ip->curx, ATTR_NOR);
68157311Shibler ite_drawcursor(ip, sp);
68241480Smckusick itecheckwrap(ip, sp);
68341480Smckusick break;
68441480Smckusick }
68541480Smckusick }
68641480Smckusick
itecheckwrap(ip,sp)68741480Smckusick itecheckwrap(ip, sp)
68841480Smckusick register struct ite_softc *ip;
68941480Smckusick register struct itesw *sp;
69041480Smckusick {
69141480Smckusick if (++ip->curx == ip->cols) {
69241480Smckusick ip->curx = 0;
69341480Smckusick clr_attr(ip, ATTR_INV);
69441480Smckusick if (++ip->cury == ip->rows) {
69541480Smckusick --ip->cury;
69657311Shibler ite_erasecursor(ip, sp);
69741480Smckusick (*sp->ite_scroll)(ip, 1, 0, 1, SCROLL_UP);
69841480Smckusick ite_clrtoeol(ip, sp, ip->cury, 0);
69941480Smckusick return;
70041480Smckusick }
70141480Smckusick }
70257311Shibler ite_movecursor(ip, sp);
70341480Smckusick }
70441480Smckusick
ite_dchar(ip,sp)70541480Smckusick ite_dchar(ip, sp)
70641480Smckusick register struct ite_softc *ip;
70741480Smckusick register struct itesw *sp;
70841480Smckusick {
70957311Shibler if (ip->curx < ip->cols - 1) {
71057311Shibler ite_erasecursor(ip, sp);
71157311Shibler (*sp->ite_scroll)(ip, ip->cury, ip->curx + 1, 1, SCROLL_LEFT);
71257311Shibler attrmov(ip, ip->cury, ip->curx + 1, ip->cury, ip->curx,
71357311Shibler 1, ip->cols - ip->curx - 1);
71457311Shibler }
71541480Smckusick attrclr(ip, ip->cury, ip->cols - 1, 1, 1);
71641480Smckusick (*sp->ite_putc)(ip, ' ', ip->cury, ip->cols - 1, ATTR_NOR);
71757311Shibler ite_drawcursor(ip, sp);
71841480Smckusick }
71941480Smckusick
ite_ichar(ip,sp)72041480Smckusick ite_ichar(ip, sp)
72141480Smckusick register struct ite_softc *ip;
72241480Smckusick register struct itesw *sp;
72341480Smckusick {
72457311Shibler if (ip->curx < ip->cols - 1) {
72557311Shibler ite_erasecursor(ip, sp);
72657311Shibler (*sp->ite_scroll)(ip, ip->cury, ip->curx, 1, SCROLL_RIGHT);
72757311Shibler attrmov(ip, ip->cury, ip->curx, ip->cury, ip->curx + 1,
72857311Shibler 1, ip->cols - ip->curx - 1);
72957311Shibler }
73041480Smckusick attrclr(ip, ip->cury, ip->curx, 1, 1);
73141480Smckusick (*sp->ite_putc)(ip, ' ', ip->cury, ip->curx, ATTR_NOR);
73257311Shibler ite_drawcursor(ip, sp);
73341480Smckusick }
73441480Smckusick
ite_dline(ip,sp)73541480Smckusick ite_dline(ip, sp)
73641480Smckusick register struct ite_softc *ip;
73741480Smckusick register struct itesw *sp;
73841480Smckusick {
73957311Shibler if (ip->cury < ip->rows - 1) {
74057311Shibler ite_erasecursor(ip, sp);
74157311Shibler (*sp->ite_scroll)(ip, ip->cury + 1, 0, 1, SCROLL_UP);
74257311Shibler attrmov(ip, ip->cury + 1, 0, ip->cury, 0,
74357311Shibler ip->rows - ip->cury - 1, ip->cols);
74457311Shibler }
74541480Smckusick ite_clrtoeol(ip, sp, ip->rows - 1, 0);
74641480Smckusick }
74741480Smckusick
ite_iline(ip,sp)74841480Smckusick ite_iline(ip, sp)
74941480Smckusick register struct ite_softc *ip;
75041480Smckusick register struct itesw *sp;
75141480Smckusick {
75257311Shibler if (ip->cury < ip->rows - 1) {
75357311Shibler ite_erasecursor(ip, sp);
75457311Shibler (*sp->ite_scroll)(ip, ip->cury, 0, 1, SCROLL_DOWN);
75557311Shibler attrmov(ip, ip->cury, 0, ip->cury + 1, 0,
75657311Shibler ip->rows - ip->cury - 1, ip->cols);
75757311Shibler }
75841480Smckusick ite_clrtoeol(ip, sp, ip->cury, 0);
75941480Smckusick }
76041480Smckusick
ite_clrtoeol(ip,sp,y,x)76141480Smckusick ite_clrtoeol(ip, sp, y, x)
76241480Smckusick register struct ite_softc *ip;
76341480Smckusick register struct itesw *sp;
76441480Smckusick register int y, x;
76541480Smckusick {
76641480Smckusick (*sp->ite_clear)(ip, y, x, 1, ip->cols - x);
76741480Smckusick attrclr(ip, y, x, 1, ip->cols - x);
76857311Shibler ite_drawcursor(ip, sp);
76941480Smckusick }
77041480Smckusick
ite_clrtoeos(ip,sp)77141480Smckusick ite_clrtoeos(ip, sp)
77241480Smckusick register struct ite_softc *ip;
77341480Smckusick register struct itesw *sp;
77441480Smckusick {
77541480Smckusick (*sp->ite_clear)(ip, ip->cury, 0, ip->rows - ip->cury, ip->cols);
77641480Smckusick attrclr(ip, ip->cury, 0, ip->rows - ip->cury, ip->cols);
77757311Shibler ite_drawcursor(ip, sp);
77841480Smckusick }
77941480Smckusick
78041480Smckusick /*
78141480Smckusick * Console functions
78241480Smckusick */
78356504Sbostic #include <hp/dev/cons.h>
78453923Shibler #ifdef hp300
78556504Sbostic #include <hp/dev/grfreg.h>
78653923Shibler #endif
78741480Smckusick
78841480Smckusick #ifdef DEBUG
78941480Smckusick /*
79041480Smckusick * Minimum ITE number at which to start looking for a console.
79141480Smckusick * Setting to 0 will do normal search, 1 will skip first ITE device,
79241480Smckusick * NITE will skip ITEs and use serial port.
79341480Smckusick */
79441480Smckusick int whichconsole = 0;
79541480Smckusick #endif
79641480Smckusick
79741480Smckusick itecnprobe(cp)
79841480Smckusick struct consdev *cp;
79941480Smckusick {
80041480Smckusick register struct ite_softc *ip;
80153923Shibler int i, sw, maj, unit, pri;
80241480Smckusick
80341480Smckusick /* locate the major number */
80441480Smckusick for (maj = 0; maj < nchrdev; maj++)
80541480Smckusick if (cdevsw[maj].d_open == iteopen)
80641480Smckusick break;
80741480Smckusick
80841480Smckusick /* urk! */
80941480Smckusick grfconfig();
81041480Smckusick
81141480Smckusick /* check all the individual displays and find the best */
81241480Smckusick unit = -1;
81341480Smckusick pri = CN_DEAD;
81441480Smckusick for (i = 0; i < NITE; i++) {
81541480Smckusick struct grf_softc *gp = &grf_softc[i];
81641480Smckusick
81741480Smckusick ip = &ite_softc[i];
81841480Smckusick if ((gp->g_flags & GF_ALIVE) == 0)
81941480Smckusick continue;
82041480Smckusick ip->flags = (ITE_ALIVE|ITE_CONSOLE);
82141480Smckusick
82253923Shibler /* locate the proper switch table. */
82353923Shibler for (sw = 0; sw < nitesw; sw++)
82453923Shibler if (itesw[sw].ite_hwid == gp->g_sw->gd_hwid)
82553923Shibler break;
82641480Smckusick
82753923Shibler if (sw == nitesw)
82853923Shibler continue;
82941480Smckusick #ifdef DEBUG
83041480Smckusick if (i < whichconsole)
83141480Smckusick continue;
83241480Smckusick #endif
83353923Shibler ip->isw = &itesw[sw];
83453923Shibler ip->grf = gp;
83553923Shibler #ifdef hp300
83641480Smckusick if ((int)gp->g_display.gd_regaddr == GRFIADDR) {
83741480Smckusick pri = CN_INTERNAL;
83841480Smckusick unit = i;
83941480Smckusick } else if (unit < 0) {
84041480Smckusick pri = CN_NORMAL;
84141480Smckusick unit = i;
84241480Smckusick }
84353923Shibler #endif
84453923Shibler #ifdef hp800
84553923Shibler /* XXX use the first one for now */
84653923Shibler if (unit < 0) {
84753923Shibler pri = CN_INTERNAL;
84853923Shibler unit = i;
84953923Shibler }
85053923Shibler #endif
85141480Smckusick }
85241480Smckusick
85341480Smckusick /* initialize required fields */
85441480Smckusick cp->cn_dev = makedev(maj, unit);
85541480Smckusick cp->cn_tp = &ite_tty[unit];
85641480Smckusick cp->cn_pri = pri;
85741480Smckusick }
85841480Smckusick
85941480Smckusick itecninit(cp)
86041480Smckusick struct consdev *cp;
86141480Smckusick {
86241480Smckusick int unit = UNIT(cp->cn_dev);
86341480Smckusick struct ite_softc *ip = &ite_softc[unit];
86441480Smckusick
86541480Smckusick ip->attrbuf = console_attributes;
86641480Smckusick iteinit(cp->cn_dev);
86741480Smckusick ip->flags |= (ITE_ACTIVE|ITE_ISCONS);
86841480Smckusick kbd_tty = &ite_tty[unit];
86941480Smckusick }
87041480Smckusick
87141480Smckusick /*ARGSUSED*/
itecngetc(dev)87241480Smckusick itecngetc(dev)
87341480Smckusick dev_t dev;
87441480Smckusick {
87541480Smckusick register int c;
87641480Smckusick int stat;
87741480Smckusick
87853923Shibler c = kbdgetc(0, &stat); /* XXX always read from keyboard 0 for now */
87941480Smckusick switch ((stat >> KBD_SSHIFT) & KBD_SMASK) {
88041480Smckusick case KBD_SHIFT:
88141480Smckusick c = kbd_shiftmap[c & KBD_CHARMASK];
88241480Smckusick break;
88341480Smckusick case KBD_CTRL:
88441480Smckusick c = kbd_ctrlmap[c & KBD_CHARMASK];
88541480Smckusick break;
88641480Smckusick case KBD_KEY:
88741480Smckusick c = kbd_keymap[c & KBD_CHARMASK];
88841480Smckusick break;
88941480Smckusick default:
89041480Smckusick c = 0;
89141480Smckusick break;
89241480Smckusick }
89341480Smckusick return(c);
89441480Smckusick }
89541480Smckusick
itecnputc(dev,c)89641480Smckusick itecnputc(dev, c)
89741480Smckusick dev_t dev;
89841480Smckusick int c;
89941480Smckusick {
90041480Smckusick static int paniced = 0;
90141480Smckusick struct ite_softc *ip = &ite_softc[UNIT(dev)];
90241480Smckusick
90341480Smckusick if (panicstr && !paniced &&
90441480Smckusick (ip->flags & (ITE_ACTIVE|ITE_INGRF)) != ITE_ACTIVE) {
90541480Smckusick (void) iteon(dev, 3);
90641480Smckusick paniced = 1;
90741480Smckusick }
90841480Smckusick iteputchar(c, dev);
90941480Smckusick }
91041480Smckusick #endif
911