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 * 1253923Shibler * from: Utah $Hdr: ite.c 1.24 92/01/21$ 1341480Smckusick * 14*56504Sbostic * @(#)ite.c 7.14 (Berkeley) 10/11/92 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*56504Sbostic #include <sys/param.h> 31*56504Sbostic #include <sys/conf.h> 32*56504Sbostic #include <sys/proc.h> 33*56504Sbostic #include <sys/ioctl.h> 34*56504Sbostic #include <sys/tty.h> 35*56504Sbostic #include <sys/systm.h> 36*56504Sbostic #include <sys/malloc.h> 3741480Smckusick 38*56504Sbostic #include <hp/dev/grfioctl.h> 39*56504Sbostic #include <hp/dev/grfvar.h> 40*56504Sbostic #include <hp/dev/itevar.h> 41*56504Sbostic #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 /* 4741480Smckusick * # of chars are output in a single itestart() call. 4841480Smckusick * If this is too big, user processes will be blocked out for 4941480Smckusick * long periods of time while we are emptying the queue in itestart(). 5041480Smckusick * If it is too small, console output will be very ragged. 5141480Smckusick */ 5241480Smckusick int iteburst = 64; 5341480Smckusick 5441480Smckusick int nite = NITE; 5541480Smckusick struct tty *kbd_tty = NULL; 5641480Smckusick struct tty ite_tty[NITE]; 5741480Smckusick struct ite_softc ite_softc[NITE]; 5841480Smckusick 5952390Smckusick void itestart(); 6054769Storek extern void ttrstrt __P((void *)); 6141480Smckusick extern struct tty *constty; 6241480Smckusick 6341480Smckusick /* 6441480Smckusick * Primary attribute buffer to be used by the first bitmapped console 6541480Smckusick * found. Secondary displays alloc the attribute buffer as needed. 6641480Smckusick * Size is based on a 68x128 display, which is currently our largest. 6741480Smckusick */ 6841480Smckusick u_char console_attributes[0x2200]; 6941480Smckusick 7041480Smckusick /* 7141480Smckusick * Perform functions necessary to setup device as a terminal emulator. 7241480Smckusick */ 7341480Smckusick iteon(dev, flag) 7441480Smckusick dev_t dev; 7541480Smckusick { 7641480Smckusick int unit = UNIT(dev); 7741480Smckusick struct tty *tp = &ite_tty[unit]; 7841480Smckusick struct ite_softc *ip = &ite_softc[unit]; 7941480Smckusick 8041480Smckusick if (unit < 0 || unit >= NITE || (ip->flags&ITE_ALIVE) == 0) 8141480Smckusick return(ENXIO); 8241480Smckusick /* force ite active, overriding graphics mode */ 8341480Smckusick if (flag & 1) { 8441480Smckusick ip->flags |= ITE_ACTIVE; 8541480Smckusick ip->flags &= ~(ITE_INGRF|ITE_INITED); 8641480Smckusick } 8741480Smckusick /* leave graphics mode */ 8841480Smckusick if (flag & 2) { 8941480Smckusick ip->flags &= ~ITE_INGRF; 9041480Smckusick if ((ip->flags & ITE_ACTIVE) == 0) 9141480Smckusick return(0); 9241480Smckusick } 9341480Smckusick ip->flags |= ITE_ACTIVE; 9441480Smckusick if (ip->flags & ITE_INGRF) 9541480Smckusick return(0); 9641480Smckusick if (kbd_tty == NULL || kbd_tty == tp) { 9741480Smckusick kbd_tty = tp; 9853923Shibler kbdenable(unit); 9941480Smckusick } 10041480Smckusick iteinit(dev); 10141480Smckusick return(0); 10241480Smckusick } 10341480Smckusick 10441480Smckusick iteinit(dev) 10541480Smckusick dev_t dev; 10641480Smckusick { 10741480Smckusick int unit = UNIT(dev); 10841480Smckusick struct ite_softc *ip = &ite_softc[unit]; 10941480Smckusick 11041480Smckusick if (ip->flags & ITE_INITED) 11141480Smckusick return; 11241480Smckusick 11341480Smckusick ip->curx = 0; 11441480Smckusick ip->cury = 0; 11541480Smckusick ip->cursorx = 0; 11641480Smckusick ip->cursory = 0; 11741480Smckusick 11853923Shibler (*ip->isw->ite_init)(ip); 11953923Shibler (*ip->isw->ite_cursor)(ip, DRAW_CURSOR); 12041480Smckusick 12141480Smckusick ip->attribute = 0; 12241480Smckusick if (ip->attrbuf == NULL) 12341480Smckusick ip->attrbuf = (u_char *) 12441480Smckusick malloc(ip->rows * ip->cols, M_DEVBUF, M_WAITOK); 12541480Smckusick bzero(ip->attrbuf, (ip->rows * ip->cols)); 12641480Smckusick 12741480Smckusick ip->imode = 0; 12841480Smckusick ip->flags |= ITE_INITED; 12941480Smckusick } 13041480Smckusick 13141480Smckusick /* 13241480Smckusick * "Shut down" device as terminal emulator. 13341480Smckusick * Note that we do not deinit the console device unless forced. 13441480Smckusick * Deinit'ing the console every time leads to a very active 13541480Smckusick * screen when processing /etc/rc. 13641480Smckusick */ 13741480Smckusick iteoff(dev, flag) 13841480Smckusick dev_t dev; 13941480Smckusick { 14041480Smckusick register struct ite_softc *ip = &ite_softc[UNIT(dev)]; 14141480Smckusick 14241480Smckusick if (flag & 2) 14341480Smckusick ip->flags |= ITE_INGRF; 14441480Smckusick if ((ip->flags & ITE_ACTIVE) == 0) 14541480Smckusick return; 14641480Smckusick if ((flag & 1) || 14741480Smckusick (ip->flags & (ITE_INGRF|ITE_ISCONS|ITE_INITED)) == ITE_INITED) 14853923Shibler (*ip->isw->ite_deinit)(ip); 14941480Smckusick if ((flag & 2) == 0) 15041480Smckusick ip->flags &= ~ITE_ACTIVE; 15141480Smckusick } 15241480Smckusick 15349132Skarels /* ARGSUSED */ 15449132Skarels #ifdef __STDC__ 15549132Skarels iteopen(dev_t dev, int mode, int devtype, struct proc *p) 15649132Skarels #else 15749132Skarels iteopen(dev, mode, devtype, p) 15841480Smckusick dev_t dev; 15949132Skarels int mode, devtype; 16049132Skarels struct proc *p; 16149132Skarels #endif 16241480Smckusick { 16341480Smckusick int unit = UNIT(dev); 16441480Smckusick register struct tty *tp = &ite_tty[unit]; 16541480Smckusick register struct ite_softc *ip = &ite_softc[unit]; 16641480Smckusick register int error; 16741480Smckusick int first = 0; 16841480Smckusick 16943409Shibler if ((tp->t_state&(TS_ISOPEN|TS_XCLUDE)) == (TS_ISOPEN|TS_XCLUDE) 17049132Skarels && p->p_ucred->cr_uid != 0) 17141480Smckusick return (EBUSY); 17241480Smckusick if ((ip->flags & ITE_ACTIVE) == 0) { 17341480Smckusick error = iteon(dev, 0); 17441480Smckusick if (error) 17541480Smckusick return (error); 17641480Smckusick first = 1; 17741480Smckusick } 17841480Smckusick tp->t_oproc = itestart; 17941480Smckusick tp->t_param = NULL; 18041480Smckusick tp->t_dev = dev; 18141480Smckusick if ((tp->t_state&TS_ISOPEN) == 0) { 18241480Smckusick ttychars(tp); 18341480Smckusick tp->t_iflag = TTYDEF_IFLAG; 18441480Smckusick tp->t_oflag = TTYDEF_OFLAG; 18541480Smckusick tp->t_cflag = CS8|CREAD; 18641480Smckusick tp->t_lflag = TTYDEF_LFLAG; 18741480Smckusick tp->t_ispeed = tp->t_ospeed = TTYDEF_SPEED; 18841480Smckusick tp->t_state = TS_ISOPEN|TS_CARR_ON; 18941480Smckusick ttsetwater(tp); 19041480Smckusick } 19141480Smckusick error = (*linesw[tp->t_line].l_open)(dev, tp); 19241480Smckusick if (error == 0) { 19341480Smckusick tp->t_winsize.ws_row = ip->rows; 19441480Smckusick tp->t_winsize.ws_col = ip->cols; 19541480Smckusick } else if (first) 19641480Smckusick iteoff(dev, 0); 19741480Smckusick return (error); 19841480Smckusick } 19941480Smckusick 20041480Smckusick /*ARGSUSED*/ 20149750Smarc iteclose(dev, flag, mode, p) 20241480Smckusick dev_t dev; 20349750Smarc int flag, mode; 20449750Smarc struct proc *p; 20541480Smckusick { 20641480Smckusick register struct tty *tp = &ite_tty[UNIT(dev)]; 20741480Smckusick 20849750Smarc (*linesw[tp->t_line].l_close)(tp, flag); 20941480Smckusick ttyclose(tp); 21041480Smckusick iteoff(dev, 0); 21141480Smckusick return(0); 21241480Smckusick } 21341480Smckusick 21441480Smckusick iteread(dev, uio, flag) 21541480Smckusick dev_t dev; 21641480Smckusick struct uio *uio; 21741480Smckusick { 21841480Smckusick register struct tty *tp = &ite_tty[UNIT(dev)]; 21941480Smckusick 22041480Smckusick return ((*linesw[tp->t_line].l_read)(tp, uio, flag)); 22141480Smckusick } 22241480Smckusick 22341480Smckusick itewrite(dev, uio, flag) 22441480Smckusick dev_t dev; 22541480Smckusick struct uio *uio; 22641480Smckusick { 22741480Smckusick int unit = UNIT(dev); 22841480Smckusick register struct tty *tp = &ite_tty[unit]; 22941480Smckusick 23041480Smckusick if ((ite_softc[unit].flags & ITE_ISCONS) && constty && 23141480Smckusick (constty->t_state&(TS_CARR_ON|TS_ISOPEN))==(TS_CARR_ON|TS_ISOPEN)) 23241480Smckusick tp = constty; 23341480Smckusick return ((*linesw[tp->t_line].l_write)(tp, uio, flag)); 23441480Smckusick } 23541480Smckusick 23652417Smckusick iteioctl(dev, cmd, addr, flag, p) 23741480Smckusick dev_t dev; 23852417Smckusick int cmd; 23941480Smckusick caddr_t addr; 24052417Smckusick int flag; 24152417Smckusick struct proc *p; 24241480Smckusick { 24341480Smckusick register struct tty *tp = &ite_tty[UNIT(dev)]; 24441480Smckusick int error; 24541480Smckusick 24652417Smckusick error = (*linesw[tp->t_line].l_ioctl)(tp, cmd, addr, flag, p); 24741480Smckusick if (error >= 0) 24841480Smckusick return (error); 24941480Smckusick error = ttioctl(tp, cmd, addr, flag); 25041480Smckusick if (error >= 0) 25141480Smckusick return (error); 25241480Smckusick return (ENOTTY); 25341480Smckusick } 25441480Smckusick 25552390Smckusick void 25641480Smckusick itestart(tp) 25741480Smckusick register struct tty *tp; 25841480Smckusick { 25941480Smckusick register int cc, s; 26041480Smckusick int hiwat = 0; 26141480Smckusick 26241480Smckusick s = spltty(); 26341480Smckusick if (tp->t_state & (TS_TIMEOUT|TS_BUSY|TS_TTSTOP)) { 26441480Smckusick splx(s); 26541480Smckusick return; 26641480Smckusick } 26741480Smckusick tp->t_state |= TS_BUSY; 26841480Smckusick cc = tp->t_outq.c_cc; 26941480Smckusick if (cc <= tp->t_lowat) { 27041480Smckusick if (tp->t_state & TS_ASLEEP) { 27141480Smckusick tp->t_state &= ~TS_ASLEEP; 27252390Smckusick wakeup((caddr_t)&tp->t_outq); 27341480Smckusick } 27452530Storek selwakeup(&tp->t_wsel); 27541480Smckusick } 27641480Smckusick /* 27741480Smckusick * Limit the amount of output we do in one burst 27841480Smckusick * to prevent hogging the CPU. 27941480Smckusick */ 28041480Smckusick if (cc > iteburst) { 28141480Smckusick hiwat++; 28241480Smckusick cc = iteburst; 28341480Smckusick } 28441480Smckusick while (--cc >= 0) { 28541480Smckusick register int c; 28641480Smckusick 28741480Smckusick c = getc(&tp->t_outq); 28841480Smckusick /* 28941480Smckusick * iteputchar() may take a long time and we don't want to 29041480Smckusick * block all interrupts for long periods of time. Since 29141480Smckusick * there is no need to stay at high priority while outputing 29241480Smckusick * the character (since we don't have to worry about 29341480Smckusick * interrupts), we don't. We just need to make sure that 29441480Smckusick * we don't reenter iteputchar, which is guarenteed by the 29541480Smckusick * earlier setting of TS_BUSY. 29641480Smckusick */ 29741480Smckusick splx(s); 29841480Smckusick iteputchar(c, tp->t_dev); 29941480Smckusick spltty(); 30041480Smckusick } 30141480Smckusick if (hiwat) { 30241480Smckusick tp->t_state |= TS_TIMEOUT; 30341480Smckusick timeout(ttrstrt, tp, 1); 30441480Smckusick } 30541480Smckusick tp->t_state &= ~TS_BUSY; 30641480Smckusick splx(s); 30741480Smckusick } 30841480Smckusick 30941480Smckusick itefilter(stat, c) 31041480Smckusick register char stat, c; 31141480Smckusick { 31241480Smckusick static int capsmode = 0; 31341480Smckusick static int metamode = 0; 31441480Smckusick register char code, *str; 31541480Smckusick 31641480Smckusick if (kbd_tty == NULL) 31741480Smckusick return; 31841480Smckusick 31941480Smckusick switch (c & 0xFF) { 32041480Smckusick case KBD_CAPSLOCK: 32141480Smckusick capsmode = !capsmode; 32241480Smckusick return; 32341480Smckusick 32441480Smckusick case KBD_EXT_LEFT_DOWN: 32541480Smckusick case KBD_EXT_RIGHT_DOWN: 32641480Smckusick metamode = 1; 32741480Smckusick return; 32841480Smckusick 32941480Smckusick case KBD_EXT_LEFT_UP: 33041480Smckusick case KBD_EXT_RIGHT_UP: 33141480Smckusick metamode = 0; 33241480Smckusick return; 33341480Smckusick } 33441480Smckusick 33541480Smckusick c &= KBD_CHARMASK; 33641480Smckusick switch ((stat>>KBD_SSHIFT) & KBD_SMASK) { 33741480Smckusick 33841480Smckusick case KBD_KEY: 33941480Smckusick if (!capsmode) { 34041480Smckusick code = kbd_keymap[c]; 34141480Smckusick break; 34241480Smckusick } 34341480Smckusick /* fall into... */ 34441480Smckusick 34541480Smckusick case KBD_SHIFT: 34641480Smckusick code = kbd_shiftmap[c]; 34741480Smckusick break; 34841480Smckusick 34941480Smckusick case KBD_CTRL: 35041480Smckusick code = kbd_ctrlmap[c]; 35141480Smckusick break; 35241480Smckusick 35341480Smckusick case KBD_CTRLSHIFT: 35441480Smckusick code = kbd_ctrlshiftmap[c]; 35541480Smckusick break; 35641480Smckusick } 35741480Smckusick 35841480Smckusick if (code == NULL && (str = kbd_stringmap[c]) != NULL) { 35941480Smckusick while (*str) 36041480Smckusick (*linesw[kbd_tty->t_line].l_rint)(*str++, kbd_tty); 36141480Smckusick } else { 36241480Smckusick if (metamode) 36341480Smckusick code |= 0x80; 36441480Smckusick (*linesw[kbd_tty->t_line].l_rint)(code, kbd_tty); 36541480Smckusick } 36641480Smckusick } 36741480Smckusick 36841480Smckusick iteputchar(c, dev) 36941480Smckusick register int c; 37041480Smckusick dev_t dev; 37141480Smckusick { 37241480Smckusick int unit = UNIT(dev); 37341480Smckusick register struct ite_softc *ip = &ite_softc[unit]; 37453923Shibler register struct itesw *sp = ip->isw; 37541480Smckusick register int n; 37641480Smckusick 37741480Smckusick if ((ip->flags & (ITE_ACTIVE|ITE_INGRF)) != ITE_ACTIVE) 37841480Smckusick return; 37941480Smckusick 38041480Smckusick if (ip->escape) { 38141480Smckusick doesc: 38241480Smckusick switch (ip->escape) { 38341480Smckusick 38441480Smckusick case '&': /* Next can be a,d, or s */ 38541480Smckusick if (ip->fpd++) { 38641480Smckusick ip->escape = c; 38741480Smckusick ip->fpd = 0; 38841480Smckusick } 38941480Smckusick return; 39041480Smckusick 39141480Smckusick case 'a': /* cursor change */ 39241480Smckusick switch (c) { 39341480Smckusick 39441480Smckusick case 'Y': /* Only y coord. */ 39555069Spendry ip->cury = min(ip->pos, ip->rows-1); 39641480Smckusick ip->pos = 0; 39741480Smckusick ip->escape = 0; 39841480Smckusick (*sp->ite_cursor)(ip, MOVE_CURSOR); 39941480Smckusick clr_attr(ip, ATTR_INV); 40041480Smckusick break; 40141480Smckusick 40241480Smckusick case 'y': /* y coord first */ 40355069Spendry ip->cury = min(ip->pos, ip->rows-1); 40441480Smckusick ip->pos = 0; 40541480Smckusick ip->fpd = 0; 40641480Smckusick break; 40741480Smckusick 40841480Smckusick case 'C': /* x coord */ 40955069Spendry ip->curx = min(ip->pos, ip->cols-1); 41041480Smckusick ip->pos = 0; 41141480Smckusick ip->escape = 0; 41241480Smckusick (*sp->ite_cursor)(ip, MOVE_CURSOR); 41341480Smckusick clr_attr(ip, ATTR_INV); 41441480Smckusick break; 41541480Smckusick 41641480Smckusick default: /* Possibly a 3 digit number. */ 41741480Smckusick if (c >= '0' && c <= '9' && ip->fpd < 3) { 41841480Smckusick ip->pos = ip->pos * 10 + (c - '0'); 41941480Smckusick ip->fpd++; 42041480Smckusick } else { 42141480Smckusick ip->pos = 0; 42241480Smckusick ip->escape = 0; 42341480Smckusick } 42441480Smckusick break; 42541480Smckusick } 42641480Smckusick return; 42741480Smckusick 42841480Smckusick case 'd': /* attribute change */ 42941480Smckusick switch (c) { 43041480Smckusick 43141480Smckusick case 'B': 43241480Smckusick set_attr(ip, ATTR_INV); 43341480Smckusick break; 43441480Smckusick case 'D': 43541480Smckusick /* XXX: we don't do anything for underline */ 43641480Smckusick set_attr(ip, ATTR_UL); 43741480Smckusick break; 43841480Smckusick case '@': 43941480Smckusick clr_attr(ip, ATTR_ALL); 44041480Smckusick break; 44141480Smckusick } 44241480Smckusick ip->escape = 0; 44341480Smckusick return; 44441480Smckusick 44541480Smckusick case 's': /* keypad control */ 44641480Smckusick switch (ip->fpd) { 44741480Smckusick 44841480Smckusick case 0: 44941480Smckusick ip->hold = c; 45041480Smckusick ip->fpd++; 45141480Smckusick return; 45241480Smckusick 45341480Smckusick case 1: 45441480Smckusick if (c == 'A') { 45541480Smckusick switch (ip->hold) { 45641480Smckusick 45741480Smckusick case '0': 45841480Smckusick clr_attr(ip, ATTR_KPAD); 45941480Smckusick break; 46041480Smckusick case '1': 46141480Smckusick set_attr(ip, ATTR_KPAD); 46241480Smckusick break; 46341480Smckusick } 46441480Smckusick } 46541480Smckusick ip->hold = 0; 46641480Smckusick } 46741480Smckusick ip->escape = 0; 46841480Smckusick return; 46941480Smckusick 47041480Smckusick case 'i': /* back tab */ 47141480Smckusick if (ip->curx > TABSIZE) { 47241480Smckusick n = ip->curx - (ip->curx & (TABSIZE - 1)); 47341480Smckusick ip->curx -= n; 47441480Smckusick } else 47541480Smckusick ip->curx = 0; 47641480Smckusick (*sp->ite_cursor)(ip, MOVE_CURSOR); 47741480Smckusick ip->escape = 0; 47841480Smckusick return; 47941480Smckusick 48041480Smckusick case '3': /* clear all tabs */ 48141480Smckusick goto ignore; 48241480Smckusick 48341480Smckusick case 'K': /* clear_eol */ 48441480Smckusick ite_clrtoeol(ip, sp, ip->cury, ip->curx); 48541480Smckusick ip->escape = 0; 48641480Smckusick return; 48741480Smckusick 48841480Smckusick case 'J': /* clear_eos */ 48941480Smckusick ite_clrtoeos(ip, sp); 49041480Smckusick ip->escape = 0; 49141480Smckusick return; 49241480Smckusick 49341480Smckusick case 'B': /* cursor down 1 line */ 49441480Smckusick if (++ip->cury == ip->rows) { 49541480Smckusick --ip->cury; 49641480Smckusick (*sp->ite_scroll)(ip, 1, 0, 1, SCROLL_UP); 49741480Smckusick ite_clrtoeol(ip, sp, ip->cury, 0); 49841480Smckusick } 49941480Smckusick else 50041480Smckusick (*sp->ite_cursor)(ip, MOVE_CURSOR); 50141480Smckusick clr_attr(ip, ATTR_INV); 50241480Smckusick ip->escape = 0; 50341480Smckusick return; 50441480Smckusick 50541480Smckusick case 'C': /* cursor forward 1 char */ 50641480Smckusick ip->escape = 0; 50741480Smckusick itecheckwrap(ip, sp); 50841480Smckusick return; 50941480Smckusick 51041480Smckusick case 'A': /* cursor up 1 line */ 51141480Smckusick if (ip->cury > 0) { 51241480Smckusick ip->cury--; 51341480Smckusick (*sp->ite_cursor)(ip, MOVE_CURSOR); 51441480Smckusick } 51541480Smckusick ip->escape = 0; 51641480Smckusick clr_attr(ip, ATTR_INV); 51741480Smckusick return; 51841480Smckusick 51941480Smckusick case 'P': /* delete character */ 52041480Smckusick ite_dchar(ip, sp); 52141480Smckusick ip->escape = 0; 52241480Smckusick return; 52341480Smckusick 52441480Smckusick case 'M': /* delete line */ 52541480Smckusick ite_dline(ip, sp); 52641480Smckusick ip->escape = 0; 52741480Smckusick return; 52841480Smckusick 52941480Smckusick case 'Q': /* enter insert mode */ 53041480Smckusick ip->imode = 1; 53141480Smckusick ip->escape = 0; 53241480Smckusick return; 53341480Smckusick 53441480Smckusick case 'R': /* exit insert mode */ 53541480Smckusick ip->imode = 0; 53641480Smckusick ip->escape = 0; 53741480Smckusick return; 53841480Smckusick 53941480Smckusick case 'L': /* insert blank line */ 54041480Smckusick ite_iline(ip, sp); 54141480Smckusick ip->escape = 0; 54241480Smckusick return; 54341480Smckusick 54441480Smckusick case 'h': /* home key */ 54541480Smckusick ip->cury = ip->curx = 0; 54641480Smckusick (*sp->ite_cursor)(ip, MOVE_CURSOR); 54741480Smckusick ip->escape = 0; 54841480Smckusick return; 54941480Smckusick 55041480Smckusick case 'D': /* left arrow key */ 55141480Smckusick if (ip->curx > 0) { 55241480Smckusick ip->curx--; 55341480Smckusick (*sp->ite_cursor)(ip, MOVE_CURSOR); 55441480Smckusick } 55541480Smckusick ip->escape = 0; 55641480Smckusick return; 55741480Smckusick 55841480Smckusick case '1': /* set tab in all rows */ 55941480Smckusick goto ignore; 56041480Smckusick 56141480Smckusick case ESC: 56241480Smckusick if ((ip->escape = c) == ESC) 56341480Smckusick break; 56441480Smckusick ip->fpd = 0; 56541480Smckusick goto doesc; 56641480Smckusick 56741480Smckusick default: 56841480Smckusick ignore: 56941480Smckusick ip->escape = 0; 57041480Smckusick return; 57141480Smckusick 57241480Smckusick } 57341480Smckusick } 57441480Smckusick 57541480Smckusick switch (c &= 0x7F) { 57641480Smckusick 57741480Smckusick case '\n': 57841480Smckusick 57941480Smckusick if (++ip->cury == ip->rows) { 58041480Smckusick --ip->cury; 58141480Smckusick (*sp->ite_scroll)(ip, 1, 0, 1, SCROLL_UP); 58241480Smckusick ite_clrtoeol(ip, sp, ip->cury, 0); 58341480Smckusick } 58441480Smckusick else 58541480Smckusick (*sp->ite_cursor)(ip, MOVE_CURSOR); 58641480Smckusick clr_attr(ip, ATTR_INV); 58741480Smckusick break; 58841480Smckusick 58941480Smckusick case '\r': 59041480Smckusick if (ip->curx) { 59141480Smckusick ip->curx = 0; 59241480Smckusick (*sp->ite_cursor)(ip, MOVE_CURSOR); 59341480Smckusick } 59441480Smckusick break; 59541480Smckusick 59641480Smckusick case '\b': 59741480Smckusick if (--ip->curx < 0) 59841480Smckusick ip->curx = 0; 59941480Smckusick else 60041480Smckusick (*sp->ite_cursor)(ip, MOVE_CURSOR); 60141480Smckusick break; 60241480Smckusick 60341480Smckusick case '\t': 60441480Smckusick if (ip->curx < TABEND(unit)) { 60541480Smckusick n = TABSIZE - (ip->curx & (TABSIZE - 1)); 60641480Smckusick ip->curx += n; 60741480Smckusick (*sp->ite_cursor)(ip, MOVE_CURSOR); 60841480Smckusick } else 60941480Smckusick itecheckwrap(ip, sp); 61041480Smckusick break; 61141480Smckusick 61241480Smckusick case CTRL('G'): 61341480Smckusick if (&ite_tty[unit] == kbd_tty) 61453923Shibler kbdbell(unit); 61541480Smckusick break; 61641480Smckusick 61741480Smckusick case ESC: 61841480Smckusick ip->escape = ESC; 61941480Smckusick break; 62041480Smckusick 62141480Smckusick default: 62241480Smckusick if (c < ' ' || c == DEL) 62341480Smckusick break; 62441480Smckusick if (ip->imode) 62541480Smckusick ite_ichar(ip, sp); 62641480Smckusick if ((ip->attribute & ATTR_INV) || attrtest(ip, ATTR_INV)) { 62741480Smckusick attrset(ip, ATTR_INV); 62841480Smckusick (*sp->ite_putc)(ip, c, ip->cury, ip->curx, ATTR_INV); 62941480Smckusick } 63041480Smckusick else 63141480Smckusick (*sp->ite_putc)(ip, c, ip->cury, ip->curx, ATTR_NOR); 63241480Smckusick (*sp->ite_cursor)(ip, DRAW_CURSOR); 63341480Smckusick itecheckwrap(ip, sp); 63441480Smckusick break; 63541480Smckusick } 63641480Smckusick } 63741480Smckusick 63841480Smckusick itecheckwrap(ip, sp) 63941480Smckusick register struct ite_softc *ip; 64041480Smckusick register struct itesw *sp; 64141480Smckusick { 64241480Smckusick if (++ip->curx == ip->cols) { 64341480Smckusick ip->curx = 0; 64441480Smckusick clr_attr(ip, ATTR_INV); 64541480Smckusick if (++ip->cury == ip->rows) { 64641480Smckusick --ip->cury; 64741480Smckusick (*sp->ite_scroll)(ip, 1, 0, 1, SCROLL_UP); 64841480Smckusick ite_clrtoeol(ip, sp, ip->cury, 0); 64941480Smckusick return; 65041480Smckusick } 65141480Smckusick } 65241480Smckusick (*sp->ite_cursor)(ip, MOVE_CURSOR); 65341480Smckusick } 65441480Smckusick 65541480Smckusick ite_dchar(ip, sp) 65641480Smckusick register struct ite_softc *ip; 65741480Smckusick register struct itesw *sp; 65841480Smckusick { 65941480Smckusick (*sp->ite_scroll)(ip, ip->cury, ip->curx + 1, 1, SCROLL_LEFT); 66041480Smckusick attrmov(ip, ip->cury, ip->curx + 1, ip->cury, ip->curx, 66141480Smckusick 1, ip->cols - ip->curx - 1); 66241480Smckusick attrclr(ip, ip->cury, ip->cols - 1, 1, 1); 66341480Smckusick (*sp->ite_putc)(ip, ' ', ip->cury, ip->cols - 1, ATTR_NOR); 66441480Smckusick (*sp->ite_cursor)(ip, DRAW_CURSOR); 66541480Smckusick } 66641480Smckusick 66741480Smckusick ite_ichar(ip, sp) 66841480Smckusick register struct ite_softc *ip; 66941480Smckusick register struct itesw *sp; 67041480Smckusick { 67141480Smckusick (*sp->ite_scroll)(ip, ip->cury, ip->curx, 1, SCROLL_RIGHT); 67241480Smckusick attrmov(ip, ip->cury, ip->curx, ip->cury, ip->curx + 1, 67341480Smckusick 1, ip->cols - ip->curx - 1); 67441480Smckusick attrclr(ip, ip->cury, ip->curx, 1, 1); 67541480Smckusick (*sp->ite_putc)(ip, ' ', ip->cury, ip->curx, ATTR_NOR); 67641480Smckusick (*sp->ite_cursor)(ip, DRAW_CURSOR); 67741480Smckusick } 67841480Smckusick 67941480Smckusick ite_dline(ip, sp) 68041480Smckusick register struct ite_softc *ip; 68141480Smckusick register struct itesw *sp; 68241480Smckusick { 68341480Smckusick (*sp->ite_scroll)(ip, ip->cury + 1, 0, 1, SCROLL_UP); 68441480Smckusick attrmov(ip, ip->cury + 1, 0, ip->cury, 0, 68541480Smckusick ip->rows - ip->cury - 1, ip->cols); 68641480Smckusick ite_clrtoeol(ip, sp, ip->rows - 1, 0); 68741480Smckusick } 68841480Smckusick 68941480Smckusick ite_iline(ip, sp) 69041480Smckusick register struct ite_softc *ip; 69141480Smckusick register struct itesw *sp; 69241480Smckusick { 69341480Smckusick (*sp->ite_scroll)(ip, ip->cury, 0, 1, SCROLL_DOWN); 69441480Smckusick attrmov(ip, ip->cury, 0, ip->cury + 1, 0, 69541480Smckusick ip->rows - ip->cury - 1, ip->cols); 69641480Smckusick ite_clrtoeol(ip, sp, ip->cury, 0); 69741480Smckusick } 69841480Smckusick 69941480Smckusick ite_clrtoeol(ip, sp, y, x) 70041480Smckusick register struct ite_softc *ip; 70141480Smckusick register struct itesw *sp; 70241480Smckusick register int y, x; 70341480Smckusick { 70441480Smckusick (*sp->ite_clear)(ip, y, x, 1, ip->cols - x); 70541480Smckusick attrclr(ip, y, x, 1, ip->cols - x); 70641480Smckusick (*sp->ite_cursor)(ip, DRAW_CURSOR); 70741480Smckusick } 70841480Smckusick 70941480Smckusick ite_clrtoeos(ip, sp) 71041480Smckusick register struct ite_softc *ip; 71141480Smckusick register struct itesw *sp; 71241480Smckusick { 71341480Smckusick (*sp->ite_clear)(ip, ip->cury, 0, ip->rows - ip->cury, ip->cols); 71441480Smckusick attrclr(ip, ip->cury, 0, ip->rows - ip->cury, ip->cols); 71541480Smckusick (*sp->ite_cursor)(ip, DRAW_CURSOR); 71641480Smckusick } 71741480Smckusick 71841480Smckusick /* 71941480Smckusick * Console functions 72041480Smckusick */ 721*56504Sbostic #include <hp/dev/cons.h> 72253923Shibler #ifdef hp300 723*56504Sbostic #include <hp/dev/grfreg.h> 72453923Shibler #endif 72541480Smckusick 72641480Smckusick #ifdef DEBUG 72741480Smckusick /* 72841480Smckusick * Minimum ITE number at which to start looking for a console. 72941480Smckusick * Setting to 0 will do normal search, 1 will skip first ITE device, 73041480Smckusick * NITE will skip ITEs and use serial port. 73141480Smckusick */ 73241480Smckusick int whichconsole = 0; 73341480Smckusick #endif 73441480Smckusick 73541480Smckusick itecnprobe(cp) 73641480Smckusick struct consdev *cp; 73741480Smckusick { 73841480Smckusick register struct ite_softc *ip; 73953923Shibler int i, sw, maj, unit, pri; 74041480Smckusick 74141480Smckusick /* locate the major number */ 74241480Smckusick for (maj = 0; maj < nchrdev; maj++) 74341480Smckusick if (cdevsw[maj].d_open == iteopen) 74441480Smckusick break; 74541480Smckusick 74641480Smckusick /* urk! */ 74741480Smckusick grfconfig(); 74841480Smckusick 74941480Smckusick /* check all the individual displays and find the best */ 75041480Smckusick unit = -1; 75141480Smckusick pri = CN_DEAD; 75241480Smckusick for (i = 0; i < NITE; i++) { 75341480Smckusick struct grf_softc *gp = &grf_softc[i]; 75441480Smckusick 75541480Smckusick ip = &ite_softc[i]; 75641480Smckusick if ((gp->g_flags & GF_ALIVE) == 0) 75741480Smckusick continue; 75841480Smckusick ip->flags = (ITE_ALIVE|ITE_CONSOLE); 75941480Smckusick 76053923Shibler /* locate the proper switch table. */ 76153923Shibler for (sw = 0; sw < nitesw; sw++) 76253923Shibler if (itesw[sw].ite_hwid == gp->g_sw->gd_hwid) 76353923Shibler break; 76441480Smckusick 76553923Shibler if (sw == nitesw) 76653923Shibler continue; 76741480Smckusick #ifdef DEBUG 76841480Smckusick if (i < whichconsole) 76941480Smckusick continue; 77041480Smckusick #endif 77153923Shibler ip->isw = &itesw[sw]; 77253923Shibler ip->grf = gp; 77353923Shibler #ifdef hp300 77441480Smckusick if ((int)gp->g_display.gd_regaddr == GRFIADDR) { 77541480Smckusick pri = CN_INTERNAL; 77641480Smckusick unit = i; 77741480Smckusick } else if (unit < 0) { 77841480Smckusick pri = CN_NORMAL; 77941480Smckusick unit = i; 78041480Smckusick } 78153923Shibler #endif 78253923Shibler #ifdef hp800 78353923Shibler /* XXX use the first one for now */ 78453923Shibler if (unit < 0) { 78553923Shibler pri = CN_INTERNAL; 78653923Shibler unit = i; 78753923Shibler } 78853923Shibler #endif 78941480Smckusick } 79041480Smckusick 79141480Smckusick /* initialize required fields */ 79241480Smckusick cp->cn_dev = makedev(maj, unit); 79341480Smckusick cp->cn_tp = &ite_tty[unit]; 79441480Smckusick cp->cn_pri = pri; 79541480Smckusick } 79641480Smckusick 79741480Smckusick itecninit(cp) 79841480Smckusick struct consdev *cp; 79941480Smckusick { 80041480Smckusick int unit = UNIT(cp->cn_dev); 80141480Smckusick struct ite_softc *ip = &ite_softc[unit]; 80241480Smckusick 80341480Smckusick ip->attrbuf = console_attributes; 80441480Smckusick iteinit(cp->cn_dev); 80541480Smckusick ip->flags |= (ITE_ACTIVE|ITE_ISCONS); 80641480Smckusick kbd_tty = &ite_tty[unit]; 80741480Smckusick } 80841480Smckusick 80941480Smckusick /*ARGSUSED*/ 81041480Smckusick itecngetc(dev) 81141480Smckusick dev_t dev; 81241480Smckusick { 81341480Smckusick register int c; 81441480Smckusick int stat; 81541480Smckusick 81653923Shibler c = kbdgetc(0, &stat); /* XXX always read from keyboard 0 for now */ 81741480Smckusick switch ((stat >> KBD_SSHIFT) & KBD_SMASK) { 81841480Smckusick case KBD_SHIFT: 81941480Smckusick c = kbd_shiftmap[c & KBD_CHARMASK]; 82041480Smckusick break; 82141480Smckusick case KBD_CTRL: 82241480Smckusick c = kbd_ctrlmap[c & KBD_CHARMASK]; 82341480Smckusick break; 82441480Smckusick case KBD_KEY: 82541480Smckusick c = kbd_keymap[c & KBD_CHARMASK]; 82641480Smckusick break; 82741480Smckusick default: 82841480Smckusick c = 0; 82941480Smckusick break; 83041480Smckusick } 83141480Smckusick return(c); 83241480Smckusick } 83341480Smckusick 83441480Smckusick itecnputc(dev, c) 83541480Smckusick dev_t dev; 83641480Smckusick int c; 83741480Smckusick { 83841480Smckusick static int paniced = 0; 83941480Smckusick struct ite_softc *ip = &ite_softc[UNIT(dev)]; 84041480Smckusick 84141480Smckusick if (panicstr && !paniced && 84241480Smckusick (ip->flags & (ITE_ACTIVE|ITE_INGRF)) != ITE_ACTIVE) { 84341480Smckusick (void) iteon(dev, 3); 84441480Smckusick paniced = 1; 84541480Smckusick } 84641480Smckusick iteputchar(c, dev); 84741480Smckusick } 84841480Smckusick #endif 849