
; Listing17e3.s = Helix.s
*****************************************************************************
; HELIX - coded by Dan Phillips  19 Jan 93
;
; Modified by Randy/Ram Jam in 1995
*****************************************************************************

;	Use joystick to move Helix!

	SECTION BITPLANE,CODE

;	include	"DaWorkBench.s"	; entferne das; vor dem Speichern mit "wo"

*****************************************************************************
	include	"/Sources/startup2.s"	; speichern interrupt, dma etc.
*****************************************************************************


; Mit DMASET entscheiden wir, welche DMA-Kanäle geöffnet und welche geschlossen werden

			;5432109876543210
DMASET	equ	%1000001110000000	; Copper, Bitplane DMA aktiviert

WaitDisk	equ	10	; 50-150 zur Rettung (soweit zutreffend)

PlaneSize:	equ	40*256			; 10240

Start:

; Zeiger auf unsere 3 Bitplanes:

	move.l	#Bitplane,d0			; Adressen Bitplanes
	move.w	d0,onelo
	swap	d0
	move.w	d0,onehi
	swap	d0
	add.l	#PlaneSize,d0
	move.w	d0,twolo
	swap	d0
	move.w	d0,twohi
	swap	d0
	add.l	#PlaneSize,d0
	move.w	d0,thrlo
	swap	d0
	move.w	d0,thrhi

; Variablen setzen

	move.w	#1,RotationSpeed
	move.w	#3,Tightness

; Zeiger Copperlist

	lea	$dff000,a5
	move.w	#DMASET,$96(a5)		; DMACON - aktivieren Bitplane, Copper
								; und Sprites.
	move.l	#Copperlist,$80(a5)	; Zeiger Copperlist
	move.w	d0,$88(a5)			; Start Copperlist
	move.w	#0,$1fc(a5)			; AGA "deaktivieren"
	move.w	#$c00,$106(a5)		; AGA "deaktivieren"
	move.w	#$11,$10c(a5)		; AGA "deaktivieren"

Mouse:
	move.l	#$1ff00,d1			; Bits durch UND auswählen
	move.l	#$0d000,d2			; warte auf Zeile $d0
WaitY1:
	move.l	4(a5),d0			; VPOSR und VHPOSR - $dff004/$dff006
	and.l	d1,d0				; wählen Sie nur die Bits der vertikalen Pos.
	cmp.l	d2,d0				; warte auf Zeile $d0
	bne.s	WaitY1

	movem.l	d0-d7/a0-a6,-(sp)

	bsr.s	Joystick
	bsr.w	MakeHelix			; make new data & draw it  

	movem.l	(sp)+,d0-d7/a0-a6

	move.l	#$1ff00,d1			; Bits durch UND auswählen
	move.l	#$0d000,d2			; warte auf Zeile $d0
WaitY2:
	move.l	4(a5),d0			; VPOSR und VHPOSR - $dff004/$dff006
	and.l	d1,d0				; wählen Sie nur die Bits der vertikalen Pos.
	cmp.l	d2,d0				; warte auf Zeile $d0
	beq.s	WaitY2

	btst	#6,$bfe001			; linke Maustaste gedrückt?
	bne.s	Mouse
	rts							; exit


******************************************************************************
; Routine, die den Joystick liest und die Effektwerte ändert, 
; Ändern der beiden Variablen RotationSpeed und Tightness
******************************************************************************

Joystick:
	bsr.w	ReadJoystick		; Lese joystick
	move.w	StickX(pc),d0		; rechts links = 1/-1
	move.w	RotationSpeed(pc),d1	; Speed aktuell
	add.w	d0,d1				; Mehrwert links / rechts, dh +1
								; wenn richtig, -1 wenn links
	move.w	d1,d0
	bpl.s	Poa
	neg.w	d0
Poa:
	cmpi.w	#360,d0				; sind wir angekommen 360?
	bcc.s	TooBig				; Wenn nicht, ok
	move.w	d1,RotationSpeed	; Ansonsten bleib bei 360, das ist das Maximum!
TooBig:
	addq.w	#1,Slow				; wir verlangsamen die Geschwindigkeitsänderung ein wenig.
	cmp.w	#3,Slow				; sind wir angekommen 3?
	bne.s	too					; Wenn noch nicht warten
	clr.w	Slow				; Setzen Sie die langsame Var zurück

	move.w	StickY(pc),d0		; oben/unten = -1/1
	move.w	Tightness(pc),d1
	add.w	d0,d1				; addiere Y-Wert aus Freude

	move.w	d1,d0
	bpl.s	Pos
	neg.w	d0
Pos:
	cmpi.w	#360,d0				; sind wir maximal?
	bcc.s	Too
	move.w	d1,Tightness		; wenn du bei 360 bleibst
Too:
	rts

Slow:	dc.w	0

;---------------------- subroutine liest joystick --------------------
;
; Beim Rausgehen geben die Variablen StickX und StickY die Richtung rechts / links 
; hoch / runter an: wenn hoch, StickY = -1, wenn runter, StickY = 1
; wenn rechts StickX = 1, wenn links StickX = -1.
; Auch Feuer = 0 oder 1, wenn der Feuerknopf gedrückt wird.

ReadJoystick:
	move.w	#0,Fire
	btst	#7,$bfe001			; Feuerknopf gedrückt?
	bne.s	NoFire				; Wenn nicht, fahren Sie fort
	move.b	#1,Fire				; Anderes Feuer=1
NoFire:
	clr.w	StickX				; Variablen zurücksetzen
	clr.w	StickY
	move.w	$dff00c,d3			; joy1dat in d3
	move.w	d3,d1
	lsr.w	#1,d1
	eor.w	d3,d1
	btst.l	#0,d1				; unten?
	bne.s	Jback				; wenn ja, StickY=1
	btst.l	#8,d1
	bne.s	Jforward
	bra.s	Jx

Jback:
	move.w	#1,StickY			; unten, StickY=1
	bra.s	Jx

Jforward:
	move.w	#-1,StickY			; oben, StickY=-1

; Überprüfen Sie links-rechts

Jx:
	btst.l	#9,d3
	beq.s	Jon3
	move.w	#-1,StickX			; links, StickX=-1
	rts

Jon3:
	btst.l	#1,d3
	beq.s	Jon4
	move.w	#1,StickX			; rechts, StickX=1
Jon4:
	rts

StickX:
	dc.w	0
StickY:
	dc.w	0
Fire:
	dc.w	0

******************************************************************************
; Routine, die den Effekt für den Bildschirm verschiebt
******************************************************************************

CenterOfScreen:	equ	160

ElementSize:	equ	4			; size of each entry


MakeHelix:
	lea	SaveArray,a6
	moveq	#0,d7				; counter
	move.w	AngleTop(pc),d0
	add.w	RotationSpeed(pc),d0
	bpl.s	ok
	addi.w	#360,d0
	bra.s	Cont

Ok:
	cmpi.w	#360,d0
	bcs.s	Cont
	subi.w	#360,d0
Cont:
	move.w	d0,AngleTop
	move.w	d0,CurrentAngle

Doit:
	tst.l	(a6)
	beq.s	Skip
	move.l	(a6),a0
	clr.l	(a0)
	lea	PlaneSize(a0),a0
	clr.l	(a0)
	lea	PlaneSize(a0),a0
	clr.l	(a0)
Skip:
	move.w	CurrentAngle(pc),d0
	add.w	Tightness(pc),d0

	bpl.s	Ok2
	addi.w	#360,d0
	bra.s	Cont2
Ok2:
	cmpi.w	#360,d0
	bcs.s	Cont2
	subi.w	#360,d0
Cont2:
	move.w	d0,CurrentAngle
	bsr.s	Cosine				; find x co.
	addi.w	#CenterOfScreen,d0
	move.w	d0,Xvalue			; save this for now

;draw it
	lea	Bitplane,a0
	move.w	d7,d0				; work out which line
	move.w	d7,d1
	asl.w	#5,d0				; x 40
	asl.w	#3,d1
	add.w	d1,d0
	adda.w	d0,a0

	move.w	Xvalue(pc),d0
	asr.w	#4,d0				; x/16
	move.w	d0,d1				; save this
	asl.w	#1,d0				; convert to bytes
	adda.w	d0,a0
	move.l	a0,(a6)				; save this while we're here

	move.w	Xvalue(pc),d0
	asl.w	#4,d1
	sub.w	d1,d0				; shift value

	moveq	#2,d2
	lea	BobData,a1
Next:
	moveq	#0,d1
	move.w	(a1)+,d1
	swap	d1
	lsr.l	d0,d1				; just like the blitter!
	move.l	d1,(a0)				; draw it
	lea	PlaneSize(a0),a0
	dbf	d2,Next

	addq.w	#ElementSize,a6
	addq.w	#1,d7
	cmpi.w	#150,d7
	bne.w	Doit
	rts	

Xvalue:		dc.w	0
CurrentAngle:	dc.w	0
AngleTop:	dc.w	0
Tightness:	dc.w	0
RotationSpeed:	dc.w	0

Cosine:							; d0 angle, returns cos in d0
	move.l	a6,-(sp)
	bsr.w	sok
	move.l	(sp)+,a6
	rts

sok:
	lea	CosTable(pc),a6
	cmpi.w	#90,d0
	bcc.s	gt90
	asl.w	#1,d0				; < 90
	move.w	0(a6,d0.w),d0
	rts

gt90:
	cmpi.w	#180,d0
	bcc.s	gt180
	move.w	#180,d1				; 90 < a < 180
	sub.w	d0,d1
	move.w	d1,d0
	asl.w	#1,d0
	move.w	0(a6,d0.w),d0
	neg.w	d0
	rts	

gt180:
	cmpi.w	#270,d0
	bcc.s	gt270

	subi.w	#180,d0				; 180 < a < 270
	asl.w	#1,d0
	move.w	0(a6,d0.w),d0
	neg.w	d0
	rts

gt270:
	move.w	#360,d1				; 270 < a <360
	sub.w	d0,d1
	move.w	d1,d0
	asl.w	#1,d0
	move.w	0(a6,d0.w),d0
	rts


BobData:
	dc.w	$cccc,$3c3c,$03fc

CosTable:
	dc.w	100,100,100,100,100,100,99,99,99,99,98,98,98,97,97,97
	dc.w	96,96,95,95,94,93,93,92,91,91,90,89,88,87,87,86,85,84
	dc.w	83,82,81,80,79,78,77,75,74,73,72,71,69,68,67,66,64,63
	dc.w	62,60,59,57,56,54,53,52,50,48,47,45,44,42,41,39,37,36
	dc.w	34,33,31,29,28,26,24,22,21,19,17,16,14,12,10,9,7,5,3,2,0

******************************************************************************
;				Copperlist
******************************************************************************

		SECTION	GRAPHIC,DATA_C
Copperlist:
	dc.w	$108,0				; BPL1MOD
	dc.w	$10a,0				; BPL2MOD
	dc.w	$92,$38				; DDFSTRT
	dc.w	$94,$d0				; DDFSTOP
	dc.w	$8e,$2c81			; DIWSTRT
	dc.w	$90,$2cc1			; DIWSTOP
	dc.w	$102,0				; BPLCON1
	dc.w	$104,0				; BPLCON2
	dc.w	$100,$3200			; BPLCON0 - 3 Bitplanes lowres (8 Farben)

	dc.w	$e0					; bpl0pth
onehi:
	dc.w	0
	dc.w	$e2					; bpl0ptl
onelo:
	dc.w	0
	dc.w	$e4					; bpl1pth
twohi:
	dc.w	0
	dc.w	$e6					; bpl1ptl
twolo:
	dc.w	0
	dc.w	$e8					; bpl2pth
thrhi:
	dc.w	0
	dc.w	$ea					; bpl2ptl
thrlo:
	dc.w	0

	dc.w	$180,$000			; COLOR00
	dc.w	$182,$fff			; COLOR01
	dc.w	$184,$ddd			; COLOR02
	dc.w	$186,$bbb			; COLOR03
	dc.w	$188,$999			; COLOR04
	dc.w	$18a,$777			; COLOR05
	dc.w	$18c,$555			; COLOR06
	dc.w	$18e,$333			; COLOR07

	dc.w	$ffff,$fffe			; Ende Copperlist

******************************************************************************
;				BITPLANES
******************************************************************************

		SECTION	LEEREPLANE,BSS_C

Bitplane:
	ds.b	PlaneSize*3


******************************************************************************

		SECTION	BUFFER,BSS

SaveArray:
	ds.b	256*ElementSize		; 256 Zeilen

	end
