[comp.sys.amiga.tech] Fast Line Drawing Routine wanted

iyh@phoenix.pub.uu.oz.au (Ian Holsman) (11/22/90)

A while ago, John Schultz posted a fast line drawing routine to this
newsgroup, if anyone archived this, could they either e-mail it to me
or re-post it on the news.


Thanks

Ian Holsman

phoenix!iyh%eyrie@labtam.oz.au
labtam!eyrie!phoenix!iyh@munnari.oz.au

jcs@crash.cts.com (John Schultz) (11/24/90)

In <1990Nov21.213441.16244@phoenix.pub.uu.oz.au> iyh@phoenix.pub.uu.oz.au (Ian Holsman) writes:

>A while ago, John Schultz posted a fast line drawing routine to this
>newsgroup, if anyone archived this, could they either e-mail it to me
>or re-post it on the news.

  Here's my latest version. Enjoy:

; 68000 Line Drawer for the Amiga
; Created by John Schultz
; 23-Nov-90
; Kernel line algorithm from "68000 Assembly Language" by Krantz and Stanley

; On a 25MHz GVP, this code is faster than the blitter. For very long
; lines, the blitter is a little faster.
; There is a new "Symmetric double step" algorithm in "Graphics Gems"
; (edited by Andrew Glassner), that could be rewritten in assembly.
; Also, an idea I haven't tried, but think will be faster, is to keep
; a mask in a register, set bits in that mask until Y changes or until
; you run out of bits in that mask. At this point write out the mask
; to memory (the slowest operation). This should tremendously increase
; the speed of this algorithm (especially for horizontal, or near
; horizontal lines. Vertical or near vertical lines will not gain
; much (if any)).

; If you can make this go faster, please mail me your solution:
;   jcs@crash.cts.com
; Thanks.

	section line,code
	xdef	_drawline68k

PLANESIZE	equ	8000	; 320x200 screen (320/8bytes*200 = 8000 bytes)

_drawline68k
	movem.l	d2-d7/a2-a6,-(sp)

	movea.l	a1,a2
	lea	PLANESIZE(a2),a3
	lea	PLANESIZE(a3),a4
	lea	PLANESIZE(a4),a5

	andi.w	#15,d7		; 0..15 color
	add.w	d7,d7		;
	add.w	d7,d7		; (4 byte entries) get table index
	lea	linejmptable(pc),a6 ; table base
	movea.l	0(a6,d7.w),a6	; get jmp address


	move.w	d0,d4
	swap	d4
	clr.w	d4
	move.w	d1,d5
	swap	d5
	clr.w	d5

	sub.w	d0,d2
	move.w	d2,d0
	bpl.b	sk1_vecd
	neg.w	d0
sk1_vecd
	sub.w	d1,d3
	move.w	d3,d1
	bpl.b	sk2_vecd
	neg.w	d1
sk2_vecd
	cmp.w	d0,d1
	bgt.b	y_biggerd
	tst.w	d2
	bmi.b	sk3_vecd
	move.l	#$10000,d6
	bra.b	sk4_vecd
sk3_vecd
	move.l	#$ffff0000,d6
sk4_vecd
	swap	d3
	clr.w	d3
	asr.l	#2,d3
	tst.w	d0
	beq.b	divtrapd
	divs	d0,d3
	ext.l	d3
	asl.l	#2,d3
	move.l	d3,d7
	move.w	d0,d2
	bra.b	sk7_vecd
y_biggerd
	tst.w	d3
	bmi.b	sk5_vecd
	move.l	#$10000,d7
	bra.b	sk6_vecd
sk5_vecd
	move.l	#$ffff0000,d7
sk6_vecd
	swap	d2
	clr.w	d2
	asr.l	#2,d2
	tst.w	d1
	beq.b	divtrapd
	divs	d1,d2
	ext.l	d2
	asl.l	#2,d2
	move.l	d2,d6
	move.w	d1,d2
sk7_vecd
sk8_vecd
	subq.w	#1,d2	; setup dbra

	move.l	#$8000,a0	; .5 to add to round up
	move.l	#$8000,a1	; "                   "

	jsr	(a6)	; draw line

divtrapd
	movem.l	(sp)+,d2-d7/a2-a6
	rts


LINEPLOT	macro
lp0_vecd\@
	move.l	d4,d0
	move.l	d5,d1
	add.l	a0,d0
	add.l	a1,d1
	swap	d0
	swap	d1

	move.w	d1,d3	; save y
	add.w	d1,d1	; *2
	add.w	d1,d1	; *4
	add.w	d1,d3	; *5
	lsl.w	#3,d3	; *40
	move.w	d0,d1	; save x
	lsr.w	#3,d0	; get x byte offset
	add.w	d0,d3	; x offset + y offset
	andi.w	#7,d1	; get x bit set
	not.b	d1	; invert bits (left to right)

        \1.b	d1,0(a2,d3.w)	
        \2.b	d1,0(a3,d3.w)	
        \3.b	d1,0(a4,d3.w)	
        \4.b	d1,0(a5,d3.w)	

	add.l	d6,d4
	add.l	d7,d5
	dbra	d2,lp0_vecd\@
	rts
	
	endm

linecolor0:
	LINEPLOT	bclr,bclr,bclr,bclr
linecolor1:
	LINEPLOT	bset,bclr,bclr,bclr
linecolor2:
	LINEPLOT	bclr,bset,bclr,bclr
linecolor3:
	LINEPLOT	bset,bset,bclr,bclr
linecolor4:
	LINEPLOT	bclr,bclr,bset,bclr
linecolor5:
	LINEPLOT	bset,bclr,bset,bclr
linecolor6:
	LINEPLOT	bclr,bset,bset,bclr
linecolor7:
	LINEPLOT	bset,bset,bset,bclr
linecolor8:
	LINEPLOT	bclr,bclr,bclr,bset
linecolor9:
	LINEPLOT	bset,bclr,bclr,bset
linecolor10:
	LINEPLOT	bclr,bset,bclr,bset
linecolor11:
	LINEPLOT	bset,bset,bclr,bset
linecolor12:
	LINEPLOT	bclr,bclr,bset,bset
linecolor13:
	LINEPLOT	bset,bclr,bset,bset
linecolor14:
	LINEPLOT	bclr,bset,bset,bset
linecolor15:
	LINEPLOT	bset,bset,bset,bset

linejmptable:
	dc.l	linecolor0
	dc.l	linecolor1
	dc.l	linecolor2
	dc.l	linecolor3
	dc.l	linecolor4
	dc.l	linecolor5
	dc.l	linecolor6
	dc.l	linecolor7
	dc.l	linecolor8
	dc.l	linecolor9
	dc.l	linecolor10
	dc.l	linecolor11
	dc.l	linecolor12
	dc.l	linecolor13
	dc.l	linecolor14
	dc.l	linecolor15