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

1993/1124/pc/kbd.c (diff list | history)

1993/1117/sys/src/9/pc/kbd.c:130,1381993/1124/sys/src/9/pc/kbd.c:130,135 (short | long | prev | next)
1992/1015    
	Ckbdint=	(1<<0),		/* kbd interrupt enable */ 
1992/0904    
}; 
1991/0703    
 
1992/1017    
static void	kbdintr(Ureg*); 
1993/0915    
static void	ctps2intr(Ureg*); 
1992/1015    
                 
1993/1117    
extern int m3mouseputc(IOQ*, int), mouseputc(IOQ*, int); 
1993/1113    
 
1991/0803    
/* 
1993/1117/sys/src/9/pc/kbd.c:235,2751993/1124/sys/src/9/pc/kbd.c:232,237
1992/0902    
	outready(); 
} 
 
1993/0915    
                 
1992/0902    
void 
1991/0703    
kbdinit(void) 
{ 
1992/0711    
	int c; 
1991/0730    
                 
1993/1113    
	kbdq = qopen(4*1024, 0, 0, 0); 
                 
1991/0716    
	setvec(Kbdvec, kbdintr); 
1991/0730    
                 
	/* wait for a quiescent controller */ 
	while((c = inb(Status)) & (Outbusy | Inready)) 
		if(c & Inready) 
			inb(Data); 
                 
1992/1015    
	/* get current controller command byte */ 
	outb(Cmd, 0x20); 
	if(inready() < 0){ 
		print("kbdinit: can't read ccc\n"); 
		ccc = 0; 
	} else 
		ccc = inb(Data); 
                 
1992/0904    
	/* enable kbd xfers and interrupts */ 
1992/1015    
	ccc &= ~Ckbddis; 
	ccc |= Csf | Ckbdint | Cscs1; 
	if(outready() < 0) 
		print("kbd init failed\n"); 
1992/0904    
	outb(Cmd, 0x60); 
	if(outready() < 0) 
		print("kbd init failed\n"); 
1992/1015    
	outb(Data, ccc); 
	outready(); 
1992/0904    
} 
1992/0408    
                 
1992/0904    
/* 
 *  setup a serial mouse 
 */ 
1993/1117/sys/src/9/pc/kbd.c:292,2971993/1124/sys/src/9/pc/kbd.c:254,313
1992/0904    
	mousetype = Mouseserial; 
} 
1992/0408    
 
1993/1124    
/* 
 *  ps/2 mouse message is three bytes 
 * 
 *	byte 0 -	0 0 SDY SDX 1 M R L 
 *	byte 1 -	DX 
 *	byte 2 -	DY 
 * 
 *  shift & left button is the same as middle button 
 */ 
static int 
ps2mouseputc(int c) 
{ 
	static short msg[3]; 
	static int nb; 
	static uchar b[] = {0, 1, 4, 5, 2, 3, 6, 7, 0, 1, 2, 5, 2, 3, 6, 7 }; 
	int buttons, dx, dy; 
 
	/*  
	 *  check byte 0 for consistency 
	 */ 
	if(nb==0 && (c&0xc8)!=0x08) 
		return 0; 
 
	msg[nb] = c; 
	if(++nb == 3){ 
		nb = 0; 
		if(msg[0] & 0x10) 
			msg[1] |= 0xFF00; 
		if(msg[0] & 0x20) 
			msg[2] |= 0xFF00; 
 
		buttons = b[(msg[0]&7) | (shift ? 8 : 0)] | keybuttons; 
		dx = msg[1]; 
		dy = -msg[2]; 
		mousetrack(buttons, dx, dy); 
	} 
	return 0; 
} 
 
static void 
ctps2intr(Ureg *ur, void *arg) 
{ 
	uchar c; 
 
	USED(ur, arg); 
	c = inb(ctport + CTstatus); 
	if(c & Error) 
		return; 
	if((c & Rready) == 0) 
		return; 
	c = inb(ctport + CTdata); 
	ps2mouseputc(c); 
} 
 
1993/0915    
static void nop(void){}; 
 
1992/0904    
/* 
1993/1117/sys/src/9/pc/kbd.c:328,3341993/1124/sys/src/9/pc/kbd.c:344,350
1993/0915    
	outb(0x390, 0xf); nop(); nop(); 
	outb(0x391, 0xf); 
 
	setvec(Mousevec, ctps2intr); 
1993/1124    
	setvec(Mousevec, ctps2intr, 0); 
1993/0915    
 
	/* enable for interrupts */ 
	c = inb(ctport + CTstatus); 
1993/1117/sys/src/9/pc/kbd.c:341,4861993/1124/sys/src/9/pc/kbd.c:357,367
1993/0915    
} 
 
/* 
1992/0904    
 *  set up a ps2 mouse 
1993/1124    
 *  keyboard interrupt 
1992/0904    
 */ 
1992/1017    
static void 
ps2mouse(void) 
1993/1124    
kbdintr(Ureg *ur, void *arg) 
1992/0904    
{ 
1992/1015    
	int x; 
1992/0904    
                 
1992/1017    
	if(mousetype) 
		error(Emouseset); 
1992/0904    
                 
1993/0915    
	if(ct82c710() == 0) 
		return; 
                 
1992/0904    
	/* enable kbd/mouse xfers and interrupts */ 
1992/1017    
	setvec(Mousevec, kbdintr); 
1992/1015    
	x = splhi(); 
	ccc &= ~Cmousedis; 
	ccc |= Cmouseint; 
	if(outready() < 0) 
		print("mouse init failed\n"); 
1992/0904    
	outb(Cmd, 0x60); 
	if(outready() < 0) 
1992/1015    
		print("mouse init failed\n"); 
	outb(Data, ccc); 
1992/0904    
	if(outready() < 0) 
1992/1015    
		print("mouse init failed\n"); 
1992/0904    
	outb(Cmd, 0xA8); 
1992/1015    
	if(outready() < 0) 
		print("mouse init failed\n"); 
1992/0904    
                 
	/* make mouse streaming, enabled */ 
1992/1017    
	mousecmd(0xEA); 
1992/0904    
	mousecmd(0xF4); 
1992/1015    
	splx(x); 
                 
1992/0904    
	mousetype = MousePS2; 
1992/0825    
} 
                 
/* 
1992/1017    
 *  ps/2 mouse message is three bytes 
1991/0731    
 * 
 *	byte 0 -	0 0 SDY SDX 1 M R L 
 *	byte 1 -	DX 
 *	byte 2 -	DY 
1992/0918    
 * 
 *  shift & left button is the same as middle button 
1991/0731    
 */ 
1992/1015    
static int 
1993/1113    
ps2mouseputc(int c) 
1991/0731    
{ 
	static short msg[3]; 
	static int nb; 
1992/0918    
	static uchar b[] = {0, 1, 4, 5, 2, 3, 6, 7, 0, 1, 2, 5, 2, 3, 6, 7 }; 
1993/0226    
	int buttons, dx, dy; 
1991/0731    
                 
	/*  
	 *  check byte 0 for consistency 
	 */ 
	if(nb==0 && (c&0xc8)!=0x08) 
1992/1015    
		return 0; 
1991/0731    
                 
	msg[nb] = c; 
	if(++nb == 3){ 
		nb = 0; 
		if(msg[0] & 0x10) 
			msg[1] |= 0xFF00; 
		if(msg[0] & 0x20) 
			msg[2] |= 0xFF00; 
                 
1993/0226    
		buttons = b[(msg[0]&7) | (shift ? 8 : 0)] | keybuttons; 
		dx = msg[1]; 
		dy = -msg[2]; 
		mousetrack(buttons, dx, dy); 
1991/0731    
	} 
1992/1015    
	return 0; 
1991/0703    
} 
                 
/* 
1992/1017    
 *  set/change mouse configuration 
 */ 
void 
mousectl(char *arg) 
{ 
	int n, x; 
	char *field[3]; 
                 
	n = getfields(arg, field, 3, ' '); 
	if(strncmp(field[0], "serial", 6) == 0){ 
1992/1020    
		switch(n){ 
		case 1: 
1992/1017    
			serialmouse(atoi(field[0]+6), 0, 1); 
1992/1020    
			break; 
		case 2: 
			serialmouse(atoi(field[1]), 0, 0); 
			break; 
		case 3: 
		default: 
			serialmouse(atoi(field[1]), field[2], 0); 
			break; 
		} 
1992/1017    
	} else if(strcmp(field[0], "ps2") == 0){ 
		ps2mouse(); 
	} else if(strcmp(field[0], "accelerated") == 0){ 
		switch(mousetype){ 
		case MousePS2: 
			x = splhi(); 
			mousecmd(0xE7); 
			splx(x); 
			break; 
		} 
	} else if(strcmp(field[0], "linear") == 0){ 
		switch(mousetype){ 
		case MousePS2: 
			x = splhi(); 
			mousecmd(0xE6); 
			splx(x); 
			break; 
		} 
	} else if(strcmp(field[0], "res") == 0){ 
		if(n < 2) 
			n = 1; 
		else 
			n = atoi(field[1]); 
		switch(mousetype){ 
		case MousePS2: 
			x = splhi(); 
			mousecmd(0xE8); 
			mousecmd(n); 
			splx(x); 
			break; 
		} 
	} 
} 
                 
/* 
1991/0703    
 *  keyboard interrupt 
 */ 
1992/0222    
int 
kbdintr0(void) 
1991/0703    
{ 
1992/0711    
	int s, c, i, nk; 
1991/0703    
	static int esc1, esc2; 
	static int caps; 
1993/1117/sys/src/9/pc/kbd.c:490,5011993/1124/sys/src/9/pc/kbd.c:371,384
1991/1211    
	static uchar kc[5]; 
1991/0703    
	int keyup; 
1991/0702    
 
1993/1124    
	USED(ur, arg); 
 
1991/0703    
	/* 
1991/0731    
	 *  get status 
1991/0703    
	 */ 
1991/0730    
	s = inb(Status); 
1991/0731    
	if(!(s&Inready)) 
		return -1; 
1993/1124    
		return; 
1991/0731    
 
	/* 
	 *  get the character 
1993/1117/sys/src/9/pc/kbd.c:507,5131993/1124/sys/src/9/pc/kbd.c:390,396
1991/0730    
	 */ 
	if(s & Minready){ 
1993/1113    
		ps2mouseputc(c); 
1991/0731    
		return 0; 
1993/1124    
		return; 
1991/0730    
	} 
1991/0703    
 
	/* 
1993/1117/sys/src/9/pc/kbd.c:515,5241993/1124/sys/src/9/pc/kbd.c:398,407
1991/0703    
	 */ 
	if(c == 0xe0){ 
		esc1 = 1; 
1991/0731    
		return 0; 
1993/1124    
		return; 
1991/0703    
	} else if(c == 0xe1){ 
		esc2 = 2; 
1991/0731    
		return 0; 
1993/1124    
		return; 
1991/0703    
	} 
 
1991/0822    
	keyup = c&0x80; 
1993/1117/sys/src/9/pc/kbd.c:525,5311993/1124/sys/src/9/pc/kbd.c:408,414
1991/0822    
	c &= 0x7f; 
	if(c > sizeof kbtab){ 
		print("unknown key %ux\n", c|keyup); 
		return 0; 
1993/1124    
		return; 
1991/0822    
	} 
 
1991/0703    
	if(esc1){ 
1993/1117/sys/src/9/pc/kbd.c:533,5391993/1124/sys/src/9/pc/kbd.c:416,422
1991/0703    
		esc1 = 0; 
	} else if(esc2){ 
		esc2--; 
1991/0731    
		return 0; 
1993/1124    
		return; 
1991/0703    
	} else if(shift) 
		c = kbtabshift[c]; 
	else 
1993/1117/sys/src/9/pc/kbd.c:554,5601993/1124/sys/src/9/pc/kbd.c:437,443
1991/0703    
			ctl = 0; 
			break; 
		} 
1991/0731    
		return 0; 
1993/1124    
		return; 
1991/0703    
	} 
 
	/* 
1993/1117/sys/src/9/pc/kbd.c:596,6431993/1124/sys/src/9/pc/kbd.c:479,633
1993/1113    
			kbdputc(kbdq, c); 
1991/0703    
			break; 
		} 
1991/1211    
		return 0; 
1993/1124    
		return; 
1991/0703    
	} else { 
		switch(c){ 
		case Caps: 
			caps ^= 1; 
1991/0731    
			return 0; 
1993/1124    
			return; 
1991/0703    
		case Num: 
			num ^= 1; 
1991/0731    
			return 0; 
1993/1124    
			return; 
1991/0703    
		case Shift: 
1992/1020    
			mouseshifted = shift = 1; 
1991/0731    
			return 0; 
1993/1124    
			return; 
1991/0703    
		case Latin: 
			lstate = 1; 
1991/0731    
			return 0; 
1993/1124    
			return; 
1991/0703    
		case Ctrl: 
			ctl = 1; 
1991/0731    
			return 0; 
1993/1124    
			return; 
1991/0703    
		} 
	} 
1993/1113    
	kbdputc(kbdq, c); 
1991/0731    
	return 0; 
1992/0222    
} 
 
1993/1124    
/* 
 *  set up a ps2 mouse 
 */ 
static void 
ps2mouse(void) 
{ 
	int x; 
 
	if(mousetype) 
		error(Emouseset); 
 
	if(ct82c710() == 0) 
		return; 
 
	/* enable kbd/mouse xfers and interrupts */ 
	setvec(Mousevec, kbdintr, 0); 
	x = splhi(); 
	ccc &= ~Cmousedis; 
	ccc |= Cmouseint; 
	if(outready() < 0) 
		print("mouse init failed\n"); 
	outb(Cmd, 0x60); 
	if(outready() < 0) 
		print("mouse init failed\n"); 
	outb(Data, ccc); 
	if(outready() < 0) 
		print("mouse init failed\n"); 
	outb(Cmd, 0xA8); 
	if(outready() < 0) 
		print("mouse init failed\n"); 
 
	/* make mouse streaming, enabled */ 
	mousecmd(0xEA); 
	mousecmd(0xF4); 
	splx(x); 
 
	mousetype = MousePS2; 
} 
 
/* 
 *  set/change mouse configuration 
 */ 
1992/0222    
void 
kbdintr(Ureg *ur) 
1993/1124    
mousectl(char *arg) 
1992/0222    
{ 
1992/0711    
	USED(ur); 
1992/0222    
	kbdintr0(); 
1993/1124    
	int n, x; 
	char *field[3]; 
 
	n = getfields(arg, field, 3, ' '); 
	if(strncmp(field[0], "serial", 6) == 0){ 
		switch(n){ 
		case 1: 
			serialmouse(atoi(field[0]+6), 0, 1); 
			break; 
		case 2: 
			serialmouse(atoi(field[1]), 0, 0); 
			break; 
		case 3: 
		default: 
			serialmouse(atoi(field[1]), field[2], 0); 
			break; 
		} 
	} else if(strcmp(field[0], "ps2") == 0){ 
		ps2mouse(); 
	} else if(strcmp(field[0], "accelerated") == 0){ 
		switch(mousetype){ 
		case MousePS2: 
			x = splhi(); 
			mousecmd(0xE7); 
			splx(x); 
			break; 
		} 
	} else if(strcmp(field[0], "linear") == 0){ 
		switch(mousetype){ 
		case MousePS2: 
			x = splhi(); 
			mousecmd(0xE6); 
			splx(x); 
			break; 
		} 
	} else if(strcmp(field[0], "res") == 0){ 
		if(n < 2) 
			n = 1; 
		else 
			n = atoi(field[1]); 
		switch(mousetype){ 
		case MousePS2: 
			x = splhi(); 
			mousecmd(0xE8); 
			mousecmd(n); 
			splx(x); 
			break; 
		} 
	} 
1993/0915    
} 
 
void 
ctps2intr(Ureg *ur) 
1993/1124    
kbdinit(void) 
1993/0915    
{ 
	uchar c; 
1993/1124    
	int c; 
1993/0915    
 
	USED(ur); 
	c = inb(ctport + CTstatus); 
	if(c & Error) 
		return; 
	if((c & Rready) == 0) 
		return; 
	c = inb(ctport + CTdata); 
1993/1113    
	ps2mouseputc(c); 
1993/1124    
	kbdq = qopen(4*1024, 0, 0, 0); 
 
	setvec(Kbdvec, kbdintr, 0); 
 
	/* wait for a quiescent controller */ 
	while((c = inb(Status)) & (Outbusy | Inready)) 
		if(c & Inready) 
			inb(Data); 
 
	/* get current controller command byte */ 
	outb(Cmd, 0x20); 
	if(inready() < 0){ 
		print("kbdinit: can't read ccc\n"); 
		ccc = 0; 
	} else 
		ccc = inb(Data); 
 
	/* enable kbd xfers and interrupts */ 
	ccc &= ~Ckbddis; 
	ccc |= Csf | Ckbdint | Cscs1; 
	if(outready() < 0) 
		print("kbd init failed\n"); 
	outb(Cmd, 0x60); 
	if(outready() < 0) 
		print("kbd init failed\n"); 
	outb(Data, ccc); 
	outready(); 
1991/0703    
} 


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