| /* |
| * 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 |
| * LeBlanc@mcc.ac.uk for the UK keyboard |
| * Tommy Thorn (tthorn@daimi.aau.dk) for Danish keyboard |
| */ |
| |
| /* KBD_FINNISH for Finnish keyboards |
| * KBD_US for US-type |
| * KBD_GR for German keyboards |
| * KBD_FR for Frech keyboard |
| * KBD_UK for British extended keyboard |
| * KBD_DK for Danish keyboard |
| */ |
| |
| .text |
| .globl _hard_reset_now |
| .globl _keyboard_interrupt |
| .globl _kapplic |
| .globl _kmode |
| .globl _kleds |
| .globl _set_leds |
| |
| /* |
| * these are for the keyboard read functions |
| */ |
| size = 2048 /* 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 |
| |
| _kapplic: .byte 0 |
| _kmode: .byte 0 /* caps, alt, ctrl and shift mode */ |
| _kleds: .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: |
| cld |
| pushl %eax |
| pushl %ebx |
| pushl %ecx |
| pushl %edx |
| push %ds |
| push %es |
| movl $0x10,%eax |
| mov %ax,%ds |
| mov %ax,%es |
| xorl %eax,%eax /* %eax is scan code */ |
| inb $0x60,%al |
| pushl %eax |
| 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 |
| jmp 1f |
| 1: jmp 1f |
| 1: movb $0x20,%al |
| outb %al,$0x20 |
| popl %eax |
| movl $1,%ebx |
| cmpb $0xE0,%al |
| je end_intr |
| movl $2,%ebx |
| cmpb $0xE1,%al |
| je end_intr |
| sti |
| call key_table(,%eax,4) |
| call _do_keyboard_interrupt |
| movl $0,%ebx |
| end_intr: |
| movb %bl,e0 |
| pop %es |
| pop %ds |
| popl %edx |
| popl %ecx |
| popl %ebx |
| popl %eax |
| iret |
| |
| /* |
| * 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,_kmode |
| 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,_kmode |
| ret |
| |
| lshift: |
| orb $0x01,_kmode |
| ret |
| unlshift: |
| andb $0xfe,_kmode |
| ret |
| rshift: |
| orb $0x02,_kmode |
| ret |
| unrshift: |
| andb $0xfd,_kmode |
| ret |
| |
| old_leds: |
| .byte 2 |
| |
| caps: testb $0x80,_kmode |
| jne 1f |
| xorb $4,_kleds |
| xorb $0x40,_kmode |
| orb $0x80,_kmode |
| _set_leds: |
| movb _kleds,%al |
| cmpb old_leds,%al |
| je 1f |
| movb %al,old_leds |
| call kb_wait |
| movb $0xed,%al /* set leds command */ |
| outb %al,$0x60 |
| call kb_wait |
| movb _kleds,%al |
| outb %al,$0x60 |
| 1: ret |
| uncaps: andb $0x7f,_kmode |
| ret |
| scroll: |
| testb $0x03,_kmode |
| je 1f |
| call _show_mem |
| jmp 2f |
| 1: call _show_state |
| 2: xorb $1,_kleds |
| jmp _set_leds |
| |
| num: cmpb $0x01,_kapplic |
| jne notappl |
| movw $0x0050,%ax |
| applkey: |
| shll $16,%eax |
| movw $0x4f1b,%ax |
| xorl %ebx,%ebx |
| jmp put_queue |
| |
| notappl: |
| xorb $2,_kleds |
| jmp _set_leds |
| |
| /* |
| * cursor-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,_kmode |
| je cur2 |
| testb $0x30,_kmode |
| jne _ctrl_alt_del |
| cur2: cmpb $0x01,e0 /* e0 forces cursor movement */ |
| je cur |
| testb $0x03,_kmode /* shift forces cursor */ |
| jne cur |
| cmpb $0x01,_kapplic |
| jne notcappl |
| movb appl_table(%eax),%al |
| jmp applkey |
| notcappl: |
| testb $0x02,_kleds /* not num-lock forces cursor */ |
| je cur |
| xorl %ebx,%ebx |
| movb num_table(%eax),%al |
| jmp put_queue |
| 1: ret |
| |
| /* |
| * cursor keys send ^[ [ x if normal, ^[ O x if application mode |
| */ |
| 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 |
| cmpb $0x01,_kapplic |
| jne put_queue |
| movb $0x4f,%ah |
| jmp put_queue |
| |
| #if defined(KBD_FR) /* || defined(KBD_DK) correct, but .. */ |
| num_table: |
| .ascii "789-456+1230." |
| #else |
| num_table: |
| .ascii "789-456+1230," |
| #endif |
| cur_table: |
| .ascii "HA5-DGC+YB623" |
| |
| /* |
| Keypad / 35 B7 Q |
| Keypad * (PrtSc) 37 B7 R |
| Keypad NumLock 45 ?? P |
| Keypad 7 (Home) 47 C7 w |
| Keypad 8 (Up arrow) 48 C8 x |
| Keypad 9 (PgUp) 49 C9 y |
| Keypad - 4A CA S |
| Keypad 4 (Left arrow) 4B CB t |
| Keypad 5 4C CC u |
| Keypad 6 (Right arrow) 4D CD v |
| Keypad + 4E CE l |
| Keypad 1 (End) 4F CF q |
| Keypad 2 (Down arrow) 50 D0 r |
| Keypad 3 (PgDn) 51 D1 s |
| Keypad 0 (Ins) 52 D2 p |
| Keypad . (Del) 53 D3 n |
| */ |
| |
| appl_table: |
| .ascii "wxyStuvlqrspn" |
| |
| /* |
| * this routine handles function keys |
| */ |
| func: |
| 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: |
| testb $0x10,_kmode |
| jne alt_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 |
| alt_func: |
| pushl %eax |
| call _change_console |
| popl %eax |
| 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_UK) |
| |
| 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 */ |
| .ascii "\\" |
| .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 |
| |
| #elif defined(KBD_DK) |
| |
| key_map: |
| .byte 0,27 |
| .ascii "1234567890+'" |
| .byte 127,9 |
| .ascii "qwertyuiop" |
| .byte 134,0,13,0 /* This is IBM-PC, change it to latin-1 */ |
| .ascii "asdfghjkl" |
| .byte 145,155,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 143,94,13,0 |
| .ascii "ASDFGHJKL" |
| .byte 146,157,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 */ |
| .ascii "\\" |
| .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,_kmode /* alt-gr */ |
| jne 1f |
| lea shift_map,%ebx |
| testb $0x0f,_kmode |
| jne 1f |
| lea key_map,%ebx |
| 1: movb (%ebx,%eax),%al |
| orb %al,%al |
| je none |
| testb $0x4c,_kmode /* ctrl or caps */ |
| je 2f |
| cmpb $'a,%al |
| jb 2f |
| cmpb $'},%al |
| ja 2f |
| subb $32,%al |
| 2: testb $0x0c,_kmode /* ctrl */ |
| je 3f |
| andb $0x1f,%al |
| 3: testb $0x10,_kmode /* left alt */ |
| je 4f |
| orb $0x80,%al |
| 4: andl $0xff,%eax |
| xorl %ebx,%ebx |
| call put_queue |
| none: ret |
| |
| /* |
| * slash and star have routines of their own, as a 'E0h' before |
| * the scan code for slash means that the numeric keypad |
| * slash was pushed. |
| */ |
| slash: cmpb $1,e0 |
| jne do_self |
| cmpb $1,_kapplic |
| jne notmapplic |
| movw $'Q,%ax |
| jmp applkey |
| |
| notmapplic: |
| movl $'/,%eax |
| xorl %ebx,%ebx |
| jmp put_queue |
| |
| star: cmpb $1,_kapplic |
| jne do_self |
| movw $'R,%ax |
| jmp applkey |
| |
| notsapplic: |
| movl $'*,%eax |
| xorl %ebx,%ebx |
| jmp put_queue |
| |
| enter: cmpb $1,e0 |
| jne do_self |
| cmpb $1,_kapplic |
| jne do_self |
| movw $'M,%ax |
| jmp applkey |
| |
| minus: cmpb $1,_kapplic |
| jne do_self |
| movw $'S,%ax |
| jmp applkey |
| |
| plus: cmpb $1,_kapplic |
| jne do_self |
| movw $'l,%ax |
| jmp applkey |
| |
| /* |
| * 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 enter,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,slash,rshift,star /* 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,minus,cursor /* 48-4B up pgup - left */ |
| .long cursor,cursor,plus,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. |
| */ |
| kb_wait: |
| pushl %eax |
| pushl %ebx |
| movl $10000,%ebx |
| 1: inb $0x64,%al |
| testb $0x02,%al |
| je 2f |
| decl %ebx |
| jne 1b |
| 2: popl %ebx |
| popl %eax |
| ret |
| |
| no_idt: |
| .long 0,0 |
| /* |
| * This routine reboots the machine by asking the keyboard |
| * controller to pulse the reset-line low. We try that for a while, |
| * and if it doesn't work, we do some other stupid things. |
| */ |
| _hard_reset_now: |
| sti |
| movl $100,%ebx |
| 1: call kb_wait |
| movw $0x1234,0x472 /* don't do memory check */ |
| movb $0xfe,%al /* pulse reset low */ |
| outb %al,$0x64 |
| decl %ebx |
| jne 1b |
| lidt no_idt /* zero-length idt: should triple-fault */ |
| jmp _hard_reset_now |