153889Smckusick /* 253889Smckusick * Copyright (c) 1992 The Regents of the University of California. 353889Smckusick * 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*58606Sutashiro * @(#)kb_ctrl.c 7.3 (Berkeley) 03/09/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 6153889Smckusick kbd_open(chan) 6253889Smckusick int chan; 6353889Smckusick { 6453889Smckusick register int i; 6553889Smckusick 66*58606Sutashiro #if defined(news3400) 6753889Smckusick kbm_open(chan); 6853889Smckusick #endif 6953889Smckusick return (0); 7053889Smckusick } 7153889Smckusick 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 8353889Smckusick kbd_write(chan, buf, n) 8453889Smckusick int chan; 8553889Smckusick char *buf; 8653889Smckusick int n; 8753889Smckusick { 8853889Smckusick 89*58606Sutashiro #if defined(news3400) 9053889Smckusick return (kbm_write(SCC_KEYBOARD, buf, n)); 9153889Smckusick #endif 9253889Smckusick } 9353889Smckusick 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 11453889Smckusick kbd_flush() 11553889Smckusick { 11653889Smckusick 11753889Smckusick ndflush(&scode_buf, scode_buf.c_cc); 11853889Smckusick return (0); 11953889Smckusick } 12053889Smckusick 12153889Smckusick static 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 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 16253889Smckusick kbd_nread() 16353889Smckusick { 16453889Smckusick 16553889Smckusick return (scode_buf.c_cc); 16653889Smckusick } 16753889Smckusick 16853889Smckusick kbd_bell(n) 16953889Smckusick register int n; 17053889Smckusick { 17153889Smckusick 172*58606Sutashiro #if defined(news3400) 17353889Smckusick (void) kbm_write(SCC_KEYBOARD, NULL, n); 17453889Smckusick #endif 17553889Smckusick return (0); 17653889Smckusick } 17753889Smckusick 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 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 19853889Smckusick kb_softint() 19953889Smckusick { 20053889Smckusick int code; 20153889Smckusick extern int tty00_is_console; 20253889Smckusick 20353889Smckusick while ((code = xgetc(SCC_KEYBOARD)) >= 0) { 204*58606Sutashiro #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 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 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 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 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 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 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 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 39653889Smckusick kbd_nread() 39753889Smckusick { 39853889Smckusick 39953889Smckusick return (buffer_status(kbd_buf)); 40053889Smckusick } 40153889Smckusick 40253889Smckusick kbd_flush() 40353889Smckusick { 40453889Smckusick 40553889Smckusick buffer_flush(kbd_buf); 40653889Smckusick return (0); 40753889Smckusick } 40853889Smckusick 40953889Smckusick #ifdef news3800 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 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 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 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 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 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 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