;;Przykład 8.8. Implementacja algorytmu wypełnienia trójkąta
.MODEL small
.STACK 100h
.CODE
PIKS	MACRO	argx,argy,akolor
 push	ES
 mov	AX,0A000h
 mov	ES,AX	
 mov	AX,argy ;;współrzędna Y
 sal	AX,8	 ;;AX=AX*256
 mov	CX,argy ;;współrzędna Y
 sal	CX,6	 ;;CX=CX*64
 add	AX,CX;;AX=(256+64)*y=320*y 
 mov	DI,argx
 add	DI,AX
 mov	AL,akolor	
 mov	BYTE PTR ES:[DI],AL	
 pop	ES
 ENDM
GRANICA	MACRO	x1,y1,x2,y2
 mov	AX,x1
 push	AX
 mov	AX,y1
 push	AX
 mov	AX,x2
 push	AX
 mov	AX,y2
 push	AX
 call	BresenTabl
 add	SP,8	;;=4*2
 ENDM
ADRZNACZN	MACRO	argx,argy
 mov	BX,SEG tablZn
 mov	ES,BX	
 mov	BX,OFFSET tablZn	
 mov	AX,argy ;;współrzędna Y
 SAL	AX,5	;;AX=AX*32
 mov	CX,argy ;;współrzędna Y
 SAL	CX,3	 ;;CX=CX*8
 add	AX,CX	;;AX=(32+8)*y=40*y 
 add	BX,AX		;;[BX]=y*4	
 mov	AX,argx ;;współrzędna X
 SAR	AX,3	;;dzielenie "x" na 8
 add	BX,AX	 ;;plus cale bajty współrzędnej X
 mov	CX,argx ;;współrzędna X
 and	CX,07h ;;w CX reszta x/8
 inc	CL	;;x od 0, a CL musi być od 1
ENDM
ZAPZNACZN	MACRO	suf,argx,argy,aznaczn
 push	ES
 ADRZNACZN	argx,argy
 mov	AL,BYTE PTR ES:[BX]
 rcr	AL,CL		;;wysuwanie bitów przez CF
 mov	DI,aznaczn
 test	DI,01h
 jz	zap1&suf
 stc	;;ustawienie znacznika CF
 jmp	zap2&suf
zap1&suf:
 clc	;;zerowanie znacznika CF
zap2&suf:
 rcl	AL,CL	 ;;wsuwanie bitów przez CF
 mov	BYTE PTR ES:[BX],AL
 pop	ES
ENDM
CZYTZNACZN	MACRO	suf,argx,argy,aznaczn
 push	ES
 ADRZNACZN	argx,argy
 mov	AL,BYTE PTR ES:[BX]
 rcr	AL,CL	;;wysuwanie bitów przez CF
 jnc	czyt1&suf
 mov	aznaczn,1	;;ustawienie znacznika
 jmp	czyt2&suf
czyt1&suf:
 mov	aznaczn,0	;;zerowanie znacznika
czyt2&suf:
 pop	ES
ENDM
POROWN	MACRO	suf,tArg,aMin,aMax
;;porównanie tArg z aMin oraz aMax
 mov	AX,tArg
 sub	AX,aMax
 jge	porGE&suf	;; tArg>=aMax
 mov	AX,tArg
 sub	AX,aMin
 jge	porKon&suf	;; tArg>=aMin
 mov	AX,tArg
 mov	aMin,AX
 jmp	porKon&suf
porGE&suf:
 mov	AX,tArg
 mov	aMax,AX
porKon&suf:
ENDM
	
;; PROGRAM "TROJDEMO"
Trojdemo	PROC
 push DS
 pop ES ;ES:=DS
;; aktualny tryb monitora
 mov	AX,0F00h
 int	10h
 mov	tryb,AL 
 mov	stron,BH 
;; ustawienie trybu graficznego 13h
 mov	AH,00h ;ustawienie trybu
 mov	AL,13h	;tryb graficzny 320x200, 256 kolorów, A0000
 int	10h
;;ekran koloru 0Fh
 mov	y,0
c1:	mov	x,0
c2:	PIKS	x,y,0Fh
 inc	x
 cmp	x,320
 jb	c2
 inc	y
 cmp	y,200
 jb	c1
;;Rysowanie trójkąta
;;przekazywanie argumentów
 mov	AX,0		;;tx1
 push	AX
 mov	AX,0		;;ty1
 push	AX
 mov	AX,160	;;tx2
 push	AX
 mov	AX,150	;;ty2
 push	AX
 mov	AX,50		;;tx3
 push	AX
 mov	AX,120	;;ty3
 push	AX
 mov	AX,0Ah ;;kolor trójkąta, 0Ah -zielony, 0Ch -czerwony 
 push	AX
 call	Trojkat
 add	SP,14	;;=7*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
Trojdemo	ENDP

;; PODPROGRAM "Trojkat"
Trojkat	PROC	NEAR	
ARG	kolor:BYTE,ty3:WORD,tx3:WORD,\
ty2:WORD,\
tx2:WORD,ty1:WORD,tx1:WORD
 push	bp
 mov	bp,sp
;;zerowanie znaczników w "tablZn"
 push	ES
 mov	AX,SEG tablZn
 mov	ES,AX
 cld		;;DF=0
 mov	DI,OFFSET tablZn
 mov	AL,0
 mov	CX,8000	;;ilość powtórzeń
 rep	stosb		;;AL==>[ES:DI]
 pop	ES
;;granica od (x1,y1) do (x2,y2)
 GRANICA tx1,ty1,tx2,ty2
;;granica od (x2,y2) do (x3,y3)
 GRANICA tx2,ty2,tx3,ty3
;;granica od (x3,y3) do (x1,y1)
 GRANICA tx3,ty3,tx1,ty1
;;prostokąt
 mov	AX,tx1
 mov	minX,AX
 mov	maxX,AX
 mov	AX,ty1
 mov	minY,AX
 mov	maxY,AX
;;porównanie z tx2
 POROWN	1,tx2,minX,maxX
;;porównanie z ty2
 POROWN	2,ty2,minY,maxY
;;porównanie z tx3
 POROWN	3,tx3,minX,maxX
;;porównanie z ty3
 POROWN	4,ty3,minY,maxY
 mov	AX,minY
 mov	y,AX
trc1:	
 mov	AX,minX
 mov	x,AX
trc2:	
 CZYTZNACZN 1,x,y,znaczn
 test	znaczn,01h
 jnz	trc3
 inc	x
 mov	AX,maxX
 cmp	x,AX
 jg	trc3a	;;jeśli błąd
 jmp	trc2
trc3a: 
 jmp	trc7
trc3: 
;; punkt jest zaznaczony
 PIKS	x,y,0Bh	;;debug
 mov	AX,x
 mov	Xzlewa,AX	
 mov	AX,maxX
 mov	x,AX
trc4:	
 CZYTZNACZN	2,x,y,znaczn
 test	znaczn,01h
 jnz	trc5
 dec	x
 mov	AX,Xzlewa
 cmp	x,AX
 jg	trc4
trc5: 
;; punkt jest zaznaczony
 mov	AX,x
 mov	Xzprawa,AX	
 mov	AX,Xzlewa
 mov	x,AX
trc6:	
 PIKS	x,y,kolor
 inc	x
 mov	AX,Xzprawa
 cmp	x,AX
 jg	trc7
 jmp	trc6
trc7:
 inc	y
 mov	AX,maxY
 cmp	y,AX
 jg	trKon
 jmp	trc1
trKon:
 pop	bp
 ret
Trojkat	ENDP
;; PODPROGRAM "BresenTabl"
BresenTabl	PROC	NEAR	
ARG	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
 sub	AX,BX
 jge	br1	;;kx>=px
;;kx<px
 neg	AX
br1:	;;kx>=px
 mov	moddx,AX	; różnica bez-względna  |kx-px|
;;obliczenie różnicy bezwzględ-nej |ky-py|
 mov	AX,ky
 mov	BX,py
 sub	AX,BX
 jge	br2	;;ky>=py
;;ky<py
 neg	AX
br2:	;;ky>=py
 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
;;porównanie bezwzględną
 mov	BX,moddy
 mov	AX,moddx
 cmp	AX,BX
 jge	br3	;;moddxx>=moddy
;;moddxx<moddy
 call	PrYTabl
 jmp	br4
br3:	;;moddxx>=moddy
 call	PrXTabl
br4:
 add	SP,8	;;=4*2
;;;;;;;;;;;;;;;;;;;;;;;;
brkon:
 pop	bp
 ret
BresenTabl	ENDP

;;PODPROGRAM "PrXTabl"
PrXTabl	PROC	NEAR
ARG	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"
;;początek cyklu
px30:	
 mov	AX,decyz	;;AX=decyz
 add	AX,delt ;;AX=decyz+delt
 mov	decyz,AX	;;decyz=decyz+delt
;;wybór wariantu "decyz"
 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
 inc	y	;;piksel niżej
 jmp	px3102
px3101:	;;ky<py
 dec	y	;;piksel wyżej
px3102:
;;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)
px3103:
 jmp px330
px320:		
;;początek obliczenia nowego DD="delt"
 mov	AX,kp2y	;;AX=2(ky-py)
 test	kpy,08000h
 jz	px3208	;;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:		
;;zapisywanie znacznika w x,y 
 ZAPZNACZN	1,x,y,1
 PIKS	x,y,0Ch	;;debug
;;następny punkt
 test	kpx,08000h
 jnz	px340		;;kx<px
 inc	x
 mov	AX,x
 cmp	AX,kx
 jg	pxkon
 jmp	px30
px340:
 dec	x
 mov	AX,x
 cmp	AX,kx
 jl	pxkon
 jmp	px30
pxkon:
 pop	bp
 ret
PrXTabl	ENDP

;;;;;;PODPROGRAM "PrYTabl"
PrYTabl	PROC	NEAR
ARG	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ąt-kowa wartość "DD"="delt"
py30: 
 mov AX,decyz  ;;AX=decyz
 add AX,delt  ;;AX=decyz+delt
 mov decyz,AX  ;;decyz=decyz+delt
;;wybór wariantu "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
 inc x ;;piksel z prawej strony
 jmp py3102
py3101:  ;;kx<px
 dec x ;;piksel z lewej strony
py3102:
;;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)
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:  
;;zapisywanie znacznika w punk-cie x,y 
 ZAPZNACZN 2,x,y,1
 PIKS x,y,0Ch ;;debug
;;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
PrYTabl ENDP
.DATA
stron  DB 0
tryb  DB 3
tablZn DB 40 dup (200 dup (0)) ;;40=320 pikseli/8 bitów
minX  DW 0
maxX  DW 0
minY  DW 0
maxY  DW 0
Xzlewa DW 0
Xzprawa DW 0
znaczn DB 0
;;zmienne lokalne
moddx  DW 0
moddy  DW 0
x  DW 0
y  DW 0
decyz  DW 0
delt  DW 0
kpx  DW 0 ;;kpx=kx-px
kpy  DW 0 ;;kpy=ky-py
kp2x  DW 0 ;;kp2x=2(kx-px)
kp2y  DW 0 ;;kp2y=2(ky-py)
END Trojdemo
	

	
	

	

	
	
	
