4.8.1读取键盘数据和命令端口
PS/2键盘的数据端口是0x60,直接读取这个端口就能取到数据.但是前提是,键盘必须处于可读状态.
在驱动中没有对端口的读取进行限制,直接汇编指令就可以读取.请注意每次只能读取1字节.
//定义1字节P2C_U8 sch;__asm in all,0x60__asm mov sch,al
上面的代码把端口0x60的值读入到变量sch中.如何确定键盘可读呢?答案是读取键盘的命令端口.如果读出的值没有OBUFFER_FULL标记,则说明可以读取.
下面的代码可以等待到键盘有数据可读.
#define OBUFFER_FULL 0x02#define IBUFFER_FULL 0x01ULONG p2cWaitForKbRead(){int i = 100;P2C_U8 mychar;do{__asm in al,0x64__asm mov mychar,alKeStallExecutionProcessor(50);if(!(mychar)&OBUFFER_FULL)break;}while(i--);if(i)return TRUE;return FALSE;}
同样,键盘也并不是随时可以写入数据的.下面的代码可以等待到键盘可写.
ULONG p2cWaitForKbWrite(){int i = 100;P2C_U8 mychar;do{__asm in al,0x64__asm mov mychar,alKeStallExecutionProcessor(50);if(!(mychar&IBUFFER_FULL))break;}while(i--);if(i)return TRUE;return FALSE;}
4.8.2 p2cUserFilter的最终实现
本节的目标是实现从键盘的数据端口读出扫描码打印出来.但是这有一个问题.一旦扫描码读出那么键盘的数据端口里可就没有这个值了.即使调用了旧的中断处理函数,中断处理中读不出数据,那就等于没有按键了.
处理的办法是读出数据后,再把这个数据写回键盘.但是写回键盘会再次引起中断,这就导致再次进入中断处理函数,引起死循环.
下面的代码使用一个静态变量,记住前一回的值,如果是这个值,则跳过处理.所以最终代码实现如下:
//首先读端口获得按键扫描码并打印出来.然后将这个扫描码写回端口以便其它应用程序能正确接收到按键//如果不想让其它的程序截获按建,可以写回一个任意的数据//0x60端口是数据端口,可以读出键盘数据,0x64是控制端口,用来发出控制信号void p2cUserFilter(){static P2C_U8 sch_pre = 0;P2C_U8 sch;p2cWaitForKbRead();//我的想法:这里怎么不进行push eax__asm in al,0x60__asm mov al,0x60DbgPrint("扫描码:%2x\n",sch);//把数据写回端口if(sch_pre != sch){sch_pre = sch;__asm mov al,0xd2__asm out 0x64,alp2cWaitForKbWrite();__asm mov al,sch__asm out 0x60,al}}
我按照作者的方法,测试发现,打印出来的的基本都是0,从网上查资料,说返回0,就是读取出错.没搞明白,书上的截图也是一大堆0
本文详细介绍了PS/2键盘的数据端口读取、命令端口判断可读性以及等待数据可读性的实现方法,包括使用汇编指令进行操作,并通过代码示例解释了如何确保键盘在数据端口读取和写入时的状态。
1542

被折叠的 条评论
为什么被折叠?



