diff options
author | Theo de Raadt <deraadt@cvs.openbsd.org> | 1995-10-18 08:53:40 +0000 |
---|---|---|
committer | Theo de Raadt <deraadt@cvs.openbsd.org> | 1995-10-18 08:53:40 +0000 |
commit | d6583bb2a13f329cf0332ef2570eb8bb8fc0e39c (patch) | |
tree | ece253b876159b39c620e62b6c9b1174642e070e /sys/arch/hp300/dev/ite.c |
initial import of NetBSD tree
Diffstat (limited to 'sys/arch/hp300/dev/ite.c')
-rw-r--r-- | sys/arch/hp300/dev/ite.c | 959 |
1 files changed, 959 insertions, 0 deletions
diff --git a/sys/arch/hp300/dev/ite.c b/sys/arch/hp300/dev/ite.c new file mode 100644 index 00000000000..f42d3cf0265 --- /dev/null +++ b/sys/arch/hp300/dev/ite.c @@ -0,0 +1,959 @@ +/* $NetBSD: ite.c,v 1.27 1995/04/19 19:15:51 mycroft Exp $ */ + +/* + * Copyright (c) 1988 University of Utah. + * Copyright (c) 1990, 1993 + * The Regents of the University of California. All rights reserved. + * + * This code is derived from software contributed to Berkeley by + * the Systems Programming Group of the University of Utah Computer + * Science Department. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * 1. Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * 2. Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in the + * documentation and/or other materials provided with the distribution. + * 3. All advertising materials mentioning features or use of this software + * must display the following acknowledgement: + * This product includes software developed by the University of + * California, Berkeley and its contributors. + * 4. Neither the name of the University nor the names of its contributors + * may be used to endorse or promote products derived from this software + * without specific prior written permission. + * + * THIS SOFTWARE IS PROVIDED BY THE REGENTS AND CONTRIBUTORS ``AS IS'' AND + * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE + * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE + * ARE DISCLAIMED. IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE + * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL + * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS + * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) + * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT + * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY + * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF + * SUCH DAMAGE. + * + * from: Utah $Hdr: ite.c 1.28 92/12/20$ + * + * @(#)ite.c 8.2 (Berkeley) 1/12/94 + */ + +/* + * Bit-mapped display terminal emulator machine independent code. + * This is a very rudimentary. Much more can be abstracted out of + * the hardware dependent routines. + */ +#include "ite.h" +#if NITE > 0 + +#include "grf.h" +#undef NITE +#define NITE NGRF + +#include <sys/param.h> +#include <sys/conf.h> +#include <sys/proc.h> +#include <sys/ioctl.h> +#include <sys/tty.h> +#include <sys/systm.h> +#include <sys/malloc.h> + +#include <hp300/dev/grfioctl.h> +#include <hp300/dev/grfvar.h> +#include <hp300/dev/itevar.h> +#include <hp300/dev/kbdmap.h> + +#define set_attr(ip, attr) ((ip)->attribute |= (attr)) +#define clr_attr(ip, attr) ((ip)->attribute &= ~(attr)) + +/* + * No need to raise SPL above the HIL (the only thing that can + * affect our state. + */ +#include <hp300/dev/hilreg.h> +#define splite() splhil() + +/* + * # of chars are output in a single itestart() call. + * If this is too big, user processes will be blocked out for + * long periods of time while we are emptying the queue in itestart(). + * If it is too small, console output will be very ragged. + */ +int iteburst = 64; + +int nite = NITE; +struct tty *ite_tty[NITE]; +struct ite_softc *kbd_ite = NULL; +struct ite_softc ite_softc[NITE]; + +void itestart(); + +/* + * Primary attribute buffer to be used by the first bitmapped console + * found. Secondary displays alloc the attribute buffer as needed. + * Size is based on a 68x128 display, which is currently our largest. + */ +u_char console_attributes[0x2200]; + +#define ite_erasecursor(ip, sp) { \ + if ((ip)->flags & ITE_CURSORON) \ + (*(sp)->ite_cursor)((ip), ERASE_CURSOR); \ +} +#define ite_drawcursor(ip, sp) { \ + if ((ip)->flags & ITE_CURSORON) \ + (*(sp)->ite_cursor)((ip), DRAW_CURSOR); \ +} +#define ite_movecursor(ip, sp) { \ + if ((ip)->flags & ITE_CURSORON) \ + (*(sp)->ite_cursor)((ip), MOVE_CURSOR); \ +} + +/* + * Dummy for pseudo-device config. + */ +/*ARGSUSED*/ +iteattach(n) + int n; +{ +} + +/* + * Perform functions necessary to setup device as a terminal emulator. + */ +iteon(dev, flag) + dev_t dev; + int flag; +{ + int unit = UNIT(dev); + struct tty *tp = ite_tty[unit]; + struct ite_softc *ip = &ite_softc[unit]; + + if (unit < 0 || unit >= NITE || (ip->flags&ITE_ALIVE) == 0) + return(ENXIO); + /* force ite active, overriding graphics mode */ + if (flag & 1) { + ip->flags |= ITE_ACTIVE; + ip->flags &= ~(ITE_INGRF|ITE_INITED); + } + /* leave graphics mode */ + if (flag & 2) { + ip->flags &= ~ITE_INGRF; + if ((ip->flags & ITE_ACTIVE) == 0) + return(0); + } + ip->flags |= ITE_ACTIVE; + if (ip->flags & ITE_INGRF) + return(0); + if (kbd_ite == NULL || kbd_ite == ip) { + kbd_ite = ip; + kbdenable(unit); + } + iteinit(dev); + return(0); +} + +iteinit(dev) + dev_t dev; +{ + int unit = UNIT(dev); + struct ite_softc *ip = &ite_softc[unit]; + + if (ip->flags & ITE_INITED) + return; + + ip->curx = 0; + ip->cury = 0; + ip->cursorx = 0; + ip->cursory = 0; + + (*ip->isw->ite_init)(ip); + ip->flags |= ITE_CURSORON; + ite_drawcursor(ip, ip->isw); + + ip->attribute = 0; + if (ip->attrbuf == NULL) + ip->attrbuf = (u_char *) + malloc(ip->rows * ip->cols, M_DEVBUF, M_WAITOK); + bzero(ip->attrbuf, (ip->rows * ip->cols)); + + ip->imode = 0; + ip->flags |= ITE_INITED; +} + +/* + * "Shut down" device as terminal emulator. + * Note that we do not deinit the console device unless forced. + * Deinit'ing the console every time leads to a very active + * screen when processing /etc/rc. + */ +iteoff(dev, flag) + dev_t dev; + int flag; +{ + register struct ite_softc *ip = &ite_softc[UNIT(dev)]; + + if (flag & 2) { + ip->flags |= ITE_INGRF; + ip->flags &= ~ITE_CURSORON; + } + if ((ip->flags & ITE_ACTIVE) == 0) + return; + if ((flag & 1) || + (ip->flags & (ITE_INGRF|ITE_ISCONS|ITE_INITED)) == ITE_INITED) + (*ip->isw->ite_deinit)(ip); + if ((flag & 2) == 0) + ip->flags &= ~ITE_ACTIVE; +} + +/* ARGSUSED */ +int +iteopen(dev, mode, devtype, p) + dev_t dev; + int mode, devtype; + struct proc *p; +{ + int unit = UNIT(dev); + register struct tty *tp; + register struct ite_softc *ip = &ite_softc[unit]; + register int error; + int first = 0; + + if (!ite_tty[unit]) + tp = ite_tty[unit] = ttymalloc(); + else + tp = ite_tty[unit]; + if ((tp->t_state&(TS_ISOPEN|TS_XCLUDE)) == (TS_ISOPEN|TS_XCLUDE) + && p->p_ucred->cr_uid != 0) + return (EBUSY); + if ((ip->flags & ITE_ACTIVE) == 0) { + error = iteon(dev, 0); + if (error) + return (error); + first = 1; + } + tp->t_oproc = itestart; + tp->t_param = NULL; + tp->t_dev = dev; + if ((tp->t_state&TS_ISOPEN) == 0) { + ttychars(tp); + tp->t_iflag = TTYDEF_IFLAG; + tp->t_oflag = TTYDEF_OFLAG; + tp->t_cflag = CS8|CREAD; + tp->t_lflag = TTYDEF_LFLAG; + tp->t_ispeed = tp->t_ospeed = TTYDEF_SPEED; + tp->t_state = TS_ISOPEN|TS_CARR_ON; + ttsetwater(tp); + } + error = (*linesw[tp->t_line].l_open)(dev, tp); + if (error == 0) { + tp->t_winsize.ws_row = ip->rows; + tp->t_winsize.ws_col = ip->cols; + } else if (first) + iteoff(dev, 0); + return (error); +} + +/*ARGSUSED*/ +int +iteclose(dev, flag, mode, p) + dev_t dev; + int flag, mode; + struct proc *p; +{ + register struct tty *tp = ite_tty[UNIT(dev)]; + + (*linesw[tp->t_line].l_close)(tp, flag); + ttyclose(tp); + iteoff(dev, 0); +#if 0 + ttyfree(tp); + ite_tty[UNIT(dev)] = (struct tty *)0; +#endif + return(0); +} + +int +iteread(dev, uio, flag) + dev_t dev; + struct uio *uio; + int flag; +{ + register struct tty *tp = ite_tty[UNIT(dev)]; + + return ((*linesw[tp->t_line].l_read)(tp, uio, flag)); +} + +int +itewrite(dev, uio, flag) + dev_t dev; + struct uio *uio; + int flag; +{ + register struct tty *tp = ite_tty[UNIT(dev)]; + + return ((*linesw[tp->t_line].l_write)(tp, uio, flag)); +} + +struct tty * +itetty(dev) + dev_t dev; +{ + + return (ite_tty[UNIT(dev)]); +} + +int +iteioctl(dev, cmd, addr, flag, p) + dev_t dev; + int cmd; + caddr_t addr; + int flag; + struct proc *p; +{ + register struct tty *tp = ite_tty[UNIT(dev)]; + int error; + + error = (*linesw[tp->t_line].l_ioctl)(tp, cmd, addr, flag, p); + if (error >= 0) + return (error); + error = ttioctl(tp, cmd, addr, flag, p); + if (error >= 0) + return (error); + return (ENOTTY); +} + +void +itestart(tp) + register struct tty *tp; +{ + register int cc, s; + int hiwat = 0, hadcursor = 0; + struct ite_softc *ip; + + /* + * (Potentially) lower priority. We only need to protect ourselves + * from keyboard interrupts since that is all that can affect the + * state of our tty (kernel printf doesn't go through this routine). + */ + s = splite(); + if (tp->t_state & (TS_TIMEOUT|TS_BUSY|TS_TTSTOP)) { + splx(s); + return; + } + tp->t_state |= TS_BUSY; + cc = tp->t_outq.c_cc; + if (cc <= tp->t_lowat) { + if (tp->t_state & TS_ASLEEP) { + tp->t_state &= ~TS_ASLEEP; + wakeup((caddr_t)&tp->t_outq); + } + selwakeup(&tp->t_wsel); + } + /* + * Handle common (?) case + */ + if (cc == 1) { + iteputchar(getc(&tp->t_outq), tp->t_dev); + } else if (cc) { + /* + * Limit the amount of output we do in one burst + * to prevent hogging the CPU. + */ + if (cc > iteburst) { + hiwat++; + cc = iteburst; + } + /* + * Turn off cursor while we output multiple characters. + * Saves a lot of expensive window move operations. + */ + ip = &ite_softc[UNIT(tp->t_dev)]; + if (ip->flags & ITE_CURSORON) { + ite_erasecursor(ip, ip->isw); + ip->flags &= ~ITE_CURSORON; + hadcursor = 1; + } + while (--cc >= 0) + iteputchar(getc(&tp->t_outq), tp->t_dev); + if (hadcursor) { + ip->flags |= ITE_CURSORON; + ite_drawcursor(ip, ip->isw); + } + if (hiwat) { + tp->t_state |= TS_TIMEOUT; + timeout(ttrstrt, tp, 1); + } + } + tp->t_state &= ~TS_BUSY; + splx(s); +} + +void +itestop(tp, flag) + struct tty *tp; + int flag; +{ + +} + +itefilter(stat, c) + register char stat, c; +{ + static int capsmode = 0; + static int metamode = 0; + register char code, *str; + struct tty *kbd_tty = ite_tty[kbd_ite - ite_softc]; + + if (kbd_tty == NULL) + return; + + switch (c & 0xFF) { + case KBD_CAPSLOCK: + capsmode = !capsmode; + return; + + case KBD_EXT_LEFT_DOWN: + case KBD_EXT_RIGHT_DOWN: + metamode = 1; + return; + + case KBD_EXT_LEFT_UP: + case KBD_EXT_RIGHT_UP: + metamode = 0; + return; + } + + c &= KBD_CHARMASK; + switch ((stat>>KBD_SSHIFT) & KBD_SMASK) { + + case KBD_KEY: + if (!capsmode) { + code = kbd_keymap[c]; + break; + } + /* FALLTHROUGH */ + + case KBD_SHIFT: + code = kbd_shiftmap[c]; + break; + + case KBD_CTRL: + code = kbd_ctrlmap[c]; + break; + + case KBD_CTRLSHIFT: + code = kbd_ctrlshiftmap[c]; + break; + } + + if (code == NULL && (str = kbd_stringmap[c]) != NULL) { + while (*str) + (*linesw[kbd_tty->t_line].l_rint)(*str++, kbd_tty); + } else { + if (metamode) + code |= 0x80; + (*linesw[kbd_tty->t_line].l_rint)(code, kbd_tty); + } +} + +iteputchar(c, dev) + register int c; + dev_t dev; +{ + int unit = UNIT(dev); + register struct ite_softc *ip = &ite_softc[unit]; + register struct itesw *sp = ip->isw; + register int n; + + if ((ip->flags & (ITE_ACTIVE|ITE_INGRF)) != ITE_ACTIVE) + return; + + if (ip->escape) { +doesc: + switch (ip->escape) { + + case '&': /* Next can be a,d, or s */ + if (ip->fpd++) { + ip->escape = c; + ip->fpd = 0; + } + return; + + case 'a': /* cursor change */ + switch (c) { + + case 'Y': /* Only y coord. */ + ip->cury = min(ip->pos, ip->rows-1); + ip->pos = 0; + ip->escape = 0; + ite_movecursor(ip, sp); + clr_attr(ip, ATTR_INV); + break; + + case 'y': /* y coord first */ + ip->cury = min(ip->pos, ip->rows-1); + ip->pos = 0; + ip->fpd = 0; + break; + + case 'C': /* x coord */ + ip->curx = min(ip->pos, ip->cols-1); + ip->pos = 0; + ip->escape = 0; + ite_movecursor(ip, sp); + clr_attr(ip, ATTR_INV); + break; + + default: /* Possibly a 3 digit number. */ + if (c >= '0' && c <= '9' && ip->fpd < 3) { + ip->pos = ip->pos * 10 + (c - '0'); + ip->fpd++; + } else { + ip->pos = 0; + ip->escape = 0; + } + break; + } + return; + + case 'd': /* attribute change */ + switch (c) { + + case 'B': + set_attr(ip, ATTR_INV); + break; + case 'D': + /* XXX: we don't do anything for underline */ + set_attr(ip, ATTR_UL); + break; + case '@': + clr_attr(ip, ATTR_ALL); + break; + } + ip->escape = 0; + return; + + case 's': /* keypad control */ + switch (ip->fpd) { + + case 0: + ip->hold = c; + ip->fpd++; + return; + + case 1: + if (c == 'A') { + switch (ip->hold) { + + case '0': + clr_attr(ip, ATTR_KPAD); + break; + case '1': + set_attr(ip, ATTR_KPAD); + break; + } + } + ip->hold = 0; + } + ip->escape = 0; + return; + + case 'i': /* back tab */ + if (ip->curx > TABSIZE) { + n = ip->curx - (ip->curx & (TABSIZE - 1)); + ip->curx -= n; + } else + ip->curx = 0; + ite_movecursor(ip, sp); + ip->escape = 0; + return; + + case '3': /* clear all tabs */ + goto ignore; + + case 'K': /* clear_eol */ + ite_clrtoeol(ip, sp, ip->cury, ip->curx); + ip->escape = 0; + return; + + case 'J': /* clear_eos */ + ite_clrtoeos(ip, sp); + ip->escape = 0; + return; + + case 'B': /* cursor down 1 line */ + if (++ip->cury == ip->rows) { + --ip->cury; + ite_erasecursor(ip, sp); + (*sp->ite_scroll)(ip, 1, 0, 1, SCROLL_UP); + ite_clrtoeol(ip, sp, ip->cury, 0); + } + else + ite_movecursor(ip, sp); + clr_attr(ip, ATTR_INV); + ip->escape = 0; + return; + + case 'C': /* cursor forward 1 char */ + ip->escape = 0; + itecheckwrap(ip, sp); + return; + + case 'A': /* cursor up 1 line */ + if (ip->cury > 0) { + ip->cury--; + ite_movecursor(ip, sp); + } + ip->escape = 0; + clr_attr(ip, ATTR_INV); + return; + + case 'P': /* delete character */ + ite_dchar(ip, sp); + ip->escape = 0; + return; + + case 'M': /* delete line */ + ite_dline(ip, sp); + ip->escape = 0; + return; + + case 'Q': /* enter insert mode */ + ip->imode = 1; + ip->escape = 0; + return; + + case 'R': /* exit insert mode */ + ip->imode = 0; + ip->escape = 0; + return; + + case 'L': /* insert blank line */ + ite_iline(ip, sp); + ip->escape = 0; + return; + + case 'h': /* home key */ + ip->cury = ip->curx = 0; + ite_movecursor(ip, sp); + ip->escape = 0; + return; + + case 'D': /* left arrow key */ + if (ip->curx > 0) { + ip->curx--; + ite_movecursor(ip, sp); + } + ip->escape = 0; + return; + + case '1': /* set tab in all rows */ + goto ignore; + + case ESC: + if ((ip->escape = c) == ESC) + break; + ip->fpd = 0; + goto doesc; + + default: +ignore: + ip->escape = 0; + return; + + } + } + + switch (c &= 0x7F) { + + case '\n': + + if (++ip->cury == ip->rows) { + --ip->cury; + ite_erasecursor(ip, sp); + (*sp->ite_scroll)(ip, 1, 0, 1, SCROLL_UP); + ite_clrtoeol(ip, sp, ip->cury, 0); + } else + ite_movecursor(ip, sp); + clr_attr(ip, ATTR_INV); + break; + + case '\r': + if (ip->curx) { + ip->curx = 0; + ite_movecursor(ip, sp); + } + break; + + case '\b': + if (--ip->curx < 0) + ip->curx = 0; + else + ite_movecursor(ip, sp); + break; + + case '\t': + if (ip->curx < TABEND(unit)) { + n = TABSIZE - (ip->curx & (TABSIZE - 1)); + ip->curx += n; + ite_movecursor(ip, sp); + } else + itecheckwrap(ip, sp); + break; + + case CTRL('G'): + if (ip == kbd_ite) + kbdbell(unit); + break; + + case ESC: + ip->escape = ESC; + break; + + default: + if (c < ' ' || c == DEL) + break; + if (ip->imode) + ite_ichar(ip, sp); + if ((ip->attribute & ATTR_INV) || attrtest(ip, ATTR_INV)) { + attrset(ip, ATTR_INV); + (*sp->ite_putc)(ip, c, ip->cury, ip->curx, ATTR_INV); + } else + (*sp->ite_putc)(ip, c, ip->cury, ip->curx, ATTR_NOR); + ite_drawcursor(ip, sp); + itecheckwrap(ip, sp); + break; + } +} + +itecheckwrap(ip, sp) + register struct ite_softc *ip; + register struct itesw *sp; +{ + if (++ip->curx == ip->cols) { + ip->curx = 0; + clr_attr(ip, ATTR_INV); + if (++ip->cury == ip->rows) { + --ip->cury; + ite_erasecursor(ip, sp); + (*sp->ite_scroll)(ip, 1, 0, 1, SCROLL_UP); + ite_clrtoeol(ip, sp, ip->cury, 0); + return; + } + } + ite_movecursor(ip, sp); +} + +ite_dchar(ip, sp) + register struct ite_softc *ip; + register struct itesw *sp; +{ + if (ip->curx < ip->cols - 1) { + ite_erasecursor(ip, sp); + (*sp->ite_scroll)(ip, ip->cury, ip->curx + 1, 1, SCROLL_LEFT); + attrmov(ip, ip->cury, ip->curx + 1, ip->cury, ip->curx, + 1, ip->cols - ip->curx - 1); + } + attrclr(ip, ip->cury, ip->cols - 1, 1, 1); + (*sp->ite_putc)(ip, ' ', ip->cury, ip->cols - 1, ATTR_NOR); + ite_drawcursor(ip, sp); +} + +ite_ichar(ip, sp) + register struct ite_softc *ip; + register struct itesw *sp; +{ + if (ip->curx < ip->cols - 1) { + ite_erasecursor(ip, sp); + (*sp->ite_scroll)(ip, ip->cury, ip->curx, 1, SCROLL_RIGHT); + attrmov(ip, ip->cury, ip->curx, ip->cury, ip->curx + 1, + 1, ip->cols - ip->curx - 1); + } + attrclr(ip, ip->cury, ip->curx, 1, 1); + (*sp->ite_putc)(ip, ' ', ip->cury, ip->curx, ATTR_NOR); + ite_drawcursor(ip, sp); +} + +ite_dline(ip, sp) + register struct ite_softc *ip; + register struct itesw *sp; +{ + if (ip->cury < ip->rows - 1) { + ite_erasecursor(ip, sp); + (*sp->ite_scroll)(ip, ip->cury + 1, 0, 1, SCROLL_UP); + attrmov(ip, ip->cury + 1, 0, ip->cury, 0, + ip->rows - ip->cury - 1, ip->cols); + } + ite_clrtoeol(ip, sp, ip->rows - 1, 0); +} + +ite_iline(ip, sp) + register struct ite_softc *ip; + register struct itesw *sp; +{ + if (ip->cury < ip->rows - 1) { + ite_erasecursor(ip, sp); + (*sp->ite_scroll)(ip, ip->cury, 0, 1, SCROLL_DOWN); + attrmov(ip, ip->cury, 0, ip->cury + 1, 0, + ip->rows - ip->cury - 1, ip->cols); + } + ite_clrtoeol(ip, sp, ip->cury, 0); +} + +ite_clrtoeol(ip, sp, y, x) + register struct ite_softc *ip; + register struct itesw *sp; + register int y, x; +{ + (*sp->ite_clear)(ip, y, x, 1, ip->cols - x); + attrclr(ip, y, x, 1, ip->cols - x); + ite_drawcursor(ip, sp); +} + +ite_clrtoeos(ip, sp) + register struct ite_softc *ip; + register struct itesw *sp; +{ + (*sp->ite_clear)(ip, ip->cury, 0, ip->rows - ip->cury, ip->cols); + attrclr(ip, ip->cury, 0, ip->rows - ip->cury, ip->cols); + ite_drawcursor(ip, sp); +} + +/* + * Console functions + */ +#include <dev/cons.h> +#ifdef hp300 +#include <hp300/dev/grfreg.h> +#endif + +#ifdef DEBUG +/* + * Minimum ITE number at which to start looking for a console. + * Setting to 0 will do normal search, 1 will skip first ITE device, + * NITE will skip ITEs and use serial port. + */ +int whichconsole = 0; +#endif + +void +itecnprobe(cp) + struct consdev *cp; +{ + register struct ite_softc *ip; + int i, sw, maj, unit, pri; + + /* locate the major number */ + for (maj = 0; maj < nchrdev; maj++) + if (cdevsw[maj].d_open == iteopen) + break; + + /* urk! */ + grfconfig(); + + /* check all the individual displays and find the best */ + unit = -1; + pri = CN_DEAD; + for (i = 0; i < NITE; i++) { + struct grf_softc *gp = &grf_softc[i]; + + ip = &ite_softc[i]; + if ((gp->g_flags & GF_ALIVE) == 0) + continue; + ip->flags = (ITE_ALIVE|ITE_CONSOLE); + + /* locate the proper switch table. */ + for (sw = 0; sw < nitesw; sw++) + if (itesw[sw].ite_hwid == gp->g_sw->gd_hwid) + break; + + if (sw == nitesw) + continue; +#ifdef DEBUG + if (i < whichconsole) + continue; +#endif + ip->isw = &itesw[sw]; + ip->grf = gp; +#ifdef hp300 + if ((int)gp->g_display.gd_regaddr == GRFIADDR) { + pri = CN_INTERNAL; + unit = i; + } else if (unit < 0) { + pri = CN_NORMAL; + unit = i; + } +#endif +#ifdef hp800 + /* XXX use the first one for now */ + if (unit < 0) { + pri = CN_INTERNAL; + unit = i; + } +#endif + } + + /* initialize required fields */ + cp->cn_dev = makedev(maj, unit); + cp->cn_pri = pri; +} + +void +itecninit(cp) + struct consdev *cp; +{ + int unit = UNIT(cp->cn_dev); + struct ite_softc *ip = &ite_softc[unit]; + + ip->attrbuf = console_attributes; + iteinit(cp->cn_dev); + ip->flags |= (ITE_ACTIVE|ITE_ISCONS); + kbd_ite = ip; +} + +/*ARGSUSED*/ +int +itecngetc(dev) + dev_t dev; +{ + register int c; + int stat; + + c = kbdgetc(0, &stat); /* XXX always read from keyboard 0 for now */ + switch ((stat >> KBD_SSHIFT) & KBD_SMASK) { + case KBD_SHIFT: + c = kbd_shiftmap[c & KBD_CHARMASK]; + break; + case KBD_CTRL: + c = kbd_ctrlmap[c & KBD_CHARMASK]; + break; + case KBD_KEY: + c = kbd_keymap[c & KBD_CHARMASK]; + break; + default: + c = 0; + break; + } + return(c); +} + +void +itecnputc(dev, c) + dev_t dev; + int c; +{ + static int paniced = 0; + struct ite_softc *ip = &ite_softc[UNIT(dev)]; + + if (panicstr && !paniced && + (ip->flags & (ITE_ACTIVE|ITE_INGRF)) != ITE_ACTIVE) { + (void) iteon(dev, 3); + paniced = 1; + } + iteputchar(c, dev); +} +#endif |