*****************************************************************************
*** Filled Circle Routine		    (c) May 1991 by McDeal/D-TECT ***
*** Release in HACK-MAG Issue #5					  ***
*****************************************************************************

;This version has NO clipping! That's something you must include by yourself!
;I'm sure that this routine can be made much faster with several subroutines
;but I wanted to write a universal routine! If you've made a faster routine
;please send me a little letter...
;                                                        McDeal/D-TECT

;Use your joystick!!! But be careful cause of the missing clipping...

ExecBase	=  4
Forbid		= -132
Permit		= -138
OldOpenLibrary	= -408
CloseLibrary	= -414

PlaneWidth	= 40
PlaneHeight	= 256
PlaneLen	= PlaneWidth*PlaneHeight

***************************************************
*** MACRO Definition				***
***************************************************

WAITBLITT:	MACRO
.\@:		btst	#6,$02(a5)
		bne.s	.\@
		ENDM

WAITBLITT2:	MACRO
.\@:		btst	#6,$02-$54(a5)
		bne.s	.\@
		ENDM

***************************************************
*** Programm Start				***
***************************************************

		section	a,code

Start:		lea	$dff000,a5
		clr.l	0.w
		bsr.s	AllOff
		bsr	CalcTables
		bsr.s	SetPlanePtr
		bsr.s	StartCopper
		bsr	Main
		bsr.s	StopCopper
		bsr.s	AllOn
		moveq	#0,d0
		rts

***************************************************
*** All Off/On					***
***************************************************

AllOff:		move.l	(ExecBase).w,a6
		jsr	Forbid(a6)
		move.w	$1c(a5),d0
		bset	#15,d0
		move.w	d0,INTENASave
		move.w	#$7fff,$9a(a5)
		rts

AllOn:		move.l	(ExecBase).w,a6
		move.w	#$7fff,$9a(a5)
		move.w	INTENASave(pc),$9a(a5)
		jmp	Permit(a6)

INTENASave:	dc.w	0

***************************************************
*** Plane Ptr in Copperlist			***
***************************************************

SetPlanePtr:	lea	PlanePtr+2,a1
		move.l	#Plane1,d0
		move.w	d0,4(a1)
		swap	d0
		move.w	d0,(a1)
		rts

***************************************************
*** Copper Init					***
***************************************************

StartCopper:	move.w	$02(a5),d0
		bset	#15,d0
		move.w	d0,DMACONSave
		move.w	#$7fff,$96(a5)
		move.l	#NCList,$80(a5)
		move.w	$88(a5),d0
		move.w	#$83f0,$96(a5)
		rts

StopCopper:	move.l	(ExecBase).w,a6
		move.w	#$7fff,$96(a5)
		lea	GFXName(pc),a1
		jsr	OldOpenLibrary(a6)
		move.l	d0,a1
		move.l	38(a1),$80(a5)
		move.w	$88(a5),d0
		jsr	CloseLibrary(a6)
		move.w	DMACONSave(pc),$96(a5)
		rts

DMACONSave:	dc.w	0
GFXName:	dc.b	"graphics.library",0
		even

***************************************************
*** Calc Tables					***
***************************************************

CalcTables:	lea	FirstWordTab(pc),a0
		lea	LastWordTab(pc),a1
		lea	First(pc),a2
		lea	Last(pc),a3
		moveq	#0,d0
		move.w	#PlaneWidth*8-1,d7
.Loop1:		move.w	d0,d1
		and.w	#%1111,d1
		add.w	d1,d1
		move.w	(a2,d1.w),(a0)+
		move.w	(a3,d1.w),(a1)+

		move.w	d0,d1
		lsr.w	#4,d1
		add.w	d1,d1
		move.w	d1,(a0)+
		clr.w	(a1)+
		addq.w	#1,d0
		dbf	d7,.Loop1
		rts

First:		dc.w	$ffff,$7fff,$3fff,$1fff,$0fff,$07ff,$03ff,$01ff
		dc.w	$00ff,$007f,$003f,$001f,$000f,$0007,$0003,$0001

Last:		dc.w	$8000,$c000,$e000,$f000,$f800,$fc00,$fe00,$ff00
		dc.w	$ff80,$ffc0,$ffe0,$fff0,$fff8,$fffc,$fffe,$ffff

***************************************************
*** Hauptschleife				***
***************************************************

Main:		move.l	$04(a5),d0
		and.l	#$1ff00,d0
		cmp.l	#50*256,d0
		bne.s	Main

		move.w	#$444,$180(a5)
		bsr	ChangePlanes
		bsr	ClearPlanes
		bsr.s	FilledCircle
		bsr	JoyControl
		move.w	#$000,$180(a5)

		btst	#6,$bfe001
		bne.s	Main
		WAITBLITT
		rts

***************************************************
*** Filled Circle				***
***************************************************

FilledCircle:	move.l	WorkPlanes(pc),a0
		move.l	a0,a1
		move.l	a0,a2
		move.l	a0,a3
		move.w	XY(pc),d7		;X
		move.w	XY+2(pc),d1		;Y
		move.w	Radius(pc),d2		;Radius
		tst.w	d2
		beq	.Exit			;if Radius=0 -> exit
		lea	FirstWordTab(pc),a4
		lea	$54(a5),a5		;BLTDPTR in a5
		lea	LastWordTab(pc),a6

		mulu	#PlaneWidth,d1
		move.w	d2,d6
		mulu	#PlaneWidth,d6

		add.w	d1,a0
		sub.w	d6,a0

		add.w	d1,a1
		add.w	d6,a1

		add.w	d1,a2
		move.l	a2,a3

		moveq	#0,d0			;x
		move.w	d2,d1			;y

		moveq	#3,d3			;d=d3
		add.w	d2,d2			;2*radius
		sub.w	d2,d3			;d=3-(2*radius)

		WAITBLITT2			;Blitter Init
		move.l	#$01ff0000,$40-$54(a5)

.Loop:		cmp.w	d1,d0			;x>=y?
		bge.s	.DrawExit		;ja-> exit
		tst.w	d3			;d positive?
		bpl.s	.IncY			;ja-> x, y increasen and draw

.IncX:		bsr	.Draw2
		move.w	d0,d2			;save x
		add.w	d2,d2			;x*4
		add.w	d2,d2
		addq.w	#6,d2			;+6
		add.w	d2,d3			;d=4*x+6
		addq.w	#1,d0			;x=x+1
		lea	-PlaneWidth(a2),a2
		lea	PlaneWidth(a3),a3
		bra.s	.Loop

.IncY:		bsr.s	.Draw
		move.w	d0,d2			;x retten
		sub.w	d1,d2			;d2=x-y
		add.w	d2,d2			;d2*4
		add.w	d2,d2
		add.w	#10,d2			;d2=d2+10
		add.w	d2,d3			;d=d+d2
		addq.w	#1,d0			;x=x+1
		subq.w	#1,d1			;y=y-1
		lea	PlaneWidth(a0),a0
		lea	-PlaneWidth(a1),a1
		lea	-PlaneWidth(a2),a2
		lea	PlaneWidth(a3),a3
		bra.s	.Loop

.DrawExit:	bsr	.Draw
		lea	$dff000,a5
.Exit:		rts

*** Beginning of the draw routine ***

.Draw:		lea	FirstWordTab(pc),a4
		move.w	d7,d4			;save originX
		sub.w	d0,d4			;originX-X
		add.w	d4,d4
		add.w	d4,d4
		move.l	(a4,d4.w),d4
		move.w	d4,d5			;add to PlanePtr
		swap	d4			;first word

		move.w	d7,d2			;originX
		add.w	d0,d2			;originX+X
		add.w	d2,d2
		add.w	d2,d2
		move.w	2(a4,d2.w),d6
		move.w	(a6,d2.w),d2

		cmp.w	d5,d6			;first&last with same offset?
		bne.s	.OrInPlane		;no-> normal OR in plane

		eor.w	d4,d2			;exclusive OR with both
		not.w	d2			;NOT result
		or.w	d2,(a0,d6.w)		;OR in plane
		or.w	d2,(a1,d6.w)
		bra.s	.BlitLine

.OrInPlane:	or.w	d4,(a0,d5.w)		;OR first word in plane
		or.w	d4,(a1,d5.w)
		or.w	d2,(a0,d6.w)		;OR last word in plane
		or.w	d2,(a1,d6.w)

.BlitLine:	sub.w	d5,d6
		lsr.w	#1,d6
		subq.w	#1,d6
		ble.s	.Draw2
		or.w	#1*64,d6
		lea	2(a0,d5.w),a4
		WAITBLITT2
		move.l	a4,(a5)
		move.w	d6,$58-$54(a5)

		lea	2(a1,d5.w),a4
		WAITBLITT2
		move.l	a4,(a5)
		move.w	d6,$58-$54(a5)

*** The same with y again... ***

.Draw2:		move.w	d7,d4			;save OriginX
		sub.w	d1,d4			;OriginX-Y
		add.w	d4,d4
		add.w	d4,d4
		move.l	FirstWordTab(pc,d4.w),d4
		move.w	d4,d5			;add to PlanePtr
		swap	d4			;First Word

		move.w	d7,d2			;and again...
		add.w	d1,d2			;originX+Y
		add.w	d2,d2
		add.w	d2,d2
		move.w	FirstWordTab+2(pc,d2.w),d6
		move.w	(a6,d2.w),d2

		cmp.w	d5,d6			;first&last the same offset?
		bne.s	.OrInPlane2		;no-> normal OR in plane

		eor.w	d4,d2			;exclusive or with both
		not.w	d2			;NOT result
		or.w	d2,(a2,d6.w)		;and now the next plane
		or.w	d2,(a3,d6.w)
		bra.s	.BlitLine2

.OrInPlane2:	or.w	d4,(a2,d5.w)		;OR in Plane
		or.w	d4,(a3,d5.w)		;OR in Plane
		or.w	d2,(a2,d6.w)
		or.w	d2,(a3,d6.w)

.BlitLine2:	sub.w	d5,d6
		lsr.w	#1,d6
		subq.w	#1,d6
		ble.s	.Exit2
		or.w	#1*64,d6
		lea	2(a2,d5.w),a4
		WAITBLITT2
		move.l	a4,(a5)
		move.w	d6,$58-$54(a5)

		lea	2(a3,d5.w),a4
		WAITBLITT2
		move.l	a4,(a5)
		move.w	d6,$58-$54(a5)
.Exit2:		rts

FirstWordTab:	ds.l	PlaneWidth*8
LastWordTab:	ds.l	PlaneWidth*8

***************************************************
*** Clear Planes				***
***************************************************

ClearPlanes:	WAITBLITT
		move.l	#$01000000,$40(a5)
		move.w	#0,$66(a5)		;Clr is not allowed!!!
		move.l	WorkPlanes(pc),$54(a5)
		move.w	#PlaneHeight*64+PlaneWidth/2,$58(a5)
		rts

***************************************************
*** Change Planes				***
***************************************************

ChangePlanes:	lea	Planes(pc),a0
		movem.l	(a0),d0-d1
		exg	d0,d1
		movem.l	d0-d1,(a0)

		lea	PlanePtr+2,a0
		move.w	d1,4(a0)
		swap	d1
		move.w	d1,(a0)
		rts

Planes:		dc.l	Plane1
WorkPlanes:	dc.l	Plane2

***************************************************
*** Joy Control					***
***************************************************

JoyControl:	lea	Radius(pc),a0
		tst.b	$bfe001
		bmi.s	.NoFire
		addq.w	#4,a0
.NoFire:	movem.w	(a0),d0/d1
		move.w	$0c(a5),d2
		btst	#1,d2
		beq.s	.TstLeft
		cmp.w	#319,d0
		bge.s	.Vertical
		addq.w	#1,d0
		bra.s	.Vertical
.TstLeft:	btst	#9,d2
		beq.s	.Vertical
		tst.w	d0
		beq.s	.Vertical
		subq.w	#1,d0
.Vertical:	move.w	d2,d3
		lsr.w	#1,d3
		eor.w	d2,d3
		btst	#0,d3
		beq.s	.TstVorn
		addq.w	#1,d1
		bra.s	.Set
.TstVorn:	btst	#8,d3
		beq.s	.Set
		subq.w	#1,d1
.Set:		movem.w	d0/d1,(a0)
		and.w	#127,Radius
		rts

Radius:		dc.w	127,0
XY:		dc.w	160,128

***************************************************
*** Datas					***
***************************************************

		section	b,data_c

NCList:		dc.l	$01200000,$01220000,$01240000,$01260000
		dc.l	$01280000,$012a0000,$012c0000,$012e0000
		dc.l	$01300000,$01320000,$01340000,$01360000
		dc.l	$01380000,$013a0000,$013c0000,$013e0000

		dc.l	$008e2981,$009029c1,$00920038,$009400d0
		dc.l	$01020000,$01040000,$01080000,$010a0000
		dc.l	$01000200

PlanePtr:	dc.l	$00e00000,$00e20000
		dc.l	$01001200

		dc.l	$01800000,$01820f00
		dc.l	-2

***************************************************
*** BSS Data-Segment				***
***************************************************

		section	c,bss_c

Plane1:		ds.b	PlaneLen
Plane2:		ds.b	PlaneLen
