	SECTION		chipMeMory,data_c	
							;BY BLAINE EVANS
							;1 ERITH WAY
							;PONTYBODKIN
							;NR MOLD
							;CLWYD
							;CH7 4TR
							;TEL O352-771673
	opt	c-,d+

Height			equ	256
Width			equ	80
Depth			equ	2

ScreenSize		equ	Height*Width

LineHeight		equ	16
LineWidth		equ	1
LineDepth		equ	2

	Move.l	4.w,a6			;FIND EXEC BASE
	Lea	gfxlib(pc),a1		;lOAD GRAPHICS lIBRARY IN A1
	Moveq	#$00,d0			;VERSION 0
	Jsr	-552(a6)		;OPEN lIBRARY
	Move.l	d0,_gfxBase		;STORE D0 (GFX ADDRESS )
	Beq	Nolib_exit		;ElSE EXIT
	Bsr	Foreground_addresses	;BRANCH TO FOREGROUND ADDRESSES
	Bsr	Init
	Move.l	_gfxBase,a0		;lOAD ADDRESS OF GRAPHICS lIB IN A0
	Move.l	50(a0),Oldcop		;STORE CURRENT COPPER,ETC TO RETRIEVE lATER
S
	Move.l	#Newcop,50(a0)		;POINT TO OUR COPPERlIST

Wait					;WAIT lOOP
	Cmp.b	#255,$dff006		;VERTICAl BlANKING GAP 
	Bne.s	Wait			;
;	Move.w	#$fff,$dff180		;REMOVE TO MEASURE RASTER TIME
	Bsr	DoubleBuffer
	Bsr	BlitClear
	Bsr	Position
	Bsr	GetXY
;	Move.w	#$000,$dff180		;REMOVE TO MEASURE RASTER TIME
	Btst	#$6,$bfe001		;QUIT lEFT MOUSE PRESSED
	Bne.s	Wait
Ended					;ElSE lOOP TO WAIT
	Move.l	_gfxBase,a0		;lOAD GRAPHICS lIB ADDRESS IN A0
	Move.l	oldcop,50(a0)		;RESTORE OlD COPPER TO RETURN TO EDITTER
NoMem_exit	
	Move.l	4.w,a6			;FIND EXEC BASE
	Move.l	_gfxBase,a1		;lOAD GRAPHICS BASE IN A1
	Jsr	-414(a6)		;ClOSE lIBRARY
Nolib_exit
	Rts				;RETURN TO EDITER
Foreground_addresses			;START OF FOREGROUND DATA
	Move.l	#Foreground,d0
	Move.w	d0,Bpl0ptl		;lOW WORD IN BIT PlANE 0 lOW
	Swap	d0				
	Move.w	d0,Bpl0pth		;HIGH WORD IN BIT PlANE 0 HIGH
	Swap	d0
	Add.l	#ScreenSize,d0
	Move.w	d0,Bpl1ptl		;lOW WORD IN BIT PlANE 1 lOW
	Swap	d0				
	Move.w	d0,Bpl1pth		;HIGH WORD IN BIT PlANE 1 HIGH
	Swap	d0
	Rts
Init
	Rts	
DoubleBuffer
	Add.w	#1,FrameCount			; Alternate every frame
	Cmp.w	#2,FrameCount
	Beq	NextFrame
	Move.l	#Foreground,d0			; pointer to bitplanes
	Move.l	#Foreground_2,d1		; pointer to blit to
	Bsr	InsertPlanes
	Rts
NextFrame
	Move.w	#0,FrameCount
	Move.l	#Foreground_2,d0		; pointer to bitplanes
	Move.l	#Foreground,d1			; pointer to blit to
	Bsr	InsertPlanes
	Rts
InsertPlanes
	Move.l	d1,ScreenPointer	; Save address to do work on
	Move.w	d0,Bpl0ptl		;lOW WORD IN BIT PlANE 0 lOW
	Swap	d0				
	Move.w	d0,Bpl0pth		;HIGH WORD IN BIT PlANE 0 HIGH
	Swap	d0
	Add.l	#ScreenSize,d0
	Move.w	d0,Bpl1ptl		;lOW WORD IN BIT PlANE 1 lOW
	Swap	d0				
	Move.w	d0,Bpl1pth		;HIGH WORD IN BIT PlANE 1 HIGH
	Swap	d0
	Rts
BlitClear
	Lea	$dff000,a5			; custom Base
	Move.l	ScreenPointer,a1
	Move.w	#(LineDepth)-1,d7		; no of planes -1
Clear_Loop
	Bsr	Clear
	Add.l	#ScreenSize,a1			; next plane
	DBra	d7,Clear_Loop
	Rts
Clear
	Bsr	WBlit				;
	Move.l	#$01000000,$40(a5)		;Bltcon0 Clear
	Move.w	#$0000,$66(a5)			;Bltdmod Skip No Bytes
	Move.l	a1,$54(a5)			;Bltdpth Set Dest
	Move.l	#-1,$44(a5)			;Bltafwm Use All Bits
	Move.w	#Height*64+(Width/2),$58(a5)	;Bltsize
	Rts
Position
	Move.l	a5,-(sp)
	Bsr	Rotate
	Move.l	(sp)+,a5

	Move.l	#200,d0			; x orogin
	Move.l	#100,d1			; y orogin
	
	Add.w	X_Rot,d0
	Add.w	Y_Rot,d1
	Bsr	BoundCheck
	Move.l	#A,a0	
	Move.w	d0,0(a0)		; save X
	Move.w	d1,2(a0)		; save Y
	
	Move.l	#200,d0			; x orogin
	Move.l	#200,d1			; y orogin
	Add.w	X_Rot,d0
	Add.w	Y_Rot,d1
	Bsr	BoundCheck
	Move.l	#B,a0			; save X
	Move.w	d0,0(a0)		; save Y
	Move.w	d1,2(a0)
	
	Rts
BoundCheck				; is within screen boundaries
	Cmp.w	#0,d0
	Bne.s	UpOk
	Move.w	#0,d0			; x < 0
UpOk
	Cmp.w	#255,d0			; x > 255
	Bne.s	DownOk
	Move.w	#255,d0
DownOk
	Cmp.w	#0,d1			; y < 0
	Bne.s	LeftOk
	Move.w	#0,d1
LeftOk
	Cmp.w	#640,d1			; y > 640
	Bne.s	RightOk
	Move.w	#640,d1
RightOk
	Rts
GetXY
	Lea	Connections(pc),a4	; address of connections
	Move.w	#ConSize,d6		; no.of connections
SizeLoop	
	Moveq.l	#0,d0			; Clear work registers
	Moveq.l	#0,d1
	Moveq.l	#0,d2
	Moveq.l	#0,d3
	Move.l	(a4)+,a0
	Move.l	(a4)+,a1

	Move.w	(a0)+,d0		; x1=d0
	Move.w	(a0)+,d1		; y1=d1
	Move.w	(a1)+,d2		; x2=d2
	Move.w	(a1)+,d3		; y2=d3
	Bsr	Line
	Dbra	d6,SizeLoop
	Rts
Octant_table
	Dc.B	1,17,9,21,5,25,13,29	; line only
	Even

Line
	Lea	$dff000,a5		; custoM Base
	Move.l	ScreenPointer,a0	; start Address of screen
	Move.l	#Width,a1		; width of screen
	Move.l	a1,d4		 
	Mulu.w	d1,d4			; Multiply y1 By width
	Moveq	#-$10,d5		; no leading chars
	And.w	d0,d5			; BottoM four Bits Masked froM x1
	Lsr.w	#3,d5			; remainder divided By 8
	Add.w	d5,d4			; y1*width+X1/8
	Add.l	a0,d4			; +start of Bitplane

	Moveq.l	#0,d5			; clear work register
	Sub.w	d1,d3			; y2-y1 d3=Delta y
	Roxl.b	d5			; shift leading char froM delta y
	Tst.w	d3			; restore n-flag
	Bge.s	Y2gy1			; when dy=+ve,goto y2gy1
	Neg.w	d3			; invert if not +ve
Y2gy1
	Sub.w	d0,d2			; x2-x1=delta X
	Roxl.b	d5			; Move leading char forM delta X
	Tst.w	d2			; restore n flag
	Bge.s	X2gx1			; when dx=+ve,goto x2gx1
	Neg.w	d2			; invert if not +ve
X2gx1
	Move.w	d3,d1			; delta y
	Sub.w	d2,d1			; deltaY-deltaX
	Bge.s	Dygdx			; when dy>dx,goto dygdx
	Exg	d2,d3			; sMaller delta in d2
Dygdx
	Roxl.b	d5			; d5=result of 3 coMparisons
	Move.b	Octant_table(pc,d5),d5	; Matching octants
	Add.w	d2,d2			; sMaller delta * 2

	Move.w	d2,SDelta_2		; store
	Sub.w	d3,d2			; 2*sMaller delta-larger delta
	Bge.s	Signn1			; when 2*sd > l.delta
	Or.b	#$40,d5			; sign flag set
Signn1
	Move.w	d2,SDelta_2_LDelta	; store 
	Sub.w	d3,d2			; 2*s.delta-2*large delta
	Move.w	d2,SDelta_2_LDelta_2	; store
	And.w	#$000f,d0		; BottoM 4 Bits froM X1
	Ror.w	#4,d0			; to START0-3
	Or.w	#$0Bca,d0		; USEx and lFx Bits  set
	lsl.w	#6,d3			; length * 64
	Addq	#2,d3			; plus (Width=2)

	Move.w	#(LineDepth)-1,d7	; no of planes -1
Draw_loop
	Bsr	Draw
	Add.l	#ScreenSize,d4		; next plane
	DBra	d7,Draw_loop
	Rts
Draw
	Bsr	WBlit
	Move.w	SDelta_2,$62(a5)	;BltBmod
	Move.w	SDelta_2_LDelta,$52(a5)	;BltAptl
	Move.w	SDelta_2_LDelta_2,$64(a5)	;BltAmod
	Move.w	#$8000,$74(a5)		;BltAdat
	Move.w	#$ffff,$72(a5)		;BltBdat
	Move.w	#$ffff,$44(a5)		;Bltafwm
	Move.w	d0,$40(a5)		;Bltcon0
	Move.w	d5,$42(a5)		;Bltcon1
	Move.l	d4,$48(a5)		;BltCpth
	Move.l	d4,$54(a5)		;BltDpth
	Move.w	a1,$60(a5)		;BltCmod
	Move.w	a1,$66(a5)		;BltDmod
	Move.w	d3,$58(a5)		;Bltsize
	Rts
WBlit
	Btst	#14,$2(a5)
	Bne.s	WBlit
	Rts

Rotate
	Move.w	Z_Angle,d0		; angle of rotation about Z
	Jsr	Trig			; get the Sine & CoSine
	Move.w	d1,Z_Sin		; store these
	Move.w	d2,Z_Cos
	Move.w	Y_Angle,d0		; do same for Y angle
	Jsr	Trig
	Move.w	d1,Y_Sin
	Move.w	d2,Y_Cos
	Move.w	X_Angle,d0		; and x angle
	Jsr	Trig
	Move.w	d1,X_Sin
	Move.w	d2,X_Cos

	Lea	wx,a0			; a0->start of x ord list
	Lea	wy,a1			; a1->start of y ord list
	Lea	wz,a2			; a2->start of z ord list
	Lea	X_Rot,a3		; a3->start of x rotated list
	Lea	Y_Rot,a4		; a4->start of y rotated list
	Lea	Z_Rot,a5		; a5->start of z rotated list
	Move.w	numpoints,d0		; d0=num of points to rotate
rloop	Move.w	Z_Sin,d1		; d1=
	Move.w	Z_Cos,d2
	Move.w	(a0),d3
	Muls.w	d3,d2
	Move.w	(a1),d3
	Muls.w	d3,d1
	sub.l	d1,d2
	lsr.l	#8,d2
	lsr.l	#6,d2
	Move.w	d2,d5
	Move.w	Z_Sin,d1
	Move.w	Z_Cos,d2
	Move.w	(a0)+,d3
	Muls.w	d3,d1
	Move.w	(a1)+,d3
	Muls.w	d3,d2
	Add.l	d1,d2
	lsr.l	#8,d2
	lsr.l	#6,d2
	Move.w	d2,d6
	Move.w	Y_Sin,d1
	Move.w	Y_Cos,d2
	Move.w	(a2),d3
	Muls.w	d3,d2
	Move.w	d5,d3
	Muls.w	d3,d1
	Sub.l	d1,d2
	Lsr.l	#8,d2
	Lsr.l	#6,d2
	Move.w	d2,d7
	Move.w	Y_Sin,d1
	Move.w	Y_Cos,d2
	Move.w	(a2)+,d3
	Muls.w	d3,d1
	Move.w	d5,d3
	Muls.w	d3,d2
	Add.l	d1,d2
	Lsr.l	#8,d2
	Lsr.l	#6,d2
	Move.w	d2,d5
	Move.w	X_Sin,d1
	Move.w	X_Cos,d2
	Move.w	d6,d4	
	Move.w	d6,d3
	Muls.w	d3,d2
	Move.w	d7,d3
	Muls.w	d3,d1
	Sub.l	d1,d2
	Lsr.l	#8,d2
	Lsr.l	#6,d2
	Move.w	d2,d6
	Move.w	X_Sin,d1
	Move.w	X_Cos,d2
	Move.w	d4,d3
	Muls.w	d3,d1
	Move.w	d7,d3
	Muls.w	d3,d2
	Add.l	d1,d2
	Lsr.l	#8,d2
	Lsr.l	#6,d2
	Move.w	d2,d7
	Move.w	d5,(a3)+
	Move.w	d6,(a4)+
	Move.w	d7,(a5)+
	Dbra	d0,rloop
BP1	
	Lea	X_Angle,a0
	Lea	X_AngLeadd,a1
	Move.l	#360,d1

	Move.w	(a1)+,d0		; bump x angle
	Add.w	d0,(a0)+
	Cmp.w	-2(a0),d1		; > 360 ?
	Bgt.s	Ok1
	Sub.w	d1,-2(a0)
Ok1	
	Move.w	(a1)+,d0		; bump y angle
	Add.w	d0,(a0)+
	Cmp.w	-2(a0),d1		; > 360 ?
	Bgt.s	Ok2
	Sub.w	d1,-2(a0)
	
Ok2	
	Move.w	(a1)+,d0		; bump z angle
	Add.w	d0,(a0)+
	Cmp.w	-2(a0),d1		; > 360 ?
	Bgt.s	Done
	Sub.w	d1,-2(a0)
Done	
	Rts


**************************************************
*	get sin/cos value for angle in d0*
**************************************************

Trig	
	Tst	d0
	Bpl.s	NoAdd
	Add	#360,d0
NoAdd	
	Lea	Sintab,a1
	Move.l	d0,d2
	Lsl	#1,d0
	Move	0(a1,d0),d1
	Cmp	#270,d2
	Blt.s	Plus9
	Sub	#270,d2
	Bra.s	Sendsin
Plus9	
	Add	#90,d2
Sendsin	
	Lsl	#1,d2
	Move	0(a1,d2),d2
	Rts
	

gfxlib	Dc.b	"graphics.library",0	
	even
_gfxBase	Dc.l	0		;lONG WORD TO STORE GFX AddRESS
oldcop		Dc.l	0		;OLD COPPERlIST AddRESS
ScreenPointer	Dc.l	0
SDelta_2	Dc.w	0
SDelta_2_LDelta	Dc.w	0
SDelta_2_LDelta_2	Dc.w	0
FrameCount	Dc.w	0
	even


Newcop
	Dc.w	$0100,%1010001000000000	
	Dc.w	$0102
Scroll	Dc.w	$0000				;SCROll VAlUE
	Dc.w	$0104,%0000000000000001		;NO PRIORITIES
	Dc.w	$0108,$0000,$010a,$0000		;MODUlAS
	Dc.w	$0092,$0038,$0094,$00d0		;256*40 SCREEN
	Dc.w	$008e,$2c81,$0090,$2cc1		;VISIBlE AREA
			
Planes
	Dc.w	$00e0
Bpl0pth	Dc.w	$0000,$00e2
Bpl0ptl	Dc.w	$0000,$00e4
Bpl1pth	Dc.w	$0000,$00e6
Bpl1ptl	Dc.w	$0000,$00e8
Bpl2pth	Dc.w	$0000,$00ea
Bpl2ptl	Dc.w	$0000,$00ec
Bpl3pth	Dc.w	$0000,$00ee
Bpl3ptl	Dc.w	$0000,$00f0
Bpl4pth	Dc.w	$0000,$00f2
Bpl4ptl	Dc.w	$0000,$00f4
Bpl5pth	Dc.w	$0000,$00f6
Bpl5ptl	Dc.w	$0000

Sprites						;SPRITES
	Dc.w	$0120
Spl0pth	Dc.w	$0000,$0122
Spl0ptl	Dc.w	$0000,$0124
Spl1pth	Dc.w	$0000,$0126
Spl1ptl	Dc.w	$0000
	Dc.w	$0128,$0000,$012a,$0000
	Dc.w	$012c,$0000,$012e,$0000
	Dc.w	$0130,$0000,$0132,$0000
	Dc.w	$0134,$0000,$0136,$0000
	Dc.w	$0138,$0000,$013a,$0000
	Dc.w	$013c,$0000,$013e,$0000

	Dc.w	$0180,$0000,$0182,$0fff		;COlORS PlAY 1
	Dc.w	$0184,$0fff,$0186,$0fff
	Dc.w	$0188,$0ff0,$018a,$00ff
	Dc.w	$018c,$008f,$018e,$0095

	Dc.w	$0190,$0000,$0192,$0283		;COlORS PlAY 2
	Dc.w	$0194,$08f4,$0196,$0095
	Dc.w	$0198,$0243,$019a,$00ff
	Dc.w	$019c,$0ff0,$019e,$0fa0

	Dc.w	$01a0,$0000,$01a2,$0fff		;SPRITE COlORS
	Dc.w	$01a4,$0f00,$01a6,$0B00
	Dc.w	$01a8,$0600,$01aa,$0F40
	Dc.w	$01ac,$0F80,$01ae,$0Fa0
	Dc.w	$01B0,$0Ff0,$01B2,$000f
	Dc.w	$01B4,$004f,$01B6,$008f
	Dc.w	$01B8,$00ff,$01Ba,$00f0
	Dc.w	$01Bc,$0283,$01Be,$0f0f

	Dc.w	$ffff,$fffe			;END OF COPPERlIST

wx		Dc.w -50
Number		Equ	*-wx

wy		Dc.w 3

wz		Dc.w 5


NumBalls	equ	Number/2     

X_Angle		Dc.w	0
Y_Angle		Dc.w	0
Z_Angle		Dc.w	0

X_AngLeadd	Dc.w	1
Y_AngLeadd	Dc.w	5
Z_AngLeadd	Dc.w	6
	
Z_Sin		Dc.w	0
Z_Cos		Dc.w	0
Y_Sin		Dc.w	0
Y_Cos		Dc.w	0
X_Sin		Dc.w	0
X_Cos		Dc.w	0

numpoints	Dc.w NumBalls-1

X_Rot		Ds.w NumBalls	
Y_Rot		Ds.w NumBalls	
Z_Rot		Ds.w NumBalls	

A		Dc.w	200,100
B		Dc.w	200,200
O		Dc.w	100,200
End		Dc.w	$ffff,$ffff

Connections	
		Dc.l	A,B	;    
		Dc.l	O,A
		Dc.l	O,B
		Dc.l	End	; END MARKER
ConEnd
ConSize		Equ	((ConEnd-Connections)/8)-1

Sintab
	dc.w 0,286,572,857,1143,1428,1713,1997,2280
	dc.w 2563,2845,3126,3406,3686,3964,4240,4516
	dc.w 4790,5063,5334,5604,5872,6138,6402,6664
	dc.w 6924,7182,7438,7692,7943,8192,8438,8682	
	dc.w 8923,9162,9397,9630,9860,10087,10311,10531
	dc.w 10749,10963,11174,11381,11585,11786,11982,12176
	dc.w 12365,12551,12733,12911,13085,13255,13421,13583
	dc.w 13741,13894,14044,14189,14330,14466,14598,14726
	dc.w 14849,14968,15082,15191,15296,15396,15491,15582
	dc.w 15668,15749,15826,15897,15964,16026,16083,16135
	dc.w 16182,16225,16262,16294,16322,16344,16362,16374
	dc.w 16382,16384
	dc.w 16382
	dc.w 16374,16362,16344,16322,16294,16262,16225,16182
	dc.w 16135,16083,16026,15964,15897,15826,15749,15668	
	dc.w 15582,15491,15396,15296,15191,15082,14967,14849
	dc.w 14726,14598,14466,14330,14189,14044,13894,13741	
	dc.w 13583,13421,13255,13085,12911,12733,12551,12365
	dc.w 12176,11982,11786,11585,11381,11174,10963,10749
	dc.w 10531,10311,10087,9860,9630,9397,9162,8923
	dc.w 8682,8438,8192,7943,7692,7438,7182,6924
	dc.w 6664,6402,6138,5872,5604,5334,5063,4790
	dc.w 4516,4240,3964,3686,3406,3126,2845,2563
	dc.w 2280,1997,1713,1428,1143,857,572,286,0
	dc.w -286,-572,-857,-1143,-1428,-1713,-1997,-2280
	dc.w -2563,-2845,-3126,-3406,-3686,-3964,-4240,-4516
	dc.w -4790,-5063,-5334,-5604,-5872,-6138,-6402,-6664
	dc.w -6924,-7182,-7438,-7692,-7943,-8192,-8438,-8682	
	dc.w -8923,-9162,-9397,-9630,-9860,-10087,-10311,-10531
	dc.w -10749,-10963,-11174,-11381,-11585,-11786,-11982,-12176
	dc.w -12365,-12551,-12733,-12911,-13085,-13255,-13421,-13583
	dc.w -13741,-13894,-14044,-14189,-14330,-14466,-14598,-14726
	dc.w -14849,-14968,-15082,-15191,-15296,-15396,-15491,-15582
	dc.w -15668,-15749,-15826,-15897,-15964,-16026,-16083,-16135
	dc.w -16182,-16225,-16262,-16294,-16322,-16344,-16362,-16374
	dc.w -16382,-16384
	dc.w -16382
	dc.w -16374,-16362,-16344,-16322,-16294,-16262,-16225,-16182
	dc.w -16135,-16083,-16026,-15964,-15897,-15826,-15749,-15668	
	dc.w -15582,-15491,-15396,-15296,-15191,-15082,-14967,-14849
	dc.w -14726,-14598,-14466,-14330,-14189,-14044,-13894,-13741	
	dc.w -13583,-13421,-13255,-13085,-12911,-12733,-12551,-12365
	dc.w -12176,-11982,-11786,-11585,-11381,-11174,-10963,-10749
	dc.w -10531,-10311,-10087,-9860,-9630,-9397,-9162,-8923
	dc.w -8682,-8438,-8192,-7943,-7692,-7438,-7182,-6924
	dc.w -6664,-6402,-6138,-5872,-5604,-5334,-5063,-4790
	dc.w -4516,-4240,-3964,-3686,-3406,-3126,-2845,-2563
	dc.w -2280,-1997,-1713,-1428,-1143,-857,-572,-286,0

Foreground
	dcb.b	ScreenSize*Depth,$00

Foreground_2
	dcb.b	ScreenSize*Depth,$00



