os-xv6分析-设备管理-kbd.c 代码分析

os-xv6分析-设备管理-kbd.c 代码分析

// kbd.c 此文件定义了键盘中断处理函数kbdintr()和读取键值的
//kbdgetc()函数,工作与默认模式下,无单独的初始化函数
// 导包
#include "types.h"
#include "x86.h"
#include "defs.h"
#include "kbd.h"

int
kbdgetc(void) // 键盘中断处理函数,读取的按键扫描码保存在data中,Shitf
//和Ctrl等按键状态保存在shift静态变量中并根据情况做不同处理
{
  static uint shift;
  static uchar *charcode[4] = {  // 4种转换用的码表
    normalmap, shiftmap, ctlmap, ctlmap
  };
  uint st, data, c;

  st = inb(KBSTATP); // 读入端口,0x64,状态字
  if((st & KBS_DIB) == 0) // IBF标志为0,表示无扫描码
    return -1;
  data = inb(KBDATAP); // 读入数据,0x60端口,
 
  if(data == 0xE0){  // 接受到EO开始的双字节扫描码
    shift |= E0ESC;  // 只需标记EOESC
    return 0;  //无法指定按键动作,需等待下一个扫描码 
  } else if(data & 0x80){  // 最高位为1,是释放按键的break码
    // Key released // 无需返回ASCII码,但需要记录Shift相关按键状态
    data = (shift & E0ESC ? data : data & 0x7F); // 上次是否为EOESC而不同
    shift &= ~(shiftcode[data] | E0ESC); // 清楚Shift/Ctrl/Alt和E0状态
    return 0;
  } else if(shift & E0ESC){ // 上一个字节为EOESC
    // Last character was an E0 escape; or with 0x80
    data |= 0x80;
    shift &= ~E0ESC; // 清楚EOESC位
  }

  shift |= shiftcode[data]; // 记录Shift/Ctrl/Alt键状态
  shift ^= togglecode[data]; // toggle按键状态反转(异或操作)
  c = charcode[shift & (CTL | SHIFT)][data]; // 确定用哪个表,并完成转换
  if(shift & CAPSLOCK){
    if('a' <= c && c <= 'z')  // 小写->大写
      c += 'A' - 'a';  
    else if('A' <= c && c <= 'Z') // 大写->小写
      c += 'a' - 'A';
  }
  return c;
}

void
kbdintr(void) //读取按键值
{
  consoleintr(kbdgetc); //调用consoleintr()将按键的ASCII码写入//input.buf[],consoleintr函数是和串口共用的,因//此,将kbdgetc()函数指针作为参数传入。
}
  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值