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

1991/0731/pc/kbd.c (diff list | history)

1991/0730/sys/src/9/pc/kbd.c:5,101991/0731/sys/src/9/pc/kbd.c:5,14 (short | long | prev | next)
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    
} 


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