【第7章】解决疑问

     接着上一个问题,这要涉及一点硬件知识了,这些书上说得很明白了,咱们长话短说,计算机里有个芯片叫8042,是CPU和键盘之间代理,负责一些工作,不要让CPU太忙了,因为CPU是很珍贵的,好钢要用在刀刃上嘛。每当按下一个键盘,8042收到相应按的键的扫描码,接着8042把这个扫描码转换一下并把这个码放到对应的缓冲区中,并通知8259A一下,让它发出一个键盘中断。如果缓冲区没被清空,那么即使再发生键盘中断,8042也不会接受了。下面是书上的原理图:

     这时我们就明白了,因为我们的键盘中断处理程序只是打印了一个星号,并没有做其它的,因为没有清掉缓冲区中的码,所以就不再相应新的键盘中断了。

     那么怎么清掉缓冲区中的码呢,就是用in指令从对应的端口中取出值来,下面就是8042的各端口信息:

     既然用到in指令,那么就要用到汇编了,我们写一个In_Byte函数,放到kliba.asm中:

global In_Byte

...

;In_Byte==============================================================
;u8 In_Byte(u16 port);
In_Byte:
 push ebp
 mov ebp,esp
 
 push edx
 
 mov edx,[ebp + 8]
 in al,dx
 
 nop
 nop
 
 pop  edx
 
 pop  ebp
 
 ret
;end of In_Byte=======================================================

     别忘了在proto.h中添加声明:

Code:
  1. u8   In_Byte(u16 port);  

     接着修改Keyboard_Handler,做清空缓冲区的工作:

Code:
  1. void Keyboard_Handler(u32 irq_no)   
  2. {   
  3.     In_Byte(0x60);   
  4.     Disp_Color_Str("*",0xc);   
  5. }  

    make一下,运行,结果如图所示:

   会发现敲一下键盘出现两个星号,这是为什么呢?看看书上怎样说的:因为敲击键盘有两个意义,一个敲击的内容,就是说是你敲的是哪个键,另一个是敲击的动作,分为3类,分别是:按下,保持按住的状态,以及放开。8048既要反映内容,又要反映在动作上。这是通过键盘产生的编码来反映的,这种编码被成为扫描码,分为Make Code,Break Code。当一个键被按下或者保持按下时,将会产生Make Code,当弹起某个键时,会产生Break Code。除了Pause键外,每一个按键对应一个Make Code和一个Break Code。

   这下明白了吧,每按一次键,会产生两次中断,一个是Make,另一次是Break。

   这下还不够好玩,让我们把从缓冲区中取得的扫描码打印一下:

Code:
  1. void Keyboard_Handler(u32 irq_no)   
  2. {   
  3.      Disp_Int(In_Byte(0x60));    
  4.     /* Disp_Color_Str("*",0xc); */  
  5. }  

   运行看看,输入a和9看看,结果如图所示:

   分别是a的Make Code,Break Code,9的Make Code。下次再来讨论这些乱七八糟的码吧。

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值