接着上篇的问题,既然是按下insert等键的问题,那我们就来打印一下这些键产生的扫描码看看。
一看吓一跳,发现了一个现象与书中的不同,就是Insert键,Home键,Page Up键 Page Down键,End键,Delete键以及四个箭头的方向键的Make Code和Break Code和书上说的有点区别,它们的Make Code,Break Code分别为:
Insert:
Home:
Page Up:
Page_Down:
End:
Delete:
Up:
Down:
Left:
Right:
先来分析一下出错的原因,看下列代码:
- 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;
- }
- }
- }
假设我们按下的是insert键,那么到了第8行的if为假,此时的scan_code的值为0x2a,正好是左边的shift键的Make Code的值!继续向下执行,看代码:
- 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;
- }
- }
第一行make置1, 第二行定位到了左shift键的行,此时当做是按下左shift键来处理!!慢着,此键的Break Code为0xE0,0xD2,0xE0,0xAA,其中有个0xAA是左shift键的Break Code啊,看起来可以模拟左shift键弹起而把Shift_L置0的效果,但是经过一番分析,却不能达到目的,分析就略了,很简单的。这时我们只能人工按一下左shift键,来将Shift_L置0,此时便又恢复正常,如图所示:
可以看到,上述这些键的Make Code和Break Code分别有四个扫描码,而书中却只有两个,Make Code多了前两个码:0xE0,0x2A,Break Code多了后两个码:0xE0,0xAA。这意味着我们的原来的逻辑是不准确的,我们就来添加处理这些键的代码,下面是修改过的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)
- {
- scan_code = Get_Byte_From_KB_Buffer();
- if(scan_code == 0x37) /* print screen */
- {
- key = PRINTSCREEN;
- make = 1;
- }
- else if(scan_code == 0x52) /* insert */
- {
- key = INSERT;
- make = 1;
- }
- else if(scan_code == 0x47) /* home */
- {
- key = HOME;
- make = 1;
- }
- else if(scan_code == 0x49) /* page up */
- {
- key = PAD_PAGEUP;
- make = 1;
- }
- else if(scan_code == 0x51) /* page down */
- {
- key = PAD_PAGEDOWN;
- make = 1;
- }
- else if(scan_code == 0x4f) /* end */
- {
- key = END;
- make = 1;
- }
- else if(scan_code == 0x53) /* delete */
- {
- key = DELETE;
- make = 1;
- }
- else if(scan_code == 0x48) /* up */
- {
- key = UP;
- make = 1;
- }
- else if(scan_code == 0x50) /* down */
- {
- key = DOWN;
- make = 1;
- }
- else if(scan_code == 0x4b) /* left */
- {
- key = LEFT;
- make = 1;
- }
- else if(scan_code == 0x4d) /* right */
- {
- key = RIGHT;
- make = 1;
- }
- }
- }
- else if(scan_code == 0xb7) /* print screen break */
- {
- if(Get_Byte_From_KB_Buffer() == 0xe0)
- {
- scan_code = Get_Byte_From_KB_Buffer();
- if(scan_code == 0xaa)
- {
- key = PRINTSCREEN;
- make = 0;
- }
- }
- }
- else if(scan_code == 0xd2) /* insert break */
- {
- if(Get_Byte_From_KB_Buffer() == 0xe0)
- {
- if(Get_Byte_From_KB_Buffer() == 0xaa)
- {
- key = INSERT;
- make = 0;
- }
- }
- }
- else if(scan_code == 0xc7) /* home break */
- {
- if(Get_Byte_From_KB_Buffer() == 0xe0)
- {
- if(Get_Byte_From_KB_Buffer() == 0xaa)
- {
- key = HOME;
- make = 0;
- }
- }
- }
- else if(scan_code == 0xc9) /* page up break */
- {
- if(Get_Byte_From_KB_Buffer() == 0xe0)
- {
- if(Get_Byte_From_KB_Buffer() == 0xaa)
- {
- key = PAD_PAGEUP;
- make = 0;
- }
- }
- }
- else if(scan_code == 0xd1) /* page down break */
- {
- if(Get_Byte_From_KB_Buffer() == 0xe0)
- {
- if(Get_Byte_From_KB_Buffer() == 0xaa)
- {
- key = PAD_PAGEDOWN;
- make = 0;
- }
- }
- }
- else if(scan_code == 0xcf) /* end break */
- {
- if(Get_Byte_From_KB_Buffer() == 0xe0)
- {
- if(Get_Byte_From_KB_Buffer() == 0xaa)
- {
- key = END;
- make = 0;
- }
- }
- }
- else if(scan_code == 0xd3) /* delete break */
- {
- if(Get_Byte_From_KB_Buffer() == 0xe0)
- {
- if(Get_Byte_From_KB_Buffer() == 0xaa)
- {
- key = DELETE ;
- make = 0;
- }
- }
- }
- else if(scan_code == 0xc8) /* up break */
- {
- if(Get_Byte_From_KB_Buffer() == 0xe0)
- {
- if(Get_Byte_From_KB_Buffer() == 0xaa)
- {
- key = UP;
- make = 0;
- }
- }
- }
- else if(scan_code == 0xd0) /* down break */
- {
- if(Get_Byte_From_KB_Buffer() == 0xe0)
- {
- if(Get_Byte_From_KB_Buffer() == 0xaa)
- {
- key = DOWN;
- make = 0;
- }
- }
- }
- else if(scan_code == 0xcb) /* left break */
- {
- if(Get_Byte_From_KB_Buffer() == 0xe0)
- {
- if(Get_Byte_From_KB_Buffer() == 0xaa)
- {
- key = LEFT;
- make = 0;
- }
- }
- }
- else if(scan_code == 0xcd) /* right break */
- {
- if(Get_Byte_From_KB_Buffer() == 0xe0)
- {
- if(Get_Byte_From_KB_Buffer() == 0xaa)
- {
- key = RIGHT;
- make = 0;
- }
- }
- }
- else
- {
- code_with_E0 = 1;
- }
- }
- if((key != PRINTSCREEN) && (key != PAUSEBREAK) && (key != INSERT) && (key != HOME) && (key != PAD_PAGEUP) &&
- (key != PAD_PAGEDOWN) && (key != END) && (key != DELETE) && (key != UP) && (key != DOWN) && (key != LEFT) &&
- (key != RIGHT))
- {
- 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,运行,结果正常。