jtc d9789d4225 Overlay our pcvt with pcvt 3.32 sources. All of our fixes have been
incorporated into the master sources, so it is unnecessary to resolve
all the conflicts that would occur if we let CVS "merge" the versions.
1995-10-07 21:43:25 +00:00

345 lines
8.9 KiB
Plaintext

/* Hello emacs, this should be edited in -*- Fundamental -*- mode */
%{
/*
* Copyright (c) 1994,1995 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: /cvsroot/src/sys/arch/i386/isa/pcvt/Util/kbdio/Attic/kbdio.y,v 1.2 1995/10/07 21:45:19 jtc Exp $"
#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 KBD_DELAY \
{ u_char x = inb(0x84); } \
{ u_char x = inb(0x84); } \
{ u_char x = inb(0x84); } \
{ u_char x = inb(0x84); } \
{ u_char x = inb(0x84); } \
{ u_char x = inb(0x84); }
#define YYDEBUG 1
void yyerror(const char *msg);
static void help(int), status(void), data(int), kbd(int), cmdbyte(int),
kbc(int), whatMCA(void);
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 WHAT
%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(); }
| WHAT '?' { whatMCA(); }
| 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"
"what ? check for MCA type 1 or 2 motherboard controller\n"
"data ? get one byte of data\n"
"led = NUM set kbd LEDs\n"
"echo send kbd ECHO command\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");
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;
case 2:
fprintf(stderr, "usage: kbdio [-d] [-f devname]\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");
}
/* see: Frank van Gilluwe, "The Undocumented PC", Addison Wesley 1994, pp 273*/
static void
whatMCA(void) {
int new, sav;
kbc(0x20); /* get command byte */
sav = kbget(); /* sav = command byte */
kbc(0x60); /* set command byte */
kbd(sav | 0x40); /* set keyboard xlate bit */
kbc(0x20); /* get keyboard command */
new = kbget(); /* new = command byte */
kbc(0x60); /* set command byte */
kbd(sav); /* restore command byte */
if(new & 0x40)
printf("Hmm - looks like MCA type 1 motherboard controller\n");
else
printf("Hmm - looks like MCA type 2 motherboard controller\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; }
KBD_DELAY
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, c;
const char *devname = "/dev/console";
while((c = getopt(argc, argv, "df:")) != EOF)
switch(c) {
case 'd':
yydebug = 1;
break;
case 'f':
devname = optarg;
break;
case '?':
default:
help(2);
return 2;
}
argc -= optind;
argv += optind;
if(argc > 0) {
help(2);
return 2;
}
if((fd = open(devname, O_RDONLY)) < 0) {
perror("open(kbd)");
return 1;
}
if(ioctl(fd, KDENABIO, 0) < 0) {
perror("ioctl(KDENABIO)");
return 1;
}
yyparse();
(void)ioctl(fd, KDDISABIO, 0);
return 0;
}