FIFO与鼠标控制
1. 获取按键编码
实现功能:让程序在按一个键后不结束,然后在屏幕上显示出信息。这样就可以切实完成中断处理程序了。
修改int.c程序中的inthandler21函数:
#define PORT_KEYDAT 0x0060
void inthandler21(int *esp)
/*来自PS/2键盘的中断*/
{
struct BOOTINFO *binfo = (struct BOOTINFO *) ADR_BOOTINFO;
unsigned char data, s[4];
io_out8(PIC0_OCW2, 0x61); /*通知PIC*IRQ-01已经受理完毕*/
data = io_in8(PORT_KEYDAT);
sprintf(s, "%02X", data);
boxfill8(binfo->vram, binfo->scrnx, COL8_008484, 0, 16, 15, 31);
putfonts8_asc(binfo->vram, binfo->scrnx, 0, 16, COL8_FFFFFF, s);
return;
}
io_out8(PIC0_OCW2, 0x61); 这句话用来通知PIC“已经知道发生了IRQ1中断。如果是IRQ3,则写成0x63.也就是说,将”0x60+IRQ号码”输出给OCW2就可以。执行这句话之后,PIC继续时刻监视IRQ1中断是否发生。反过来,如果忘记了执行这句话,PIC就不在监视IRQ1中断,不管下次由键盘输入什么信息,系统都感知不到了。
详情参阅:http://community.osdev,info/?(PIC)8259A
从编号为0x0060的设备输入的8位信息是按键编码。编号为0x0060的设备就是键盘。
2. 加快中断处理
实现功能:将处理字符显示内容的功能从中断处理中提出来,将按键编码接收下来保存到变量中,然后由HariMain偶尔去查看这个变量。发现有数据就显示出来。
原因:中断处理是打断CPU本来的工作,加塞要求进行处理。在处理进行期间不再接受别的中断。若中断处理速度太慢会影响CPU的的工作。
Int.c节选:
struct KEYBUF {
unsigned char data, flag;
};
#define PORT_KEYDAT 0x0060
struct KEYBUF keybuf;
void inthandler21(int *esp)
/*来自PS/2键盘的中断*/
{
unsigned char data;
io_out8(PIC0_OCW2, 0x61); /*通知PIC*IRQ-01已经受理完毕*/
data = io_in8(PORT_KEYDAT);
if (keybuf.flag == 0)
{
keybuf.data = data;
keybuf.flag = 1;
}
return;
}
在函数中用到了两个变量:data和flag,所以可以建一个结构体把两个变量集中起来。
将bootpack.c中MariMain函数中的io_halt()函数更改如下:
for(;;) {
io_cli();
if (keybuf.flag == 0)
{
io_stihlt();
} else {
i = keybuf.data;
keybuf.flag = 0;
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);
}
}
即将最初的inthandler21()函数拆解成了inthandler21()和for循环函数。
开始先用io_cli指令屏蔽中断(是为了防止被另外的指令中断),然后去看一看keybuf.flag的值是什么。
如果flag是0说明键还没有按下,就去执行io_