*************************************************************************
*									*
*                   Line Routine for one plane, by TIP			*
*			RELEASED IN HACK-MAG #7				*
*************************************************************************

; Internal Version: 1.01

; - assemble defs -------------------------------------------------------

DL_Width = 40
DL_Fill  = 0			;0: NOFILL 1:FILL

; - internal ------------------------------------------------------------

 ifeq DL_Fill
DL_MInterns = $ca
 else
DL_MInterns = $4a
 endc

; ------------- the routine itsself -------------------------------------
;Needs:
; a0    planept
; a6    $dff002
; d0/d1 x,y start pos
; d2/d3 x,y end   pos
; d4    Width of plane

;Kills:
; d0-d4/a0-a1 (+d5 in Fill Mode)

DrawLine:	cmp.w	d1,d3			;   drawing only from top to bottom is
		bge.s	.y1ly2			;   necessary for:
		exg	d0,d2			;   a: up-down differences (same koords)
		exg	d1,d3			;   b: blitter invert bit (only at top of line)

.y1ly2:		sub.w	d1,d3			;d3:yd

; here we could do an optimization with special shifts
; depending on the DL_Width value ... i know it, but please, let it be.

		mulu	d4,d1			;   use muls for neg y-vals
		add.l	d1,a0			;   please don't use add.w here!
		moveq	#0,d1			;d1:quant-counter
		sub.w	d0,d2			;d2:xd
		bge.s	.xdpos
		addq.w	#2,d1			;   set bit 1 of quant-counter (here it could be a moveq)
		neg.w	d2
.xdpos:		moveq	#$f,d4			;   d4 full cleaned (for later oktants move.b)
		and.w	d0,d4
	ifne	DL_Fill
		move.b	d4,d5			;d5:special fill bit
		not.b	d5
	endc
		lsr.w	#3,d0			;   yeah, on byte (necessary for bchg) ....
		add.w	d0,a0			;   ... blitter ands automagically
		ror.w	#4,d4			;d4:shift
		or.w	#$b00+DL_MInterns,d4	;   bltcon0-codes
		swap	d4
		cmp.w	d2,d3			;   which delta is the biggest?
		bge.s	.dygdx
		addq.w	#1,d1			;   set bit 0 of quant-counter
		exg	d2,d3			;   exchange xd with yd
.dygdx:		add.w	d2,d2			;d2:xd*2
		move.w	d2,d0			;d0:save for $52(a6)
		sub.w	d3,d0			;d0:xd*2-yd
		addx.w	d1,d1			;Bit0:sign-bit
		move.b	.oktants(pc,d1.w),d4	;   in low byte of d4 (upper byte cleaned above)
		swap	d2
		move.w	d0,d2
		sub.w	d3,d2			;d2:2*(xd-yd)
		moveq	#6,d1			;d1:shiftval(not necessary) + testval for the blitter
		lsl.w	d1,d3			;d3:BLTSIZE
		add.w	#$42,d3
		lea	$52-2(a6),a1		;a1:CUSTOM + $52

; WARNING:  if you use fastmem and an extreme DMA-Access (e.g.  6
; planes and copper), you should insert a tst.b (a6) here (for the
; shitty AGNUS-BUG).

.wb:		btst	d1,(a6)			;   waiting for the blitter ...
		bne.s	.wb
	ifne	DL_Fill
		bchg	d5,(a0)			;   inverting the first bit of line.
	endc
; ------------- Not necessary, should never be used. Only for testing purposes.
;		move.w	#$8000,$74-2(a6)
;		move.w	#-1,$44-2(a6)
;		move.w	#-1,$72-2(a6)
;		move.w	#DL_Width,$60-2(a6)
;		move.w	#DL_Width,$66-2(a6)
; -------------
		move.l	d4,$40-2(a6)		;   writing to the blitter regs as fast as possible.
		move.l	d2,$62-2(a6)
		move.l	a0,$48-2(a6)
		move.w	d0,(a1)+
		move.l	a0,(a1)+		;   shit-word buffer pt.
		move.w	d3,(a1)
		rts

; ------------- oktant-table --------------------------------------------

	ifne	DL_Fill
SML = 2
	else
SML = 0
	endc

.oktants:	dc.b	SML+1,SML+1+$40
		dc.b	SML+17,SML+17+$40
		dc.b	SML+9,SML+9+$40
		dc.b	SML+21,SML+21+$40

; ------------- optimized init-part -------------------------------------

; Needs:
; a6:co

; Kills:
; d0-d2

DL_Init:	addq.w	#2,a6
		moveq	#-1,d1
	ifgt	DL_Width-127
		move.w	#DL_Width,d0
	else
		moveq	#DL_Width,d0
	endc
		moveq	#6,d2
.wb:		btst	d2,(a6)
		bne.s	.wb
		move.w	d1,$44-2(a6)
		move.w	d1,$72-2(a6)
		move.w	#$8000,$74-2(a6)
		move.w	d0,$60-2(a6)
		move.w	d0,$66-2(a6)
		rts

; ------------- exit-part -----------------------------------------------

DL_Exit:	subq.w	#2,a6
		rts


		end
