1 /* $NetBSD: ite.c,v 1.56 2009/01/17 09:20:46 isaki Exp $ */
4 * Copyright (c) 1990 The Regents of the University of California.
7 * This code is derived from software contributed to Berkeley by
8 * the Systems Programming Group of the University of Utah Computer
11 * Redistribution and use in source and binary forms, with or without
12 * modification, are permitted provided that the following conditions
14 * 1. Redistributions of source code must retain the above copyright
15 * notice, this list of conditions and the following disclaimer.
16 * 2. Redistributions in binary form must reproduce the above copyright
17 * notice, this list of conditions and the following disclaimer in the
18 * documentation and/or other materials provided with the distribution.
19 * 3. Neither the name of the University nor the names of its contributors
20 * may be used to endorse or promote products derived from this software
21 * without specific prior written permission.
23 * THIS SOFTWARE IS PROVIDED BY THE REGENTS AND CONTRIBUTORS ``AS IS'' AND
24 * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
25 * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
26 * ARE DISCLAIMED. IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE
27 * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
28 * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
29 * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
30 * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
31 * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
32 * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
35 * from: Utah $Hdr: ite.c 1.1 90/07/09$
37 * @(#)ite.c 7.6 (Berkeley) 5/16/91
40 * Copyright (c) 1988 University of Utah.
42 * This code is derived from software contributed to Berkeley by
43 * the Systems Programming Group of the University of Utah Computer
46 * Redistribution and use in source and binary forms, with or without
47 * modification, are permitted provided that the following conditions
49 * 1. Redistributions of source code must retain the above copyright
50 * notice, this list of conditions and the following disclaimer.
51 * 2. Redistributions in binary form must reproduce the above copyright
52 * notice, this list of conditions and the following disclaimer in the
53 * documentation and/or other materials provided with the distribution.
54 * 3. All advertising materials mentioning features or use of this software
55 * must display the following acknowledgement:
56 * This product includes software developed by the University of
57 * California, Berkeley and its contributors.
58 * 4. Neither the name of the University nor the names of its contributors
59 * may be used to endorse or promote products derived from this software
60 * without specific prior written permission.
62 * THIS SOFTWARE IS PROVIDED BY THE REGENTS AND CONTRIBUTORS ``AS IS'' AND
63 * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
64 * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
65 * ARE DISCLAIMED. IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE
66 * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
67 * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
68 * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
69 * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
70 * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
71 * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
74 * from: Utah $Hdr: ite.c 1.1 90/07/09$
76 * @(#)ite.c 7.6 (Berkeley) 5/16/91
80 * ite - bitmaped terminal.
81 * Supports VT200, a few terminal features will be unavailable until
82 * the system actually probes the device (i.e. not after consinit())
85 #include <sys/cdefs.h>
86 __KERNEL_RCSID(0, "$NetBSD: ite.c,v 1.56 2009/01/17 09:20:46 isaki Exp $");
96 #include <sys/param.h>
99 #include <sys/ioctl.h>
101 #include <sys/systm.h>
102 #include <sys/device.h>
103 #include <sys/malloc.h>
104 #include <sys/kauth.h>
106 #include <machine/cpu.h>
107 #include <machine/kbio.h>
108 #include <machine/bus.h>
109 #include <machine/autoconf.h>
110 #include <machine/grfioctl.h>
111 #include <machine/iteioctl.h>
113 #include <arch/x68k/dev/grfvar.h>
114 #include <arch/x68k/dev/itevar.h>
115 #include <arch/x68k/dev/kbdmap.h>
116 #include <arch/x68k/dev/mfp.h>
121 #define SUBR_INIT(ip) ip->isw->ite_init(ip)
122 #define SUBR_DEINIT(ip) ip->isw->ite_deinit(ip)
123 #define SUBR_PUTC(ip,c,dy,dx,m) ip->isw->ite_putc(ip,c,dy,dx,m)
124 #define SUBR_CURSOR(ip,flg) ip->isw->ite_cursor(ip,flg)
125 #define SUBR_CLEAR(ip,sy,sx,h,w) ip->isw->ite_clear(ip,sy,sx,h,w)
126 #define SUBR_SCROLL(ip,sy,sx,count,dir) \
127 ip->isw->ite_scroll(ip,sy,sx,count,dir)
131 inline static void itesendch(int);
132 inline static void alignment_display(struct ite_softc
*);
133 inline static void snap_cury(struct ite_softc
*);
134 inline static void ite_dnchar(struct ite_softc
*, int);
135 static void ite_inchar(struct ite_softc
*, int);
136 inline static void ite_clrtoeol(struct ite_softc
*);
137 inline static void ite_clrtobol(struct ite_softc
*);
138 inline static void ite_clrline(struct ite_softc
*);
139 inline static void ite_clrtoeos(struct ite_softc
*);
140 inline static void ite_clrtobos(struct ite_softc
*);
141 inline static void ite_clrscreen(struct ite_softc
*);
142 inline static void ite_dnline(struct ite_softc
*, int);
143 inline static void ite_inline(struct ite_softc
*, int);
144 inline static void ite_index(struct ite_softc
*);
145 inline static void ite_lf(struct ite_softc
*);
146 inline static void ite_crlf(struct ite_softc
*);
147 inline static void ite_cr(struct ite_softc
*);
148 inline static void ite_rlf(struct ite_softc
*);
149 static void iteprecheckwrap(struct ite_softc
*);
150 static void itecheckwrap(struct ite_softc
*);
151 static int ite_argnum(struct ite_softc
*);
152 static int ite_zargnum(struct ite_softc
*);
153 static void ite_sendstr(struct ite_softc
*, const char *);
154 inline static int atoi(const char *);
155 void ite_reset(struct ite_softc
*);
156 struct ite_softc
*getitesp(dev_t
);
157 int iteon(dev_t
, int);
158 void iteoff(dev_t
, int);
160 struct itesw itesw
[] = {
161 {0, tv_init
, tv_deinit
, 0,
166 * # of chars are output in a single itestart() call.
167 * If this is too big, user processes will be blocked out for
168 * long periods of time while we are emptying the queue in itestart().
169 * If it is too small, console output will be very ragged.
173 struct tty
*ite_tty
[NITE
];
174 struct ite_softc
*kbd_ite
= NULL
;
175 struct ite_softc con_itesoftc
;
177 struct tty
*kbd_tty
= NULL
;
179 int start_repeat_timeo
= 20; /* /100: initial timeout till pressed key repeats */
180 int next_repeat_timeo
= 3; /* /100: timeout when repeating for next char */
182 u_char cons_tabs
[MAX_TABS
];
184 void itestart(struct tty
*);
186 void iteputchar(int, struct ite_softc
*);
187 void ite_putstr(const u_char
*, int, dev_t
);
189 int itematch(device_t
, cfdata_t
, void *);
190 void iteattach(device_t
, device_t
, void *);
192 CFATTACH_DECL_NEW(ite
, sizeof(struct ite_softc
),
193 itematch
, iteattach
, NULL
, NULL
);
195 extern struct cfdriver ite_cd
;
197 dev_type_open(iteopen
);
198 dev_type_close(iteclose
);
199 dev_type_read(iteread
);
200 dev_type_write(itewrite
);
201 dev_type_ioctl(iteioctl
);
202 dev_type_tty(itetty
);
203 dev_type_poll(itepoll
);
205 const struct cdevsw ite_cdevsw
= {
206 iteopen
, iteclose
, iteread
, itewrite
, iteioctl
,
207 nostop
, itetty
, itepoll
, nommap
, ttykqfilter
, D_TTY
211 itematch(device_t pdp
, cfdata_t cdp
, void *auxp
)
213 struct grf_softc
*gp
;
216 if (cdp
->cf_loc
[GRFCF_GRFADDR
] != gp
->g_cfaddr
)
223 * iteinit() is the standard entry point for initialization of
224 * an ite device, it is also called from ite_cninit().
227 iteattach(device_t pdp
, device_t dp
, void *auxp
)
229 struct ite_softc
*ip
;
230 struct grf_softc
*gp
;
232 gp
= (struct grf_softc
*)auxp
;
233 ip
= device_private(dp
);
234 if(con_itesoftc
.grf
!= NULL
235 /*&& con_itesoftc.grf->g_unit == gp->g_unit*/) {
237 * console reinit copy params over.
238 * and console always gets keyboard
240 memcpy(&ip
->grf
, &con_itesoftc
.grf
,
241 (char *)&ip
[1] - (char *)&ip
->grf
);
242 con_itesoftc
.grf
= NULL
;
246 iteinit(device_unit(&ip
->device
)); /* XXX */
247 aprint_normal(": rows %d cols %d", ip
->rows
, ip
->cols
);
257 if (x68k_realconfig
&& con_itesoftc
.grf
== NULL
)
258 return device_lookup_private(&ite_cd
, UNIT(dev
));
260 if (con_itesoftc
.grf
== NULL
)
261 panic("no ite_softc for console");
262 return(&con_itesoftc
);
268 struct ite_softc
*ip
;
272 if (ip
->flags
& ITE_INITED
)
274 memcpy(&kbdmap
, &ascii_kbdmap
, sizeof(struct kbdmap
));
281 ip
->isw
= &itesw
[device_unit(&ip
->device
)]; /* XXX */
283 SUBR_CURSOR(ip
, DRAW_CURSOR
);
285 ip
->tabs
= malloc(MAX_TABS
*sizeof(u_char
), M_DEVBUF
, M_WAITOK
);
287 ip
->flags
|= ITE_INITED
;
291 ite_config_console(void)
293 struct grf_softc
*gp
= &congrf
;
295 if (con_itesoftc
.grf
!= NULL
)
297 con_itesoftc
.grf
= gp
;
298 con_itesoftc
.tabs
= cons_tabs
;
302 * Perform functions necessary to setup device as a terminal emulator.
305 iteon(dev_t dev
, int flag
)
307 int unit
= UNIT(dev
);
308 struct ite_softc
*ip
;
310 if (unit
< 0 || unit
>= ite_cd
.cd_ndevs
||
311 (ip
= getitesp(unit
)) == NULL
|| (ip
->flags
&ITE_ALIVE
) == 0)
313 /* force ite active, overriding graphics mode */
315 ip
->flags
|= ITE_ACTIVE
;
316 ip
->flags
&= ~(ITE_INGRF
|ITE_INITED
);
318 /* leave graphics mode */
320 ip
->flags
&= ~ITE_INGRF
;
321 if ((ip
->flags
& ITE_ACTIVE
) == 0)
324 ip
->flags
|= ITE_ACTIVE
;
325 if (ip
->flags
& ITE_INGRF
)
331 mfp_send_usart(0x49); /* XXX */
337 * "Shut down" device as terminal emulator.
338 * Note that we do not deinit the console device unless forced.
339 * Deinit'ing the console every time leads to a very active
340 * screen when processing /etc/rc.
343 iteoff(dev_t dev
, int flag
)
345 int unit
= UNIT(dev
);
346 struct ite_softc
*ip
;
348 /* XXX check whether when call from grf.c */
349 if (unit
< 0 || unit
>= ite_cd
.cd_ndevs
||
350 (ip
= getitesp(unit
)) == NULL
|| (ip
->flags
&ITE_ALIVE
) == 0)
353 ip
->flags
|= ITE_INGRF
;
355 if ((ip
->flags
& ITE_ACTIVE
) == 0)
358 (ip
->flags
& (ITE_INGRF
|ITE_ISCONS
|ITE_INITED
)) == ITE_INITED
)
362 * XXX When the system is rebooted with "reboot", init(8)
363 * kills the last process to have the console open.
364 * If we don't revent the ITE_ACTIVE bit from being
365 * cleared, we will never see messages printed during
366 * the process of rebooting.
368 if ((flag
& 2) == 0 && (ip
->flags
& ITE_ISCONS
) == 0) {
369 ip
->flags
&= ~ITE_ACTIVE
;
371 mfp_send_usart(0x48); /* XXX */
377 * standard entry points to the device.
382 iteopen(dev_t dev
, int mode
, int devtype
, struct lwp
*l
)
384 int unit
= UNIT(dev
);
386 struct ite_softc
*ip
;
390 if (unit
>= ite_cd
.cd_ndevs
|| (ip
= getitesp(dev
)) == NULL
)
392 if (!ite_tty
[unit
]) {
393 tp
= ite_tty
[unit
] = ttymalloc();
397 if (kauth_authorize_device_tty(l
->l_cred
, KAUTH_DEVICE_TTY_OPEN
, tp
))
399 if ((ip
->flags
& ITE_ACTIVE
) == 0) {
400 error
= iteon(dev
, 0);
405 tp
->t_oproc
= itestart
;
408 if ((tp
->t_state
&TS_ISOPEN
) == 0) {
410 tp
->t_iflag
= TTYDEF_IFLAG
;
411 tp
->t_oflag
= TTYDEF_OFLAG
;
412 tp
->t_cflag
= TTYDEF_CFLAG
;
413 tp
->t_lflag
= TTYDEF_LFLAG
;
414 tp
->t_ispeed
= tp
->t_ospeed
= TTYDEF_SPEED
;
415 tp
->t_state
= TS_ISOPEN
|TS_CARR_ON
;
418 error
= (*tp
->t_linesw
->l_open
)(dev
, tp
);
420 tp
->t_winsize
.ws_row
= ip
->rows
;
421 tp
->t_winsize
.ws_col
= ip
->cols
;
429 iteclose(dev_t dev
, int flag
, int mode
, struct lwp
*l
)
431 struct tty
*tp
= ite_tty
[UNIT(dev
)];
433 (*tp
->t_linesw
->l_close
)(tp
, flag
);
438 ite_tty
[UNIT(dev
)] = (struct tty
*)0;
444 iteread(dev_t dev
, struct uio
*uio
, int flag
)
446 struct tty
*tp
= ite_tty
[UNIT(dev
)];
448 return ((*tp
->t_linesw
->l_read
)(tp
, uio
, flag
));
452 itewrite(dev_t dev
, struct uio
*uio
, int flag
)
454 struct tty
*tp
= ite_tty
[UNIT(dev
)];
456 return ((*tp
->t_linesw
->l_write
)(tp
, uio
, flag
));
460 itepoll(dev_t dev
, int events
, struct lwp
*l
)
462 struct tty
*tp
= ite_tty
[UNIT(dev
)];
464 return ((*tp
->t_linesw
->l_poll
)(tp
, events
, l
));
471 return (ite_tty
[UNIT(dev
)]);
475 iteioctl(dev_t dev
, u_long cmd
, void *addr
, int flag
, struct lwp
*l
)
477 struct iterepeat
*irp
;
478 struct tty
*tp
= ite_tty
[UNIT(dev
)];
481 error
= (*tp
->t_linesw
->l_ioctl
)(tp
, cmd
, addr
, flag
, l
);
482 if (error
!= EPASSTHROUGH
)
485 error
= ttioctl(tp
, cmd
, addr
, flag
, l
);
486 if (error
!= EPASSTHROUGH
)
493 memcpy(&kbdmap
, addr
, sizeof(struct kbdmap
));
499 memcpy(addr
, &kbdmap
, sizeof(struct kbdmap
));
503 irp
= (struct iterepeat
*)addr
;
504 irp
->start
= start_repeat_timeo
;
505 irp
->next
= next_repeat_timeo
;
508 irp
= (struct iterepeat
*)addr
;
509 if (irp
->start
< ITEMINREPEAT
&& irp
->next
< ITEMINREPEAT
)
511 start_repeat_timeo
= irp
->start
;
512 next_repeat_timeo
= irp
->next
;
516 memcpy(kern_font
, addr
, 4096 /*sizeof(kernel_font)*/);
523 if (addr
&& *(u_int8_t
*)addr
< 0x40) {
524 return mfp_send_usart(* (u_int8_t
*)addr
);
530 return (EPASSTHROUGH
);
534 itestart(struct tty
*tp
)
537 struct ite_softc
*ip
;
538 u_char buf
[ITEBURST
];
541 ip
= getitesp(tp
->t_dev
);
543 * (Potentially) lower priority. We only need to protect ourselves
544 * from keyboard interrupts since that is all that can affect the
545 * state of our tty (kernel printf doesn't go through this routine).
548 if (tp
->t_state
& (TS_TIMEOUT
| TS_BUSY
| TS_TTSTOP
))
550 tp
->t_state
|= TS_BUSY
;
552 len
= q_to_b(rbp
, buf
, ITEBURST
);
555 /* Here is a really good place to implement pre/jumpscroll() */
556 ite_putstr(buf
, len
, tp
->t_dev
);
559 tp
->t_state
&= ~TS_BUSY
;
560 /* we have characters remaining. */
562 tp
->t_state
|= TS_TIMEOUT
;
563 callout_schedule(&tp
->t_rstrt_ch
, 1);
569 /* XXX called after changes made in underlying grf layer. */
570 /* I want to nuke this */
572 ite_reinit(dev_t dev
)
574 struct ite_softc
*ip
;
575 int unit
= UNIT(dev
);
577 /* XXX check whether when call from grf.c */
578 if (unit
< 0 || unit
>= ite_cd
.cd_ndevs
||
579 (ip
= getitesp(unit
)) == NULL
)
582 ip
->flags
&= ~ITE_INITED
;
587 ite_reset(struct ite_softc
*ip
)
596 ip
->save_attribute
= 0;
598 ip
->emul_level
= EMUL_VT300_8
;
601 ip
->bottom_margin
= ip
->rows
- 1;
602 ip
->inside_margins
= 0; /* origin mode == absolute */
603 ip
->linefeed_newline
= 0;
605 ip
->cursor_appmode
= 0;
606 ip
->keypad_appmode
= 0;
610 ip
->G1
= CSET_JIS1983
;
611 ip
->G2
= CSET_JISKANA
;
612 ip
->G3
= CSET_JIS1990
;
619 for (i
= 0; i
< ip
->cols
; i
++)
620 ip
->tabs
[i
] = ((i
& 7) == 0);
621 /* XXX clear screen */
622 SUBR_CLEAR(ip
, 0, 0, ip
->rows
, ip
->cols
);
623 attrclr(ip
, 0, 0, ip
->rows
, ip
->cols
);
626 /* Used in console at startup only */
628 ite_cnfilter(u_char c
)
630 static u_char mod
= 0;
632 u_char code
, up
, mask
;
635 up
= c
& 0x80 ? 1 : 0;
642 if (c
>= KBD_LEFT_ALT
&& !(c
>= 0x63 && c
<= 0x6c)) { /* 0x63: F1, 0x6c:F10 */
645 mask
= KBD_MOD_SHIFT
;
657 mask
= KBD_MOD_LMETA
;
661 mask
= KBD_MOD_RMETA
;
666 * capslock already behaves `right', don't need to
667 * keep track of the state in here.
682 if (mask
& KBD_MOD_CAPS
) {
685 kbdled
^= LED_CAPS_LOCK
;
700 /* translate modifiers */
701 if (mod
& KBD_MOD_SHIFT
) {
702 if (mod
& KBD_MOD_ALT
)
703 key
= kbdmap
.alt_shift_keys
[c
];
705 key
= kbdmap
.shift_keys
[c
];
706 } else if (mod
& KBD_MOD_ALT
)
707 key
= kbdmap
.alt_keys
[c
];
709 key
= kbdmap
.keys
[c
];
710 /* if CAPS and key is CAPable (no pun intended) */
711 if ((mod
& KBD_MOD_CAPS
) && (key
.mode
& KBD_MODE_CAPS
))
712 key
= kbdmap
.shift_keys
[c
];
716 /* if string return */
717 if (key
.mode
& (KBD_MODE_STRING
| KBD_MODE_KPAD
)) {
721 /* handle dead keys */
722 if (key
.mode
& KBD_MODE_DEAD
) {
726 if (mod
& KBD_MOD_CTRL
)
728 if (mod
& KBD_MOD_META
)
731 /* do console mapping. */
732 code
= code
== '\r' ? '\n' : code
;
738 /* And now the old stuff. */
742 (*kbd_tty
->t_linesw
->l_rint
)(ch
, kbd_tty
);
749 static u_short mod
= 0;
750 unsigned char code
, *str
;
755 if (!kbd_ite
|| !(kbd_tty
= ite_tty
[device_unit(&kbd_ite
->device
)]))
758 /* have to make sure we're at spltty in here */
761 up
= c
& 0x80 ? 1 : 0;
766 if (c
>= KBD_LEFT_ALT
&&
767 !(c
>= 0x63 && c
<= 0x6c)) { /* 0x63: F1, 0x6c:F10 */
770 mask
= KBD_MOD_SHIFT
;
782 mask
= KBD_MOD_LMETA
;
786 mask
= KBD_MOD_RMETA
;
791 * capslock already behaves `right', don't need to keep
792 * track of the state in here.
810 if (up
) { /* ite got 0xff */
816 if (mask
& KBD_MOD_CAPS
) {
819 kbdled
^= LED_CAPS_LOCK
;
827 * return even if it wasn't a modifier key, the other
828 * codes up here are either special (like reset warning),
841 * intercept LAlt-LMeta-F1 here to switch back to original ascii-keymap.
842 * this should probably be configurable..
844 if (mod
== (KBD_MOD_LALT
|KBD_MOD_LMETA
) && c
== 0x63) {
845 memcpy(&kbdmap
, &ascii_kbdmap
, sizeof(struct kbdmap
));
850 /* translate modifiers */
851 if (mod
& KBD_MOD_SHIFT
) {
852 if (mod
& KBD_MOD_ALT
)
853 key
= kbdmap
.alt_shift_keys
[c
];
855 key
= kbdmap
.shift_keys
[c
];
856 } else if (mod
& KBD_MOD_ALT
)
857 key
= kbdmap
.alt_keys
[c
];
859 key
= kbdmap
.keys
[c
];
860 /* if CAPS and key is CAPable (no pun intended) */
861 if ((mod
& KBD_MOD_CAPS
) && (key
.mode
& KBD_MODE_CAPS
))
862 key
= kbdmap
.shift_keys
[c
];
863 else if ((mod
& KBD_MOD_OPT2
) && (key
.mode
& KBD_MODE_KPAD
))
864 key
= kbdmap
.shift_keys
[c
];
868 /* handle dead keys */
869 if (key
.mode
& KBD_MODE_DEAD
) {
873 /* if not string, apply META and CTRL modifiers */
874 if (! (key
.mode
& KBD_MODE_STRING
)
875 && (!(key
.mode
& KBD_MODE_KPAD
) ||
876 (kbd_ite
&& !kbd_ite
->keypad_appmode
))) {
877 if ((mod
& KBD_MOD_CTRL
) &&
878 (code
== ' ' || (code
>= '@' && code
<= 'z')))
880 if (mod
& KBD_MOD_META
)
882 } else if ((key
.mode
& KBD_MODE_KPAD
) &&
883 (kbd_ite
&& kbd_ite
->keypad_appmode
)) {
884 static const char * const in
= "0123456789-+.\r()/*";
885 static const char * const out
= "pqrstuvwxymlnMPQRS";
886 char *cp
= strchr(in
, code
);
889 * keypad-appmode sends SS3 followed by the above
890 * translated character
892 (*kbd_tty
->t_linesw
->l_rint
)(27, kbd_tty
);
893 (*kbd_tty
->t_linesw
->l_rint
)('O', kbd_tty
);
894 (*kbd_tty
->t_linesw
->l_rint
)(out
[cp
- in
], kbd_tty
);
898 /* *NO* I don't like this.... */
899 static u_char app_cursor
[] =
906 str
= kbdmap
.strings
+ code
;
908 * if this is a cursor key, AND it has the default
909 * keymap setting, AND we're in app-cursor mode, switch
910 * to the above table. This is *nasty* !
912 if (c
>= 0x3b && c
<= 0x3e && kbd_ite
->cursor_appmode
913 && !memcmp(str
, "\x03\x1b[", 3) &&
914 strchr("ABCD", str
[3]))
915 str
= app_cursor
+ 4 * (str
[3] - 'A');
918 * using a length-byte instead of 0-termination allows
919 * to embed \0 into strings, although this is not used
920 * in the default keymap
922 for (i
= *str
++; i
; i
--)
923 (*kbd_tty
->t_linesw
->l_rint
)(*str
++, kbd_tty
);
927 (*kbd_tty
->t_linesw
->l_rint
)(code
, kbd_tty
);
933 /* helper functions, makes the code below more readable */
935 ite_sendstr(struct ite_softc
*ip
, const char *str
)
942 alignment_display(struct ite_softc
*ip
)
946 for (j
= 0; j
< ip
->rows
; j
++)
947 for (i
= 0; i
< ip
->cols
; i
++)
948 SUBR_PUTC(ip
, 'E', j
, i
, ATTR_NOR
);
949 attrclr(ip
, 0, 0, ip
->rows
, ip
->cols
);
953 snap_cury(struct ite_softc
*ip
)
955 if (ip
->inside_margins
) {
956 if (ip
->cury
< ip
->top_margin
)
957 ip
->cury
= ip
->top_margin
;
958 if (ip
->cury
> ip
->bottom_margin
)
959 ip
->cury
= ip
->bottom_margin
;
964 ite_dnchar(struct ite_softc
*ip
, int n
)
966 n
= min(n
, ip
->cols
- ip
->curx
);
967 if (n
< ip
->cols
- ip
->curx
) {
968 SUBR_SCROLL(ip
, ip
->cury
, ip
->curx
+ n
, n
, SCROLL_LEFT
);
969 attrmov(ip
, ip
->cury
, ip
->curx
+ n
, ip
->cury
, ip
->curx
,
970 1, ip
->cols
- ip
->curx
- n
);
971 attrclr(ip
, ip
->cury
, ip
->cols
- n
, 1, n
);
974 SUBR_PUTC(ip
, ' ', ip
->cury
, ip
->cols
- n
- 1, ATTR_NOR
);
978 ite_inchar(struct ite_softc
*ip
, int n
)
980 int c
= ip
->save_char
;
982 n
= min(n
, ip
->cols
- ip
->curx
);
983 if (n
< ip
->cols
- ip
->curx
) {
984 SUBR_SCROLL(ip
, ip
->cury
, ip
->curx
, n
, SCROLL_RIGHT
);
985 attrmov(ip
, ip
->cury
, ip
->curx
, ip
->cury
, ip
->curx
+ n
,
986 1, ip
->cols
- ip
->curx
- n
);
987 attrclr(ip
, ip
->cury
, ip
->curx
, 1, n
);
990 SUBR_PUTC(ip
, ' ', ip
->cury
, ip
->curx
+ n
, ATTR_NOR
);
995 ite_clrtoeol(struct ite_softc
*ip
)
997 int y
= ip
->cury
, x
= ip
->curx
;
998 if (ip
->cols
- x
> 0) {
999 SUBR_CLEAR(ip
, y
, x
, 1, ip
->cols
- x
);
1000 attrclr(ip
, y
, x
, 1, ip
->cols
- x
);
1005 ite_clrtobol(struct ite_softc
*ip
)
1007 int y
= ip
->cury
, x
= min(ip
->curx
+ 1, ip
->cols
);
1008 SUBR_CLEAR(ip
, y
, 0, 1, x
);
1009 attrclr(ip
, y
, 0, 1, x
);
1013 ite_clrline(struct ite_softc
*ip
)
1016 SUBR_CLEAR(ip
, y
, 0, 1, ip
->cols
);
1017 attrclr(ip
, y
, 0, 1, ip
->cols
);
1021 ite_clrtoeos(struct ite_softc
*ip
)
1024 if (ip
->cury
< ip
->rows
- 1) {
1025 SUBR_CLEAR(ip
, ip
->cury
+ 1, 0, ip
->rows
- 1 - ip
->cury
, ip
->cols
);
1026 attrclr(ip
, ip
->cury
, 0, ip
->rows
- ip
->cury
, ip
->cols
);
1031 ite_clrtobos(struct ite_softc
*ip
)
1035 SUBR_CLEAR(ip
, 0, 0, ip
->cury
, ip
->cols
);
1036 attrclr(ip
, 0, 0, ip
->cury
, ip
->cols
);
1041 ite_clrscreen(struct ite_softc
*ip
)
1043 SUBR_CLEAR(ip
, 0, 0, ip
->rows
, ip
->cols
);
1044 attrclr(ip
, 0, 0, ip
->rows
, ip
->cols
);
1050 ite_dnline(struct ite_softc
*ip
, int n
)
1053 * interesting.. if the cursor is outside the scrolling
1054 * region, this command is simply ignored..
1056 if (ip
->cury
< ip
->top_margin
|| ip
->cury
> ip
->bottom_margin
)
1059 n
= min(n
, ip
->bottom_margin
+ 1 - ip
->cury
);
1060 if (n
<= ip
->bottom_margin
- ip
->cury
) {
1061 SUBR_SCROLL(ip
, ip
->cury
+ n
, 0, n
, SCROLL_UP
);
1062 attrmov(ip
, ip
->cury
+ n
, 0, ip
->cury
, 0,
1063 ip
->bottom_margin
+ 1 - ip
->cury
- n
, ip
->cols
);
1065 SUBR_CLEAR(ip
, ip
->bottom_margin
- n
+ 1, 0, n
, ip
->cols
);
1066 attrclr(ip
, ip
->bottom_margin
- n
+ 1, 0, n
, ip
->cols
);
1070 ite_inline(struct ite_softc
*ip
, int n
)
1073 * interesting.. if the cursor is outside the scrolling
1074 * region, this command is simply ignored..
1076 if (ip
->cury
< ip
->top_margin
|| ip
->cury
> ip
->bottom_margin
)
1081 else n
= min(n
, ip
->bottom_margin
+ 1 - ip
->cury
);
1082 if (n
<= ip
->bottom_margin
- ip
->cury
) {
1083 SUBR_SCROLL(ip
, ip
->cury
, 0, n
, SCROLL_DOWN
);
1084 attrmov(ip
, ip
->cury
, 0, ip
->cury
+ n
, 0,
1085 ip
->bottom_margin
+ 1 - ip
->cury
- n
, ip
->cols
);
1087 SUBR_CLEAR(ip
, ip
->cury
, 0, n
, ip
->cols
);
1088 attrclr(ip
, ip
->cury
, 0, n
, ip
->cols
);
1093 ite_index(struct ite_softc
*ip
)
1096 if ((ip
->cury
== ip
->bottom_margin
+1) || (ip
->cury
== ip
->rows
)) {
1098 SUBR_SCROLL(ip
, ip
->top_margin
+ 1, 0, 1, SCROLL_UP
);
1101 /*clr_attr(ip, ATTR_INV);*/
1105 ite_lf(struct ite_softc
*ip
)
1108 if (ip
->cury
> ip
->bottom_margin
) {
1110 SUBR_SCROLL(ip
, ip
->top_margin
+ 1, 0, 1, SCROLL_UP
);
1113 /* SUBR_CURSOR(ip, MOVE_CURSOR);*/
1114 /*clr_attr(ip, ATTR_INV);*/
1115 /* reset character set ... thanks for mohta. */
1116 ip
->G0
= CSET_ASCII
;
1117 ip
->G1
= CSET_JIS1983
;
1118 ip
->G2
= CSET_JISKANA
;
1119 ip
->G3
= CSET_JIS1990
;
1127 ite_crlf(struct ite_softc
*ip
)
1134 ite_cr(struct ite_softc
*ip
)
1142 ite_rlf(struct ite_softc
*ip
)
1145 if ((ip
->cury
< 0) || (ip
->cury
== ip
->top_margin
- 1)) {
1147 SUBR_SCROLL(ip
, ip
->top_margin
, 0, 1, SCROLL_DOWN
);
1150 clr_attr(ip
, ATTR_INV
);
1154 atoi(const char *cp
)
1158 for (n
= 0; *cp
&& *cp
>= '0' && *cp
<= '9'; cp
++)
1159 n
= n
* 10 + *cp
- '0';
1164 ite_argnum(struct ite_softc
*ip
)
1169 /* convert argument string into number */
1170 if (ip
->ap
== ip
->argbuf
)
1174 n
= atoi(ip
->argbuf
);
1181 ite_zargnum(struct ite_softc
*ip
)
1186 /* convert argument string into number */
1187 if (ip
->ap
== ip
->argbuf
)
1190 *ip
->ap
= 0; /* terminate string */
1191 n
= atoi(ip
->argbuf
);
1194 return n
; /* don't "n ? n : 1" here, <CSI>0m != <CSI>1m ! */
1198 ite_putstr(const u_char
*s
, int len
, dev_t dev
)
1200 struct ite_softc
*ip
;
1205 /* XXX avoid problems */
1206 if ((ip
->flags
& (ITE_ACTIVE
|ITE_INGRF
)) != ITE_ACTIVE
)
1209 SUBR_CURSOR(ip
, START_CURSOROPT
);
1210 for (i
= 0; i
< len
; i
++)
1212 iteputchar(s
[i
], ip
);
1213 SUBR_CURSOR(ip
, END_CURSOROPT
);
1217 iteputchar(int c
, struct ite_softc
*ip
)
1222 if (c
>= 0x20 && ip
->escape
) {
1223 switch (ip
->escape
) {
1227 /* first 7bit equivalents for the 8bit control characters */
1232 break; /* and fall into the next switch below (same for all `break') */
1241 /* set TAB at current col */
1253 /* single shift G2 */
1259 /* single shift G3 */
1276 /* String Terminator */
1297 /* introduces 7/8bit control */
1299 /* can be followed by either F or G */
1304 /* a lot of character set selections, not yet used...
1305 94-character sets: */
1313 case 'B': /* ASCII */
1314 case 'A': /* ISO latin 1 */
1315 case '<': /* user preferred suplemental */
1316 case '0': /* dec special graphics */
1318 /* 96-character sets: */
1323 /* national character sets: */
1324 case '4': /* dutch */
1326 case 'C': /* finnish */
1327 case 'R': /* french */
1328 case 'Q': /* french canadian */
1329 case 'K': /* german */
1330 case 'Y': /* italian */
1331 case '6': /* norwegian/danish */
1332 /* note: %5 and %6 are not supported (two chars..) */
1335 /* just ignore for now */
1338 /* 94-multibyte character sets designate */
1343 /* locking shift modes */
1374 /* font width/height control */
1380 /* hard terminal reset .. */
1382 SUBR_CURSOR(ip
, MOVE_CURSOR
);
1389 ip
->save_curx
= ip
->curx
;
1390 ip
->save_cury
= ip
->cury
;
1391 ip
->save_attribute
= ip
->attribute
;
1392 ip
->sc_om
= ip
->inside_margins
;
1403 /* restore cursor */
1404 ip
->curx
= ip
->save_curx
;
1405 ip
->cury
= ip
->save_cury
;
1406 ip
->attribute
= ip
->save_attribute
;
1407 ip
->inside_margins
= ip
->sc_om
;
1414 SUBR_CURSOR(ip
, MOVE_CURSOR
);
1419 /* keypad application mode */
1420 ip
->keypad_appmode
= 1;
1425 /* keypad numeric mode */
1426 ip
->keypad_appmode
= 0;
1430 case 'Z': /* request ID */
1431 if (ip
->emul_level
== EMUL_VT100
)
1432 ite_sendstr(ip
, "\033[61;0c"); /* XXX not clean */
1434 ite_sendstr(ip
, "\033[63;0c"); /* XXX not clean */
1438 /* default catch all for not recognized ESC sequences */
1446 case '(': /* designate G0 */
1448 case 'B': /* USASCII */
1449 ip
->G0
= CSET_ASCII
;
1453 ip
->G0
= CSET_JISKANA
;
1457 ip
->G0
= CSET_JISROMA
;
1460 case 'A': /* British or ISO-Latin-1 */
1461 case 'H': /* Swedish */
1462 case 'K': /* German */
1463 case 'R': /* French */
1464 case 'Y': /* Italian */
1465 case 'Z': /* Spanish */
1472 case ')': /* designate G1 */
1476 case '$': /* 94-multibyte character set */
1479 ip
->G0
= CSET_JIS1978
;
1483 ip
->G0
= CSET_JIS1983
;
1487 ip
->G0
= CSET_JIS1990
;
1499 ip
->eightbit_C1
= 0;
1504 ip
->eightbit_C1
= 1;
1518 /* single height, single width */
1523 /* double width, single height */
1538 /* screen alignment pattern... */
1539 alignment_display(ip
);
1554 case '0': case '1': case '2': case '3': case '4':
1555 case '5': case '6': case '7': case '8': case '9':
1556 case ';': case '\"': case '$': case '>':
1557 if (ip
->ap
< ip
->argbuf
+ MAX_ARGSIZE
)
1563 if (!strncmp(ip
->argbuf
, "61\"", 3))
1564 ip
->emul_level
= EMUL_VT100
;
1565 else if (!strncmp(ip
->argbuf
, "63;1\"", 5)
1566 || !strncmp(ip
->argbuf
, "62;1\"", 5))
1567 ip
->emul_level
= EMUL_VT300_7
;
1569 ip
->emul_level
= EMUL_VT300_8
;
1577 ip
->ap
= ip
->argbuf
;
1582 /* device attributes */
1584 if (ip
->argbuf
[0] == '>') {
1585 ite_sendstr(ip
, "\033[>24;0;0;0c");
1587 switch (ite_zargnum(ip
)) {
1589 /* primary DA request, send primary DA response */
1590 if (ip
->emul_level
== EMUL_VT100
)
1591 ite_sendstr(ip
, "\033[?1;1c");
1593 ite_sendstr(ip
, "\033[63;0c");
1600 switch (ite_zargnum(ip
)) {
1602 ite_sendstr(ip
, "\033[0n"); /* no malfunction */
1605 /* cursor position report */
1606 sprintf(ip
->argbuf
, "\033[%d;%dR",
1607 ip
->cury
+ 1, ip
->curx
+ 1);
1608 ite_sendstr(ip
, ip
->argbuf
);
1616 switch (ite_zargnum(ip
)) {
1618 /* Fake some terminal parameters. */
1619 ite_sendstr(ip
, "\033[2;1;1;112;112;1;0x");
1622 ite_sendstr(ip
, "\033[3;1;1;112;112;1;0x");
1631 switch (ite_zargnum(ip
)) {
1633 if (ip
->curx
< ip
->cols
)
1634 ip
->tabs
[ip
->curx
] = 0;
1637 for (n
= 0; n
< ip
->cols
; n
++)
1649 case 'h': /* set mode */
1650 case 'l': /* reset mode */
1651 n
= ite_zargnum(ip
);
1654 ip
->imode
= (c
== 'h'); /* insert/replace mode */
1657 ip
->linefeed_newline
= (c
== 'h');
1666 ite_dnline(ip
, ite_argnum(ip
));
1673 ite_inline(ip
, ite_argnum(ip
));
1680 ite_dnchar(ip
, ite_argnum(ip
));
1686 /* insert char(s) */
1687 ite_inchar(ip
, ite_argnum(ip
));
1692 /* soft terminal reset */
1693 ip
->escape
= 0; /* XXX */
1697 /* this one was *not* in my vt320 manual but in
1698 a vt320 termcap entry.. who is right?
1699 It's supposed to set the horizontal cursor position. */
1701 x
= atoi(ip
->argbuf
);
1704 ip
->curx
= min(x
, ip
->cols
- 1);
1706 SUBR_CURSOR(ip
, MOVE_CURSOR
);
1707 clr_attr(ip
, ATTR_INV
);
1712 /* same thing here, this one's for setting the absolute
1713 vertical cursor position. Not documented... */
1715 y
= atoi(ip
->argbuf
);
1718 if (ip
->inside_margins
)
1719 y
+= ip
->top_margin
;
1720 ip
->cury
= min(y
, ip
->rows
- 1);
1723 SUBR_CURSOR(ip
, MOVE_CURSOR
);
1724 clr_attr(ip
, ATTR_INV
);
1731 y
= atoi(ip
->argbuf
);
1733 cp
= strchr(ip
->argbuf
, ';');
1740 if (ip
->inside_margins
)
1741 y
+= ip
->top_margin
;
1742 ip
->cury
= min(y
, ip
->rows
- 1);
1743 ip
->curx
= min(x
, ip
->cols
- 1);
1746 SUBR_CURSOR(ip
, MOVE_CURSOR
);
1747 /*clr_attr(ip, ATTR_INV);*/
1753 n
= ip
->cury
- (n
? n
: 1);
1756 if (ip
->inside_margins
)
1757 n
= max(ip
->top_margin
, n
);
1758 else if (n
== ip
->top_margin
- 1)
1759 /* allow scrolling outside region, but don't scroll out
1760 of active region without explicit CUP */
1764 SUBR_CURSOR(ip
, MOVE_CURSOR
);
1765 clr_attr(ip
, ATTR_INV
);
1771 n
= ip
->cury
+ (n
? n
: 1);
1772 n
= min(ip
->rows
- 1, n
);
1774 if (ip
->inside_margins
)
1776 n
= min(ip
->bottom_margin
, n
);
1778 else if (n
== ip
->bottom_margin
+ 1)
1779 /* allow scrolling outside region, but don't scroll out
1780 of active region without explicit CUP */
1781 n
= ip
->bottom_margin
;
1785 SUBR_CURSOR(ip
, MOVE_CURSOR
);
1786 clr_attr(ip
, ATTR_INV
);
1790 /* cursor forward */
1793 ip
->curx
= min(ip
->curx
+ n
, ip
->cols
- 1);
1795 SUBR_CURSOR(ip
, MOVE_CURSOR
);
1796 clr_attr(ip
, ATTR_INV
);
1800 /* cursor backward */
1804 ip
->curx
= n
>= 0 ? n
: 0;
1806 SUBR_CURSOR(ip
, MOVE_CURSOR
);
1807 clr_attr(ip
, ATTR_INV
);
1814 n
= ite_zargnum(ip
);
1827 n
= ite_zargnum(ip
);
1839 n
= ite_zargnum(ip
);
1842 else if (n
> ip
->rows
-1)
1844 SUBR_SCROLL(ip
, ip
->rows
-1, 0, n
, SCROLL_UP
);
1850 n
= ite_zargnum(ip
);
1853 else if (n
> ip
->rows
-1)
1855 SUBR_SCROLL(ip
, 0, 0, n
, SCROLL_DOWN
);
1860 /* erase character */
1861 n
= ite_argnum(ip
) - 1;
1862 n
= min(n
, ip
->cols
- 1 - ip
->curx
);
1863 for (; n
>= 0; n
--) {
1864 attrclr(ip
, ip
->cury
, ip
->curx
+ n
, 1, 1);
1865 SUBR_PUTC(ip
, ' ', ip
->cury
, ip
->curx
+ n
, ATTR_NOR
);
1872 /* status line control */
1877 /* set scrolling region */
1880 x
= atoi(ip
->argbuf
);
1883 cp
= strchr(ip
->argbuf
, ';');
1886 y
= y
? y
: ip
->rows
;
1892 ip
->top_margin
= min(x
, ip
->rows
- 2);
1893 ip
->bottom_margin
= min(y
, ip
->rows
- 1);
1894 if (ip
->inside_margins
) {
1895 ip
->cury
= ip
->top_margin
;
1903 /* big attribute setter/resetter */
1907 /* kludge to make CSIm work (== CSI0m) */
1908 if (ip
->ap
== ip
->argbuf
)
1910 for (c_p
= ip
->argbuf
; c_p
< ip
->ap
; ) {
1914 clr_attr(ip
, ATTR_ALL
);
1921 set_attr(ip
, ATTR_BOLD
);
1928 clr_attr(ip
, ATTR_BOLD
);
1933 clr_attr(ip
, ATTR_UL
);
1938 clr_attr(ip
, ATTR_BLINK
);
1943 clr_attr(ip
, ATTR_INV
);
1955 case '0': case '1': case '2': case '3':
1956 case '4': case '5': case '6': case '7':
1957 /* foreground colors */
1958 ip
->fgcolor
= c_p
[1] - '0';
1969 case '0': case '1': case '2': case '3':
1970 case '4': case '5': case '6': case '7':
1971 /* background colors */
1972 ip
->bgcolor
= c_p
[1] - '0';
1976 set_attr(ip
, ATTR_UL
);
1983 set_attr(ip
, ATTR_BLINK
);
1988 set_attr(ip
, ATTR_INV
);
2005 ite_sendstr(ip
, "\033P\033\\");
2017 case '?': /* CSI ? */
2019 case '0': case '1': case '2': case '3': case '4':
2020 case '5': case '6': case '7': case '8': case '9':
2021 case ';': case '\"': case '$':
2022 /* Don't fill the last character; it's needed. */
2023 /* XXX yeah, where ?? */
2024 if (ip
->ap
< ip
->argbuf
+ MAX_ARGSIZE
- 1)
2030 /* Terminal Reports */
2032 if (ip
->ap
== &ip
->argbuf
[2]) {
2033 if (!strncmp(ip
->argbuf
, "15", 2))
2034 /* printer status: no printer */
2035 ite_sendstr(ip
, "\033[13n");
2037 else if (!strncmp(ip
->argbuf
, "25", 2))
2039 ite_sendstr(ip
, "\033[20n");
2041 else if (!strncmp(ip
->argbuf
, "26", 2))
2042 /* keyboard dialect: US */
2043 ite_sendstr(ip
, "\033[27;1n");
2049 case 'h': /* set dec private modes */
2050 case 'l': /* reset dec private modes */
2051 n
= ite_zargnum(ip
);
2054 /* CKM - cursor key mode */
2055 ip
->cursor_appmode
= (c
== 'h');
2059 /* 132/80 columns (132 == 'h') */
2062 case 4: /* smooth scroll */
2066 /* light background (=='h') /dark background(=='l') */
2069 case 6: /* origin mode */
2070 ip
->inside_margins
= (c
== 'h');
2073 ip
->cury
= ip
->inside_margins
? ip
->top_margin
: 0;
2074 SUBR_CURSOR(ip
, MOVE_CURSOR
);
2078 case 7: /* auto wraparound */
2079 ip
->auto_wrap
= (c
== 'h');
2082 case 8: /* keyboard repeat */
2083 ip
->key_repeat
= (c
== 'h');
2086 case 20: /* newline mode */
2087 ip
->linefeed_newline
= (c
== 'h');
2090 case 25: /* cursor on/off */
2091 SUBR_CURSOR(ip
, (c
== 'h') ? DRAW_CURSOR
: ERASE_CURSOR
);
2098 /* selective erase in line */
2100 /* selective erase in display */
2116 case 0x00: /* NUL */
2117 case 0x01: /* SOH */
2118 case 0x02: /* STX */
2119 case 0x03: /* ETX */
2120 case 0x04: /* EOT */
2121 case 0x05: /* ENQ */
2122 case 0x06: /* ACK */
2127 if (kbd_ite
&& ite_tty
[device_unit(&kbd_ite
->device
)])
2136 SUBR_CURSOR(ip
, MOVE_CURSOR
);
2140 for (n
= ip
->curx
+ 1; n
< ip
->cols
; n
++) {
2143 SUBR_CURSOR(ip
, MOVE_CURSOR
);
2149 case VT
: /* VT is treated like LF */
2150 case FF
: /* so is FF */
2152 /* cr->crlf distinction is done here, on output,
2154 if (ip
->linefeed_newline
)
2173 case 0x10: /* DLE */
2174 case 0x11: /* DC1/XON */
2175 case 0x12: /* DC2 */
2176 case 0x13: /* DC3/XOFF */
2177 case 0x14: /* DC4 */
2178 case 0x15: /* NAK */
2179 case 0x16: /* SYN */
2180 case 0x17: /* ETB */
2184 ip
->escape
= 0; /* cancel any escape sequence in progress */
2191 ip
->escape
= 0; /* dito, but see below */
2192 /* should also display a reverse question mark!! */
2205 /* now it gets weird.. 8bit control sequences.. */
2206 case IND
: /* index: move cursor down, scroll */
2210 case NEL
: /* next line. next line, first pos. */
2214 case HTS
: /* set horizontal tab */
2215 if (ip
->curx
< ip
->cols
)
2216 ip
->tabs
[ip
->curx
] = 1;
2219 case RI
: /* reverse index */
2223 case SS2
: /* go into G2 for one character */
2224 ip
->save_GL
= ip
->GR
; /* GL XXX EUC */
2225 ip
->GR
= &ip
->G2
; /* GL XXX */
2228 case SS3
: /* go into G3 for one character */
2229 ip
->save_GL
= ip
->GR
; /* GL XXX EUC */
2230 ip
->GR
= &ip
->G3
; /* GL XXX */
2233 case DCS
: /* device control string introducer */
2235 ip
->ap
= ip
->argbuf
;
2238 case CSI
: /* control sequence introducer */
2240 ip
->ap
= ip
->argbuf
;
2243 case ST
: /* string terminator */
2244 /* ignore, if not used as terminator */
2247 case OSC
: /* introduces OS command. Ignore everything upto ST */
2251 case PM
: /* privacy message, ignore everything upto ST */
2255 case APC
: /* application program command, ignore everything upto ST */
2263 if (!ip
->save_char
&& (*((c
& 0x80) ? ip
->GR
: ip
->GL
) & CSET_MULTI
)) {
2268 ite_inchar(ip
, ip
->save_char
? 2 : 1);
2269 iteprecheckwrap(ip
);
2270 #ifdef DO_WEIRD_ATTRIBUTES
2271 if ((ip
->attribute
& ATTR_INV
) || attrtest(ip
, ATTR_INV
)) {
2272 attrset(ip
, ATTR_INV
);
2273 SUBR_PUTC(ip
, c
, ip
->cury
, ip
->curx
, ATTR_INV
);
2276 SUBR_PUTC(ip
, c
, ip
->cury
, ip
->curx
, ATTR_NOR
);
2278 SUBR_PUTC(ip
, c
, ip
->cury
, ip
->curx
, ip
->attribute
);
2280 /* SUBR_CURSOR(ip, DRAW_CURSOR);*/
2282 if (ip
->save_char
) {
2288 * reset single shift
2290 ip
->GR
= ip
->save_GL
;
2298 iteprecheckwrap(struct ite_softc
*ip
)
2300 if (ip
->auto_wrap
&& ip
->curx
+ (ip
->save_char
? 1 : 0) == ip
->cols
) {
2302 clr_attr(ip
, ATTR_INV
);
2303 if (++ip
->cury
>= ip
->bottom_margin
+ 1) {
2304 ip
->cury
= ip
->bottom_margin
;
2305 /*SUBR_CURSOR(ip, MOVE_CURSOR);*/
2306 SUBR_SCROLL(ip
, ip
->top_margin
+ 1, 0, 1, SCROLL_UP
);
2309 SUBR_CURSOR(ip, MOVE_CURSOR);*/
2314 itecheckwrap(struct ite_softc
*ip
)
2317 if (++ip
->curx
== ip
->cols
) {
2318 if (ip
->auto_wrap
) {
2320 clr_attr(ip
, ATTR_INV
);
2321 if (++ip
->cury
>= ip
->bottom_margin
+ 1) {
2322 ip
->cury
= ip
->bottom_margin
;
2323 SUBR_CURSOR(ip
, MOVE_CURSOR
);
2324 SUBR_SCROLL(ip
, ip
->top_margin
+ 1, 0, 1, SCROLL_UP
);
2329 /* stay there if no autowrap.. */
2333 if (ip
->curx
< ip
->cols
) {
2335 /*SUBR_CURSOR(ip, MOVE_CURSOR);*/
2342 #if NITE > 0 && NKBD > 0
2347 #include <dev/cons.h>
2348 extern void kbdenable(int);
2349 extern int kbdcngetc(void);
2352 * Return a priority in consdev->cn_pri field highest wins. This function
2353 * is called before any devices have been probed.
2356 itecnprobe(struct consdev
*cd
)
2360 /* locate the major number */
2361 maj
= cdevsw_lookup_major(&ite_cdevsw
);
2364 * return priority of the best ite (already picked from attach)
2367 if (con_itesoftc
.grf
== NULL
)
2368 cd
->cn_pri
= CN_DEAD
;
2370 con_itesoftc
.flags
= (ITE_ALIVE
|ITE_CONSOLE
);
2372 * hardcode the minor number.
2373 * currently we support only one ITE, it is enough for now.
2375 con_itesoftc
.isw
= &itesw
[0];
2376 cd
->cn_pri
= CN_INTERNAL
;
2377 cd
->cn_dev
= makedev(maj
, 0);
2383 itecninit(struct consdev
*cd
)
2385 struct ite_softc
*ip
;
2387 ip
= getitesp(cd
->cn_dev
);
2388 iteinit(cd
->cn_dev
); /* init console unit */
2389 ip
->flags
|= ITE_ACTIVE
| ITE_ISCONS
;
2391 mfp_send_usart(0x49);
2395 * itecnfinish() is called in ite_init() when the device is
2396 * being probed in the normal fasion, thus we can finish setting
2397 * up this ite now that the system is more functional.
2400 itecnfinish(struct ite_softc
*ip
)
2411 itecngetc(dev_t dev
)
2417 c
= ite_cnfilter(c
);
2423 itecnputc(dev_t dev
, int c
)
2425 static int paniced
= 0;
2426 struct ite_softc
*ip
= getitesp(dev
);
2428 #ifdef ITE_KERNEL_ATTR
2429 short save_attribute
;
2432 if (panicstr
&& !paniced
&&
2433 (ip
->flags
& (ITE_ACTIVE
|ITE_INGRF
)) != ITE_ACTIVE
) {
2434 (void) iteon(dev
, 3);
2437 #ifdef ITE_KERNEL_ATTR
2438 save_attribute
= ip
->attribute
;
2439 ip
->attribute
= ITE_KERNEL_ATTR
;
2441 ite_putstr(&ch
, 1, dev
);
2442 #ifdef ITE_KERNEL_ATTR
2443 ip
->attribute
= save_attribute
;