我已经规范了系统代码风格,类似于按照linux分包,把各部分功能区分开了
console的图形化实现与规则均在main/bootpack.c中完成
interrupt/int.c 中实现了键盘中断处理,按键会中断两次,一次按下,一次弹起,在响应处理中,只需要处理第一次按下即可。
一 . 键盘按键
如何来判断中断来自于键盘?(代码如下)
// gdt初始化操作... // fifo加载操作... if (fifo8_status(&keyfifo) != 0) { // True则说明中断来自于键盘 i = fifo8_get(&keyfifo); io_sti(); // i 就是中断返回的值,分析他即可得到按键信息, 在下面我把它转换为了16进制存储在了一个char array s中 sprintf(s, "%02X", i); // 把两次中断变为一次,看下文 }得到了s,就是得到了键盘按键的信息。
开头说了,按下一次,会有两次中断发生,那么我们是否可以使用一个flag来区分按下和弹起呢?
if (flag){ keyshow(); // 显示这次按键,把按下的中断当作一个键位的信息,把弹起的中断用下面flag的方法屏蔽掉 } // 屏蔽 if(flag==1){ flag = 0 ; }else { flag = 1 ; }这是一个很拙略的实现方法,而且我测试了几次之后发现有一个bug,就是同时按下两个键位时,屏蔽的方法就会变成另一种。
比如开始是用按下识别一个键位,那么同时按下两个键位之后就是以弹起的方法来识别键位了。
这个情况留在之后再考虑。
二 . 按键识别
上文中已经将按键返回的数据存储到了char数组s,只需要在屏幕上显示s的数据就可以了。
int write_x = 55 ; //按键显示位置的x,y坐标 int write_y = 57 ; void key(struct BOOTINFO *binfo,char s[40]){ //在指定位置显示数据 showkeys(binfo->vram, binfo->scrnx, write_x, write_y, COL8_FFFFFF, s); // 显示之后光标右移 write_x += 19 ; // 如果超出右边界,换行 if(write_x>155){ write_x = 55 ; write_y += 19 ; } // 如果超出下边界,刷新清理本页,开启新的一页 if(write_y>180){ new_pe(binfo); } }结果:
// gdt初始化操作... // fifo加载操作... if (fifo8_status(&keyfifo) != 0) { // True则说明中断来自于键盘 i = fifo8_get(&keyfifo); io_sti(); // i 就是中断返回的值,分析他即可得到按键信息, 在下面我把它转换为了16进制存储在了一个char array s中 sprintf(s, "%02X", i); // 把两次中断变为一次,看下文 } if (flag){ keyshow(); // 显示这次按键,把按下的中断当作一个键位的信息,把弹起的中断用下面flag的方法屏蔽掉 } // 屏蔽 if(flag==1){ flag = 0 ; }else { flag = 1 ; }int write_x = 55 ; //按键显示位置的x,y坐标 int write_y = 57 ; void key(struct BOOTINFO *binfo,char s[40]){ //在指定位置显示数据 showkeys(binfo->vram, binfo->scrnx, write_x, write_y, COL8_FFFFFF, s); // 显示之后光标右移 write_x += 19 ; // 如果超出右边界,换行 if(write_x>155){ write_x = 55 ; write_y += 19 ; } // 如果超出下边界,刷新清理本页,开启新的一页 if(write_y>180){ new_pe(binfo); } }
很明显,我们需要编写一种转换机制,将表示16进制的数据对应成为键盘按键。
键盘上需要显示的有字母和特殊符号,还有一些功能性的按键shift,backspace等。
测试记录了几个按键的按下数据
键盘 按下
F1 3B
F2 3C
F3 3D
F4 3E
A 1E
B 30
Backspace OE
空格 39
既然已经知道了对应关系,那么很容易就可以建立一种对应。
先来实现这几个特殊按键功能
我打算将 F1 实现为 clear 功能,实现页面刷新 。 Backspace 实现回退功能。Enter实现确定以及回车功能。
void showkey(struct BOOTINFO *binfo,char s[40]){ // 回车键 if(strcmp(s,"1C")==0){ write_x = 55 ; // 光标移动至下一行起始位置。<
