您的位置:首页 > 其它

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

2013-07-19 18:28 183 查看
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 即可正常运行。

现在的鼠标可能会擦除原来的桌面底部画面,可以考虑重绘桌面来防止这种情况。
内容来自用户分享和网络整理,不保证内容的准确性,如有侵权内容,可联系管理员处理 点击这里给我发消息
标签: