
				cseg

				public	 _sini		;sin( ang ); 
				public	 _cosi		;cos( ang );
				public	 _mult		;mult( x1, x2 );
				public	 _divi		;divi( x1, x2 );
				public	 _distance	;distance( x, y, z );

				public	_pixle		; pixcolor( color, x1, y1 );
									; WORD color, x1, y2
									; Draws one pixle at x1, y1

				public	_fill		; fill( bit, x1, y1, x2, y2, color );
									; APTR *bit : pointer to bitmap
									; WORD x1, y1, Top Left Corner
									; WORD x2, y2, Bottom Left Corner
									; WORD color

				public	_line		; line( color, x1, y1, x2, y2 )
									; WORD color
									; WORD x1, y1, x2, y2 : endpoints

				dseg

offset1			ds.l	1
offset2			ds.l	1
width			ds.w	1
bltsize			ds.w	1
fillcolor		ds.w	1
env1			ds.l	16

				; external
				public	 _rp  ; This Raster Port controls line() and pixle().

sines		dc.w $0000, $0065, $00c9, $012d, $0191, $01f5, $0259, $02bc
			dc.w $031f, $0381, $03e3, $0444, $04a5, $0505, $0564, $05c2
			dc.w $061f, $067c, $06d7, $0732, $078b, $07e3, $083a, $088f
			dc.w $08e4, $0937, $0988, $09d8, $0a26, $0a73, $0abf, $0b08
			dc.w $0b50, $0b97, $0bdb, $0c1e, $0c5e, $0c9d, $0cda, $0d15
			dc.w $0d4e, $0d85, $0db9, $0dec, $0e1c, $0e4b, $0e77, $0ea1
			dc.w $0ec8, $0eee, $0f11, $0f31, $0f50, $0f6c, $0f85, $0f9c
			dc.w $0fb1, $0fc4, $0fd4, $0fe1, $0fec, $0ff5, $0ffb, $0fff
			dc.w $1000

epsilon			equ		1   ; How close to resove square root in distance()

				;BitMap struct
.BytesPerRow	equ		0
.Rows			equ		2
.Flags			equ		4
.Depth			equ		5
.pad			equ		6
.Planes			equ		8

				;struct TmpRas
.RasPtr			equ		0
.Size			equ		4

				;struct RastPort
.Layer			equ		$0
.BitMap			equ		$4
.AreaPtrn		equ		$8
.TmpRas			equ		$c
.AreaInfo		equ		$10
.GelsInfo		equ		$14
.Potinp			equ		$16
.Mask			equ		$18
.FgPen			equ		$19
.BgPen			equ		$1a
.AOlPen			equ		$1b

JOY0DAT			equ			$00a
JOY1DAT			equ			$00c
POT0DAT			equ			$012
POT1DAT			equ			$014
POTINP			equ			$016
POTGO			equ			$034

DMACONR			equ			$002
BBUSY			equ			$6
DMACON 			equ			$096
BLT_NASTY		equ			$8400
BLT_UNNASTY		equ			$0400
BLTCON0			equ			$040
BLTCON1			equ			$042
BLTAFWM			equ			$044
BLTALWM			equ			$046
BLTCPTH			equ			$048
BLTCPTL			equ			$04a
BLTBPTH			equ			$04c
BLTBPTL			equ			$04e
BLTAPTH			equ			$050
BLTAPTL			equ			$052
BLTDPTH			equ			$054
BLTDPTL			equ			$056
BLTSIZE			equ			$058
BLTCMOD			equ			$060
BLTBMOD			equ			$062
BLTAMOD			equ			$064
BLTDMOD			equ			$066
BLTCDAT			equ			$070
BLTBDAT			equ			$072
BLTADAT			equ			$074
INTENA			equ			$06a
INTENAR			equ			$01c

COLOR00			equ			$180


			cseg

_sini		move.w  4(a7),d0        Get range argument
			move.w  d0, d1
			move.w  d0, d2
			andi.w	#$007f, d0
			btst	#6, d1
			beq		sini1
			neg.w	d0
			addi.w	#$80, d0
sini1		lsl.w	#1, d0
			lea		sines, a2
			move.w	(a2,d0.w),d0
			btst	#7, d1
			beq		sini2
			neg.w	d0
sini2		rts

_cosi		move.w  4(a7),d0        Get range argument
			addi.w	#$0040, d0
			move.w	d0,-(a7)
			jsr		_sini
			lea		2(a7), a7
			rts

_mult		move.w  4(a7), d0
			muls	6(a7), d0
			moveq	#12, d1
			asr.l	   d1, d0
			rts

_divi		movem.w  4(a7), d0/d1
			move.w  d0, d3
			tst.w	d1
			beq		divi3
			moveq	#1, d2
			tst.w	d0
			bgt		divi1
			neg.w	d0
			neg.w	d2
divi1		tst.w	d1
			bgt		divi2
			neg.w	d1
			neg.w	d2
divi2		asr.w	#3, d0
			cmp.w	d1, d0
			blt		divi4
			move.w	#$7fff, d0
			tst.w	d2
			bgt		divi3
			move.w	#$8000, d0
divi3		rts
divi4		moveq	#12, d2
			move.w  d3, d0
			ext.l	d0
			lsl.l	d2, d0
			divs	6(a7), d0
			rts

_distance
		move.w  4(a7),d0
		asr.w	#1, d0
		muls	d0, d0
		move.l	d0, d2
		move.w  6(a7),d0
		asr.w	#1, d0
		muls	d0, d0
		add.l	d0, d2
		move.w  8(a7),d0
		asr.w	#1, d0
		muls	d0, d0
		add.l	d0, d2
		and.l	#$7fffffff, d2
		move.w	#epsilon, d3
		move.w	#$3000, d0
		cmp.l	#$01000000, d2
		bgt		distance1
		move.w	#$0300, d0
		cmp.l	#$00010000, d2
		bgt		distance1
		move.w	#$0030, d0
		cmp.l	#$00000100, d2
		bgt		distance1
		move.w	#$0003, d0
		tst.l	d2
		bgt		distance1
		moveq	#$0001, d0
		bra		distance2
distance1
		move.w	d0, d1
		move.l	d2, d0
		divu	d1, d0
		add.w	d1, d0
		lsr.w	#1, d0
		sub.w	d0, d1
		cmp.w	d3, d1
		bgt		distance1
		neg.w	d1
		cmp.w	d3, d1
		bgt		distance1
		tst.w	d0
		bgt		distance2
		moveq	#$0001, d0
distance2
		rts
_pixle
			movem.l	d4-d7/a0/a1/a5/a6, env1
			movem.w	4(a7), d0-d2
			lea		$dff000, a0				; a0 always points to blitter chip
			movea.l	_rp,  a1
			movea.l	.BitMap(a1), a2			; a2 always points to BitMap struct
			move.w d2, d3
			move.w	d1, d7
			mulu	.BytesPerRow(a2), d7
			move.w	d0, d4
			lsr.w	#4, d4
			lsl.w	#1, d4
			add.w	d4, d7
			ext.l	d7						; d7 holds the byte offset
			move.w	d0, d4
			andi.w	#$f, d4
			move.w	#$8000, d5
			lsr.w	d4, d5
			move.w	d5, d6					; d5 hold mask to OR a one
			not.w	d6						; d6 hold mask to AND a zero
			move.b	.Depth(a2), d0			; Merge tmp area to color planes.
			ext.w	d0
			subq.w	#1, d0
			clr.w	d1
pixl61		move.w	d1, d2
			lsl.w	#2, d2
			movea.l	.Planes(a2, d2.w),  a3
			add.l	d7, a3
			btst	d1, d3					; d3 holds the color
			beq		pixl62
			or.w	d5, (a3)
			bra		pixl63
pixl62		and.w	d6, (a3)
pixl63		addq.w	#1, d1
			dbra	d0, pixl61
			movem.l	env1, d4-d7/a0/a1/a5/a6		; Exit with    error code in d0
			rts


_fill
			movem.l	d4-d7/a0-a1, env1
			movea.l	4(a7), a2				; a2 always points to BitMap struct
			lea		$dff000, a0				; a0 always points to blitter chip
			movem.w	8(a7),d1-d5
			exg	d2, d3
			move.b	d5,   fillcolor
			move.w	d4, d5
			sub.w	d3, d5
			ble		fill99
			lsr.w	#    4, d1
			lsr.w	#    4, d2
			lsl.w	#    1, d1
			lsl.w	#    1, d2
			move.w	d2, d5
			sub.w	d1, d5
			addq.w	#2, d5
			move.w	d5, width
			move.w	d4, d6
			sub.w	d3, d6
			addq.w	#1, d6
			lsr.w	#1, d5
			lsl.w	#6, d6
			or.w	d6, d5
			move.w	d5, bltsize
			move.w	.BytesPerRow(a2), d6
			mulu	d6, d4
			add.w	d2, d4
			move.l	d4, offset1			; Bottom right of fill area
			mulu	d6, d3
			add.w	d1, d3
			move.l	d3, offset2			; Top left of fill area
			move.b	.Depth(a2), d0		; Merge tmp area to color planes.
			ext.w	d0
			tst.w	d0
			ble		fill99
			cmpi.w	#6, d0
			bgt		fill99
			subq.w	#1, d0
			clr.w	d1
			move.w	.BytesPerRow(a2), d2
			sub.w	width, d2
			moveq	#-1, d3
			move.w	bltsize, d7
fill60		btst	#BBUSY, DMACONR(a0)
			bne		fill60
			move.l	d3, BLTAFWM(a0)
			move.w	d3, BLTBDAT(a0)
			move.w	d2, BLTDMOD(a0)
fill61		move.w	d1, d2
			lsl.w	#2, d2
			move.l	.Planes(a2, d2.w),  d4
			add.l	offset2, d4
			btst	d1, fillcolor
			beq		fill62
			move.l	#$01ff0000, d6
			bra		fill63
fill62		move.l	#$01000000, d6
fill63		addq.w	#1, d1
fill64		btst	#BBUSY, DMACONR(a0)
			bne		fill64
			move.l	d6, BLTCON0(a0)
			move.l	d4, BLTDPTH(a0)
			move.w	d7, BLTSIZE(a0)
			dbra	d0, fill61
fill99		movem.l	env1, d4-d7/a0-a1
			rts

_line		movem.l	d4-d7/a0-a1, env1		; Save environment
			lea		$dff000, a0				; a0 holds the custom chip base
			movea.l	_rp,  a1
			move.w	4(a7), d4
			move.b	d4, fillcolor				; Save color
			movem.w	6(a7),d0-d3				; Load x1, y1, x2, y2
			exg		d0, d2
			exg		d1, d3
			movea.l	.BitMap(a1), a2			; a2 holds the BitMap pointer
			moveq   #$f, d4
			and.w   d2, d4					; Starting shift point
			sub.w	d3, d1
			mulu	.BytesPerRow(a2), d3	; d3 holds vertical offset
			sub.w	d2, d0
			blt		lineleft				; Branch if line leftward
			tst.w	d1
			blt		linerightup				; Branch if line upward
			cmp.w	d0, d1
			bge		lineright1				; Branch if slope > 45
			moveq	#$11, d7
			bra		line1
lineright1	moveq	#$1, d7
			exg		d1, d0					; Reverse delta x & y
			bra		line1
linerightup	neg.w	d1						; Make d1 positive
			cmp.w	d0, d1
			bge		lineright2				; Branch if slope > 45
			moveq	#$19, d7				; Set Octant bits
			bra		line1
lineright2	moveq	#$5, d7					; Set Octant bits
			exg		d1, d0					; Reverse delta x & y
			bra		line1
lineleft	neg.w	d0
			tst.w	d1
			blt		lineleftup				; Branch if line upward
			cmp.w	d0, d1
			bge		lineleft1				; Branch if slope > 45
			moveq	#$15, d7				; Set Octant bits
			bra		line1
lineleft1	moveq	#$9, d7					; Set Octant bits
			exg		d1, d0					; Reverse delta x & y
			bra		line1
lineleftup	neg.w	d1						; Make d1 positive
			cmp.w	d0, d1
			bge		lineleft2				; Branch if slope > 45
			moveq	#$1d, d7				; Set Octant bits
			bra		line1
lineleft2	moveq	#$d, d7					; Set Octant bits
			exg		d1, d0					; Reverse delta x & y
line1		add.w	d1, d1
			asr.w	#3, d2
			ext.l	d2
			add.l	d2, d3
			move.w	d1, d2
			sub.w	d0, d2
			bge		line2					; Branch if line SIGN bit zero
			ori.w	#$40, d7
line2		move.w	d7, d5
			movea.w	d2, a3
line3		btst	#BBUSY, DMACONR(a0)
			bne		line3					; Wait for blitter to be free
			move.w	(a2),   BLTCMOD(a0)		; Load C Modulo
			move.w	d1,     BLTBMOD(a0)		; Load B Modulo
			move.w	d2, d1
			sub.w	d0, d1
			move.w	d1,     BLTAMOD(a0)		; Load A Modulo
			moveq	#-1, d1
			move.l	d1,     BLTAFWM(a0)		; Set mask to 1's
			move.w	#$8000, BLTADAT(a0)		; Set mask for line bit
			move.w	d1,     BLTBDAT(a0)		; Set mask to 1's - no pattern
			addq.w	#1, d0					; d0 holds y count
			asl.w	#6, d0					; Pack y count with
			addq.w	#2, d0					;   x count =2 for bltsize
			move.w	d4, d2
			swap	d4
			asr.l	#4, d4
			ori.w	#$b00, d4				; d4 holds BLTCON0 word
			swap	d5
			move.w	d4, d5
			swap	d5						; d5 holds BLTCON0/1 long word
			clr.w	d1
			move.b	.Depth(a2), d2			; Number of planes
			lea		.Planes(a2), a2			; Pointer to first plane
lineloop	move.l	(a2)+, d7				; Get next plane
			swap	d5
			btst.b	d1, fillcolor				; Test next color bit
			beq		lineclear
			move.b	#$fa, d5				; Set minterm for 1's write
			bra		line4
lineclear	move.b	#$0a, d5				; Set minterm for 0's write
line4		swap	d5
			add.l	d3, d7					; Add offset to plane pointer
line5		btst	#BBUSY, DMACONR(a0)
			bne		line5					; Wait for blitter to be free
			move.l	d5, BLTCON0(a0)			; Load control register
			move.w	a3, BLTAPTL(a0)			; Load pointer registers
			move.l	d7, BLTCPTH(a0)
			move.l	d7, BLTDPTH(a0)
			move.w	d0, BLTSIZE(a0)			; Load size and start blitter
			addq.w	#1, d1
			cmp.b	d1, d2
			bne		lineloop
			movem.l	env1, d4-d7/a0-a1		; Return enivornment
			rts

			end

Geodesic Publications                      Visual Aural Animations
                               or          PO Box 4898
                                           Arcata, CA 95521
(916) 629-2514                             (707) 822-4800



