我们将程序改善一下,让程序在按下一个键后不结束,而是把所按键的编码在画面上显示出来,这样就可以切实完成中断处理程序了。
所谓中断处理,基本上就是打断CPU本来的工作,加塞要求进行处理。而且处理中断期间不再接收别的中断。所以如果处理键盘的中断速度太慢,就会出现鼠标动作不连贯,不能从网上接收数据等情况。
考虑到键盘输入时需要缓冲区,我们定义了一个结构体:
struct KEYBUF {
unsigned char data, flag;
};
其中flag是用来判断缓冲区是否为空的。0既是空,1则有数据。
当按下键盘的右Ctrl键时,会产生两个字节的键码值“E0 1D",而松开这个键之后会产生两个字节的键码值“E0 9D”。由于键盘内部电路一次只能发送一个字节,所以一次按键会产生两次中断。
根据CPU的规范,在STI指令之后如果紧跟HLT指令,就暂时不受理这两条指令之间的中断。而要等HLT指令之后才受理。
(这让我想起了操作系统原理讲的PV原语)
说起缓冲,这次我们需要的是FIFO型。我们先是用数组代替单个变量充当缓冲区。从缓冲区取数据先从0开始,然后将数据的存放位置全部向前移动:
当然这个还不够,接下来我们要改进先进先出(FIFO) 的存储区,改进方式采用了循环队列的思想:
不仅要维护下一个写入数据的位置,还要维护下一个要读出数据的位置。这就好像数据读出位置在追着数据写入位置跑一样。当两者追上时就相当于缓冲区为空,没有数据
当下一个数据写入位置或读入位置到达缓冲区最末尾的时候,就强行置为0,导致如下效果:
鼠标只要稍微一动,就会连续发出3个字节的数据。
IDT/PIC的初始化结束后就会解除CPU的中断禁止。
事实上,鼠标控制电路包含在键盘控制电路里,如果键盘控制电路的初始化正常完成,数表电路控制器的激活也完成了。