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 /