下面来搞定开头为0xE0的扫描码,看看以0xE0的扫描码,几乎都是0xE0再跟着另一个码的,唯独有一个键例外,就是print screen键,我们再对这个键做单独处理:
修改后的Keyboard_Read函数:
- void Keyboard_Read()
- {
- u8 scan_code;
- int make;
- char disp[2];
- u32 *key_row;
- u32 key = 0;
- int col = 0;
- Memory_Set(&disp[0],2,0);
- if(kb_input_buffer.count > 0)
- {
- scan_code = Get_Byte_From_KB_Buffer();
- if(scan_code == 0xe1)
- {
- int i;
- u8 pause_make_code[] = {0xe1,0x1d,0x45,0xe1,0x9d,0xc5};
- int is_pause = 1;
- for(i = 1 ; i < 6 ; i++)
- {
- if(Get_Byte_From_KB_Buffer() != pause_make_code[i])
- {
- is_pause = 0;
- break;
- }
- }
- if(is_pause)
- {
- key = PAUSEBREAK;
- }
- }
- else if(scan_code == 0xe0)
- {
- scan_code = Get_Byte_From_KB_Buffer();
- if(scan_code == 0x2a)
- {
- if(Get_Byte_From_KB_Buffer() == 0xe0)
- {
- if(Get_Byte_From_KB_Buffer() == 0x37)
- {
- key = PRINTSCREEN;
- make = 1;
- }
- }
- }
- else if(scan_code == 0xb7)
- {
- if(scan_code == 0xe0)
- {
- if(Get_Byte_From_KB_Buffer() == 0xaa)
- {
- key = PRINTSCREEN;
- make = 0;
- }
- }
- }
- else
- {
- /* 处理其它以0xe0开头的双字节扫描码 */
- }
- }
- else
- {
- make = (scan_code & NR_SCAN_CODES)? 0 : 1;
- key_row = &Key_Map[(scan_code & 0x7f) * MAP_COLS];
- if(Shift_L || Shift_R)
- {
- col = 1;
- }
- key = key_row[col];
- switch(key)
- {
- case SHIFT_L:
- Shift_L = make;
- key = 0;
- break;
- case SHIFT_R:
- Shift_R = make;
- key = 0;
- break;
- default:
- if(!make)
- {
- key = 0;
- break;
- }
- }
- }
- if(key)
- {
- disp[0] = key;
- Disp_Color_Str(disp,0xa);
- }
- }
- }
本来PauseBreak和PrintScreen是不可打印的,但我们为了验证结果,还是打印了,另外PrintScreen弹起的时候,也进行了打印。
make,运行,结果如图所示,打印了一个莫名其妙的字符:
接下来就要处理双扫描码的键了,此时要多设一个局部变量code_with_E0,来标识是否在处理0xE0开头的双字节的扫描码,在排除掉PrintScreen键和PauseBreak键之后,就可以把code_with_E0,在后面的处理中,就可以根据这个值,把col的值设为2,就可以把key赋为相对应的值。修改后的Keyboard_Read函数如下:
- void Keyboard_Read()
- {
- u8 scan_code;
- int make;
- char disp[2];
- u32 *key_row;
- u32 key = 0;
- int col = 0;
- int code_with_E0 = 0;
- Memory_Set(&disp[0],2,0);
- if(kb_input_buffer.count > 0)
- {
- scan_code = Get_Byte_From_KB_Buffer();
- if(scan_code == 0xe1)
- {
- int i;
- u8 pause_make_code[] = {0xe1,0x1d,0x45,0xe1,0x9d,0xc5};
- int is_pause = 1;
- for(i = 1 ; i < 6 ; i++)
- {
- if(Get_Byte_From_KB_Buffer() != pause_make_code[i])
- {
- is_pause = 0;
- break;
- }
- }
- if(is_pause)
- {
- key = PAUSEBREAK;
- }
- }
- else if(scan_code == 0xe0)
- {
- scan_code = Get_Byte_From_KB_Buffer();
- if(scan_code == 0x2a)
- {
- if(Get_Byte_From_KB_Buffer() == 0xe0)
- {
- if(Get_Byte_From_KB_Buffer() == 0x37)
- {
- key = PRINTSCREEN;
- make = 1;
- }
- }
- }
- else if(scan_code == 0xb7)
- {
- if(Get_Byte_From_KB_Buffer() == 0xe0)
- {
- if(Get_Byte_From_KB_Buffer() == 0xaa)
- {
- key = PRINTSCREEN;
- make = 0;
- }
- }
- }
- else
- {
- code_with_E0 = 1;
- }
- }
- if((key != PRINTSCREEN) && (key != PAUSEBREAK))
- {
- make = (scan_code & NR_SCAN_CODES)? 0 : 1;
- key_row = &Key_Map[(scan_code & 0x7f) * MAP_COLS];
- if(Shift_L || Shift_R)
- {
- col = 1;
- }
- if(code_with_E0)
- {
- col = 2;
- }
- key = key_row[col];
- switch(key)
- {
- case SHIFT_L:
- Shift_L = make;
- key = 0;
- break;
- case SHIFT_R:
- Shift_R = make;
- key = 0;
- break;
- default:
- if(!make)
- {
- key = 0;
- break;
- }
- }
- }
- if(key)
- {
- disp[0] = key;
- Disp_Color_Str(disp,0xa);
- }
- }
- }
make,运行,这里我发现一个奇怪的现象,如果按下了insert和delete等键后,再按下字母键或数字键后,打印的却是shift+这些键后的东东,如图所示:
这是怎么一回事呢?下回再说。