DataMuseum.dk

Presents historical artifacts from the history of:

Commodore CBM-900

This is an automatic "excavation" of a thematic subset of
artifacts from Datamuseum.dk's BitArchive.

See our Wiki for more about Commodore CBM-900

Excavated with: AutoArchaeologist - Free & Open Source Software.


top - download

⟦771070a90⟧ TextFile

    Length: 9272 (0x2438)
    Types: TextFile
    Notes: UNIX file
    Names: »kev.c«

Derivation

└─⟦f27320a65⟧ Bits:30001972 Commodore 900 hard disk image with partial source code
    └─⟦2d53db1df⟧ UNIX V7 Filesystem
        └─ ⟦this⟧ »hr/src/smgr/kev.c« 

TextFile

#include <stdio.h>
#include <errno.h>
#include <smgr.h>

/*
 * Keyboard/display driver.
 */

#define	SPC	0376			/* Special encoding */
#define XXX	0377			/* Non-character */
#define	KBDATA	0x60			/* Keyboard data */
#define	KBCTRL	0x61			/* Keyboard control */
#define	KBFLAG	0x80			/* Keyboard reset flag */

#define	KEYUP	0x80			/* Key up change */
#define	KEYSC	0x7F			/* Key scan code mask */
#define	LSHIFT	0x2A-1			/* Left shift key */
#define LSHIFTA 0x2B-1			/* Alternate left-shift key */
#define	RSHIFT	0x36-1			/* Right shift key */
#define	CTRL	0x1D-1			/* Control key */
#define	ALT	0x38-1			/* Alt key */
#define	CAPLOCK	0x3A-1			/* Caps lock key */
#define	DELETE	0x53-1			/* Del, as in CTRL-ALT-DEL */
#define BACKSP	0x0E-1			/* Back space */
#define SCRLOCK	0x46-1			/* Scroll lock */

/* Shift flags */
#define	SRS	0x01			/* Right shift key on */
#define	SLS	0x02			/* Left shift key on */
#define CTS	0x04			/* Ctrl key on */
#define ALS	0x08			/* Alt key on */
#define CPLS	0x10			/* Caps lock on */
#define NMLS	0x20			/* Num lock on */
#define AKPS	0x40			/* Alternate keypad shift */
#define SHFT	0x80			/* Shift key flag */

/* Function key information */
#define	NFKEY	40			/* Number of settable functions */
#define	NFCHAR	600			/* Number of characters settable */
#define	NFBUF	(NFKEY*2+NFCHAR+1)	/* Size of buffer */


/* ASCII codes */
#define	DEL	0x7f			/* delete code	*/


/*
 * State variables.
 */
static	char	shift;			/* Overall shift state */
static  char	lshift = LSHIFT;	/* Left shift alternate state */
static	int	kbd_wid;

extern	int	myfd;
extern	POINT	SM_Mouse_Pos;

/*
 * Tables for converting key code to ASCII.
 * lmaptab specifies unshifted conversion,
 * umaptab specifies shifted conversion,
 * smaptab specifies the shift states which are active.
 * An entry of XXX says the key is dead.
 * An entry of SPC requires further processing.
 *
 * Key codes:
 *	ESC .. <- == 1 .. 14
 *	-> .. \n == 15 .. 28
 *	CTRL .. ` == 29 .. 41
 *	^Shift .. PrtSc == 42 .. 55
 * 	ALT .. CapsLock == 56 .. 58
 *	F1 .. F10 == 59 .. 68
 *	NumLock .. Del == 69 .. 83
 */
static unsigned char lmaptab[] ={
	     '\33',  '1',  '2',  '3',  '4',  '5',  '6',		/* 1 - 7 */
	 '7',  '8',  '9',  '0',  '-',  '=', '\b', '\t',		/* 8 - 15 */
	 'q',  'w',  'e',  'r',  't',  'y',  'u',  'i',		/* 16 - 23 */
	 'o',  'p',  '[',  ']', '\r',  XXX,  'a',  's',		/* 24 - 31 */
	 'd',  'f',  'g',  'h',  'j',  'k',  'l',  ';',		/* 32 - 39 */
	 '\'', '`',  XXX,  '\\',  'z',  'x',  'c',  'v',	/* 40 - 47 */
	 'b',  'n',  'm',  ',',  '.',  '/',  XXX,  SPC,		/* 48 - 55 */
	 XXX,  ' ',  XXX,  SPC,  SPC,  SPC,  SPC,  SPC,		/* 56 - 63 */
	 SPC,  SPC,  SPC,  SPC,  SPC,  SPC,  SPC,  SPC,		/* 64 - 71 */
	 SPC,  SPC,  '-',  SPC,  SPC,  SPC,  '+',  SPC,		/* 72 - 79 */
	 SPC,  SPC,  SPC,  SPC,  SPC,  DEL,  SPC,  SPC,		/* 80 - 87 */
	 SPC,  SPC,  SPC,  SPC,  SPC,  SPC,  '\r', SPC,		/* 88 - 95 */
	 SPC,  SPC,  SPC,  XXX,  XXX				/* 96 - 100*/
};

static unsigned char umaptab[] ={
	     '\33',  '!',  '@',  '#',  '$',  '%',  '^',		/* 1 - 7 */
	 '&',  '*',  '(',  ')',  '_',  '+', '\b', '\t',		/* 8 - 15 */
	 'Q',  'W',  'E',  'R',  'T',  'Y',  'U',  'I',		/* 16 - 23 */
	 'O',  'P',  '{',  '}', '\r',  XXX,  'A',  'S',		/* 24 - 31 */
	 'D',  'F',  'G',  'H',  'J',  'K',  'L',  ':',		/* 32 - 39 */
	 '"',  '~',  XXX,  '|',  'Z',  'X',  'C',  'V',		/* 40 - 47 */
	 'B',  'N',  'M',  '<',  '>',  '?',  XXX,  SPC,		/* 48 - 55 */
	 XXX,  ' ',  XXX,  SPC,  SPC,  SPC,  SPC,  SPC,		/* 56 - 63 */
	 SPC,  SPC,  SPC,  SPC,  SPC,  SPC,  SPC,  SPC,		/* 64 - 71 */
	 SPC,  SPC,  '-',  SPC,  SPC,  SPC,  '+',  SPC,		/* 72 - 79 */
	 SPC,  SPC,  SPC,  SPC,  SPC,  DEL,  SPC,  SPC,		/* 80 - 87 */
	 SPC,  SPC,  SPC,  SPC,  SPC,  SPC,  '\r', SPC,		/* 88 - 95 */
	 SPC,  SPC,  SPC,  XXX,  XXX				/* 96 - 100*/
};

#define SS0	0			/* No shift */
#define SS1	(SLS|SRS|CTS)		/* Shift, Ctrl */
#define SES	(SLS|SRS)		/* Shift */
#define LET	(SLS|SRS|CPLS|CTS)	/* Shift, Caps, Ctrl */
#define KEY	(SLS|SRS|NMLS|AKPS)	/* Shift, Num, Alt keypad */

static unsigned char smaptab[] ={
	       SS0,  SES,  SS1,  SES,  SES,  SES,  SS1,		/* 1 - 7 */
	 SES,  SES,  SES,  SES,  SS1,  SES,  SS0,  SS0,		/* 8 - 15 */
	 LET,  LET,  LET,  LET,  LET,  LET,  LET,  LET,		/* 16 - 23 */
	 LET,  LET,  SS1,  SS1,  SS0, SHFT,  LET,  LET,		/* 24 - 31 */
	 LET,  LET,  LET,  LET,  LET,  LET,  LET,  SES,		/* 32 - 39 */
	 SES,  SS1, SHFT,  SS1,  LET,  LET,  LET,  LET,		/* 40 - 47 */
	 LET,  LET,  LET,  SES,  SES,  SES, SHFT,  SS0,		/* 48 - 55 */
	SHFT,  SS1, SHFT,  SS0,  SS0,  SS0,  SS0,  SS0,		/* 56 - 63 */
	 SS0,  SS0,  SS0,  SS0,  SS0,  SS0,  KEY,  KEY,		/* 64 - 71 */
	 KEY,  KEY,  SS0,  KEY,  KEY,  KEY,  SS0,  KEY,		/* 72 - 79 */
	 KEY,  KEY,  KEY,  KEY,  SS0,  SS0,  SS0,  SS0,		/* 80 - 87 */
	 SS0,  SS0,  SS0,  SS0,  SS0,  SS0,  SS0,  SS0,		/* 88 - 95 */
	 SS0,  SS0,  SS0,  LET,  LET				/* 96 - 100*/
};


/*
** When the keyboard interrupt routine sends a key position to 
** the screen manager sm_key routine is called. This routine checks
** the key position to decide if the key was for screen manager or
** or for an active window and then calls an appropriate routine
** to do the work.
*/
SM_Keyboard()
{
	register int	c;
	register int	s;
	register int	r;

	r = msgData1 & 0xFF;
	if (r == 0xFF)
		return;	/* Overrun */
	c = (r & KEYSC) - 1;
#ifdef DEBUG
	if ( ~(r&KEYUP) )
		printf("KEY:\t0x%x  %d\n", r, r);
#endif

	/*
	 * Track "shift" keys.
	 */
	s = smaptab[c];
	if (s&SHFT)
	{
		if (r&KEYUP)
		{				/* "shift" released */
			if (c == RSHIFT)
				shift &= ~SRS;
			else if (c == lshift)
				shift &= ~SLS;
			else if (c == CTRL)
				shift &= ~CTS;
			else if (c == ALT)
				shift &= ~ALS;
		}
		else
		{				/* "shift" pressed */
			if (c == lshift)
				shift |= SLS;
			else if (c == RSHIFT)
				shift |= SRS;
			else if (c == CTRL)
				shift |= CTS;
			else if (c == ALT)
				shift |= ALS;
			else if (c == CAPLOCK)  
				shift ^= CPLS;	/* toggle cap lock */
#ifdef NUMLOCK
			else if (c == NUMLOCK)  
				shift ^= NMLS;	/* toggle num lock */
#endif
		}
		return;
	}

	/*
	 * No other key up codes of interest.
	 */
	if (r&KEYUP)
		return;

	/*
	 * If no window to receive the character, then toss it.
	 */
	kbd_wid = who_top_at(SM_Mouse_Pos);
	if ( kbd_wid == NO_WINDOW )
		return;
	if ( not ( wtbl[kbd_wid]->wn_Evmask & KBD_ENABLE ) )
		return;


	/*
	 * Map character, based on the
	 * current state of the shift, control,
	 * meta and lock flags.
	 */
	if (shift & CTS)
	{
		if (s==SS1 || s==LET)		/* Normal Ctrl map */
			c = umaptab[c]&0x1F;	/* Clear bits 5-6 */
		else				
			return;			/* Ignore this char */
	}
	else if (s &= shift)
	{
		if (shift & SES)
		{		 		/* if shift on */
			if (s & (CPLS|NMLS))     /* if caps/num lock */
				c = lmaptab[c];  /* use unshifted */
			else
				c = umaptab[c];	 /* use shifted */
		}
		else
		{			 	/* if shift not on */
			if (s & (CPLS|NMLS))     /* if caps/num lock */
				c = umaptab[c];	 /* use shifted */
			else
				c = lmaptab[c];	 /* use unshifted */
		}
	}
	else					 
		c = lmaptab[c];			 /* use unshifted */

	/*
	 * Act on character.
	 */
	if (c == XXX)				
		return;				 /* char to ignore */
	if (c != SPC)
	{					 /* not special char? */
#ifdef DOALT
		if (shift & ALS)		 /* ALT (meta bit)? */
		   c |= 0x80;			 /* set meta */
#endif
		gen_msg(r, c, shift);
	}
	else
		isspecial(r);			 /* special chars */
}

/*
 * Handle special input sequences.
 * The character passed is the key number.
 *
 * The keypad is translated by the following table,
 * the first entry is the normal sequence, the second the shifted,
 * and the third the alternate keypad sequence.
 */
static char keypad[] = {
	'*',	/* 55 */
	'\0',	/* 88 */
	',',	/* 89 */
	'/',	/* 90 */
	'7',	/* 71 */
	'8',	/* 72 */
	'9',	/* 73 */
	'4',	/* 75 */
	'5',	/* 76 */
	'6',	/* 77 */
	'1',	/* 79 */
	'2',	/* 80 */
	'3',	/* 81 */
	'0',	/* 82 */
	'.'	/* 83 */
};

isspecial(key)
register int key;
{
	register int c;

	c = key;
	switch (key) {
	case 59: case 60: case 61: case 62: case 63:	/* F1 - F5	*/
	case 64: case 65: case 66: case 67: case 68:	/* F6 - F10	*/
	case 84: case 86: case 87: case 69:		/* HELP, F12, F13, F14 */
	case 70:					/* F15 (Scroll Lock)*/
	case 91: case 92: case 93:			/* W1 - W3	 */
	case 95: case 96: case 97: case 98:		/* cursor keys	 */
		gen_msg(key, 0, shift);
		return;

	case 55:					/* PF3		 */
		c = 87;
	case 88: case 89: case 90:			/* PF1, PF2, PF4 */
		c -= 18;
	case 79:		/* 1/End */
	case 80:		/* 2/DOWN */
	case 81:		/* 3/PgDn */
	case 82:		/* 0/Ins */
	case 83:		/* ./Del */
		--c;		/* adjust code */
	case 75:		/* 4/LEFT */
	case 76:		/* 5 */
	case 77:		/* 6/RIGHT */
		--c;		/* adjust code */
	case 71:		/* 7/Home/Clear */
	case 72:		/* 8/UP */
	case 73:		/* 9/PgUp */
#ifndef TRACE
		if ( (shift&NMLS) || (shift&SES) ||
		   (!(shift&NMLS) && !(shift&SES) && (shift&AKPS)) )
			c = 0;
		else
			c = keypad[c-67];
		break;
#else
		DB_dump();
		break;
#endif
	default:
		c = 0;
		break;
	}
	gen_msg(key, c, shift);
}

 
/*
** generate message to the active window manager 
*/
gen_msg(kpos, kval, mod)
unsigned kpos, kval, mod;
{
	MESSAGE m;

	m.msg_Receiver = wtbl[kbd_wid]->wn_Wmgr;
	m.msg_Cmd = WM_CHARACTER;
	m.msg_Data[0] = kbd_wid << 8;
	m.msg_Data[0] |=  kval;
	m.msg_Data[1] = kpos;
	m.msg_Data[2] = mod;
	sendmsg( &m );
}