装配鼠标没有int33h

时间:2017-08-02 08:08:48

标签: assembly mouse x86-16

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

1 个答案:

答案 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上,端口实际上也花费了大量时间,然后固定计数器可能会起作用。)