终于要让键盘和鼠标使用起来了,前期工作都完成了,这一步其实是非常容易的。
一、键盘中断和处理
当键盘中的一个按钮被按下或抬起时,将通过8259A芯片向CPU发送一个键盘中断的消息,这时CPU将转入键盘中断处理程序。键盘上的每个按键都对应一个扫描码,当有键盘中断时,这个扫描码被送入0x60端口。CPU通过读取0x60端口中的扫描码就可以得知是键盘中的哪个键盘被按下或抬起了。
在system文件夹下新建一个keyboard文件夹,然后新建keyboard.c和keyboard.h
打开functions.s,要新建一个键盘的中断处理函数,不要忘记.global一下,因为我们还要在main.c中使用它的地址。
KeyboardIntCallBack:
cli
pushal
pushfl
//调用键盘中断处理函数
call IntKeyboard
popfl
popal
sti
iret
回到main.c,声明这个函数 extern void KeyboardIntCallBack(void);
修改如下内容:
for (i=1;i<0x30;i++)
{
idt[i].offset1 = (short)((int)(void*)(DefaultIntCallBack));
idt[i].selector = 0x0008;
idt[i].no_use = 0x8e00;
idt[i].offset2 = (short)(((int)(void*)(DefaultIntCallBack))>>16);
}//增加下边的四行
idt[0x21].offset1 = (short)((int)(void*)(KeyboardIntCallBack));
idt[0x21].selector = 0x0008;
idt[0x21].no_use = 0x8e00;
idt[0x21].offset2 = (short)(((int)(void*)(KeyboardIntCallBack))>>16);
简单解释一下,int 21是我们的键盘中断,可以在第五讲中分析出来,所以我们要特别设置int 21的回调函数为KeyboardIntCallBack,这个函数在汇编function.s中,调用这个函数后,KeyboardIntCallBack对中断进行处理,然后调用keyboard.c中的IntKeyboard处理函数进行处理。
我们先把keyboard.c加到Makefile中,Makefile添加下边一句话
keyboard.o : keyboard/keyboard.c Makefile
gcc -c keyboard/keyboard.c -o $(OBJ_DIR)/keyboard.o -m32
然后修改链接ld为如下:
system.bin : system.o Makefile system.lds main.o functions.o font.o font_code.o cursor.o keyboard.o
ld -m elf_i386 -o $(BIN_DIR)/system.elf \
$(OBJ_DIR)/system.o $(OBJ_DIR)/functions.o $(OBJ_DIR)/main.o \
$(OBJ_DIR)/font.o $(OBJ_DIR)/font_code.o \
$(OBJ_DIR)/cursor.o $(OBJ_DIR)/keyboard.o \
-T system.lds
搞定,开始编写keyboard.c
按键的输入码并不是ASCII码,而是一种特殊的编码,如下给出:
#define KEY_ESC 0X01 // ESC
#define KEY_1 0X02 // 1
#define KEY_2 0X03 // 2
#define KEY_3 0X04 // 3
#define KEY_4 0X05 // 4
#define KEY_5 0X06 // 5
#define KEY_6 0X07 // 6
#define KEY_7 0X08 // 7
#define KEY_8 0X09 // 8
#define KEY_9 0X0A // 9
#define KEY_0 0X0B // 0
#define KEY_DASH 0X0C // -
#define KEY_EQUAL 0X0D // =
#define KEY_BACKSPACE 0X0E // BACKSPACE
#define KEY_TAB 0X0F // TAB
#define KEY_Q 0X10 // Q
#define KEY_W 0X11 // W
#define KEY_E 0X12 // E
#define KEY_R 0X13 // R
#define KEY_T 0X14 // T
#define KEY_Y 0X15 // Y
#define KEY_U 0X16 // U
#define KEY_I 0X17 // I
#define KEY_O 0X18 // O
#define KEY_P 0X19 // P
#define KEY_LBRACKET 0X1A // [
#define KEY_RBRACKET 0X1B // ]
#define KEY_ENTER 0X1C // ENTER
#define KEY_CTRL 0X1D // CTRL
#define KEY_A 0X1E // A
#define KEY_S 0X1F // S
#define KEY_D 0X20 // D
#define KEY_F 0X21 // F
#define KEY_G 0X22 // G
#define KEY_H 0X23 // H
#define KEY_J 0X24 // J
#define KEY_K 0X25 // K
#define KEY_L 0X26 // L
#define KEY_SEMICOLON 0X27 // ;
#define KEY_RQUOTE 0X28 // '
#define KEY_LQUOTE 0X29 // `
#define KEY_LEFT_SHIFT 0X2A // LEFT SHIFT
#define KEY_BACKSLASH 0X2B // '\'
#define KEY_Z 0X2C // Z
#define KEY_X 0X2D // X
#define KEY_C 0X2E // C
#define KEY_V 0X2F // V
#define KEY_B 0X30 // B
#define KEY_N 0X31 // N
#define KEY_M 0X32 // M
#define KEY_COMMA 0X33 // ,
#define KEY_PERIOD 0X34 // .
#define KEY_SLASH 0X35 // /
#define KEY_RIGHT_SHIFT 0X36 // RIGHT SHIFT
#define KEY_PRTSC 0X37 // PRINT SCREEN
#define KEY_ALT 0X38 // ALT
#define KEY_SPACE 0X39 // SPACE
#define KEY_CAPS_LOCK 0X3A // CAPS LOCK
#define KEY_F1 0X3B // F1
#define KEY_F2 0X3C // F2
#define KEY_F3 0X3D // F3
#define KEY_F4 0X3E // F4
#define KEY_F5 0X3F // F5
#define KEY_F6 0X40 // F6
#define KEY_F7 0X41 // F7
#define KEY_F8 0X42 // F8
#define KEY_F9 0X43 // F9
#define KEY_F10 0X44 // F10
#define KEY_NUM_LOCK 0X45 // NUM LOCK
#define KEY_SCROLL_LOCK 0X46 // SCROLL LOCK
#define KEY_HOME 0X47 // HOME
#define KEY_UP 0X48 // UP
#define KEY_PAGE_UP 0X49 // PAGE UP
#define KEY_SUB 0X4A // SUB
#define KEY_LEFT 0X4B // LEFT
#define KEY_CENTER 0X4C // CENTER
#define KEY_RIGHT 0X4D // RIGHT
#define KEY_ADD 0X4E // ADD
#define KEY_