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