Home | History | Annotate | Line # | Download | only in dev
ite.c revision 1.1.1.2
      1 /*
      2  * Copyright (c) 1988 University of Utah.
      3  * Copyright (c) 1990 The Regents of the University of California.
      4  * All rights reserved.
      5  *
      6  * This code is derived from software contributed to Berkeley by
      7  * the Systems Programming Group of the University of Utah Computer
      8  * Science Department.
      9  *
     10  * Redistribution and use in source and binary forms, with or without
     11  * modification, are permitted provided that the following conditions
     12  * are met:
     13  * 1. Redistributions of source code must retain the above copyright
     14  *    notice, this list of conditions and the following disclaimer.
     15  * 2. Redistributions in binary form must reproduce the above copyright
     16  *    notice, this list of conditions and the following disclaimer in the
     17  *    documentation and/or other materials provided with the distribution.
     18  * 3. All advertising materials mentioning features or use of this software
     19  *    must display the following acknowledgement:
     20  *	This product includes software developed by the University of
     21  *	California, Berkeley and its contributors.
     22  * 4. Neither the name of the University nor the names of its contributors
     23  *    may be used to endorse or promote products derived from this software
     24  *    without specific prior written permission.
     25  *
     26  * THIS SOFTWARE IS PROVIDED BY THE REGENTS AND CONTRIBUTORS ``AS IS'' AND
     27  * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
     28  * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
     29  * ARE DISCLAIMED.  IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE
     30  * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
     31  * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
     32  * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
     33  * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
     34  * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
     35  * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
     36  * SUCH DAMAGE.
     37  *
     38  * from: Utah $Hdr: ite.c 1.1 90/07/09$
     39  *
     40  *	from: @(#)ite.c	7.6 (Berkeley) 5/16/91
     41  *	$Id: ite.c,v 1.1.1.2 1993/09/02 16:53:36 mw Exp $
     42  *
     43  * Original author: unknown
     44  * Amiga author:: Markus Wild
     45  * Other contributors: Bryan Ford (improved vt100 compability)
     46  */
     47 
     48 /*
     49  * Bit-mapped display terminal emulator machine independent code.
     50  * This is a very rudimentary.  Much more can be abstracted out of
     51  * the hardware dependent routines.
     52  */
     53 #include "ite.h"
     54 #if NITE > 0
     55 
     56 #include "grf.h"
     57 
     58 #undef NITE
     59 #define NITE	NGRF
     60 
     61 #include "param.h"
     62 #include "conf.h"
     63 #include "proc.h"
     64 #include "ioctl.h"
     65 #include "tty.h"
     66 #include "systm.h"
     67 #include "malloc.h"
     68 
     69 #include "itevar.h"
     70 #include "iteioctl.h"
     71 #include "kbdmap.h"
     72 
     73 #include "machine/cpu.h"
     74 #include "../amiga/cons.h"
     75 
     76 #ifdef __STDC__
     77 /* automatically generated, as you might guess:-) */
     78 
     79 struct consdev;
     80 struct itesw;
     81 
     82 extern int iteon (dev_t dev, int flag);
     83 extern int iteinit (dev_t dev);
     84 extern int iteoff (dev_t dev, int flag);
     85 extern int iteopen (dev_t dev, int mode, int devtype, struct proc *p);
     86 extern int iteclose (dev_t dev, int flag, int mode, struct proc *p);
     87 extern int iteread (dev_t dev, struct uio *uio, int flag);
     88 extern int itewrite (dev_t dev, struct uio *uio, int flag);
     89 extern int iteioctl (dev_t dev, int cmd, caddr_t addr, int flag);
     90 extern int itestart (register struct tty *tp);
     91 extern int itefilter (register u_char c, enum caller caller);
     92 extern void iteputchar (register int c, dev_t dev);
     93 extern int iteprecheckwrap (register struct ite_softc *ip, register struct itesw *sp);
     94 extern int itecheckwrap (register struct ite_softc *ip, register struct itesw *sp);
     95 extern int itecnprobe (struct consdev *cp);
     96 extern int itecninit (struct consdev *cp);
     97 extern int itecngetc (dev_t dev);
     98 extern int itecnputc (dev_t dev, int c);
     99 static void repeat_handler (int a0, int a1);
    100 static void inline ite_reset(struct ite_softc *ip);
    101 static void ite_dnchar (struct ite_softc *ip, struct itesw *sp, int n);
    102 static void ite_inchar (struct ite_softc *ip, struct itesw *sp, int n);
    103 static void ite_clrtoeol (struct ite_softc *ip, struct itesw *sp);
    104 static void ite_clrtobol (struct ite_softc *ip, struct itesw *sp);
    105 static void ite_clrline (struct ite_softc *ip, struct itesw *sp);
    106 static void ite_clrtoeos (struct ite_softc *ip, struct itesw *sp);
    107 static void ite_clrtobos (struct ite_softc *ip, struct itesw *sp);
    108 static void ite_clrscreen (struct ite_softc *ip, struct itesw *sp);
    109 static void ite_dnline (struct ite_softc *ip, struct itesw *sp, int n);
    110 static void ite_inline (struct ite_softc *ip, struct itesw *sp, int n);
    111 static void ite_lf (struct ite_softc *ip, struct itesw *sp);
    112 static void ite_crlf (struct ite_softc *ip, struct itesw *sp);
    113 static void ite_cr (struct ite_softc *ip, struct itesw *sp);
    114 static void ite_rlf (struct ite_softc *ip, struct itesw *sp);
    115 static int atoi (const char *cp);
    116 static char *index (const char *cp, char ch);
    117 static int ite_argnum (struct ite_softc *ip);
    118 static int ite_zargnum (struct ite_softc *ip);
    119 static void ite_sendstr (struct ite_softc *ip, char *str);
    120 static int strncmp (const char *a, const char *b, int l);
    121 #endif
    122 
    123 
    124 #define set_attr(ip, attr)	((ip)->attribute |= (attr))
    125 #define clr_attr(ip, attr)	((ip)->attribute &= ~(attr))
    126 
    127 extern  int nodev();
    128 
    129 int customc_scroll(),	customc_init(),		customc_deinit();
    130 int customc_clear(),	customc_putc(),		customc_cursor();
    131 
    132 int tiga_scroll(),	tiga_init(),		tiga_deinit();
    133 int tiga_clear(),	tiga_putc(),		tiga_cursor();
    134 
    135 int retina_scroll(),	retina_init(),		retina_deinit();
    136 int retina_clear(),	retina_putc(),		retina_cursor();
    137 
    138 struct itesw itesw[] =
    139 {
    140 	customc_init,		customc_deinit,		0,
    141 	0,			0,			0,
    142 
    143 	tiga_init,		tiga_deinit,		tiga_clear,
    144 	tiga_putc,		tiga_cursor,		tiga_scroll,
    145 
    146 	retina_init,		retina_deinit,		retina_clear,
    147 	retina_putc,		retina_cursor,		retina_scroll,
    148 };
    149 
    150 /*
    151  * # of chars are output in a single itestart() call.
    152  * If this is too big, user processes will be blocked out for
    153  * long periods of time while we are emptying the queue in itestart().
    154  * If it is too small, console output will be very ragged.
    155  */
    156 int	iteburst = 64;
    157 
    158 int	nite = NITE;
    159 
    160 struct  tty *kbd_tty = NULL;
    161 struct	ite_softc *kbd_ip = NULL;
    162 
    163 struct	tty ite_cons1, ite_cons2;
    164 #if 0
    165 struct	tty *ite_tty[NITE] = { &ite_cons1, &ite_cons2 };
    166 #else
    167 struct	tty *ite_tty[NITE];
    168 /* ugh.. */
    169 static int delayed_con_tty = -1;  /* if >= 0 set cn_tp later to that tty.. */
    170 #endif
    171 struct  ite_softc ite_softc[NITE];
    172 
    173 int	itestart();
    174 extern	int ttrstrt();
    175 extern	struct tty *constty;
    176 
    177 /* These are (later..) settable via an ioctl */
    178 int	start_repeat_timo = 20;	/* /100: initial timeout till pressed key repeats */
    179 int	next_repeat_timo  = 3;  /* /100: timeout when repeating for next char */
    180 
    181 #ifdef DO_WEIRD_ATTRIBUTES
    182 /*
    183  * Primary attribute buffer to be used by the first bitmapped console
    184  * found. Secondary displays alloc the attribute buffer as needed.
    185  * Size is based on a 68x128 display, which is currently our largest.
    186  */
    187 u_char  console_attributes[0x2200];
    188 #endif
    189 u_char	console_tabs[256 * NITE];
    190 
    191 /*
    192  * Perform functions necessary to setup device as a terminal emulator.
    193  */
    194 iteon(dev, flag)
    195 	dev_t dev;
    196 {
    197 	int unit = UNIT(dev);
    198 	struct tty *tp = ite_tty[unit];
    199 	struct ite_softc *ip = &ite_softc[unit];
    200 
    201 	if (unit < 0 || unit >= NITE || (ip->flags&ITE_ALIVE) == 0)
    202 		return(ENXIO);
    203 	/* force ite active, overriding graphics mode */
    204 	if (flag & 1) {
    205 		ip->flags |= ITE_ACTIVE;
    206 		ip->flags &= ~(ITE_INGRF|ITE_INITED);
    207 	}
    208 	/* leave graphics mode */
    209 	if (flag & 2) {
    210 		ip->flags &= ~ITE_INGRF;
    211 		if ((ip->flags & ITE_ACTIVE) == 0)
    212 			return(0);
    213 	}
    214 	ip->flags |= ITE_ACTIVE;
    215 	if (ip->flags & ITE_INGRF)
    216 		return(0);
    217 	if (tp && (kbd_tty == NULL || kbd_tty == tp)) {
    218 		kbd_tty = tp;
    219 		kbd_ip = ip;
    220 		kbdenable();
    221 	}
    222 	iteinit(dev);
    223 	return(0);
    224 }
    225 
    226 /* used by the grf layer to reinitialize ite after changing fb parameters */
    227 itereinit(dev)
    228      dev_t dev;
    229 {
    230   int unit = UNIT(dev);
    231   struct ite_softc *ip = &ite_softc[unit];
    232 
    233   ip->flags &= ~ITE_INITED;
    234   iteinit (dev);
    235 }
    236 
    237 iteinit(dev)
    238      dev_t dev;
    239 {
    240 	int unit = UNIT(dev);
    241 	struct ite_softc *ip = &ite_softc[unit];
    242 
    243 	if (ip->flags & ITE_INITED)
    244 		return;
    245 
    246 	bcopy (&ascii_kbdmap, &kbdmap, sizeof (struct kbdmap));
    247 
    248 	ip->cursorx = 0;
    249 	ip->cursory = 0;
    250 	(*itesw[ip->type].ite_init)(ip);
    251 
    252 #ifdef DO_WEIRD_ATTRIBUTES
    253 	if (ip->attrbuf == NULL)
    254 		ip->attrbuf = (u_char *)
    255 			malloc(ip->rows * ip->cols, M_DEVBUF, M_WAITOK);
    256 	bzero(ip->attrbuf, (ip->rows * ip->cols));
    257 #endif
    258 	if (! ip->tabs)
    259 	  {
    260 	    /* can't use malloc, as this buffer might be used before
    261 	       the allocators are initialized (console!) */
    262 	    ip->tabs = &console_tabs[unit * 256];
    263 	  }
    264 
    265 	ite_reset (ip);
    266 
    267 	(*itesw[ip->type].ite_cursor)(ip, DRAW_CURSOR);
    268 	ip->flags |= ITE_INITED;
    269 }
    270 
    271 /*
    272  * "Shut down" device as terminal emulator.
    273  * Note that we do not deinit the console device unless forced.
    274  * Deinit'ing the console every time leads to a very active
    275  * screen when processing /etc/rc.
    276  */
    277 iteoff(dev, flag)
    278 	dev_t dev;
    279 {
    280 	register struct ite_softc *ip = &ite_softc[UNIT(dev)];
    281 
    282 	if (flag & 2)
    283 		ip->flags |= ITE_INGRF;
    284 	if ((ip->flags & ITE_ACTIVE) == 0)
    285 		return;
    286 	if ((flag & 1) ||
    287 	    (ip->flags & (ITE_INGRF|ITE_ISCONS|ITE_INITED)) == ITE_INITED)
    288 		(*itesw[ip->type].ite_deinit)(ip);
    289 	if ((flag & 2) == 0)
    290 		ip->flags &= ~ITE_ACTIVE;
    291 }
    292 
    293 /* ARGSUSED */
    294 #ifdef __STDC__
    295 iteopen(dev_t dev, int mode, int devtype, struct proc *p)
    296 #else
    297 iteopen(dev, mode, devtype, p)
    298 	dev_t dev;
    299 	int mode, devtype;
    300 	struct proc *p;
    301 #endif
    302 {
    303 	int unit = UNIT(dev);
    304 	register struct tty *tp;
    305 	register struct ite_softc *ip = &ite_softc[unit];
    306 	register int error;
    307 	int first = 0;
    308 
    309 	if (unit >= NITE)
    310 	  return ENXIO;
    311 
    312 	if(!ite_tty[unit]) {
    313 #if 0
    314 		MALLOC(tp, struct tty *, sizeof(struct tty), M_TTYS, M_WAITOK);
    315 		bzero(tp, sizeof(struct tty));
    316 		ite_tty[unit] = tp;
    317 #else
    318 		tp = ite_tty[unit] = ttymalloc();
    319 		/* HA! caught it finally... */
    320 		if (unit == delayed_con_tty)
    321 		  {
    322 		    extern struct consdev *cn_tab;
    323 		    extern struct tty *cn_tty;
    324 
    325 		    kbd_tty = tp;
    326 		    kbd_ip = ip;
    327 		    kbdenable ();
    328 		    cn_tty = cn_tab->cn_tp = tp;
    329 		    delayed_con_tty = -1;
    330 		  }
    331 #endif
    332 	} else
    333 		tp = ite_tty[unit];
    334 
    335 	if ((tp->t_state&(TS_ISOPEN|TS_XCLUDE)) == (TS_ISOPEN|TS_XCLUDE)
    336 	    && p->p_ucred->cr_uid != 0)
    337 		return (EBUSY);
    338 	if ((ip->flags & ITE_ACTIVE) == 0) {
    339 		error = iteon(dev, 0);
    340 		if (error)
    341 			return (error);
    342 		first = 1;
    343 	}
    344 	tp->t_oproc = itestart;
    345 	tp->t_param = NULL;
    346 	tp->t_dev = dev;
    347 	if ((tp->t_state&TS_ISOPEN) == 0) {
    348 		ttychars(tp);
    349 		tp->t_iflag = TTYDEF_IFLAG;
    350 		tp->t_oflag = TTYDEF_OFLAG;
    351 		tp->t_cflag = CS8|CREAD;
    352 		tp->t_lflag = TTYDEF_LFLAG;
    353 		tp->t_ispeed = tp->t_ospeed = TTYDEF_SPEED;
    354 		/* don't set TS_ISOPEN  here, or the tty queues won't
    355 		   be initialized in ttyopen()! */
    356 		tp->t_state = TS_CARR_ON;
    357 		ttsetwater(tp);
    358 	}
    359 	error = (*linesw[tp->t_line].l_open)(dev, tp);
    360 	if (error == 0) {
    361 		tp->t_winsize.ws_row = ip->rows;
    362 		tp->t_winsize.ws_col = ip->cols;
    363 		ip->open_cnt++;
    364 	} else if (first)
    365 		iteoff(dev, 0);
    366 	return (error);
    367 }
    368 
    369 /*ARGSUSED*/
    370 iteclose(dev, flag, mode, p)
    371 	dev_t dev;
    372 	int flag, mode;
    373 	struct proc *p;
    374 {
    375 	int unit = UNIT(dev);
    376 	register struct tty *tp = ite_tty[unit];
    377 	register struct ite_softc *ip = &ite_softc[unit];
    378 
    379 #if 0
    380 	/* aliasing with /dev/console can lead to such weird problems... */
    381 	if (ip->open_cnt-- > 0)
    382 	  return 0;
    383 #endif
    384 
    385 	if (tp)
    386 	  {
    387 	    (*linesw[tp->t_line].l_close)(tp, flag);
    388 	    ttyclose(tp);
    389 	  }
    390 	iteoff(dev, 0);
    391 #if 0
    392 	if (tp != &ite_cons)
    393 	  {
    394 #if 0
    395 	    FREE(tp, M_TTYS);
    396 #else
    397 	    ttyfree (tp);
    398 #endif
    399 	    ite_tty[UNIT(dev)] = (struct tty *)NULL;
    400 	  }
    401 #endif
    402 	return(0);
    403 }
    404 
    405 iteread(dev, uio, flag)
    406 	dev_t dev;
    407 	struct uio *uio;
    408 {
    409 	register struct tty *tp = ite_tty[UNIT(dev)];
    410 	int rc;
    411 
    412 	if (! tp)
    413 	  return ENXIO;
    414 
    415 	rc = ((*linesw[tp->t_line].l_read)(tp, uio, flag));
    416 	return rc;
    417 }
    418 
    419 itewrite(dev, uio, flag)
    420 	dev_t dev;
    421 	struct uio *uio;
    422 {
    423 	int unit = UNIT(dev);
    424 	register struct tty *tp = ite_tty[unit];
    425 
    426 	if (! tp)
    427 	  return ENXIO;
    428 
    429 	if ((ite_softc[unit].flags & ITE_ISCONS) && constty &&
    430 	    (constty->t_state&(TS_CARR_ON|TS_ISOPEN))==(TS_CARR_ON|TS_ISOPEN))
    431 		tp = constty;
    432 	return ((*linesw[tp->t_line].l_write)(tp, uio, flag));
    433 }
    434 
    435 iteioctl(dev, cmd, addr, flag)
    436 	dev_t dev;
    437 	caddr_t addr;
    438 {
    439 	register struct tty *tp = ite_tty[UNIT(dev)];
    440 	int error;
    441 
    442 	if (! tp)
    443 	  return ENXIO;
    444 
    445 
    446 	error = (*linesw[tp->t_line].l_ioctl)(tp, cmd, addr, flag);
    447 	if (error >= 0)
    448 		return (error);
    449 	error = ttioctl(tp, cmd, addr, flag);
    450 	if (error >= 0)
    451 		return (error);
    452 
    453 	switch (cmd)
    454 	  {
    455 	  case ITELOADKMAP:
    456 	    if (addr)
    457 	      {
    458 		bcopy (addr, &kbdmap, sizeof (struct kbdmap));
    459 		return 0;
    460 	      }
    461 	    else
    462 	      return EFAULT;
    463 
    464 	  case ITEGETKMAP:
    465 	    if (addr)
    466 	      {
    467 		bcopy (&kbdmap, addr, sizeof (struct kbdmap));
    468 		return 0;
    469 	      }
    470 	    else
    471 	      return EFAULT;
    472 	  }
    473 
    474 
    475 	return (ENOTTY);
    476 }
    477 
    478 itestart(tp)
    479 	register struct tty *tp;
    480 {
    481 	register int cc, s;
    482 	int unit = UNIT(tp->t_dev);
    483 	register struct ite_softc *ip = &ite_softc[unit];
    484 	int hiwat = 0;
    485 
    486 	s = spltty();
    487 	if (tp->t_state & (TS_TIMEOUT|TS_BUSY|TS_TTSTOP)) {
    488 		splx(s);
    489 		return;
    490 	}
    491 	tp->t_state |= TS_BUSY;
    492 	cc = tp->t_outq.c_cc;
    493 	if (cc <= tp->t_lowat) {
    494 		if (tp->t_state & TS_ASLEEP) {
    495 			tp->t_state &= ~TS_ASLEEP;
    496 			wakeup((caddr_t) &tp->t_outq);
    497 		}
    498 		selwakeup(&tp->t_wsel);
    499 	}
    500 	/*
    501 	 * Limit the amount of output we do in one burst
    502 	 * to prevent hogging the CPU.
    503 	 */
    504 	if (cc > iteburst) {
    505 		hiwat++;
    506 		cc = iteburst;
    507 	}
    508 	(*itesw[ip->type].ite_cursor)(ip, START_CURSOROPT);
    509 	while (--cc >= 0) {
    510 		register int c;
    511 
    512 		c = getc(&tp->t_outq);
    513 		/*
    514 		 * iteputchar() may take a long time and we don't want to
    515 		 * block all interrupts for long periods of time.  Since
    516 		 * there is no need to stay at high priority while outputing
    517 		 * the character (since we don't have to worry about
    518 		 * interrupts), we don't.  We just need to make sure that
    519 		 * we don't reenter iteputchar, which is guarenteed by the
    520 		 * earlier setting of TS_BUSY.
    521 		 */
    522 		splx(s);
    523 		iteputchar(c, tp->t_dev);
    524 		spltty();
    525 	}
    526 	(*itesw[ip->type].ite_cursor)(ip, END_CURSOROPT);
    527 	if (hiwat) {
    528 		tp->t_state |= TS_TIMEOUT;
    529 		timeout((timeout_t) ttrstrt, (caddr_t) tp, 1);
    530 	}
    531 	tp->t_state &= ~TS_BUSY;
    532 	splx(s);
    533 }
    534 
    535 /* these are used to implement repeating keys.. */
    536 static u_char last_char = 0;
    537 static u_char tout_pending = 0;
    538 
    539 static void
    540 repeat_handler (a0, a1)
    541     int a0, a1;
    542 {
    543   tout_pending = 0;
    544   /* leave it up to itefilter() to possibly install a new callout entry
    545      to reinvoke repeat_handler() */
    546   if (last_char)
    547     {
    548       /* don't call itefilter directly, we're at spl6 here, and have
    549 	 blocked out way too much stuff. Besides, the keyboard wouldn't
    550 	 even have a chance to tell us about key-up events if we
    551 	 did.. */
    552       add_sicallback (itefilter, last_char, ITEFILT_REPEATER);
    553 
    554       /* itefilter (last_char, ITEFILT_REPEATER); */
    555     }
    556 }
    557 
    558 static void inline
    559 itesendch (int ch)
    560 {
    561   (*linesw[kbd_tty->t_line].l_rint)(ch, kbd_tty);
    562 }
    563 
    564 
    565 int
    566 itefilter(c, caller)
    567      register u_char c;
    568      enum caller caller;
    569 {
    570   static u_char mod = 0;
    571   static u_char last_dead = 0;
    572   register unsigned char code, *str;
    573   u_char up, mask, i;
    574   struct key key;
    575   int s;
    576 
    577   if (caller != ITEFILT_CONSOLE && kbd_tty == NULL)
    578      return;
    579 
    580   /* have to make sure we're at spltty in here */
    581   s = spltty ();
    582 
    583   /* keyboard interrupts come at priority 2, while softint-
    584      generated keyboard-repeat interrupts come at level 1.
    585      So, to not allow a key-up event to get thru before
    586      a repeat for the key-down, we remove any outstanding
    587      callout requests.. */
    588   rem_sicallback (itefilter);
    589 
    590   up = c & 0x80 ? 1 : 0;
    591   c &= 0x7f;
    592   code = 0;
    593 
    594   mask = 0;
    595   if (c >= KBD_LEFT_SHIFT)
    596     {
    597       switch (c)
    598         {
    599         case KBD_LEFT_SHIFT:
    600           mask = KBD_MOD_LSHIFT;
    601           break;
    602 
    603         case KBD_RIGHT_SHIFT:
    604           mask = KBD_MOD_RSHIFT;
    605           break;
    606 
    607         case KBD_LEFT_ALT:
    608           mask = KBD_MOD_LALT;
    609           break;
    610 
    611         case KBD_RIGHT_ALT:
    612           mask = KBD_MOD_RALT;
    613           break;
    614 
    615         case KBD_LEFT_META:
    616           mask = KBD_MOD_LMETA;
    617           break;
    618 
    619         case KBD_RIGHT_META:
    620           mask = KBD_MOD_RMETA;
    621           break;
    622 
    623         case KBD_CAPS_LOCK:
    624           /* capslock already behaves `right', don't need to keep track of the
    625              state in here. */
    626           mask = KBD_MOD_CAPS;
    627           break;
    628 
    629         case KBD_CTRL:
    630           mask = KBD_MOD_CTRL;
    631           break;
    632         }
    633 
    634       if (mask)
    635         {
    636           if (up)
    637             mod &= ~mask;
    638           else
    639             mod |= mask;
    640         }
    641 
    642       /* these keys should not repeat, so it's the Right Thing dealing with
    643          repeaters only after this block. */
    644 
    645       /* return even if it wasn't a modifier key, the other codes up here
    646          are either special (like reset warning), or not yet defined */
    647       splx (s);
    648       return -1;
    649     }
    650 
    651   /* no matter which character we're repeating, stop it if we get a key-up
    652      event. I think this is the same thing amigados does. */
    653   if (up)
    654     {
    655       if (tout_pending)
    656         {
    657           untimeout ((timeout_t) repeat_handler, 0);
    658           tout_pending = 0;
    659 	  last_char = 0;
    660         }
    661       splx (s);
    662       return -1;
    663     }
    664 
    665 
    666   /* intercept Ctrl-LAlt-F1 here to switch back to original ascii-keymap.
    667      this should probably be configurable.. */
    668   if (mod == (KBD_MOD_LALT|KBD_MOD_SHIFT) && code == 0x50)
    669     {
    670       bcopy (&ascii_kbdmap, &kbdmap, sizeof (struct kbdmap));
    671       splx (s);
    672       return -1;
    673     }
    674 
    675 
    676   switch (mod & (KBD_MOD_ALT | KBD_MOD_SHIFT))
    677     {
    678     case 0:
    679 	key = kbdmap.keys[c];
    680 	if (!(mod & KBD_MOD_CAPS) || !(key.mode & KBD_MODE_CAPS))
    681 	  break;
    682 	/* FALL INTO */
    683 
    684     case KBD_MOD_LSHIFT:
    685     case KBD_MOD_RSHIFT:
    686     case KBD_MOD_SHIFT:
    687         key = kbdmap.shift_keys[c];
    688         break;
    689 
    690     case KBD_MOD_LALT:
    691     case KBD_MOD_RALT:
    692     case KBD_MOD_ALT:
    693 	key = kbdmap.alt_keys[c];
    694 	if (!(mod & KBD_MOD_CAPS) || !(key.mode & KBD_MODE_CAPS))
    695 	  break;
    696 	/* FALL INTO */
    697 
    698     case KBD_MOD_LALT|KBD_MOD_LSHIFT:
    699     case KBD_MOD_LALT|KBD_MOD_RSHIFT:
    700     case KBD_MOD_LALT|KBD_MOD_SHIFT:
    701     case KBD_MOD_RALT|KBD_MOD_RSHIFT:
    702     case KBD_MOD_RALT|KBD_MOD_SHIFT:
    703     case KBD_MOD_ALT|KBD_MOD_RSHIFT:
    704 	key = kbdmap.alt_shift_keys[c];
    705 	break;
    706     }
    707 
    708   code = key.code;
    709 
    710   /* arrange to repeat the keystroke. By doing this at the level of scan-codes,
    711      we can have function keys, and keys that send strings, repeat too. This
    712      also entitles an additional overhead, since we have to do the conversion
    713      each time, but I guess that's ok. */
    714   if (!tout_pending && caller == ITEFILT_TTY && kbd_ip->key_repeat)
    715     {
    716       tout_pending = 1;
    717       last_char = c;
    718       timeout ((timeout_t) repeat_handler, 0, start_repeat_timo);
    719     }
    720   else if (!tout_pending && caller == ITEFILT_REPEATER && kbd_ip->key_repeat)
    721     {
    722       tout_pending = 1;
    723       last_char = c;
    724       timeout ((timeout_t) repeat_handler, 0, next_repeat_timo);
    725     }
    726 
    727   /* handle dead keys */
    728   if (key.mode & KBD_MODE_DEAD)
    729     {
    730       /* if entered twice, send accent itself */
    731       if (last_dead == key.mode & KBD_MODE_ACCMASK)
    732         last_dead = 0;
    733       else
    734 	{
    735 	  last_dead = key.mode & KBD_MODE_ACCMASK;
    736 	  splx (s);
    737 	  return -1;
    738 	}
    739     }
    740   if (last_dead)
    741     {
    742       /* can't apply dead flag to string-keys */
    743       if (! (key.mode & KBD_MODE_STRING) && code >= '@' && code < 0x7f)
    744         code = acctable[KBD_MODE_ACCENT (last_dead)][code - '@'];
    745 
    746       last_dead = 0;
    747     }
    748 
    749   /* if not string, apply META and CTRL modifiers */
    750   if (! (key.mode & KBD_MODE_STRING))
    751     {
    752       if (mod & KBD_MOD_CTRL)
    753         code &= 0x1f;
    754 
    755       if (mod & KBD_MOD_META)
    756         code |= 0x80;
    757     }
    758   else
    759     {
    760       /* strings are only supported in normal tty mode, not in console mode */
    761       if (caller != ITEFILT_CONSOLE)
    762         {
    763           str = kbdmap.strings + code;
    764           /* using a length-byte instead of 0-termination allows to embed \0 into
    765              strings, although this is not used in the default keymap */
    766           for (i = *str++; i; i--)
    767             itesendch(*str++);
    768         }
    769       splx (s);
    770       return -1;
    771     }
    772 
    773   if (caller == ITEFILT_CONSOLE)
    774     {
    775       /* do the conversion here because raw console input doesn't go thru
    776 	 tty conversions */
    777       code = code == '\r' ? '\n' : code;
    778       splx (s);
    779       return code;
    780     }
    781   else
    782     /* NOTE: *don't* do any cr->crlf conversion here, this is input
    783 	     processing, the mentioned conversion should only be
    784 	     done for output processing (for input, it is not
    785 	     terminal-specific but depends on tty-settings!) */
    786     (*linesw[kbd_tty->t_line].l_rint)(code, kbd_tty);
    787 
    788   splx (s);
    789   return -1;
    790 }
    791 
    792 
    793 /* helper functions, makes the code below more readable */
    794 static void inline
    795 ite_sendstr (ip, str)
    796     struct ite_softc *ip;
    797     char *str;
    798 {
    799   while (*str)
    800     itesendch (*str++);
    801 }
    802 
    803 static void
    804 alignment_display(struct ite_softc *ip, struct itesw *sp)
    805 {
    806   int i, j;
    807 
    808   for (j = 0; j < ip->rows; j++)
    809     for (i = 0; i < ip->cols; i++)
    810       (*sp->ite_putc)(ip, 'E', j, i, ATTR_NOR);
    811   attrclr(ip, 0, 0, ip->rows, ip->cols);
    812   (*sp->ite_cursor)(ip, DRAW_CURSOR);
    813 }
    814 
    815 static void inline
    816 snap_cury(struct ite_softc *ip, struct itesw *sp)
    817 {
    818   if (ip->inside_margins)
    819     {
    820       if (ip->cury < ip->top_margin)
    821 	ip->cury = ip->top_margin;
    822       if (ip->cury > ip->bottom_margin)
    823 	ip->cury = ip->bottom_margin;
    824     }
    825 }
    826 
    827 static void inline
    828 ite_dnchar(ip, sp, n)
    829      struct ite_softc *ip;
    830      struct itesw *sp;
    831      int n;
    832 {
    833   n = MIN(n, ip->cols - ip->curx);
    834   if (n < ip->cols - ip->curx)
    835     {
    836       (*sp->ite_scroll)(ip, ip->cury, ip->curx + n, n, SCROLL_LEFT);
    837       attrmov(ip, ip->cury, ip->curx + n, ip->cury, ip->curx,
    838 	      1, ip->cols - ip->curx - n);
    839       attrclr(ip, ip->cury, ip->cols - n, 1, n);
    840     }
    841   while (n-- > 0)
    842     (*sp->ite_putc)(ip, ' ', ip->cury, ip->cols - n - 1, ATTR_NOR);
    843   (*sp->ite_cursor)(ip, DRAW_CURSOR);
    844 }
    845 
    846 static void inline
    847 ite_inchar(ip, sp, n)
    848      struct ite_softc *ip;
    849      struct itesw *sp;
    850      int n;
    851 {
    852   n = MIN(n, ip->cols - ip->curx);
    853   if (n < ip->cols - ip->curx)
    854     {
    855       (*sp->ite_scroll)(ip, ip->cury, ip->curx, n, SCROLL_RIGHT);
    856       attrmov(ip, ip->cury, ip->curx, ip->cury, ip->curx + n,
    857 	      1, ip->cols - ip->curx - n);
    858       attrclr(ip, ip->cury, ip->curx, 1, n);
    859     }
    860   while (n--)
    861     (*sp->ite_putc)(ip, ' ', ip->cury, ip->curx + n, ATTR_NOR);
    862   (*sp->ite_cursor)(ip, DRAW_CURSOR);
    863 }
    864 
    865 static void inline
    866 ite_clrtoeol(ip, sp)
    867      struct ite_softc *ip;
    868      struct itesw *sp;
    869 {
    870   int y = ip->cury, x = ip->curx;
    871   if (ip->cols - x > 0)
    872     {
    873       (*sp->ite_clear)(ip, y, x, 1, ip->cols - x);
    874       attrclr(ip, y, x, 1, ip->cols - x);
    875       (*sp->ite_cursor)(ip, DRAW_CURSOR);
    876     }
    877 }
    878 
    879 static void inline
    880 ite_clrtobol(ip, sp)
    881      struct ite_softc *ip;
    882      struct itesw *sp;
    883 {
    884   int y = ip->cury, x = MIN(ip->curx + 1, ip->cols);
    885   (*sp->ite_clear)(ip, y, 0, 1, x);
    886   attrclr(ip, y, 0, 1, x);
    887   (*sp->ite_cursor)(ip, DRAW_CURSOR);
    888 }
    889 
    890 static void inline
    891 ite_clrline(ip, sp)
    892      struct ite_softc *ip;
    893      struct itesw *sp;
    894 {
    895   int y = ip->cury;
    896   (*sp->ite_clear)(ip, y, 0, 1, ip->cols);
    897   attrclr(ip, y, 0, 1, ip->cols);
    898   (*sp->ite_cursor)(ip, DRAW_CURSOR);
    899 }
    900 
    901 
    902 
    903 static void inline
    904 ite_clrtoeos(ip, sp)
    905      struct ite_softc *ip;
    906      struct itesw *sp;
    907 {
    908   ite_clrtoeol(ip, sp);
    909   if (ip->cury < ip->rows - 1)
    910     {
    911       (*sp->ite_clear)(ip, ip->cury + 1, 0, ip->rows - 1 - ip->cury, ip->cols);
    912       attrclr(ip, ip->cury, 0, ip->rows - ip->cury, ip->cols);
    913       (*sp->ite_cursor)(ip, DRAW_CURSOR);
    914     }
    915 }
    916 
    917 static void inline
    918 ite_clrtobos(ip, sp)
    919      struct ite_softc *ip;
    920      struct itesw *sp;
    921 {
    922   ite_clrtobol(ip, sp);
    923   if (ip->cury > 0)
    924     {
    925       (*sp->ite_clear)(ip, 0, 0, ip->cury, ip->cols);
    926       attrclr(ip, 0, 0, ip->cury, ip->cols);
    927       (*sp->ite_cursor)(ip, DRAW_CURSOR);
    928     }
    929 }
    930 
    931 static void inline
    932 ite_clrscreen(ip, sp)
    933      struct ite_softc *ip;
    934      struct itesw *sp;
    935 {
    936   (*sp->ite_clear)(ip, 0, 0, ip->rows, ip->cols);
    937   attrclr(ip, 0, 0, ip->rows, ip->cols);
    938   (*sp->ite_cursor)(ip, DRAW_CURSOR);
    939 }
    940 
    941 
    942 
    943 static void inline
    944 ite_dnline(ip, sp, n)
    945      struct ite_softc *ip;
    946      struct itesw *sp;
    947      int n;
    948 {
    949   n = MIN(n, ip->bottom_margin + 1 - ip->cury);
    950   if (n <= ip->bottom_margin - ip->cury)
    951     {
    952       (*sp->ite_scroll)(ip, ip->cury + n, 0, n, SCROLL_UP);
    953       attrmov(ip, ip->cury + n, 0, ip->cury, 0,
    954 	      ip->bottom_margin + 1 - ip->cury - n, ip->cols);
    955     }
    956   (*sp->ite_clear)(ip, ip->bottom_margin - n + 1, 0, n, ip->cols);
    957   attrclr(ip, ip->bottom_margin - n + 1, 0, n, ip->cols);
    958   (*sp->ite_cursor)(ip, DRAW_CURSOR);
    959 }
    960 
    961 static void inline
    962 ite_inline(ip, sp, n)
    963      struct ite_softc *ip;
    964      struct itesw *sp;
    965      int n;
    966 {
    967   if ((ip->cury >= ip->top_margin) && (ip->cury <= ip->bottom_margin))
    968     {
    969       n = MIN(n, ip->bottom_margin + 1 - ip->cury);
    970       if (n <= ip->bottom_margin - ip->cury)
    971 	{
    972 	  (*sp->ite_scroll)(ip, ip->cury, 0, n, SCROLL_DOWN);
    973 	  attrmov(ip, ip->cury, 0, ip->cury + n, 0,
    974 		  ip->bottom_margin + 1 - ip->cury - n, ip->cols);
    975 	}
    976       (*sp->ite_clear)(ip, ip->cury, 0, n, ip->cols);
    977       attrclr(ip, ip->cury, 0, n, ip->cols);
    978       (*sp->ite_cursor)(ip, DRAW_CURSOR);
    979     }
    980 }
    981 
    982 static void inline
    983 ite_lf (ip, sp)
    984      struct ite_softc *ip;
    985      struct itesw *sp;
    986 {
    987   if (ip->inside_margins)
    988     {
    989       ++ip->cury;
    990       if ((ip->cury == ip->bottom_margin+1) || (ip->cury == ip->rows))
    991         {
    992           ip->cury--;
    993           (*sp->ite_scroll)(ip, ip->top_margin + 1, 0, 1, SCROLL_UP);
    994           ite_clrline(ip, sp);
    995         }
    996       (*sp->ite_cursor)(ip, MOVE_CURSOR);
    997     }
    998   else
    999     {
   1000       if (++ip->cury >= ip->rows)
   1001         {
   1002           ip->cury = ip->rows - 1;
   1003           (*sp->ite_scroll)(ip, 1, 0, 1, SCROLL_UP);
   1004           ite_clrline(ip, sp);
   1005         }
   1006       (*sp->ite_cursor)(ip, MOVE_CURSOR);
   1007     }
   1008   clr_attr(ip, ATTR_INV);
   1009 }
   1010 
   1011 static void inline
   1012 ite_crlf (ip, sp)
   1013      struct ite_softc *ip;
   1014      struct itesw *sp;
   1015 {
   1016   ip->curx = 0;
   1017   ite_lf (ip, sp);
   1018 }
   1019 
   1020 static void inline
   1021 ite_cr (ip, sp)
   1022      struct ite_softc *ip;
   1023      struct itesw *sp;
   1024 {
   1025   if (ip->curx)
   1026     {
   1027       ip->curx = 0;
   1028       (*sp->ite_cursor)(ip, MOVE_CURSOR);
   1029     }
   1030 }
   1031 
   1032 static void inline
   1033 ite_rlf (ip, sp)
   1034      struct ite_softc *ip;
   1035      struct itesw *sp;
   1036 {
   1037   int top = ip->inside_margins ? ip->top_margin : 0;
   1038 
   1039   ip->cury--;
   1040   if ((ip->cury < 0) || (ip->cury == top-1))
   1041     {
   1042       ip->cury++;
   1043       (*sp->ite_scroll)(ip, top, 0, 1, SCROLL_DOWN);
   1044       ite_clrline(ip, sp);
   1045     }
   1046   (*sp->ite_cursor)(ip, MOVE_CURSOR);
   1047   clr_attr(ip, ATTR_INV);
   1048 }
   1049 
   1050 static int inline
   1051 atoi (cp)
   1052     const char *cp;
   1053 {
   1054   int n;
   1055 
   1056   for (n = 0; *cp && *cp >= '0' && *cp <= '9'; cp++)
   1057     n = n * 10 + *cp - '0';
   1058 
   1059   return n;
   1060 }
   1061 
   1062 static char *
   1063 index (cp, ch)
   1064     const char *cp;
   1065     char ch;
   1066 {
   1067   while (*cp && *cp != ch) cp++;
   1068   return *cp ? (char *) cp : 0;
   1069 }
   1070 
   1071 
   1072 
   1073 static int inline
   1074 ite_argnum (ip)
   1075     struct ite_softc *ip;
   1076 {
   1077   char ch;
   1078   int n;
   1079 
   1080   /* convert argument string into number */
   1081   if (ip->ap == ip->argbuf)
   1082     return 1;
   1083   ch = *ip->ap;
   1084   *ip->ap = 0;
   1085   n = atoi (ip->argbuf);
   1086   *ip->ap = ch;
   1087 
   1088   return n;
   1089 }
   1090 
   1091 static int inline
   1092 ite_zargnum (ip)
   1093     struct ite_softc *ip;
   1094 {
   1095   char ch, *cp;
   1096   int n;
   1097 
   1098   /* convert argument string into number */
   1099   if (ip->ap == ip->argbuf)
   1100     return 0;
   1101   ch = *ip->ap;
   1102   *ip->ap = 0;
   1103   n = atoi (ip->argbuf);
   1104   *ip->ap = ch;
   1105 
   1106   return n;	/* don't "n ? n : 1" here, <CSI>0m != <CSI>1m ! */
   1107 }
   1108 
   1109 static int inline
   1110 strncmp (a, b, l)
   1111     const char *a, *b;
   1112     int l;
   1113 {
   1114   for (;l--; a++, b++)
   1115     if (*a != *b)
   1116       return *a - *b;
   1117   return 0;
   1118 }
   1119 
   1120 static void inline
   1121 ite_reset(ip)
   1122     struct ite_softc *ip;
   1123 {
   1124   int i;
   1125 
   1126   ip->curx = 0;
   1127   ip->cury = 0;
   1128   ip->attribute = 0;
   1129   ip->save_curx = 0;
   1130   ip->save_cury = 0;
   1131   ip->save_attribute = 0;
   1132   ip->ap = ip->argbuf;
   1133   ip->emul_level = EMUL_VT300_7;
   1134   ip->eightbit_C1 = 0;
   1135   ip->top_margin = 0; ip->bottom_margin = ip->rows - 1;
   1136   ip->inside_margins = 1;
   1137   ip->linefeed_newline = 0;
   1138   ip->auto_wrap = 0;
   1139   ip->cursor_appmode = 0;
   1140   ip->keypad_appmode = 0;
   1141   ip->imode = 0;
   1142   ip->key_repeat = 1;
   1143 
   1144 #ifdef DO_WEIRD_ATTRIBUTES
   1145   bzero(ip->attrbuf, (ip->rows * ip->cols));
   1146 #endif
   1147   bzero (ip->tabs, ip->cols);
   1148   for (i = 0; i < ip->cols; i++)
   1149     ip->tabs[i] = (i & 7) == 0;
   1150 }
   1151 
   1152 
   1153 void
   1154 iteputchar(c, dev)
   1155 	register int c;
   1156 	dev_t dev;
   1157 {
   1158 	int unit = UNIT(dev);
   1159 	register struct ite_softc *ip = &ite_softc[unit];
   1160 	register struct itesw *sp = &itesw[ip->type];
   1161 	register int n;
   1162 	int x, y;
   1163 	char *cp;
   1164 
   1165 	if ((ip->flags & (ITE_ACTIVE|ITE_INGRF)) != ITE_ACTIVE)
   1166 	  	return;
   1167 
   1168 #if 0
   1169 	if (ite_tty[unit])
   1170 	  if ((ite_tty[unit]->t_cflag & CSIZE) == CS7
   1171 	      || (ite_tty[unit]->t_cflag & PARENB))
   1172 	    c &= 0x7f;
   1173 #endif
   1174 
   1175 	if (ip->escape)
   1176 	  {
   1177 doesc:
   1178 	    switch (ip->escape)
   1179 	      {
   1180 	      case ESC:
   1181 	        switch (c)
   1182 	          {
   1183 		  /* first 7bit equivalents for the 8bit control characters */
   1184 
   1185 	          case 'D':
   1186 		    c = IND;
   1187 		    ip->escape = 0;
   1188 		    break; /* and fall into the next switch below (same for all `break') */
   1189 
   1190 		  case 'E':
   1191 		    c = NEL;
   1192 		    ip->escape = 0;
   1193 		    break;
   1194 
   1195 		  case 'H':
   1196 		    c = HTS;
   1197 		    ip->escape = 0;
   1198 		    break;
   1199 
   1200 		  case 'M':
   1201 		    c = RI;
   1202 		    ip->escape = 0;
   1203 		    break;
   1204 
   1205 		  case 'N':
   1206 		    c = SS2;
   1207 		    ip->escape = 0;
   1208 		    break;
   1209 
   1210 		  case 'O':
   1211 		    c = SS3;
   1212 		    ip->escape = 0;
   1213 		    break;
   1214 
   1215 		  case 'P':
   1216 		    c = DCS;
   1217 		    ip->escape = 0;
   1218 		    break;
   1219 
   1220 		  case '[':
   1221 		    c = CSI;
   1222 		    ip->escape = 0;
   1223 		    break;
   1224 
   1225 		  case '\\':
   1226 		    c = ST;
   1227 		    ip->escape = 0;
   1228 		    break;
   1229 
   1230 		  case ']':
   1231 		    c = OSC;
   1232 		    ip->escape = 0;
   1233 		    break;
   1234 
   1235 		  case '^':
   1236 		    c = PM;
   1237 		    ip->escape = 0;
   1238 		    break;
   1239 
   1240 		  case '_':
   1241 		    c = APC;
   1242 		    ip->escape = 0;
   1243 		    break;
   1244 
   1245 
   1246 		  /* introduces 7/8bit control */
   1247 		  case ' ':
   1248 		     /* can be followed by either F or G */
   1249 		     ip->escape = ' ';
   1250 		     break;
   1251 
   1252 
   1253 		  /* a lot of character set selections, not yet used...
   1254 		     94-character sets: */
   1255 		  case '(':	/* G0 */
   1256 		  case ')':	/* G1 */
   1257 		    ip->escape = c;
   1258 		    return;
   1259 
   1260 		  case '*':	/* G2 */
   1261 		  case '+':	/* G3 */
   1262 		  case 'B':	/* ASCII */
   1263 		  case 'A':	/* ISO latin 1 */
   1264 		  case '<':	/* user preferred suplemental */
   1265 		  case '0':	/* dec special graphics */
   1266 
   1267 		  /* 96-character sets: */
   1268 		  case '-':	/* G1 */
   1269 		  case '.':	/* G2 */
   1270 		  case '/':	/* G3 */
   1271 
   1272 		  /* national character sets: */
   1273 		  case '4':	/* dutch */
   1274 		  case '5':
   1275 		  case 'C':	/* finnish */
   1276 		  case 'R':	/* french */
   1277 		  case 'Q':	/* french canadian */
   1278 		  case 'K':	/* german */
   1279 		  case 'Y':	/* italian */
   1280 		  case '6':	/* norwegian/danish */
   1281 		  /* note: %5 and %6 are not supported (two chars..) */
   1282 
   1283 		    ip->escape = 0;
   1284 		    /* just ignore for now */
   1285 		    return;
   1286 
   1287 
   1288 		  /* locking shift modes (as you might guess, not yet supported..) */
   1289 		  case '`':
   1290 		    ip->GR = ip->G1;
   1291 		    ip->escape = 0;
   1292 		    return;
   1293 
   1294 		  case 'n':
   1295 		    ip->GL = ip->G2;
   1296 		    ip->escape = 0;
   1297 		    return;
   1298 
   1299 		  case '}':
   1300 		    ip->GR = ip->G2;
   1301 		    ip->escape = 0;
   1302 		    return;
   1303 
   1304 		  case 'o':
   1305 		    ip->GL = ip->G3;
   1306 		    ip->escape = 0;
   1307 		    return;
   1308 
   1309 		  case '|':
   1310 		    ip->GR = ip->G3;
   1311 		    ip->escape = 0;
   1312 		    return;
   1313 
   1314 
   1315 		  /* font width/height control */
   1316 		  case '#':
   1317 		    ip->escape = '#';
   1318 		    return;
   1319 
   1320 
   1321 		  /* hard terminal reset .. */
   1322 		  case 'c':
   1323 		    ite_reset (ip);
   1324 		    (*itesw[ip->type].ite_cursor)(ip, MOVE_CURSOR);
   1325 		    ip->escape = 0;
   1326 		    return;
   1327 
   1328 
   1329 		  case '7':
   1330 		    ip->save_curx = ip->curx;
   1331 		    ip->save_cury = ip->cury;
   1332 		    ip->save_attribute = ip->attribute;
   1333 		    ip->escape = 0;
   1334 		    return;
   1335 
   1336 		  case '8':
   1337 		    ip->curx = ip->save_curx;
   1338 		    ip->cury = ip->save_cury;
   1339 		    ip->attribute = ip->save_attribute;
   1340 		    (*sp->ite_cursor)(ip, MOVE_CURSOR);
   1341 		    ip->escape = 0;
   1342 		    return;
   1343 
   1344 		  case '=':
   1345 		    ip->keypad_appmode = 1;
   1346 		    ip->escape = 0;
   1347 		    return;
   1348 
   1349 		  case '>':
   1350 		    ip->keypad_appmode = 0;
   1351 		    ip->escape = 0;
   1352 		    return;
   1353 
   1354 		  case 'Z':	/* request ID */
   1355 		    if (ip->emul_level == EMUL_VT100)
   1356 		      ite_sendstr (ip, "\033[61;0c");
   1357 		    else
   1358 		      ite_sendstr (ip, "\033[63;0c");
   1359 		    ip->escape = 0;
   1360 		    return;
   1361 
   1362 		  /* default catch all for not recognized ESC sequences */
   1363 		  default:
   1364 		    ip->escape = 0;
   1365 		    return;
   1366 		  }
   1367 		break;
   1368 
   1369 
   1370 	      case '(':
   1371 	      case ')':
   1372 		ip->escape = 0;
   1373 		return;
   1374 
   1375 
   1376 	      case ' ':
   1377 	        switch (c)
   1378 	          {
   1379 	          case 'F':
   1380 		    ip->eightbit_C1 = 0;
   1381 		    ip->escape = 0;
   1382 		    return;
   1383 
   1384 		  case 'G':
   1385 		    ip->eightbit_C1 = 1;
   1386 		    ip->escape = 0;
   1387 		    return;
   1388 
   1389 		  default:
   1390 		    /* not supported */
   1391 		    ip->escape = 0;
   1392 		    return;
   1393 		  }
   1394 		break;
   1395 
   1396 
   1397 	      case '#':
   1398 		switch (c)
   1399 		  {
   1400 		  case '5':
   1401 		    /* single height, single width */
   1402 		    ip->escape = 0;
   1403 		    return;
   1404 
   1405 		  case '6':
   1406 		    /* double width, single height */
   1407 		    ip->escape = 0;
   1408 		    return;
   1409 
   1410 		  case '3':
   1411 		    /* top half */
   1412 		    ip->escape = 0;
   1413 		    return;
   1414 
   1415 		  case '4':
   1416 		    /* bottom half */
   1417 		    ip->escape = 0;
   1418 		    return;
   1419 
   1420 		  case '8':
   1421 		    /* screen alignment pattern... */
   1422 		    ip->escape = 0;
   1423 		    return;
   1424 
   1425 		  default:
   1426 		    ip->escape = 0;
   1427 		    return;
   1428 		  }
   1429 		break;
   1430 
   1431 
   1432 
   1433 	      case CSI:
   1434 	        /* the biggie... */
   1435 	        switch (c)
   1436 	          {
   1437 	          case '0': case '1': case '2': case '3': case '4':
   1438 	          case '5': case '6': case '7': case '8': case '9':
   1439 	          case ';': case '\"': case '$': case '>':
   1440 	            if (ip->ap < ip->argbuf + ARGBUF_SIZE)
   1441 	              *ip->ap++ = c;
   1442 	            return;
   1443 
   1444 	          case 'p':
   1445 		    *ip->ap = 0;
   1446 	            if (! strncmp (ip->argbuf, "61\"", 3))
   1447 	              ip->emul_level = EMUL_VT100;
   1448 	            else if (! strncmp (ip->argbuf, "63;1\"", 5)
   1449 	            	     || ! strncmp (ip->argbuf, "62;1\"", 5))
   1450 	              ip->emul_level = EMUL_VT300_7;
   1451 	            else
   1452 	              ip->emul_level = EMUL_VT300_8;
   1453 	            ip->escape = 0;
   1454 	            return;
   1455 
   1456 
   1457 	          case '?':
   1458 		    *ip->ap = 0;
   1459 	            ip->escape = '?';
   1460 	            ip->ap = ip->argbuf;
   1461 	            return;
   1462 
   1463 
   1464 		  case 'c':
   1465   		    *ip->ap = 0;
   1466 		    if (ip->argbuf[0] == '>')
   1467 		      {
   1468 		        ite_sendstr (ip, "\033[>24;0;0;0c");
   1469 		      }
   1470 		    else switch (ite_zargnum(ip))
   1471 		      {
   1472 		      case 0:
   1473 			/* primary DA request, send primary DA response */
   1474 			if (ip->emul_level == EMUL_VT100)
   1475 		          ite_sendstr (ip, "\033[?1;1c");
   1476 		        else
   1477 		          ite_sendstr (ip, "\033[63;0c");
   1478 			break;
   1479 		      }
   1480 		    ip->escape = 0;
   1481 		    return;
   1482 
   1483 		  case 'n':
   1484 		    switch (ite_zargnum(ip))
   1485 		      {
   1486 		      case 5:
   1487 		        ite_sendstr (ip, "\033[0n");	/* no malfunction */
   1488 			break;
   1489 		      case 6:
   1490 			/* cursor position report */
   1491 		        sprintf (ip->argbuf, "\033[%d;%dR",
   1492 				 ip->cury + 1, ip->curx + 1);
   1493 			ite_sendstr (ip, ip->argbuf);
   1494 			break;
   1495 		      }
   1496 		    ip->escape = 0;
   1497 		    return;
   1498 
   1499 
   1500 		  case 'x':
   1501 		    switch (ite_zargnum(ip))
   1502 		      {
   1503 		      case 0:
   1504 			/* Fake some terminal parameters.  */
   1505 		        ite_sendstr (ip, "\033[2;1;1;112;112;1;0x");
   1506 			break;
   1507 		      case 1:
   1508 		        ite_sendstr (ip, "\033[3;1;1;112;112;1;0x");
   1509 			break;
   1510 		      }
   1511 		    ip->escape = 0;
   1512 		    return;
   1513 
   1514 
   1515 		  case 'g':
   1516 		    switch (ite_zargnum(ip))
   1517 		      {
   1518 		      case 0:
   1519 			if (ip->curx < ip->cols)
   1520 			  ip->tabs[ip->curx] = 0;
   1521 			break;
   1522 		      case 3:
   1523 		        for (n = 0; n < ip->cols; n++)
   1524 		          ip->tabs[n] = 0;
   1525 			break;
   1526 		      }
   1527 		    ip->escape = 0;
   1528 		    return;
   1529 
   1530 
   1531   	          case 'h': case 'l':
   1532 		    n = ite_zargnum (ip);
   1533 		    switch (n)
   1534 		      {
   1535 		      case 4:
   1536 		        ip->imode = (c == 'h');	/* insert/replace mode */
   1537 			break;
   1538 		      case 20:
   1539 			ip->linefeed_newline = (c == 'h');
   1540 			break;
   1541 		      }
   1542 		    ip->escape = 0;
   1543 		    return;
   1544 
   1545 
   1546 		  case 'M':
   1547 		    ite_dnline (ip, sp, ite_argnum (ip));
   1548 	            ip->escape = 0;
   1549 	            return;
   1550 
   1551 
   1552 		  case 'L':
   1553 		    ite_inline (ip, sp, ite_argnum (ip));
   1554 	            ip->escape = 0;
   1555 	            return;
   1556 
   1557 
   1558 		  case 'P':
   1559 		    ite_dnchar (ip, sp, ite_argnum (ip));
   1560 	            ip->escape = 0;
   1561 	            return;
   1562 
   1563 
   1564 		  case '@':
   1565 		    ite_inchar (ip, sp, ite_argnum (ip));
   1566 	            ip->escape = 0;
   1567 	            return;
   1568 
   1569 
   1570 		  case 'H':
   1571 		  case 'f':
   1572 		    *ip->ap = 0;
   1573 		    y = atoi (ip->argbuf);
   1574 		    x = 0;
   1575 		    cp = index (ip->argbuf, ';');
   1576 		    if (cp)
   1577 		      x = atoi (cp + 1);
   1578 		    if (x) x--;
   1579 		    if (y) y--;
   1580 		    ip->cury = MIN(y, ip->rows - 1);
   1581 		    ip->curx = MIN(x, ip->cols - 1);
   1582 		    ip->escape = 0;
   1583 		    snap_cury(ip, sp);
   1584 		    (*sp->ite_cursor)(ip, MOVE_CURSOR);
   1585 		    clr_attr (ip, ATTR_INV);
   1586 		    return;
   1587 
   1588 		  case 'A':
   1589 		    n = ip->cury - ite_argnum (ip);
   1590 		    if (n < 0) n = 0;
   1591 		    ip->cury = MAX(n, ip->inside_margins ? ip->top_margin : 0);
   1592 		    ip->escape = 0;
   1593 		    (*sp->ite_cursor)(ip, MOVE_CURSOR);
   1594 		    clr_attr (ip, ATTR_INV);
   1595 		    return;
   1596 
   1597 		  case 'B':
   1598 		    n = ite_argnum (ip) + ip->cury;
   1599 		    ip->cury = MIN(n, ip->inside_margins ? ip->bottom_margin : ip->rows - 1);
   1600 		    ip->escape = 0;
   1601 		    (*sp->ite_cursor)(ip, MOVE_CURSOR);
   1602 		    clr_attr (ip, ATTR_INV);
   1603 		    return;
   1604 
   1605 		  case 'C':
   1606 		    n = ite_argnum (ip);
   1607 		    ip->curx = MIN(ip->curx + n, ip->cols - 1);
   1608 		    ip->escape = 0;
   1609 		    (*sp->ite_cursor)(ip, MOVE_CURSOR);
   1610 		    clr_attr (ip, ATTR_INV);
   1611 		    return;
   1612 
   1613 		  case 'D':
   1614 		    n = ite_argnum (ip);
   1615 		    n = ip->curx - n;
   1616 		    ip->curx = n >= 0 ? n : 0;
   1617 		    ip->escape = 0;
   1618 		    (*sp->ite_cursor)(ip, MOVE_CURSOR);
   1619 		    clr_attr (ip, ATTR_INV);
   1620 		    return;
   1621 
   1622 
   1623 
   1624 
   1625 		  case 'J':
   1626 		    *ip->ap = 0;
   1627 		    n = ite_zargnum (ip);
   1628 		    if (n == 0)
   1629 	              ite_clrtoeos(ip, sp);
   1630 		    else if (n == 1)
   1631 		      ite_clrtobos(ip, sp);
   1632 		    else if (n == 2)
   1633 		      ite_clrscreen(ip, sp);
   1634 	            ip->escape = 0;
   1635 	            return;
   1636 
   1637 
   1638 		  case 'K':
   1639 		    n = ite_zargnum (ip);
   1640 		    if (n == 0)
   1641 		      ite_clrtoeol(ip, sp);
   1642 		    else if (n == 1)
   1643 		      ite_clrtobol(ip, sp);
   1644 		    else if (n == 2)
   1645 		      ite_clrline(ip, sp);
   1646 		    ip->escape = 0;
   1647 		    return;
   1648 
   1649 
   1650 		  case 'X':
   1651 		    n = ite_argnum(ip) - 1;
   1652 		    n = MIN(n, ip->cols - 1 - ip->curx);
   1653 		    for (; n >= 0; n--)
   1654 		      {
   1655 			attrclr(ip, ip->cury, ip->curx + n, 1, 1);
   1656 			(*sp->ite_putc)(ip, ' ', ip->cury, ip->curx + n, ATTR_NOR);
   1657 		      }
   1658 		    ip->escape = 0;
   1659 		    return;
   1660 
   1661 
   1662 	          case '}': case '`':
   1663 	            /* status line control */
   1664 	            ip->escape = 0;
   1665 	            return;
   1666 
   1667 
   1668 		  case 'r':
   1669 		    *ip->ap = 0;
   1670 		    x = atoi (ip->argbuf);
   1671 		    y = 0;
   1672 		    cp = index (ip->argbuf, ';');
   1673 		    if (cp)
   1674 		      y = atoi (cp + 1);
   1675 		    if ((x > 0) || (y > 1))
   1676 		      {
   1677 		        if (x) x--;
   1678 		        if (y) y--;
   1679 		        ip->top_margin = MIN(x, ip->rows - 1);
   1680 		        ip->bottom_margin = MIN(y, ip->rows - 1);
   1681 			if (ip->bottom_margin < ip->top_margin)
   1682 			  ip->bottom_margin = ip->top_margin;
   1683 		      }
   1684 		    else
   1685 		      {
   1686 			ip->top_margin = 0;
   1687 			ip->bottom_margin = ip->rows - 1;
   1688 		      }
   1689 		    ip->cury = ip->top_margin;
   1690 		    ip->curx = 0;
   1691 		    (*sp->ite_cursor)(ip, MOVE_CURSOR);
   1692 		    ip->escape = 0;
   1693 		    return;
   1694 
   1695 
   1696 		  case 'm':
   1697 		    /* big attribute setter/resetter */
   1698 		    {
   1699 		      char *cp;
   1700 		      *ip->ap = 0;
   1701 		      /* kludge to make CSIm work (== CSI0m) */
   1702 		      if (ip->ap == ip->argbuf)
   1703 		        ip->ap++;
   1704 		      for (cp = ip->argbuf; cp < ip->ap; )
   1705 		        {
   1706 			  switch (*cp)
   1707 			    {
   1708 			    case 0:
   1709 			    case '0':
   1710 			      clr_attr (ip, ATTR_ALL);
   1711 			      cp++;
   1712 			      break;
   1713 
   1714 			    case '1':
   1715 			      set_attr (ip, ATTR_BOLD);
   1716 			      cp++;
   1717 			      break;
   1718 
   1719 			    case '2':
   1720 			      switch (cp[1])
   1721 			        {
   1722 			        case '2':
   1723 			          clr_attr (ip, ATTR_BOLD);
   1724 			          cp += 2;
   1725 			          break;
   1726 
   1727 			        case '4':
   1728 			          clr_attr (ip, ATTR_UL);
   1729 			          cp += 2;
   1730 			          break;
   1731 
   1732 			        case '5':
   1733 			          clr_attr (ip, ATTR_BLINK);
   1734 			          cp += 2;
   1735 			          break;
   1736 
   1737 			        case '7':
   1738 			          clr_attr (ip, ATTR_INV);
   1739 			          cp += 2;
   1740 			          break;
   1741 
   1742 		        	default:
   1743 		        	  cp++;
   1744 		        	  break;
   1745 		        	}
   1746 			      break;
   1747 
   1748 			    case '4':
   1749 			      set_attr (ip, ATTR_UL);
   1750 			      cp++;
   1751 			      break;
   1752 
   1753 			    case '5':
   1754 			      set_attr (ip, ATTR_BLINK);
   1755 			      cp++;
   1756 			      break;
   1757 
   1758 			    case '7':
   1759 			      set_attr (ip, ATTR_INV);
   1760 			      cp++;
   1761 			      break;
   1762 
   1763 			    default:
   1764 			      cp++;
   1765 			      break;
   1766 			    }
   1767 		        }
   1768 
   1769 		    }
   1770 		    ip->escape = 0;
   1771 		    return;
   1772 
   1773 
   1774 		  case 'u':
   1775 		    /* DECRQTSR */
   1776 		    ite_sendstr (ip, "\033P\033\\");
   1777 		    ip->escape = 0;
   1778 		    return;
   1779 
   1780 
   1781 
   1782 		  default:
   1783 		    ip->escape = 0;
   1784 		    return;
   1785 		  }
   1786 		break;
   1787 
   1788 
   1789 
   1790 	      case '?':	/* CSI ? */
   1791 	      	switch (c)
   1792 	      	  {
   1793 	          case '0': case '1': case '2': case '3': case '4':
   1794 	          case '5': case '6': case '7': case '8': case '9':
   1795 	          case ';': case '\"': case '$':
   1796 		    /* Don't fill the last character; it's needed.  */
   1797 		    /* XXX yeah, where ?? */
   1798 	            if (ip->ap < ip->argbuf + ARGBUF_SIZE - 1)
   1799 	              *ip->ap++ = c;
   1800 	            return;
   1801 
   1802 
   1803 		  case 'n':
   1804 		    *ip->ap = 0;
   1805 		    if (ip->ap == &ip->argbuf[2])
   1806 		      {
   1807 		        if (! strncmp (ip->argbuf, "15", 2))
   1808 		          /* printer status: no printer */
   1809 		          ite_sendstr (ip, "\033[13n");
   1810 
   1811 		        else if (! strncmp (ip->argbuf, "25", 2))
   1812 		          /* udk status */
   1813 		          ite_sendstr (ip, "\033[20n");
   1814 
   1815 		        else if (! strncmp (ip->argbuf, "26", 2))
   1816 		          /* keyboard dialect: US */
   1817 		          ite_sendstr (ip, "\033[27;1n");
   1818 		      }
   1819 		    ip->escape = 0;
   1820 		    return;
   1821 
   1822 
   1823   		  case 'h': case 'l':
   1824 		    n = ite_zargnum (ip);
   1825 		    switch (n)
   1826 		      {
   1827 		      case 1:
   1828 		        ip->cursor_appmode = (c == 'h');
   1829 		        break;
   1830 
   1831 		      case 3:
   1832 		        /* 132/80 columns (132 == 'h') */
   1833 		        break;
   1834 
   1835 		      case 4: /* smooth scroll */
   1836 			break;
   1837 
   1838 		      case 5:
   1839 		        /* light background (=='h') /dark background(=='l') */
   1840 		        break;
   1841 
   1842 		      case 6: /* origin mode */
   1843 			ip->inside_margins = (c == 'h');
   1844 			break;
   1845 
   1846 		      case 7: /* auto wraparound */
   1847 			ip->auto_wrap = (c == 'h');
   1848 			break;
   1849 
   1850 		      case 8: /* keyboard repeat */
   1851 			ip->key_repeat = (c == 'h');
   1852 			break;
   1853 
   1854 		      case 20: /* newline mode */
   1855 			ip->linefeed_newline = (c == 'h');
   1856 			break;
   1857 
   1858 		      case 25: /* cursor on/off */
   1859 			(*itesw[ip->type].ite_cursor)(ip, (c == 'h') ? DRAW_CURSOR : ERASE_CURSOR);
   1860 			break;
   1861 		      }
   1862 		    ip->escape = 0;
   1863 		    return;
   1864 
   1865 		  default:
   1866 		    ip->escape = 0;
   1867 		    return;
   1868 		  }
   1869 		break;
   1870 
   1871 
   1872 	      default:
   1873 	        ip->escape = 0;
   1874 	        return;
   1875 	      }
   1876           }
   1877 
   1878 
   1879 	switch (c) {
   1880 
   1881 	case VT:	/* VT is treated like LF */
   1882 	case FF:	/* so is FF */
   1883 	case LF:
   1884 		/* cr->crlf distinction is done here, on output,
   1885 		   not on input! */
   1886 		if (ip->linefeed_newline)
   1887 		  ite_crlf (ip, sp);
   1888 		else
   1889 		  ite_lf (ip, sp);
   1890 		break;
   1891 
   1892 	case CR:
   1893 		ite_cr (ip, sp);
   1894 		break;
   1895 
   1896 	case BS:
   1897 		if (--ip->curx < 0)
   1898 			ip->curx = 0;
   1899 		else
   1900 			(*sp->ite_cursor)(ip, MOVE_CURSOR);
   1901 		break;
   1902 
   1903 	case HT:
   1904 		for (n = ip->curx + 1; n < ip->cols; n++) {
   1905 			if (ip->tabs[n]) {
   1906 				ip->curx = n;
   1907 				(*sp->ite_cursor)(ip, MOVE_CURSOR);
   1908 				break;
   1909 			}
   1910 		}
   1911 		break;
   1912 
   1913 	case BEL:
   1914 		if (kbd_tty && ite_tty[unit] == kbd_tty)
   1915 			kbdbell();
   1916 		break;
   1917 
   1918 	case SO:
   1919 		ip->GL = ip->G1;
   1920 		break;
   1921 
   1922 	case SI:
   1923 		ip->GL = ip->G0;
   1924 		break;
   1925 
   1926 	case ENQ:
   1927 		/* send answer-back message !! */
   1928 		break;
   1929 
   1930 	case CAN:
   1931 		ip->escape = 0;	/* cancel any escape sequence in progress */
   1932 		break;
   1933 
   1934 	case SUB:
   1935 		ip->escape = 0;	/* dito, but see below */
   1936 		/* should also display a reverse question mark!! */
   1937 		break;
   1938 
   1939 	case ESC:
   1940 		ip->escape = ESC;
   1941 		break;
   1942 
   1943 
   1944 	/* now it gets weird.. 8bit control sequences.. */
   1945 	case IND:	/* index: move cursor down, scroll */
   1946 		ite_lf (ip, sp);
   1947 		break;
   1948 
   1949 	case NEL:	/* next line. next line, first pos. */
   1950 		ite_crlf (ip, sp);
   1951 		break;
   1952 
   1953 	case HTS:	/* set horizontal tab */
   1954 		if (ip->curx < ip->cols)
   1955 		  ip->tabs[ip->curx] = 1;
   1956 		break;
   1957 
   1958 	case RI:	/* reverse index */
   1959 		ite_rlf (ip, sp);
   1960 		break;
   1961 
   1962 	case SS2:	/* go into G2 for one character */
   1963 		/* not yet supported */
   1964 		break;
   1965 
   1966 	case SS3:	/* go into G3 for one character */
   1967 		break;
   1968 
   1969 	case DCS:	/* device control string introducer */
   1970 		ip->escape = DCS;
   1971 		ip->ap = ip->argbuf;
   1972 		break;
   1973 
   1974 	case CSI:	/* control sequence introducer */
   1975 		ip->escape = CSI;
   1976 		ip->ap = ip->argbuf;
   1977 		break;
   1978 
   1979 	case ST:	/* string terminator */
   1980 		/* ignore, if not used as terminator */
   1981 		break;
   1982 
   1983 	case OSC:	/* introduces OS command. Ignore everything upto ST */
   1984 		ip->escape = OSC;
   1985 		break;
   1986 
   1987 	case PM:	/* privacy message, ignore everything upto ST */
   1988 		ip->escape = PM;
   1989 		break;
   1990 
   1991 	case APC:	/* application program command, ignore everything upto ST */
   1992 		ip->escape = APC;
   1993 		break;
   1994 
   1995 	default:
   1996 		if (c < ' ' || c == DEL)
   1997 			break;
   1998 		if (ip->imode)
   1999 			ite_inchar(ip, sp, 1);
   2000 		iteprecheckwrap(ip, sp);
   2001 #ifdef DO_WEIRD_ATTRIBUTES
   2002 		if ((ip->attribute & ATTR_INV) || attrtest(ip, ATTR_INV)) {
   2003 			attrset(ip, ATTR_INV);
   2004 			(*sp->ite_putc)(ip, c, ip->cury, ip->curx, ATTR_INV);
   2005 		}
   2006 		else
   2007 			(*sp->ite_putc)(ip, c, ip->cury, ip->curx, ATTR_NOR);
   2008 #else
   2009 		(*sp->ite_putc)(ip, c, ip->cury, ip->curx, ip->attribute);
   2010 #endif
   2011 		(*sp->ite_cursor)(ip, DRAW_CURSOR);
   2012 		itecheckwrap(ip, sp);
   2013 		break;
   2014 	}
   2015 }
   2016 
   2017 iteprecheckwrap(ip, sp)
   2018      register struct ite_softc *ip;
   2019      register struct itesw *sp;
   2020 {
   2021 	if (ip->auto_wrap && ip->curx == ip->cols) {
   2022 		ip->curx = 0;
   2023 		clr_attr(ip, ATTR_INV);
   2024 		if (++ip->cury >= ip->bottom_margin + 1) {
   2025 			ip->cury = ip->bottom_margin;
   2026 			(*sp->ite_cursor)(ip, MOVE_CURSOR);
   2027 			(*sp->ite_scroll)(ip, ip->top_margin + 1, 0, 1, SCROLL_UP);
   2028 			ite_clrtoeol(ip, sp);
   2029 		} else
   2030 			(*sp->ite_cursor)(ip, MOVE_CURSOR);
   2031 	}
   2032 }
   2033 
   2034 itecheckwrap(ip, sp)
   2035      register struct ite_softc *ip;
   2036      register struct itesw *sp;
   2037 {
   2038 #if 0
   2039 	if (++ip->curx == ip->cols) {
   2040 		if (ip->auto_wrap) {
   2041 			ip->curx = 0;
   2042 			clr_attr(ip, ATTR_INV);
   2043 			if (++ip->cury >= ip->bottom_margin + 1) {
   2044 				ip->cury = ip->bottom_margin;
   2045 				(*sp->ite_cursor)(ip, MOVE_CURSOR);
   2046 				(*sp->ite_scroll)(ip, ip->top_margin + 1, 0, 1, SCROLL_UP);
   2047 				ite_clrtoeol(ip, sp);
   2048 				return;
   2049 			}
   2050 		} else
   2051 			/* stay there if no autowrap.. */
   2052 			ip->curx--;
   2053 	}
   2054 #else
   2055 	if (ip->curx < ip->cols) {
   2056 		ip->curx++;
   2057 		(*sp->ite_cursor)(ip, MOVE_CURSOR);
   2058 	}
   2059 #endif
   2060 }
   2061 
   2062 /*
   2063  * Console functions
   2064  */
   2065 #include "grfioctl.h"
   2066 #include "grfvar.h"
   2067 
   2068 #ifdef DEBUG
   2069 /*
   2070  * Minimum ITE number at which to start looking for a console.
   2071  * Setting to 0 will do normal search, 1 will skip first ITE device,
   2072  * NITE will skip ITEs and use serial port.
   2073  */
   2074 int	whichconsole = 0;
   2075 #endif
   2076 
   2077 itecnprobe(cp)
   2078 	struct consdev *cp;
   2079 {
   2080 	register struct ite_softc *ip;
   2081 	int i, maj, unit, pri;
   2082 
   2083 	/* locate the major number */
   2084 	for (maj = 0; maj < nchrdev; maj++)
   2085 		if (cdevsw[maj].d_open == iteopen)
   2086 			break;
   2087 
   2088 	/* urk! */
   2089 	grfconfig();
   2090 
   2091 	/* check all the individual displays and find the best */
   2092 	unit = -1;
   2093 	pri = CN_DEAD;
   2094 	for (i = 0; i < NITE; i++) {
   2095 		struct grf_softc *gp = &grf_softc[i];
   2096 
   2097 		ip = &ite_softc[i];
   2098 		if ((gp->g_flags & GF_ALIVE) == 0)
   2099 			continue;
   2100 		ip->flags = (ITE_ALIVE|ITE_CONSOLE);
   2101 
   2102 		/* XXX - we need to do something about mapping these */
   2103 		switch (gp->g_type) {
   2104 		case GT_CUSTOMCHIPS:
   2105 		        ip->type = ITE_CUSTOMCHIPS;
   2106 		        break;
   2107 
   2108 		case GT_TIGA_A2410:
   2109 		        ip->type = ITE_TIGA_A2410;
   2110 		        break;
   2111 
   2112 		case GT_RETINA:
   2113 			ip->type = ITE_RETINA;
   2114 			break;
   2115 		}
   2116 #ifdef DEBUG
   2117 		if (i < whichconsole)
   2118 			continue;
   2119 #endif
   2120 		if ((int)gp->g_type == GT_CUSTOMCHIPS) {
   2121 			pri = CN_INTERNAL;
   2122 			unit = i;
   2123 		} else /* if (unit < 0) */ {
   2124 			pri = CN_NORMAL;
   2125 			unit = i;
   2126 		}
   2127 
   2128 	}
   2129 
   2130 	/* initialize required fields */
   2131 	cp->cn_dev = makedev(maj, unit);
   2132 #if 0
   2133 	cp->cn_tp = ite_tty[unit];
   2134 #else
   2135 	delayed_con_tty = unit;
   2136 #endif
   2137 	cp->cn_pri = pri;
   2138 }
   2139 
   2140 itecninit(cp)
   2141 	struct consdev *cp;
   2142 {
   2143 	int unit;
   2144 	struct ite_softc *ip;
   2145 
   2146 	iteinit(cp->cn_dev);
   2147 	unit = UNIT(cp->cn_dev);
   2148 	ip = &ite_softc[unit];
   2149 
   2150 #ifdef DO_WEIRD_ATTRIBUTES
   2151 	ip->attrbuf = console_attributes;
   2152 #endif
   2153 	ip->flags |= (ITE_ACTIVE|ITE_ISCONS);
   2154 	/* if this is the console, NEVER close the device! */
   2155 	ip->open_cnt++;
   2156 #if 0
   2157 	/* have to delay this too.. sigh.. */
   2158 	kbd_tty = ite_tty[unit];
   2159 	kbd_ip = ip;
   2160 	kbdenable();
   2161 #endif
   2162 }
   2163 
   2164 /*ARGSUSED*/
   2165 itecngetc(dev)
   2166 	dev_t dev;
   2167 {
   2168 	register int c;
   2169 
   2170         do
   2171           {
   2172             c = kbdgetcn ();
   2173             c = itefilter (c, ITEFILT_CONSOLE);
   2174           }
   2175         while (c == -1);
   2176 
   2177 	return(c);
   2178 }
   2179 
   2180 itecnputc(dev, c)
   2181 	dev_t dev;
   2182 	int c;
   2183 {
   2184 	static int paniced = 0;
   2185 	struct ite_softc *ip = &ite_softc[UNIT(dev)];
   2186 
   2187 	if (panicstr && !paniced &&
   2188 	    (ip->flags & (ITE_ACTIVE|ITE_INGRF)) != ITE_ACTIVE) {
   2189 		(void) iteon(dev, 3);
   2190 		paniced = 1;
   2191 	}
   2192 	iteputchar(c, dev);
   2193 }
   2194 #endif
   2195