

** CODE		ASTEROID FIELD
** CODER 	MARC .B

** THANK'S TO MIKE CROSS
** FOR HIS EXCELLENT SPRITE TUTORIAL AND STAR-FIELD CODE **

; this code attempts to recreate the asteroid field effect
; seen in many games like lunar lander etc.....

		
	   
***	system calls	***

execbase	equ	4
openlibrary	equ	-408
closelibrary	equ	-414
allocmem	equ	-198
freemem		equ	-210
forbid		equ	-132
permit		equ	-138
copymem		equ	-624


***	constants	***

chip		equ	2
clear		equ	$10000
number_field	equ	12
max_speed	equ	2


*** 	include	hardware.i	***

	include	source:include/hardware.i

	lea	$dff000,a5			;custom base address


**********************************************************
*	OPEN GFX LIBRARY AND SAVE SYSTEM COPPER		 *
**********************************************************

	move.l	execbase,a6
	move.l	#gfxname,a1
	moveq	#0,d0
	jsr	openlibrary(a6)
	tst	d0			
	beq	the_end			
	move.l	d0,gfxbase		
	move.l	d0,a0			;put gfxbase in a0 
	move.l	38(a0),systemcopper	;save the copper address 


****************************************************
*	ALLOCATE MEMORY FOR BIT PLANES		   *
****************************************************

	move.l	execbase,a6
	move.l	#(320/8*256)*2,d0	;memory for 2 bitplanes
	move.l	#chip+clear,d1		;chip memory and wipe it 
	jsr	allocmem(a6)
	tst	d0			;fail 
	beq	exit			;yep 
	move.l	d0,bitbase		;save  pointer



*******************************************************
*	  ALLOCATE MEMORY FOR ASTEROIDS		      *
*******************************************************

	move.l	execbase,a6
	move.l	#number_field*spritelen,d0	;total bytes needed
	move.l	#chip+clear,d1
	jsr	allocmem(a6)			;get the memory
	tst	d0				;course it worked
	beq	exit1				;no it didn't
	move.l	d0,spritebase			;save sprite address

*********************************************************
*		COPY SPRITES TO MEMORY			*
*********************************************************

copy_sprites
	move.l	#number_field-1,d7
	move.l	spritebase,a1

copy_loop
	move.l	#sprite,a0
	move.l	#spritelen,d0
	move.l	execbase,a6
	jsr	copymem(a6)
	dbf	d7,copy_loop


*****************************************************************
*	LOAD BITPLANE AND SPRITE POINTERS INTO COPPER LIST      *
*****************************************************************


	move.l	bitbase,d0
	lea	copper,a0
	move.w	d0,6(a0)	;load bitplane pointers into c list
	swap	d0
	move.w	d0,2(a0)
	swap	d0
	add.l	#$2800,d0
	move.w	d0,14(a0)
	swap	d0
	move.w	d0,10(a0)
	swap d0
	move.l	spritebase,d1	;load sprite pointer into c list
	move.w	d1,22(a0)
	swap	d1
	move.w	d1,18(a0)
	swap	d1


*********************************************************************
*		    MAKE ASTERIOD FIELD				    *
*********************************************************************


setup_field

	move.l	spritebase,a0		;address of sprite memory
	move.w	#number_field-1,d7	;set loop counter
	move.w	#75,d0			;initial y position
	move.l	#0,d2			;set y overflow flag to zero
	move.w	#$301f,d3
	move.w	#$5512,d5		;random number seeds

make_field
	move.w	VHPOSR(a5),d4
	or.l	d3,d5
	add.l	d4,d5
	move.b	d0,(a0)+		;y position  ( 1st control word)
	move.b	d5,(a0)+		;x position  (random)
	add.w	#13,d0			;incrememt y position
	move.b	d0,(a0)+		;set display stop byte (2nd ctrl word)
	move.b	d2,(a0)+		;set y overflow
	add.w	#52,a0			;point to next sprite
	add.w	#3,d0			;increase y position
	cmpi.w	#238,d0			;reached bottom of screen ?
	bls	okay			;not there yet !!
	move.w	#0,d0			;reset y counter
	move.w	#6,d2			;set overflow flag
okay
	dbf	d7,make_field		;build till d7 = 0
	

	
***************************************************************
*		START CUSTOM COPPER LIST		      *
***************************************************************	

	move.l	#copper,COP1LCH(a5)
	move.l	#0,COPJMP1(a5)
	move.l	execbase,a6
	jsr	forbid(a6)

*************************************************************
*		    MAIN CODE LOOP    			    *
*************************************************************

wait
	move.l	VPOSR(a5),d0	;read current beam position
	and.l	#$0001ff00,d0	;mask all but the vertical pos
	lsr.l	#8,d0		
	cmp.w	#$0106,d0	;wait for end of display
	bne	wait
	bsr	move_field	;move field
	btst	#6,CIAAPRA	;check mouse button status
	beq	clean_up	;exit if left button pressed
	bra	wait

**********************************************************
*			RESTORE SYSTEM 			 *
**********************************************************

clean_up
	move.l	systemcopper,COP1LCH(a5)
	move.l	#0,COPJMP1(a5)
	move.l	execbase,a6
	jsr	permit(a6)
	move.l	execbase,a6		  
	move.l	#number_field*spritelen,d0
	move.l	spritebase,a1
	jsr	freemem(a6)


exit1
	move.l	execbase,a6		;free bitplane memory
	move.l	#(320/8*256)*2,d0
	move.l	bitbase,a1
	jsr	freemem(a6)

exit
	move.l	gfxbase,a1		;close the graphics library
	move.l	execbase,a6
	jsr	closelibrary(a6)
	
the_end
	rts				;exit from program



***************************************************************
* 		     MOVE ASTEROID FIELD		      *
***************************************************************

move_field
	move.l	spritebase,a0
	move.w	#(number_field/2)-1,d7	;the number of stars is divided
	moveq.w	#1,d1			;by 2 because ths sprites are moved
					;two at a time in the field_loop

field_loop
	add.b	d1,1(a0)		;move sprite right
	add.w	#56,a0			;point to next sprite
	sub.b	d1,1(a0)		;move it left
	add.w	#56,a0			;point to next sprite
	addq.b	#1,d1			;increase speed
	cmpi.b	#max_speed,d1		;check it
	ble	speed_okay
	moveq.b	#1,d1			;to fast reset speed counter

speed_okay
	dbf	d7,field_loop
	rts



***********************************************************
*		   CUSTOM COPPER LIST			  *
***********************************************************

	SECTION		copper.list,CODE_C

copper
	dc.w	BPL1PTH,0000		;next 4 blank words
	dc.w	BPL1PTL,0000		;are where we load
	dc.w	BPL2PTH,0000		;the bitplane pointers
	dc.w	BPL2PTL,0000
	dc.w	SPR0PTH,0000
	dc.w	SPR0PTL,0000		;sprite 0 pointer
	dc.w	SPR1PTH,0000
	dc.w	SPR1PTL,0000		;sprite 1 pointer
	dc.w	SPR2PTH,0000
	dc.w	SPR2PTL,0000		;sprite 2 pointer
	dc.w	SPR3PTH,0000
	dc.w	SPR3PTL,0000		;sprite 3 pointer
	dc.w	SPR4PTH,0000
	dc.w	SPR4PTL,0000		;sprite 4 pointer
	dc.w	SPR5PTH,0000
	dc.w	SPR5PTL,0000		;sprite 5 pointer
	dc.w	SPR6PTH,0000
	dc.w	SPR6PTL,0000		;sprite 6 pointer
	dc.w	SPR7PTH,0000
	dc.w	SPR7PTL,0000		;sprite 7 pointer
	dc.l 	$2b01fffe		;wait for line 43
	dc.w	DIWSTRT,$2c81		;where we start displaying
	dc.w	DIWSTOP,$2cc1		;where we stop!
	dc.w	BPLCON0,$0200		;this is for Amiga 1000 owners
	dc.w	BPLCON2,$0024		
	dc.w	DDFSTRT,$0038		;where to start the horizontal display
	dc.w	DDFSTOP,$00d0		;and where we stop
	dc.w	BPLCON1,$0000
	dc.w	BPL1MOD,$0000		;not a scroller
	dc.w	BPL2MOD,$0000		;so these are blank
	dc.w	COLOR00,$0000		;background colour black
	dc.w	COLOR01,$0fff		;colour 1 
	dc.w	COLOR02,$0e00		;colour 2 
	dc.w	COLOR03,$00a1		;colour 3 
	dc.w	COLOR04,$0d80
	dc.w	COLOR05,$0c70
	dc.w	COLOR06,$0c71
	dc.w	COLOR07,$0b61
	dc.w	COLOR08,$0b62
	dc.w	COLOR09,$0a52
	dc.w	COLOR10,$0a52
	dc.w	COLOR11,$0fb0
	dc.w	COLOR12,$000f
	dc.w	COLOR13,$0f00
	dc.w	COLOR14,$0f82
	dc.w	COLOR15,$0ff3
	dc.w	COLOR16,$0000
	dc.w	COLOR17,$0d80
	dc.w	COLOR18,$0b61
	dc.w	COLOR19,$0a52
	dc.w	COLOR20,$0333
	dc.w	COLOR21,$0444
	dc.w	COLOR22,$0555
	dc.w	COLOR23,$0666
	dc.w	COLOR24,$0777
	dc.w	COLOR25,$0888
	dc.w	COLOR26,$0999
	dc.w	COLOR27,$0aaa
	dc.w	COLOR28,$0ccc
	dc.w	COLOR29,$0ddd
	dc.w	COLOR30,$0eee
	dc.w	COLOR31,$06f8
	dc.l	$2c01fffe		;wait for line 44
	dc.w	BPLCON0,$2200		;turn on bit planes
	dc.l	$fffffffe		;wait for the impossible
endcopper

copperlen	equ	endcopper-copper

************************************************************
*		SPRITE DATA SECTION			   *
************************************************************

sprite

	dc.w	$0000,$0000	SPRxPOS,SPRxCTL
	dc.w	$0000,$0000
	dc.w	$0080,$0080
	dc.w	$03d0,$00c0
	dc.w	$0258,$0040
	dc.w	$36d8,$0000
	dc.w	$3cdc,$0010
	dc.w	$6fba,$0638
	dc.w	$37b3,$3300
	dc.w	$1dbb,$1180
	dc.w	$1ee2,$1000
	dc.w	$0126,$0000
	dc.w	$00dc,$00c0
	dc.w	$0070,$0060
endsprite

	
spritelen	equ	endsprite-sprite
	
	
************************************************************
*			VARIABLES	 		   *
************************************************************


gfxbase		dc.l 0
bitbase		dc.l 0
systemcopper	dc.l 0
spritebase	dc.l 0
gfxname		dc.b 'graphics.library',0


end
	
