nfs@notecnirp.Princeton.EDU (Norbert Schlenker) (05/08/89)
Here is my utility to improve the responsiveness of an AT's keyboard.
A help file is included. It should be interpolated into /usr/lib/helpfile.
The shell archive includes a copy of Henry Spencer's getopt, for those
who don't have one already. The GNU getopt, which some might also have,
will work here as well (but it's a bit rococo for me).
I use this by including the line
/usr/local/bin/fastkey -d 500
in my /etc/rc. That fixes things up for me automagically at boot time.
I use a delay of 500 ms before typematic starts because the next lower
value (250 ms, which is also the default) makes the keyboard a little
too touchy for my lazy fingers.
-------------------------------- Cut here ------------------------------------
# Extract this archive by removing all the above lines and feeding to /bin/sh.
echo x - Makefile
sed '/^X/s///' > Makefile << '/'
X# Makefile for fastkey.
X
X# Note that getopt.s should be removed from the OBJS macro if a
X# version has been installed in /usr/lib/libc.a.
X# LOCALSRC and LOCALBIN should be changed to reflect your configuration.
X
XOBJS = fastkey.s getopt.s
XLOCALSRC = /usr/local/src
XLOCALBIN = /usr/local/bin
X
Xfastkey: $(OBJS)
X cc -o fastkey $(OBJS)
X chmem =1000 fastkey
X
Xinstall: fastkey
X mv fastkey.c getopt.c $(LOCALSRC)
X mv fastkey $(LOCALBIN)
X
Xclean:
X rm *.s
/
echo x - fastkey.c
sed '/^X/s///' > fastkey.c << '/'
X/* fastkey - modify PC/AT's home keyboard response */
X
X/* Copyright 1988 Norbert Schlenker.
X *
X * Permission is granted to anyone to use, alter, and redistribute this
X * software, subject to the following conditions.
X *
X * - This software carries no warranty whatsoever. The author is
X * not responsible for any loss or damage that occurs through the
X * use of this software.
X * - Fees for redistribution of this software are limited to nominal
X * copying or transmission costs.
X * - Altered versions of this software must be plainly marked as such.
X * - This notice may not be removed or altered.
X */
X
X/* Note that this program can only be used on IBM PC/AT's and strict
X * compatibles. It affects only the typematic rate of the home keyboard,
X * and has no useful effect on other machine types or RS-232 terminals.
X */
X
X/* External interfaces */
X
X#include <stdio.h>
X
Xextern int getopt(/* int argc, char **argv, char *optstring */);
Xextern char* optarg;
Xextern int opterr;
X
X
X/* Local definitions */
X
X#define KBC_PORT 0x60 /* keyboard controller port on an AT */
X#define TYPEMATIC_REG 0xf3 /* typematic register in the AT's KBC */
X#define KBC_ACK 0xfa /* keyboard controller's acknowledgement byte */
X#define DELAYS 4 /* number of possible typematic delays */
X#define RATES 32 /* number of possible typematic rates */
X#define DELAY_SHIFT 5 /* delay position in control byte */
X#define RATE_SHIFT 0 /* rate position in control byte */
X
Xstatic int delays[DELAYS] = {250, 500, 750, 1000};
Xstatic int rates[RATES] = { 34, 38, 42, 46, 50, 55, 59, 63,
X 68, 76, 84, 92, 100, 110, 118, 126,
X 136, 152, 168, 184, 200, 220, 236, 252,
X 272, 304, 336, 368, 400, 440, 472, 504};
X
Xmain(argc, argv)
Xint argc;
Xchar **argv;
X{
X int delay = 0; /* default delay is very short */
X int rate = 0; /* default rate is very fast */
X int verbose = 0; /* default verbosity is quiet */
X int flag;
X int n;
X int ack;
X
X opterr = 0;
X while ((flag = getopt(argc, argv, "d:r:v")) != EOF)
X switch(flag) {
X case 'd':
X n = atoi(optarg);
X for (delay = 0; delay < DELAYS-1 && n > delays[delay]; delay++) ;
X break;
X case 'r':
X n = atoi(optarg);
X for (rate = 0; rate < RATES-1 && n > rates[rate]; rate++) ;
X break;
X case 'v':
X verbose = 1;
X break;
X default:
X printf("Usage: %s [-d delay] [-r rate] [-v]\n", argv[0]);
X exit(1);
X }
X
X port_out(KBC_PORT, TYPEMATIC_REG);
X for (n = 1000; n > 0; n--) {
X port_in(KBC_PORT, &ack);
X if (ack == KBC_ACK)
X break;
X }
X
X if (n == 0) {
X if (verbose)
X printf("%s: Keyboard controller timed out\n", argv[0]);
X exit(2);
X }
X
X port_out(KBC_PORT, (delay << DELAY_SHIFT) | (rate << RATE_SHIFT));
X if (verbose)
X printf("%s: %d ms typematic delay and %d ms typematic rate.\n",
X argv[0], delays[delay], rates[rate]);
X exit(0);
X
X}
/
echo x - fastkey.help
sed '/^X/s///' > fastkey.help << '/'
X#fastkey
XCommand: fastkey - modify keyboard responsiveness on an AT
XSyntax: fastkey [-d delay] [-r rate] [-v]
XFlags: -d delay Typematic delay set to _d_e_l_a_y milliseconds
X -r rate Typematic rate set to _r_a_t_e milliseconds
X -v Verbose
X
X _F_a_s_t_k_e_y programs the AT's keyboard controller to improve its
Xresponsiveness. Flags may specify, to the granularity of the keyboard
Xcontroller, both the _d_e_l_a_y until the keyboard starts repeating a held key,
Xand the time between repetitions (the _r_a_t_e).
/
echo x - getopt.c
sed '/^X/s///' > getopt.c << '/'
X/*
X * getopt - get option letter from argv
X *
X * Copyright (c) Henry Spencer.
X * Written by Henry Spencer.
X *
X * This software is not subject to any license of the American Telephone
X * and Telegraph Company or of the Regents of the University of California.
X *
X * Permission is granted to anyone to use this software for any purpose on
X * any computer system, and to alter it and redistribute it freely, subject
X * to the following restrictions:
X *
X * 1. The author is not responsible for the consequences of use of this
X * software, no matter how awful, even if they arise from flaws in it.
X *
X * 2. The origin of this software must not be misrepresented, either by
X * explicit claim or by omission. Since few users ever read sources,
X * credits must appear in the documentation.
X *
X * 3. Altered versions must be plainly marked as such, and must not be
X * misrepresented as being the original software. Since few users
X * ever read sources, credits must appear in the documentation.
X *
X * 4. This notice may not be removed or altered.
X */
X
X/*
X * changed index() calls to strchr() - darwin, oct 87.
X *
X * added opterr & optopt - Terrence W. Holm, Aug. 1988
X */
X
X#include <stdio.h>
X
Xchar *optarg; /* Global argument pointer. */
Xint optind = 0; /* Global argv index. */
Xint opterr = 1; /* Print error flag, default = on */
Xint optopt;
X
Xstatic char *scan = NULL; /* Private scan pointer. */
X
Xextern char *strchr();
X
Xint
Xgetopt(argc, argv, optstring)
Xint argc;
Xchar *argv[];
Xchar *optstring;
X{
X register char c;
X register char *place;
X
X optarg = NULL;
X
X if (scan == NULL || *scan == '\0') {
X if (optind == 0)
X optind++;
X
X if (optind >= argc || argv[optind][0] != '-' || argv[optind][1] == '\0')
X return(EOF);
X if (strcmp(argv[optind], "--")==0) {
X optind++;
X return(EOF);
X }
X
X scan = argv[optind]+1;
X optind++;
X }
X
X optopt = c = *scan++;
X place = strchr(optstring, c);
X
X if (place == NULL || c == ':') {
X if ( opterr )
X fprintf(stderr, "%s: unknown option -%c\n", argv[0], c);
X return('?');
X }
X
X place++;
X if (*place == ':') {
X if (*scan != '\0') {
X optarg = scan;
X scan = NULL;
X } else if (optind < argc) {
X optarg = argv[optind];
X optind++;
X } else {
X if ( opterr )
X fprintf(stderr, "%s: -%c argument missing\n", argv[0], c);
X return('?');
X }
X }
X
X return(c);
X}
/
echo x - getopt.3
sed '/^X/s///' > getopt.3 << '/'
XSUBROUTINES
X getopt(3) - get option letter from argv
X
XINVOCATION
X extern char *optarg;
X extern int optind;
X extern int opterr;
X extern int optopt;
X
X int getopt( argc, argv, optstring )
X int argc;
X char *argv[];
X char *optstring;
X
XEXPLANATION
X Getopt(3) is used to ease the process of scanning the
X options on a command line. The <argc> and <argv> given
X to main() are passed to getopt(3), as well as a string
X naming all of the single character option names. If
X an option allows an argument, then a ':' is put after
X the name in <optstring>.
X
X For example, the <optstring> "af:x" means that the
X command accepts the options "-a", "-f" and "-x". The
X "-f" option has an argument. When a command line is
X entered the options without a following argument may
X be grouped together, and there may be space between
X the "-f" and its argument in the command line. For
X example,
X
X cmd -a -xf arg rest of line
X
X After each call, main() must check the returned option
X name and, if appropriate, the argument referenced by
X <optarg>. Main() should continue to call getopt(3) until
X it returns EOF, at which time main() can use <optind> to
X determine how many items still remain on the command line.
X
X The cases for getopt(3) returning EOF are: no more items
X in the command line, an item does not start with a "-",
X an item is simply "-" or an item is "--". In the latter
X case, <optind> is incremented past this item.
X
X Normally getopt(3) will print an error message on stderr
X if either an unknown option is encountered or an option
X is missing an argument. This output may be suppressed by
X setting <opterr> to 0. Errors cause '?' to be returned and
X <optopt> to be set to the offending option letter.
X
XRESULTS
X o/w : Option character, <optarg> points to possible argument.
X EOF : Finished scanning options, <optind> is next <argv>.
X '?' : Encountered an illegal option, <optopt> is letter.
X
XAUTHOR
X Henry Spencer
/