Posts Tagged ‘asm’

PostHeaderIcon Assembler

Proste programy napisane w assemblerze MASM

PostHeaderIcon Program rezydentny

Program rezydentny (ang. TSR) tj. pozostający w pamięci komputera podczas normalnej pracy systemu i generujący jakiś ciekawy krótki dźwięk po naciśnięciu klawisza SPACE przy wciśniętym wcześniej klawiszu CTRL. Dźwięk jest generowany na głośniku PC (brzęczyku PC)
Program powinien się instalować w pamięci tylko jeden raz! Ponowne jego uruchomienie powinno generować komunikat, że program jest już zainstalowany.
Wywołanie programu z opcją -u odinstalowuje program i zwalnia zajmowaną przez niego pamięć

; by Pawel Konieczny
; ver 0.9
.model tiny
;..................................................

;ASSUME cs:code1, ds:code1

;................. Segment kodu ...................
code1 segment
org 100h
start:

 jmp param

 stproc    dd    0
 znacznik    dw 'vs'
 czasomierz    equ    40h
 TC     equ     36157    ; 1193181Hz/33Hz
 TD     equ     32248    ; 1193181Hz/37Hz
 TE     equ     29102    ; 1193181Hz/41Hz
 TF     equ     27118    ; 1193181Hz/44Hz
 TG     equ     24351    ; 1193181Hz/49Hz
 TA     equ     21694    ; 1193181Hz/55Hz
 TH     equ     19245    ; 1193181Hz/62Hz

; -------------------------------------------------
;              Glowny kod programu
; -------------------------------------------------

 mainprog:
 push es
 in al,60h            ;pobierz klawisz
 cmp al,39h            ;scan-code spacji
 jne koniec
 xor ax,ax
 mov es,ax
 test byte ptr es:[417h],4    ;sprawdzam czy jest 'ctrl' wcisniety
 jz koniec

 ; wlaczenie

 in al,61h                     ; czyta biezacy status kontrolera
 or al,00000011b               ; dwa ostatnie bity na '1'
 out 61h,al                    ; zapisuje nowy status

 ; melodia

 mov ax,TA                     ; 1193181 / czestotl. = ax
 mov cl,3
 shr ax,cl                     ; ax = ax / 2^oktawa
 call graj
 call czas

 mov ax,TC
 mov cl,4
 shr ax,cl
 call graj
 call czas

 mov ax,TH
 mov cl,3
 shr ax,cl
 call graj
 call czas

 mov ax,TC
 mov cl,4
 shr ax,cl
 call graj
 call czas

 mov ax,TA
 mov cl,3
 shr ax,cl
 call graj
 call czas

 mov ax,TA
 mov cl,3
 shr ax,cl
 call graj
 call czas

 ; -------------------

 mov ax,TE
 mov cl,4
 shr ax,cl
 call graj
 call czas

 mov ax,TG
 mov cl,4
 shr ax,cl
 call graj
 call czas

 mov ax,TE
 mov cl,4
 shr ax,cl
 call graj
 call czas

 mov ax,TD
 mov cl,4
 shr ax,cl
 call graj
 call czas

 mov ax,TE
 mov cl,4
 shr ax,cl
 call graj
 call czas

 mov ax,TE
 mov cl,4
 shr ax,cl
 call graj
 call czas

 ; ------------------

 mov ax,TA
 mov cl,3
 shr ax,cl
 call graj
 call czas

 mov ax,TA
 mov cl,3
 shr ax,cl
 call graj
 call czas

 mov ax,TA
 mov cl,3
 shr ax,cl
 call graj
 call czas

 mov ax,TC
 mov cl,4
 shr ax,cl
 call graj
 call czas

 mov ax,TD
 mov cl,4
 shr ax,cl
 call graj
 call czas

 mov ax,TH
 mov cl,3
 shr ax,cl
 call graj
 call czas

 mov ax,TH
 mov cl,3
 shr ax,cl
 call graj
 call czas

 ; --------------------

 mov ax,TC
 mov cl,4
 shr ax,cl
 call graj
 call czas

 mov ax,TA
 mov cl,3
 shr ax,cl
 call graj
 call czas

 mov ax,TG
 mov cl,3
 shr ax,cl
 call graj
 call czas

 mov ax,TH
 mov cl,3
 shr ax,cl
 call graj
 call czas

 mov ax,TA
 mov cl,3
 shr ax,cl
 call graj
 call czas

 ; wylaczenie

 in al,61h                     ; czyta biezacy status kontrolera
 and al,11111100b              ; dwa ostatnie buty na '0'
 out 61h,al                    ; zapisuje nowy status

 jmp koniec

 sek PROC
 mov cx,0fh
 mov dx,4240h
 ret
 sek ENDP

 pol_sek PROC
 mov cx,7Ah
 mov dx,120h
 ret
 pol_sek ENDP

 cw_sek PROC
 mov cx,3Dh
 mov dx,090h
 ret
 cw_sek ENDP

 os_sek PROC
 mov cx,1Eh
 mov dx,848h
 ret
 os_sek ENDP

 graj PROC                        ; ax - podzielnik
 out 42h,al
 mov al,ah
 out 42h,al
 ret
 graj ENDP

 czas PROC
 xor al,al            ;opoznienie na 1 sek
 out 70h,al            ;czas odczytuje z cmosu
 jmp $+2                ;drobne opuznienie potrzebne do poprawnej wspolpracy z CMOS
 in al,71h
 mov dl,al
 petla1:                    ;w tej petli pobieram aktualna sekunde
 xor al,al
 out    70h,al
 jmp $+2                ;drobne opoznienie potrzebne do poprawnej wspolpracy z CMOS
 in al,71h
 cmp    dl,al            ;i sprawdzam czy jest rowna poprzedniej
 je petla1
 ret
 czas ENDP

 koniec:
 pop es
 jmp dword ptr cs:[stproc]        ; skok do oryginalnej procedury

; -------------------------------------------------
;           Wczytywanie parametru
; -------------------------------------------------

 param:
 mov    ax,cs
 mov    ds,ax            ; DS = CS, na wszelki wypadek

 mov    al,byte ptr es:[80h]
 cmp al,0
 je install

 mov    al,byte ptr es:[81h]        ; sprawdzamy kolejny znak w linii polecen
 cmp    al,0dh
 je install                        ; Enter = koniec linii, wiec instaluj

 mov    al,byte ptr es:[82h]
 cmp    al,'-'
 jne    Komunikat1

 mov    al,byte ptr es:[83h]
 cmp al,'u'
 jne Komunikat1

 mov    al,byte ptr es:[84h]
 cmp al,0dh
 jne Komunikat1

 jmp uninstall

; -------------------------------------------------
;               Odinstalowanie
; -------------------------------------------------

 Uninstall:
 mov ax,3508h                              ; pobranie wektora przerwania
 int 21h
 cmp bx,offset mainprog                    ; sprawdzamy, czy sie zgadzaja offsety
 jne NieMa
 ;mov si,offset znacznik                   ; adres lokalnego znacznika do DS:SI
 ;mov di,si                                ; i znacznika sprawdzanego do ES:DI
 ;mov cx,2                                 ; dlugosc znacznika w bajtach
 ;cld
 ;repe cmpsb                               ; sprawdzamy az do rozniacego sie bajtu
 mov si,'vs'
 mov di,si
 cmp word ptr es:[bx-2],'vs'
 jne NieMa                                 ; gdy rozne znaczniki
 ;jnz NieMa

 mov dx,word ptr es:[stproc]               ; czytamy oryginalny wektor
 mov ax,word ptr es:[stproc+2]             ; z bloku TSRa
 mov ds,ax
 mov ax,2508h                              ; ustawienie wektora przerwania, adres podany w ds:dx
 int 21h

 mov ah,49h                                ; zwolnienie bloku pamieci w segmencie ES z TSRem
 int 21h

 mov ax,cs
 mov ds,ax                                 ; przywracamy do DS segment naszego programu
 mov ah,9                                  ; wydruk napisu na ekran
 mov dx,offset uninst
 int 21h                                   ; drukujemy komunikat o pomyœlym usuniêciu TSRa

 jmp koniecx

 NieMa:
 mov ah,9                                  ; wydruk napisu na ekran
 mov dx,offset blad
 int 21h
 jmp koniecx

; -------------------------------------------------
;                Instalowanie
; -------------------------------------------------

 Install:
 mov ax,3508h
 int 21h                                   ; sprawdz, czy przed procedura obslugi przerwania ...
 cmp word ptr es:[bx-2],'vs'               ; ... znajduje sie 'vs'
 je Komunikat2                             ; jesli tak, to znak, ze program byl juz zainstalowany

 mov es,word ptr ds:[2ch]                  ; numer segmentu srodowiska odczytamy z PSP, wrzucimy do ES
 mov ah,49h                                ; zwolnienie bloku pamieci
 int 21h

 mov ax,3508h                              ; pobranie adresu procedury obslugi przerwania 8h
 int 21h                                   ; wynik do ES:BX
 mov word ptr cs:[stproc],bx
 mov word ptr cs:[stproc+2],es

 mov ax,2508h                              ; ustawienie nowego adresu procedury obslugi przerwania
 mov dx,offset mainprog                    ; DS:DX - wektor naszej procedury
 int 21h

 mov ah,9                                  ; wydruk napisu na ekran
 mov dx,offset inst
 int 21h

 mov dx,offset param                       ; do DX wpisujemy adres pierwszego bajtu, który ma byc zwolniony
 int 27h                                   ; wczesniejsze pozostaja pamieci

; -------------------------------------------------
;                Reszta kodu
; -------------------------------------------------

 Komunikat1:
 lea dx,error_1
 jmp sh_err

 Komunikat2:
 lea dx,error_2
 jmp sh_err

 sh_err:                   ; wypisuje na ekran bledy
 mov ah,9h
 int 21h

 koniecx:
 mov ax,4c00h
 int 21h


error_1        db    'Bledny parametr$'
blad        db    'Nie mozna odinstalowac programu, ktory nie byl zainstalowany$'
uninst    db    'Program odinstalowano.$'
error_2    db    'Program byl juz wczesniej zainstalowany.$'
inst        db    'Program zainstalowano.$'

code1 ends
;..................................................

END start

PostHeaderIcon Tryb graficzny

Program rysujący na ekranie figury geometryczne na podstawie danych umieszczonych w pliku wejściowym o nazwie podawanej przy wywołaniu.
Figury powinny być rysowane w trybach VGA: 320×200-256kol i 640×480-16kol w jednym z czterech kolorów: biały, czerwony, zielony lub niebieski (B,C,Z lub N). Ekran jest traktowany jako pierwsza ćwiartka układu współrzędnych. Początek układu współrzędnych znajduje się w lewym dolnym rogu ekranu.
Dodatkowo w trybie 320×200 figury są wypełniane
Pierwsza linia pliku zawiera tryb ekranu: 320 lub 640
320 – oznacza tryb 320×200
640 – oznacza tryb 640×480

Kolejne linie określają poszczególne figury do wyświetlenia na ekranie. Każda taka linia zawiera na początku literę określającą kolor figury, a następnie ciąg par współrzędnych wierzchołków figury.
Przykład pliku wejściowego: (rysuje czerwony kwadrat i niebieski trójkąt w trybie 320×200):

320
C 0,0 50,0 50,50 0,50
N 100,80 150,110 200,40

Przykład wywołania Programu:
program3 dane.wej

; by Pawel Konieczny
; ver 1.0
.186
;................. Segment danych .................
dane1 segment
p0          dw  ?
q0          dw  ?
p1          dw  ?
q1          dw  ?
f_in            db  10 dup (?),'0'
uchwyt          dw  ?
bufor          db  1000 dup ('$')
errorx        db  'Za duza wspolrzedna X$'
errory            db  'Za duza wspolrzedna Y$'
error1        db  'Brak parametru$'
error2        db  'Nie znaleziono pliku$'
error4        db  'Nie mozna zamknac pliku$'
gran_linii    dw  ?
gran_ekran    dw  ?
WspX        dw  ?
WspY        dw  ?
kop_di        dw  ?
x          dw  ?
y          dw  ?
w1        dw  ?
w2        dw  ?
a          dw  ?
b          dw  ?
dex          dw  ?
dey          dw  ?
adx          dw  ?
ady          dw  ?
ix          dw  ?
iy          dw  ?
du          dw  ?
dr         dw  ?
pp          dw  ?
cp          dw  ?
kolor          db  ?
dane1 ends
;..................................................

;................. Segment kodu ...................
code1 segment
ASSUME cs:code1, ds:dane1, ss:stos1
start:
mov ax,seg dane1
mov ds,ax

call CzyParam
call CzytPar
next:
call OtwPlik
call CzytPlik
call Wcz_rozdz

mov di,5           ; tu sie zaczyna pierwszy kolor
call Wcz_kolor
inc di
inc di
jmp startuj
start3:
mov di,[kop_di]
call Wcz_kolor
inc di
inc di
startuj:
call Czytaj       ; pierwsza wspolrzedna (dwie liczby), ustawia 'di' na pierwszy znak po ostatniej liczbie
mov ax,[a]
mov [p0],ax
mov [w1],ax
mov ax,[b]
mov [q0],ax
mov [w2],ax

inc di            ; przeskocz spacje
call CzyKoniec    ; sprawdz, czy doszlismy do konca linii

start2:
call Czytaj       ; druga wspolrzedna
mov ax,[a]
mov [p1],ax
mov ax,[b]
mov [q1],ax

call Rysuj_linie

inc di
call CzyKoniec

mov ax,[p1]
mov [p0],ax
mov ax,[q1]
mov [q0],ax
jmp start2

pob_pierw:
mov ax,[w1]
mov [p0],ax
mov ax,[w2]
mov [q0],ax
call Rysuj_linie

mov di,-1
mov ax,[WspX]
dec ax
mov [gran_linii],ax         ; gran_linii = WspX - 1
xor bx,bx
jmp szuk_pier
do_nowej_linii:
mov di,[gran_linii]
mov cx,[WspX]
add [gran_linii],cx
xor bx,bx
mov cx,[gran_ekran]
cmp [gran_linii],cx
ja start3                  ; gdy dojdziemy do konca, wczytuj nastepna figure
szuk_pier:
inc di
cmp di,[gran_linii]
jae do_nowej_linii
mov al,byte ptr es:[di]
cmp al,[kolor]
jne szuk_pier
mov bx,di              ; znacznik pierwszego wystapienia
szuk_drug:               ; znaleziono pierwszy punkt
inc di
cmp di,[gran_linii]      ; drugi punkt musi byc w tej samej linii ...
ja [do_nowej_linii]     ; ... gdy go nie ma, skaczemy do nowej linii
mov al,byte ptr es:[di]
cmp al,[kolor]
je czy_nie_sa_obok     ; znaleziono drugi punkt, ale sprawdzamy, czy nie sa obok siebie
jmp szuk_drug

czy_nie_sa_obok:
inc bx
cmp bx,di
je szuk_drug
;    dec bx

cmp [WspX],320
je wypelnij_low
call ZamkPlik
call Koniec

wypelnij_low:
mov al,[kolor]
mov byte ptr es:[bx],al
inc bx
cmp bx,di
jne wypelnij_low
jmp do_nowej_linii
;jmp szuk_pier

CzyParam PROC               ; sprawdzenie czy sa parametry
mov bx,80h           ; sprawdzamy czy istnieje ...
mov cl,byte ptr es:[bx]       ; ... jakikolwiek parametr
cmp cl,0             ; jesli nie ma zadnego parametru, to ...
je Komunikat1        ; ... wypisz blad
ret
CzyParam ENDP

CzytPar PROC               ; czytanie pierwszego parametru
inc bx               ; parametry zaczynaja sie od 82h
mov dl,byte ptr es:[bx]       ; wczytujemy znak do dl
cmp dl,0dh
je next
mov f_in[di],dl      ; a nastepnie do bufora, ktory bedzie nazwa pliku
inc di
jmp CzytPar
ret
CzytPar ENDP

CzyKoniec PROC                ; ------------------ Sprawdz, czy doszlismy do konca linii ------------------------------
mov dl,[bufor+di]
mov [kop_di],di
inc [kop_di]
inc [kop_di]
cmp dl,0dh
je pob_pierw
ret
CzyKoniec ENDP
; wejscie : 'di' - miejsce w pliku
; wyjscie : skok do 'pob_pierw', gdy napotkano na koniec pliku

Wcz_rozdz PROC                ; ------------------------- Wczytanie rozdzielczosci ------------------------------------
low_res:              ; -- czy 320 x 200 --
mov dl,[bufor]
cmp dl,'3'
jne high_res
mov dl,[bufor+1]
cmp dl,'2'
jne Koniec
mov dl,[bufor+2]
cmp dl,'0'
jne Koniec
mov dl,[bufor+3]
cmp dl,13            ; sprawdzamy, czy jest znak konca linii ...
jne Koniec           ; ... gdy nie, wychodzimy (znaczy to, ze jest jeszcze jakas cyfra)
mov [WspX],320
mov [WspY],200
mov [gran_ekran],63999
call InitLow
ret

high_res:              ; -- czy 640 x 480 --
mov dl,[bufor]
cmp dl,'6'
jne Koniec
mov dl,[bufor+1]
cmp dl,'4'
jne Koniec
mov dl,[bufor+2]
cmp dl,'0'
jne Koniec
mov dl,[bufor+3]
cmp dl,13            ; sprawdzamy, czy jest znak konca linii ...
jne Koniec           ; ... gdy nie, wychodzimy
mov [WspX],640
mov [WspY],480
mov [gran_ekran],307199
call InitHigh
ret
Wcz_rozdz ENDP

Wcz_kolor PROC                ; ----------------------------- Wczytanie koloru ----------------------------------------
mov dl,[bufor+di]
cmp dl,'B'
je bialy               ;  kolor bialy
cmp dl,'C'
je czerwony           ;  kolor czerwony
cmp dl,'Z'
je zielony           ;  kolor zielony
cmp dl,'N'
je niebieski           ;  kolor niebieski

jmp Koniec           ; gdy kolor jest niezdefiniowany, wychodzimy

bialy:
mov [kolor],15
ret

czerwony:
mov [kolor],4
ret

zielony:
mov [kolor],2
ret

niebieski:
mov [kolor],1
ret
Wcz_kolor ENDP

Czytaj PROC                   ; --------- Wczytanie liczb obok przecinka i umieszczenie ich do zmiennych a,b ----------
xor cx,cx
; --------- wczytanie pierwszego punktu do 'cx' ----------
first_p:            ; zmienna 'p'
mov al,[bufor+di]

sub al,30h
xor ah,ah         ; zamien ascii na cyfre
add cx,ax         ; dodaj cyfre do sumy
mov ax,cx         ; przenies sume do 'ax'

inc di            ; sprawdz nastepny znak
mov dl,[bufor+di]     ; ...........
cmp dl,','        ; jesli jest przecinkiem ...
je podstaw        ; ... to zakoncz wczytywanie

mov bx,ax         ; ... w przeciwnym wypadku pomnoz przez 10 poprzednia liczbe
shl ax,3            ; ax = ax * 8
shl bx,1            ; bx = bx * 2 = ax * 2
add ax,bx         ; ax = ax + bx = ax * 10

mov cx,ax
jmp first_p

podstaw:
cmp ax,[WspX]
jae Komunikatx
mov a,ax
inc di
xor cx,cx

; --------- wczytanie drugiego punktu do 'cx' ----------
second_p:            ; zmienna 'q'
mov al,[bufor+di]

sub al,30h
xor ah,ah         ; zamien ascii na cyfre
add cx,ax         ; dodaj cyfre do sumy
mov ax,cx         ; przenies sume do 'ax'

inc di            ; sprawdz nastepny znak
mov dl,[bufor+di]     ; ...........
cmp dl,' '        ; jesli jest spacja
je podstaw2        ; to zakoncz wczytywanie

mov bx,ax         ; w przeciwnym wypadku pomnoz przez 10 poprzednia liczbe
shl ax,3            ; 2^3 +
shl bx,1            ; + 2^1
add ax,bx

mov cx,ax
jmp second_p

podstaw2:
cmp ax,[WspY]
jae Komunikaty
mov [b],ax
ret
Czytaj ENDP

InitLow PROC                  ; -------------------------- Inicjalizacja trybu 320 x 200 x 256 ------------------------
mov ax,0013h
int 10h
mov ax,0A000h
mov es,ax         ; es = 0A000h
ret
InitLow ENDP

InitHigh PROC                 ; -------------------------- Inicjalizacja trybu 640 x 480 x 16 -------------------------
mov ax,0012h
int 10h
mov ax,0a000h
mov es,ax         ; es = 0A000h
ret
InitHigh ENDP

RysujPunkt PROC
cmp [WspX],320
je PunktLow
cmp [WspX],640
je PunktHigh
ret
RysujPunkt ENDP

PunktLow:                 ; ------------------------ Rysowanie punktu o wps. x,y ----------------------------------
mov ax,[y]
neg ax
add ax,199        ; ax = 199 - ax
mov bx,ax         ; 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,[x]            ; ax = wiersz*320 + kolumna = 320y+x
mov di,ax
mov al,[kolor]
mov byte ptr es:[di],al
ret

PunktHigh:               ; ------------------------ Rysowanie punktu o wps. x,y ----------------------------------
push cx
mov ax,[x]
mov bx,[y]
neg bx
add bx,479
mov dx,bx
shl bx,6
shl dx,4
add bx,dx         ; bx = y * 80
mov dx,ax
shr dx,3          ; dx = x / 8
add bx,dx         ; bx = wyliczony adres
mov cl,7
and cl,al         ; cl = n (numer bitu w wyznaczonym bajcie w bx)
mov al,80h
shr al,cl         ; al = maska
mov dx,3CFh
out dx,al               ; wpisujemy do rejestru Bit Mask

mov al,2
mov dx,3C4h
out dx,al               ; select map mask register

mov al,0Fh
mov dx,3C5h
out dx,al               ; enable all planes

mov al,es:[bx]          ; czytanie z pamieci
mov es:[bx],byte ptr 0  ; czyszczenie kolorow
mov al,[kolor]
out dx,al               ; ustawianie nowego koloru
mov es:[bx],byte ptr 0FFh ; zapisywanie do pamieci

pop cx
ret

OtwPlik PROC                  ; ----------------------------- Otwieranie pliku ----------------------------------------
mov ax,3d00h       ; otwieramy plik do odczytu
lea dx,[f_in]
int 21h
jc Komunikat2
mov [uchwyt],ax
ret
OtwPlik ENDP

CzytPlik PROC                 ; ------------------------- Czytanie z pliku do bufora ----------------------------------
mov ax,3f00h
mov bx,[uchwyt]
mov cx,500         ; czytamy..
lea dx,[bufor]       ; do bufora
int 21h
ret
CzytPlik ENDP

Rysuj_linie PROC              ; ----------------- Rysowanie linii o koncach (p0, q0), (p1, q1) ------------------------
push di
mov ax,[p1]
sub ax,p0
mov [dex],ax      ; dex = p1-p0
mov ax,[q1]
sub ax,[q0]
mov [dey],ax      ; dey = q1-q0
cmp [dex],0       ; ---- sprawdzanie dex
jge dalej
mov ax,[dex]    ; gdy dex < 0
neg ax
mov [adx],ax    ; adx = |dex|
jmp spr_y
dalej:          ; gdy dex >= 0
mov ax,[dex]
mov [adx],ax      ; adx = |dex|
spr_y:
cmp [dey],0       ; ---- sprawdzanie dey
jge dalej2
mov ax,[dey]   ; gdy dey < 0
neg ax
mov [ady],ax   ; ady = |dey|
jmp nie_spr
dalej2:          ; gdy dey >= 0
mov ax,[dey]
mov [ady],ax      ; ady = |dey|
nie_spr:
mov ax,[p0]
mov [x],ax          ; x = p0
mov ax,[q0]
mov [y],ax          ; y = q0
mov [cp],0          ; cp = 0
cmp [dex],0       ; ----- pierwszy if -------
jle dalej3
mov [ix],1     ; if dex > 0 then ix = 1
jmp if_2     ; wyskocz z petli
dalej3:
mov [ix],-1    ; if dex <= 0 then ix = -1
mov [cp],-1    ;                  cp = -1
if_2:          ; ------ drugi if --------
cmp [dey],0
jle dalej4
mov [iy],1     ; if dey > 0 then iy = 1
jmp if_3     ; wyskocz z petli
dalej4:
mov [iy],-1    ; if dey <= 0 then iy = -1
if_3:          ; ------ trzeci if -------
mov ax,[adx]
cmp ax,[ady]
jl end_else
mov ax,[ady]   ; -------  gdy adx >= ady  ---------
add ax,ax    ;  ax = 2*ady
mov [dr],ax    ; dr = 2*ady
mov ax,[adx]
add ax,ax    ;  ax = 2*adx
mov bx,[dr]    ;  bx = dr
sub bx,ax    ;  bx = dr - 2*adx
mov [du],bx    ; du = dr - 2*adx
mov ax,[dr]
sub ax,[adx]   ;  ax = dr - adx
mov [pp],ax    ; pp = dr - adx
mov ax,[adx]
inc ax
mov cx,ax
petla_for1:
call RysujPunkt
mov ax,[x]
add ax,[ix]
mov [x],ax    ; x = x + ix
mov ax,[pp]
cmp ax,[cp]   ; cp nie jest -1
jle if_el
mov ax,[y]         ; if pp > cp
add ax,[iy]
mov [y],ax   ; y = y + iy
mov ax,[pp]
add ax,[du]
mov [pp],ax  ; pp = pp + du
loop petla_for1
pop di
ret
if_el:            ; if pp <= cp
mov ax,[pp]
add ax,[dr]
mov [pp],ax  ; pp = pp + dr
loop petla_for1
pop di
ret
end_else:       ; -------  gdy adx < ady  ---------
mov ax,[adx]
add ax,ax
mov [dr],ax    ; dr = 2*adx
mov ax,[ady]
add ax,ax    ;  ax = 2*ady
mov bx,[dr]    ;  bx = dr
sub bx,ax    ;  bx = dr - 2*ady
mov [du],bx    ; du = dr - 2*ady
mov ax,[dr]
sub ax,[ady]   ;  ax = dr - ady
mov [pp],ax    ; pp = dr - ady
mov ax,ady
inc ax
mov cx,ax
petla_for2:
call RysujPunkt
mov ax,[y]
add ax,[iy]
mov [y],ax    ; y = y + iy
mov ax,[pp]
cmp ax,[cp]
jle if_else
mov ax,[x]         ; if pp > cp
add ax,[ix]
mov [x],ax   ; x = x + ix
mov ax,[pp]
add ax,[du]
mov [pp],ax  ; pp = pp + du
loop petla_for2
pop di
ret
if_else:          ; if pp <= cp
mov ax,[pp]
add ax,[dr]
mov [pp],ax  ; pp = pp + dr
loop petla_for2
pop di
ret
Rysuj_linie ENDP

ZamkPlik PROC                 ; ------------------------------- Zamykanie pliku ---------------------------------------
mov ax,3e00h
mov bx,[uchwyt]
int 21h
jc Komunikat4
ret
ZamkPlik ENDP

Komunikat1:
lea dx,[error1]
mov ah,9h
int 21h
call Koniec

Komunikat2:
lea dx,[error2]
mov ah,9h
int 21h
call Koniec

Komunikat4:
lea dx,[error4]
mov ah,9h
int 21h
call Koniec

Komunikatx:
mov ax,0003h
int 10h
lea dx,[errorx]         ; mov dx,offset error
mov ah,9h
int 21h
call Koniec

Komunikaty:
mov ax,0003h
int 10h
lea dx,[errory]         ; mov dx,offset error
mov ah,9h
int 21h
call Koniec

Koniec PROC                   ; ------------------------------ Procedury koncowe --------------------------------------
; ---------- Czekanie na klawisz -------------

mov ax,0
int 16h

; ---------- Powrot do tr. tekstowego -------------

mov ax,0003h
int 10h

; ---------- Wyjscie do systemu -------------

mov ax,4c00h
int 21h
ret
Koniec ENDP

code1 ends
;..................................................

;................ Segment stosu ...................
stos1 segment stack
dw 1000 dup(?)
stos1 ends
;..................................................

END start