《30天自制操作系统》读书笔记Day8

来源:互联网 发布:淘宝网团队 编辑:程序博客网 时间:2024/06/01 11:10
1.解析鼠标数据
首先明确每次从鼠标传过来的信息都是3个字节一组的,第一字节表示点击、滚动,第二字节表示左右移动,第三字节表示上下移动。这里修改HariMain函数:
unsigned char mouse_dbuf[3], mouse_phase;//mouse_dbuf[]储存三字节信息,mouse_phase标识储存进行到的步骤mouse_phase = 0;//进入等待鼠标的0xfa状态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) {/* 等待鼠标0xfa状态 */if (i == 0xfa) {mouse_phase = 1;}} else if (mouse_phase == 1) {/* 等待鼠标的第1字节数据并存入mouse_dbuf[] */mouse_dbuf[0] = i;mouse_phase = 2;} else if (mouse_phase == 2) {/* 等待鼠标的第2字节数据并存入mouse_dbuf[] */mouse_dbuf[1] = i;mouse_phase = 3;} else if (mouse_phase == 3) {/* 等待鼠标的第3字节数据并存入mouse_dbuf[] */mouse_dbuf[2] = i;mouse_phase = 1;/* 获得全部的3字节数据,显示出来 */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);}}}}


这时移动鼠标即可获得全部的三个数据。
接下来对bootpack.c进行简单的整理就好了。


2.移动鼠标指针
接着修改mouse_decode,使程序能够舍去不正确的数据,并且提取出需要的按键信息。


struct MOUSE_DEC {unsigned char buf[3], phase;int x, y, btn;//x,y表示鼠标移动信息,btn表示按键信息};int mouse_decode(struct MOUSE_DEC *mdec, unsigned char dat){if (mdec->phase == 0) {/* 等待鼠标0xfa的阶段 */if (dat == 0xfa) {mdec->phase = 1;}return 0;}if (mdec->phase == 1) {/* 等待鼠标的第1字节数据 */if ((dat & 0xc8)==0x08) //修正鼠标按键信息{mdec->buf[0] = dat;mdec->phase = 2;}return 0;}if (mdec->phase == 2) {/* 等待鼠标的第2字节数据 */mdec->buf[1] = dat;mdec->phase = 3;return 0;}if (mdec->phase == 3) {/* 等待鼠标的第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; /* 鼠标移动的y轴方向与屏幕y轴方向相反 */return 1;}return -1; /* 异常返回 */}


然后修改显示信息:
else if (fifo8_status(&mousefifo) != 0) {i = fifo8_get(&mousefifo);io_sti();if (mouse_decode(&mdec, i) != 0) {/* 获得全部3字节数据,显示数据 */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);}}



make run 显示正常
最后,移动鼠标指针,在显示函数中修改:
if (mouse_decode(&mdec, i) != 0) {/* 获得全部3字节数据,显示数据 */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);/*移动鼠标指针*/boxfill8(binfo->vram, binfo->scrnx, COL8_008484, mx, my, mx + 15, my + 15); /* 隐藏原来的鼠标指针 */mx += mdec.x;my += mdec.y;if (mx < 0) {mx = 0;}if (my < 0) {my = 0;}if (mx > binfo->scrnx - 16) {mx = binfo->scrnx - 16;}if (my > binfo->scrny - 16) {my = binfo->scrny - 16;}sprintf(s, "(%3d, %3d)", mx, my);boxfill8(binfo->vram, binfo->scrnx, COL8_008484, 0, 0, 79, 15); /* 隐藏坐标 */putfonts8_asc(binfo->vram, binfo->scrnx, 0, 0, COL8_FFFFFF, s); /* 显示坐标 */putblock8_8(binfo->vram, binfo->scrnx, 16, 16, mx, my, mcursor, 16); /* 重新绘制鼠标 */}



make run 即可正常运行。
现在的鼠标可能会擦除原来的桌面底部画面,可以考虑重绘桌面来防止这种情况。
原创粉丝点击