Use balloc to extend Ifile.
[unix-history] / usr / src / sys / news3400 / bm / kb_ctrl.c
CommitLineData
af5295ff
KM
1/*
2 * Copyright (c) 1992 The Regents of the University of California.
3 * All rights reserved.
4 *
5 * This code is derived from software contributed to Berkeley by
6 * Sony Corp. and Kazumasa Utashiro of Software Research Associates, Inc.
7 *
8 * %sccs.include.redist.c%
9 *
10 * from: $Hdr: kb_ctrl.c,v 4.300 91/06/09 06:14:49 root Rel41 $ SONY
11 *
12 * @(#)kb_ctrl.c 7.1 (Berkeley) %G%
13 */
14
15/*
16 * Keyboard driver
17 */
18
19#include "../include/fix_machine_type.h"
20
21#ifdef IPC_MRX
22#include "../../h/ioctl.h"
23#include "../../iop/keyboard.h"
24#include "../../iop/kbreg.h"
25#else
26#include "ioctl.h"
27#include "param.h"
28#include "systm.h"
29#include "types.h"
30#include "../iop/keyboard.h"
31#include "../iop/kbreg.h"
32#endif
33
34extern int tmode;
35extern int kbd_status;
36
37int iscaps = 0;
38int change_country = K_JAPANESE_J;
39int country;
40
41extern Key_table default_table[];
42
43#ifdef CPU_SINGLE
44extern Key_table key_table[];
45Key_table *key_table_addr = key_table;
46#endif
47
48#ifdef CPU_DOUBLE
49Key_table *key_table_addr = default_table;
50#endif
51
52#ifdef CPU_SINGLE
53#include "ms.h"
54#include "clist.h"
55#include "ttydev.h"
56#include "tty.h"
57#include "../sio/scc.h"
58#include "time.h"
59#include "../iop/mouse.h"
60
61extern int cnrint();
62
63kbd_open(chan)
64 int chan;
65{
66 register int i;
67
68#ifdef news700
69 scc_open(chan);
70#endif
71#if defined(news1700) || defined(news1200) || defined(news3400)
72 kbm_open(chan);
73#endif
74 return (0);
75}
76
77kbd_read(chan, buf, n)
78 int chan;
79 char *buf;
80 int n;
81{
82#ifdef news700
83 register int i;
84
85 for (i = n; i > 0; i--)
86 *buf++ = scc_getc(chan);
87 return (n);
88#endif
89#if defined(news1700) || defined(news1200)
90
91 return (kbd_read_raw(chan, buf, n));
92#endif
93}
94
95kbd_write(chan, buf, n)
96 int chan;
97 char *buf;
98 int n;
99{
100#ifdef news700
101 register int i;
102
103 for (i = 0; i < n; i++) {
104 scc_putc(SCC_KEYBOARD, *buf++);
105#ifndef NO_PRE_EMPT
106 if (i % 4 == 0) PRE_EMPT;
107#endif
108 }
109 return (n);
110#endif /* news700 */
111#if defined(news1700) || defined(news1200) || defined(news3400)
112
113 return (kbm_write(SCC_KEYBOARD, buf, n));
114#endif
115}
116
117kbd_back(buf, len)
118 register char *buf;
119 register int len;
120{
121 int s;
122
123 while (--len >= 0) {
124 s = spltty();
125 cnrint(*buf++);
126 (void) splx(s);
127 }
128 return (0);
129}
130
131#define KBPRI (PZERO+1)
132
133struct clist scode_buf;
134struct clist keyboard_buf;
135char kb_rwait;
136
137kbd_flush()
138{
139
140 ndflush(&scode_buf, scode_buf.c_cc);
141 return (0);
142}
143
144static
145kbd_put_raw(scode)
146 int scode;
147{
148 extern char kb_busy;
149
150 if (kb_busy) {
151 if (scode_buf.c_cc < CBSIZE)
152 putc(scode, &scode_buf);
153 if (kb_rwait) {
154 kb_rwait = 0;
155 wakeup((caddr_t)&kb_rwait);
156 }
157 }
158 return (scode);
159
160}
161
162kbd_read_raw(chan, buf, count)
163 int chan;
164 char *buf;
165 register int count;
166{
167 register int i;
168 register int n;
169 register int s;
170
171 if (count <= 0)
172 return (count);
173 s = splscc();
174 while ((n = min(scode_buf.c_cc, count)) == 0) {
175 kb_rwait = 1;
176 sleep((caddr_t)&kb_rwait, KBPRI);
177 kb_rwait = 0;
178 }
179 (void) splx(s);
180 for (i = n; i > 0 ; i--)
181 *buf++ = getc(&scode_buf);
182 return (n);
183}
184
185kbd_nread()
186{
187
188 return (scode_buf.c_cc);
189}
190
191kbd_bell(n)
192 register int n;
193{
194
195#if defined(news1700) || defined(news1200) || defined(news3400)
196 (void) kbm_write(SCC_KEYBOARD, NULL, n);
197#endif
198#ifdef news700
199 kbd_bell_scc(n);
200#endif
201 return (0);
202}
203
204kbd_putcode(code)
205 int code;
206{
207 int c;
208
209 kbd_put_raw(code);
210 kbd_encode(code);
211 while ((c = getc(&keyboard_buf)) != -1)
212 cnrint(c);
213}
214
215put_code(buf, cnt)
216 register char *buf;
217 register int cnt;
218{
219
220 while (--cnt >= 0)
221 putc(*buf++, &keyboard_buf);
222}
223
224kb_softint()
225{
226 int code;
227 extern int tty00_is_console;
228
229 while ((code = xgetc(SCC_KEYBOARD)) >= 0) {
230#if defined(news1200) || defined(news3200) /* BEGIN reiko */
231 if ((code & 0x7f) == KEY_EISUU) {
232 int up = code & OFF;
233 static int kana = 0;
234
235 if (kana) {
236 if (up) {
237 kana = 0;
238 }
239 } else {
240 if (up) {
241 code = KEY_KANA | OFF;
242 kana = 1;
243 } else {
244 code = KEY_KANA;
245 }
246 }
247 }
248#endif
249
250#ifdef NOTDEF /* KU:XXX */
251 if (!tty00_is_console)
252#endif
253 rst_dimmer_cnt();
254#if NMS > 0
255 if (!mskeytrigger(0, code & OFF, code & 0x7f))
256#endif
257 kbd_putcode(code);
258 }
259}
260#endif /* CPU_SINGLE */
261
262#ifdef IPC_MRX
263#include "mrx.h"
264#include "queue.h"
265#include "process.h"
266#include "buffer.h"
267#include "port.h"
268#include "message.h"
269#include "machdep.h"
270#include "malloc.h"
271#include "config.h"
272#include "kbms.h"
273
274#ifdef news1800
275#include "scc.h"
276#endif
277
278static struct buffer *kbd_buf;
279static int port_kbd_intr;
280static int port_kbd_back;
281static int port_kbd_ctrl;
282
283keyboard(chan)
284 int chan;
285{
286 int kbd_ctrl(), kbd_output();
287 int kbd_read(), kbd_ioctl(), kbd_io();
288
289#ifdef news3800
290 extern int (*Xkb_intr)();
291 int kb_intr();
292
293 Xkb_intr = kb_intr;
294#endif
295
296#ifdef news1800
297 int scc_input(), scc_output();
298
299 if (scc_open(SCC_KEYBOARD) < 0)
300 return;
301 proc_create("scc_kbread", scc_input, 601, 512, SCC_KEYBOARD);
302 proc_create("scc_kbwrite", scc_output, 601, 512, SCC_KEYBOARD);
303 while (scc_std_ports[SCC_KEYBOARD][0] == 0)
304 proc_sleep_self(100);
305#endif
306 kb_ioctl = kbd_ioctl;
307 kb_read = kbd_read;
308 kbd_init();
309 proc_create("kbd_ctrl", kbd_ctrl, 300, DEFAULT_STACK_SIZE, 0);
310 proc_create("kbd_output", kbd_output, 300, DEFAULT_STACK_SIZE, 0);
311 proc_create("kbd_io", kbd_io, 300, DEFAULT_STACK_SIZE, 0);
312}
313
314int (*reset_dimmer)();
315
316kbd_ctrl()
317{
318 register int m, n;
319 register int select;
320 int *len, from, count;
321 char *addr;
322 int ports[3];
323 static char buf[16];
324
325 ports[0] = port_kbd_intr = port_create("kb_intr");
326 ports[1] = port_kbd_back = port_create("kb_echoback");
327 ports[2] = port_kbd_ctrl = STDPORT;
328
329#ifdef news3800
330 *(char *)KEYBD_RESET = 0;
331 *(char *)KEYBD_INTE = 1;
332#endif
333#ifdef news1800
334 count = 1;
335 msg_send(scc_std_ports[SCC_KEYBOARD][0], ports[0],
336 &count, sizeof (count), 0);
337#endif
338
339 kbd_buf = buffer_alloc(32);
340 (void) spl0();
341 for (;;) {
342 if (buffer_status(kbd_buf) > 0)
343 m = 3;
344 else
345 m = 2;
346 if ((select = msg_select(m, ports)) == 0) {
347 msg_recv(ports[0], NULL, &addr, &count, 0);
348 if (reset_dimmer)
349 (*reset_dimmer)();
350 while (--count >= 0) {
351 if (send_mouse == 0 || (*send_mouse)(*addr) == 0)
352 kbd_encode(*addr);
353 addr++;
354 }
355#ifdef news1800
356 count = 1;
357 msg_send(scc_std_ports[SCC_KEYBOARD][0], ports[select],
358 &count, sizeof (count), 0);
359#endif
360 } else if (select == 1) { /* ESC [ 6 n */
361 msg_recv(ports[select], NULL, &addr, &count, 0);
362 put(kbd_buf, addr, count);
363 } else {
364 msg_recv(ports[select], &from, &len, NULL, 0);
365 n = buffer_status(kbd_buf);
366 n = min(n, *len);
367 n = get(kbd_buf, buf, min(n, sizeof (buf)));
368 msg_send(from, ports[select], buf, n, 0);
369 }
370 }
371}
372
373kbd_output()
374{
375 char *addr;
376 int from, len;
377#ifdef news1800
378 register int subport;
379
380 subport = port_create("port_kbd_write");
381#endif
382
383 (void) spl0();
384 for (;;) {
385 msg_recv(STDPORT, &from, &addr, &len, 0);
386#ifdef news3800
387 len = kbd_write(0, addr, len);
388#endif
389#ifdef news1800
390 len = kbd_write(subport, addr, len);
391#endif
392 msg_send(from, STDPORT, &len, sizeof(len), 0);
393 }
394}
395
396kbd_io()
397{
398 struct kb_ctrl_req *req;
399 int from, reply;
400#ifdef news1800
401 register int sub_port;
402
403 sub_port = port_create("port_kbd_sub");
404#endif
405
406 (void) spl0();
407 for (;;) {
408 msg_recv(STDPORT, &from, &req, NULL, 0);
409 if (req->kb_func == KIOCCHTBL || req->kb_func == KIOCOYATBL)
410 kbd_ioctl(0, req->kb_func, req->kb_arg);
411 else
412#ifdef news1800
413 kbd_ioctl(sub_port, req->kb_func, &req->kb_arg);
414#else
415 kbd_ioctl(0, req->kb_func, &req->kb_arg);
416#endif
417 reply = req->kb_arg;
418 msg_send(from, STDPORT, &reply, sizeof(reply), 0);
419 }
420}
421
422kbd_read(chan, buf, n)
423 int chan;
424 char *buf;
425 int n;
426{
427 static int port;
428 char *addr;
429 int len;
430
431 if (port == 0)
432 port = port_create("port_kbd_read");
433 if (n <= 0)
434 return (0);
435 msg_send(port_kbd_ctrl, port, &n, sizeof (n), 0);
436 msg_recv(port, NULL, &addr, &len, 0);
437 bcopy(addr, buf, len);
438 msg_free(port);
439 return (len);
440}
441
442kbd_write(chan, buf, n)
443 int chan;
444 char *buf;
445 int n;
446{
447#ifdef news1800
448 return (scc_write(chan, SCC_KEYBOARD, buf, n));
449#endif
450
451#ifdef news3800
452 *(char *)BEEP_FREQ = ~(n & 1);
453 *(char *)KEYBD_BEEP = 1;
454 return (n);
455#endif
456}
457
458kbd_back(buf, len)
459 char *buf;
460 int len;
461{
462
463 msg_send(port_kbd_back, 0, buf, len, 0);
464 return (0);
465}
466
467kbd_nread()
468{
469
470 return (buffer_status(kbd_buf));
471}
472
473kbd_flush()
474{
475
476 buffer_flush(kbd_buf);
477 return (0);
478}
479
480#ifdef news3800
481kb_intr()
482{
483 char c;
484
485 if (port_kbd_intr > 0)
486 while (*(char *)KBMS_STAT & (1 << b_KBREADY)) {
487 c = *(char *)KEYBD_DATA;
488 msg_send(port_kbd_intr, 0, &c, sizeof (char), 0);
489 }
490}
491#endif /* news3800 */
492
493kbd_bell(n, port)
494 int n, port;
495{
496
497#ifdef news3800
498 (void) kbd_write(0, NULL, n);
499#else
500 kbd_bell_scc(n, port);
501#endif
502 return (0);
503}
504
505put_code(buf, cnt)
506 char *buf;
507 int cnt;
508{
509
510 put(kbd_buf, buf, cnt);
511}
512#endif /* IPC_MRX */
513
514kbd_ioctl(chan, cmd, argp)
515 int chan;
516 int cmd;
517 int *argp;
518{
519 switch (cmd) {
520
521 case KIOCFLUSH:
522 return (kbd_flush());
523
524 case KIOCSETS:
525 case KIOCGETS:
526 return (kbd_string(cmd, (Pfk_string *)argp));
527
528 case KIOCBELL:
529#ifdef news1800
530 return (kbd_bell(*argp, chan));
531#else
532 return (kbd_bell(*argp));
533#endif
534
535 case KIOCBACK:
536 if (argp == NULL)
537 return (-1);
538 if ((int)((Key_string *)argp)->key_string == NULL)
539 return (-1);
540 if ((int)((Key_string *)argp)->key_length <= 0)
541 return (-1);
542 return (kbd_back(((Key_string *)argp)->key_string,
543 ((Key_string *)argp)->key_length));
544
545 case KIOCREPT:
546 return (kbd_repeat(1));
547
548 case KIOCNRPT:
549 return (kbd_repeat(0));
550
551 case KIOCNREAD:
552 *argp = kbd_nread();
553 return (0);
554
555 case KIOCSETLOCK:
556 iscaps = *argp;
557 return (0);
558
559 case KIOCGETCNUM:
560 *argp = country;
561 return (0);
562
563 case KIOCSETCNUM:
564 country = *argp;
565 change_country = country;
566 return (0);
567
568 case KIOCDEFTBL:
569 key_table_addr = default_table;
570 country = K_JAPANESE_J;
571 return (0);
572
573 case KIOCCHTBL:
574 key_table_addr = (Key_table *)argp;
575 country = change_country;
576 return (0);
577
578 case KIOCGETSTAT:
579 *argp = kbd_status;
580 return (0);
581
582 case KIOCSETSTAT:
583 kbd_status = *argp;
584 return (0);
585
586 default:
587 return (-1);
588 }
589}
590
591#ifdef news1800
592kbd_bell_scc(n, port)
593 register int n, port;
594#else
595kbd_bell_scc(n)
596 register int n;
597#endif
598{
599 register int i;
600 static char bell_data[] = {
601 0xf0, 0xf0, 0xf0, 0xf0, 0xf0, 0xf0, 0xf0, 0xf0,
602 0xf0, 0xf0, 0xf0, 0xf0, 0xf0, 0xf0, 0xf0, 0xf0,
603 0xf0, 0xf0, 0xf0, 0xf0, 0xf0, 0xf0, 0xf0, 0xf0,
604 0xf0, 0xf0, 0xf0, 0xf0, 0xf0, 0xf0, 0xf0, 0xf0
605 };
606
607 while (n > 0) {
608 i = min(n, sizeof (bell_data));
609#ifdef news1800
610 (void) kbd_write(port, bell_data, i);
611#else
612 (void) kbd_write(0, bell_data, i);
613#endif
614 n -= i;
615 }
616}
617
618#ifdef KBDEBUG
619scc_error_puts(chan, buf)
620 int chan;
621 char *buf;
622{
623 while (*buf) {
624 scc_error_write(chan, *buf++, 1);
625 }
626}
627
628scc_error_write_hex(chan, n, zs)
629 int chan;
630 unsigned int n;
631 int zs;
632{
633 int i;
634 int tmp, al;
635 static char hex[] = "0123456789abcdef";
636
637 al = 0;
638
639 for (i = 28; i >= 0; i -= 4) {
640 tmp = (n >> i) & 0x0f;
641 if (tmp || al || !zs || !i) {
642 al++;
643 scc_error_write(chan, hex[tmp], 1);
644 }
645 }
646}
647#endif /* KBDEBUG */