0
votes

ALRIGHTY, so I have been working on assembly long enough to understand decent code.

I have been trying to get a mouse up w/o int 33h mainly because there is no 33h in VMware or Bochs (emulators w/o MS-DOS).

Does my code seem right? I followed OSDev Wiki and 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
ok well, the code got a little screwed up.Logan Rios
Just test it and you got your answer.cadaniluk
Just a curiosity but is your intent to write an OS or are you just using OSdev for the information?Michael Petch
@MichaelPetch Ehh im playing with OSDev trying to improve my skills on assembly. My main intent is to get more information and maybe join some open source programs in assemblyLogan Rios
I asked the question because if I was moving towards OS development I might be inclined to set up interrupt service routines for the keyboard and the mouse IRQs and handle the keystrokes/mouse movements as each interrupt is fired. There are complexities in this but it is better than polling. You'd have to create something like a ring buffer to store the incoming characters from the keyboard.Michael Petch

1 Answers

1
votes

It's not clear from the question, what is your question, if you are asking for complete code review + debug, then that is AFAIK not a "good" SO question, without at least giving out some hint about how many problems and which ones may be there.

I still took about 15min to read through it quickly, and it feels like not working bad quality first try, so I'm not going to dig into more, and I will just summarize what I didn't like so far (there would be probably lot more to it, if I would do full review, but that would take much more time than I'm willing to put into this). And disclaimer: I never did my own mouse handler for PC, so I'm just comparing your code to the specs from the OSDev Wiki, if those are wrong, my suggestions will be too.


I followed OSDev Wiki

And there is this:

Since both keyboard and mouse data is showing up to be read on port 0x60, it is necessary to be able to tell which is which. To tell if there is any available data on port 0x60 at all, it is necessary to read a byte from port 0x64. In that byte from port 0x64, bit number 0 (value=1) indicates that a byte is available to be read on port 0x60. An additional bit, bit number 5 (value=0x20), indicates that this next byte came from the mouse, if the bit is set. If you look at RBIL, it says that this "mouse bit" is MCA specific, but this is no longer true. All PCs that support PS2 mice use this bit to indicate that the incoming byte was generated by the auxiliary PS2 input port.

But your code is:

mouse_wait_data:
    ...
.a1:;jump into this loop until we rec a signal
    in al, 0x64 
    cmp al, 1
    jne .a1
    ...

So you wait until the port 0x64 is set to 1, but that means data from keyboard. Overall the cmp is usually not a good choice to test bits, as you never know how the control value will be extended in the future and there may be (MADE UP FICTIONAL EXAMPLE in italics) new b7 functionality signalling by 1 the wireless PS/2 device powering, in such case the b0 and b5 may still signal available data from mouse, but you will never catch them by cmp and wireless mouse, because b7 is unexpectedly set all the time.

The code should look more like:

    ...
.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 #

This is too broad, do you already set up the PIT 8253/8254 chip, so you have some source of time, like the DOS int 8 system time ticks?

Then the easiest way may be to use such timer ticks to implement timeout mechanism.

Other way without timer (often used in high level languages) is to have fixed static counter to limit the loop to run only so-many-times, but with non-delayed assembly and vast variety between CPU speeds, for some CPUs 100k loops may be one tenth of second, and for others one billion would be just hundredth of second, so that's not applicable here, unless you figure out some source of reliable delay (like if reading one of the 0x64 or 0x60 ports is actually taking significant amount of time even on modern PC, then fixed counter may work).