键盘中有一颗键盘编码器的芯片,通常是Intel8048及兼容芯片,它的作用就是监视键盘并把相应的数据传个pc机。在pc机的主板上有一个键盘控制器,通常是8042及兼容芯片,它的作用用来接收和解码来着键盘的数据并放到缓冲区,然后通知8259A产生中断IRQ1.
那么我们收到键盘中断IRQ1应该做什么呢?当然是读出缓冲区的数据,然后解析出我们想要的键值了。那么我们重点看一下8042的操作:
1.读缓冲区,读0x60端口
2.写缓冲区,写0x60端口
3.读状态寄存器,读0x64端口
4.控制寄存器,写0x64端口
很明显我们的任务就是在中断函数中读0x60端口
首先我们先新建一个keyboard.S文件,keyboard_interrupt用来处理键盘中断,其实它的主要作用就是调用do_keyboard函数,我们把主要工作放到这里
.globl keyboard_interrupt keyboard_interrupt: push %ds pushl %edx pushl %ecx pushl %ebx pushl %eax movl $0x10, %eax mov %ax, %ds mov %ax,%es call do_keyboard movb $0x20,%al outb %al,$0x20 popl %eax popl %ebx popl %ecx popl %edx pop %ds iret
con_init中干了两件事:1,注册键盘中断处理函数keyboard_interrupt。2,打开键盘中断。do_keyboard函数不用多说,keyboard_interrupt调用了它,它的主要工作就是读0x60端口,然后进行处理。0xe0和0xe1是特殊键值我们单独处理,一般字符我们用key_table这个函数指针数组来处理。
void do_keyboard(void) { register unsigned char scan_code; scan_code=inb_p(0x60); if(scan_code==0xe0) { disp_str("0xe0"); } else if(scan_code==0xe1) { disp_str("0xe1"); } else { key_table[scan_code](); } } extern void keyboard_interrupt(void); void con_init(void) { register unsigned char a; set_trap_gate(0x21,&keyboard_interrupt); outb_p(inb_p(0x21)&0xfd,0x21); a=inb_p(0x61); outb_p(a|0x80,0x61); outb(a,0x61); }
void none(void) { disp_str("none"); } void do_self(void) { disp_str("do_self"); } void ctrl(void) { disp_str("ctrl"); } void lshift(void) { disp_str("lshift"); } void rshift(void) { disp_str("rshift"); } void minus(void) { disp_str("minus"); } void alt(void) { disp_str("alt"); } void caps(void) { disp_str("caps"); } void func(void) { disp_str("func"); } void num(void) { disp_str("num"); } void scroll(void) { disp_str("scroll"); } void cursor(void) { disp_str("cursor"); } void unctrl(void) { disp_str("unctrl"); } void unlshift(void) { disp_str("unlshift"); } void unrshift(void) { disp_str("unrshift"); } void unalt(void) { disp_str("unalt"); } void uncaps(void) { disp_str("uncaps"); } typedef void (*function)(void); #define Function(address) (*(function)address)() static function key_table[] = { none,do_self,do_self,do_self /* 00-03 s0 esc 1 2 */ ,do_self,do_self,do_self,do_self /* 04-07 3 4 5 6 */ ,do_self,do_self,do_self,do_self /* 08-0B 7 8 9 0 */ ,do_self,do_self,do_self,do_self /* 0C-0F + ' bs tab */ ,do_self,do_self,do_self,do_self /* 10-13 q w e r */ ,do_self,do_self,do_self,do_self /* 14-17 t y u i */ ,do_self,do_self,do_self,do_self /* 18-1B o p } ^ */ ,do_self,ctrl,do_self,do_self /* 1C-1F enter ctrl a s */ ,do_self,do_self,do_self,do_self /* 20-23 d f g h */ ,do_self,do_self,do_self,do_self /* 24-27 j k l | */ ,do_self,do_self,lshift,do_self /* 28-2B { para lshift , */ ,do_self,do_self,do_self,do_self /* 2C-2F z x c v */ ,do_self,do_self,do_self,do_self /* 30-33 b n m , */ ,do_self,minus,rshift,do_self /* 34-37 . - rshift * */ ,alt,do_self,caps,func /* 38-3B alt sp caps f1 */ ,func,func,func,func /* 3C-3F f2 f3 f4 f5 */ ,func,func,func,func /* 40-43 f6 f7 f8 f9 */ ,func,num,scroll,cursor /* 44-47 f10 num scr home */ ,cursor,cursor,do_self,cursor /* 48-4B up pgup - left */ ,cursor,cursor,do_self,cursor /* 4C-4F n5 right + end */ ,cursor,cursor,cursor,cursor /* 50-53 dn pgdn ins del */ ,none,none,do_self,func /* 54-57 sysreq ? < f11 */ ,func,none,none,none /* 58-5B f12 ? ? ? */ ,none,none,none,none /* 5C-5F ? ? ? ? */ ,none,none,none,none /* 60-63 ? ? ? ? */ ,none,none,none,none /* 64-67 ? ? ? ? */ ,none,none,none,none /* 68-6B ? ? ? ? */ ,none,none,none,none /* 6C-6F ? ? ? ? */ ,none,none,none,none /* 70-73 ? ? ? ? */ ,none,none,none,none /* 74-77 ? ? ? ? */ ,none,none,none,none /* 78-7B ? ? ? ? */ ,none,none,none,none /* 7C-7F ? ? ? ? */ ,none,none,none,none /* 80-83 ? br br br */ ,none,none,none,none /* 84-87 br br br br */ ,none,none,none,none /* 88-8B br br br br */ ,none,none,none,none /* 8C-8F br br br br */ ,none,none,none,none /* 90-93 br br br br */ ,none,none,none,none /* 94-97 br br br br */ ,none,none,none,none /* 98-9B br br br br */ ,none,unctrl,none,none /* 9C-9F br unctrl br br */ ,none,none,none,none /* A0-A3 br br br br */ ,none,none,none,none /* A4-A7 br br br br */ ,none,none,unlshift,none /* A8-AB br br unlshift br */ ,none,none,none,none /* AC-AF br br br br */ ,none,none,none,none /* B0-B3 br br br br */ ,none,none,unrshift,none /* B4-B7 br br unrshift br */ ,unalt,none,uncaps,none /* B8-BB unalt br uncaps br */ ,none,none,none,none /* BC-BF br br br br */ ,none,none,none,none /* C0-C3 br br br br */ ,none,none,none,none /* C4-C7 br br br br */ ,none,none,none,none /* C8-CB br br br br */ ,none,none,none,none /* CC-CF br br br br */ ,none,none,none,none /* D0-D3 br br br br */ ,none,none,none,none /* D4-D7 br br br br */ ,none,none,none,none /* D8-DB br ? ? ? */ ,none,none,none,none /* DC-DF ? ? ? ? */ ,none,none,none,none /* E0-E3 e0 e1 ? ? */ ,none,none,none,none /* E4-E7 ? ? ? ? */ ,none,none,none,none /* E8-EB ? ? ? ? */ ,none,none,none,none /* EC-EF ? ? ? ? */ ,none,none,none,none /* F0-F3 ? ? ? ? */ ,none,none,none,none /* F4-F7 ? ? ? ? */ ,none,none,none,none /* F8-FB ? ? ? ? */ ,none,none,none,none /* FC-FF ? ? ? ? */ };