第四章5 直接用端口操作键盘

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 0x01
ULONG p2cWaitForKbRead()
{
int i = 100;
P2C_U8 mychar;
do
{
__asm in al,0x64
__asm mov mychar,al
KeStallExecutionProcessor(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,al
KeStallExecutionProcessor(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,0x60
DbgPrint("扫描码:%2x\n",sch);
//把数据写回端口
if(sch_pre != sch)
{
sch_pre = sch;
__asm mov al,0xd2
__asm out 0x64,al
p2cWaitForKbWrite();
__asm mov al,sch
__asm out 0x60,al
}
}


我按照作者的方法,测试发现,打印出来的的基本都是0,从网上查资料,说返回0,就是读取出错.没搞明白,书上的截图也是一大堆0
















  • 0
    点赞
  • 3
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值