diff options
Diffstat (limited to 'usr.sbin/pcvt/kbdio/kbdio.y')
-rw-r--r-- | usr.sbin/pcvt/kbdio/kbdio.y | 298 |
1 files changed, 298 insertions, 0 deletions
diff --git a/usr.sbin/pcvt/kbdio/kbdio.y b/usr.sbin/pcvt/kbdio/kbdio.y new file mode 100644 index 0000000..ea9a55f --- /dev/null +++ b/usr.sbin/pcvt/kbdio/kbdio.y @@ -0,0 +1,298 @@ +/* Hello emacs, this should be edited in -*- Fundamental -*- mode */ +%{ +/* + * Copyright (c) 1994 Joerg Wunsch + * + * All rights reserved. + * + * This program is free software. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * 1. Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * 2. Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in the + * documentation and/or other materials provided with the distribution. + * 3. All advertising materials mentioning features or use of this software + * must display the following acknowledgement: + * This product includes software developed by Joerg Wunsch + * 4. The name of the developer may not be used to endorse or promote + * products derived from this software without specific prior written + * permission. + * + * THIS SOFTWARE IS PROVIDED BY THE DEVELOPERS ``AS IS'' AND ANY EXPRESS OR + * IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES + * OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. + * IN NO EVENT SHALL THE DEVELOPERS BE LIABLE FOR ANY DIRECT, INDIRECT, + * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT + * NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, + * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY + * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT + * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF + * THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. + */ + +#ident "$Header: /home/joerg/src/kbdio/RCS/kbdio.y,v 1.2 1994/09/18 19:49:22 j Exp $" + +/* + * $Log: kbdio.y,v $ + * Revision 1.2 1994/09/18 19:49:22 j + * Refined expr handling; can now set/clear bits. + * + * Revision 1.1 1994/09/18 12:57:13 j + * Initial revision + * + * + */ + +#include <stdio.h> +#include <stdlib.h> +#include <math.h> +#include <sys/fcntl.h> +#include <machine/cpufunc.h> +#include <machine/pcvt_ioctl.h> + +#ifdef __NetBSD__ +#include <machine/pio.h> +#endif + +#define YYDEBUG 1 + +void yyerror(const char *msg); + +static void help(int), status(void), data(int), kbd(int), cmdbyte(int), + kbc(int); +static int kbget(void); +%} + +%union { + int num; +} + +%token NEWLINE +%token ALL CMD DATA DEFAULTS ECHOC ENABLE EXPR HELP ID LED +%token MAKE ONLY RELEASE RESEND RESET SCAN STATUS TYPEMATIC +%token <num> NUM + +%type <num> expr opr + +%% + +interpret: lines ; + +lines: line + | lines line + ; + +line: statements NEWLINE + | NEWLINE + | error NEWLINE { fprintf(stderr, "bing!\n"); } + ; + +statements: statement + | statements ';' statement + ; + +statement: '?' { help(0); } + | HELP { help(0); } + | HELP EXPR { help(1); } + | STATUS '?' { status(); } + | DATA '?' { data(kbget()); } + | LED '=' NUM { kbd(0xed); kbd($3); } + | ECHOC { kbd(0xee); kbget(); } + | SCAN '=' NUM { kbd(0xf0); kbd($3); + if($3 == 0) data(kbget()); } + | SCAN '?' { kbd(0xf0); kbd(0); data(kbget()); } + | ID '?' { kbd(0xf2); data(kbget()); + data(kbget()); } + | TYPEMATIC '=' NUM ',' NUM + { kbd(0xf3); + if($3 > 1000) $3 = 1000; + if($5 > 30) $5 = 30; + if($5 < 2) $5 = 2; + kbd( + (int) + (8.0 * log(30.0 / (double)$5) + / log(2)) + | ((($3 / 250) - 1) * 32) + ); + } + | ENABLE { kbd(0xf4); } + | DEFAULTS { kbd(0xf6); } + | ALL TYPEMATIC { kbd(0xf7); } + | ALL MAKE RELEASE { kbd(0xf8); } + | ALL MAKE ONLY { kbd(0xf9); } + | ALL TYPEMATIC MAKE RELEASE + { kbd(0xfa); } + | NUM TYPEMATIC { kbd(0xfb); kbd($1); } + | NUM MAKE RELEASE { kbd(0xfc); kbd($1); } + | NUM MAKE ONLY { kbd(0xfd); kbd($1); } + | RESEND { kbd(0xfe); } + | RESET { kbd(0xff); } + | CMD '?' { kbc(0x20); cmdbyte(kbget()); } + | CMD '=' expr { kbc(0x60); kbd($3); } + | /* lambda */ + ; + +expr: opr { $$ = $1; } + | expr '+' opr { $$ = $1 | $3; } + | expr '-' opr { $$ = $1 & ~($3); } + ; + +opr: NUM { $$ = $1; } + | CMD { kbc(0x20); $$ = kbget(); } + ; + +%% + +static void +help(int topic) { + switch(topic) { + case 0: + printf( + "Input consists of lines, containing one or more semicolon-separated\n" + "statements. Numbers are implicitly hexadecimal, append a dot for\n" + "decimal numbers. Valid statements include:\n" + "help [expr]; give help [to expression syntax]\n" + "status ? interpret kbd ctrl status byte\n" + "data ? get one byte of data\n" + "led = NUM set kbd LEDs\n" + "echo = NUM echo byte to kbd\n" + "scan = NUM; scan ? set scan code set; return current set\n" + "id ? get two id bytes\n" + "typematic=delay,rate set typematic delay(ms)&rate(1/s)\n" + "enable; defaults enable kbd; back to defaults\n" + "all typematic make all keys typematic\n" + "all make release make all keys sending make/release\n" + "all make only make all keys sending make only\n" + "all typematic make release make all keys typematic & make/release\n" + "NUM typematic make specific key typematic\n" + "NUM make release make specific key sending make/release\n" + "NUM make only make specific key sending make only\n" + "resend; reset resend last byte from kbd; reset kbd\n" + "cmd ? fetch kbd ctrl command byte\n" + "cmd = expr set kbd ctrl command byte\n" + "\n"); + break; + + case 1: + printf( + "Expressions can either consist of a number, possibly followed\n" + "by a + or - sign and bit values in numeric or symbolic form.\n" + "Symbolic bit values are:\n" + "SCCONV IGNPAR CLKLOW OVRINH TEST IRQ\n" + "\n"); + break; + } +} + +static void +status(void) { + int c = inb(0x64); + if(c&0x80) printf("parity error | "); + if(c&0x40) printf("rx timeout | "); + if(c&0x20) printf("tx timeout | "); + if(c&0x10) printf("kbd released "); + else printf("kbd locked "); + if(c&0x08) printf("| cmd last sent "); + else printf("| data last sent "); + if(c&0x04) printf("| power-on "); + else printf("| test ok "); + if(c&0x02) printf("| ctrl write busy "); + else printf("| ctrl write ok "); + if(c&0x01) printf("| ctrl read ok\n"); + else printf("| ctrl read empty\n"); +} + +static void +kbd(int d) { + int i = 100000; + while(i && (inb(0x64) & 2)) i--; + if(i == 0) { printf("kbd write: timed out\n"); return; } + outb(0x60, d); +} + +static void +kbc(int d) { + int i = 100000; + while(i && (inb(0x64) & 2)) i--; + if(i == 0) { printf("ctrl write: timed out\n"); return; } + outb(0x64, d); +} + +static int +kbget(void) { + int i, c; + for(;;) { + i = 10000; + while(i && (inb(0x64) & 1) == 0) i--; + if(i == 0) { printf("data read: timed out\n"); return -1; } + c = (unsigned char)inb(0x60); + switch(c) { + case 0: case 0xff: + printf("got kbd overrun\n"); break; + case 0xaa: + printf("got self-test OK\n"); break; + case 0xee: + printf("got ECHO byte\n"); break; + case 0xfa: + printf("got ACK\n"); break; + case 0xfc: + printf("got self-test FAIL\n"); break; + case 0xfd: + printf("got internal failure\n"); break; + case 0xfe: + printf("got RESEND request\n"); break; + default: + goto done; + } + } +done: + return c; +} + +static void +cmdbyte(int d) { + if(d&0x40) printf("scan conv "); + else printf("pass thru "); + if(d&0x20) printf("| ign parity "); + else printf("| check parity "); + if(d&0x10) printf("| kbd clk low "); + else printf("| enable kbd "); + if(d&0x08) printf("| override kbd inh "); + if(d&0x04) printf("| test ok "); + else printf("| power-on "); + if(d&0x01) printf("| irq 1 enable\n"); + else printf("| no irq\n"); +} + +static void +data(int d) { + if(d < 0) return; + printf("data: 0x%02x\n", d); +} + +void yyerror(const char *msg) { + fprintf(stderr, "yyerror: %s\n", msg); +} + +int main(int argc, char **argv) { + int fd; + + if(argc > 1) yydebug = 1; + + if((fd = open("/dev/console", O_RDONLY)) < 0) + fd = 0; + + if(ioctl(fd, KDENABIO, 0) < 0) { + perror("ioctl(KDENABIO)"); + return 1; + } + yyparse(); + + (void)ioctl(fd, KDDISABIO, 0); + return 0; +} + |