|
|
1.1 ! root 1: /* ! 2: * keyboard.s ! 3: */ ! 4: ! 5: .text ! 6: .globl _keyboard_interrupt ! 7: ! 8: /* ! 9: * these are for the keyboard read functions ! 10: */ ! 11: size = 1024 /* must be a power of two ! And MUST be the same ! 12: as in tty_io.c !!!! */ ! 13: head = 4 ! 14: tail = 8 ! 15: proc_list = 12 ! 16: buf = 16 ! 17: ! 18: mode: .byte 0 /* caps, alt, ctrl and shift mode */ ! 19: leds: .byte 2 /* num-lock, caps, scroll-lock mode (nom-lock on) */ ! 20: e0: .byte 0 ! 21: ! 22: /* ! 23: * con_int is the real interrupt routine that reads the ! 24: * keyboard scan-code and converts it into the appropriate ! 25: * ascii character(s). ! 26: */ ! 27: _keyboard_interrupt: ! 28: pushl %eax ! 29: pushl %ebx ! 30: pushl %ecx ! 31: pushl %edx ! 32: push %ds ! 33: push %es ! 34: movl $0x10,%eax ! 35: mov %ax,%ds ! 36: mov %ax,%es ! 37: xorl %al,%al /* %eax is scan code */ ! 38: inb $0x60,%al ! 39: cmpb $0xe0,%al ! 40: je set_e0 ! 41: cmpb $0xe1,%al ! 42: je set_e1 ! 43: call key_table(,%eax,4) ! 44: movb $0,e0 ! 45: e0_e1: inb $0x61,%al ! 46: jmp 1f ! 47: 1: jmp 1f ! 48: 1: orb $0x80,%al ! 49: jmp 1f ! 50: 1: jmp 1f ! 51: 1: outb %al,$0x61 ! 52: jmp 1f ! 53: 1: jmp 1f ! 54: 1: andb $0x7F,%al ! 55: outb %al,$0x61 ! 56: movb $0x20,%al ! 57: outb %al,$0x20 ! 58: pushl $0 ! 59: call _do_tty_interrupt ! 60: addl $4,%esp ! 61: pop %es ! 62: pop %ds ! 63: popl %edx ! 64: popl %ecx ! 65: popl %ebx ! 66: popl %eax ! 67: iret ! 68: set_e0: movb $1,e0 ! 69: jmp e0_e1 ! 70: set_e1: movb $2,e0 ! 71: jmp e0_e1 ! 72: ! 73: /* ! 74: * This routine fills the buffer with max 8 bytes, taken from ! 75: * %ebx:%eax. (%edx is high). The bytes are written in the ! 76: * order %al,%ah,%eal,%eah,%bl,%bh ... until %eax is zero. ! 77: */ ! 78: put_queue: ! 79: pushl %ecx ! 80: pushl %edx ! 81: movl _table_list,%edx # read-queue for console ! 82: movl head(%edx),%ecx ! 83: 1: movb %al,buf(%edx,%ecx) ! 84: incl %ecx ! 85: andl $size-1,%ecx ! 86: cmpl tail(%edx),%ecx # buffer full - discard everything ! 87: je 3f ! 88: shrdl $8,%ebx,%eax ! 89: je 2f ! 90: shrl $8,%ebx ! 91: jmp 1b ! 92: 2: movl %ecx,head(%edx) ! 93: movl proc_list(%edx),%ecx ! 94: testl %ecx,%ecx ! 95: je 3f ! 96: movl $0,(%ecx) ! 97: 3: popl %edx ! 98: popl %ecx ! 99: ret ! 100: ! 101: ctrl: movb $0x04,%al ! 102: jmp 1f ! 103: alt: movb $0x10,%al ! 104: 1: cmpb $0,e0 ! 105: je 2f ! 106: addb %al,%al ! 107: 2: orb %al,mode ! 108: ret ! 109: unctrl: movb $0x04,%al ! 110: jmp 1f ! 111: unalt: movb $0x10,%al ! 112: 1: cmpb $0,e0 ! 113: je 2f ! 114: addb %al,%al ! 115: 2: notb %al ! 116: andb %al,mode ! 117: ret ! 118: ! 119: lshift: ! 120: orb $0x01,mode ! 121: ret ! 122: unlshift: ! 123: andb $0xfe,mode ! 124: ret ! 125: rshift: ! 126: orb $0x02,mode ! 127: ret ! 128: unrshift: ! 129: andb $0xfd,mode ! 130: ret ! 131: ! 132: caps: testb $0x80,mode ! 133: jne 1f ! 134: xorb $4,leds ! 135: xorb $0x40,mode ! 136: orb $0x80,mode ! 137: set_leds: ! 138: call kb_wait ! 139: movb $0xed,%al /* set leds command */ ! 140: outb %al,$0x60 ! 141: call kb_wait ! 142: movb leds,%al ! 143: outb %al,$0x60 ! 144: ret ! 145: uncaps: andb $0x7f,mode ! 146: ret ! 147: scroll: ! 148: xorb $1,leds ! 149: jmp set_leds ! 150: num: xorb $2,leds ! 151: jmp set_leds ! 152: ! 153: /* ! 154: * curosr-key/numeric keypad cursor keys are handled here. ! 155: * checking for numeric keypad etc. ! 156: */ ! 157: cursor: ! 158: subb $0x47,%al ! 159: jb 1f ! 160: cmpb $12,%al ! 161: ja 1f ! 162: jne cur2 /* check for ctrl-alt-del */ ! 163: testb $0x0c,mode ! 164: je cur2 ! 165: testb $0x30,mode ! 166: jne reboot ! 167: cur2: cmpb $0x01,e0 /* e0 forces cursor movement */ ! 168: je cur ! 169: testb $0x02,leds /* not num-lock forces cursor */ ! 170: je cur ! 171: testb $0x03,mode /* shift forces cursor */ ! 172: jne cur ! 173: xorl %ebx,%ebx ! 174: movb num_table(%eax),%al ! 175: jmp put_queue ! 176: 1: ret ! 177: ! 178: cur: movb cur_table(%eax),%al ! 179: cmpb $'9,%al ! 180: ja ok_cur ! 181: movb $'~,%ah ! 182: ok_cur: shll $16,%eax ! 183: movw $0x5b1b,%ax ! 184: xorl %ebx,%ebx ! 185: jmp put_queue ! 186: ! 187: num_table: ! 188: .ascii "789 456 1230," ! 189: cur_table: ! 190: .ascii "HA5 DGC YB623" ! 191: ! 192: /* ! 193: * this routine handles function keys ! 194: */ ! 195: func: ! 196: subb $0x3B,%al ! 197: jb end_func ! 198: cmpb $9,%al ! 199: jbe ok_func ! 200: subb $18,%al ! 201: cmpb $10,%al ! 202: jb end_func ! 203: cmpb $11,%al ! 204: ja end_func ! 205: ok_func: ! 206: cmpl $4,%ecx /* check that there is enough room */ ! 207: jl end_func ! 208: movl func_table(,%eax,4),%eax ! 209: xorl %ebx,%ebx ! 210: jmp put_queue ! 211: end_func: ! 212: ret ! 213: ! 214: /* ! 215: * function keys send F1:'esc [ [ A' F2:'esc [ [ B' etc. ! 216: */ ! 217: func_table: ! 218: .long 0x415b5b1b,0x425b5b1b,0x435b5b1b,0x445b5b1b ! 219: .long 0x455b5b1b,0x465b5b1b,0x475b5b1b,0x485b5b1b ! 220: .long 0x495b5b1b,0x4a5b5b1b,0x4b5b5b1b,0x4c5b5b1b ! 221: ! 222: key_map: ! 223: .byte 0,27 ! 224: .ascii "1234567890+'" ! 225: .byte 127,9 ! 226: .ascii "qwertyuiop}" ! 227: .byte 0,10,0 ! 228: .ascii "asdfghjkl|{" ! 229: .byte 0,0 ! 230: .ascii "'zxcvbnm,.-" ! 231: .byte 0,'*,0,32 /* 36-39 */ ! 232: .fill 16,1,0 /* 3A-49 */ ! 233: .byte '-,0,0,0,'+ /* 4A-4E */ ! 234: .byte 0,0,0,0,0,0,0 /* 4F-55 */ ! 235: .byte '< ! 236: .fill 10,1,0 ! 237: ! 238: shift_map: ! 239: .byte 0,27 ! 240: .ascii "!\"#$%&/()=?`" ! 241: .byte 127,9 ! 242: .ascii "QWERTYUIOP]^" ! 243: .byte 10,0 ! 244: .ascii "ASDFGHJKL\\[" ! 245: .byte 0,0 ! 246: .ascii "*ZXCVBNM;:_" ! 247: .byte 0,'*,0,32 /* 36-39 */ ! 248: .fill 16,1,0 /* 3A-49 */ ! 249: .byte '-,0,0,0,'+ /* 4A-4E */ ! 250: .byte 0,0,0,0,0,0,0 /* 4F-55 */ ! 251: .byte '> ! 252: .fill 10,1,0 ! 253: ! 254: alt_map: ! 255: .byte 0,0 ! 256: .ascii "\0@\0$\0\0{[]}\\\0" ! 257: .byte 0,0 ! 258: .byte 0,0,0,0,0,0,0,0,0,0,0 ! 259: .byte '~,10,0 ! 260: .byte 0,0,0,0,0,0,0,0,0,0,0 ! 261: .byte 0,0 ! 262: .byte 0,0,0,0,0,0,0,0,0,0,0 ! 263: .byte 0,0,0,0 /* 36-39 */ ! 264: .fill 16,1,0 /* 3A-49 */ ! 265: .byte 0,0,0,0,0 /* 4A-4E */ ! 266: .byte 0,0,0,0,0,0,0 /* 4F-55 */ ! 267: .byte '| ! 268: .fill 10,1,0 ! 269: ! 270: /* ! 271: * do_self handles "normal" keys, ie keys that don't change meaning ! 272: * and which have just one character returns. ! 273: */ ! 274: do_self: ! 275: lea alt_map,%ebx ! 276: testb $0x20,mode /* alt-gr */ ! 277: jne 1f ! 278: lea shift_map,%ebx ! 279: testb $0x03,mode ! 280: jne 1f ! 281: lea key_map,%ebx ! 282: 1: movb (%ebx,%eax),%al ! 283: orb %al,%al ! 284: je none ! 285: testb $0x4c,mode /* ctrl or caps */ ! 286: je 2f ! 287: cmpb $'a,%al ! 288: jb 2f ! 289: cmpb $'z,%al ! 290: ja 2f ! 291: subb $32,%al ! 292: 2: testb $0x0c,mode /* ctrl */ ! 293: je 3f ! 294: cmpb $64,%al ! 295: jb 3f ! 296: cmpb $64+32,%al ! 297: jae 3f ! 298: subb $64,%al ! 299: 3: testb $0x10,mode /* left alt */ ! 300: je 4f ! 301: orb $0x80,%al ! 302: 4: andl $0xff,%eax ! 303: xorl %ebx,%ebx ! 304: call put_queue ! 305: none: ret ! 306: ! 307: /* ! 308: * minus has a routine of it's own, as a 'E0h' before ! 309: * the scan code for minus means that the numeric keypad ! 310: * slash was pushed. ! 311: */ ! 312: minus: cmpb $1,e0 ! 313: jne do_self ! 314: movl $'/,%eax ! 315: xorl %ebx,%ebx ! 316: jmp put_queue ! 317: ! 318: /* ! 319: * This table decides which routine to call when a scan-code has been ! 320: * gotten. Most routines just call do_self, or none, depending if ! 321: * they are make or break. ! 322: */ ! 323: key_table: ! 324: .long none,do_self,do_self,do_self /* 00-03 s0 esc 1 2 */ ! 325: .long do_self,do_self,do_self,do_self /* 04-07 3 4 5 6 */ ! 326: .long do_self,do_self,do_self,do_self /* 08-0B 7 8 9 0 */ ! 327: .long do_self,do_self,do_self,do_self /* 0C-0F + ' bs tab */ ! 328: .long do_self,do_self,do_self,do_self /* 10-13 q w e r */ ! 329: .long do_self,do_self,do_self,do_self /* 14-17 t y u i */ ! 330: .long do_self,do_self,do_self,do_self /* 18-1B o p } ^ */ ! 331: .long do_self,ctrl,do_self,do_self /* 1C-1F enter ctrl a s */ ! 332: .long do_self,do_self,do_self,do_self /* 20-23 d f g h */ ! 333: .long do_self,do_self,do_self,do_self /* 24-27 j k l | */ ! 334: .long do_self,do_self,lshift,do_self /* 28-2B { para lshift , */ ! 335: .long do_self,do_self,do_self,do_self /* 2C-2F z x c v */ ! 336: .long do_self,do_self,do_self,do_self /* 30-33 b n m , */ ! 337: .long do_self,minus,rshift,do_self /* 34-37 . - rshift * */ ! 338: .long alt,do_self,caps,func /* 38-3B alt sp caps f1 */ ! 339: .long func,func,func,func /* 3C-3F f2 f3 f4 f5 */ ! 340: .long func,func,func,func /* 40-43 f6 f7 f8 f9 */ ! 341: .long func,num,scroll,cursor /* 44-47 f10 num scr home */ ! 342: .long cursor,cursor,do_self,cursor /* 48-4B up pgup - left */ ! 343: .long cursor,cursor,do_self,cursor /* 4C-4F n5 right + end */ ! 344: .long cursor,cursor,cursor,cursor /* 50-53 dn pgdn ins del */ ! 345: .long none,none,do_self,func /* 54-57 sysreq ? < f11 */ ! 346: .long func,none,none,none /* 58-5B f12 ? ? ? */ ! 347: .long none,none,none,none /* 5C-5F ? ? ? ? */ ! 348: .long none,none,none,none /* 60-63 ? ? ? ? */ ! 349: .long none,none,none,none /* 64-67 ? ? ? ? */ ! 350: .long none,none,none,none /* 68-6B ? ? ? ? */ ! 351: .long none,none,none,none /* 6C-6F ? ? ? ? */ ! 352: .long none,none,none,none /* 70-73 ? ? ? ? */ ! 353: .long none,none,none,none /* 74-77 ? ? ? ? */ ! 354: .long none,none,none,none /* 78-7B ? ? ? ? */ ! 355: .long none,none,none,none /* 7C-7F ? ? ? ? */ ! 356: .long none,none,none,none /* 80-83 ? br br br */ ! 357: .long none,none,none,none /* 84-87 br br br br */ ! 358: .long none,none,none,none /* 88-8B br br br br */ ! 359: .long none,none,none,none /* 8C-8F br br br br */ ! 360: .long none,none,none,none /* 90-93 br br br br */ ! 361: .long none,none,none,none /* 94-97 br br br br */ ! 362: .long none,none,none,none /* 98-9B br br br br */ ! 363: .long none,unctrl,none,none /* 9C-9F br unctrl br br */ ! 364: .long none,none,none,none /* A0-A3 br br br br */ ! 365: .long none,none,none,none /* A4-A7 br br br br */ ! 366: .long none,none,unlshift,none /* A8-AB br br unlshift br */ ! 367: .long none,none,none,none /* AC-AF br br br br */ ! 368: .long none,none,none,none /* B0-B3 br br br br */ ! 369: .long none,none,unrshift,none /* B4-B7 br br unrshift br */ ! 370: .long unalt,none,uncaps,none /* B8-BB unalt br uncaps br */ ! 371: .long none,none,none,none /* BC-BF br br br br */ ! 372: .long none,none,none,none /* C0-C3 br br br br */ ! 373: .long none,none,none,none /* C4-C7 br br br br */ ! 374: .long none,none,none,none /* C8-CB br br br br */ ! 375: .long none,none,none,none /* CC-CF br br br br */ ! 376: .long none,none,none,none /* D0-D3 br br br br */ ! 377: .long none,none,none,none /* D4-D7 br br br br */ ! 378: .long none,none,none,none /* D8-DB br ? ? ? */ ! 379: .long none,none,none,none /* DC-DF ? ? ? ? */ ! 380: .long none,none,none,none /* E0-E3 e0 e1 ? ? */ ! 381: .long none,none,none,none /* E4-E7 ? ? ? ? */ ! 382: .long none,none,none,none /* E8-EB ? ? ? ? */ ! 383: .long none,none,none,none /* EC-EF ? ? ? ? */ ! 384: .long none,none,none,none /* F0-F3 ? ? ? ? */ ! 385: .long none,none,none,none /* F4-F7 ? ? ? ? */ ! 386: .long none,none,none,none /* F8-FB ? ? ? ? */ ! 387: .long none,none,none,none /* FC-FF ? ? ? ? */ ! 388: ! 389: /* ! 390: * kb_wait waits for the keyboard controller buffer to empty. ! 391: * there is no timeout - if the buffer doesn't empty, we hang. ! 392: */ ! 393: kb_wait: ! 394: pushl %eax ! 395: 1: inb $0x64,%al ! 396: testb $0x02,%al ! 397: jne 1b ! 398: popl %eax ! 399: ret ! 400: /* ! 401: * This routine reboots the machine by asking the keyboard ! 402: * controller to pulse the reset-line low. ! 403: */ ! 404: reboot: ! 405: call kb_wait ! 406: movw $0x1234,0x472 /* don't do memory check */ ! 407: movb $0xfc,%al /* pulse reset and A20 low */ ! 408: outb %al,$0x64 ! 409: die: jmp die
This archive runs on limited infrastructure. Preserving old code on modern bandwidth. Automated agents are requested to crawl responsibly.