Clean (void) casts from usr.sbin
[dragonfly.git] / usr.sbin / pcvt / kbdio / kbdio.y
1 /* Hello emacs, this should be edited in -*- Fundamental -*- mode */
2 %{
3 /*
4  * Copyright (c) 1994 Joerg Wunsch
5  *
6  * All rights reserved.
7  *
8  * This program is free software.
9  *
10  * Redistribution and use in source and binary forms, with or without
11  * modification, are permitted provided that the following conditions
12  * are met:
13  * 1. Redistributions of source code must retain the above copyright
14  *    notice, this list of conditions and the following disclaimer.
15  * 2. Redistributions in binary form must reproduce the above copyright
16  *    notice, this list of conditions and the following disclaimer in the
17  *    documentation and/or other materials provided with the distribution.
18  * 3. All advertising materials mentioning features or use of this software
19  *    must display the following acknowledgement:
20  *      This product includes software developed by Joerg Wunsch
21  * 4. The name of the developer may not be used to endorse or promote
22  *    products derived from this software without specific prior written
23  *    permission.
24  *
25  * THIS SOFTWARE IS PROVIDED BY THE DEVELOPERS ``AS IS'' AND ANY EXPRESS OR
26  * IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES
27  * OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED.
28  * IN NO EVENT SHALL THE DEVELOPERS BE LIABLE FOR ANY DIRECT, INDIRECT,
29  * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT
30  * NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
31  * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
32  * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
33  * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF
34  * THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
35  */
36
37 #ident "$FreeBSD: src/usr.sbin/pcvt/kbdio/kbdio.y,v 1.6 1999/09/06 07:39:30 peter Exp $"
38 #ident "$DragonFly: src/usr.sbin/pcvt/kbdio/Attic/kbdio.y,v 1.3 2004/12/18 22:48:04 swildner Exp $"
39
40 /*
41  * $Log: kbdio.y,v $
42  * Revision 1.2  1994/09/18  19:49:22  j
43  * Refined expr handling; can now set/clear bits.
44  *
45  * Revision 1.1  1994/09/18  12:57:13  j
46  * Initial revision
47  *
48  *
49  */
50
51 #include <stdio.h>
52 #include <stdlib.h>
53 #include <math.h>
54 #include <sys/fcntl.h>
55 #include <machine/cpufunc.h>
56 #include <machine/pcvt_ioctl.h>
57
58 #ifdef __NetBSD__
59 #include <machine/pio.h>
60 #endif
61
62 #define KBD_DELAY \
63         { u_char x = inb(0x84); } \
64         { u_char x = inb(0x84); } \
65         { u_char x = inb(0x84); } \
66         { u_char x = inb(0x84); } \
67         { u_char x = inb(0x84); } \
68         { u_char x = inb(0x84); }
69
70 #define YYDEBUG 1
71
72 void yyerror(const char *msg);
73
74 static  void help(int), status(void), data(int), kbd(int), cmdbyte(int),
75         kbc(int), whatMCA(void);
76 static  int kbget(void);
77 %}
78
79 %union {
80         int num;
81 }
82
83 %token          NEWLINE
84 %token          ALL CMD DATA DEFAULTS ECHOC ENABLE EXPR HELP ID LED
85 %token          MAKE ONLY RELEASE RESEND RESET SCAN STATUS TYPEMATIC
86 %token          WHAT
87 %token  <num>   NUM
88
89 %type   <num>   expr opr
90
91 %%
92
93 interpret:      lines ;
94
95 lines:          line
96                 | lines line
97                 ;
98
99 line:           statements NEWLINE
100                 | NEWLINE
101                 | error NEWLINE         { fprintf(stderr, "bing!\n"); }
102                 ;
103
104 statements:     statement
105                 | statements ';' statement
106                 ;
107
108 statement:      '?'                     { help(0); }
109                 | HELP                  { help(0); }
110                 | HELP EXPR             { help(1); }
111                 | STATUS '?'            { status(); }
112                 | WHAT '?'              { whatMCA(); }
113                 | DATA '?'              { data(kbget()); }
114                 | LED '=' NUM           { kbd(0xed); kbd($3); }
115                 | ECHOC                 { kbd(0xee); kbget(); }
116                 | SCAN '=' NUM          { kbd(0xf0); kbd($3);
117                                           if($3 == 0) data(kbget()); }
118                 | SCAN '?'              { kbd(0xf0); kbd(0); data(kbget()); }
119                 | ID '?'                { kbd(0xf2); data(kbget());
120                                           data(kbget()); }
121                 | TYPEMATIC '=' NUM ',' NUM
122                                         { kbd(0xf3);
123                                           if($3 > 1000) $3 = 1000;
124                                           if($5 > 30) $5 = 30;
125                                           if($5 < 2) $5 = 2;
126                                           kbd(
127                                               (int)
128                                                 (8.0 * log(30.0 / (double)$5)
129                                                  / log(2))
130                                               | ((($3 / 250) - 1) * 32)
131                                              );
132                                         }
133                 | ENABLE                { kbd(0xf4); }
134                 | DEFAULTS              { kbd(0xf6); }
135                 | ALL TYPEMATIC         { kbd(0xf7); }
136                 | ALL MAKE RELEASE      { kbd(0xf8); }
137                 | ALL MAKE ONLY         { kbd(0xf9); }
138                 | ALL TYPEMATIC MAKE RELEASE
139                                         { kbd(0xfa); }
140                 | NUM TYPEMATIC         { kbd(0xfb); kbd($1); }
141                 | NUM MAKE RELEASE      { kbd(0xfc); kbd($1); }
142                 | NUM MAKE ONLY         { kbd(0xfd); kbd($1); }
143                 | RESEND                { kbd(0xfe); }
144                 | RESET                 { kbd(0xff); }
145                 | CMD '?'               { kbc(0x20); cmdbyte(kbget()); }
146                 | CMD '=' expr          { kbc(0x60); kbd($3); }
147                 | /* lambda */
148                 ;
149
150 expr:           opr                     { $$ = $1; }
151                 | expr '+' opr          { $$ = $1 | $3; }
152                 | expr '-' opr          { $$ = $1 & ~($3); }
153                 ;
154
155 opr:            NUM                     { $$ = $1; }
156                 | CMD                   { kbc(0x20); $$ = kbget(); }
157                 ;
158
159 %%
160
161 static void
162 help(int topic) {
163         switch(topic) {
164         case 0:
165         printf(
166         "Input consists of lines, containing one or more semicolon-separated\n"
167         "statements. Numbers are implicitly hexadecimal, append a dot for\n"
168         "decimal numbers. Valid statements include:\n"
169         "help [expr];           give help [to expression syntax]\n"
170         "status ?               interpret kbd ctrl status byte\n"
171         "what ?                 check for MCA type 1 or 2 motherboard controller\n"
172         "data ?                 get one byte of data\n"
173         "led = NUM              set kbd LEDs\n"
174         "echo = NUM             echo byte to kbd\n"
175         "scan = NUM; scan ?     set scan code set; return current set\n"
176         "id ?                   get two id bytes\n"
177         "typematic=delay,rate   set typematic delay(ms)&rate(1/s)\n"
178         "enable; defaults       enable kbd; back to defaults\n"
179         "all typematic          make all keys typematic\n"
180         "all make release       make all keys sending make/release\n"
181         "all make only          make all keys sending make only\n"
182         "all typematic make release     make all keys typematic & make/release\n"
183         "NUM typematic          make specific key typematic\n"
184         "NUM make release       make specific key sending make/release\n"
185         "NUM make only          make specific key sending make only\n"
186         "resend; reset          resend last byte from kbd; reset kbd\n"
187         "cmd ?                  fetch kbd ctrl command byte\n"
188         "cmd = expr             set kbd ctrl command byte\n"
189         "\n");
190         break;
191
192         case 1:
193         printf(
194         "Expressions can either consist of a number, possibly followed\n"
195         "by a + or - sign and bit values in numeric or symbolic form.\n"
196         "Symbolic bit values are:\n"
197         "SCCONV IGNPAR CLKLOW OVRINH TEST IRQ\n"
198         "\n");
199         break;
200         }
201 }
202
203 static void
204 status(void) {
205         int c = inb(0x64);
206         if(c&0x80) printf("parity error | ");
207         if(c&0x40) printf("rx timeout | ");
208         if(c&0x20) printf("tx timeout | ");
209         if(c&0x10) printf("kbd released ");
210         else       printf("kbd locked   ");
211         if(c&0x08) printf("| cmd last sent  ");
212         else       printf("| data last sent ");
213         if(c&0x04) printf("| power-on ");
214         else       printf("| test ok  ");
215         if(c&0x02) printf("| ctrl write busy ");
216         else       printf("| ctrl write ok   ");
217         if(c&0x01) printf("| ctrl read ok\n");
218         else       printf("| ctrl read empty\n");
219 }
220
221 /* see: Frank van Gilluwe, "The Undocumented PC", Addison Wesley 1994, pp 273 */
222
223 static void
224 whatMCA(void) {
225         int new, sav;
226         kbc(0x20);              /* get command byte */
227         sav = kbget();          /* sav = command byte */
228         kbc(0x60);              /* set command byte */
229         kbd(sav | 0x40);        /* set keyboard xlate bit */
230         kbc(0x20);              /* get keyboard command */
231         new = kbget();          /* new = command byte */
232         kbc(0x60);              /* set command byte */
233         kbd(sav);               /* restore command byte */
234         if(new & 0xbf)
235                 printf("Hmm - looks like MCA type 1 motherboard controller\n");
236         else
237                 printf("Hmm - looks like MCA type 2 motherboard controller\n");
238 }
239
240 static void
241 kbd(int d) {
242         int i = 100000;
243         while(i && (inb(0x64) & 2)) i--;
244         if(i == 0) { printf("kbd write: timed out\n"); return; }
245         outb(0x60, d);
246 }
247
248 static void
249 kbc(int d) {
250         int i = 100000;
251         while(i && (inb(0x64) & 2)) i--;
252         if(i == 0) { printf("ctrl write: timed out\n"); return; }
253         outb(0x64, d);
254 }
255
256 static int
257 kbget(void) {
258         int i, c;
259         for(;;) {
260                 i = 10000;
261                 while(i && (inb(0x64) & 1) == 0) i--;
262                 if(i == 0) { printf("data read: timed out\n"); return -1; }
263                 KBD_DELAY
264                 c = (unsigned char)inb(0x60);
265                 switch(c) {
266                         case 0: case 0xff:
267                                 printf("got kbd overrun\n"); break;
268                         case 0xaa:
269                                 printf("got self-test OK\n"); break;
270                         case 0xee:
271                                 printf("got ECHO byte\n"); break;
272                         case 0xfa:
273                                 printf("got ACK\n"); break;
274                         case 0xfc:
275                                 printf("got self-test FAIL\n"); break;
276                         case 0xfd:
277                                 printf("got internal failure\n"); break;
278                         case 0xfe:
279                                 printf("got RESEND request\n"); break;
280                         default:
281                                 goto done;
282                 }
283         }
284 done:
285         return c;
286 }
287
288 static void
289 cmdbyte(int d) {
290         if(d&0x40) printf("scan conv ");
291         else       printf("pass thru ");
292         if(d&0x20) printf("| ign parity   ");
293         else       printf("| check parity ");
294         if(d&0x10) printf("| kbd clk low ");
295         else       printf("| enable kbd  ");
296         if(d&0x08) printf("| override kbd inh ");
297         if(d&0x04) printf("| test ok  ");
298         else       printf("| power-on ");
299         if(d&0x01) printf("| irq 1 enable\n");
300         else       printf("| no irq\n");
301 }
302
303 static void
304 data(int d) {
305         if(d < 0) return;
306         printf("data: 0x%02x\n", d);
307 }
308
309 void yyerror(const char *msg) {
310         fprintf(stderr, "yyerror: %s\n", msg);
311 }
312
313 int main(int argc, char **argv) {
314         int fd;
315
316         if(argc > 1) yydebug = 1;
317
318         if((fd = open("/dev/console", O_RDONLY)) < 0)
319                 fd = 0;
320
321         if(ioctl(fd, KDENABIO, 0) < 0) {
322                 perror("ioctl(KDENABIO)");
323                 return 1;
324         }
325         yyparse();
326
327         ioctl(fd, KDDISABIO, 0);
328         return 0;
329 }
330