【第7章】解析扫描码【四】

     下面来搞定开头为0xE0的扫描码,看看以0xE0的扫描码,几乎都是0xE0再跟着另一个码的,唯独有一个键例外,就是print screen键,我们再对这个键做单独处理:

     修改后的Keyboard_Read函数:

Code:
  1. void Keyboard_Read()   
  2. {   
  3.     u8 scan_code;   
  4.     int make;   
  5.     char disp[2];   
  6.     u32 *key_row;   
  7.     u32 key = 0;   
  8.     int col = 0;   
  9.        
  10.     Memory_Set(&disp[0],2,0);   
  11.        
  12.     if(kb_input_buffer.count > 0)   
  13.     {   
  14.         scan_code = Get_Byte_From_KB_Buffer();   
  15.            
  16.         if(scan_code == 0xe1)   
  17.         {   
  18.             int i;   
  19.             u8 pause_make_code[] = {0xe1,0x1d,0x45,0xe1,0x9d,0xc5};   
  20.             int is_pause = 1;   
  21.             for(i = 1 ; i < 6 ; i++)   
  22.             {   
  23.                 if(Get_Byte_From_KB_Buffer() != pause_make_code[i])   
  24.                 {   
  25.                     is_pause = 0;   
  26.                     break;   
  27.                 }   
  28.             }   
  29.             if(is_pause)   
  30.             {   
  31.                 key = PAUSEBREAK;   
  32.             }   
  33.         }   
  34.         else if(scan_code == 0xe0)   
  35.         {   
  36.             scan_code = Get_Byte_From_KB_Buffer();   
  37.             if(scan_code == 0x2a)   
  38.             {   
  39.                 if(Get_Byte_From_KB_Buffer() == 0xe0)   
  40.                 {   
  41.                     if(Get_Byte_From_KB_Buffer() == 0x37)   
  42.                     {   
  43.                         key = PRINTSCREEN;   
  44.                         make = 1;   
  45.                     }   
  46.                 }   
  47.             }   
  48.             else if(scan_code == 0xb7)   
  49.             {   
  50.                 if(scan_code == 0xe0)   
  51.                 {   
  52.                     if(Get_Byte_From_KB_Buffer() == 0xaa)   
  53.                     {   
  54.                         key = PRINTSCREEN;   
  55.                         make = 0;   
  56.                     }   
  57.                 }       
  58.             }   
  59.             else  
  60.             {   
  61.                 /* 处理其它以0xe0开头的双字节扫描码 */  
  62.             }     
  63.         }   
  64.         else  
  65.         {   
  66.             make = (scan_code & NR_SCAN_CODES)? 0 : 1;   
  67.             key_row = &Key_Map[(scan_code & 0x7f) * MAP_COLS];   
  68.                
  69.             if(Shift_L || Shift_R)   
  70.             {   
  71.                 col = 1;   
  72.             }   
  73.                
  74.             key = key_row[col];   
  75.                
  76.             switch(key)   
  77.             {   
  78.                 case SHIFT_L:   
  79.                     Shift_L = make;   
  80.                     key = 0;   
  81.                     break;   
  82.                 case SHIFT_R:   
  83.                     Shift_R = make;   
  84.                     key = 0;   
  85.                     break;   
  86.                 default:   
  87.                     if(!make)   
  88.                     {   
  89.                         key = 0;   
  90.                         break;   
  91.                     }   
  92.             }   
  93.         }   
  94.         if(key)   
  95.         {   
  96.             disp[0] = key;   
  97.             Disp_Color_Str(disp,0xa);   
  98.         }    
  99.     }   
  100. }  

     本来PauseBreak和PrintScreen是不可打印的,但我们为了验证结果,还是打印了,另外PrintScreen弹起的时候,也进行了打印。

     make,运行,结果如图所示,打印了一个莫名其妙的字符:

     接下来就要处理双扫描码的键了,此时要多设一个局部变量code_with_E0,来标识是否在处理0xE0开头的双字节的扫描码,在排除掉PrintScreen键和PauseBreak键之后,就可以把code_with_E0,在后面的处理中,就可以根据这个值,把col的值设为2,就可以把key赋为相对应的值。修改后的Keyboard_Read函数如下:

Code:
  1. void Keyboard_Read()   
  2. {   
  3.     u8 scan_code;   
  4.     int make;   
  5.     char disp[2];   
  6.     u32 *key_row;   
  7.     u32 key = 0;   
  8.     int col = 0;   
  9.     int code_with_E0 = 0;   
  10.        
  11.     Memory_Set(&disp[0],2,0);   
  12.        
  13.     if(kb_input_buffer.count > 0)   
  14.     {   
  15.         scan_code = Get_Byte_From_KB_Buffer();   
  16.            
  17.         if(scan_code == 0xe1)   
  18.         {   
  19.             int i;   
  20.             u8 pause_make_code[] = {0xe1,0x1d,0x45,0xe1,0x9d,0xc5};   
  21.             int is_pause = 1;   
  22.             for(i = 1 ; i < 6 ; i++)   
  23.             {   
  24.                 if(Get_Byte_From_KB_Buffer() != pause_make_code[i])   
  25.                 {   
  26.                     is_pause = 0;   
  27.                     break;   
  28.                 }   
  29.             }   
  30.             if(is_pause)   
  31.             {   
  32.                 key = PAUSEBREAK;   
  33.             }   
  34.         }   
  35.         else if(scan_code == 0xe0)   
  36.         {   
  37.             scan_code = Get_Byte_From_KB_Buffer();   
  38.             if(scan_code == 0x2a)   
  39.             {   
  40.                 if(Get_Byte_From_KB_Buffer() == 0xe0)   
  41.                 {   
  42.                     if(Get_Byte_From_KB_Buffer() == 0x37)   
  43.                     {   
  44.                         key = PRINTSCREEN;   
  45.                         make = 1;   
  46.                     }   
  47.                 }   
  48.             }   
  49.             else if(scan_code == 0xb7)   
  50.             {   
  51.                 if(Get_Byte_From_KB_Buffer() == 0xe0)   
  52.                 {   
  53.                     if(Get_Byte_From_KB_Buffer() == 0xaa)   
  54.                     {   
  55.                         key = PRINTSCREEN;   
  56.                         make = 0;   
  57.                     }   
  58.                 }   
  59.             }   
  60.             else  
  61.             {   
  62.                 code_with_E0 = 1;   
  63.             }   
  64.                
  65.         }   
  66.            
  67.         if((key != PRINTSCREEN) && (key != PAUSEBREAK))   
  68.         {   
  69.             make = (scan_code & NR_SCAN_CODES)? 0 : 1;   
  70.             key_row = &Key_Map[(scan_code & 0x7f) * MAP_COLS];   
  71.                    
  72.             if(Shift_L || Shift_R)   
  73.             {   
  74.                 col = 1;   
  75.             }   
  76.                
  77.             if(code_with_E0)   
  78.             {   
  79.                 col = 2;   
  80.             }   
  81.                    
  82.             key = key_row[col];   
  83.                    
  84.             switch(key)   
  85.             {   
  86.                 case SHIFT_L:   
  87.                     Shift_L = make;   
  88.                     key = 0;   
  89.                     break;   
  90.                 case SHIFT_R:   
  91.                     Shift_R = make;   
  92.                     key = 0;   
  93.                     break;   
  94.                 default:   
  95.                     if(!make)   
  96.                     {   
  97.                         key = 0;   
  98.                         break;   
  99.                     }   
  100.             }   
  101.         }   
  102.            
  103.         if(key)   
  104.         {   
  105.             disp[0] = key;   
  106.             Disp_Color_Str(disp,0xa);   
  107.         }    
  108.     }   
  109. }  

     make,运行,这里我发现一个奇怪的现象,如果按下了insert和delete等键后,再按下字母键或数字键后,打印的却是shift+这些键后的东东,如图所示:

     这是怎么一回事呢?下回再说。

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值