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