*******************************************************************************
*  Non-Rotated Ellipse Algo  - normal version-                                *
*  (C)oded by TIBO/ZENITH      August '92				      *
*  Published through FREEDOM CRACK                                            *
*******************************************************************************

width	=	320
height	=	256



	section	ellipse,code

d:

	movem.l	d1-d7/a0-a6,-(a7)       ;save registers
	move.l	4.w,a6
	jsr	-132(a6)
	lea	$dff000,a6
	lea	d(pc),a5
; --- inits ---
	bsr.w	make_mulstab
	bsr.b	start

waitraster:
	move.l	$4(a6),d0
	and.l	#$1ff00,d0
	cmp.l	#$06100,d0
	bne.s	waitraster

	btst	#10,$16(a6)
	beq.B	waitraster

	move.w	#$f00,$180(a6)
	bsr.w	draw_ellipse

	clr.w	$180(a6)

	btst	#6,$bfe001
	bne.b	waitraster

exit:
	bsr.w	stop			; restore system
	move.l	4.w,a6
	jsr	-138(a6)
	movem.l	(a7)+,d1-d7/a0-a6
	moveq	#0,d0
	rts
;-----------------------------------------------------------------------
start:			;old save and restore system routine... 
	tst.b	$06(a6)
	bne.s	start

	move.w 	$02(a6),dmacon-d(a5)
	move.w 	$1c(a6),intenar-d(a5)
	move.l 	#$80008000,d0
	or.l 	d0,dmacon-d(a5)	
	not.l 	d0
	move.w 	d0,$96(a6)
	move.w 	d0,$9a(a6)
	move.w 	#$87c0,$96(a6)
	move.b 	#$87,$bfd100
	lea 	copper_list,a0
	move.l 	a0,$84(a6)
	move.w 	d0,$8a(a6)

	lea 	$140(a6),a0				;Kills Sprites
	moveq 	#[$180-$140]/4-1,d0
	moveq	#0,d1
.clear_sprites:	
	move.l 	d1,(a0)+
	dbf 	d0,.clear_sprites

	move.l	#plane,d0			; put plane address in CL
	lea	bp_ellips+2,a0
	move.w	d0,4(a0)
	swap	d0
	move.w	d0,(a0)
	rts

;-----------------------------------------------------------------------

stop:	tst.b	$06(a6)
	bne.b	stop

	move.w 	#$7fff,$96(a6)
	move.w	#$7fff,$9a(a6)
	move.w 	dmacon-d(a5),$96(a6)
	move.w 	intenar-d(a5),$9a(a6)
	rts

dmacon:dc.w 0
intenar:dc.w 0
;----------------------------------------------------------------------------
make_mulstab:
	lea	mulstab(pc),a0
	moveq	#0,d0
	moveq	#[width/8],d2			; plane width
	move.w	#height-1,d1			; whole 256 screen lines
.loop:
	move.w	d0,(a0)+
	add.w	d2,d0
	dbf	d1,.loop
	rts

mulstab:	blk.w	height,0
;----------------------------------------------------------------------------
; Beware there's no clipping, so Amax=160 and Bmax=128 !!!
a:dc.w	150
b:dc.w	120

ac:dc.w	0	; These are buffers for squares
bc:dc.w	0

draw_ellipse:
; Let's do the first inits
	move.w	a(pc),d0
	move.w	b(pc),d1
	moveq	#0,d5			; x
	move.w	d1,d6			; y
	add.w	d6,d6			; y is multiplied by 2 for saving time
					; while plotting (we need an EVEN value
					; for the tabs...)

	muls	d0,d0			; a^2
	move.w	d0,ac-d(a5)		; store square

	move.w	d1,d2
	add.w	d2,d2			; 2b
	move.w	d2,d3
	subq.w	#1,d2
	muls	d0,d2			; a^2(2b-1)
	move.l	d2,a0			; AA

	add.w	d3,d3
	add.w	d3,d3			; 8b
	moveq	#8,d2
	sub.w	d3,d2
	muls	d0,d2			; 8(1-b)*a^2
	move.l	d2,a3			; FF

	move.w	d1,d7
	muls	d1,d1
	move.w	d1,bc-d(a5)
	add.l	d1,d1			; 2b^2
	move.l	d1,a1			; BB
	move.l	d1,d4
	add.l	d1,d4
	add.l	d1,d4			; 6b^2
	add.l	d4,d4
	move.l	d4,a2			; EE=12b^2

	add.w	d7,d7
	neg.w	d7
	muls	d0,d7			; -2b*a^2
	add.l	d1,d7
	add.l	d7,d7
	add.l	d0,d7			; DD=4(b^2-a^2*b)+a^2
	
	add.l	d0,d0			; 2a^2
	move.l	d0,d2
	asl.l	#2,d2			; 8a^2
	move.l	d1,d3
	asl.l	#2,d3			; 8b^2

	lea	plane,a6
	lea	mulstab(pc),a5
	lea	save_coords(pc),a4

.first_test:
	tst.l	d7
	bmi.b	.first_neg
.first_pos:
	add.l	a3,d7			; DD:=DD+FF
	add.l	d2,a3			; FF:=FF+8a^2
	subq.w	#2,d6			; y-1
	sub.l	d0,a0			; AA:=AA-2a^2

.first_neg:
	add.l	a2,d7			; DD:=DD+EE
	add.l	d3,a2			; EE:=EE+8b^2
	addq.w	#1,d5			; x+1
	add.l	d1,a1			; BB:=BB+2b^2

; from now we use the symetry to draw 4 points

	movem.w	d5/d6,(a4)
	add.w	#width/2,d5		; center X and Y
	add.w	#height,d6		; remember we use Y*2
	move.w	(a5,d6.w),d6
	move.w	d5,d4
	not.w	d5
	lsr.w	#3,d4
	movem.w	d4/d5,4(a4)		; used later
	add.w	d6,d4
	bset	d5,(a6,d4.w)		; (x,y)

	move.w	(a4),d5
	neg.w	d5
	add.w	#width/2,d5
	move.w	d5,d4
	not.w	d5
	lsr.w	#3,d4
	add.w	d6,d4
	bset	d5,(a6,d4.w)		; (-x,y)
	sub.w	d6,d4

	move.w	2(a4),d6
	neg.w	d6
	add.w	#height,d6
	move.w	(a5,d6.w),d6
	add.w	d6,d4
	bset	d5,(a6,d4.w)		; (-x,-y)

	movem.w	4(a4),d4/d5
	add.w	d6,d4
	bset	d5,(a6,d4.w)		; (x,-y)

	movem.w	(a4),d5/d6

	cmp.l	a1,a0
	bgt.w	.first_test

.first_end:
; second part of the drawing routine,so we NEED new inits...
	sub.l	d1,a2			; EE:=EE-4b^2
	sub.l	d1,a2
	add.l	d0,a3			; FF:=FF+4a^2
	add.l	d0,a3

	move.w	d6,d7
	asr.w	#1,d7
	muls	d7,d7
	sub.w	d6,d7
	addq.w	#1,d7			; (y^2-2y+1)	
	muls	ac(pc),d7		; a^2(  ...   )

	move.w	d5,d4
	muls	d4,d4
	add.w	d5,d4
	muls	bc(pc),d4
	asl.l	#2,d4
	moveq	#0,d5
	move.w	bc(pc),d5
	add.l	d5,d4			; b^2(4x^2+4x+1)

	muls	ac(pc),d5
	sub.l	d5,d7
	asl.l	#2,d7
	add.l	d4,d7			; finished with DD !!!

	movem.w	(a4),d5/d6		; get back x and y

; As we no longer need A0/A1 we use them in order to avoid d(Ax) op codes
; while drawing the points -> we earn a little speed

.second_test:
	tst.l	d7
	bge.b	.second_pos
.second_neg:
	add.l	a2,d7			; DD:=DD+EE
	add.l	d3,a2			; EE:=EE+8b^2
	addq.w	#1,d5			; x+1
.second_pos:
	add.l	a3,d7			; DD:=DD+FF
	add.l	d2,a3			; FF:=FF+8a^2
	subq.w	#2,d6			; y-1

	move.w	d5,a0
	move.w	d6,a1
	add.w	#width/2,d5
	add.w	#height,d6
	move.w	(a5,d6.w),d6
	move.w	d5,d4
	not.w	d5
	lsr.w	#3,d4
	movem.w	d4/d5,(a4)		; used later
	add.w	d6,d4
	bset	d5,(a6,d4.w)		; (x,y)

	move.w	a0,d5
	neg.w	d5
	add.w	#height/2,d5
	move.w	d5,d4
	not.w	d5
	lsr.w	#3,d4
	add.w	d6,d4
	bset	d5,(a6,d4.w)		; (-x,y)
	sub.w	d6,d4

	move.w	a1,d6
	neg.w	d6
	add.w	#height,d6
	move.w	(a5,d6.w),d6
	add.w	d6,d4
	bset	d5,(a6,d4.w)		; (-x,-y)

	movem.w	(a4),d4/d5
	add.w	d6,d4
	bset	d5,(a6,d4.w)		; (x,-y)

	move.w	a0,d5
	move.w	a1,d6
	
	tst.w	d6
	bgt.b	.second_test

	lea	d(pc),a5
	lea	$dff000,a6
	rts

save_coords:
 dc.l	0,0	;1rst long for d5/d6 et 2nd for saving sum time... 
;------------------------------------------------------------------------------
f:

	section copper_list,data_c

copper_list:
 dc.w	$8e,$2c81,$90,$2cc1,$92,$38,$94,$d0
 dc.w	$100,$1200,$102,0,$104,0,$108,0,$10a,0
bp_ellips:
 dc.w	$e0,0,$e2,0
;;; dc.w	$180,0
 dc.w	$182,$fff
 dc.l	-2

	section plane,data_c

plane:	blk.b	width*height,0
end
