[comp.os.minix] Keyboard speedup on an AT

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
/