上QQ阅读APP看书,第一时间看更新
7 从鼠标接受数据(harib04g)
既然中断已经来了,现在就让我们取出中断数据吧。前面已经说过,鼠标和键盘的原理几乎相同,所以程序也就非常相似。
int.c节选
struct FIFO8 mousefifo; void inthandler2c(int *esp) /* 来自PS/2鼠标的中断 */ { unsigned char data; io_out8(PIC1_OCW2, 0x64); /* 通知PIC1 IRQ-12的受理已经完成 */ io_out8(PIC0_OCW2, 0x62); /* 通知PIC0 IRQ-02的受理已经完成 */ data = io_in8(PORT_KEYDAT); fifo8_put(&mousefifo, data); return; }
不同之处只有送给PIC的中断受理通知。IRQ-12是从PIC的第4号(从PIC相当于IRQ-08~IRQ-15),首先要通知IRQ-12受理已完成,然后再通知主PIC。这是因为主/从PIC的协调不能够自动完成,如果程序不教给主PIC该怎么做,它就会忽视从PIC的下一个中断请求。从PIC连接到主PIC的第2号上,这么做OK。
■■■■■
下面的鼠标数据取得方法,居然与键盘完全相同。这不是笔者的失误,而是事实。也许是因为键盘控制电路中含有鼠标控制电路,才造成了这种结果。至于传到这个设备的数据,究竟是来自键盘还是鼠标,要靠中断号码来区分。
取得数据的程序如下所示:
bootpack.c节选
fifo8_init(&mousefifo, 128, mousebuf); for (; ; ) { io_cli(); if (fifo8_status(&keyfifo) + fifo8_status(&mousefifo) == 0) { io_stihlt(); } else { if (fifo8_status(&keyfifo) ! = 0) { i = fifo8_get(&keyfifo); io_sti(); sprintf(s, "%02X", i); boxfill8(binfo->vram, binfo->scrnx, COL8_008484, 0, 16, 15, 31); putfonts8_asc(binfo->vram, binfo->scrnx, 0, 16, COL8_FFFFFF, s); } else if (fifo8_status(&mousefifo) ! = 0) { i = fifo8_get(&mousefifo); io_sti(); sprintf(s, "%02X", i); boxfill8(binfo->vram, binfo->scrnx, COL8_008484, 32, 16, 47, 31); putfonts8_asc(binfo->vram, binfo->scrnx, 32, 16, COL8_FFFFFF, s); } } }
因为鼠标往往会比键盘更快地送出大量数据,所以我们将它的FIFO缓冲区增加到了128字节。这样,就算是一下子来了很多数据,也不会溢出。
取得数据的程序中,如果键盘和鼠标的FIFO缓冲区都为空了,就执行HLT。如果不是两者都空,就先检查keyinfo,如果有数据,就取出一个显示出来。如果keyinfo是空,就再去检查mouseinfo,如果有数据,就取出一个显示出来。很简单吧。
到底能不能执行呢?好紧张呀。我们来测试一下。运行“make run”。
就像上面那样,最初只显示鼠标发送过来的数据,且内容的确是FA。
随便滚动鼠标一下,就会像下面这样显示出各种各样的数据来。
如果按下键盘,当然会像以前一样,正常响应。
看,运行得很正常很不错呀。
好了,今天我们做的事已经不少了,就先到这吧。明天我们来解读鼠标数据,让鼠标指针在屏幕上动起来。真期待呀。啊,今天就不要再往下读了哦。先睡觉,明天再继续,好吧?