图层叠加就是用于鼠标,窗口等拖动设计。
这时候就需要完成缓冲区系统了。注意这个时候不要输入中文,输入法切换掉。
然后,在每一次循环中都要执行一遍鼠标移动和键盘获取,为Keyboard_Process和Mouse_Process。相应的缓存区为Keyboard_Buf和Mouse_Buf。
另外设计lib里的queue。
鼠标三个数据一组,先开始送来0xfa(在这之前还会有一连串的out初始化操作),开始接收,然后就一直接收就可以了。第一个数据的前半位与移动有关,后半位与按键有关,第二个数据掌管左右移动,第三个数据掌管上下移动。
通过对第一字节进行约束,就不用担心数据读取错误。
鼠标与屏幕的y方向刚好相反,因此要倒转过来。
关于队列,内核中都是使用循环队列,例如:
Mouse_Buf 缓冲区首地址
Mouse_Buf_Size 整个缓冲区的大小
Mouse_Buf_Count 里面元素的多少
Mouse_Buf_Begin 第一个指针
Mouse_Buf_End 最后一个指针
注意都是4字节的。例如一共32个字节,当缓冲区里一个都没有的时候,begin=end=0,当有一个的时候,begin=0,end=1,当满了的时候,begin=end
一个写入,一个读出,读出为第一个内容,写入为最后一个没有内容。当满了的时候,二者重合,当空的时候,二者重合,实际上,这两种都是不允许成立的,因此我们规定为空时二者重合,如果满了,禁止满了,就是这样。人为浪费一个单元,空闲单元法。
两个中断就一直往队列中送数据。
因为只是一个al,因此只能是db了,因此最好用宏来实现。
今天实现了鼠标很多,真给劲。
鼠标传来3个字节,第一个字节是按键信息,第二个字节是x值,第三个字节是y值,鼠标按键的信息,只存在于第一个字节的低3位,因此要and 0x7,基本上第二个字节就是x值,第三个字节就是y值,只不过30天里用了int表示x和y,因此给前面清空了一下。
关于状态1的测试,是if(dat & 0xc8 == 0x08),其中,0xc8=11001000,0x08=00001000,他的解释是用于判断第一字节对移动有反应的部分是否在0~3的范围内,同时还要判断第一字节对点击有反应的部分是否在8~F的范围内,如果这个字节的数据不在以上范围内,它就会被舍去。
什么意思呢?字面意思上说,这个字节绝对会保证00xx1xxx,这样,而且其他字节不会有这样的效果。
这就好多了。虽然鼠标的移动云里雾里的,但是能够移动了!只要好好修改一下,就没有任何问题了。
虽然自己插的是USB鼠标,但是看30day的img也能照常使用,感觉应该没什么关系。
坐标是8位正负号的,正负号被放在了第一个字节的4,5位。
X和Y的溢出位,即当一次移动距离过大时,超过寄存器的范围时,就会发生溢出该位设置为1,而对于第三位默认设计为1.
因此1字节就是偏移量而已,这个足够了。根据正负号来进行加减而已。
但关键是每处理一个字节就会循环一轮,那么这样就不对,如果能读,就要在一轮中全部都出来算了。既然能确定第一个是第一个,那么必然能够确定后面的,多一轮也只不过是多一个循环,等待时间给push?意义都是一样的吧。
现在自己做的,eax相当于前半部分是y,后半部分是x。就是如此。因此最好存在后面。
现在发现,一旦符号为1,那么就是FX,取补码的,而且y轴向下为1,整体就是如此。
补码这个问题真的自闭了,或者说,整体都在取补码,它是9位的,计算机从来没有反码一说,要取就取补码。
补码的话,无论正负,它都是相加的,因此你设一个2字节的,前面补上ff就可以了。
然后直接相加,就很舒服。
0xffff = 65535个像素,因此用一个字够用了,况且eax本身就一个字节。
虽然是9位的,但是怎么说呢,哪能一下子就到200多像素的,但是这也没关系,我是仅仅根据正负填高阶是不是ff的而已。
最后不要忘记给y取反一下。
最后终于成功了,爽!
每日小常识:
如果作为8位寄存器来使用,低8位寄存器中产生的进位不会存储到高8位寄存器中。