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

1999/1005/pc/kbd.c (diff list | history)

1991/0702/sys/src/9/pc/kbd.c:2,71991/0703/sys/src/9/pc/kbd.c:2,9 (short | long)
1991/0702    
#include	"lib.h" 
#include	"dat.h" 
#include	"fns.h" 
1991/0703    
#include	"io.h" 
#include	"mem.h" 
1991/0702    
 
enum { 
	Data=		0x60,	/* data port */ 
1991/0702/sys/src/9/pc/kbd.c:16,331991/0703/sys/src/9/pc/kbd.c:18,246
1991/0702    
	 Rtimeout=	0x40,	/*  receive timeout */ 
	 Parity=	0x80,	/*  0==odd, 1==even */ 
 
	                 
1991/0703    
	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, 
	Caps=	Spec|0x64, 
	Num=	Spec|0x65, 
	No=	Spec|0x7F,	/* no mapping */ 
 
	Home=	F|13, 
	Up=	F|14, 
	Pgup=	F|15, 
	Print=	F|16, 
	Left=	View, 
	Right=	View, 
	End=	'\r', 
	Down=	View, 
	Pgdown=	View, 
	Ins=	F|20, 
	Del=	0x7F, 
1991/0702    
}; 
 
char noshift[256] =  
1991/0703    
uchar kbtab[] =  
1991/0702    
{ 
[0x00]	Nokey,	0x1b,	'1',	'2',	'3',	'4',	'5',	'6', 
1991/0703    
[0x00]	No,	0x1b,	'1',	'2',	'3',	'4',	'5',	'6', 
1991/0702    
[0x08]	'7',	'8',	'9',	'0',	'-',	'=',	'\b',	'\t', 
[0x10] 
[0x28] 
[0x30] 
1991/0703    
[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,	No, 
[0x38]	Latin,	' ',	Caps,	F|1,	F|2,	F|3,	F|4,	F|5, 
[0x40]	F|6,	F|7,	F|8,	F|9,	F|10,	Num,	F|12,	Home, 
[0x48]	No,	No,	No,	No,	No,	No,	No,	No, 
[0x50]	No,	No,	No,	No,	No,	No,	No,	F|11, 
[0x58]	F|12,	No,	No,	No,	No,	No,	No,	No, 
1991/0702    
}; 
 
1991/0703    
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,	No, 
[0x38]	Latin,	' ',	Caps,	F|1,	F|2,	F|3,	F|4,	F|5, 
[0x40]	F|6,	F|7,	F|8,	F|9,	F|10,	Num,	F|12,	Home, 
[0x48]	No,	No,	No,	No,	No,	No,	No,	No, 
[0x50]	No,	No,	No,	No,	No,	No,	No,	F|11, 
[0x58]	F|12,	No,	No,	No,	No,	No,	No,	No, 
}; 
 
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,	No,	Ctrl,	No,	No, 
[0x20]	No,	No,	No,	No,	No,	No,	No,	No, 
[0x28]	No,	No,	No,	No,	No,	No,	No,	No, 
[0x30]	No,	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,	Down,	No,	Right,	No,	End, 
[0x50]	Left,	Pgdown,	Ins,	Del,	No,	No,	No,	No, 
[0x58]	No,	No,	No,	No,	No,	No,	No,	No, 
}; 
 
struct latin 
{ 
	uchar	l; 
	char	c[2]; 
}latintab[] = { 
	'€',	"!!",	/* spanish initial ! */ 
	'€',	"c|",	/* cent */ 
	'€',	"c$",	/* cent */ 
	'€',	"l$",	/* pound sterling */ 
	'€',	"g$",	/* general currency */ 
	'€',	"y$",	/* yen */ 
	'€',	"j$",	/* yen */ 
	'€',	"||",	/* broken vertical bar */ 
	'€',	"SS",	/* section symbol */ 
	'€',	"\"\"",	/* dieresis */ 
	'€',	"cr",	/* copyright */ 
	'€',	"cO",	/* copyright */ 
	'€',	"sa",	/* super a, feminine ordinal */ 
	'€',	"<<",	/* left angle quotation */ 
	'€',	"no",	/* not sign, hooked overbar */ 
	'€',	"--",	/* soft hyphen */ 
	'€',	"rg",	/* registered trademark */ 
	'€',	"__",	/* macron */ 
	'€',	"s0",	/* degree (sup o) */ 
	'€',	"+-",	/* plus-minus */ 
	'€',	"s2",	/* sup 2 */ 
	'€',	"s3",	/* sup 3 */ 
	'€',	"''",	/* grave accent */ 
	'€',	"mu",	/* mu */ 
	'€',	"pg",	/* paragraph (pilcrow) */ 
	'€',	"..",	/* centered . */ 
	'€',	",,",	/* cedilla */ 
	'€',	"s1",	/* sup 1 */ 
	'€',	"so",	/* sup o */ 
	'€',	">>",	/* right angle quotation */ 
	'€',	"14",	/* 1/4 */ 
	'€',	"12",	/* 1/2 */ 
	'€',	"34",	/* 3/4 */ 
	'€',	"??",	/* spanish initial ? */ 
	'€',	"A`",	/* A grave */ 
	'€',	"A'",	/* A acute */ 
	'€',	"A^",	/* A circumflex */ 
	'€',	"A~",	/* A tilde */ 
	'€',	"A\"",	/* A dieresis */ 
	'€',	"A:",	/* A dieresis */ 
	'€',	"Ao",	/* A circle */ 
	'€',	"AO",	/* A circle */ 
	'€',	"Ae",	/* AE ligature */ 
	'€',	"AE",	/* AE ligature */ 
	'€',	"C,",	/* C cedilla */ 
	'€',	"E`",	/* E grave */ 
	'€',	"E'",	/* E acute */ 
	'€',	"E^",	/* E circumflex */ 
	'€',	"E\"",	/* E dieresis */ 
	'€',	"E:",	/* E dieresis */ 
	'€',	"I`",	/* I grave */ 
	'€',	"I'",	/* I acute */ 
	'€',	"I^",	/* I circumflex */ 
	'€',	"I\"",	/* I dieresis */ 
	'€',	"I:",	/* I dieresis */ 
	'€',	"D-",	/* Eth */ 
	'€',	"N~",	/* N tilde */ 
	'€',	"O`",	/* O grave */ 
	'€',	"O'",	/* O acute */ 
	'€',	"O^",	/* O circumflex */ 
	'€',	"O~",	/* O tilde */ 
	'€',	"O\"",	/* O dieresis */ 
	'€',	"O:",	/* O dieresis */ 
	'€',	"OE",	/* O dieresis */ 
	'€',	"Oe",	/* O dieresis */ 
	'€',	"xx",	/* times sign */ 
	'€',	"O/",	/* O slash */ 
	'€',	"U`",	/* U grave */ 
	'€',	"U'",	/* U acute */ 
	'€',	"U^",	/* U circumflex */ 
	'€',	"U\"",	/* U dieresis */ 
	'€',	"U:",	/* U dieresis */ 
	'€',	"UE",	/* U dieresis */ 
	'€',	"Ue",	/* U dieresis */ 
	'€',	"Y'",	/* Y acute */ 
	'€',	"P|",	/* Thorn */ 
	'€',	"Th",	/* Thorn */ 
	'€',	"TH",	/* Thorn */ 
	'€',	"ss",	/* sharp s */ 
	'€',	"a`",	/* a grave */ 
	'€',	"a'",	/* a acute */ 
	'€',	"a^",	/* a circumflex */ 
	'€',	"a~",	/* a tilde */ 
	'€',	"a\"",	/* a dieresis */ 
	'€',	"a:",	/* a dieresis */ 
	'€',	"ao",	/* a circle */ 
	'€',	"ae",	/* ae ligature */ 
	'€',	"c,",	/* c cedilla */ 
	'€',	"e`",	/* e grave */ 
	'€',	"e'",	/* e acute */ 
	'€',	"e^",	/* e circumflex */ 
	'€',	"e\"",	/* e dieresis */ 
	'€',	"e:",	/* e dieresis */ 
	'€',	"i`",	/* i grave */ 
	'€',	"i'",	/* i acute */ 
	'€',	"i^",	/* i circumflex */ 
	'€',	"i\"",	/* i dieresis */ 
	'€',	"i:",	/* i dieresis */ 
	'€',	"d-",	/* eth */ 
	'€',	"n~",	/* n tilde */ 
	'€',	"o`",	/* o grave */ 
	'€',	"o'",	/* o acute */ 
	'€',	"o^",	/* o circumflex */ 
	'€',	"o~",	/* o tilde */ 
	'€',	"o\"",	/* o dieresis */ 
	'€',	"o:",	/* o dieresis */ 
	'€',	"oe",	/* o dieresis */ 
	'€',	"-:",	/* divide sign */ 
	'€',	"o/",	/* o slash */ 
	'€',	"u`",	/* u grave */ 
	'€',	"u'",	/* u acute */ 
	'€',	"u^",	/* u circumflex */ 
	'€',	"u\"",	/* u dieresis */ 
	'€',	"u:",	/* u dieresis */ 
	'€',	"ue",	/* u dieresis */ 
	'€',	"y'",	/* y acute */ 
	'€',	"th",	/* thorn */ 
	'€',	"p|",	/* thorn */ 
	'€',	"y\"",	/* y dieresis */ 
	'€',	"y:",	/* y dieresis */ 
	0,	0, 
}; 
 
KIOQ	kbdq; 
 
int 
latin1(int k1, int k2) 
{ 
	int i; 
	struct latin *l; 
 
	for(l=latintab; l->l; l++) 
		if(k1==l->c[0] && k2==l->c[1]) 
			return l->l; 
	return 0; 
} 
 
void 
kbdinit(void) 
{ 
	initq(&kbdq); 
	setvec(Kbdvec, kbdintr, SEGIG); 
} 
 
1991/0702    
/* 
 *  get a byte from the keyboard 
 */ 
1991/0702/sys/src/9/pc/kbd.c:34,1351991/0703/sys/src/9/pc/kbd.c:247,383
1991/0702    
int 
kbdc(void) 
{ 
	while((inb(Status)&Inready)==0) 
		; 
	return inb(Data); 
1991/0703    
	int c; 
 
	for(;;){ 
		while((inb(Status)&Inready)==0) 
			; 
		kbdintr(&c); 
		c = getc(&kbdq); 
		if(c != -1) 
			return c; 
	} 
1991/0702    
} 
 
1	0x1b, 
3b	F1, 
3c	F2, 
3d	F3, 
3e	F4, 
3f	F5, 
40	f6, 
41	F7, 
42	F8, 
43	F9, 
44	F10, 
57	F11, 
58	F12, 
e0 52	INS, 
e0 53	DEL, 
2	'1', 
3	'2', 
4	'3', 
5	'4', 
6	'5', 
7	'6', 
8	'7', 
9	'8', 
A	'9', 
B	'0', 
C	'-', 
D	'=', 
E	'\b', 
E0 47	Home, 
F	'\t', 
10	'q', 
11	'w', 
12	'e', 
13	'r', 
14	't', 
15	'y', 
16	'u', 
17	'i', 
18	'o', 
19	'p', 
1a	'[', 
1b	']', 
2b	'\\', 
e0 49	Pageup, 
3a	Capslock, 
1e	'a' 
1f	's'  
20	'd' 
21	'f' 
22	'g' 
23	'h' 
24	'j' 
25	'k' 
26	'l' 
27	';' 
28	'\'' 
1c	'\r' 
2a	Lshift, 
2c	'z' 
2d	'x' 
2e	'c' 
2f	'v' 
30	'b' 
31	'n' 
32	'm' 
33	',' 
34	'.' 
35	'/' 
36	Rshift, 
e0 51	Pagedown, 
e0 4f	End, 
e0 48	Uparrow, 
e0 50	Downarrow, 
e0 4b	Leftarrow, 
e0 4d   Rightarrow, 
e0 1d	Rctl, 
e0 38	Ralt, 
39	Space, 
38	Lalt, 
1d	Lctl, 
29	'`', 
1d 38 1 81 b8 9d	F1 
1d 38 21 a1 b8 9d	F2 
	2e ae		F3 
	19 99		F4 
	26		F5 
	2F		F6 
1991/0703    
int 
kbdputc(IOQ* q, int c) 
{ 
	screenputc(c); 
	putc(q, c); 
} 
 
/* 
 *  keyboard interrupt 
 */ 
void 
kbdintr(void *a) 
{ 
	int c, nc; 
	static int esc1, esc2; 
	static int shift; 
	static int caps; 
	static int ctl; 
	static int num; 
	static int lstate, k1, k2; 
	int keyup; 
1991/0702    
 
e1 1d 45 e1 9d cf	F7 
e0 46 e0 c6		f8 
e0 2a e0 37 e0 b7 e0 aa	f9 
54			f10 
45			f11 
46			f12 
1991/0703    
	/* 
	 *  get a character to be there 
	 */ 
	c = inb(Data); 
 
	keyup = c&0x80; 
	c &= 0x7f; 
	if(c > sizeof kbtab){ 
		print("unknown key %ux\n", c|keyup); 
		kbdputc(&kbdq, k1); 
		goto out; 
	} 
 
	/* 
	 *  e0's is the first of a 2 character sequence 
	 */ 
	if(c == 0xe0){ 
		esc1 = 1; 
		goto out; 
	} else if(c == 0xe1){ 
		esc2 = 2; 
		goto out; 
	} 
 
	if(esc1){ 
		c = kbtabesc1[c]; 
		esc1 = 0; 
	} else if(esc2){ 
		esc2--; 
		goto out; 
	} else if(shift) 
		c = kbtabshift[c]; 
	else 
		c = kbtab[c]; 
 
	if(caps && c<='z' && c>='a') 
		c += 'A' - 'a'; 
 
	/* 
	 *  keyup only important for shifts 
	 */ 
	if(keyup){ 
		switch(c){ 
		case Shift: 
			shift = 0; 
			break; 
		case Ctrl: 
			ctl = 0; 
			break; 
		} 
		goto out; 
	} 
 
	/* 
 	 *  normal character 
	 */ 
	if(!(c & Spec)){ 
		if(ctl) 
			c &= 0x1f; 
		switch(lstate){ 
		case 1: 
			k1 = c; 
			lstate = 2; 
			return; 
		case 2: 
			k2 = c; 
			lstate = 0; 
			c = latin1(k1, k2); 
			if(c == 0){ 
				kbdputc(&kbdq, k1); 
				c = k2; 
			} 
			/* fall through */ 
		default: 
			break; 
		} 
	} else { 
		switch(c){ 
		case Caps: 
			caps ^= 1; 
			goto out; 
		case Num: 
			num ^= 1; 
			goto out; 
		case Shift: 
			shift = 1; 
			goto out; 
		case Latin: 
			lstate = 1; 
			goto out; 
		case Ctrl: 
			ctl = 1; 
			goto out; 
		} 
	} 
	kbdputc(&kbdq, c); 
out: 
	INTENABLE;			/* reenable interrupt */ 
	return; 
} 
1991/0703/sys/src/9/pc/kbd.c:378,3831991/0705/sys/src/9/pc/kbd.c:378,383 (short | long)
1991/0703    
	} 
	kbdputc(&kbdq, c); 
out: 
	INTENABLE;			/* reenable interrupt */ 
1991/0705    
	INT0ENABLE;			/* reenable interrupt */ 
1991/0703    
	return; 
} 
1991/0705/sys/src/9/pc/kbd.c:1,91991/0706/sys/src/9/pc/kbd.c:1,9 (short | long)
1991/0702    
#include	"u.h" 
#include	"lib.h" 
1991/0706    
#include	"mem.h" 
1991/0702    
#include	"dat.h" 
#include	"fns.h" 
1991/0703    
#include	"io.h" 
#include	"mem.h" 
1991/0702    
 
enum { 
	Data=		0x60,	/* data port */ 
1991/0705/sys/src/9/pc/kbd.c:241,2681991/0706/sys/src/9/pc/kbd.c:241,251
1991/0703    
	setvec(Kbdvec, kbdintr, SEGIG); 
} 
 
1991/0702    
/* 
 *  get a byte from the keyboard 
 */ 
int 
kbdc(void) 
{ 
1991/0703    
	int c; 
                 
	for(;;){ 
		while((inb(Status)&Inready)==0) 
			; 
		kbdintr(&c); 
		c = getc(&kbdq); 
		if(c != -1) 
			return c; 
	} 
1991/0702    
} 
                 
1991/0703    
int 
kbdputc(IOQ* q, int c) 
{ 
	screenputc(c); 
1991/0706    
	if(c==0x10) 
		panic("^p"); 
1991/0703    
	putc(q, c); 
} 
 
1991/0705/sys/src/9/pc/kbd.c:270,2761991/0706/sys/src/9/pc/kbd.c:253,259
1991/0703    
 *  keyboard interrupt 
 */ 
void 
kbdintr(void *a) 
1991/0706    
kbdintr(Ureg *ur) 
1991/0703    
{ 
	int c, nc; 
	static int esc1, esc2; 
1991/0705/sys/src/9/pc/kbd.c:291,2971991/0706/sys/src/9/pc/kbd.c:274,280
1991/0703    
	if(c > sizeof kbtab){ 
		print("unknown key %ux\n", c|keyup); 
		kbdputc(&kbdq, k1); 
		goto out; 
1991/0706    
		return; 
1991/0703    
	} 
 
	/* 
1991/0705/sys/src/9/pc/kbd.c:299,3081991/0706/sys/src/9/pc/kbd.c:282,291
1991/0703    
	 */ 
	if(c == 0xe0){ 
		esc1 = 1; 
		goto out; 
1991/0706    
		return; 
1991/0703    
	} else if(c == 0xe1){ 
		esc2 = 2; 
		goto out; 
1991/0706    
		return; 
1991/0703    
	} 
 
	if(esc1){ 
1991/0705/sys/src/9/pc/kbd.c:310,3161991/0706/sys/src/9/pc/kbd.c:293,299
1991/0703    
		esc1 = 0; 
	} else if(esc2){ 
		esc2--; 
		goto out; 
1991/0706    
		return; 
1991/0703    
	} else if(shift) 
		c = kbtabshift[c]; 
	else 
1991/0705/sys/src/9/pc/kbd.c:331,3371991/0706/sys/src/9/pc/kbd.c:314,320
1991/0703    
			ctl = 0; 
			break; 
		} 
		goto out; 
1991/0706    
		return; 
1991/0703    
	} 
 
	/* 
1991/0705/sys/src/9/pc/kbd.c:361,3831991/0706/sys/src/9/pc/kbd.c:344,364
1991/0703    
		switch(c){ 
		case Caps: 
			caps ^= 1; 
			goto out; 
1991/0706    
			return; 
1991/0703    
		case Num: 
			num ^= 1; 
			goto out; 
1991/0706    
			return; 
1991/0703    
		case Shift: 
			shift = 1; 
			goto out; 
1991/0706    
			return; 
1991/0703    
		case Latin: 
			lstate = 1; 
			goto out; 
1991/0706    
			return; 
1991/0703    
		case Ctrl: 
			ctl = 1; 
			goto out; 
1991/0706    
			return; 
1991/0703    
		} 
	} 
	kbdputc(&kbdq, c); 
out: 
1991/0705    
	INT0ENABLE;			/* reenable interrupt */ 
1991/0703    
	return; 
} 
1991/0706/sys/src/9/pc/kbd.c:241,2541991/0711/sys/src/9/pc/kbd.c:241,246 (short | long)
1991/0703    
	setvec(Kbdvec, kbdintr, SEGIG); 
} 
 
1991/0702    
int 
1991/0703    
kbdputc(IOQ* q, int c) 
{ 
1991/0706    
	if(c==0x10) 
		panic("^p"); 
1991/0703    
	putc(q, c); 
} 
                 
/* 
 *  keyboard interrupt 
 */ 
1991/0711/sys/src/9/pc/kbd.c:238,2441991/0716/sys/src/9/pc/kbd.c:238,244 (short | long)
1991/0703    
kbdinit(void) 
{ 
	initq(&kbdq); 
	setvec(Kbdvec, kbdintr, SEGIG); 
1991/0716    
	setvec(Kbdvec, kbdintr); 
1991/0703    
} 
 
/* 
1991/0716/sys/src/9/pc/kbd.c:257,2631991/0719/sys/src/9/pc/kbd.c:257,263 (short | long)
1991/0703    
	int keyup; 
1991/0702    
 
1991/0703    
	/* 
	 *  get a character to be there 
1991/0719    
	 *  get a character 
1991/0703    
	 */ 
	c = inb(Data); 
 
1991/0719/sys/src/9/pc/kbd.c:11,231991/0730/sys/src/9/pc/kbd.c:11,25 (short | long)
1991/0702    
	Status=		0x64,	/* status port */ 
	 Inready=	0x01,	/*  input character ready */ 
	 Outbusy=	0x02,	/*  output busy */ 
	 Sysflag=	0x04,	/*  ??? */ 
1991/0730    
	 Sysflag=	0x04,	/*  system flag */ 
1991/0702    
	 Cmddata=	0x08,	/*  cmd==0, data==1 */ 
	 kbdinh=	0x10,	/*  keyboard inhibited */ 
	 Xtimeout=	0x20,	/*  transmit timeout */ 
	 Rtimeout=	0x40,	/*  receive timeout */ 
	 Parity=	0x80,	/*  0==odd, 1==even */ 
1991/0730    
	 Inhibit=	0x10,	/*  keyboard/mouse inhibited */ 
	 Minready=	0x20,	/*  mouse character ready */ 
	 Rtimeout=	0x40,	/*  general timeout */ 
	 Parity=	0x80,	/*  1 == error */ 
1991/0702    
 
1991/0730    
	Cmd=		0x64,	/* command port (write only) */ 
 
1991/0703    
	Spec=	0x80, 
 
	PF=	Spec|0x20,	/* num pad function key */ 
1991/0719/sys/src/9/pc/kbd.c:237,2441991/0730/sys/src/9/pc/kbd.c:239,273
1991/0703    
void 
kbdinit(void) 
{ 
1991/0730    
	uchar c; 
 
1991/0703    
	initq(&kbdq); 
1991/0716    
	setvec(Kbdvec, kbdintr); 
1991/0730    
 
	/* wait for a quiescent controller */ 
	while((c = inb(Status)) & (Outbusy | Inready)) 
		if(c & Inready) 
			inb(Data); 
 
	/* read controller command byte */ 
	outb(Cmd, 0x20); 
	while(!(inb(Status) & Inready)) 
		; 
	c = inb(Data); 
print("input completed\n"); 
delay(5000); 
 
	/* enable mouse and mouse interupts */ 
	c = (c&~0x20) | 0x02; 
	outb(Cmd, 0x60); 
	while(inb(Status) & Outbusy) 
		; 
	outb(Data, c); 
print("mouse enabled\n"); 
delay(5000); 
 
	initq(&mouseq); 
	setvec(Mousevec, kbdintr); 
1991/0703    
} 
 
/* 
1991/0719/sys/src/9/pc/kbd.c:247,2531991/0730/sys/src/9/pc/kbd.c:276,282
1991/0703    
void 
1991/0706    
kbdintr(Ureg *ur) 
1991/0703    
{ 
	int c, nc; 
1991/0730    
	int s, c, nc; 
1991/0703    
	static int esc1, esc2; 
	static int shift; 
	static int caps; 
1991/0719/sys/src/9/pc/kbd.c:257,2651991/0730/sys/src/9/pc/kbd.c:286,304
1991/0703    
	int keyup; 
1991/0702    
 
1991/0703    
	/* 
1991/0719    
	 *  get a character 
1991/0730    
	 *  get status and character 
1991/0703    
	 */ 
1991/0730    
	s = inb(Status); 
1991/0703    
	c = inb(Data); 
1991/0730    
 
	/* 
	 *  if it's the mouse... 
	 */ 
	if(s & Minready){ 
print("mousechar\n"); 
		mouseputc(&mouseq, c); 
		return; 
	} 
1991/0703    
 
	keyup = c&0x80; 
	c &= 0x7f; 
1991/0730/sys/src/9/pc/kbd.c:5,101991/0731/sys/src/9/pc/kbd.c:5,14 (short | long)
1991/0702    
#include	"fns.h" 
1991/0703    
#include	"io.h" 
1991/0702    
 
1991/0731    
#include	<libg.h> 
#include	<gnot.h> 
#include	"screen.h" 
 
1991/0702    
enum { 
	Data=		0x60,	/* data port */ 
 
1991/0730/sys/src/9/pc/kbd.c:16,221991/0731/sys/src/9/pc/kbd.c:20,26
1991/0730    
	 Inhibit=	0x10,	/*  keyboard/mouse inhibited */ 
	 Minready=	0x20,	/*  mouse character ready */ 
	 Rtimeout=	0x40,	/*  general timeout */ 
	 Parity=	0x80,	/*  1 == error */ 
1991/0731    
	 Parity=	0x80, 
1991/0702    
 
1991/0730    
	Cmd=		0x64,	/* command port (write only) */ 
 
1991/0730/sys/src/9/pc/kbd.c:24,301991/0731/sys/src/9/pc/kbd.c:28,34
1991/0703    
 
	PF=	Spec|0x20,	/* num pad function key */ 
	View=	Spec|0x00,	/* view (shift window up) */ 
	F=	Spec|0x40,	/* function key */ 
1991/0731    
	KF=	Spec|0x40,	/* function key */ 
1991/0703    
	Shift=	Spec|0x60, 
	Break=	Spec|0x61, 
	Ctrl=	Spec|0x62, 
1991/0730/sys/src/9/pc/kbd.c:33,481991/0731/sys/src/9/pc/kbd.c:37,52
1991/0703    
	Num=	Spec|0x65, 
	No=	Spec|0x7F,	/* no mapping */ 
 
	Home=	F|13, 
	Up=	F|14, 
	Pgup=	F|15, 
	Print=	F|16, 
1991/0731    
	Home=	KF|13, 
	Up=	KF|14, 
	Pgup=	KF|15, 
	Print=	KF|16, 
1991/0703    
	Left=	View, 
	Right=	View, 
	End=	'\r', 
	Down=	View, 
	Pgdown=	View, 
	Ins=	F|20, 
1991/0731    
	Ins=	KF|20, 
1991/0703    
	Del=	0x7F, 
1991/0702    
}; 
 
1991/0730/sys/src/9/pc/kbd.c:55,651991/0731/sys/src/9/pc/kbd.c:59,69
1991/0703    
[0x20]	'd',	'f',	'g',	'h',	'j',	'k',	'l',	';', 
[0x28]	'\'',	'`',	Shift,	'\\',	'z',	'x',	'c',	'v', 
[0x30]	'b',	'n',	'm',	',',	'.',	'/',	Shift,	No, 
[0x38]	Latin,	' ',	Caps,	F|1,	F|2,	F|3,	F|4,	F|5, 
[0x40]	F|6,	F|7,	F|8,	F|9,	F|10,	Num,	F|12,	Home, 
1991/0731    
[0x38]	Latin,	' ',	Caps,	KF|1,	KF|2,	KF|3,	KF|4,	KF|5, 
[0x40]	KF|6,	KF|7,	KF|8,	KF|9,	KF|10,	Num,	KF|12,	Home, 
1991/0703    
[0x48]	No,	No,	No,	No,	No,	No,	No,	No, 
[0x50]	No,	No,	No,	No,	No,	No,	No,	F|11, 
[0x58]	F|12,	No,	No,	No,	No,	No,	No,	No, 
1991/0731    
[0x50]	No,	No,	No,	No,	No,	No,	No,	KF|11, 
[0x58]	KF|12,	No,	No,	No,	No,	No,	No,	No, 
1991/0702    
}; 
 
1991/0703    
uchar kbtabshift[] = 
1991/0730/sys/src/9/pc/kbd.c:71,811991/0731/sys/src/9/pc/kbd.c:75,85
1991/0703    
[0x20]	'D',	'F',	'G',	'H',	'J',	'K',	'L',	':', 
[0x28]	'"',	'~',	Shift,	'|',	'Z',	'X',	'C',	'V', 
[0x30]	'B',	'N',	'M',	'<',	'>',	'?',	Shift,	No, 
[0x38]	Latin,	' ',	Caps,	F|1,	F|2,	F|3,	F|4,	F|5, 
[0x40]	F|6,	F|7,	F|8,	F|9,	F|10,	Num,	F|12,	Home, 
1991/0731    
[0x38]	Latin,	' ',	Caps,	KF|1,	KF|2,	KF|3,	KF|4,	KF|5, 
[0x40]	KF|6,	KF|7,	KF|8,	KF|9,	KF|10,	Num,	KF|12,	Home, 
1991/0703    
[0x48]	No,	No,	No,	No,	No,	No,	No,	No, 
[0x50]	No,	No,	No,	No,	No,	No,	No,	F|11, 
[0x58]	F|12,	No,	No,	No,	No,	No,	No,	No, 
1991/0731    
[0x50]	No,	No,	No,	No,	No,	No,	No,	KF|11, 
[0x58]	KF|12,	No,	No,	No,	No,	No,	No,	No, 
1991/0703    
}; 
 
uchar kbtabesc1[] = 
1991/0730/sys/src/9/pc/kbd.c:236,2481991/0731/sys/src/9/pc/kbd.c:240,279
1991/0703    
	return 0; 
} 
 
1991/0731    
static void 
mousecmd(int cmd, int arg) 
{ 
	unsigned int c; 
 
	do { 
		while(inb(Status) & Outbusy) 
			; 
		outb(Cmd, 0xD4); 
		while(inb(Status) & Outbusy) 
			; 
		outb(Data, cmd); 
		if(arg >= 0){ 
			while(inb(Status) & Outbusy) 
				; 
			outb(Data, arg); 
		} 
		while(!(inb(Status) & Inready)) 
			; 
		c = inb(Data); 
	} while(c == 0xFE); 
	if(c != 0xFA) 
		print("mouse command returns bad status %lux", c); 
} 
 
1991/0703    
void 
kbdinit(void) 
{ 
1991/0730    
	uchar c; 
1991/0731    
	int c, s; 
1991/0730    
 
1991/0703    
	initq(&kbdq); 
1991/0716    
	setvec(Kbdvec, kbdintr); 
1991/0731    
	initq(&mouseq); 
	setvec(Mousevec, kbdintr); 
1991/0730    
 
	/* wait for a quiescent controller */ 
	while((c = inb(Status)) & (Outbusy | Inready)) 
1991/0730/sys/src/9/pc/kbd.c:249,2801991/0731/sys/src/9/pc/kbd.c:280,349
1991/0730    
		if(c & Inready) 
			inb(Data); 
 
	/* read controller command byte */ 
	outb(Cmd, 0x20); 
	while(!(inb(Status) & Inready)) 
		; 
	c = inb(Data); 
print("input completed\n"); 
delay(5000); 
                 
	/* enable mouse and mouse interupts */ 
	c = (c&~0x20) | 0x02; 
1991/0731    
	/* enable kbd/mouse xfers and interrupts */ 
1991/0730    
	outb(Cmd, 0x60); 
	while(inb(Status) & Outbusy) 
		; 
	outb(Data, c); 
print("mouse enabled\n"); 
1991/0731    
	outb(Data, 0x47); 
	while(inb(Status) & Outbusy) 
		; 
	outb(Cmd, 0xA8); 
 
	/* make mouse streaming (and enabled) */ 
	mousecmd(0xEA, -1); 
	mousecmd(0xF4, -1); 
 
	/* resolution */ 
	mousecmd(0xE8, 0x03); 
print("res set\n"); 
1991/0730    
delay(5000); 
1991/0731    
} 
1991/0730    
 
	initq(&mouseq); 
	setvec(Mousevec, kbdintr); 
1991/0731    
/* 
 *  mouse message is three bytes 
 * 
 *	byte 0 -	0 0 SDY SDX 1 M R L 
 *	byte 1 -	DX 
 *	byte 2 -	DY 
 */ 
static void 
mymouseputc(int c) 
{ 
	static short msg[3]; 
	static int nb; 
	static uchar b[] = {0, 4, 1, 5, 2, 6, 3, 7}; 
	static lastdx, lastdy; 
	int diff; 
	extern Mouseinfo mouse; 
 
	/*  
	 *  check byte 0 for consistency 
	 */ 
	if(nb==0 && (c&0xc8)!=0x08) 
		return; 
 
	msg[nb] = c; 
	if(++nb == 3){ 
		nb = 0; 
		if(msg[0] & 0x10) 
			msg[1] |= 0xFF00; 
		if(msg[0] & 0x20) 
			msg[2] |= 0xFF00; 
 
		mouse.newbuttons = b[msg[0]&7]; 
		mouse.dx = msg[1]; 
		mouse.dy = -msg[2]; 
print("%d %d\n", mouse.dx, mouse.dy); 
		mouse.track = 1; 
		mouseclock(); 
	} 
1991/0703    
} 
 
/* 
 *  keyboard interrupt 
 */ 
void 
1991/0706    
kbdintr(Ureg *ur) 
1991/0731    
int 
kbdintr0(void) 
1991/0703    
{ 
1991/0730    
	int s, c, nc; 
1991/0703    
	static int esc1, esc2; 
1991/0730/sys/src/9/pc/kbd.c:286,2941991/0731/sys/src/9/pc/kbd.c:355,369
1991/0703    
	int keyup; 
1991/0702    
 
1991/0703    
	/* 
1991/0730    
	 *  get status and character 
1991/0731    
	 *  get status 
1991/0703    
	 */ 
1991/0730    
	s = inb(Status); 
1991/0731    
	if(!(s&Inready)) 
		return -1; 
 
	/* 
	 *  get the character 
	 */ 
1991/0703    
	c = inb(Data); 
1991/0730    
 
	/* 
1991/0730/sys/src/9/pc/kbd.c:295,3031991/0731/sys/src/9/pc/kbd.c:370,377
1991/0730    
	 *  if it's the mouse... 
	 */ 
	if(s & Minready){ 
print("mousechar\n"); 
		mouseputc(&mouseq, c); 
		return; 
1991/0731    
		mymouseputc(c); 
		return 0; 
1991/0730    
	} 
1991/0703    
 
	keyup = c&0x80; 
1991/0730/sys/src/9/pc/kbd.c:305,3111991/0731/sys/src/9/pc/kbd.c:379,385
1991/0703    
	if(c > sizeof kbtab){ 
		print("unknown key %ux\n", c|keyup); 
		kbdputc(&kbdq, k1); 
1991/0706    
		return; 
1991/0731    
		return 0; 
1991/0703    
	} 
 
	/* 
1991/0730/sys/src/9/pc/kbd.c:313,3221991/0731/sys/src/9/pc/kbd.c:387,396
1991/0703    
	 */ 
	if(c == 0xe0){ 
		esc1 = 1; 
1991/0706    
		return; 
1991/0731    
		return 0; 
1991/0703    
	} else if(c == 0xe1){ 
		esc2 = 2; 
1991/0706    
		return; 
1991/0731    
		return 0; 
1991/0703    
	} 
 
	if(esc1){ 
1991/0730/sys/src/9/pc/kbd.c:324,3301991/0731/sys/src/9/pc/kbd.c:398,404
1991/0703    
		esc1 = 0; 
	} else if(esc2){ 
		esc2--; 
1991/0706    
		return; 
1991/0731    
		return 0; 
1991/0703    
	} else if(shift) 
		c = kbtabshift[c]; 
	else 
1991/0730/sys/src/9/pc/kbd.c:345,3511991/0731/sys/src/9/pc/kbd.c:419,425
1991/0703    
			ctl = 0; 
			break; 
		} 
1991/0706    
		return; 
1991/0731    
		return 0; 
1991/0703    
	} 
 
	/* 
1991/0730/sys/src/9/pc/kbd.c:358,3641991/0731/sys/src/9/pc/kbd.c:432,438
1991/0703    
		case 1: 
			k1 = c; 
			lstate = 2; 
			return; 
1991/0731    
			return 0; 
1991/0703    
		case 2: 
			k2 = c; 
			lstate = 0; 
1991/0730/sys/src/9/pc/kbd.c:375,3951991/0731/sys/src/9/pc/kbd.c:449,476
1991/0703    
		switch(c){ 
		case Caps: 
			caps ^= 1; 
1991/0706    
			return; 
1991/0731    
			return 0; 
1991/0703    
		case Num: 
			num ^= 1; 
1991/0706    
			return; 
1991/0731    
			return 0; 
1991/0703    
		case Shift: 
			shift = 1; 
1991/0706    
			return; 
1991/0731    
			return 0; 
1991/0703    
		case Latin: 
			lstate = 1; 
1991/0706    
			return; 
1991/0731    
			return 0; 
1991/0703    
		case Ctrl: 
			ctl = 1; 
1991/0706    
			return; 
1991/0731    
			return 0; 
1991/0703    
		} 
	} 
	kbdputc(&kbdq, c); 
	return; 
1991/0731    
	return 0; 
} 
 
void 
kbdintr(Ureg *ur) 
{ 
	while(kbdintr0() == 0) 
		; 
1991/0703    
} 
1991/0731/sys/src/9/pc/kbd.c:294,3021991/0801/sys/src/9/pc/kbd.c:294,300 (short | long)
1991/0731    
	mousecmd(0xF4, -1); 
 
	/* resolution */ 
	mousecmd(0xE8, 0x03); 
print("res set\n"); 
1991/0730    
delay(5000); 
1991/0801    
/*	mousecmd(0xE8, 0x03); /**/ 
1991/0731    
} 
1991/0730    
 
1991/0731    
/* 
1991/0731/sys/src/9/pc/kbd.c:333,3391991/0801/sys/src/9/pc/kbd.c:331,336
1991/0731    
		mouse.newbuttons = b[msg[0]&7]; 
		mouse.dx = msg[1]; 
		mouse.dy = -msg[2]; 
print("%d %d\n", mouse.dx, mouse.dy); 
		mouse.track = 1; 
		mouseclock(); 
	} 
1991/0801/sys/src/9/pc/kbd.c:240,2681991/0803/sys/src/9/pc/kbd.c:240,296 (short | long)
1991/0703    
	return 0; 
} 
 
1991/0731    
static void 
mousecmd(int cmd, int arg) 
1991/0803    
/* 
 *  wait for output no longer busy 
 */ 
static int 
outready(void) 
1991/0731    
{ 
1991/0803    
	int tries; 
 
	for(tries = 0; (inb(Status) & Outbusy); tries++) 
		if(tries > 1000) 
			return -1; 
	return 0; 
} 
 
/* 
 *  wait for input 
 */ 
static int 
inready(void) 
{ 
	int tries; 
 
	for(tries = 0; !(inb(Status) & Inready); tries++) 
		if(tries > 1000) 
			return -1; 
	return 0; 
} 
 
/* 
 *  send a command to the mouse 
 */ 
static int 
mousecmd(int cmd) 
{ 
1991/0731    
	unsigned int c; 
1991/0803    
	int tries; 
1991/0731    
 
	do { 
		while(inb(Status) & Outbusy) 
			; 
1991/0803    
	for(tries=0; tries < 10; tries++){ 
		if(outready() < 0) 
			return -1; 
1991/0731    
		outb(Cmd, 0xD4); 
		while(inb(Status) & Outbusy) 
			; 
1991/0803    
		if(outready() < 0) 
			return -1; 
1991/0731    
		outb(Data, cmd); 
		if(arg >= 0){ 
			while(inb(Status) & Outbusy) 
				; 
			outb(Data, arg); 
		} 
		while(!(inb(Status) & Inready)) 
			; 
1991/0803    
		if(inready() < 0) 
			return -1; 
1991/0731    
		c = inb(Data); 
	} while(c == 0xFE); 
	if(c != 0xFA) 
		print("mouse command returns bad status %lux", c); 
1991/0803    
		return -1; 
	return 0; 
1991/0731    
} 
 
1991/0703    
void 
1991/0801/sys/src/9/pc/kbd.c:269,2741991/0803/sys/src/9/pc/kbd.c:297,303
1991/0703    
kbdinit(void) 
{ 
1991/0731    
	int c, s; 
1991/0803    
	int tries; 
1991/0730    
 
1991/0703    
	initq(&kbdq); 
1991/0716    
	setvec(Kbdvec, kbdintr); 
1991/0801/sys/src/9/pc/kbd.c:282,3001991/0803/sys/src/9/pc/kbd.c:311,327
1991/0730    
 
1991/0731    
	/* enable kbd/mouse xfers and interrupts */ 
1991/0730    
	outb(Cmd, 0x60); 
	while(inb(Status) & Outbusy) 
		; 
1991/0803    
	if(outready() < 0) 
		print("kbd init failed\n"); 
1991/0731    
	outb(Data, 0x47); 
	while(inb(Status) & Outbusy) 
		; 
1991/0803    
	if(outready() < 0) 
		print("kbd init failed\n"); 
1991/0731    
	outb(Cmd, 0xA8); 
 
	/* make mouse streaming (and enabled) */ 
	mousecmd(0xEA, -1); 
	mousecmd(0xF4, -1); 
                 
	/* resolution */ 
1991/0801    
/*	mousecmd(0xE8, 0x03); /**/ 
1991/0803    
	/* make mouse streaming, enabled */ 
	if(mousecmd(0xEA) < 0 
	|| mousecmd(0xF4) < 0) 
		print("can't initialize mouse\n"); 
1991/0731    
} 
1991/0730    
 
1991/0731    
/* 
1991/0803/sys/src/9/pc/kbd.c:336,3421991/0809/sys/src/9/pc/kbd.c:336,342 (short | long)
1991/0731    
{ 
	static short msg[3]; 
	static int nb; 
	static uchar b[] = {0, 4, 1, 5, 2, 6, 3, 7}; 
1991/0809    
	static uchar b[] = {0, 1, 4, 5, 2, 3, 6, 7}; 
1991/0731    
	static lastdx, lastdy; 
	int diff; 
	extern Mouseinfo mouse; 
1991/0809/sys/src/9/pc/kbd.c:418,4231991/0821/sys/src/9/pc/kbd.c:418,424 (short | long)
1991/0703    
	} 
 
	if(esc1){ 
1991/0821    
print("\nescape1 %lux\n", c); 
1991/0703    
		c = kbtabesc1[c]; 
		esc1 = 0; 
	} else if(esc2){ 
1991/0821/sys/src/9/pc/kbd.c:398,4111991/0822/sys/src/9/pc/kbd.c:398,403 (short | long)
1991/0731    
		return 0; 
1991/0730    
	} 
1991/0703    
 
	keyup = c&0x80; 
	c &= 0x7f; 
	if(c > sizeof kbtab){ 
		print("unknown key %ux\n", c|keyup); 
		kbdputc(&kbdq, k1); 
1991/0731    
		return 0; 
1991/0703    
	} 
                 
	/* 
	 *  e0's is the first of a 2 character sequence 
	 */ 
1991/0821/sys/src/9/pc/kbd.c:417,4261991/0822/sys/src/9/pc/kbd.c:409,427
1991/0731    
		return 0; 
1991/0703    
	} 
 
1991/0822    
	keyup = c&0x80; 
	c &= 0x7f; 
	if(c > sizeof kbtab){ 
		print("unknown key %ux\n", c|keyup); 
		kbdputc(&kbdq, k1); 
		return 0; 
	} 
 
1991/0703    
	if(esc1){ 
1991/0821    
print("\nescape1 %lux\n", c); 
1991/0703    
		c = kbtabesc1[c]; 
		esc1 = 0; 
1991/0822    
		kbdputc(&kbdq, c); 
		return 0; 
1991/0703    
	} else if(esc2){ 
		esc2--; 
1991/0731    
		return 0; 
1991/0822/sys/src/9/pc/kbd.c:359,3641991/0823/sys/src/9/pc/kbd.c:359,365 (short | long)
1991/0731    
		mouse.dx = msg[1]; 
		mouse.dy = -msg[2]; 
		mouse.track = 1; 
1991/0823    
		spllo();		/* mouse tracking kills uart0 */ 
1991/0731    
		mouseclock(); 
	} 
1991/0703    
} 
1991/0823/sys/src/9/pc/kbd.c:277,2921991/0904/sys/src/9/pc/kbd.c:277,295 (short | long)
1991/0731    
	unsigned int c; 
1991/0803    
	int tries; 
1991/0731    
 
1991/0803    
	for(tries=0; tries < 10; tries++){ 
		if(outready() < 0) 
			return -1; 
1991/0731    
		outb(Cmd, 0xD4); 
1991/0803    
		if(outready() < 0) 
			return -1; 
1991/0731    
		outb(Data, cmd); 
1991/0803    
		if(inready() < 0) 
			return -1; 
1991/0731    
		c = inb(Data); 
1991/0904    
	c = 0; 
	do{ 
		for(tries=0; tries < 10; tries++){ 
			if(outready() < 0) 
				return -1; 
			outb(Cmd, 0xD4); 
			if(outready() < 0) 
				return -1; 
			outb(Data, cmd); 
			if(inready() < 0) 
				return -1; 
			c = inb(Data); 
		} 
1991/0731    
	} while(c == 0xFE); 
	if(c != 0xFA) 
1991/0803    
		return -1; 
1991/0904/sys/src/9/pc/kbd.c:226,2321991/0905/sys/src/9/pc/kbd.c:226,241 (short | long)
1991/0703    
	0,	0, 
}; 
 
1991/0905    
/* 
 *  keyboard input q 
 */ 
1991/0703    
KIOQ	kbdq; 
1991/0905    
 
/* 
 *  predeclared 
 */ 
static void	kbdintr(Ureg*); 
 
1991/0703    
 
int 
latin1(int k1, int k2) 
1991/0905/sys/src/9/pc/kbd.c:433,4391991/0906/sys/src/9/pc/kbd.c:433,440 (short | long)
1991/0703    
	if(esc1){ 
		c = kbtabesc1[c]; 
		esc1 = 0; 
1991/0822    
		kbdputc(&kbdq, c); 
1991/0906    
		if(!keyup) 
			kbdputc(&kbdq, c); 
1991/0822    
		return 0; 
1991/0703    
	} else if(esc2){ 
		esc2--; 
1991/0906/sys/src/9/pc/kbd.c:35,401991/0911/sys/src/9/pc/kbd.c:35,41 (short | long)
1991/0703    
	Latin=	Spec|0x63, 
	Caps=	Spec|0x64, 
	Num=	Spec|0x65, 
1991/0911    
	Middle=	Spec|0x66, 
1991/0703    
	No=	Spec|0x7F,	/* no mapping */ 
 
1991/0731    
	Home=	KF|13, 
1991/0906/sys/src/9/pc/kbd.c:59,651991/0911/sys/src/9/pc/kbd.c:60,66
1991/0703    
[0x20]	'd',	'f',	'g',	'h',	'j',	'k',	'l',	';', 
[0x28]	'\'',	'`',	Shift,	'\\',	'z',	'x',	'c',	'v', 
[0x30]	'b',	'n',	'm',	',',	'.',	'/',	Shift,	No, 
1991/0731    
[0x38]	Latin,	' ',	Caps,	KF|1,	KF|2,	KF|3,	KF|4,	KF|5, 
1991/0911    
[0x38]	Latin,	' ',	Ctrl,	KF|1,	KF|2,	KF|3,	KF|4,	KF|5, 
1991/0731    
[0x40]	KF|6,	KF|7,	KF|8,	KF|9,	KF|10,	Num,	KF|12,	Home, 
1991/0703    
[0x48]	No,	No,	No,	No,	No,	No,	No,	No, 
1991/0731    
[0x50]	No,	No,	No,	No,	No,	No,	No,	KF|11, 
1991/0906/sys/src/9/pc/kbd.c:75,811991/0911/sys/src/9/pc/kbd.c:76,82
1991/0703    
[0x20]	'D',	'F',	'G',	'H',	'J',	'K',	'L',	':', 
[0x28]	'"',	'~',	Shift,	'|',	'Z',	'X',	'C',	'V', 
[0x30]	'B',	'N',	'M',	'<',	'>',	'?',	Shift,	No, 
1991/0731    
[0x38]	Latin,	' ',	Caps,	KF|1,	KF|2,	KF|3,	KF|4,	KF|5, 
1991/0911    
[0x38]	Latin,	' ',	Ctrl,	KF|1,	KF|2,	KF|3,	KF|4,	KF|5, 
1991/0731    
[0x40]	KF|6,	KF|7,	KF|8,	KF|9,	KF|10,	Num,	KF|12,	Home, 
1991/0703    
[0x48]	No,	No,	No,	No,	No,	No,	No,	No, 
1991/0731    
[0x50]	No,	No,	No,	No,	No,	No,	No,	KF|11, 
1991/0906/sys/src/9/pc/kbd.c:231,2361991/0911/sys/src/9/pc/kbd.c:232,240
1991/0905    
 */ 
1991/0703    
KIOQ	kbdq; 
1991/0905    
 
1991/0911    
static int mousebuttons; 
static int middlebutton; 
 
1991/0905    
/* 
 *  predeclared 
 */ 
1991/0906/sys/src/9/pc/kbd.c:367,3731991/0911/sys/src/9/pc/kbd.c:371,378
1991/0731    
		if(msg[0] & 0x20) 
			msg[2] |= 0xFF00; 
 
		mouse.newbuttons = b[msg[0]&7]; 
1991/0911    
		mousebuttons = b[msg[0]&7]; 
		mouse.newbuttons = mousebuttons | middlebutton; 
1991/0731    
		mouse.dx = msg[1]; 
		mouse.dy = -msg[2]; 
		mouse.track = 1; 
1991/0906/sys/src/9/pc/kbd.c:377,3821991/0911/sys/src/9/pc/kbd.c:382,402
1991/0703    
} 
 
/* 
1991/0911    
 *  Ctrl key used as middle button pressed 
 */ 
static void 
middle(int newval) 
{ 
	middlebutton = newval; 
	mouse.newbuttons = mousebuttons | middlebutton; 
	mouse.dx = 0; 
	mouse.dy = 0; 
	mouse.track = 1; 
	spllo();		/* mouse tracking kills uart0 */ 
	mouseclock(); 
} 
 
/* 
1991/0703    
 *  keyboard interrupt 
 */ 
1991/0731    
int 
1991/0906/sys/src/9/pc/kbd.c:458,4631991/0911/sys/src/9/pc/kbd.c:478,486
1991/0703    
		case Ctrl: 
			ctl = 0; 
			break; 
1991/0911    
		case Middle: 
			middle(0); 
			break; 
1991/0703    
		} 
1991/0731    
		return 0; 
1991/0703    
	} 
1991/0906/sys/src/9/pc/kbd.c:501,5061991/0911/sys/src/9/pc/kbd.c:524,532
1991/0731    
			return 0; 
1991/0703    
		case Ctrl: 
			ctl = 1; 
1991/0911    
			return 0; 
		case Middle: 
			middle(2); 
1991/0731    
			return 0; 
1991/0703    
		} 
	} 
1991/0911/sys/src/9/pc/kbd.c:99,2321991/1108/sys/src/9/pc/kbd.c:99,104 (short | long)
1991/0703    
[0x58]	No,	No,	No,	No,	No,	No,	No,	No, 
}; 
 
struct latin 
{ 
	uchar	l; 
	char	c[2]; 
}latintab[] = { 
	'€',	"!!",	/* spanish initial ! */ 
	'€',	"c|",	/* cent */ 
	'€',	"c$",	/* cent */ 
	'€',	"l$",	/* pound sterling */ 
	'€',	"g$",	/* general currency */ 
	'€',	"y$",	/* yen */ 
	'€',	"j$",	/* yen */ 
	'€',	"||",	/* broken vertical bar */ 
	'€',	"SS",	/* section symbol */ 
	'€',	"\"\"",	/* dieresis */ 
	'€',	"cr",	/* copyright */ 
	'€',	"cO",	/* copyright */ 
	'€',	"sa",	/* super a, feminine ordinal */ 
	'€',	"<<",	/* left angle quotation */ 
	'€',	"no",	/* not sign, hooked overbar */ 
	'€',	"--",	/* soft hyphen */ 
	'€',	"rg",	/* registered trademark */ 
	'€',	"__",	/* macron */ 
	'€',	"s0",	/* degree (sup o) */ 
	'€',	"+-",	/* plus-minus */ 
	'€',	"s2",	/* sup 2 */ 
	'€',	"s3",	/* sup 3 */ 
	'€',	"''",	/* grave accent */ 
	'€',	"mu",	/* mu */ 
	'€',	"pg",	/* paragraph (pilcrow) */ 
	'€',	"..",	/* centered . */ 
	'€',	",,",	/* cedilla */ 
	'€',	"s1",	/* sup 1 */ 
	'€',	"so",	/* sup o */ 
	'€',	">>",	/* right angle quotation */ 
	'€',	"14",	/* 1/4 */ 
	'€',	"12",	/* 1/2 */ 
	'€',	"34",	/* 3/4 */ 
	'€',	"??",	/* spanish initial ? */ 
	'€',	"A`",	/* A grave */ 
	'€',	"A'",	/* A acute */ 
	'€',	"A^",	/* A circumflex */ 
	'€',	"A~",	/* A tilde */ 
	'€',	"A\"",	/* A dieresis */ 
	'€',	"A:",	/* A dieresis */ 
	'€',	"Ao",	/* A circle */ 
	'€',	"AO",	/* A circle */ 
	'€',	"Ae",	/* AE ligature */ 
	'€',	"AE",	/* AE ligature */ 
	'€',	"C,",	/* C cedilla */ 
	'€',	"E`",	/* E grave */ 
	'€',	"E'",	/* E acute */ 
	'€',	"E^",	/* E circumflex */ 
	'€',	"E\"",	/* E dieresis */ 
	'€',	"E:",	/* E dieresis */ 
	'€',	"I`",	/* I grave */ 
	'€',	"I'",	/* I acute */ 
	'€',	"I^",	/* I circumflex */ 
	'€',	"I\"",	/* I dieresis */ 
	'€',	"I:",	/* I dieresis */ 
	'€',	"D-",	/* Eth */ 
	'€',	"N~",	/* N tilde */ 
	'€',	"O`",	/* O grave */ 
	'€',	"O'",	/* O acute */ 
	'€',	"O^",	/* O circumflex */ 
	'€',	"O~",	/* O tilde */ 
	'€',	"O\"",	/* O dieresis */ 
	'€',	"O:",	/* O dieresis */ 
	'€',	"OE",	/* O dieresis */ 
	'€',	"Oe",	/* O dieresis */ 
	'€',	"xx",	/* times sign */ 
	'€',	"O/",	/* O slash */ 
	'€',	"U`",	/* U grave */ 
	'€',	"U'",	/* U acute */ 
	'€',	"U^",	/* U circumflex */ 
	'€',	"U\"",	/* U dieresis */ 
	'€',	"U:",	/* U dieresis */ 
	'€',	"UE",	/* U dieresis */ 
	'€',	"Ue",	/* U dieresis */ 
	'€',	"Y'",	/* Y acute */ 
	'€',	"P|",	/* Thorn */ 
	'€',	"Th",	/* Thorn */ 
	'€',	"TH",	/* Thorn */ 
	'€',	"ss",	/* sharp s */ 
	'€',	"a`",	/* a grave */ 
	'€',	"a'",	/* a acute */ 
	'€',	"a^",	/* a circumflex */ 
	'€',	"a~",	/* a tilde */ 
	'€',	"a\"",	/* a dieresis */ 
	'€',	"a:",	/* a dieresis */ 
	'€',	"ao",	/* a circle */ 
	'€',	"ae",	/* ae ligature */ 
	'€',	"c,",	/* c cedilla */ 
	'€',	"e`",	/* e grave */ 
	'€',	"e'",	/* e acute */ 
	'€',	"e^",	/* e circumflex */ 
	'€',	"e\"",	/* e dieresis */ 
	'€',	"e:",	/* e dieresis */ 
	'€',	"i`",	/* i grave */ 
	'€',	"i'",	/* i acute */ 
	'€',	"i^",	/* i circumflex */ 
	'€',	"i\"",	/* i dieresis */ 
	'€',	"i:",	/* i dieresis */ 
	'€',	"d-",	/* eth */ 
	'€',	"n~",	/* n tilde */ 
	'€',	"o`",	/* o grave */ 
	'€',	"o'",	/* o acute */ 
	'€',	"o^",	/* o circumflex */ 
	'€',	"o~",	/* o tilde */ 
	'€',	"o\"",	/* o dieresis */ 
	'€',	"o:",	/* o dieresis */ 
	'€',	"oe",	/* o dieresis */ 
	'€',	"-:",	/* divide sign */ 
	'€',	"o/",	/* o slash */ 
	'€',	"u`",	/* u grave */ 
	'€',	"u'",	/* u acute */ 
	'€',	"u^",	/* u circumflex */ 
	'€',	"u\"",	/* u dieresis */ 
	'€',	"u:",	/* u dieresis */ 
	'€',	"ue",	/* u dieresis */ 
	'€',	"y'",	/* y acute */ 
	'€',	"th",	/* thorn */ 
	'€',	"p|",	/* thorn */ 
	'€',	"y\"",	/* y dieresis */ 
	'€',	"y:",	/* y dieresis */ 
	0,	0, 
}; 
                 
1991/0905    
/* 
 *  keyboard input q 
 */ 
1991/0911/sys/src/9/pc/kbd.c:240,2571991/1108/sys/src/9/pc/kbd.c:112,117
1991/0905    
 */ 
static void	kbdintr(Ureg*); 
 
1991/0703    
                 
int 
latin1(int k1, int k2) 
{ 
	int i; 
	struct latin *l; 
                 
	for(l=latintab; l->l; l++) 
		if(k1==l->c[0] && k2==l->c[1]) 
			return l->l; 
	return 0; 
} 
 
1991/0803    
/* 
 *  wait for output no longer busy 
1991/1108/sys/src/9/pc/kbd.c:189,1981991/1207/sys/src/9/pc/kbd.c:189,198 (short | long)
1991/0730    
	outb(Cmd, 0x60); 
1991/0803    
	if(outready() < 0) 
		print("kbd init failed\n"); 
1991/0731    
	outb(Data, 0x47); 
1991/1207    
	outb(Data, 0x47);	/* BUG -- on 6300 0x65 */ 
1991/0803    
	if(outready() < 0) 
		print("kbd init failed\n"); 
1991/0731    
	outb(Cmd, 0xA8); 
1991/1207    
	outb(Cmd, 0xA8);	/* BUG -- should this be AE? */ 
1991/0731    
 
1991/0803    
	/* make mouse streaming, enabled */ 
	if(mousecmd(0xEA) < 0 
1991/1207/sys/src/9/pc/kbd.c:169,1751991/1210/sys/src/9/pc/kbd.c:169,201 (short | long)
1991/0803    
	return 0; 
1991/0731    
} 
 
1991/1210    
/* 
 *  ask 8042 to enable the use of address bit 20 
 */ 
1991/0703    
void 
1991/1210    
i8042a20(void) 
{ 
	outready(); 
	outb(Cmd, 0xD1); 
	outready(); 
	outb(Data, 0xDF); 
	outready(); 
} 
 
/* 
 *  ask 8042 to reset the 386 
 */ 
void 
i8042reset(void) 
{ 
	outready(); 
	outb(Cmd, 0xD1); 
	outready(); 
	outb(Data, 0xDE); 
	outready(); 
} 
 
void 
1991/0703    
kbdinit(void) 
{ 
1991/0731    
	int c, s; 
1991/1207/sys/src/9/pc/kbd.c:185,2031991/1210/sys/src/9/pc/kbd.c:211,240
1991/0730    
		if(c & Inready) 
			inb(Data); 
 
1991/0731    
	/* enable kbd/mouse xfers and interrupts */ 
1991/0730    
	outb(Cmd, 0x60); 
1991/0803    
	if(outready() < 0) 
		print("kbd init failed\n"); 
1991/1207    
	outb(Data, 0x47);	/* BUG -- on 6300 0x65 */ 
1991/0803    
	if(outready() < 0) 
		print("kbd init failed\n"); 
1991/1207    
	outb(Cmd, 0xA8);	/* BUG -- should this be AE? */ 
1991/0731    
                 
1991/0803    
	/* make mouse streaming, enabled */ 
	if(mousecmd(0xEA) < 0 
	|| mousecmd(0xF4) < 0) 
		print("can't initialize mouse\n"); 
1991/1210    
	switch(machtype){ 
	case Attnsx: 
		/* enable kbd/mouse xfers and interrupts */ 
		outb(Cmd, 0x60); 
		if(outready() < 0) 
			print("kbd init failed\n"); 
		outb(Data, 0x47); 
		if(outready() < 0) 
			print("kbd init failed\n"); 
		outb(Cmd, 0xA8); 
	 
		/* make mouse streaming, enabled */ 
		if(mousecmd(0xEA) < 0 
		|| mousecmd(0xF4) < 0) 
			print("can't initialize mouse\n"); 
		break; 
	case At: 
		/* enable kbd xfers and interrupts */ 
		outb(Cmd, 0x60); 
		if(outready() < 0) 
			print("kbd init failed\n"); 
		outb(Data, 0x65); 
		break; 
	} 
1991/0731    
} 
1991/0730    
 
1991/0731    
/* 
1991/1210/sys/src/9/pc/kbd.c:191,1971991/1211/sys/src/9/pc/kbd.c:191,197 (short | long)
1991/1210    
	outready(); 
	outb(Cmd, 0xD1); 
	outready(); 
	outb(Data, 0xDE); 
1991/1211    
	outb(Data, 0x0); 
1991/1210    
	outready(); 
} 
 
1991/1210/sys/src/9/pc/kbd.c:299,3111991/1211/sys/src/9/pc/kbd.c:299,312
1991/0731    
int 
kbdintr0(void) 
1991/0703    
{ 
1991/0730    
	int s, c, nc; 
1991/1211    
	int s, c, i, nk, nc; 
1991/0703    
	static int esc1, esc2; 
	static int shift; 
	static int caps; 
	static int ctl; 
	static int num; 
	static int lstate, k1, k2; 
1991/1211    
	static int lstate; 
	static uchar kc[5]; 
1991/0703    
	int keyup; 
1991/0702    
 
1991/0703    
	/* 
1991/1210/sys/src/9/pc/kbd.c:343,3491991/1211/sys/src/9/pc/kbd.c:344,349
1991/0822    
	c &= 0x7f; 
	if(c > sizeof kbtab){ 
		print("unknown key %ux\n", c|keyup); 
		kbdputc(&kbdq, k1); 
		return 0; 
	} 
 
1991/1210/sys/src/9/pc/kbd.c:390,4101991/1211/sys/src/9/pc/kbd.c:390,427
1991/0703    
			c &= 0x1f; 
		switch(lstate){ 
		case 1: 
			k1 = c; 
1991/1211    
			kc[0] = c; 
1991/0703    
			lstate = 2; 
1991/0731    
			return 0; 
1991/1211    
			if(c == 'X') 
				lstate = 3; 
			break; 
1991/0703    
		case 2: 
			k2 = c; 
1991/1211    
			kc[1] = c; 
			c = latin1(kc); 
			nk = 2; 
		putit: 
1991/0703    
			lstate = 0; 
			c = latin1(k1, k2); 
			if(c == 0){ 
				kbdputc(&kbdq, k1); 
				c = k2; 
			} 
			/* fall through */ 
1991/1211    
			if(c != -1) 
				kbdputc(&kbdq, c); 
			else for(i=0; i<nk; i++) 
				kbdputc(&kbdq, kc[i]); 
			break; 
		case 3: 
		case 4: 
		case 5: 
			kc[lstate-2] = c; 
			lstate++; 
			break; 
		case 6: 
			kc[4] = c; 
			c = unicode(kc); 
			nk = 5; 
			goto putit; 
1991/0703    
		default: 
1991/1211    
			kbdputc(&kbdq, c); 
1991/0703    
			break; 
		} 
1991/1211    
		return 0; 
1991/0703    
	} else { 
		switch(c){ 
		case Caps: 
1991/1211/sys/src/9/pc/kbd.c:351,3571992/0211/sys/src/9/pc/kbd.c:351,357 (short | long)
1991/0703    
		c = kbtabesc1[c]; 
		esc1 = 0; 
1991/0906    
		if(!keyup) 
			kbdputc(&kbdq, c); 
1992/0211    
			goto dochar; 
1991/0822    
		return 0; 
1991/0703    
	} else if(esc2){ 
		esc2--; 
1991/1211/sys/src/9/pc/kbd.c:385,3901992/0211/sys/src/9/pc/kbd.c:385,391
1991/0703    
	/* 
 	 *  normal character 
	 */ 
1992/0211    
dochar: 
1991/0703    
	if(!(c & Spec)){ 
		if(ctl) 
			c &= 0x1f; 
1992/0211/sys/src/9/pc/kbd.c:296,3031992/0221/sys/src/9/pc/kbd.c:296,303 (short | long)
1991/0911    
/* 
1991/0703    
 *  keyboard interrupt 
 */ 
1991/0731    
int 
kbdintr0(void) 
1992/0221    
void 
kbdintr(Ureg *ur) 
1991/0703    
{ 
1991/1211    
	int s, c, i, nk, nc; 
1991/0703    
	static int esc1, esc2; 
1992/0211/sys/src/9/pc/kbd.c:309,3141992/0221/sys/src/9/pc/kbd.c:309,316
1991/1211    
	static uchar kc[5]; 
1991/0703    
	int keyup; 
1991/0702    
 
1992/0221    
	USED(ur); 
 
1991/0703    
	/* 
1991/0731    
	 *  get status 
1991/0703    
	 */ 
1992/0211/sys/src/9/pc/kbd.c:447,4571992/0221/sys/src/9/pc/kbd.c:449,452
1991/0703    
	} 
	kbdputc(&kbdq, c); 
1991/0731    
	return 0; 
} 
                 
void 
kbdintr(Ureg *ur) 
{ 
	while(kbdintr0() == 0) 
		; 
1991/0703    
} 
1992/0221/sys/src/9/pc/kbd.c:296,3031992/0222/sys/src/9/pc/kbd.c:296,303 (short | long)
1991/0911    
/* 
1991/0703    
 *  keyboard interrupt 
 */ 
1992/0221    
void 
kbdintr(Ureg *ur) 
1992/0222    
int 
kbdintr0(void) 
1991/0703    
{ 
1991/1211    
	int s, c, i, nk, nc; 
1991/0703    
	static int esc1, esc2; 
1992/0221/sys/src/9/pc/kbd.c:309,3161992/0222/sys/src/9/pc/kbd.c:309,314
1991/1211    
	static uchar kc[5]; 
1991/0703    
	int keyup; 
1991/0702    
 
1992/0221    
	USED(ur); 
                 
1991/0703    
	/* 
1991/0731    
	 *  get status 
1991/0703    
	 */ 
1992/0221/sys/src/9/pc/kbd.c:449,4521992/0222/sys/src/9/pc/kbd.c:447,456
1991/0703    
	} 
	kbdputc(&kbdq, c); 
1991/0731    
	return 0; 
1992/0222    
} 
 
void 
kbdintr(Ureg *ur) 
{ 
	kbdintr0(); 
1991/0703    
} 
Too many diffs (26 > 25). Stopping.


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