haribote keyboard.c 键盘管理程序阅读注释

[ 1] haribote ipl09.nas    引导程序阅读注释
[ 2] haribote asmhead.nas  从实模式进入保护模式程序阅读注释
[ 3] haribote dsctbl.c     设置GDT和IDT程序阅读注释
[ 4] haribote memory.c     内存管理程序阅读注释
[ 5] haribote int.c        可编程中断控制器(PIC)初始配置程序阅读注释
[ 6] haribote timer.c      定时器管理程序阅读注释
[ 7] haribote fifo.c       循环队列管理程序阅读注释

[8] haribote keyboard.c 键盘管理程序阅读注释
keyboard.c
/* keyboard.c, 键盘管理程序接口 */

#include "bootpack.h"

/* 键盘缓冲队列全局指针,键盘缓冲队列数据的基数/标识
 * (键盘数据加上 keydata0 后发往键盘缓冲队列中)。*/
struct FIFO32 *keyfifo;
int keydata0;

/* inthandler21,
 * 键盘中断C处理函数,读取键盘输入到键盘缓冲队列中。
 * 
 * 当有键盘输入而向PIC输出中断时,
 * CPU处理PIC申请的键盘中断时会执行IDT[21h]中的入口处
 * 理程序 _asm_inthandler21 (见int.c和dsctbl.c), 该处
 * 理函数会调用此处的C处理函数 inthandler21.*/
void inthandler21(int *esp)
{
    int data;

    /* 发送EOI命令结束键盘中断 */
    io_out8(PIC0_OCW2, 0x61);
    /* 读键盘输入扫描码 data,并将其加上键盘数
     * 据基数发送到键盘队列中, 供其他任务读取。*/
    data = io_in8(PORT_KEYDAT);
    fifo32_put(keyfifo, data + keydata0);
    return;
}

/* PORT_KEYSTA,键盘控制器8042状态寄存器端口;
 * KEYSTA_SEND_NOTREADY,8042状态控制器输入缓冲器满的标志;
 * KEYCMD_WRITE_MODE,写入键盘控制命令字节的命令,具体的命令字节随后从60h端口写入;
 *
 * KBC_MODE, KEYCMD_WRITE_MODE的参数即具体的命令字节: 
 * 键盘以PC兼容方式运作,使用鼠和标键盘以及鼠标和键盘中断,
 * 未完成当前键盘数据时不接收下一个键盘数据等 */
#define PORT_KEYSTA          0x0064
#define KEYSTA_SEND_NOTREADY 0x02
#define KEYCMD_WRITE_MODE    0x60
#define KBC_MODE             0x47


/* wait_KBC_sendready,
 * 等待键盘控制器8042输入缓冲器寄存器空。*/
void wait_KBC_sendready(void)
{
    /* 8042状态控制器bit[1]=0时表示其输入缓冲寄存器为空即已可接受输入 */
    for (;;) {
        if ((io_in8(PORT_KEYSTA) & KEYSTA_SEND_NOTREADY) == 0) {
            break;
        }
    }
    return;
}

/* init_keyboard,
 * 初始化键盘控制器并设置键盘缓冲队列fifo及其数据标识data0。
 * 
 * 设置键盘控制器8042运作方式:键盘以PC兼容方式运作,在未完成
 * 当前键盘数据的接收时不接收下一个键盘输入。*/
void init_keyboard(struct FIFO32 *fifo, int data0)
{
    /* 设置键盘换成队列和键盘队列数据标识 */
    keyfifo = fifo;
    keydata0 = data0;

    /* 设置键盘运作模式,粗略含义见宏处注释 */
    wait_KBC_sendready();
    io_out8(PORT_KEYCMD, KEYCMD_WRITE_MODE);
    wait_KBC_sendready();
    io_out8(PORT_KEYDAT, KBC_MODE);
    return;
}
bootpack.h
/* ... */

/* keyboard.c */
void inthandler21(int *esp);
void wait_KBC_sendready(void);
void init_keyboard(struct FIFO32 *fifo, int data0);
/* 8042 端口地址,
 * in  al, 60h, 读8042输出缓冲寄存器内容到al;
 * in  al, 64h, 读8042状态寄存器内容到al;
 * out 60h, al, 写数据al到8042输入缓冲寄存器;
 * out 64h, al, 写命令al到8042输入缓冲寄存器. */
#define PORT_KEYDAT 0x0060
#define PORT_KEYCMD 0x0064

/* ... */
  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

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

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值