	include	df0:source/HardwareDefs.i
	rsreset
StarX		rs.w	1	X,Y,Z of star
StarY		rs.w	1
StarZ		rs.w	1
StarBit		rs.w	1	bit position for star deletion
StarAddr	rs.l	1	Address of star on screen
StarSize	rs.w	0

	rsreset
mv_Dir		rs.w	1	Direction to move star in
mv_DirAmount	rs.w	1	Number of pixels to move each frame
mv_RotateAngle	rs.w	1	angle to rotate star by
mv_RotateDir	rs.w	1	plane to rotate
mv_Duration	rs.w	1	length of this move
mv_Size		rs.w	0


NumberLines	EQU	160
NumberStars	EQU	100

Forbid		EQU	-$84
Permit		EQU	-$8a
AllocMem	EQU	-$c6
FreeMem		EQU	-$d2
OldOpenLibrary	EQU	-$198
CloseLibrary	EQU	-$19e

OwnBlitter	EQU	-$1c8
DisownBlitter	EQU	-$1ce

ScreenHeight		EQU	256
ScreenWidth		EQU	320
PlaneSize		EQU	$2800
BitPlaneMemorySize	EQU	PlaneSize*4

	SECTION	Start,CODE_C

	move.l	$4.w,a6			open graphics.library
	lea	GfxName(pc),a1
	jsr	OldOpenLibrary(a6)
	move.l	d0,GfxBase

	move.l	#BitPlaneMemorySize,d0	Allocate chip memory for bit planes
	move.l	#$10002,d1		need chip memory
	move.l	$4.w,a6
	jsr	AllocMem(a6)
	move.l	d0,Screen		Put correct places for planes
	tst.l	d0
	beq	no_memory

	add.l	#3*PlaneSize,d0
	move.l	d0,ScrollScreen

	move.l	GfxBase(pc),a6		Get blitter
	jsr	OwnBlitter(a6)
	move.l	$4.w,a6
	jsr	Forbid(a6)		kill system legally


	lea	$dff000,a5		
	move.w	DMACONR(a5),OldDMACON	save old system variables
	move.w	INTENAR(a5),OldINTENA
	move.w	INTREQR(a5),OldINTREQ

; Now to set up the system as we need it

	move.w	#$7fff,DMACON(a5)	disable all dma
	move.w	#$7fff,INTENA(a5)	disable interrupts


	lea	LineAmplitudes(pc),a0	initialise text to centre of wave
	move.w	#NumberLines-1,d0
.SetAmp	move.w	#$640,(a0)+
	dbra	d0,.SetAmp

	move.l	$6c.w,OldVBl+2		Install interrupt handler
	move.l	#Interrupt,$6c.w

	move.l	Screen(pc),d0		Put starfield screen into copper
	lea	NewCopper(pc),a0
	move.w	d0,6(a0)
	swap	d0
	move.w	d0,2(a0)
	swap	d0
	add.l	#PlaneSize,d0
	move.w	d0,$e(a0)
	swap	d0
	move.w	d0,$a(a0)
	swap	d0
	add.l	#PlaneSize,d0
	move.w	d0,$16(a0)
	swap	d0
	move.w	d0,$12(a0)
	swap	d0
	add.l	#PlaneSize,d0

	move.l	ScrollScreen(pc),d0	Put addr of screen into copper list
	move.w	d0,ScrPtr+6
	move.w	d0,ClrPtr+6
	swap	d0
	move.w	d0,ScrPtr+2
	move.w	d0,ClrPtr+2

	bsr	InitColours		Get screen colours


	move.l	#NewCopper,COP1LCH(a5)	install new copper list

	move.w	#$83c0,DMACON(a5)	enable bitplane,copper,blitter dma
	clr.w	SPR0CTL(a5)		stop possible sprite residue

	move.w	#$c010,INTENA(a5)
	move.w	#$7fff,INTREQ(a5)	Only allow copper interrupts

	move.w	#-1,COPCON(a5)
	move.w	#$ffff,BLTAFWM(a5)

	clr.w	COPJMP1(a5)		Start copperlist

	bsr	AnimStars
.WaitMouse
	btst	#6,$bfe001
	bne.s	.WaitMouse

; Now to restart the system
	lea	$dff000,a5
	move.w	#$7fff,INTENA(a5)	disable interrupts
	move.w	#$7fff,INTREQ(a5)	clear interrupts

;kill copper list safely, as we are using a blitter clear screen in it

.WaitInt
	btst	#4,INTREQR+1(a5)	wait for copper interrupt
	beq.s	.WaitInt
	bsr	WaitBlitter		wait for blitter to finish

	move.w	#$7fff,DMACON(a5)	disable all dma (including blitter)


	move.l	OldVBl+2(pc),$6c.w	restore old interrupts

	move.l	GfxBase(pc),a6
	move.l	38(a6),COP1LCH(a5)	Reset Copper to origional value

	move.w	OldDMACON(pc),d0	restore DMA
	or.w	#$8000,d0
	move.w	d0,DMACON(a5)
	move.w	OldINTENA(pc),d0	restore interrupt mask
	or.w	#$8000,d0
	move.w	d0,INTENA(a5)
	move.w	OldINTREQ(pc),d0	restore interrupt requests
	or.w	#$8000,d0
	move.w	d0,INTREQ(a5)


	move.l	$4.w,a6
	jsr	Permit(a6)
	move.l	GfxBase(pc),a6
	jsr	DisownBlitter(a6)
	move.l	$4.w,a6
	clr.w	COPJMP1(a5)		start system copper running again

	move.l	Screen(pc),a1		Free the memory allocated for screen.
	move.l	#BitPlaneMemorySize,d0
	move.l	$4.w,a6
	jsr	FreeMem(a6)

	
no_memory
	move.l	GfxBase(pc),a1
	jsr	CloseLibrary(a6)

	moveq	#0,d0
	rts



*************	moves stars and exits when mouse button pressed
* AnimStars *
*************
AnimStars
	bsr	InitStars

	lea	StarMove-mv_Size(pc),a6
ChangeStars
	lea	mv_Size(a6),a6
	tst.w	mv_Dir(a6)
	bpl.s	GetNext
	lea	StarMove(pc),a6
GetNext	move.w	mv_Duration(a6),NextChange

DoSpriteChanges
	move.w	#NumberStars-1,d7
	lea	StarMemory(pc),a0
DrawNextStar
	move.w	mv_Dir(a6),d0
	move.w	mv_DirAmount(a6),d1
	add.w	d1,0(a0,d0.w)

	bsr	DeleteStar

	cmp.w	#160*$40,StarX(a0)
	bmi.s	Xok
	add.w	#-320*$40,StarX(a0)
Xok	cmp.w	#-160*$40,StarX(a0)
	bgt.s	Xok2
	add.w	#320*$40,StarX(a0)
Xok2
	cmp.w	#160*$40,StarY(a0)
	bmi.s	Yok
	add.w	#-320*$40,StarY(a0)
Yok	cmp.w	#-160*$40,StarY(a0)
	bgt.s	Yok2
	add.w	#320*$40,StarY(a0)

Yok2	cmp.w	#128*$40,StarZ(a0)
	bmi.s	Zok
	add.w	#-256*$40,StarZ(a0)
Zok	cmp.w	#-128*$40,StarZ(a0)
	bgt.s	Zok2
	add.w	#256*$40,StarZ(a0)
Zok2

	move.w	mv_RotateAngle(a6),d0
	move.w	mv_RotateDir(a6),d1
	bsr	RotateStar

	bsr	DrawStar
	
	lea	StarSize(a0),a0
	dbra	d7,DrawNextStar

	subq.w	#1,NextChange
	bmi	ChangeStars
	btst	#6,$bfe001
	bne	DoSpriteChanges
	rts

*************	new interrupt handler
* Interrupt *
*************
Interrupt
	btst	#4,$dff000+INTREQR+1		Is it copper interrupt ?
	beq.s	OldVBl
	movem.l	d0-d7/a0-a6,-(sp)		yes, so scroll text
	bsr.s	DoScroll
	movem.l	(sp)+,d0-d7/a0-a6
	move.w	#$10,$dff000+INTREQ		clear copper interrupt
	rte
OldVBl	jmp	0


************	move and draw the scrolling text
* DoScroll *
************
DoScroll
	move.w	Amplitude(pc),d0	increase/decrease amplitude value to
	cmp.w	NewAmplitude(pc),d0	new setting
	beq.s	.Equal
	bpl.s	.Less
	addq.w	#2,d0
	bra.s	.Equal
.Less	subq.w	#2,d0
.Equal	move.w	d0,Amplitude

	lea	LineAmplitudes+NumberLines*2(pc),a0
	lea	2(a0),a1			Scroll forward sine wave
	move.w	#NumberLines-1,d0
.Wave	move.w	-(a0),-(a1)
	dbra	d0,.Wave

	move.w	CurrAngle(pc),d0		Get next sine value
	add.w	RepeatSpeed(pc),d0
	cmp.w	#720,d0
	blt.s	.NoWrap
	sub.w	#720,d0
.NoWrap	move.w	d0,CurrAngle

	lea	sintab(pc),a1
	move.w	0(a1,d0.w),d0
	muls	Amplitude(pc),d0
	divs	#$6400,d0
	asr.w	#1,d0
	and.w	#$fff8,d0
	move.w	d0,d1
	add.w	d0,d0
	add.w	d0,d0
	add.w	d1,d0
	add.w	#$640,d0
	move.w	d0,(a0)				add this value to list


	move.w	PauseScroll(pc),d0		Message pausing ?
	bne	DoPause

	move.w	CharOffset(pc),d1
	add.w	Speed(pc),d1
	move.w	d1,d0
	and.w	#1,d0
	move.w	d0,CharOffset
	and.w	#$fffe,d1

	lea	ScrolltextData(pc),a0		no, so scroll text back
	move.w	#NumberLines+8,d0		(Speed) pixels
	lea	0(a0,d1.w),a1
.MvPixl	move.w	(a1)+,(a0)+
	dbra	d0,.MvPixl

	sub.w	d1,BitsLeft		Need next character in scroller ?
	bge	DrawScroll

	move.l	TextPos(pc),a0		yes
NextChr	moveq	#0,d0
	move.b	(a0)+,d0
	bne.s	.NoWrap
	lea	TextStart(pc),a0
.NoWrap	cmp.b	#"0",d0
	bmi.s	.Space
	cmp.b	#"a",d0			Handle escape codes
	beq.s	SetAmplitude
	cmp.b	#"b",d0
	beq.s	SetPause
	cmp.b	#"c",d0
	beq.s	SetSpeed
	cmp.b	#"d",d0
	beq.s	SetRepeat
	bmi.s	.Char
.Space	moveq	#$40,d0
.Char	move.l	a0,TextPos		Add new character to end of scroller
	sub.b	#$30,d0
	lea	Font(pc),a1
	lsl.w	#4,d0
	add.w	d0,a1
	move.w	BitsLeft(pc),d0
	lea	ScrolltextData+NumberLines*2(pc),a0
	add.w	d0,a0			Work out where to put extra char
	add.w	#16,d0
	move.w	d0,BitsLeft		number of bits of next char left
	
	move.l	(a1)+,(a0)+
	move.l	(a1)+,(a0)+
	move.l	(a1)+,(a0)+
	move.l	(a1)+,(a0)+
	bra.s	DrawScroll

SetSpeed
	move.b	(a0)+,d0		Change speed of scroller
	sub.b	#"0"-1,d0
	move.w	d0,Speed
	bra.s	NextChr

SetPause
	move.b	(a0)+,d0		Pause displayed text 
	sub.b	#"0"-1,d0
	lsl.b	#4,d0
	move.b	d0,PauseScroll
	bra.s	NextChr

SetAmplitude
	move.b	(a0)+,d0		Change amplitude of sine wave
	sub.b	#"0",d0
	lsl.w	#7,d0
	move.w	d0,NewAmplitude
	bra	NextChr

SetRepeat
	move.b	(a0)+,d0		Change waviness of sine wave
	sub.b	#"0",d0
	add.w	d0,d0
	move.w	d0,RepeatSpeed
	bra	NextChr

DoPause	subq.b	#1,PauseScroll

DrawScroll
	lea	$dff000,a5		Draw the scrolling text
	bsr	WaitBlitter
	move.w	#$ffc8,BLTBMOD(a5)	4*(dy-dx)
	clr.w	BLTAMOD(a5)		4*dy
	move.w	#40,BLTCMOD(a5)		screen width
	move.w	#40,BLTDMOD(a5)
	move.w	#$ffff,BLTALWM(a5)

	move.l	ScrollScreen(pc),a0
	move.l	#$bea0009,d2
	lea	ScrolltextData(pc),a1
	lea	LineAmplitudes(pc),a3
	move.w	#NumberLines-1,d0

.NxLine	add.l	#$20000000,d2		Advance to next pixel position
	bcc.s	.SameWord
	addq.w	#2,a0			Advance to next word
.SameWord
	move.w	(a3)+,d6		amplitude for pixel line
	move.w	(a1)+,d4		data for pixel line
	beq.s	.Blank			if blank, ignore
	lea	0(a0,d6.w),a4
	swap	d4
	move.w	#$8000,d4

	bsr.s	WaitBlitter		Wait for last blit to finish
	move.w	#$ffe4,BLTAPTL(a5)	4*dy-2*dx
	move.l	a4,BLTCPTH(a5)
	move.l	a4,BLTDPTH(a5)
	move.l	d4,BLTBDAT(a5)			& BLTADAT
	move.l	d2,BLTCON0(a5)			& BLTCON1
	move.w	#$3c2,BLTSIZE(a5)
.Blank	dbra	d0,.NxLine

;Now fill in the gaps in the scrolltext my copying the whole scroll text 1
;pixel line to the right

	bsr.s	WaitBlitter		Wait for last blit to finish


	move.w	CharOffset(pc),d1
	bne.s	DoOdd
	move.l	ScrollScreen(pc),a0	Copy plane 1 pixel right
	move.l	a0,BLTAPTH(a5)
	move.l	a0,BLTBPTH(a5)
	move.l	a0,BLTDPTH(a5)
	move.w	#$fffe,BLTALWM(a5)	Ignore last pixel of source A
	clr.l	BLTCMOD(a5)
	clr.l	BLTAMOD(a5)
	move.l	#$1dfc0000,BLTCON0(a5)
	move.w	#$2814,BLTSIZE(a5)
	rts

***************	Wait until last blitter operation has finished
* WaitBlitter *
***************
WaitBlitter
	tst.w	DMACONR(a5)
.Wait	btst	#6,DMACONR(a5)
	bne.s	.Wait
	rts

DoOdd	move.l	ScrollScreen(pc),a0	Copy plane 1 pixel left
	move.l	a0,BLTBPTH(a5)
	move.l	a0,BLTDPTH(a5)
	addq.w	#2,a0
	move.l	a0,BLTAPTH(a5)
	clr.l	BLTCMOD(a5)
	clr.l	BLTAMOD(a5)
	move.l	#$fdfc0000,BLTCON0(a5)
	move.w	#$2814,BLTSIZE(a5)
	rts



; Font used is a 7 pixels wide by 14 pixels high. Font is presented one
; vertical row at a time, as this is the way the sine wave scroller needs it

Font	dc.w	$7ff0,$fffc,$c00c,$c00c,$c00c,$fffc,$7ff0,0	0
	dc.w	$0000,$3000,$fffc,$fffc,$fffc,$0000,$0000,0	1
	dc.w	$30fc,$f3fc,$c3fc,$c30c,$ff0c,$ff0c,$3c0c,0	2
	dc.w	$c030,$c33c,$cf0c,$ff0c,$fffc,$f3fc,$c0f0,0	3
	dc.w	$03c0,$0fc0,$3cc0,$f0c0,$fffc,$fffc,$00c0,0	4
	dc.w	$fc30,$fc3c,$fc0c,$cc0c,$cffc,$cffc,$c3f0,0	5
	dc.w	$3ff0,$fffc,$fffc,$c30c,$c30c,$c3fc,$00f0,0	6
	dc.w	$c000,$c000,$c3fc,$cffc,$fffc,$fc00,$f000,0	7
	dc.w	$3cf0,$fffc,$fffc,$c30c,$c30c,$fffc,$3cf0,0	8
	dc.w	$3c30,$ff3c,$c30c,$c30c,$fffc,$fffc,$3ff0,0	9
	dc.w	$0000,$0000,$0000,$003c,$003c,$0000,$0000,0	: => .
	dc.l	0,0,0,0
	dc.l	0,0,0,0
	dc.l	0,0,0,0
	dc.l	0,0,0,0
	dc.w	$3000,$f000,$c3cc,$cfcc,$ffcc,$fc00,$3000,0	?
	dc.l	0,0,0,0						" "

	dc.w	$3ffc,$fffc,$fffc,$c300,$c300,$fffc,$3ffc,0	A
	dc.w	$fffc,$fffc,$fffc,$c30c,$c30c,$fffc,$3cf0,0	B
	dc.w	$3ff0,$fffc,$fffc,$c00c,$c00c,$f03c,$3030,0	C
	dc.w	$fffc,$fffc,$fffc,$c00c,$c00c,$fffc,$3ff0,0	D
	dc.w	$fffc,$fffc,$fffc,$c30c,$c30c,$c00c,$c00c,0	E
	dc.w	$fffc,$fffc,$fffc,$c300,$c300,$c000,$c000,0	F
	dc.w	$3ff0,$fffc,$fffc,$c00c,$c30c,$f3fc,$33fc,0	G
	dc.w	$fffc,$fffc,$fffc,$0300,$0300,$fffc,$fffc,0	H
	dc.w	$0000,$0000,$fffc,$fffc,$fffc,$0000,$0000,0	I
	dc.w	$0030,$003c,$000c,$000c,$fffc,$fffc,$fff0,0	J
	dc.w	$fffc,$fffc,$fffc,$0fc0,$3cf0,$f03c,$c00c,0	K
	dc.w	$fffc,$fffc,$fffc,$000c,$000c,$000c,$000c,0	L
	dc.w	$fffc,$fffc,$3f00,$0fc0,$3f00,$fffc,$fffc,0	M
	dc.w	$fffc,$fffc,$3f00,$0fc0,$03f0,$fffc,$fffc,0	N
	dc.w	$3ff0,$fffc,$fffc,$c00c,$c00c,$fffc,$3ff0,0	O
	dc.w	$fffc,$fffc,$fffc,$c300,$c300,$ff00,$3c00,0	P
	dc.w	$3ff0,$fffc,$fffc,$c00c,$c0f0,$ff3c,$3fcc,0	Q
	dc.w	$fffc,$fffc,$fffc,$c3c0,$c3f0,$ff3c,$3c0c,0	R
	dc.w	$3c30,$ff3c,$ff3c,$c30c,$c3fc,$f3fc,$30f0,0	S
	dc.w	$c000,$c000,$fffc,$fffc,$fffc,$c000,$c000,0	T
	dc.w	$fff0,$fffc,$fffc,$000c,$000c,$fffc,$fff0,0	U
	dc.w	$ffc0,$fff0,$fffc,$003c,$00fc,$fff0,$ffc0,0	V
	dc.w	$fffc,$fffc,$03f0,$0fc0,$03f0,$fffc,$fffc,0	W
	dc.w	$f03c,$fcfc,$3ff0,$0fc0,$3ff0,$fcfc,$f03c,0	X
	dc.w	$fc00,$ff00,$fffc,$03fc,$03fc,$ff00,$fc00,0	Y
	dc.w	$c03c,$c0fc,$c3fc,$cfcc,$ff0c,$fc0c,$f00c,0	Z

GfxName		dc.b	"graphics.library",0
GfxBase		dc.l	0
OldCopper	dc.l	0
OldDMACON	dc.w	0
OldINTENA	dc.w	0
OldINTREQ	dc.w	0

TextPos		dc.l	TextStart

ScrollScreen	dc.l	0

Amplitude	dc.w	0
NewAmplitude	dc.w	0
Speed		dc.w	2
PauseScroll	dc.w	0
CurrAngle	dc.w	0
RepeatSpeed	dc.w	4
CharOffset	dc.w	0
BitsLeft	dc.w	0

;a<number> - 0..4 set amplitude of sine wave
;b<number> - pause scroller
;c<number> - Set speed of scroller
;d<number> - Set speed of sine wave repetitions
;dc.b 0	   - wrap message
TextStart
	dc.b	"a4c0            HELLO THERE    c2b7 "
	dc.b	"THIS IS A         DEMONd8STRATION d0  b7   "
	dc.b	"d1AS YOU CAN SEE IT c3HAS d2a1VARIOUS c5SPEEDS "
	dc.b	" d4DOc1 WAVY THINGS AND a0 JUST BE c2A NORMAL BORING "
	dc.b	" SCROLLING MESSAGE    d4a2    LETS HAVE SOME DOTS "
	dc.b	"::::a4::::::d8:::::::::d6:::::::d4::::::d2:::::::c3:::::"
	dc.b	":a2:::::::d1:::::::::::d6:::::::"
	dc.b	"::a3:c2:::d2::::::d4:a1:::::d6::::::d8:::::::a4:d4::::::d8:::d0:"
	dc.b	"::::d4:::a2:::::d8:::::::::::d4a0:::           "
	dc.b	"c2a3d3ITS ABOUT THAT TIME TO THANK EVERYBODY IN SIGHT:::: SO"
	dc.b	" THANKS GO TO c1::: THE POSTMAN ::a2c0 THE MILKMAN ::c1 THE d2MAN WHO ERECTED OUR "
	dc.b	"GARDEN SHED ::: c2a4d3ETC ::: ETC ::: ETC ::::::::    "
	dc.b	"THANKS c6FOR STAYING WITH THIS AND READING a3THE WHOLE MESSAGE a4::: c3HA "
	dc.b	"::: HA ::: HA a0           WRITTEN   BY     JUSTIN LECK    d2b9               "
	dc.b	0

	even
NewCopper
	dc.w	BPL1PTH,0
	dc.w	BPL1PTL,0
	dc.w	BPL2PTH,0
	dc.w	BPL2PTL,0
	dc.w	BPL3PTH,0
	dc.w	BPL3PTL,0

	dc.w	DIWSTRT,$2c81
	dc.w	DIWSTOP,$2cc1
	dc.w	DDFSTART,$38
	dc.w	DDFSTOP,$d0
	dc.w	BPLCON0,$3000		3 bit planes - no scroller
	dc.w	BPLCON1,0
	dc.w	BPL1MOD,0
	dc.w	BPL2MOD,0
	dc.w	$6cff,$fffe

	dc.w	BPLCON0,$4000		4 bit planes - with scroller
ScrPtr	dc.w	BPL4PTH,0
	dc.w	BPL4PTL,0
	dc.w	$ccff,$fffe		wait for end of scrolly message

	dc.w	BPLCON0,$3000		3 bit planes - no scroller
ClrPtr	dc.w	BLTDPTH,0	Copper programs blitter to clear message
	dc.w	BLTDPTL,0
	dc.w	BLTDMOD,0
	dc.w	BLTCON0,$100
	dc.w	BLTCON1,0
	dc.w	BLTSIZE,$c80
	dc.w	$feff,$fffe	wait until blitter is done or nearly done
	dc.w	INTREQ,$8010	cause copper interrupt - redraw message
	dc.w	$ffff,$fffe

LineAmplitudes	ds.w	NumberLines+2
ScrolltextData	ds.w	NumberLines+16

				******** Star handling routines ******

***************	Sets up palette
* InitColours *
***************
InitColours
	lea	Colours(pc),a0
	lea	$dff180,a1
	moveq	#$f,d0
.copy	move.l	(a0)+,(a1)+
	dbra	d0,.copy
	rts
Colours	dc.w	$000,$640,$851,$972,$b84,$ca6,$ec8,$fff
	dc.w	$00f,$00f,$00f,$00f,$b84,$ca6,$ec8,$fff

************		a0 = structure of star to draw
* DrawStar *
************
DrawStar
	move.w	StarY(a0),d0
	muls	StarZ(a0),d0
	swap	d0
	add.l	d0,d0
	add.l	d0,d0
	add.w	StarY(a0),d0		d0 = y co-ordinate

	move.w	StarX(a0),d1
	muls	StarZ(a0),d1
	swap	d1
	add.l	d1,d1
	add.l	d1,d1
	add.w	StarX(a0),d1		d1 = x co-ordinate

	add.w	#128*$40,d0		is star off top of screen ?
	bmi.s	NoStar
	cmp.w	#ScreenHeight*$40,d0	is star off bottom of screen ?
	bpl.s	NoStar

	add.w	#160*$40,d1		Is star off left of screen ?
	bmi.s	NoStar
	cmp.w	#ScreenWidth*$40,d1	Is star off right of screen ?
	bpl.s	NoStar

	and.l	#$ffc0,d0		;d0=d0/$40*$28 => d0=d0/8*5
	lsr.w	#3,d0
	move.w	d0,d2
	add.w	d0,d0
	add.w	d0,d0
	add.w	d2,d0			d0 = byte offset due to y coord

	lsr.w	#6,d1
	move.w	d1,d2
	lsr.w	#3,d1
	add.w	d1,d0			d0 = offset to planes for star
	and.w	#7,d2			d2 = bit position of star
	eor.w	#7,d2

	move.l	Screen(pc),a1
	add.l	d0,a1

	move.w	StarZ(a0),d1		Get Star colour (nearer = brighter)
	add.w	#128*$40,d1
	bmi.s	NoStar
	rol.w	#5,d1
	and.w	#7,d1
	addq.w	#1,d1
	cmp.w	#8,d1
	blt.s	.ColOk
	moveq	#7,d1
.ColOk
	lsr.w	#1,d1
	bcc.s	NoPlane0
	bset	d2,(a1)
NoPlane0
	lsr.w	#1,d1
	bcc.s	NoPlane1
	bset	d2,PlaneSize(a1)
NoPlane1
	lsr.w	#1,d1
	bcc.s	NoPlane2
	bset	d2,PlaneSize*2(a1)
NoPlane2
	move.w	d2,StarBit(a0)		save last bit point & address
	move.l	a1,StarAddr(a0)
	rts
NoStar	clr.l	StarAddr(a0)
	rts

**************	Removes star from screen using last bit point & address
* DeleteStar *
**************
DeleteStar
	move.l	StarAddr(a0),d0
	beq.s	.NoStar
	move.l	d0,a1
	move.w	StarBit(a0),d2
	bclr	d2,(a1)
	bclr	d2,PlaneSize(a1)
	bclr	d2,PlaneSize*2(a1)
.NoStar	rts

*************
* InitStars *
*************
InitStars
	lea	StarMemory(pc),a0
	move.w	#NumberStars-1,d7
InitNextStar
	move.w	#320*$40,d0			get X
	bsr	IntRnd
	sub.w	#160*$40,d0
	move.w	d0,(a0)+
	move.w	#320*$40,d0			get Y
	bsr	IntRnd
	sub.w	#160*$40,d0
	move.w	d0,(a0)+
	move.w	#256*$40,d0			get Z
	bsr	IntRnd
	sub.w	#128*$40,d0
	move.w	d0,(a0)+
	clr.w	(a0)+				clear bit position
	clr.l	(a0)+				clear last address
	dbra	d7,InitNextStar
	rts

*****************
*    IntRnd	*	d0 = Int(rnd(1)*d0)
*****************
IntRnd	move.l	d0,d6
	bsr.s	Random
	and.l	#$ffff,d0
	divu	d6,d0
	clr.w	d0
	swap	d0
	rts

*****************
*   Random	*	- 24 bit random number generator
*****************
Random	move.l	Rand(pc),d2
	bne.s	NotFirstRand
	move.w	$dff006,d2
	swap	d2
	move.w	$dff006,d2
NotFirstRand
	move.l	#3141592621,d1
	bsr.s	LongMult
	addq.l	#1,d0
	move.l	d0,Rand
	lsr.l	#8,d0		d0 = 24 bit randomish number
	rts

Rand	dc.l	0

*****************
*   LongMult	* - Multiplies top d1 by d2, result in d0
***************** uses d0->d4

LongMult
	moveq	#0,d4
	tst.l	d1
	bge.s	NotNeg1
	neg.l	d1
	moveq	#1,d4
NotNeg1	tst.l	d2
	bge.s	NotNeg2
	neg.l	d2
	addq.w	#1,d4			d4=whether result +ve,or -ve
NotNeg2	move.w	d1,d0
	mulu	d2,d0
	move.w	d2,d3
	swap	d2
	mulu	d1,d2
	swap	d1
	mulu	d3,d1
	add.w	d2,d1
	swap	d0
	add.w	d1,d0
	swap	d0
	lsr.w	#1,d4
	bcc.s	NotNeg3
	neg.l	d0
NotNeg3	rts

; for x axis rotation,
; X' := X; Y' := Y x COS(d0) - Z x SIN(d0); Z' := Y x SIN(d0) + Z x COS(d0)
**************	Rotates star (a0), by d0 degrees, on axis d1
* RotateStar *	d1 = -ve, (x axis), d1 = 0 (y axis), d1 = +ve (z axis)
**************
RotateStar
	lea	sintab(pc,d0.w),a1
	lea	StarX(a0),a2		Assume rotate z axis
	lea	StarY(a0),a3
	tst.w	d1
	bpl.s	.NoRotX
	addq.w	#2,a2		Rotate x axis
	addq.w	#2,a3
	bra.s	.Cont
.NoRotX	bne.s	.Cont
	addq.w	#4,a2		Rotate y axis
	subq.w	#2,a3
.Cont

RotCont	move.w	(a2),d5
	muls	(a1),d5
	move.w	(a3),d4
	muls	180(a1),d4
	add.l	d4,d5
	add.l	d5,d5
	swap	d5

	move.w	(a2),d2
	muls	180(a1),d2
	move.w	(a3),d3
	muls	(a1),d3
	sub.l	d3,d2
	add.l	d2,d2
	swap	d2

	move.w	d2,(a2)
	move.w	d5,(a3)
	rts

sintab	dc.w	0,$23C,$478,$6B3,$8EE,$B28,$D61,$F99,$11D0,$1406
	dc.w	$163A,$186C,$1A9D,$1CCB,$1EF7,$2121,$2348,$256C,$278E,$29AC
	dc.w	$2BC7,$2DDF,$2FF3,$3203,$3410,$3618,$381C,$3A1C,$3C17,$3E0E
	dc.w	$4000,$41EC,$43D4,$45B6,$4793,$496A,$4B3C,$4D08,$4ECD,$508D
	dc.w	$5246,$53F9,$55A5,$574B,$58EA,$5A82,$5C13,$5D9C,$5F1F,$609A
	dc.w	$620D,$6379,$64DD,$6639,$678D,$68D9,$6A1D,$6B59,$6C8C,$6DB7
	dc.w	$6ED9,$6FF3,$7104,$720C,$730B,$7401,$74EE,$75D2,$76AD,$777F
	dc.w	$7847,$7906,$79BB,$7A67,$7B0A,$7BA2,$7C32,$7CB7,$7D33,$7DA5
	dc.w	$7E0D,$7E6C,$7EC0,$7F0B,$7F4B,$7F82,$7FAF,$7FD2,$7FEB,$7FFA
costab	dc.w	$7FFF,$7FFA,$7FEB,$7FD2,$7FAF,$7F82,$7F4B,$7F0B,$7EC0,$7E6C
	dc.w	$7E0D,$7DA5,$7D33,$7CB7,$7C32,$7BA2,$7B0A,$7A67,$79BB,$7906
	dc.w	$7847,$777F,$76AD,$75D2,$74EE,$7401,$730B,$720C,$7104,$6FF3
	dc.w	$6ED9,$6DB7,$6C8C,$6B59,$6A1D,$68D9,$678D,$6639,$64DD,$6379
	dc.w	$620D,$609A,$5F1F,$5D9C,$5C13,$5A82,$58EA,$574B,$55A5,$53F9
	dc.w	$5246,$508D,$4ECD,$4D08,$4B3C,$496A,$4793,$45B6,$43D4,$41EC
	dc.w	$4000,$3E0E,$3C17,$3A1C,$381C,$3618,$3410,$3203,$2FF3,$2DDF
	dc.w	$2BC7,$29AC,$278E,$256C,$2348,$2121,$1EF7,$1CCB,$1A9D,$186C
	dc.w	$163A,$1406,$11D0,$F99,$D61,$B28,$8EE,$6B3,$478,$23C
	dc.w	0,-$23C,-$478,-$6B3,-$8EE,-$B28,-$D61,-$F99,-$11D0,-$1406
	dc.w	-$163A,-$186C,-$1A9D,-$1CCB,-$1EF7,-$2121,-$2348,-$256C,-$278E,-$29AC
	dc.w	-$2BC7,-$2DDF,-$2FF3,-$3203,-$3410,-$3618,-$381C,-$3A1C,-$3C17,-$3E0E
	dc.w	-$3FFF,-$41EC,-$43D4,-$45B6,-$4793,-$496A,-$4B3C,-$4D08,-$4ECD,-$508D
	dc.w	-$5246,-$53F9,-$55A5,-$574B,-$58EA,-$5A82,-$5C13,-$5D9C,-$5F1F,-$609A
	dc.w	-$620D,-$6379,-$64DD,-$6639,-$678D,-$68D9,-$6A1D,-$6B59,-$6C8C,-$6DB7
	dc.w	-$6ED9,-$6FF3,-$7104,-$720C,-$730B,-$7401,-$74EE,-$75D2,-$76AD,-$777F
	dc.w	-$7847,-$7906,-$79BB,-$7A67,-$7B0A,-$7BA2,-$7C32,-$7CB7,-$7D33,-$7DA5
	dc.w	-$7E0D,-$7E6C,-$7EC0,-$7F0B,-$7F4B,-$7F82,-$7FAF,-$7FD2,-$7FEB,-$7FFA
	dc.w	-$7FFF,-$7FFA,-$7FEB,-$7FD2,-$7FAF,-$7F82,-$7F4B,-$7F0B,-$7EC0,-$7E6C
	dc.w	-$7E0D,-$7DA5,-$7D33,-$7CB7,-$7C32,-$7BA2,-$7B0A,-$7A67,-$79BB,-$7906
	dc.w	-$7847,-$777F,-$76AD,-$75D2,-$74EE,-$7401,-$730B,-$720C,-$7104,-$6FF3
	dc.w	-$6ED9,-$6DB7,-$6C8C,-$6B59,-$6A1D,-$68D9,-$678D,-$6639,-$64DD,-$6379
	dc.w	-$620D,-$609A,-$5F1F,-$5D9C,-$5C13,-$5A82,-$58EA,-$574B,-$55A5,-$53F9
	dc.w	-$5246,-$508D,-$4ECD,-$4D08,-$4B3C,-$496A,-$4793,-$45B6,-$43D4,-$41EC
	dc.w	-$4000,-$3E0E,-$3C17,-$3A1C,-$381C,-$3618,-$3410,-$3203,-$2FF3,-$2DDF
	dc.w	-$2BC7,-$29AC,-$278E,-$256C,-$2348,-$2121,-$1EF7,-$1CCB,-$1A9D,-$186C
	dc.w	-$163A,-$1406,-$11D0,-$F99,-$D61,-$B28,-$8EE,-$6B3,-$478,-$23C
	dc.w	0,$23C,$478,$6B3,$8EE,$B28,$D61,$F99,$11D0,$1406
	dc.w	$163A,$186C,$1A9D,$1CCB,$1EF7,$2121,$2348,$256C,$278E,$29AC
	dc.w	$2BC7,$2DDF,$2FF3,$3203,$3410,$3618,$381C,$3A1C,$3C17,$3E0E
	dc.w	$4000,$41EC,$43D4,$45B6,$4793,$496A,$4B3C,$4D08,$4ECD,$508D
	dc.w	$5246,$53F9,$55A5,$574B,$58EA,$5A82,$5C13,$5D9C,$5F1F,$609A
	dc.w	$620D,$6379,$64DD,$6639,$678D,$68D9,$6A1D,$6B59,$6C8C,$6DB7
	dc.w	$6ED9,$6FF3,$7104,$720C,$730B,$7401,$74EE,$75D2,$76AD,$777F
	dc.w	$7847,$7906,$79BB,$7A67,$7B0A,$7BA2,$7C32,$7CB7,$7D33,$7DA5
	dc.w	$7E0D,$7E6C,$7EC0,$7F0B,$7F4B,$7F82,$7FAF,$7FD2,$7FEB,$7FFA



MOVESTAR MACRO
	IFNE	NARG-5
	FAIL	MOVESTAR requires 5 arguments
	ENDC
	dc.w	\1,\2*$40,\3*2,\4,\5
	ENDM
; following data table tells stars how to move:
;<move direction>,<amount>,<angle to rotate>,<rotate direction>,<duration>
;<move direction> = StarX,StarY,StarZ. -1 = repeat sequence
;<rotate direction> => -ve, (x axis), 0 (y axis), +ve (z axis)
StarMove
	MOVESTAR StarZ,4,0,0,100
	MOVESTAR StarZ,5,1,-1,10
	MOVESTAR StarZ,6,2,-1,40
	MOVESTAR StarZ,5,1,-1,10
	MOVESTAR StarZ,4,0,0,100
	MOVESTAR StarZ,5,359,-1,10
	MOVESTAR StarZ,8,358,-1,40
	MOVESTAR StarZ,6,0,0,100
	MOVESTAR StarZ,3,359,-1,10
	MOVESTAR StarZ,-4,0,0,40
	MOVESTAR StarX,-5,2,0,10
	MOVESTAR StarX,-6,4,0,40
	MOVESTAR StarZ,2,3,0,10
	MOVESTAR StarZ,5,1,0,10
	MOVESTAR StarZ,6,1,-1,20
	MOVESTAR StarZ,3,3,-1,40
	MOVESTAR StarZ,-1,1,-1,20
	MOVESTAR StarZ,-5,1,1,20
	MOVESTAR StarZ,-10,2,1,20
	MOVESTAR StarZ,-16,2,1,60
	MOVESTAR StarZ,-10,2,1,20
	MOVESTAR StarZ,-4,1,1,20

	MOVESTAR StarZ,0,359,-1,20
	MOVESTAR StarZ,3,357,-1,40
	MOVESTAR StarZ,5,359,-1,20

	MOVESTAR StarY,-6,0,0,100
	MOVESTAR StarY,-4,1,-1,5
	MOVESTAR StarZ,-5,1,-1,100
	MOVESTAR StarZ,-5,0,0,20
	MOVESTAR StarZ,-5,359,1,100
	MOVESTAR StarZ,-8,0,0,100
	MOVESTAR StarZ,-6,0,0,5
	MOVESTAR StarZ,4,0,0,5
	MOVESTAR StarZ,8,0,0,5
	MOVESTAR StarZ,18,0,0,100
	MOVESTAR StarZ,14,1,1,5
	MOVESTAR StarZ,14,1,1,100
	MOVESTAR StarZ,12,1,1,5
	MOVESTAR StarZ,12,1,0,100
	MOVESTAR StarZ,10,1,1,5
	MOVESTAR StarZ,10,359,-1,100
	MOVESTAR StarZ,8,1,1,5
	MOVESTAR StarZ,8,359,0,100
	MOVESTAR StarZ,6,1,1,5
	MOVESTAR StarZ,8,1,-1,100
	MOVESTAR StarZ,4,1,1,100

	dc.w	-1

NextChange	dc.w	0
Screen		dc.l	0
StarMemory	ds.b	NumberStars*StarSize


