xref: /csrg-svn/sys/news3400/bm/kb_ctrl.c (revision 63250)
153889Smckusick /*
2*63250Sbostic  * Copyright (c) 1992, 1993
3*63250Sbostic  *	The Regents of the University of California.  All rights reserved.
453889Smckusick  *
553889Smckusick  * This code is derived from software contributed to Berkeley by
653889Smckusick  * Sony Corp. and Kazumasa Utashiro of Software Research Associates, Inc.
753889Smckusick  *
853889Smckusick  * %sccs.include.redist.c%
953889Smckusick  *
1053889Smckusick  * from: $Hdr: kb_ctrl.c,v 4.300 91/06/09 06:14:49 root Rel41 $ SONY
1153889Smckusick  *
12*63250Sbostic  *	@(#)kb_ctrl.c	8.1 (Berkeley) 06/10/93
1353889Smckusick  */
1453889Smckusick 
1553889Smckusick /*
1653889Smckusick  *	Keyboard driver
1753889Smckusick  */
1853889Smckusick 
1953889Smckusick #ifdef IPC_MRX
2057177Sutashiro #include <sys/ioctl.h>
2157177Sutashiro #include <news3400/iop/keyboard.h>
2257177Sutashiro #include <news3400/iop/kbreg.h>
2353889Smckusick #else
2457177Sutashiro #include <sys/ioctl.h>
2557177Sutashiro #include <sys/param.h>
2657177Sutashiro #include <sys/systm.h>
2757177Sutashiro #include <sys/types.h>
2857177Sutashiro #include <news3400/iop/keyboard.h>
2957177Sutashiro #include <news3400/iop/kbreg.h>
3053889Smckusick #endif
3153889Smckusick 
3253889Smckusick extern int tmode;
3353889Smckusick extern int kbd_status;
3453889Smckusick 
3553889Smckusick int iscaps = 0;
3653889Smckusick int change_country = K_JAPANESE_J;
3753889Smckusick int country;
3853889Smckusick 
3953889Smckusick extern Key_table default_table[];
4053889Smckusick 
4153889Smckusick #ifdef CPU_SINGLE
4253889Smckusick extern Key_table key_table[];
4353889Smckusick Key_table *key_table_addr = key_table;
4453889Smckusick #endif
4553889Smckusick 
4653889Smckusick #ifdef CPU_DOUBLE
4753889Smckusick Key_table *key_table_addr = default_table;
4853889Smckusick #endif
4953889Smckusick 
5053889Smckusick #ifdef CPU_SINGLE
5153889Smckusick #include "ms.h"
5257177Sutashiro #include <sys/clist.h>
5357177Sutashiro #include <sys/ttydev.h>
5457177Sutashiro #include <sys/tty.h>
5557177Sutashiro #include <news3400/sio/scc.h>
5657177Sutashiro #include <sys/time.h>
5757177Sutashiro #include <news3400/iop/mouse.h>
5853889Smckusick 
5953889Smckusick extern int cnrint();
6053889Smckusick 
kbd_open(chan)6153889Smckusick kbd_open(chan)
6253889Smckusick 	int chan;
6353889Smckusick {
6453889Smckusick 	register int i;
6553889Smckusick 
6658606Sutashiro #if defined(news3400)
6753889Smckusick 	kbm_open(chan);
6853889Smckusick #endif
6953889Smckusick 	return (0);
7053889Smckusick }
7153889Smckusick 
kbd_read(chan,buf,n)7253889Smckusick kbd_read(chan, buf, n)
7353889Smckusick 	int chan;
7453889Smckusick 	char *buf;
7553889Smckusick 	int n;
7653889Smckusick {
7753889Smckusick #if defined(news1700) || defined(news1200)
7853889Smckusick 
7953889Smckusick 	return (kbd_read_raw(chan, buf, n));
8053889Smckusick #endif
8153889Smckusick }
8253889Smckusick 
kbd_write(chan,buf,n)8353889Smckusick kbd_write(chan, buf, n)
8453889Smckusick 	int chan;
8553889Smckusick 	char *buf;
8653889Smckusick 	int n;
8753889Smckusick {
8853889Smckusick 
8958606Sutashiro #if defined(news3400)
9053889Smckusick 	return (kbm_write(SCC_KEYBOARD, buf, n));
9153889Smckusick #endif
9253889Smckusick }
9353889Smckusick 
kbd_back(buf,len)9453889Smckusick kbd_back(buf, len)
9553889Smckusick 	register char *buf;
9653889Smckusick 	register int len;
9753889Smckusick {
9853889Smckusick 	int s;
9953889Smckusick 
10053889Smckusick 	while (--len >= 0) {
10153889Smckusick 		s = spltty();
10253889Smckusick 		cnrint(*buf++);
10353889Smckusick 		(void) splx(s);
10453889Smckusick 	}
10553889Smckusick 	return (0);
10653889Smckusick }
10753889Smckusick 
10853889Smckusick #define	KBPRI	(PZERO+1)
10953889Smckusick 
11053889Smckusick struct clist scode_buf;
11153889Smckusick struct clist keyboard_buf;
11253889Smckusick char	kb_rwait;
11353889Smckusick 
kbd_flush()11453889Smckusick kbd_flush()
11553889Smckusick {
11653889Smckusick 
11753889Smckusick 	ndflush(&scode_buf, scode_buf.c_cc);
11853889Smckusick 	return (0);
11953889Smckusick }
12053889Smckusick 
12153889Smckusick static
kbd_put_raw(scode)12253889Smckusick kbd_put_raw(scode)
12353889Smckusick 	int scode;
12453889Smckusick {
12553889Smckusick 	extern char kb_busy;
12653889Smckusick 
12753889Smckusick 	if (kb_busy) {
12853889Smckusick 		if (scode_buf.c_cc < CBSIZE)
12953889Smckusick 			putc(scode, &scode_buf);
13053889Smckusick 		if (kb_rwait) {
13153889Smckusick 			kb_rwait = 0;
13253889Smckusick 			wakeup((caddr_t)&kb_rwait);
13353889Smckusick 		}
13453889Smckusick 	}
13553889Smckusick 	return (scode);
13653889Smckusick 
13753889Smckusick }
13853889Smckusick 
kbd_read_raw(chan,buf,count)13953889Smckusick kbd_read_raw(chan, buf, count)
14053889Smckusick 	int chan;
14153889Smckusick 	char *buf;
14253889Smckusick 	register int count;
14353889Smckusick {
14453889Smckusick 	register int i;
14553889Smckusick 	register int n;
14653889Smckusick 	register int s;
14753889Smckusick 
14853889Smckusick 	if (count <= 0)
14953889Smckusick 		return (count);
15053889Smckusick 	s = splscc();
15153889Smckusick 	while ((n = min(scode_buf.c_cc, count)) == 0) {
15253889Smckusick 		kb_rwait = 1;
15353889Smckusick 		sleep((caddr_t)&kb_rwait, KBPRI);
15453889Smckusick 		kb_rwait = 0;
15553889Smckusick 	}
15653889Smckusick 	(void) splx(s);
15753889Smckusick 	for (i = n; i > 0 ; i--)
15853889Smckusick 		*buf++ = getc(&scode_buf);
15953889Smckusick 	return (n);
16053889Smckusick }
16153889Smckusick 
kbd_nread()16253889Smckusick kbd_nread()
16353889Smckusick {
16453889Smckusick 
16553889Smckusick 	return (scode_buf.c_cc);
16653889Smckusick }
16753889Smckusick 
kbd_bell(n)16853889Smckusick kbd_bell(n)
16953889Smckusick 	register int n;
17053889Smckusick {
17153889Smckusick 
17258606Sutashiro #if defined(news3400)
17353889Smckusick 	(void) kbm_write(SCC_KEYBOARD, NULL, n);
17453889Smckusick #endif
17553889Smckusick 	return (0);
17653889Smckusick }
17753889Smckusick 
kbd_putcode(code)17853889Smckusick kbd_putcode(code)
17953889Smckusick 	int code;
18053889Smckusick {
18153889Smckusick 	int c;
18253889Smckusick 
18353889Smckusick 	kbd_put_raw(code);
18453889Smckusick 	kbd_encode(code);
18553889Smckusick 	while ((c = getc(&keyboard_buf)) != -1)
18653889Smckusick 		cnrint(c);
18753889Smckusick }
18853889Smckusick 
put_code(buf,cnt)18953889Smckusick put_code(buf, cnt)
19053889Smckusick 	register char *buf;
19153889Smckusick 	register int cnt;
19253889Smckusick {
19353889Smckusick 
19453889Smckusick 	while (--cnt >= 0)
19553889Smckusick 		putc(*buf++, &keyboard_buf);
19653889Smckusick }
19753889Smckusick 
kb_softint()19853889Smckusick kb_softint()
19953889Smckusick {
20053889Smckusick 	int code;
20153889Smckusick 	extern int tty00_is_console;
20253889Smckusick 
20353889Smckusick 	while ((code = xgetc(SCC_KEYBOARD)) >= 0) {
20458606Sutashiro #if defined(news3200)		/* BEGIN reiko */
20553889Smckusick 		if ((code & 0x7f) == KEY_EISUU) {
20653889Smckusick 			int up = code & OFF;
20753889Smckusick 			static int kana = 0;
20853889Smckusick 
20953889Smckusick 			if (kana) {
21053889Smckusick 				if (up) {
21153889Smckusick 					kana = 0;
21253889Smckusick 				}
21353889Smckusick 			} else {
21453889Smckusick 				if (up) {
21553889Smckusick 					code = KEY_KANA | OFF;
21653889Smckusick 					kana = 1;
21753889Smckusick 				} else {
21853889Smckusick 					code = KEY_KANA;
21953889Smckusick 				}
22053889Smckusick 			}
22153889Smckusick 		}
22253889Smckusick #endif
22353889Smckusick 
22453889Smckusick #ifdef NOTDEF /* KU:XXX */
22553889Smckusick 		if (!tty00_is_console)
22653889Smckusick #endif
22753889Smckusick 			rst_dimmer_cnt();
22853889Smckusick #if NMS > 0
22953889Smckusick 		if (!mskeytrigger(0, code & OFF, code & 0x7f))
23053889Smckusick #endif
23153889Smckusick 		kbd_putcode(code);
23253889Smckusick 	}
23353889Smckusick }
23453889Smckusick #endif /* CPU_SINGLE */
23553889Smckusick 
23653889Smckusick #ifdef IPC_MRX
23753889Smckusick #include "mrx.h"
23853889Smckusick #include "queue.h"
23953889Smckusick #include "process.h"
24053889Smckusick #include "buffer.h"
24153889Smckusick #include "port.h"
24253889Smckusick #include "message.h"
24353889Smckusick #include "machdep.h"
24453889Smckusick #include "malloc.h"
24553889Smckusick #include "config.h"
24653889Smckusick #include "kbms.h"
24753889Smckusick 
24853889Smckusick static struct buffer *kbd_buf;
24953889Smckusick static int port_kbd_intr;
25053889Smckusick static int port_kbd_back;
25153889Smckusick static int port_kbd_ctrl;
25253889Smckusick 
keyboard(chan)25353889Smckusick keyboard(chan)
25453889Smckusick 	int chan;
25553889Smckusick {
25653889Smckusick 	int kbd_ctrl(), kbd_output();
25753889Smckusick 	int kbd_read(), kbd_ioctl(), kbd_io();
25853889Smckusick 
25953889Smckusick #ifdef news3800
26053889Smckusick 	extern int (*Xkb_intr)();
26153889Smckusick 	int kb_intr();
26253889Smckusick 
26353889Smckusick 	Xkb_intr = kb_intr;
26453889Smckusick #endif
26553889Smckusick 	kb_ioctl = kbd_ioctl;
26653889Smckusick 	kb_read = kbd_read;
26753889Smckusick 	kbd_init();
26853889Smckusick 	proc_create("kbd_ctrl", kbd_ctrl, 300, DEFAULT_STACK_SIZE, 0);
26953889Smckusick 	proc_create("kbd_output", kbd_output, 300, DEFAULT_STACK_SIZE, 0);
27053889Smckusick 	proc_create("kbd_io", kbd_io, 300, DEFAULT_STACK_SIZE, 0);
27153889Smckusick }
27253889Smckusick 
27353889Smckusick int (*reset_dimmer)();
27453889Smckusick 
kbd_ctrl()27553889Smckusick kbd_ctrl()
27653889Smckusick {
27753889Smckusick 	register int m, n;
27853889Smckusick 	register int select;
27953889Smckusick 	int *len, from, count;
28053889Smckusick 	char *addr;
28153889Smckusick 	int ports[3];
28253889Smckusick 	static char buf[16];
28353889Smckusick 
28453889Smckusick 	ports[0] = port_kbd_intr = port_create("kb_intr");
28553889Smckusick 	ports[1] = port_kbd_back = port_create("kb_echoback");
28653889Smckusick 	ports[2] = port_kbd_ctrl = STDPORT;
28753889Smckusick 
28853889Smckusick #ifdef news3800
28953889Smckusick 	*(char *)KEYBD_RESET = 0;
29053889Smckusick 	*(char *)KEYBD_INTE = 1;
29153889Smckusick #endif
29253889Smckusick 
29353889Smckusick 	kbd_buf = buffer_alloc(32);
29453889Smckusick 	(void) spl0();
29553889Smckusick 	for (;;) {
29653889Smckusick 		if (buffer_status(kbd_buf) > 0)
29753889Smckusick 			m = 3;
29853889Smckusick 		else
29953889Smckusick 			m = 2;
30053889Smckusick 		if ((select = msg_select(m, ports)) == 0) {
30153889Smckusick 			msg_recv(ports[0], NULL, &addr, &count, 0);
30253889Smckusick 			if (reset_dimmer)
30353889Smckusick 				(*reset_dimmer)();
30453889Smckusick 			while (--count >= 0) {
30553889Smckusick 				if (send_mouse == 0 || (*send_mouse)(*addr) == 0)
30653889Smckusick 					kbd_encode(*addr);
30753889Smckusick 				addr++;
30853889Smckusick 			}
30953889Smckusick 		} else if (select == 1) {	/* ESC [ 6 n */
31053889Smckusick 			msg_recv(ports[select], NULL, &addr, &count, 0);
31153889Smckusick 			put(kbd_buf, addr, count);
31253889Smckusick 		} else {
31353889Smckusick 			msg_recv(ports[select], &from, &len, NULL, 0);
31453889Smckusick 			n = buffer_status(kbd_buf);
31553889Smckusick 			n = min(n, *len);
31653889Smckusick 			n = get(kbd_buf, buf, min(n, sizeof (buf)));
31753889Smckusick 			msg_send(from, ports[select], buf, n, 0);
31853889Smckusick 		}
31953889Smckusick 	}
32053889Smckusick }
32153889Smckusick 
kbd_output()32253889Smckusick kbd_output()
32353889Smckusick {
32453889Smckusick 	char *addr;
32553889Smckusick 	int from, len;
32653889Smckusick 
32753889Smckusick 	(void) spl0();
32853889Smckusick 	for (;;) {
32953889Smckusick 		msg_recv(STDPORT, &from, &addr, &len, 0);
33053889Smckusick #ifdef news3800
33153889Smckusick 		len = kbd_write(0, addr, len);
33253889Smckusick #endif
33353889Smckusick 		msg_send(from, STDPORT, &len, sizeof(len), 0);
33453889Smckusick 	}
33553889Smckusick }
33653889Smckusick 
kbd_io()33753889Smckusick kbd_io()
33853889Smckusick {
33953889Smckusick 	struct kb_ctrl_req *req;
34053889Smckusick 	int from, reply;
34153889Smckusick 
34253889Smckusick 	(void) spl0();
34353889Smckusick 	for (;;) {
34453889Smckusick 		msg_recv(STDPORT, &from, &req, NULL, 0);
34553889Smckusick 		if (req->kb_func == KIOCCHTBL || req->kb_func == KIOCOYATBL)
34653889Smckusick 			kbd_ioctl(0, req->kb_func, req->kb_arg);
34753889Smckusick 		else
34853889Smckusick 			kbd_ioctl(0, req->kb_func, &req->kb_arg);
34953889Smckusick 		reply = req->kb_arg;
35053889Smckusick 		msg_send(from, STDPORT, &reply, sizeof(reply), 0);
35153889Smckusick 	}
35253889Smckusick }
35353889Smckusick 
kbd_read(chan,buf,n)35453889Smckusick kbd_read(chan, buf, n)
35553889Smckusick 	int chan;
35653889Smckusick 	char *buf;
35753889Smckusick 	int n;
35853889Smckusick {
35953889Smckusick 	static int port;
36053889Smckusick 	char *addr;
36153889Smckusick 	int len;
36253889Smckusick 
36353889Smckusick 	if (port == 0)
36453889Smckusick 		port = port_create("port_kbd_read");
36553889Smckusick 	if (n <= 0)
36653889Smckusick 		return (0);
36753889Smckusick 	msg_send(port_kbd_ctrl, port, &n, sizeof (n), 0);
36853889Smckusick 	msg_recv(port, NULL, &addr, &len, 0);
36953889Smckusick 	bcopy(addr, buf, len);
37053889Smckusick 	msg_free(port);
37153889Smckusick 	return (len);
37253889Smckusick }
37353889Smckusick 
kbd_write(chan,buf,n)37453889Smckusick kbd_write(chan, buf, n)
37553889Smckusick 	int chan;
37653889Smckusick 	char *buf;
37753889Smckusick 	int n;
37853889Smckusick {
37953889Smckusick 
38053889Smckusick #ifdef news3800
38153889Smckusick 	*(char *)BEEP_FREQ = ~(n & 1);
38253889Smckusick 	*(char *)KEYBD_BEEP = 1;
38353889Smckusick 	return (n);
38453889Smckusick #endif
38553889Smckusick }
38653889Smckusick 
kbd_back(buf,len)38753889Smckusick kbd_back(buf, len)
38853889Smckusick 	char *buf;
38953889Smckusick 	int len;
39053889Smckusick {
39153889Smckusick 
39253889Smckusick 	msg_send(port_kbd_back, 0, buf, len, 0);
39353889Smckusick 	return (0);
39453889Smckusick }
39553889Smckusick 
kbd_nread()39653889Smckusick kbd_nread()
39753889Smckusick {
39853889Smckusick 
39953889Smckusick 	return (buffer_status(kbd_buf));
40053889Smckusick }
40153889Smckusick 
kbd_flush()40253889Smckusick kbd_flush()
40353889Smckusick {
40453889Smckusick 
40553889Smckusick 	buffer_flush(kbd_buf);
40653889Smckusick 	return (0);
40753889Smckusick }
40853889Smckusick 
40953889Smckusick #ifdef news3800
kb_intr()41053889Smckusick kb_intr()
41153889Smckusick {
41253889Smckusick 	char c;
41353889Smckusick 
41453889Smckusick 	if (port_kbd_intr > 0)
41553889Smckusick 		while (*(char *)KBMS_STAT & (1 << b_KBREADY)) {
41653889Smckusick 			c = *(char *)KEYBD_DATA;
41753889Smckusick 			msg_send(port_kbd_intr, 0, &c, sizeof (char), 0);
41853889Smckusick 		}
41953889Smckusick }
42053889Smckusick #endif /* news3800 */
42153889Smckusick 
kbd_bell(n,port)42253889Smckusick kbd_bell(n, port)
42353889Smckusick 	int n, port;
42453889Smckusick {
42553889Smckusick 
42653889Smckusick #ifdef news3800
42753889Smckusick 	(void) kbd_write(0, NULL, n);
42853889Smckusick #else
42953889Smckusick 	kbd_bell_scc(n, port);
43053889Smckusick #endif
43153889Smckusick 	return (0);
43253889Smckusick }
43353889Smckusick 
put_code(buf,cnt)43453889Smckusick put_code(buf, cnt)
43553889Smckusick 	char *buf;
43653889Smckusick 	int cnt;
43753889Smckusick {
43853889Smckusick 
43953889Smckusick 	put(kbd_buf, buf, cnt);
44053889Smckusick }
44153889Smckusick #endif /* IPC_MRX */
44253889Smckusick 
kbd_ioctl(chan,cmd,argp)44353889Smckusick kbd_ioctl(chan, cmd, argp)
44453889Smckusick 	int chan;
44553889Smckusick 	int cmd;
44653889Smckusick 	int *argp;
44753889Smckusick {
44853889Smckusick 	switch (cmd) {
44953889Smckusick 
45053889Smckusick 	case KIOCFLUSH:
45153889Smckusick 		return (kbd_flush());
45253889Smckusick 
45353889Smckusick 	case KIOCSETS:
45453889Smckusick 	case KIOCGETS:
45553889Smckusick 		return (kbd_string(cmd, (Pfk_string *)argp));
45653889Smckusick 
45753889Smckusick 	case KIOCBELL:
45853889Smckusick 		return (kbd_bell(*argp));
45953889Smckusick 
46053889Smckusick 	case KIOCBACK:
46153889Smckusick 		if (argp == NULL)
46253889Smckusick 			return (-1);
46353889Smckusick 		if ((int)((Key_string *)argp)->key_string == NULL)
46453889Smckusick 			return (-1);
46553889Smckusick 		if ((int)((Key_string *)argp)->key_length <= 0)
46653889Smckusick 			return (-1);
46753889Smckusick 		return (kbd_back(((Key_string *)argp)->key_string,
46853889Smckusick 		    ((Key_string *)argp)->key_length));
46953889Smckusick 
47053889Smckusick 	case KIOCREPT:
47153889Smckusick 		return (kbd_repeat(1));
47253889Smckusick 
47353889Smckusick 	case KIOCNRPT:
47453889Smckusick 		return (kbd_repeat(0));
47553889Smckusick 
47653889Smckusick 	case KIOCNREAD:
47753889Smckusick 		*argp = kbd_nread();
47853889Smckusick 		return (0);
47953889Smckusick 
48053889Smckusick 	case KIOCSETLOCK:
48153889Smckusick 		iscaps = *argp;
48253889Smckusick 		return (0);
48353889Smckusick 
48453889Smckusick 	case KIOCGETCNUM:
48553889Smckusick 		*argp = country;
48653889Smckusick 		return (0);
48753889Smckusick 
48853889Smckusick 	case KIOCSETCNUM:
48953889Smckusick 		country = *argp;
49053889Smckusick 		change_country = country;
49153889Smckusick 		return (0);
49253889Smckusick 
49353889Smckusick 	case KIOCDEFTBL:
49453889Smckusick 		key_table_addr = default_table;
49553889Smckusick 		country = K_JAPANESE_J;
49653889Smckusick 		return (0);
49753889Smckusick 
49853889Smckusick 	case KIOCCHTBL:
49953889Smckusick 		key_table_addr = (Key_table *)argp;
50053889Smckusick 		country = change_country;
50153889Smckusick 		return (0);
50253889Smckusick 
50353889Smckusick 	case KIOCGETSTAT:
50453889Smckusick 		*argp = kbd_status;
50553889Smckusick 		return (0);
50653889Smckusick 
50753889Smckusick 	case KIOCSETSTAT:
50853889Smckusick 		kbd_status = *argp;
50953889Smckusick 		return (0);
51053889Smckusick 
51153889Smckusick 	default:
51253889Smckusick 		return (-1);
51353889Smckusick 	}
51453889Smckusick }
51553889Smckusick 
kbd_bell_scc(n)51653889Smckusick kbd_bell_scc(n)
51753889Smckusick 	register int n;
51853889Smckusick {
51953889Smckusick 	register int i;
52053889Smckusick 	static char bell_data[] = {
52153889Smckusick 		0xf0, 0xf0, 0xf0, 0xf0, 0xf0, 0xf0, 0xf0, 0xf0,
52253889Smckusick 		0xf0, 0xf0, 0xf0, 0xf0, 0xf0, 0xf0, 0xf0, 0xf0,
52353889Smckusick 		0xf0, 0xf0, 0xf0, 0xf0, 0xf0, 0xf0, 0xf0, 0xf0,
52453889Smckusick 		0xf0, 0xf0, 0xf0, 0xf0, 0xf0, 0xf0, 0xf0, 0xf0
52553889Smckusick 	};
52653889Smckusick 
52753889Smckusick 	while (n > 0) {
52853889Smckusick 		i = min(n, sizeof (bell_data));
52953889Smckusick 		(void) kbd_write(0, bell_data, i);
53053889Smckusick 		n -= i;
53153889Smckusick 	}
53253889Smckusick }
53353889Smckusick 
53453889Smckusick #ifdef KBDEBUG
scc_error_puts(chan,buf)53553889Smckusick scc_error_puts(chan, buf)
53653889Smckusick 	int chan;
53753889Smckusick 	char *buf;
53853889Smckusick {
53953889Smckusick 	while (*buf) {
54053889Smckusick 		scc_error_write(chan, *buf++, 1);
54153889Smckusick 	}
54253889Smckusick }
54353889Smckusick 
scc_error_write_hex(chan,n,zs)54453889Smckusick scc_error_write_hex(chan, n, zs)
54553889Smckusick 	int chan;
54653889Smckusick 	unsigned int n;
54753889Smckusick 	int zs;
54853889Smckusick {
54953889Smckusick 	int i;
55053889Smckusick 	int tmp, al;
55153889Smckusick 	static char hex[] = "0123456789abcdef";
55253889Smckusick 
55353889Smckusick 	al = 0;
55453889Smckusick 
55553889Smckusick 	for (i = 28; i >= 0; i -= 4) {
55653889Smckusick 		tmp = (n >> i) & 0x0f;
55753889Smckusick 		if (tmp || al || !zs || !i) {
55853889Smckusick 			al++;
55953889Smckusick 			scc_error_write(chan, hex[tmp], 1);
56053889Smckusick 		}
56153889Smckusick 	}
56253889Smckusick }
56353889Smckusick #endif /* KBDEBUG */
564