/*
 * Set keyboard click/bell
 *
 * Dave Baggett
 *
 * Compiled with Sozobon C.  Your mileage may vary.
 */
#include <stdio.h>
#include <osbind.h>

#define CONTERM *((unsigned char *) 0x484)

int	cs, bs, rs;

static void	c_off(), c_on(), b_off(), b_on(), r_off(), r_on(), usage();
static void	c_status(), b_status(), r_status();

main(argc, argv)
	int	argc;
	char	**argv;
{	
	register int		i;
	register unsigned char	id, rd;
	
	if (argc < 2) {
		usage();
		exit(0);
	}

	for (i = 1; i < argc; i++) {
		switch (argv[i][1]) {
			case 'c':
			case 'C':
				if (argv[i][0] == '-')
					Supexec(c_off);
				else
					Supexec(c_on);	
				break;
			case 'b':
			case 'B':
				if (argv[i][0] == '-')
					Supexec(b_off);
				else
					Supexec(b_on);	
				break;
			case 'r':
			case 'R':
				if (argv[i][0] == '-')
					Supexec(r_off);
				else {
					Supexec(r_on);	
					
					if (i + 2 < argc) {
						id = atoi(argv[++i]);
						rd = atoi(argv[++i]);
					
						Kbrate(id, rd);
					}
				}
				break;

			default:
				usage();
				exit(-1);
				break;
		}
	}

	exit(0);
}

static void
usage()
{
	unsigned int	repeat;
	unsigned char	id, rd;
	static char	str[80];
	static char	onoff[2][10] = {"[off]", "[on]"};

	/*
	 * Get current values
	 */
	Supexec(c_status);
	Supexec(b_status);
	Supexec(r_status);

	repeat = Kbrate(-1, -1);
	repeat &= 0x0000FFFF;
	id = repeat >> 8;
	rd = repeat &= 0x00FF;

	Cconws("usage: kbd {-c|-b|-r} {+c|+b|+r [id rd]}\r\n");
	Cconws("c = click, b = bell, r = repeat\r\n");
	Cconws("id = initial delay, rd = repeat delay\r\n");
	Cconws("Delays are in ticks (~20 microseconds)\r\n");
	Cconws("\r\nCurrent values:\r\n");
	sprintf(str, "click: %s   bell: %s   repeat: %s\r\n", 
		onoff[cs], onoff[bs], onoff[rs]);
	Cconws(str);

	if (rs) {
		sprintf(str, "initial delay = %d   repeat delay = %d\r\n",
			id, rd);
		Cconws(str);
	}
}

static void
c_off()
{
	CONTERM &= 0xFE;
}

static void
c_on()
{
	CONTERM |= 0x01;
}

static void
c_status()
{
	cs = (CONTERM & 0x01) ? 1 : 0;
}

static void
b_off()
{
	CONTERM &= 0xFB;
}

static void
b_on()
{
	CONTERM |= 0x04;
}

static void
b_status()
{
	bs = (CONTERM & 0x04) ? 1 : 0;
}

static void
r_off()
{
	CONTERM &= 0xFD;
}

static void
r_on()
{
	CONTERM |= 0x02;
}

static void
r_status()
{
	rs = (CONTERM & 0x02) ? 1 : 0;
}

