鼠标控制与32位模式切换
在编写代码的时候可以对照书中的代码,以便及时找出自己的错误。
1. 鼠标解读(1)
已经能从鼠标取得数据了,紧接着的问题是要解读这些数据,调查鼠标是怎么移动的,然后结合鼠标的动作,让鼠标指针相应地动起来。
首先对bootpack.c中的HariMain进行一些修改:
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) {
/*等待鼠标的第一字节*/
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);
}
}
}
}
实际上是将HariMain中for循环部分进行修改,首先把最初读到的0xfa舍弃掉。之后,每次从鼠标那里送过来的数据都应该是3个字节一组的,所以每当数据累积到3个字节,就把他显示在屏幕上。
变量mouse_phase用来记住接受鼠标数据的工作进展到了什么阶段(phase)。接受到的数据放在mouse_dbuf[0~2]内。
if (mouse_phase == 0) /*等待鼠标的0xfa的状态*/
{
各种处理;
} else if (mouse_phase == 1) {
/*等待鼠标的第一字节*/
各种处理;
} else if (mouse_phase == 2) {
/* 等待鼠标的第二字节 */
各种处理;
} else if (mouse_phase == 3) {
/*鼠标的三个字节都齐了,显示出来*/
各种处理;
}
这部分就是对于不同的mouse_phase值,相应地做各种不同的处理。显示结果如下(鼠标移动过):
屏幕上除了括号内的还有三字节数字,即mouse_dbuf[0],mouse_dbuf[1],mouse_dbuf[2]里的数据。”08”部分0会在0~3的范围内变化,”8”只有在点击鼠标时才会有变化,值在8~F之间。第二个字节与鼠标的左右移动有关,第三个字节与鼠标的上下移动有关。
2. 整理
在HariMain函数中出现的unsigned char mouse_dbuf[3], mouse_phase;声明可以放到函数前的结构体里:
struct MOUSE_DEC {
unsigned char buf[3], phase;
};
并在这句话修改为:
struct MOUSE_DEC mdec;
创建的这个结构体MOUSE_DEC,DEC是decode的缩写,用这个结构日把鼠标所需要的变量都归总到一块儿。
然后将鼠标的解读从函数HariMain的接受信息处理中剥离出来,放到了mouse_decode函数。
3. 鼠标解读(2)
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) {
/* 等待鼠标的0xfa的阶段 */
if (dat == 0xfa) {
mdec->phase = 1