plan 9 kernel history: overview | file list | diff list

1994/0306/carrera/kbd.c (diff list | history)

1994/0201/sys/src/9/carrera/kbd.c:10,401994/0306/sys/src/9/carrera/kbd.c:10,24 (short | long | prev | next)
1993/0907    
 
enum 
{ 
1994/0306    
	/* controller command byte */ 
	Cscs1=		(1<<6),		/* scan code set 1 */ 
	Cmousedis=	(1<<5),		/* mouse disable */ 
	Ckbddis=	(1<<4),		/* kbd disable */ 
	Csf=		(1<<2),		/* system flag */ 
	Cmouseint=	(1<<1),		/* mouse interrupt enable */ 
	Ckbdint=	(1<<0),		/* kbd interrupt enable */ 
 
1993/0907    
	/* 
	 *  commands 
	 */ 
	Krdcmd=		0x20,	/* read command byte */ 
	Kwrcmd=		0x60,	/* write command byte */ 
	Kselftest=	0xAA,	/* self test */ 
	Ktest=		0xAB,	/* keyboard test */ 
	Kdisable=	0xAD,	/* disable keyboard */ 
	Kenable=	0xAE,	/* enable keyboard */ 
1993/1003    
	Kmseena=	0xA8,	/* enable mouse */ 
1993/0907    
	Krdin=		0xC0,	/* read input port */ 
	Krdout=		0xD0,	/* read output port */ 
	Kwrout=		0xD1,	/* write output port */ 
	Krdtest=	0xE0,	/* read test inputs */ 
	Kwrlights=	0xED,	/* set lights */ 
	Kreset=		0xF0,	/* soft reset */ 
	/* 
	 *  magic characters 
	 */ 
	Msetscan=	0xF0,	/* set scan type (0 == unix) */ 
	Menable=	0xF4,	/* enable the keyboard */ 
	Mdisable=	0xF5,	/* disable the keyboard */ 
	Mdefault=	0xF6,	/* set defaults */ 
	Mreset=		0xFF,	/* reset the keyboard */ 
	/* 
	 *  responses from keyboard 
	 */ 
	Rok=		0xAA,		/* self test OK */ 
1994/0201/sys/src/9/carrera/kbd.c:43,661994/0306/sys/src/9/carrera/kbd.c:27,34
1993/0907    
	Rfail=		0xFC,		/* self test failed */ 
	Rresend=	0xFE,		/* ??? */ 
	Rovfl=		0xFF,		/* input overflow */ 
1994/0306    
 
1993/0907    
	/* 
	 *  command register bits 
	 */ 
	Cintena=	1<<0,	/* enable output interrupt */ 
1993/1003    
	Cmseint=	1<<1,	/* enable mouse interrupt */ 
1993/0907    
	Csystem=	1<<2,	/* set system */ 
	Cinhibit=	1<<3,	/* inhibit override */ 
	Cdisable=	1<<4,	/* disable keyboard */ 
	/* 
	 *  output port bits 
	 */ 
	Osoft=		1<<0,	/* soft reset bit (must be 1?) */ 
	Oparity=	1<<1,	/* force bad parity */ 
	Omemtype=	1<<2,	/* simm type (1 = 4Mb, 0 = 1Mb)	*/ 
	Obigendian=	1<<3,	/* big endian */ 
	Ointena=	1<<4,	/* enable interrupt */ 
	Oclear=		1<<5,	/* clear expansion slot interrupt */ 
	/* 
	 *  status bits 
	 */ 
	Sobf=		1<<0,	/* output buffer full */ 
1994/0201/sys/src/9/carrera/kbd.c:71,821994/0306/sys/src/9/carrera/kbd.c:39,70
1993/0907    
	Stxtimeout=	1<<5,	/* transmit to kybd has timed out */ 
	Srxtimeout=	1<<6,	/* receive from kybd has timed out */ 
	Sparity=	1<<7,	/* parity on byte was even */ 
	/* 
	 *  light bits 
	 */ 
	L1=		1<<0,	/* light 1, network activity */ 
	L2=		1<<2,	/* light 2, caps lock */ 
	L3=		1<<1,	/* light 3, no label */ 
1994/0306    
 
	Spec=		0x80, 
 
	PF=		Spec|0x20,	/* num pad function key */ 
	View=		Spec|0x00,	/* view (shift window up) */ 
	KF=		Spec|0x40,	/* function key */ 
	Shift=		Spec|0x60, 
	Break=		Spec|0x61, 
	Ctrl=		Spec|0x62, 
	Latin=		Spec|0x63, 
	Caps=		Spec|0x64, 
	Num=		Spec|0x65, 
	Middle=		Spec|0x66, 
	No=		0x00,		/* peter */ 
 
	Home=		KF|13, 
	Up=		KF|14, 
	Pgup=		KF|15, 
	Print=		KF|16, 
	Left=		View, 
	Right=		View, 
	End=		'\r', 
	Down=		View, 
	Pgdown=		View, 
	Ins=		KF|20, 
	Del=		0x7F, 
1993/0907    
}; 
 
#define KBDCTL	(*(uchar*)(KeyboardIO+Keyctl)) 
1994/0201/sys/src/9/carrera/kbd.c:85,1531994/0306/sys/src/9/carrera/kbd.c:73,132
1993/0907    
#define INWAIT	while(!(KBDCTL & Sobf)); kdbdly(1) 
#define ACKWAIT INWAIT ; if(KBDDAT != Rack) print("bad response\n"); kdbdly(1) 
 
enum 
1994/0306    
uchar kbtab[] =  
1993/0907    
{ 
	Spec=	0x80, 
                 
	PF=	Spec|0x20,	/* num pad function key */ 
	View=	Spec|0x00,	/* view (shift window up) */ 
	F=	Spec|0x40,	/* function key */ 
	Shift=	Spec|0x60, 
	Break=	Spec|0x61, 
	Ctrl=	Spec|0x62, 
	Latin=	Spec|0x63, 
	Up=	Spec|0x70,	/* key has come up */ 
	No=	Spec|0x7F,	/* no mapping */ 
                 
	Tmask=	Spec|0x60, 
1994/0306    
[0x00]	No,	0x1b,	'1',	'2',	'3',	'4',	'5',	'6', 
[0x08]	'7',	'8',	'9',	'0',	'-',	'=',	'\b',	'\t', 
[0x10]	'q',	'w',	'e',	'r',	't',	'y',	'u',	'i', 
[0x18]	'o',	'p',	'[',	']',	'\n',	Ctrl,	'a',	's', 
[0x20]	'd',	'f',	'g',	'h',	'j',	'k',	'l',	';', 
[0x28]	'\'',	'`',	Shift,	'\\',	'z',	'x',	'c',	'v', 
[0x30]	'b',	'n',	'm',	',',	'.',	'/',	Shift,	'*', 
[0x38]	Latin,	' ',	Ctrl,	KF|1,	KF|2,	KF|3,	KF|4,	KF|5, 
[0x40]	KF|6,	KF|7,	KF|8,	KF|9,	KF|10,	Num,	KF|12,	'7', 
[0x48]	'8',	'9',	'-',	'4',	'5',	'6',	'+',	'1', 
[0x50]	'2',	'3',	'0',	'.',	No,	No,	No,	KF|11, 
[0x58]	KF|12,	No,	No,	No,	No,	No,	No,	No, 
1993/0907    
}; 
 
uchar keymap[] = { 
[0]	No,	No,	No,	No,	No,	No,	No,	F|1, 
	'\033',	No,	No,	No,	No,	'\t',	'`',	F|2, 
[0x10]	No,	Ctrl,	Shift,	Shift,	Shift,	'q',	'1',	F|3, 
	No,	Shift,	'z',	's',	'a',	'w',	'2',	F|4, 
[0x20]	No,	'c',	'x',	'd',	'e',	'4',	'3',	F|5, 
	No,	' ',	'v',	'f',	't',	'r',	'5',	F|6, 
[0x30]	No,	'n',	'b',	'h',	'g',	'y',	'6',	F|7, 
	No,	View,	'm',	'j',	'u',	'7',	'8',	F|8, 
[0x40]	No,	',',	'k',	'i',	'o',	'0',	'9',	F|9, 
	No,	'.',	'/',	'l',	';',	'p',	'-',	F|10, 
[0x50]	No,	No,	'\'',	No,	'[',	'=',	F|11,	'\r', 
	Latin,	Shift,	'\n',	']',	'\\',	No,	F|12,	Break, 
[0x60]	View,	View,	Break,	Shift,	'\177',	No,	'\b',	No, 
	No,	'1',	View,	'4',	'7',	',',	No,	No, 
[0x70]	'0',	'.',	'2',	'5',	'6',	'8',	PF|1,	PF|2, 
	No,	'\n',	'3',	No,	PF|4,	'9',	PF|3,	No, 
[0x80]	No,	No,	No,	No,	'-',	No,	No,	No, 
1994/0306    
uchar kbtabshift[] = 
{ 
[0x00]	No,	0x1b,	'!',	'@',	'#',	'$',	'%',	'^', 
[0x08]	'&',	'*',	'(',	')',	'_',	'+',	'\b',	'\t', 
[0x10]	'Q',	'W',	'E',	'R',	'T',	'Y',	'U',	'I', 
[0x18]	'O',	'P',	'{',	'}',	'\n',	Ctrl,	'A',	'S', 
[0x20]	'D',	'F',	'G',	'H',	'J',	'K',	'L',	':', 
[0x28]	'"',	'~',	Shift,	'|',	'Z',	'X',	'C',	'V', 
[0x30]	'B',	'N',	'M',	'<',	'>',	'?',	Shift,	'*', 
[0x38]	Latin,	' ',	Ctrl,	KF|1,	KF|2,	KF|3,	KF|4,	KF|5, 
[0x40]	KF|6,	KF|7,	KF|8,	KF|9,	KF|10,	Num,	KF|12,	'7', 
[0x48]	'8',	'9',	'-',	'4',	'5',	'6',	'+',	'1', 
[0x50]	'2',	'3',	'0',	'.',	No,	No,	No,	KF|11, 
[0x58]	KF|12,	No,	No,	No,	No,	No,	No,	No, 
1993/0907    
}; 
 
uchar skeymap[] = { 
[0]	No,	No,	No,	No,	No,	No,	No,	F|1, 
	'\033',	No,	No,	No,	No,	'\t',	'~',	F|2, 
[0x10]	No,	Ctrl,	Shift,	Shift,	Shift,	'Q',	'!',	F|3, 
	No,	Shift,	'Z',	'S',	'A',	'W',	'@',	F|4, 
[0x20]	No,	'C',	'X',	'D',	'E',	'$',	'#',	F|5, 
	No,	' ',	'V',	'F',	'T',	'R',	'%',	F|6, 
[0x30]	No,	'N',	'B',	'H',	'G',	'Y',	'^',	F|7, 
	No,	View,	'M',	'J',	'U',	'&',	'*',	F|8, 
[0x40]	No,	'<',	'K',	'I',	'O',	')',	'(',	F|9, 
	No,	'>',	'?',	'L',	':',	'P',	'_',	F|10, 
[0x50]	No,	No,	'"',	No,	'{',	'+',	F|11,	'\r', 
	Latin,	Shift,	'\n',	'}',	'|',	No,	F|12,	Break, 
[0x60]	View,	View,	Break,	Shift,	'\177',	No,	'\b',	No, 
	No,	'1',	View,	'4',	'7',	',',	No,	No, 
[0x70]	'0',	'.',	'2',	'5',	'6',	'8',	PF|1,	PF|2, 
	No,	'\n',	'3',	No,	PF|4,	'9',	PF|3,	No, 
[0x80]	No,	No,	No,	No,	'-',	No,	No,	No, 
1994/0306    
uchar kbtabesc1[] = 
{ 
[0x00]	No,	No,	No,	No,	No,	No,	No,	No, 
[0x08]	No,	No,	No,	No,	No,	No,	No,	No, 
[0x10]	No,	No,	No,	No,	No,	No,	No,	No, 
[0x18]	No,	No,	No,	No,	'\n',	Ctrl,	No,	No, 
[0x20]	No,	No,	No,	No,	No,	No,	No,	No, 
[0x28]	No,	No,	Shift,	No,	No,	No,	No,	No, 
[0x30]	No,	No,	No,	No,	No,	'/',	No,	Print, 
[0x38]	Latin,	No,	No,	No,	No,	No,	No,	No, 
[0x40]	No,	No,	No,	No,	No,	No,	Break,	Home, 
[0x48]	Up,	Pgup,	No,	Left,	No,	Right,	No,	End, 
[0x50]	Down,	Pgdown,	Ins,	Del,	No,	No,	No,	No, 
[0x58]	No,	No,	No,	No,	No,	No,	No,	No, 
1993/0907    
}; 
 
                 
struct Kbd 
{ 
	Lock; 
	int l; 
} kbd; 
1994/0306    
static uchar ccc; 
1993/0907    
 
void 
kdbdly(int l) 
1994/0201/sys/src/9/carrera/kbd.c:175,1911994/0306/sys/src/9/carrera/kbd.c:154,159
1993/0907    
	return 0; 
} 
 
/* 
 *  wait for a keyboard acknowledge (or some max time) 
 */ 
int 
kbdackwait(void) 
{ 
	if(kbdintr()) 
		return KBDDAT; 
	return 0; 
1993/1001    
} 
                 
void 
mouseintr(void) 
{ 
1994/0201/sys/src/9/carrera/kbd.c:219,2801994/0306/sys/src/9/carrera/kbd.c:187,271
1993/1003    
	} 
1993/0907    
} 
 
int 
1994/0306    
void 
1993/0907    
kbdintr(void) 
{ 
	int c, i, nk; 
	uchar ch, code; 
1994/0306    
	static int esc1, esc2; 
	static int caps; 
	static int ctl; 
	static int num; 
	static int lstate; 
1993/0907    
	static uchar kc[5]; 
	static int shifted, ctrled, lstate; 
1993/0908    
	static int upcode; 
1994/0306    
	static int shift; 
	int keyup; 
1993/0907    
 
	kbdwait(); 
	code = KBDDAT; 
1994/0306    
	c = KBDDAT; 
1993/0907    
 
	/* 
	 *  key has gone up 
1994/0306    
	 *  e0's is the first of a 2 character sequence 
1993/0907    
	 */ 
	if(code == Up) { 
1993/0908    
		upcode = 1; 
		return 0; 
1994/0306    
	if(c == 0xe0){ 
		esc1 = 1; 
		return; 
	} else if(c == 0xe1){ 
		esc2 = 2; 
		return; 
1993/0908    
	} 
 
	if(code > 0x87) 
		return 1; 
1994/0306    
	keyup = c&0x80; 
	c &= 0x7f; 
	if(c > sizeof kbtab){ 
		print("unknown key %ux\n", c|keyup); 
		return; 
	} 
1993/0908    
 
	if(upcode){ 
		ch = keymap[code]; 
1993/0907    
		if(ch == Ctrl) 
			ctrled = 0; 
		else if(ch == Shift) 
			shifted = 0; 
1993/0908    
		upcode = 0; 
1993/0907    
		return 0; 
1994/0306    
	if(esc1){ 
		c = kbtabesc1[c]; 
		esc1 = 0; 
1993/0907    
	} 
1993/0908    
	upcode = 0; 
1994/0306    
	else if(esc2){ 
		esc2--; 
		return; 
	} 
	else if(shift) 
		c = kbtabshift[c]; 
	else 
		c = kbtab[c]; 
1993/0907    
 
1994/0306    
	if(caps && c<='z' && c>='a') 
		c += 'A' - 'a'; 
 
1993/0907    
	/* 
	 *  convert 
1994/0306    
	 *  keyup only important for shifts 
1993/0907    
	 */ 
	if(shifted) 
		ch = skeymap[code]; 
	else 
		ch = keymap[code]; 
1994/0306    
	if(keyup){ 
		switch(c){ 
		case Shift: 
			shift = 0; 
			break; 
		case Ctrl: 
			ctl = 0; 
			break; 
		} 
		return; 
	} 
1993/0907    
	/* 
 	 *  normal character 
	 */ 
	if(!(ch & Spec)){ 
		if(ctrled) 
			ch &= 0x1f; 
1994/0306    
	if(!(c & Spec)){ 
		if(ctl) 
			c &= 0x1f; 
1993/0907    
		switch(lstate){ 
		case 1: 
			kc[0] = ch; 
1994/0306    
			kc[0] = c; 
1993/0907    
			lstate = 2; 
			if(ch == 'X') 
1994/0306    
			if(c == 'X') 
1993/0907    
				lstate = 3; 
			break; 
		case 2: 
			kc[1] = ch; 
1994/0306    
			kc[1] = c; 
1993/0907    
			c = latin1(kc); 
			nk = 2; 
		putit: 
1994/0201/sys/src/9/carrera/kbd.c:281,3541994/0306/sys/src/9/carrera/kbd.c:272,323
1993/0907    
			lstate = 0; 
			if(c != -1) 
				kbdputc(kbdq, c); 
			else { 
				for(i=0; i<nk; i++) 
					kbdputc(kbdq, kc[i]); 
			} 
1994/0306    
			else for(i=0; i<nk; i++) 
				kbdputc(kbdq, kc[i]); 
1993/0907    
			break; 
		case 3: 
		case 4: 
		case 5: 
			kc[lstate-2] = ch; 
1994/0306    
			kc[lstate-2] = c; 
1993/0907    
			lstate++; 
			break; 
		case 6: 
			kc[4] = ch; 
1994/0306    
			kc[4] = c; 
1993/0907    
			c = unicode(kc); 
			nk = 5; 
			goto putit; 
		default: 
			kbdputc(kbdq, ch); 
1994/0306    
			kbdputc(kbdq, c); 
1993/0907    
			break; 
		} 
		return 0; 
1994/0306    
		return; 
1993/0907    
	} 
                 
	/* 
	 *  filter out function keys 
	 */ 
	if((Tmask&ch) == (Spec|F)) 
		return 0; 
                 
	/* 
	 *  special character 
	 */ 
	switch(ch){ 
	case Shift: 
		shifted = 1; 
		break; 
	case Break: 
		break; 
	case Ctrl: 
		ctrled = 1; 
		break; 
	case Latin: 
		lstate = 1; 
		break; 
	default: 
		kbdputc(kbdq, ch); 
1994/0306    
	else { 
		switch(c){ 
		case Caps: 
			caps ^= 1; 
			return; 
		case Num: 
			num ^= 1; 
			return; 
		case Shift: 
			shift = 1; 
			return; 
		case Latin: 
			lstate = 1; 
			return; 
		case Ctrl: 
			ctl = 1; 
			return; 
		} 
1993/0907    
	} 
	return 0; 
1994/0306    
	kbdputc(kbdq, c); 
1993/0907    
} 
 
void 
lights(int l) 
{ 
	int s; 
	int tries; 
                 
	s = splhi(); 
	for(tries = 0; tries < 2000 && (KBDCTL & Sibf); tries++) 
		; 
	kdbdly(1); 
	KBDDAT = Kwrlights; 
	kbdackwait(); 
	for(tries = 0; tries < 2000 && (KBDCTL & Sibf); tries++) 
		; 
	kdbdly(1); 
	KBDDAT = kbd.l = l; 
	kbdackwait(); 
	splx(s); 
1994/0306    
	USED(l); 
1993/0907    
} 
 
static void 
1994/0201/sys/src/9/carrera/kbd.c:410,4521994/0306/sys/src/9/carrera/kbd.c:379,402
1993/0907    
	} 
 
 
	/* 
	 *  disable the interface 
	 */ 
1994/0306    
	/* wait for a quiescent controller */ 
1993/0907    
	OUTWAIT; 
	KBDCTL = Kwrcmd; 
	OUTWAIT; 
	KBDDAT = Csystem | Cinhibit | Cdisable | Cintena; 
1994/0306    
	KBDCTL = 0x20; 
	if(kbdwait() == 0) { 
		print("kbdinit: can't read ccc\n"); 
		ccc = 0; 
	} else 
		ccc = KBDDAT; 
1993/0907    
 
	/* 
	 *  set unix scan on the keyboard 
	 */ 
	OUTWAIT; 
	KBDDAT = Mdisable; 
	INWAIT; 
	if(KBDDAT != Rack) 
		return 0; 
	OUTWAIT; 
	KBDDAT = Msetscan; 
	ACKWAIT; 
	OUTWAIT; 
	KBDDAT = 0; 
	ACKWAIT; 
	OUTWAIT; 
	KBDDAT = Menable; 
1994/0306    
	/* enable kbd xfers and interrupts */ 
	ccc &= ~Ckbddis; 
	ccc |= Csf | Ckbdint | Cscs1 | Cmouseint; 
1993/0907    
 
	/* 
	 *  enable the interface 
	 */ 
	OUTWAIT; 
	KBDCTL = Kwrcmd; 
1994/0306    
	KBDCTL = 0x60; 
1993/0907    
	OUTWAIT; 
1993/1003    
	KBDDAT = Csystem | Cinhibit | Cintena | Cmseint; 
1994/0306    
	KBDDAT = ccc; 
1993/0907    
	OUTWAIT; 
	KBDCTL = Kenable; 
1993/1003    
	OUTWAIT; 
	KBDCTL = Kmseena; 
1993/0907    
	empty(); 
1993/1003    
 
1994/0201    
	mousecmd(0xEA);	/* streaming */ 
	mousecmd(0xE8);	/* set resolution */ 


source code copyright © 1990-2005 Lucent Technologies; see license
Plan 9 distribution
comments to russ cox (rsc@swtch.com)