linux内核源代码

源代码在线查看: keyboard.s

软件大小: 150 K
上传用户: kens
关键词: linux 内核 源代码
下载地址: 免注册下载 普通下载 VIP

相关代码

				/*				 *  linux/kernel/keyboard.S				 *				 *  (C) 1991  Linus Torvalds				 */								/*				 *	Thanks to Alfred Leung for US keyboard patches				 *		Wolfgang Thiel for German keyboard patches				 *		Marc Corsini for the French keyboard				 */								#include 								.text				.globl _keyboard_interrupt								/*				 * these are for the keyboard read functions				 */				size	= 1024		/* must be a power of two ! And MUST be the same							   as in tty_io.c !!!! */				head = 4				tail = 8				proc_list = 12				buf = 16								mode:	.byte 0		/* caps, alt, ctrl and shift mode */				leds:	.byte 2		/* num-lock, caps, scroll-lock mode (nom-lock on) */				e0:	.byte 0								/*				 *  con_int is the real interrupt routine that reads the				 *  keyboard scan-code and converts it into the appropriate				 *  ascii character(s).				 */				_keyboard_interrupt:					pushl %eax					pushl %ebx					pushl %ecx					pushl %edx					push %ds					push %es					movl $0x10,%eax					mov %ax,%ds					mov %ax,%es					xorl %al,%al		/* %eax is scan code */					inb $0x60,%al					cmpb $0xe0,%al					je set_e0					cmpb $0xe1,%al					je set_e1					call key_table(,%eax,4)					movb $0,e0				e0_e1:	inb $0x61,%al					jmp 1f				1:	jmp 1f				1:	orb $0x80,%al					jmp 1f				1:	jmp 1f				1:	outb %al,$0x61					jmp 1f				1:	jmp 1f				1:	andb $0x7F,%al					outb %al,$0x61					movb $0x20,%al					outb %al,$0x20					pushl $0					call _do_tty_interrupt					addl $4,%esp					pop %es					pop %ds					popl %edx					popl %ecx					popl %ebx					popl %eax					iret				set_e0:	movb $1,e0					jmp e0_e1				set_e1:	movb $2,e0					jmp e0_e1								/*				 * This routine fills the buffer with max 8 bytes, taken from				 * %ebx:%eax. (%edx is high). The bytes are written in the				 * order %al,%ah,%eal,%eah,%bl,%bh ... until %eax is zero.				 */				put_queue:					pushl %ecx					pushl %edx					movl _table_list,%edx		# read-queue for console					movl head(%edx),%ecx				1:	movb %al,buf(%edx,%ecx)					incl %ecx					andl $size-1,%ecx					cmpl tail(%edx),%ecx		# buffer full - discard everything					je 3f					shrdl $8,%ebx,%eax					je 2f					shrl $8,%ebx					jmp 1b				2:	movl %ecx,head(%edx)					movl proc_list(%edx),%ecx					testl %ecx,%ecx					je 3f					movl $0,(%ecx)				3:	popl %edx					popl %ecx					ret								ctrl:	movb $0x04,%al					jmp 1f				alt:	movb $0x10,%al				1:	cmpb $0,e0					je 2f					addb %al,%al				2:	orb %al,mode					ret				unctrl:	movb $0x04,%al					jmp 1f				unalt:	movb $0x10,%al				1:	cmpb $0,e0					je 2f					addb %al,%al				2:	notb %al					andb %al,mode					ret								lshift:					orb $0x01,mode					ret				unlshift:					andb $0xfe,mode					ret				rshift:					orb $0x02,mode					ret				unrshift:					andb $0xfd,mode					ret								caps:	testb $0x80,mode					jne 1f					xorb $4,leds					xorb $0x40,mode					orb $0x80,mode				set_leds:					call kb_wait					movb $0xed,%al		/* set leds command */					outb %al,$0x60					call kb_wait					movb leds,%al					outb %al,$0x60					ret				uncaps:	andb $0x7f,mode					ret				scroll:					xorb $1,leds					jmp set_leds				num:	xorb $2,leds					jmp set_leds								/*				 *  curosr-key/numeric keypad cursor keys are handled here.				 *  checking for numeric keypad etc.				 */				cursor:					subb $0x47,%al					jb 1f					cmpb $12,%al					ja 1f					jne cur2		/* check for ctrl-alt-del */					testb $0x0c,mode					je cur2					testb $0x30,mode					jne reboot				cur2:	cmpb $0x01,e0		/* e0 forces cursor movement */					je cur					testb $0x02,leds	/* not num-lock forces cursor */					je cur					testb $0x03,mode	/* shift forces cursor */					jne cur					xorl %ebx,%ebx					movb num_table(%eax),%al					jmp put_queue				1:	ret								cur:	movb cur_table(%eax),%al					cmpb $'9,%al					ja ok_cur					movb $'~,%ah				ok_cur:	shll $16,%eax					movw $0x5b1b,%ax					xorl %ebx,%ebx					jmp put_queue								#if defined(KBD_FR)				num_table:					.ascii "789 456 1230."				#else				num_table:					.ascii "789 456 1230,"				#endif				cur_table:					.ascii "HA5 DGC YB623"								/*				 * this routine handles function keys				 */				func:					pushl %eax					pushl %ecx					pushl %edx					call _show_stat					popl %edx					popl %ecx					popl %eax					subb $0x3B,%al					jb end_func					cmpb $9,%al					jbe ok_func					subb $18,%al					cmpb $10,%al					jb end_func					cmpb $11,%al					ja end_func				ok_func:					cmpl $4,%ecx		/* check that there is enough room */					jl end_func					movl func_table(,%eax,4),%eax					xorl %ebx,%ebx					jmp put_queue				end_func:					ret								/*				 * function keys send F1:'esc [ [ A' F2:'esc [ [ B' etc.				 */				func_table:					.long 0x415b5b1b,0x425b5b1b,0x435b5b1b,0x445b5b1b					.long 0x455b5b1b,0x465b5b1b,0x475b5b1b,0x485b5b1b					.long 0x495b5b1b,0x4a5b5b1b,0x4b5b5b1b,0x4c5b5b1b								#if	defined(KBD_FINNISH)				key_map:					.byte 0,27					.ascii "1234567890+'"					.byte 127,9					.ascii "qwertyuiop}"					.byte 0,13,0					.ascii "asdfghjkl|{"					.byte 0,0					.ascii "'zxcvbnm,.-"					.byte 0,'*,0,32		/* 36-39 */					.fill 16,1,0		/* 3A-49 */					.byte '-,0,0,0,'+	/* 4A-4E */					.byte 0,0,0,0,0,0,0	/* 4F-55 */					.byte '					.fill 10,1,0								shift_map:					.byte 0,27					.ascii "!\"#$%&/()=?`"					.byte 127,9					.ascii "QWERTYUIOP]^"					.byte 13,0					.ascii "ASDFGHJKL\\["					.byte 0,0					.ascii "*ZXCVBNM;:_"					.byte 0,'*,0,32		/* 36-39 */					.fill 16,1,0		/* 3A-49 */					.byte '-,0,0,0,'+	/* 4A-4E */					.byte 0,0,0,0,0,0,0	/* 4F-55 */					.byte '>					.fill 10,1,0								alt_map:					.byte 0,0					.ascii "\0@\0$\0\0{[]}\\\0"					.byte 0,0					.byte 0,0,0,0,0,0,0,0,0,0,0					.byte '~,13,0					.byte 0,0,0,0,0,0,0,0,0,0,0					.byte 0,0					.byte 0,0,0,0,0,0,0,0,0,0,0					.byte 0,0,0,0		/* 36-39 */					.fill 16,1,0		/* 3A-49 */					.byte 0,0,0,0,0		/* 4A-4E */					.byte 0,0,0,0,0,0,0	/* 4F-55 */					.byte '|					.fill 10,1,0								#elif defined(KBD_US)								key_map:					.byte 0,27					.ascii "1234567890-="					.byte 127,9					.ascii "qwertyuiop[]"					.byte 13,0					.ascii "asdfghjkl;'"					.byte '`,0					.ascii "\\zxcvbnm,./"					.byte 0,'*,0,32		/* 36-39 */					.fill 16,1,0		/* 3A-49 */					.byte '-,0,0,0,'+	/* 4A-4E */					.byte 0,0,0,0,0,0,0	/* 4F-55 */					.byte '					.fill 10,1,0												shift_map:					.byte 0,27					.ascii "!@#$%^&*()_+"					.byte 127,9					.ascii "QWERTYUIOP{}"					.byte 13,0					.ascii "ASDFGHJKL:\""					.byte '~,0					.ascii "|ZXCVBNM?"					.byte 0,'*,0,32		/* 36-39 */					.fill 16,1,0		/* 3A-49 */					.byte '-,0,0,0,'+	/* 4A-4E */					.byte 0,0,0,0,0,0,0	/* 4F-55 */					.byte '>					.fill 10,1,0								alt_map:					.byte 0,0					.ascii "\0@\0$\0\0{[]}\\\0"					.byte 0,0					.byte 0,0,0,0,0,0,0,0,0,0,0					.byte '~,13,0					.byte 0,0,0,0,0,0,0,0,0,0,0					.byte 0,0					.byte 0,0,0,0,0,0,0,0,0,0,0					.byte 0,0,0,0		/* 36-39 */					.fill 16,1,0		/* 3A-49 */					.byte 0,0,0,0,0		/* 4A-4E */					.byte 0,0,0,0,0,0,0	/* 4F-55 */					.byte '|					.fill 10,1,0								#elif defined(KBD_GR)								key_map:					.byte 0,27					.ascii "1234567890\\'"					.byte 127,9					.ascii "qwertzuiop@+"					.byte 13,0					.ascii "asdfghjkl[]^"					.byte 0,'#					.ascii "yxcvbnm,.-"					.byte 0,'*,0,32		/* 36-39 */					.fill 16,1,0		/* 3A-49 */					.byte '-,0,0,0,'+	/* 4A-4E */					.byte 0,0,0,0,0,0,0	/* 4F-55 */					.byte '					.fill 10,1,0												shift_map:					.byte 0,27					.ascii "!\"#$%&/()=?`"					.byte 127,9					.ascii "QWERTZUIOP\\*"					.byte 13,0					.ascii "ASDFGHJKL{}~"					.byte 0,''					.ascii "YXCVBNM;:_"					.byte 0,'*,0,32		/* 36-39 */					.fill 16,1,0		/* 3A-49 */					.byte '-,0,0,0,'+	/* 4A-4E */					.byte 0,0,0,0,0,0,0	/* 4F-55 */					.byte '>					.fill 10,1,0								alt_map:					.byte 0,0					.ascii "\0@\0$\0\0{[]}\\\0"					.byte 0,0					.byte '@,0,0,0,0,0,0,0,0,0,0					.byte '~,13,0					.byte 0,0,0,0,0,0,0,0,0,0,0					.byte 0,0					.byte 0,0,0,0,0,0,0,0,0,0,0					.byte 0,0,0,0		/* 36-39 */					.fill 16,1,0		/* 3A-49 */					.byte 0,0,0,0,0		/* 4A-4E */					.byte 0,0,0,0,0,0,0	/* 4F-55 */					.byte '|					.fill 10,1,0												#elif defined(KBD_FR)								key_map:					.byte 0,27					.ascii "&{\"'(-}_/@)="					.byte 127,9					.ascii "azertyuiop^$"					.byte 13,0					.ascii "qsdfghjklm|"					.byte '`,0,42		/* coin sup gauche, don't know, [*|mu] */					.ascii "wxcvbn,;:!"					.byte 0,'*,0,32		/* 36-39 */					.fill 16,1,0		/* 3A-49 */					.byte '-,0,0,0,'+	/* 4A-4E */					.byte 0,0,0,0,0,0,0	/* 4F-55 */					.byte '					.fill 10,1,0								shift_map:					.byte 0,27					.ascii "1234567890]+"					.byte 127,9					.ascii "AZERTYUIOP"					.byte 13,0					.ascii "QSDFGHJKLM%"					.byte '~,0,'#					.ascii "WXCVBN?./\\"					.byte 0,'*,0,32		/* 36-39 */					.fill 16,1,0		/* 3A-49 */					.byte '-,0,0,0,'+	/* 4A-4E */					.byte 0,0,0,0,0,0,0	/* 4F-55 */					.byte '>					.fill 10,1,0								alt_map:					.byte 0,0					.ascii "\0~#{[|`\\^@]}"					.byte 0,0					.byte '@,0,0,0,0,0,0,0,0,0,0					.byte '~,13,0					.byte 0,0,0,0,0,0,0,0,0,0,0					.byte 0,0					.byte 0,0,0,0,0,0,0,0,0,0,0					.byte 0,0,0,0		/* 36-39 */					.fill 16,1,0		/* 3A-49 */					.byte 0,0,0,0,0		/* 4A-4E */					.byte 0,0,0,0,0,0,0	/* 4F-55 */					.byte '|					.fill 10,1,0								#else				#error "KBD-type not defined"				#endif				/*				 * do_self handles "normal" keys, ie keys that don't change meaning				 * and which have just one character returns.				 */				do_self:					lea alt_map,%ebx					testb $0x20,mode		/* alt-gr */					jne 1f					lea shift_map,%ebx					testb $0x03,mode					jne 1f					lea key_map,%ebx				1:	movb (%ebx,%eax),%al					orb %al,%al					je none					testb $0x4c,mode		/* ctrl or caps */					je 2f					cmpb $'a,%al					jb 2f					cmpb $'},%al					ja 2f					subb $32,%al				2:	testb $0x0c,mode		/* ctrl */					je 3f					cmpb $64,%al					jb 3f					cmpb $64+32,%al					jae 3f					subb $64,%al				3:	testb $0x10,mode		/* left alt */					je 4f					orb $0x80,%al				4:	andl $0xff,%eax					xorl %ebx,%ebx					call put_queue				none:	ret								/*				 * minus has a routine of it's own, as a 'E0h' before				 * the scan code for minus means that the numeric keypad				 * slash was pushed.				 */				minus:	cmpb $1,e0					jne do_self					movl $'/,%eax					xorl %ebx,%ebx					jmp put_queue								/*				 * This table decides which routine to call when a scan-code has been				 * gotten. Most routines just call do_self, or none, depending if				 * they are make or break.				 */				key_table:					.long none,do_self,do_self,do_self	/* 00-03 s0 esc 1 2 */					.long do_self,do_self,do_self,do_self	/* 04-07 3 4 5 6 */					.long do_self,do_self,do_self,do_self	/* 08-0B 7 8 9 0 */					.long do_self,do_self,do_self,do_self	/* 0C-0F + ' bs tab */					.long do_self,do_self,do_self,do_self	/* 10-13 q w e r */					.long do_self,do_self,do_self,do_self	/* 14-17 t y u i */					.long do_self,do_self,do_self,do_self	/* 18-1B o p } ^ */					.long do_self,ctrl,do_self,do_self	/* 1C-1F enter ctrl a s */					.long do_self,do_self,do_self,do_self	/* 20-23 d f g h */					.long do_self,do_self,do_self,do_self	/* 24-27 j k l | */					.long do_self,do_self,lshift,do_self	/* 28-2B { para lshift , */					.long do_self,do_self,do_self,do_self	/* 2C-2F z x c v */					.long do_self,do_self,do_self,do_self	/* 30-33 b n m , */					.long do_self,minus,rshift,do_self	/* 34-37 . - rshift * */					.long alt,do_self,caps,func		/* 38-3B alt sp caps f1 */					.long func,func,func,func		/* 3C-3F f2 f3 f4 f5 */					.long func,func,func,func		/* 40-43 f6 f7 f8 f9 */					.long func,num,scroll,cursor		/* 44-47 f10 num scr home */					.long cursor,cursor,do_self,cursor	/* 48-4B up pgup - left */					.long cursor,cursor,do_self,cursor	/* 4C-4F n5 right + end */					.long cursor,cursor,cursor,cursor	/* 50-53 dn pgdn ins del */					.long none,none,do_self,func		/* 54-57 sysreq ? < f11 */					.long func,none,none,none		/* 58-5B f12 ? ? ? */					.long none,none,none,none		/* 5C-5F ? ? ? ? */					.long none,none,none,none		/* 60-63 ? ? ? ? */					.long none,none,none,none		/* 64-67 ? ? ? ? */					.long none,none,none,none		/* 68-6B ? ? ? ? */					.long none,none,none,none		/* 6C-6F ? ? ? ? */					.long none,none,none,none		/* 70-73 ? ? ? ? */					.long none,none,none,none		/* 74-77 ? ? ? ? */					.long none,none,none,none		/* 78-7B ? ? ? ? */					.long none,none,none,none		/* 7C-7F ? ? ? ? */					.long none,none,none,none		/* 80-83 ? br br br */					.long none,none,none,none		/* 84-87 br br br br */					.long none,none,none,none		/* 88-8B br br br br */					.long none,none,none,none		/* 8C-8F br br br br */					.long none,none,none,none		/* 90-93 br br br br */					.long none,none,none,none		/* 94-97 br br br br */					.long none,none,none,none		/* 98-9B br br br br */					.long none,unctrl,none,none		/* 9C-9F br unctrl br br */					.long none,none,none,none		/* A0-A3 br br br br */					.long none,none,none,none		/* A4-A7 br br br br */					.long none,none,unlshift,none		/* A8-AB br br unlshift br */					.long none,none,none,none		/* AC-AF br br br br */					.long none,none,none,none		/* B0-B3 br br br br */					.long none,none,unrshift,none		/* B4-B7 br br unrshift br */					.long unalt,none,uncaps,none		/* B8-BB unalt br uncaps br */					.long none,none,none,none		/* BC-BF br br br br */					.long none,none,none,none		/* C0-C3 br br br br */					.long none,none,none,none		/* C4-C7 br br br br */					.long none,none,none,none		/* C8-CB br br br br */					.long none,none,none,none		/* CC-CF br br br br */					.long none,none,none,none		/* D0-D3 br br br br */					.long none,none,none,none		/* D4-D7 br br br br */					.long none,none,none,none		/* D8-DB br ? ? ? */					.long none,none,none,none		/* DC-DF ? ? ? ? */					.long none,none,none,none		/* E0-E3 e0 e1 ? ? */					.long none,none,none,none		/* E4-E7 ? ? ? ? */					.long none,none,none,none		/* E8-EB ? ? ? ? */					.long none,none,none,none		/* EC-EF ? ? ? ? */					.long none,none,none,none		/* F0-F3 ? ? ? ? */					.long none,none,none,none		/* F4-F7 ? ? ? ? */					.long none,none,none,none		/* F8-FB ? ? ? ? */					.long none,none,none,none		/* FC-FF ? ? ? ? */								/*				 * kb_wait waits for the keyboard controller buffer to empty.				 * there is no timeout - if the buffer doesn't empty, we hang.				 */				kb_wait:					pushl %eax				1:	inb $0x64,%al					testb $0x02,%al					jne 1b					popl %eax					ret				/*				 * This routine reboots the machine by asking the keyboard				 * controller to pulse the reset-line low.				 */				reboot:					call kb_wait					movw $0x1234,0x472	/* don't do memory check */					movb $0xfc,%al		/* pulse reset and A20 low */					outb %al,$0x64				die:	jmp die							

相关资源