/****************************************************************
 *	Module name  :	FKEY.C                                  *
 *	Purpose      :	Quick change for funtion keys           *
 *	Created      :	02-09-89				* 
 *	Last edit    : 	10-09-89		Version 1.0	*
 * 	Copyright    :	G R Buckeridge				*
 ****************************************************************/

#include stdio.h
#include gb.h

#define OUT_A_to	0xD3
#define LD_BC_with	0x01
#define LDIR		0xED,0xB0
#define RET		0xC9

#define HI		/256
#define LO		%256
#define DEST		0,0
#define SOURCE		0,0
#define LENGTH		0x90,0

static char key_tbl[0x91],keys[9][0x31],rest_keys[0x81];

static char code[] = {			/* Machine code must be in common store. */
	
	DI,				/* This copys the key table where we can */
		
	LD_A_with, 0,			/* get at it and manipulate it. */
	OUT_A_to, 0xF0,
	
	LD_HL_with, SOURCE,
	LD_DE_with, DEST,
	LD_BC_with, LENGTH,
	LDIR,
	
	LD_A_with, 4,
	OUT_A_to, 0xF0,
	
	EI,
	RET

	};

main(argc,argv)
int argc;
char *argv[];

	{

	FAST char argv_buffer[MAXARGS * 2 +132];/* declares command buffer  */
	static inp[41],loop[2];
	int key2,i;
	char key;		

	cpm_cmd_line (&argc,&argv,argv_buffer); /* for reading command line */

	get_key_tbl();			
	putchar('\n');		
	expand_keys();
	key=argv[1][0];				/* Read 2nd argument from command line */
	
	cls();

	while (1)				/* keep looping */
		{
		home();
		copyright();
		print_keys();
		printf("\33J");
		if(argc<2)			/* command line contains key number */
			key='0';
		while ((key <'1' || key>'8') && key!='R' && key!='X' && key!='?')
			{
			printf("Alter which key ? (1-8, X=eXit, R=Reset keys, ?=Help) ");
			while (!keyhit())
				{}		/* Just wait for key */
			key=toupper(rawin());
			printf("%c\n",key);
			}
		if (key=='?')			/* My golly */
			{
			cls();
			copyright();
			help();
			exit(0);
			}
			
		if (key=='X')			/* Is it a bird */
			exit(0);

		if (key=='R')			/* Is it a plane */	
			{

			strcpy(keys[1],"^Z");
			strcpy(keys[2],"^Z");
			strcpy(keys[3],"^Q");
			strcpy(keys[4],"^Q");	/* Resets to default */
			strcpy(keys[5],"^S");
			strcpy(keys[6],"^S");
			strcpy(keys[7],"^P");
			strcpy(keys[8],"^P");

			}
		else
			{
			key2=key-48;
		
		if(argc<3)			/* String in command line */
			{
			i=0;
			while (i<1)		/* No empty key strings */
				{
				printf("\nEnter string for F%c ? ",key);
				i=input(inp,30);	/* Gets a new key string */
				strcpy(keys[key2],inp);
				}
			}
		else
			strcpy(keys[key2],argv[2]);
			}
		argc=1;
		compress_keys();		/* Back as it should be */
		set_key_tbl();
		}

	}
	
void get_key_tbl()				/* Extract keyboard table */

	{
	unsigned temp;
	
	temp = cast (unsigned) key_tbl;
	code[6]=0x76;
	code[7]=0x28;
	code[9]=temp LO;
	code[10]=temp HI;
	
	inline(
		CALL code
		);
	}

void set_key_tbl()				/* Reinstate keyboard table */

	{
	unsigned temp;
	
	temp = cast (unsigned) key_tbl;
	code[6]=temp LO;
	code[7]=temp HI;
	code[9]=0x76;
	code[10]=0x28;

	inline(
		CALL code
		);
	}

void expand_keys()				/* Expand key table to its */

	{					/* individual elements */
	int i,j,p,q;
	char c;

	p=0;					/* Key table offset */ 
	for (i=0;i<9;i++)			/* 0-8 includes STOP key */
		{
		q=0;				/* Indididual key offset */
		for(j=1;j<=key_tbl[p];j++)
			{
			c=key_tbl[p+j];
			if(c<0x20)		/* Change ctrl-? to ^? */
				{
				c+=0x40;
				keys[i][q++]=0x5E;	/* 0x5E = '^' */
				}
			keys[i][q++]=c;
			}
		keys[i][q]='\0';
		p+=j;
		}
	strcpy(rest_keys,key_tbl+p);		/* Anything else constitutes the rest */
	}
	
void compress_keys()				/* The reverse of extract_keys() */

	{
	int i,j,k;
	char c;
	static char temp[0x31],len[]={'\0','\0'};	

	key_tbl[0]='\0';			/* Ensures entire table is rewritten */
	for(i=0;i<9;i++)
		{
		k=0;
		for(j=0;j<strlen(keys[i]);j++)
			{
			c=keys[i][j];
			if(c==0x5e)		/* Changes ^? back to ctrl-? again */
				c=keys[i][++j]-0x40;
			temp[k++]=c;		/* Temp holds the compressed key value */
			}
		temp[k]='\0';
		len[0]=k;
		strcat(key_tbl,len);		/* Rebuild the key table */
		strcat(key_tbl,temp);	
		}
	strcat(key_tbl,rest_keys);		/* Finish it off */
	}

void print_keys()				/* Just prints the function keys */

	{
	int i,j;

	for(i=1;i<9;i++)
		{
		printf("\t\tF%d = %s\33K",i,keys[i]);	
		putchar('\n');
		}
	putchar('\n');	
	}

void copyright()

	{
	printf("\nPCW Function Key Modifier v1.0  -  Copyright G.R. Buckeridge. 1989\n\n");
	}

void help()

	{
	printf("This programs enables you to alter the function keys on your\n");
	printf("keyboard.  It is easier to run than SETKEYS, and does not\n");
	printf("need a text file.\n\n");

	printf("You can either run FKEY just by typing the name :-\n\n");

	printf("FKEY <cr>\n\n");

	printf("or :-\n\n");

	printf("FKEY 2 <cr>\n\n");

	printf("which takes you straight to the 'alter text' prompt for the\n");
	printf("function key, in this case, F2.\n\n");

	printf("A control code may be inserted as in SETKEYS.  e.g. ctrl-M\n");
	printf("becomes ^M.  So 'dir^M' will invoke a DIR every time the\n");
	printf("respective function key is pressed.\n\n");
	
	printf("FKEY 3 dir^M <cr>\n\n");
	
	printf("This method sets the string directly from the command line, but\n");
	printf("does have its limitations.  i.e. The string cannot contain spaces\n");
	printf("and is converted to upper case.  Use the other methods to get\n");
	printf("round this problem.\n\n");
	
	}
	

#include ?gb.lib		
#include ?cpm.lib
#include ?stdio.lib

ds to get\n");
	printf("round this problem.\n\n");
	
	}
	

#include ?gb.lib		
#include 