;---------------SETLINE---routine begins--------------------------+
; ROUTINE SETLINE from BLUEBOOK OF ASSEMBLY ROUTINES FOR IBM PC & XT.
;         page 145
; FUNCTION: draws a line from (x1,y1) to (x2,y2) in the spec-
; ified color.  It uses BRESENHAM's algorithm.
;
; INPUT: Upon entry:
;	 x1 contains x-coordinate of starting point
;	 y1 contains y-coordinate of starting point
;	 x2 contains x-coordinate of end point
;	 y2 contains y-coordinate of end point
;	 color contains the color of the line
;
; OUTPUT: Just to the screen
;
; REGISTERS USED:  No registers are modified
;
; SEGMENTS REFERENCED:  Upon entry ES must point to video RAM at
; B8000h and DS must point to a data segment used by the point-
; plotting routine (see SETPT or XORPT above)
;
; ROUTINES CALLED:  SETPT (can substitute XORPT)
;
; SPECIAL NOTES: No bounds checking is performed.  The user must make
; sure that the coordinates and the color are in their proper ranges.
; That is, x1 & x2 must be between 0 and 319; y1 & y2 must be between
; 0 and 199, and color must be between 0 and 3.
;
; ROUTINE TO DRAW A LINE
;
setline	proc	far
	push	bx		; save registers
	push 	cx 		;
	push 	dx
	push	si
	push	di
	push	ax
;
; set up x and y updates
	mov	si,1		;start with positive 1 for x update
	mov	di,1		;start with positive 1 for y update
;
; find |y2-y1|
	mov	dx,y2		;get y2
	sub	dx,y1		;subtract y2
	jge	storey		;skip if y2-y1 is non-negative
	neg	di		;move in negative y direction
	neg	dx		;absolute value of y2-y1
storey:
	mov	deldy,di		;store y update for diagonal moves
;
; find |x1-x2|
	mov	cx,x2		;get x2
	sub	cx,x1		;subtract x2
	jge	storex		;skip if x2-x1 is non-negative
	neg	si		;move in negative x direction
	neg	cx		;absolute value of x2-x1
storex:
	mov	deldx,si	;store x update for diagonal moves
;
; sort |y2-y1| and |x2-x1|
	cmp	cx,dx		; compare dels with delp
	jge	setdiag		; skip if straight moves in y direction
	mov	si,0		; if straight=vertical, kill & update
	xchg	cx,dx		;   & exchange differences
	jmp	storedelsxy
;
setdiag:
	mov	di,0		; if straight = horizontal, kill y update
;
; store dels, delp, delsx and delsy
storedelsxy:
	mov	dels,cx		; change in straight direction
	mov	delp,dx		; change in perpendicular to straight
	mov	delsx,si	; x update in straight direction
	mov	delsy,di	; y update in straight direction
;
; get initial values for x and y
	mov	si,x1		; x coordinate
	mov	di,y1		; y coordinate
;
; compute initial value and increments for error function
	mov	ax,delp
	sal	ax,1		; 2 * delp
	mov	delse,ax	; change if straight move
;
	sub	ax,cx		; 2*delp - dels
	mov	bx,ax		; initial value
;
	sub	ax,cx		; 2*delp - 2*dels
	mov	delde,ax	; change if diagonal move
;
; adjust count
	inc	cx
;
; get the color
	mov	dx,color	; get the color
;
; main loop structure
lineloop:
	call 	setpt		; plot the point
	cmp	bx,0		; determine if straight or diagonal move
	jge	diagonal
;
; case for straight move
straight:
	add	si,delsx	; update x
	add	di,delsy	; update y
	add	bx,delse	; update error term
	loop	lineloop	; next point
	jmp	lineexit
;
; case for diagonal move
diagonal:
	add	si,deldx	; update x
	add	di,deldy	; update y
	add	bx,delde	; update error term
	loop	lineloop	; next point
;
lineexit:
	pop	ax		; restore registers
	pop	di
	pop	si
	pop	dx
	pop	cx
	pop	bx
	ret			; return
setline	endp
;---------------SETLINE---routine ends---------------------------+
