开启鼠标中断

设置中断描述符表

for(i = 0; i < 256; i++){
    set_gatedesc(idt + i, 0, 0, 0);
}
load_idtr(0x7ff, 0x0026f800);
//键盘中断号是0x21
// set_gatedesc(idt + 0x21, (int)asm_inthandler21, 2 * 8, AR_INTGATE32);
// 鼠标中断号是0x2c
set_gatedesc(idt + 0x2c, (int)asm_inthandler2c, 2 * 8, AR_INTGATE32);

设置PIC

//PIC初始化
void init_pic(void)
{
    io_out8(PIC0_IMR,  0xff  );   //禁止所有中断
    io_out8(PIC1_IMR,  0xff  );   //禁止所有中断

    io_out8(PIC0_ICW1, 0x11  );   //边沿触发模式
    io_out8(PIC0_ICW2, 0x20  );   //IRQ1~7中断信号由INT20~27接收 
    io_out8(PIC0_ICW3, 1 << 2);   //PIC1由IRQ2连接
    io_out8(PIC0_ICW4, 0x01  );   //无缓冲区模式

    io_out8(PIC1_ICW1, 0x11  );   //边沿触发模式
    io_out8(PIC1_ICW2, 0x28  );   //IRQ8~15中断信号由INT28~2f接收
    io_out8(PIC1_ICW3, 2     );   //PIC1由IRQ2连接
    io_out8(PIC1_ICW4, 0x01  );   //无缓冲区模式

    io_out8(PIC0_IMR,  0xfb  );   // 11111011 PIC1以外全部禁止
    io_out8(PIC1_IMR,  0xff  );   // 11111111 禁止所有中断

    return;
}

中断处理函数

// 鼠标中断处理函数
void inthandler2c(int *esp)
{
    struct BOOTINFO *binfo = (struct BOOTINFO*) ADR_BOOTINFO;
    boxfill8(binfo->vram, binfo->scrnx, COL8_000000, 0, 0, 32 * 8 - 1, 15);
    putfont8_asc(binfo->vram, binfo->scrnx, 0, 0, COL8_FFFFFF, "INT 2C (IRQ-12) : PS/2 mouse");
    for(;;){
        io_hlt();
    }
}
_asm_inthandler2c:  ;void asm_inthandler2c(void);
        PUSH ES
        PUSH DS
        PUSHAD
        MOV EAX, ESP
        PUSH EAX
        MOV AX, SS
        MOV DS, AX
        MOV ES, AX
        CALL _inthandler2c
        POP EAX
        POPAD
        POP DS
        POP ES
        IRETD

允许CPU中断

io_sti();
_io_sti:    ; void io_sti(void);
        STI
        RET

开启鼠标中断

io_out8(PIC1_IMR, 0xef); /* PIC1 鼠标中断设置许可(11101111) */
_io_out8:   ; void io_out8(int port, int data);
        MOV     EDX,[ESP+4]     ; port
        MOV     AL,[ESP+8]      ; data
        OUT     DX,AL
        RET

以上跟键盘中断设置几乎一样,但鼠标还需要两步关键的设置

鼠标控制电路生效

#define PORT_KEYDAT             0x0060
#define PORT_KEYSTA             0x0064
#define PORT_KEYCMD             0x0064
#define KEYSTA_SEND_NOTREADY    0x02
#define KEYCMD_WRITE_MODE       0x60
#define KBC_MODE                0x47

//等待键盘控制电路准备完毕
void wait_KBC_sendread()
{
    for(;;){
        if((io_in8(PORT_KEYSTA) & KEYSTA_SEND_NOTREADY) == 0){
            break;
        }
    }
}

// 初始化键盘控制电路
void init_keyboard()
{
    wait_KBC_sendread();
    io_out8(PORT_KEYCMD, KEYCMD_WRITE_MODE);
    wait_KBC_sendread();
    io_out8(PORT_KEYDAT, KBC_MODE);
    return;
}

鼠标本身生效

void enable_mouse()
{
    wait_KBC_sendread();
    io_out8(PORT_KEYCMD, KEYCMD_SENDTO_MOUSE);
    wait_KBC_sendread();
    io_out8(PORT_KEYDAT, MOUSECMD_ENABLE);
    return;
}

运行结果

这里写图片描述

  • 0
    点赞
  • 4
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值