   #Start Contents

                          Obsluga myszy w asemblerze

   W tej czesci dowiemy sie, jak dodac w naszych programach obsluge
   myszy.
   Do naszych celow potrzebne nam beda zaladowane sterowniki myszy w
   pamieci oraz przerwanie int 33h.

   Zapoznajmy sie z kilkoma podstawowymi funkcjami tegoz przerwania
   (patrzymy oczywiscie w liste przerwan Ralfa Brown'a - RBIL):
   (przeskocz opis funkcji int 33h)
        INT 33 - MS MOUSE - RESET DRIVER AND READ STATUS
                AX = 0000h
        Return: AX = status
                        0000h hardware/driver not installed
                        FFFFh hardware/driver installed
                BX = number of buttons
                        0000h other than two
                        0002h two buttons (many drivers)
                        0003h Mouse Systems/Logitech three-button mouse
                        FFFFh two buttons

        INT 33 - MS MOUSE v1.0+ - SHOW MOUSE CURSOR
                AX = 0001h

        INT 33 - MS MOUSE v1.0+ - HIDE MOUSE CURSOR
                AX = 0002h

        INT 33 - MS MOUSE v1.0+ - POSITION MOUSE CURSOR
                AX = 0004h
                CX = column
                DX = row

        INT 33 - MS MOUSE v1.0+ - RETURN BUTTON RELEASE DATA
                AX = 0006h
                BX = button number (see #03169)
        Return: AX = button states (see #03168)
                BX = number of times specified button has been released since
                         last call
                CX = column at time specified button was last released
                DX = row at time specified button was last released

        (Table 03169)
        Values for mouse button number:
        0000h  left
        0001h  right
        0002h  middle

   Tyle powinno nam wystarczyc. Sa tez funkcje, ktore na przyklad
   definiuja zasieg poziomy i pionowy kursora (mozna ustawic tak, ze
   kursor bedzie sie mogl poruszac tylko w wyznaczonym "oknie"), ale tymi
   nie bedziemy sie zajmowac.

   Na dobry poczatek resetujemy sterownik i sprawdzamy, czy w ogole jest
   jakas mysz zainstalowana (jeszcze wczesniej mozna byloby sprawdzic,
   czy sam sterownik nie jest procedura, ktora nic nie robi, ale pomine
   to). Kod jest wyjatkowo krotki:
        xor     ax, ax
        int     33h                     ; sprawdzamy, czy jest mysz
        or      ax, ax
        jz      brak_myszy

   Jak bylo widac wczesniej, pokazanie kursora nie jest trudne i
   sprowadza sie do:
        mov     ax, 1
        int     33h                     ; pokaz kursor

   Do szczescia brakuje nam juz tylko sprawdzenie, czy i gdzie nacisnieto
   jakis przycisk. Do tego posluzy nam funkcja numer 6. Wystarczy w BX
   podac interesujacy nas przycisk, a w CX i DX powinnismy otrzymac
   wspolrzedne (dobrze jest przed rozpoczeciem pracy wywolac raz te
   funkcje dla wszystkich przyciskow, aby wyzerowac liczniki nacisniec).
   Przyklad:
        mov     ax, 6
        xor     bx, bx
        int     33h
        or      bx, bx
        jz      nie_wcisnieto_lewego

        mov     [kolumna], cx
        mov     [wiersz], dx

   Nie ma w tym duzo wysilku, na szczescie. Wszystko za nas robi
   sterownik, a my tylko potem sprawdzamy rejestry.
   Dlatego tez od razu przejde do finalu tego artykulu i zaprezentuje
   program, w ktorym zawarlem wszystko to, o czym mowilem. Zadaniem
   programu jest nic innego, jak tylko wyswietlenie odpowiedniego napisu,
   gdy uzytkownik nacisnie jakis klawisz myszki (nacisniecie czegos na
   klawiaturze spowoduje wyjscie z programu). Napis zostanie wyswietlony
   w miejscu, gdzie nacisnieto przycisk.

   Oto kod:
   (przeskocz kod programu)
; Program wyswietlajacy napis w miejscu, gdzie zostal nacisniety
; klawisz myszki.
;
; POD WINDOWS URUCHAMIAC W TRYBIE PELNOEKRANOWYM
;
;
; Autor: Bogdan D.
; kontakt: bogdandr (at) op (dot) pl
;
; nasm -O999 -o mysz.com -f bin mysz.asm


org 100h

        xor     ax, ax                  ; AX = 0
        int     33h                     ; sprawdzamy, czy jest mysz
        or      ax, ax
        jnz     mysz_ok

        mov     dx, nie_ma_myszy
        mov     ah, 9
        int     21h

        mov     ax, 4c01h               ; zwracamy kod bledu=1
        int     21h


mysz_ok:
        mov     ax, 3
        int     10h                     ; czyscimy ekran

        mov     ax, 1
        int     33h                     ; pokazujemy kursor myszki

                                        ; zerujemy liczniki nacisniec:
        mov     ax, 6
        xor     bx, bx                  ; lewy przycisk
        int     33h

        mov     ax, 6
        mov     bx, 1                   ; prawy przycisk
        int     33h

petla:
        mov     ah, 1
        int     16h             ; czy nacisnieto klawisz na klawiaturze?
        jnz     koniec          ; jesli tak, to wychodzimy z programu

        mov     ax, 6
        xor     bx, bx                  ; sprawdzamy lewy przycisk
        int     33h

        or      bx, bx          ; jesli nacisnieto, to idziemy cos wyswietlic
        jnz     pokaz_l

        mov     ax, 6
        mov     bx, 1                   ; sprawdzamy prawy przycisk
        int     33h

        or      bx, bx          ; jesli nacisnieto, to idziemy cos wyswietlic
        jnz     pokaz_p

        jmp     short petla

pokaz_l:
                                ; wiemy, ze CX=kolumna, DX=wiersz, gdzie
                                ;nacisnieto klawisz, ale to sa numery pikseli
                                ; Aby otrzymac kolumne i wiersz, dzielimy je
                                ; przez 8 (bo jest 8 pikseli/znak):
        shr     dx, 3
        shr     cx, 3

        mov     ah, 2                   ; funkcja ustawiania kursora
        mov     dh, dl                  ; DH = wiersz
        mov     dl, cl                  ; DL = kolumna
        int     10h                     ; ustaw nasz kursor tam

        mov     dx, lewy_p
        mov     ah, 9
        int     21h

        jmp     short petla

pokaz_p:
                                ; wiemy, ze CX=kolumna, DX=wiersz, gdzie
                                ;nacisnieto klawisz, ale to sa numery pikseli
                                ; Aby otrzymac kolumne i wiersz, dzielimy je
                                ; przez 8 (bo jest 8 pikseli/znak):
        shr     dx, 3
        shr     cx, 3

        mov     ah, 2                   ; funkcja ustawiania kursora
        mov     dh, dl                  ; DH = wiersz
        mov     dl, cl                  ; DL = kolumna
        int     10h                     ; ustaw nasz kursor tam

        mov     dx, prawy_p
        mov     ah, 9
        int     21h

        jmp     short petla


koniec:
        mov     ax, 4c00h
        int     21h

nie_ma_myszy    db      "Sterowniki myszy nie sa zainstalowane.$"
lewy_p          db      "Lewy$"
prawy_p         db      "Prawy$"

   Jak widac, korzystanie z myszy niekoniecznie musi byc tak trudne, jak
   to sie moglo wydawac. Po bardziej zaawansowane funkcje radze siegnac
   do RBIL, gdzie zawsze znajdziecie wiecej informacji o danym przerwaniu
   niz w moim kursie, ktory skupia sie przeciez na przedstawianiu
   algorytmow a nie na zapamietywaniu kazdego szczegoliku.

   Milego eksperymentowania.

   Spis tresci off-line (klawisz dostepu 1)
   Spis tresci on-line (klawisz dostepu 2)
   Ulatwienia dla niepelnosprawnych (klawisz dostepu 0)
