[ Pobierz całość w formacie PDF ]

wyświetlać piksele gdzieś indziej?
Cóż, są dwie możliwości:
1. W czasie pisania programu (czyli przed kompilacją) znasz dokładną pozycję, gdzie będziesz rysować.
W takim przypadku kompilator policzy DI za ciebie, wystarczy wpisać coś takiego:
mov di, wiersz*320 + kolumna
wstawiając w miejsce słów wiersz i kolumna znane przez siebie wartości.
2. Pozycja, gdzie będziesz rysować jest zmienna i zależy np. od tego, co wpisze użytkownik.
Tutaj jest gorzej. Trzeba wpisać do programu instrukcje, które przemnożą wiersz przez 320 i dodadzą
kolumnę. Należy raczej unikać powolnej instrukcji (I)MUL. Ten problem rozwiążemy tak (wiersz i
kolumna to 2 zmienne po 16 bitów):
mov ax, [wiersz]
mov bx, [wiersz] ; BX = AX
shl ax, 8 ; AX = AX*256
shl bx, 6 ; BX = BX*64 = AX*64
add ax, bx ; AX = AX*256 + AX*64 = AX*320 =
; = wiersz*320
add ax, [kolumna] ; AX = wiersz*320 + kolumna
mov di,ax
Ostatni przykład: rysowanie okręgu (no, w każdym razie czegoś co miało być okręgiem a ma kształt bardziej
przypominający elipsę...). Program ten wykorzystuje koprocesor do policzenia sinusów i kosinusów dla kątów
od 0 do 360 stopni, przerobionych na radiany. Komentarze obok instrukcji FPU oznaczają stan stosu, od st(0)
z lewej.
przeskocz program rysujący koło
; nasm -O999 -o kolo.com -f bin kolo.asm
org 100h
mov ax, 13h
int 10h
mov ax, 0a000h
mov es, ax
mov cx, 360
finit
fldpi
fild word [sto80]
Bogdan Drozdowski 193
Bogdan Drozdowski Język asembler dla każdego 2007-11-12
fdivp st1, st0 ; pi/180
finit
fld1
fild word [r] ; r, 1, pi/180
fldz ; kąt=0, r, 1, pi/180
mov al, 15
rysuj:
fld st0 ; kąt, kąt, r, 1, pi/180
fmul st3 ; kąt w radianach
mov di, 100*320 + 160 ; środek ekranu
fsin ; sin(kąt), kąt, r, 1, pi/180
fmul st2 ; sin(kąt)*r, kąt, r, 1, pi/180
fistp word [wys] ; kąt, r, 1, pi/180
fld st0 ; kąt, kąt, r, 1, pi/180
fcos ; cos(kąt), kąt, r, 1, pi/180
fmul st2 ; r*cos(kąt), kąt, r, 1, pi/180
fistp word [szer] ; kąt, r, 1, pi/180
add di, [szer] ; dodajemy odległość poziomą
mov dx, [wys]
mov bx, dx
shl dx, 8
shl bx, 6
add dx, bx ; dx = wys*320
sub di, dx ; odejmujemy odległość pionową
mov [es:di], al ; wyświetlamy piksel
fadd st0, st2 ; kat += 1
dec cx
jnz rysuj
finit
xor ah, ah
int 16h
mov ax, 3
int 10h
mov ax, 4c00h
int 21h
r dw 50
szer dw 0
wys dw 0
sto80 dw 180
Podobnie, używając FSIN i FCOS, można rysować np. linie ukośne, które pominąłem w tym kursie.
Mam nadzieję, że po lekturze tego odcinka każdy bez problemów będzie rysował w tym dość prostym
194 Bogdan Drozdowski
2007-11-12 Język asembler dla każdego Bogdan Drozdowski
(zwłaszcza do nauki) trybie graficznym.
Miłego eksperymentowania!
Spis treści off-line (Alt+1)
Spis treści on-line (Alt+2)
Ułatwienia dla niepełnosprawnych (Alt+0)
Bogdan Drozdowski 195
Bogdan Drozdowski Język asembler dla każdego 2007-11-12
196 Bogdan Drozdowski
2007-11-12 Język asembler dla każdego Bogdan Drozdowski
Obsługa myszy w asemblerze
W tej części dowiemy się, jak dodać w naszych programach obsługę myszy.
Do naszych celów potrzebne nam będą załadowane sterowniki myszy w pamięci oraz przerwanie int 33h.
Zapoznajmy się z kilkoma podstawowymi funkcjami tegoż przerwania (patrzymy oczywiście w listę przerwań
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 wystarczyć. Są też funkcje, które np. definiują zasięg poziomy i pionowy kursora (można
ustawić tak, że kursor będzie się mógł poruszać tylko w wyznaczonym oknie), ale tymi nie będziemy się
zajmować.
Na dobry początek resetujemy sterownik i sprawdzamy, czy w ogóle jest jakaś mysz zainstalowana (jeszcze
wcześniej można byłoby sprawdzić, czy sam sterownik nie jest procedurą, która nic nie robi, ale pominę to).
Kod jest wyjątkowo krótki:
xor ax, ax
int 33h ; sprawdzamy, czy jest mysz
or ax, ax
jz brak_myszy
Bogdan Drozdowski 197
Bogdan Drozdowski Język asembler dla każdego 2007-11-12
Jak było widać wcześniej, pokazanie kursora nie jest trudne i sprowadza się do:
mov ax, 1
int 33h ; pokaż kursor [ Pobierz całość w formacie PDF ]