ALRIGHTY,所以我一直致力于组装,以便了解合适的代码。
我一直试图在没有33h的情况下使用鼠标,主要是因为VMware或Bochs没有33h(没有MS-DOS的模拟器)。
我的代码是否正确?我跟着OSDev Wiki和Cosmos c#
;==================================== ;#Handles the mouse routines # ; # ;#TODO: Find a way to make it so # ;# the mouse_wait_signal times out # ;==================================== mouse_initalize: ;first enable IRQ12 mov al, 0xA8 out 0x64, al ;wait for signal call mouse_wait_signal ;next enable interrupt mov al, 0x20 ;command out 0x64, al ;wait for data call mouse_wait_data ;get data in al, 0x60 mov [mouse_status], al ;wait for more signal call mouse_wait_signal ;command mov al, 0x60 out 0x64, al ;wait le sig call mouse_wait_signal ;set the status in al, 0x60 mov [mouse_status], al ;finnaly enable mouse ;---DEFAULT----- mov al, 0xF6 call mouse_write call mouse_read ;acknowlage ;---DEFAULT----- ;---ENABLE------ mov al, 0xF4 call mouse_write call mouse_read ;acknowlage ;---ENABLE------ ret ;------------------------------------ ;Waits for signal from mouse port mouse_wait_signal: ;save prev al mov [.buffer], al .a1:;jump into this loop until we rec a signal in al, 0x64 cmp al, 0 je .a1 ;loop stoped meaning we have a signal mov al, [.buffer] ret .buffer db 0x00 ;------------------------------------ ;Waits for data signal from port 0x64 mouse_wait_data: ;save prev al mov [.buffer], al .a1:;jump into this loop until we rec a signal in al, 0x64 cmp al, 1 jne .a1 ;loop stoped meaning we have a signal mov al, [.buffer] ret .buffer db 0x00 ;------------------------------------ ;Writes to the mouse ;IN: AL = cmd mouse_write: ;save prev al mov [.buffer], al ;wait,send1,wait,sendcmd call mouse_wait_signal mov al, 0xD4 out 0x64, al call mouse_wait_signal mov al, [.buffer] out 0x60, al ;loop stoped meaning we have a signal mov al, [.buffer] ret .buffer db 0x00 ;------------------------------------ ;Reads the mouse ;RET: AL = data mouse_write: call mouse_wait_data in al, 0x60 ret ;===VARIABLES======================== mouse_status db 0x00
答案 0 :(得分:1)
问题不清楚,你的问题是什么,如果你要求完整的代码审查+调试,那么这就是AFAIK而不是"好"所以问题,至少没有给出一些关于有多少问题以及可能存在哪些问题的暗示。
我还是花了大约15分钟来快速阅读它,感觉好像没有质量不好第一次尝试,所以我不打算深入研究,我只是总结一下我没有做过的事情。就像到目前为止(如果我要进行全面审查,可能会有更多的内容,但这比我愿意投入的时间要多得多)。免责声明:我从来没有为PC做过自己的鼠标处理程序,所以我只是将你的代码与OSDev Wiki的规范进行比较,如果这些是错误的,我的建议也是如此。
我关注了OSDev Wiki
有这个:
由于键盘和鼠标数据都显示在端口0x60上读取,因此必须能够分辨哪个是哪个。要知道端口0x60上是否有任何可用数据,必须从端口0x64读取一个字节。在来自端口0x64的该字节中,位号0(值= 1)表示可以在端口0x60上读取一个字节。如果该位置1,则另一位,位号5(值= 0x20)表示该下一个字节来自鼠标。如果你看看RBIL,它会说这个"鼠标位"是MCA特定的,但这不再是真的。所有支持PS2鼠标的PC都使用此位来指示输入字节是由辅助PS2输入端口生成的。
但你的代码是:
mouse_wait_data:
...
.a1:;jump into this loop until we rec a signal
in al, 0x64
cmp al, 1
jne .a1
...
所以你要等到端口0x64设置为1,但这意味着来自键盘的数据。总的来说,cmp
通常不是测试位的好选择,因为您永远不知道将来如何扩展控制值,并且可能存在(斜体中的MADE UP FICTIONAL EXAMPLE) new b7功能信令通过1无线PS / 2设备供电,在这种情况下,b0和b5仍然可以通过鼠标发出可用数据信号,但是你永远不会通过cmp
和无线鼠标捕获它们,因为b7一直意外设置< / em>的
代码看起来应该更像:
...
.a1:;jump into this loop until we rec a signal
in al, 0x64
and al, 0x21 ; mask b5 (mouse data) and b0 (data available)
cmp al, 0x21 ; are both bits set?
jne .a1 ; until some mouse data are available (throws away keyboard data!)
...
;#TODO: Find a way to make it so #
;# the mouse_wait_signal times out #
这太宽泛了,你是否已经设置了PIT 8253/8254 chip,所以你有一些时间来源,比如DOS int 8
system time ticks?
然后最简单的方法是使用这样的计时器滴答来实现超时机制。
没有计时器(通常在高级语言中使用)的其他方式是使用固定的静态计数器来限制循环只运行这么多次,但是对于某些CPU来说,没有延迟组装和CPU速度之间的差异很大100k循环可能是十分之一秒,而对于其他循环,10亿只是百分之一秒,所以这里不适用,除非你找出一些可靠延迟的来源(比如读取0x64或0x60之一)即使在现代PC上,端口实际上也花费了大量时间,然后固定计数器可能会起作用。)