*
*	Line drawing demo, with clipping
*

	INCLUDE	"e:\includes\amiga\hardware\custom.i"

	SECTION	Code

_linedemo	lea	$dff000,a0

	move.w	#%0101001000000000,bplcon0(a0)
	move.w	#0,bplcon1(a0)
	move.w	#0,bpl1mod(a0)
	move.w	#0,bpl2mod(a0)
	move.w	#$0038,ddfstrt(a0)
	move.w	#$00d0,ddfstop(a0)
	move.w	#$2c81,diwstrt(a0)
	move.w	#$f4c1,diwstop(a0)

	lea	copperlist,a1
	move.l	#bitplanes,d0
	moveq	#5-1,d1
bpl_loop	move.w	d0,6(a1)	low part of bitplane address
	swap	d0
	move.w	d0,2(a1)	high part of bitplane address
	swap	d0
	add.l	#8000,d0	address of next bitplane
	lea	8(a1),a1	next copper instruction
	dbra	d1,bpl_loop

	move.l	#copperlist,cop1lc(a0)
	move.w	copjmp1(a0),d0

	lea	color(a0),a1
	move.w	#0,(a1)+
	moveq	#32-2,d0
palette_loop	bsr	random
	and.w	#$fff,d7
	move.w	d7,(a1)+
	dbra	d0,palette_loop

	move.w	#%0000000000100000,dmacon(a0)	disable sprite dma
	move.w	#%1000001110000000,dmacon(a0)	enable bpls/copper dma
*
lineloop	bsr	random
	and.w	#$1ff,d7
	move.w	d7,d0	x1
	bsr	random
	and.w	#$1ff,d7
	move.w	d7,d1	y1
	bsr	random
	and.w	#$1ff,d7
	move.w	d7,d2	x2
	bsr	random
	and.w	#$1ff,d7
	move.w	d7,d3	y2

	bsr	_lineclip
	bne.s	nextline

	bsr	random
	and.w	#$f,d7
	move.w	d7,d4	colour
	bsr	_drawline
nextline	bra	lineloop	continue forever

*
****************************************************************************
*	LINECLIP.S	Line clip routine
****************************************************************************
*	On entry/exit	d0/d1          x/y coords of first vertex
*		d2/d3          x/y coords of second vertex
****************************************************************************
*	On exit	zero flag set = line visible & clipped
*		zero flag clear = line not visible
****************************************************************************
*	d0-d6 used
****************************************************************************

horiz_crossa	MACRO
	move.w	d2,d4          copy of x2
	move.w	d6,d5          copy of yval
	sub.w	d3,d5          (yval-y2)
	sub.w	d0,d2          (x2-x1)
	muls	d5,d2
	sub.w	d1,d3          (y2-y1)
	divs	d3,d2
	add.w	d4,d2          new x
	move.w	d6,d3          new y = clipping value
	ENDM

vert_crossa	MACRO
	move.w	d3,d4          copy of y2
	move.w	d6,d5          copy of xval
	sub.w	d2,d5          (xval-x2)
	sub.w	d1,d3          (y2-y1)
	muls	d5,d3
	sub.w	d0,d2          (x2-x1)
	divs	d2,d3
	add.w	d4,d3          new y
	move.w	d6,d2          new x = clipping value
	ENDM

horiz_crossb	MACRO
	move.w	d0,d4          copy of x1
	move.w	d6,d5          copy of yval
	sub.w	d1,d5          (yval-y1)
	sub.w	d2,d0          (x1-x2)
	muls	d5,d0
	sub.w	d3,d1          (y1-y2)
	divs	d1,d0
	add.w	d4,d0          new x
	move.w	d6,d1          new y = clipping value
	ENDM
*
vert_crossb	MACRO
	move.w	d1,d4          copy of y1
	move.w	d6,d5          copy of xval
	sub.w	d0,d5          (xval-x1)
	sub.w	d3,d1          (y1-y2)
	muls	d5,d1
	sub.w	d2,d0          (x1-x2)
	divs	d0,d1
	add.w	d4,d1          new y
	move.w	d6,d0          new x = clipping value
	ENDM

clip	MACRO
	cmp.w	d6,d\2
	b\4t.s	.outside\@
*	-------------------------------------------------------------
.inside\@	cmp.w	d6,d\3
	b\5e.s	.outofclip\@
	cmp.w	d6,d\2
	beq	.offscreen
	\1a	               change d2/d3
	bra.s	.outofclip\@
*	-------------------------------------------------------------
.outside\@	cmp.w	d6,d\3
	b\4e	.offscreen
	\1b	               change d0/d1
*	-------------------------------------------------------------
.outofclip\@
	ENDM

_lineclip	move.w	#199,d6
	clip	horiz_cross,1,3,g,l
	move.w	#0,d6
	clip	horiz_cross,1,3,l,g
	move.w	#0,d6
	clip	vert_cross,0,2,l,g
	move.w	#319,d6
	clip	vert_cross,0,2,g,l
*---------------------------------------------------------------------------
.clipdone	clr.w	d6             set zero flag
	rts
*---------------------------------------------------------------------------
.offscreen	moveq	#1,d6         clear zero flag
	rts

*
****************************************************************************
*(Amiga)	DRAWLINE.S	Line drawing routine
****************************************************************************
*	assembly call	bsr _drawline
*		d0/d1          x/y coords of first vertex
*		d2/d3          x/y coords of second vertex
*		d4.w           colour number
****************************************************************************
*	uses d0-d6	a6
****************************************************************************


plot	MACRO	bit,offset
	IF	\1=0
	and.w	d0,\2(a6)
	ENDIF
	IF	\1<>0
	or.w	d1,\2(a6)
	ENDIF
	ENDM

colour_loops	MACRO	no planes,total of bits,bit1,bit2, etc
	cmp.w	d5,d6          	which component is biggest
	bgt	y_greater\@
*---------------------------------------------------------------------------
x_greater\@	cmp.w	#0,d5          	are x coords equal
	bne.s	dividea\@
	clr.l	d6             	if so, increment = 0
	bra.s	x_loop\@
*	-------------------------------------------------------------
dividea\@	swap	d6
	divu	d5,d6
	bvc	x_loop\@
	move.w	#65535,d6      	put 1
*---------------------------------------------------------------------------
x_loop\@	plot	\3             	no offset for (An) mode
	plot	\4,8000
	plot	\5,8000*2
	plot	\6,8000*3
	add.w	d6,d3
	bcc.s	changebit\@
	add.w	d2,a6          	change row
changebit\@
	IF	\2=0             	zero's only
	ror.w	#1,d0
	dbcc	d5,x_loop\@
	addq.w	#2,a6
	dbcs	d5,x_loop\@
	ENDIF
	IF	\2<>0
	IF	\1-\2<>0          	zero's and...
	ror.w	#1,d0
	ENDIF
	ror.w	#1,d1          	...ones
	dbcs	d5,x_loop\@
	addq.w	#2,a6
	dbcc	d5,x_loop\@
	ENDIF
*---------------------------------------------------------------------------
	rts
*
y_greater\@	cmp.w	#0,d6          	are y coords equal
	bne.s	divideb\@
	clr.l	d5             	if so, increment = 0
	bra.s	y_loop\@
*	-------------------------------------------------------------
divideb\@	swap	d5             	y>x so result must be fraction
	divu	d6,d5
*---------------------------------------------------------------------------
y_loop\@	plot	\3             	no offset for (An) mode
	plot	\4,8000
	plot	\5,8000*2
	plot	\6,8000*3
	add.w	d5,d3
	bcc.s	changerow\@
	IF	\2=0             	zero's only
	ror.w	#1,d0
	add.w	d2,a6
	dbcc	d6,y_loop\@
	addq.w	#2,a6
	dbcs	d6,y_loop\@
	rts
	ENDIF
	IF	\2<>0
	IF	\1-\2<>0
	ror.w	#1,d0          	zero's and...
	ENDIF
	ror.w	#1,d1          	...ones
	ENDIF
changerow\@	add.w	d2,a6          	always
	dbcs	d6,y_loop\@
	addq.w	#2,a6
	dbcc	d6,y_loop\@
*---------------------------------------------------------------------------
	rts
	ENDM
*
_drawline	cmp.w	d0,d2          	compare x coords
	bgt.s	get_diffs
	exg	d0,d2
	exg	d1,d3
*	-------------------------------------------------------------
get_diffs	clr.l	d5
	move.w	d2,d5
	sub.w	d0,d5          	x1-x0
	clr.l	d6
	move.w	d3,d6
	sub.w	d1,d6          	y1-y0
*	-------------------------------------------------------------
	bpl.s	downwards
upwards	neg.w	d6             	make +ve
	move.w	#-40,d2
	bra.s	find_start
downwards	move.w	#40,d2
*---------------------------------------------------------------------------
find_start	lea	bitplanes,a6	bpls address
	muls	#40,d1      	start byte of required row
	add.l	d1,a6          	absolute address of 1st byte
	ext.l	d0             	get x0 in long
	ror.l	#4,d0          	word no.
	asl.w	#1,d0          	bytes
	add.w	d0,a6          	add word no on row
	clr.w	d0
	rol.l	#4,d0
	neg.w	d0
	add.w	#15,d0         	bit no of byte
	clr.w	d1
	bset.l	d0,d1          	bit pattern
	move.w	d1,d0
	not.w	d0             	inverse bit pattern
	clr.w	d3             	clear accumulator

	lsl.w	#2,d4
	move.l	colour_routine(pc,d4.w),a0
	jmp	(a0)

colour_routine	DC.L	low_colour0,low_colour1,low_colour2,low_colour3,low_colour4
	DC.L	low_colour5,low_colour6,low_colour7,low_colour8,low_colour9
	DC.L	low_colour10,low_colour11,low_colour12,low_colour13,low_colour14
	DC.L	low_colour15

low_colour0	colour_loops	4,0,0,0,0,0
low_colour1	colour_loops	4,1,1,0,0,0
low_colour2	colour_loops	4,1,0,1,0,0
low_colour3	colour_loops	4,2,1,1,0,0
low_colour4	colour_loops	4,1,0,0,1,0
low_colour5	colour_loops	4,2,1,0,1,0
low_colour6	colour_loops	4,2,0,1,1,0
low_colour7	colour_loops	4,3,1,1,1,0
low_colour8	colour_loops	4,1,0,0,0,1
low_colour9	colour_loops	4,2,1,0,0,1
low_colour10	colour_loops	4,2,0,1,0,1
low_colour11	colour_loops	4,3,1,1,0,1
low_colour12	colour_loops	4,2,0,0,1,1
low_colour13	colour_loops	4,3,1,0,1,1
low_colour14	colour_loops	4,3,0,1,1,1
low_colour15	colour_loops	4,4,1,1,1,1

*
random	move.w	seed,d7
	mulu	#125,d7
	divu	#65521,d7
	swap	d7
	move.w	d7,seed
	rts

seed	DC.W	1001

	SECTION	Data_c

cmove	MACRO	;address,data
	DC.W	(\1)&$fffe,(\2)
	ENDM

cend	MACRO
	DC.W	$ffff,$fffe
	ENDM

copperlist	cmove	bplpt,0
	cmove	bplpt+2,0
	cmove	bplpt+4,0
	cmove	bplpt+6,0
	cmove	bplpt+8,0
	cmove	bplpt+10,0
	cmove	bplpt+12,0
	cmove	bplpt+14,0
	cmove	bplpt+16,0
	cmove	bplpt+18,0
	cend

	SECTION	Bss_c

bitplanes	DS.B	8000*5

	END
