summaryrefslogtreecommitdiff
path: root/sys/arch/hp300/dev/ite.c
diff options
context:
space:
mode:
authorTheo de Raadt <deraadt@cvs.openbsd.org>1995-10-18 08:53:40 +0000
committerTheo de Raadt <deraadt@cvs.openbsd.org>1995-10-18 08:53:40 +0000
commitd6583bb2a13f329cf0332ef2570eb8bb8fc0e39c (patch)
treeece253b876159b39c620e62b6c9b1174642e070e /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.c959
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