You can not select more than 25 topics
			Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.
		
		
		
		
		
			
		
			
				
					
					
						
							589 lines
						
					
					
						
							12 KiB
						
					
					
				
			
		
		
	
	
							589 lines
						
					
					
						
							12 KiB
						
					
					
				/*
 | 
						|
 *  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 <linux/config.h>
 | 
						|
 | 
						|
.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
 | 
						|
	xor %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
 |