30天自制操作系统开发笔记——响应鼠标和键盘(上)
设置好鼠标和键盘对应的中断之后,这时候操作系统已经对键盘有了反应,只是我们看不到而已,为了能看到按下键盘上按键的编码,需要利用缓冲区接收键盘传过来的数据,并在自己的操作系统上显示出来。首先我们定义一个缓冲区才接收键盘传过来的内容:
char keybuf[32],每次按键最多会传过来两个字节的内容,开到32为CPU留下一定的响应时间足够了。
然后定义一个缓冲区的结构体,其缓冲区地址的指针赋值为keybuf
fifo8_init(&keyfifo,32,keybuf);
然后我们在主函数中要一直检测缓冲区中是否有数据到来,有就输出到画面上:
for(;;)
{
io_cli();
if(fifo8_status(&keyfifo)==0)
{
io_stihlt();
}
else
{
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);/*在坐标0,16位置上显示字符串s,这些函数都需要自己制作,利用书中提供的字体*/
}
}
对于鼠标,在数据处理的部分和键盘很类似,但是,因为鼠标的电路是在键盘电路里的,所以需要激活鼠标电路,鼠标的动作才能变成数据发给系统。激活鼠标之前,先要初始化键盘电路才可以,所以,先初始化键盘电路:
#define PORT_KEYDAT 0x0060
#define PORT_KEYSTA 0x0064
#define PORT_KEYCMD 0x0064
#define KEYSAT_SEND_NOTREADY 0x02
#define KEYCMD_WRITE_MODE 0x60
#define KBC_MODE 0x47
void wait_KBC_sendready(void)/*等待键盘电路准备好*/
{
for(;;)
{
if((io_in8(PORT_KEYSTA)&KEYSAT_SEND_NOTREADY)==0)/*io_in8()是利用汇编编写的in指令函数,io_out()类似*/
break;
}
return;
}
void init_keyboard(void)/*初始化键盘,向键盘电路发送命令*/
{
wait_KBC_sendready();
io_out8(PORT_KEYCMD,KEYCMD_WRITE_MODE);
wait_KBC_sendready();
io_out8(PORT_KEYDAT,KBC_MODE);
return;
}
初始化键盘电路完成之后,就要激活鼠标了,激活鼠标,就要先告诉键盘电路接下来的数据是要发送给鼠标电路的,所以还要向键盘电路发送一个消息:
#define KEYCMD_SENDTO_MOUSE 0xd4
#define MOUSECMD_ENABLE 0xf4
void enable_mouse()/*激活鼠标*/
{
wait_KBC_sendready();
io_out8(PORT_KEYCMD,KEYCMD_SENDTO_MOUSE);/*向键盘电路发送激活鼠标电路的消息*/
wait_KBC_sendready();
io_out8(PORT_KEYDAT,MOUSECMD_ENABLE);
return;
}