开启鼠标中断
程序员文章站
2024-02-25 21:27:39
...
设置中断描述符表
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;
}