;;Przykład 8.7. Implementacja algorytmu Bresenhama

.MODEL tiny
.CODE
PIKS2  MACRO argx,argy,kolor2
 mov AX,argy ;;współrzędna Y
 SAL AX,8  ;;AX=AX*256
 mov CX,argy ;;320
 SAL CX,6  ;;CX=CX*64
 add AX,CX 	;;AX=(256+64)*y=320*y 
 mov	DI,argx	
 add	DI,AX
 mov	AL,kolor2	
 mov	BYTE PTR ES:[DI],AL	
		;;lub stosb
 ENDM
org 100h
	
Start	PROC
;;informacja o aktualnym trybie
;;monitora i o numerze stronicy
 mov	AX,0F00h
 int	10h  mov	tryb,AL 
 mov	stron,BH 
;;ustawienie trybu graficznego
 mov	AH,00h ;ustawienie trybu
 mov	AL,13h ;tryb graficzny 320x200, 256 kolorów, A0000
 int	10h
;; ustawienie segmentu bufora wideo
 mov	AX,0A000h	
 mov	ES,AX
;;zapełnienie ekranu kolorem białym (0Fh)
 mov	y,0
c1:	mov	x,0
c2:	PIKS2	x,y,0Fh
 inc	x
 cmp	x,320
 jb	c2
 inc	y
 cmp	y,200
 jb	c1

;; prosta 1
;;przekazywanie argumentów
 mov	AX,160	;;px1
 push	AX
 mov	AX,101	;;py1
 push	AX
 mov	AX,300	;;kx1
 push	AX
 mov	AX,110	;;ky1
 push	AX mov	AH,0
 mov	AL,0Ch	;;kol_lin1
 push	AX
 call	Bresen
 add	SP,10	;;=5*2
;;czekanie na spację
czek3:
 mov	ah,07h		;czekanie na znak
 int	21h
 cmp	AL,20h	;;spacja
 jne	czek3
;;powrót do trybu pierwotnego  mov	AH,00h	;ustawienie trybu
 mov	AL,tryb	;tryb	
 int	10h
 mov	AH,05h	;ustawienie stronicy	
 mov	AL,stron	;stronica	
 int	10h
;;zakończenie programu
 mov	ax,4C00h
 int	21h
Start	ENDP
;;;;;;;;;;;;;;;;;;;;;;;;
;; PODPROGRAM "BRESEN"
;;;;;;;;;;;;;;;;;;;;;;;;
Bresen PROC NEAR	
ARG	kol_lin:BYTE, ky:WORD, kx:WORD, py:WORD, px:WORD
 push	bp
 mov	bp,sp
;;jeśli |kx - px| >= |ky - py|, to przesuwamy się wzdłuż osi X, 
;;inaczej - wzdłuż osi Y
;;obliczenie różnicy bezwzględ¬nej |kx-px|
 mov	AX,kx
 mov	BX,px
;;obliczenie różnicy |kx-px|
 mov	AX,kx
 mov	BX,px
 sub	AX,BX
 jge	br1	;;kx>=px
;;kx<px
 neg	AX
br1:	
 mov	moddx,AX	; różnica bezwzględna  |kx-px|
;;obliczenie różnicy |ky-py|
 mov	AX,ky
 mov	BX,py
 sub	AX,BX
 jge	br2	;;ky>=py
;;ky<py
 neg	AX
br2:	
 mov	moddy,AX	; różnica bezwzględna  |ky-py|
;;przekazywanie argumentów
 mov	AX,px
 push	AX
 mov	AX,py
 push	AX
 mov	AX,kx
 push	AX
 mov	AX,ky
 push	AX
 mov	AH,0
 mov	AL,kol_lin
 push	AX
;;porównanie 
 mov	BX,moddy
 mov	AX,moddx
 cmp	AX,BX
 jge	br3	;;moddxx>=moddy
;;moddxx<moddy
 call	ProstaY
 jmp	br4
br3:	
 call	ProstaX
br4:
 add	SP,10	;;=5*2
;;
brkon:
 pop	bp
 ret
Bresen ENDP
	
;; PODPROGRAM "PROSTAX"
;;;;;;;;;;;;;;;;;;;;;;;
ProstaX	PROC	NEAR
ARG	kol_lin:BYTE, ky:WORD, kx:WORD, py:WORD, px:WORD
 push	bp
 mov	bp,sp
;;
 mov	AX,kx
 sub	AX,px
 mov	kpx,AX	;;kpx=kx-px
 sal	AX,1		;;AX=2*(kx-px)
 mov	kp2x,AX	;;kpx=2(kx-px)
 mov	AX,ky
 sub	AX,py
 mov	kpy,AX	;;kpy=ky-py
 sal	AX,1		;;AX=2*(ky-py)
 mov	kp2y,AX	;;kpy=2(ky-py)
;;
 mov	AX,px
 mov	x,AX
 mov	AX,py
 mov	y,AX
;;
 mov	AX,kpx	;;AX=kx-px
 neg	AX		;;AX=-(kx-px)
 mov	decyz,AX ;;decyz=-(kx-px)(początkowa wartość "D"= "decyz")
 mov	delt,0 ;;delt=0 (początkowa wartość "DD"="delt")
px30:
 mov	AX,decyz	;;AX=decyz
 add	AX,delt		;;AX=decyz+delt
 mov	decyz,AX		;;decyz=decyz+delt
 test	kpx,08000h  jnz	px310		;;kx<px
 jmp	px320		;;kx>=px
px310:
;;początek obliczenia nowego DD="delt"
 mov	AX,kp2y	;;AX=2(ky-py)
 test	kpy,08000h
 jnz	px3109	;;ky<py
 neg	AX		;;AX=-2*(ky-py)	
px3109:
 mov delt,AX ;;delt=+-2*(ky-py)
;;analiza "decyz"
 mov	AX,decyz	;;AX=decyz
 or	AX,AX
 jg	px3103	;;decyz>0
;;wybór wariantu sąsiada
 test	kpy,08000h
 jnz	px3101	;;ky<py
;;przypadek ky>=py
 inc	y	;;piksel niżej
 jmp	px3102
px3101:		
 dec	y	;;piksel wyżej
px3102:
;;przedłużenie obliczenia nowego DD="delt"
 mov	AX,kp2x ;;AX=2(kx-px)
 sub	delt,AX ;;delt=+-2*(ky-py)-2*(kx-px)
px3103:
 jmp px330
px320:		
;;kx>=px
;;początek obliczenia nowego DD="delt"
 mov	AX,kp2y	;;AX=2(ky-py)
 test	kpy,08000h
 jz	px3208	;;ky>=py
;;przypadek ky<py
 neg	AX ;;AX=-2*(ky-py)
px3208:
 mov	delt,AX ;;delt=+-2*(ky-py)
;;analiza "decyz"
 mov	AX,decyz	;;AX=decyz
 or	AX,AX
 jl	px3203	;;decyz<0
;;wybór wariantu sąsiada
 test	kpy,08000h
 jnz	px3101	;;ky<py
 inc	y	;;piksel niżej
 jmp	px3202
px3201:		;;ky<py
 dec	y	;;piksel wyżej

px3202:
;;przedłużenie obliczenia nowe-go DD="delt"
 mov	AX,kp2x ;;AX=2(kx-px)
 sub	delt,AX ;;delt=+-2*(ky-py)-2*(kx-px)
px3203:
 jmp px330
px330:		
;;wyświetlenie piksela w punk-cie x,y 
 PIKS2	x,y,kol_lin
;;następny punkt
 test	kpx,08000h
 jnz	px340		;;kx<px
;;przypadek kx>=px
 inc	x
 mov	AX,x
 cmp	AX,kx
 jg	pxkon
 jmp	px30
px340:
;;kx<px
 dec	x
 mov	AX,x
 cmp	AX,kx
 jl	pxkon
 jmp	px30
pxkon:
 pop	bp
 ret
ProstaX		ENDP
	
;;;;;;;;;;;;;;;;;;;;;;;;
;; PODPROGRAM "PROSTAY"
;;;;;;;;;;;;;;;;;;;;;;;;
ProstaY	PROC	NEAR
ARG	kol_lin:BYTE,ky:WORD, kx:WORD,py:WORD, px:WORD
 push	bp
 mov	bp,sp
;;
 mov	AX,kx
 sub	AX,px
 mov	kpx,AX	;;kpx=kx-px
 sal	AX,1		;;AX=2*(kx-px)
 mov	kp2x,AX	;;kpx=2(kx-px)
 mov	AX,ky
 sub	AX,py
 mov	kpy,AX	;;kpy=ky-py
 sal	AX,1		;;AX=2*(ky-py)
 mov	kp2y,AX	;;kpy=2(ky-py)
 mov	AX,px
 mov	x,AX
 mov	AX,py
 mov	y,AX
 mov	AX,kpy	;;AX=ky-py
 neg	AX		;;AX=-(ky-py)
mov	decyz,AX	;;decyz=-(ky-py)- początkowa wartość "D"="decyz"
 mov	delt,0	;;delt=0 - początkowa wartość "DD"="delt"
py30:	
 mov	AX,decyz	;;AX=decyz
 add	AX,delt ;;AX=decyz+delt
 mov	decyz,AX;;decyz=decyz+delt
;;wybór warianta "decyz"
 test	kpy,08000h
 jnz	py310		;;ky<py
 jmp	py320		;;ky>=py
py310:	
;;początek obliczenia nowego DD="delt"
 mov	AX,kp2x	;;AX=2(kx-px)
 test	kpx,08000h
 jnz	py3109	;;kx<px
 neg	AX	;;AX=-2*(kx-px)
py3109:
 mov	delt,AX ;;delt=-2*(kx-px)
;;analiza "decyz"
 mov	AX,decyz	;;AX=decyz
 or	AX,AX
 jg	py3103	;;decyz>0
;;wybór wariantu sąsiada
 test	kpx,08000h
 jnz	py3101 ;;kx<px
;;przypadek kx>=px
 inc	x ;;piksel z prawej strony
 jmp	py3102
py3101:		;;kx<px
 dec	x ;;piksel z lewej strony	

py3102:
;;przedłużenie obliczenia nowego DD="delt"
 mov	AX,kp2y	;;AX=2(ky-py)
 sub	delt,AX	;;delt=+-2*(kx-px)-2*(ky-py) py3103:
 jmp py330
py320:		
;;początek obliczenia nowego DD="delt"
 mov	AX,kp2x	;;AX=2(kx-px)
 test	kpx,08000h
 jz	py3208	;;kx>=px
 neg	AX	;;AX=-2*(kx-px)
py3208:
 mov	delt,AX ;;delt=+-2*(kx-px)
;;analiza "decyz"
 mov	AX,decyz	;;AX=decyz
 or	AX,AX
 jl	py3203	;;decyz<0
;;wybór wariantu sąsiada
 test	kpx,08000h
 jnz	py3101	;;kx<px
 inc	x	;;piksel z prawej strony
 jmp	py3202
py3201:	;;kx<px
 dec	x ;;piksel z lewej strony
py3202:
;;przedłużenie obliczenia nowe-go DD="delt"
 mov	AX,kp2y	;;AX=2(ky-py)
 sub	delt,AX	;;delt=+-2*(kx-px)-2*(ky-py)
py3203:
 jmp py330
py330:		
;;wyświetlenie piksela w punk-cie x,y 
 PIKS2	x,y,kol_lin
;;następny punkt
 test	kpy,08000h
 jnz	py340		;;ky<py
 inc	y
 mov	AX,y
 cmp	AX,ky
 jg	pykon
 jmp	py30
py340:
 dec	y
 mov	AX,y
 cmp	AX,ky
 jl	pykon
 jmp	py30
pykon:
 pop	bp
 ret
ProstaY	ENDP
	
.DATA
stron		DB	0
tryb		DB	3
x		DW	0
y		DW	0
moddx		DW	0	;; |kx-px| 
moddy		DW	0	;; |ky-py| 
decyz	DW	0	;; D 
delt	DW	0 ;; składnik DD
kpx	DW	0 ;; kx-px
kpy	DW	0 ;; ky-py
kp2x	DW	0 ;; 2(kx-px)
kp2y	DW	0 ;; 2(ky-py)
END Start	
	
