鼠标控制与32位模式切换
一、鼠标控制
1. 鼠标数据解读
unsigned char mouse_dbuf[3], mouse_phase;
for (;;) {
io_cli();
if (fifo8_status(&keyfifo) + fifo8_status(&mousefifo) == 0) {
io_stihlt();
} else {
if (fifo8_status(&keyfifo) != 0) {
i = fifo8_get(&keyfifo);
io_sti();
sprintf(s, "%02X", i);
boxfill8(binfo->vram, binfo->scrnx, COL8_008484, 0, 16, 15, 31);
putfonts8_asc(binfo->vram, binfo->scrnx, 0, 16, COL8_FFFFFF, s);
} else if (fifo8_status(&mousefifo) != 0) {
i = fifo8_get(&mousefifo);
io_sti();
if (mouse_phase == 0) {
if (i == 0xfa) {
mouse_phase = 1;
}
} else if (mouse_phase == 1) {
mouse_dbuf[0] = i;
mouse_phase = 2;
} else if (mouse_phase == 2) {
mouse_dbuf[1] = i;
mouse_phase = 3;
} else if (mouse_phase == 3) {
mouse_dbuf[2] = i;
mouse_phase = 1;
sprintf(s, "%02X %02X %02X", mouse_dbuf[0], mouse_dbuf[1], mouse_dbuf[2]);
boxfill8(binfo->vram, binfo->scrnx, COL8_008484, 32, 16, 32 + 8 * 8 - 1, 31);
putfonts8_asc(binfo->vram, binfo->scrnx, 32, 16, COL8_FFFFFF, s);
}
}
}
}
- mouse_phase用于记录鼠标工作状态的数组
- 如果检测到有键盘数据,则根据鼠标的状态进行处理
- 鼠标数据一般是三个字节一组,读到三个字节数据就调用显示写入显存,然后显示在屏幕上
2. 代码整理
- 将鼠标相关的变量用结构体进行存储,剥离鼠标数据的逻辑为独立的函数
struct MOUSE_DEC {
unsigned char buf[3], phase;
int x, y, btn;
};
void enable_mouse(struct MOUSE_DEC *mdec)
{
wait_KBC_sendready();
io_out8(PORT_KEYCMD, KEYCMD_SENDTO_MOUSE);
wait_KBC_sendready();
io_out8(PORT_KEYDAT, MOUSECMD_ENABLE);
mdec->phase = 0;
return;
}
int mouse_decode(struct MOUSE_DEC *mdec, unsigned char dat)
{
if (mdec->phase == 0) {
if (dat == 0xfa) {
mdec->phase = 1;
}
return 0;
}
if (mdec->phase == 1) {
mdec->buf[0] = dat;
mdec->phase = 2;
return 0;
}
if (mdec->phase == 2) {
mdec->buf[1] = dat;
mdec->phase = 3;
return 0;
}
if (mdec->phase == 3) {
mdec->buf[2] = dat;
mdec->phase = 1;
return 1;
}
return -1;
}
3. 鼠标数据解读
struct MOUSE_DEC {
unsigned char buf[3], phase;
int x, y, btn;
};
int mouse_decode(struct MOUSE_DEC *mdec, unsigned char dat)
{
if (mdec->phase == 0) {
if (dat == 0xfa) {
mdec->phase = 1;
}
return 0;
}
if (mdec->phase == 1) {
if ((dat & 0xc8) == 0x08) {
mdec->buf[0] = dat;
mdec->phase = 2;
}
return 0;
}
if (mdec->phase == 2) {
mdec->buf[1] = dat;
mdec->phase = 3;
return 0;
}
if (mdec->phase == 3) {
mdec->buf[2] = dat;
mdec->phase = 1;
mdec->btn = mdec->buf[0] & 0x07;
mdec->x = mdec->buf[1];
mdec->y = mdec->buf[2];
if ((mdec->buf[0] & 0x10) != 0) {
mdec->x |= 0xffffff00;
}
if ((mdec->buf[0] & 0x20) != 0) {
mdec->y |= 0xffffff00;
}
mdec->y = - mdec->y;
return 1;
}
return -1;
}
- 结构体的x, y存储移动的xy轴信息,btn存储鼠标按键的状态信息
- mouse_phase == 1 时:
- 0x08 的二进制形式是 0000 1000
- 按位与 用于判断第一个字节对移动有反应的部分是否在03之间,对点击有反应的部分是否在8F之间,防止因鼠标连接问题而导致的数据丢失,从而导致数据错位而无法正确读取鼠标的信息
- mouse_phase == 3 时:
- 鼠标的状态放在bug[0]的低三位,0x07 == 0000 0111, 按位与去获取第三位的鼠标键的状态
- 为了正确解读xy的数据,需要使用第一字节的对移动有反应的几位信息,将xy的第八位和之后的数据全部设为1,或者全部保留位0
- 0x20 == 0010 0000, 如果按位与位部位0则表示 第三位为1,需要全部置为 1, 0xffffff00 == 1111.... 0000 0000
- 解读最后需要对y轴去反,因为鼠标和屏幕的y方向是相反的
鼠标数据的显示
for (;;) {
io_cli();
if (fifo8_status(&keyfifo) + fifo8_status(&mousefifo) == 0) {
io_stihlt();
} else {
if (fifo8_status(&keyfifo) != 0) {
i = fifo8_get(&keyfifo);
io_sti();
sprintf(s, "%02X", i);
boxfill8(binfo->vram, binfo->scrnx, COL8_008484, 0, 16, 15, 31);
putfonts8_asc(binfo->vram, binfo->scrnx, 0, 16, COL8_FFFFFF, s);
} else if (fifo8_status(&mousefifo) != 0) {
i = fifo8_get(&mousefifo);
io_sti();
if (mouse_decode(&mdec, i) != 0) {
sprintf(s, "[lcr %4d %4d]", mdec.x, mdec.y);
if ((mdec.btn & 0x01) != 0) {
s[1] = 'L';
}
if ((mdec.btn & 0x02) != 0) {
s[3] = 'R';
}
if ((mdec.btn & 0x04) != 0) {
s[2] = 'C';
}
boxfill8(binfo->vram, binfo->scrnx, COL8_008484, 32, 16, 32 + 15 * 8 - 1, 31);
putfonts8_asc(binfo->vram, binfo->scrnx, 32, 16, COL8_FFFFFF, s);
}
}
}
}
- mdec.btn与 0000 0001 按位与判断最低位是否为1,也就是是否要转为大写字符
4. 移动鼠标指针
【推荐】国内首个AI IDE,深度理解中文开发场景,立即下载体验Trae
【推荐】编程新体验,更懂你的AI,立即体验豆包MarsCode编程助手
【推荐】抖音旗下AI助手豆包,你的智能百科全书,全免费不限次数
【推荐】轻量又高性能的 SSH 工具 IShell:AI 加持,快人一步
· AI与.NET技术实操系列:基于图像分类模型对图像进行分类
· go语言实现终端里的倒计时
· 如何编写易于单元测试的代码
· 10年+ .NET Coder 心语,封装的思维:从隐藏、稳定开始理解其本质意义
· .NET Core 中如何实现缓存的预热?
· 分享一个免费、快速、无限量使用的满血 DeepSeek R1 模型,支持深度思考和联网搜索!
· 25岁的心里话
· 基于 Docker 搭建 FRP 内网穿透开源项目(很简单哒)
· ollama系列01:轻松3步本地部署deepseek,普通电脑可用
· 按钮权限的设计及实现