	.include	'eq.s'
	.include	'externs.s'

	.text

anim_enemies::
	clr.w	d6
	lea		enemy0,a1				;first enemy object header
	lea		en_an_chg,a2			;when to change en_an_step
	lea		en_an_time,a3			;limit for en_an_chg
	lea		en_an_step,a4			;enemy animation step
	lea		en_action,a5			;enemy action
.10:
	tst.b	O_TYPE(a1)
	bmi		.50					;skip if delete flag is on
	move.w	O_DESC(a1),d4			;enemy is an explosion if >= $80
	bmi		.50
	lsl.w	#2,d4				;enemy type * 4 actions for each enemy
	clr.w	d5
	move.b	(a5,d6.w),d5			;get enemy action
	add.w	d4,d5				;add enemy type * 4 to enemy action (save this for later)
;d4 = enemy type * 4
;d5 = enemy type * 4 + enemy action

	addq.b	#1,(a2,d6.w)			;increase en_anim_chg
	move.b	(a2,d6.w),d2			;get en_an_chg
	cmp.b	(a3,d6.w),d2			;see if en_an_chg has reached en_an_time yet
	bcs		.30					;branch if d2 < (a3,d6.w)
	clr.b	(a2,d6.w)				;reset en_an_chg
	addq.b	#1,(a4,d6.w)			;increase en_an_step
	move.b	(a4,d6.w),d2			;current en_an_step
	lea		en_steps,a6
	cmp.b	(a6,d5.w),d2			;compare anim steps for this enemy type and action to current en_an_step
	bcs.b	.20					;exit if current < total
	clr.b	(a4,d6.w)				;reset animation step
	lea		en_fired,a6
	clr.b	(a6,d6.w)				;reset en_fired flag
	cmp.b	#EN_DYING,(a5,d6.w)		;see if enemy is dying
	bne.b	.15
	bsr		start_explosion		;start explosion after dying animation is done
	bra		.50
.15:
	move.b	(a5,d6.w),d0			;get current action
	move.b	#EN_MOVING,(a5,d6.w)	;switch from current action to new action
	lea		atk_chnc,a6
	move.b	(a6,d6.w),d1			;get atk_chnc for this enemy
	beq.b	.30					;if 0, this type of enemy does not attack
	bsr		random
	cmp.b	d1,d0				;compare random byte to chance of attacking
	bcc.b	.30					;branch if random number < chance of attack (don't attack)
.18:	cmp.w	#PLR_PLAY,player+O_DESC
	bne		.30					;don't attack if player is not playing
	move.b	#EN_ATTACK,(a5,d6.w)	;switch from current action to new action
.20:	cmp.b	#EN_ATTACK,(a5,d6.w)	;check enemy action
	bne.b	.30					;if not attacking, don't try to shoot
	lea		shstart,a6			;which anim step to start shot
	move.b	(a4,d6.w),d1			;get current anim step
	cmp.b	(a6,d4.w),d1			;compare 1st shot start anim step to current step
	beq.b	.25					;if current anim step = step to start shot, shoot
	cmp.b	1(a6,d4.w),d1			;compare 2nd shot start anim step to current step
	beq.b	.25
	cmp.b	2(a6,d4.w),d1			;compare 3rd shot start anim step to current step
	beq.b	.25
	cmp.b	3(a6,d4.w),d1			;compare 4th shot start anim step to current step
	bne.b	.30
.25:
	bsr		en_shoot				;make enemy fire a shot
.30:
	lea		en_chg_times,a6		;table of times for each en_action
	move.b	(a6,d5.w),(a3,d6.w)		;get limit for en_an_chg depending on en_action

	move.w	O_DESC(a1),d0
	mulu		#80,d0				;for each enemy - 80 bytes for animation addresses (4 actions: 4 bytes, 12 bytes, 32 bytes, 32 bytes)

	lea		act_ofst,a6
	clr.w	d1
	move.b	(a5,d6.w),d1			;get enemy action
	lsl.w	#1,d1				;action * 2
	add.w	(a6,d1.w),d0			;get bytes to skip in en_an_table for each action, add to enemy_type * 80
	cmp.w	#EN_MOVING*2,d1
	bne.b	.35
	lea		en_altmv,a6
	cmp.b	#1,(a6,d6.w)			;see if enemy is using alternate moving animation
	bne.b	.35
	add.w	#16,d0				;use second set of 16 moving animation steps
.35:
	move.b	(a4,d6.w),d1			;high byte was already cleared
	add.w	d1,d0				;add current anim step for this enemy
	lea		en_an_table,a6
	move.b	(a6,d0.w),d1			;get frame number to use
	lsl.w	#2,d1				;4 bytes per data address
	lea		en_an,a6
	move.w	O_DESC(a1),d0			;get enemy type
	lsl.w	#3,d0				;2 addresses, 4 bytes per address
	move.l	(a6,d0.w),a0			;get address of list of data addresses for this enemy
	move.l	(a0,d1.w),O_DATA(a1)	;get address from list, use it as the data address
	move.l	4(a6,d0.w),a0			;get address of table of heights for each frame number
	cmpa.l	#0,a0				;can't just do beq here, need to do cmp #0
	beq.b	.38					;if 0, no height adjustment needed
	lsr.w	#1,d1				;change frame number * 4 to frame number * 2
	move.w	(a0,d1.w),O_HEIGHT(a1)

.38:	clr.w	d1
	move.b	(a5,d6.w),d1			;get enemy action
	lsr.w	#1,d0				;change enemy type * 8 to enemy type * 4
	add.w	d1,d0				;add enemy action to enemy type * 4 that is already in D0
	lea		en_actdw,a6			;dwidth, iwidth for each action
	move.b	(a6,d0.w),d0
	and.w	#$00FF,d0				;clear high byte
	move.w	d0,O_DWIDTH(a1)
	move.w	d0,O_IWIDTH(a1)

	cmp.w	#GEYSER,O_DESC(a1)
	bne.b	.40
	bsr		adj_geys
	bra.b	.50
.40:	cmp.w	#SNAKE,O_DESC(a1)
	bne.b	.50
	bsr		adj_snk

.50:
	adda.l	#OBJ_SIZE,a1			;next object header
	addq.w	#1,d6				;enemy counter
	cmp.w	#TOTAL_ENEMIES,d6		;total enemies
	bne		.10
	rts

adj_geys::
;adjust ypos of geyser
;this is called by anim_enemies, so lots of pointers are already set
;DON'T CHANGE THEM!!
	clr.w	d0
	move.b	(a4,d6.w),d0			;get anim step for this enemy number
	lsl.b	#1,d0

	tst.b	(a2,d6.w)				;check en_an_chg for this enemy number
	bne.b	.90					;if not 0, anim step did not change since last time
	lea		geys_y,a6				;ok to use a6, not needed by anim_enemies
	move.w	(a6,d0.w),d0			;get ypos adjustment
	add.w	O_YPOS(a1),d0			;add current ypos
	or.w		#1,d0
	move.w	d0,O_YPOS(a1)			;new ypos
.90:	rts

geys_y::
;adjustment to geyser ypos when anim step changes
	dc.w		   0, -24, -40, -74, -78,-148, -90,  90, -90,  90, -90,  90, -90,  90, 148,  78,  74,  40,  24

adj_snk::
;adjust height and dwidth of snake
;this is called by anim_enemies, so lots of pointers are already set
;don't change them!!!
	clr.w	d0
	move.b	(a4,d6.w),d0			;get anim step for this enemy
	lsl.b	#1,d0
	cmp.b	#EN_APPEAR,(a5,d6.w)	;check enemy action
	beq.b	.20
	lea		snk_dw,a6
	move.w	(a6,d0.w),O_DWIDTH(a1)
	move.w	(a6,d0.w),O_IWIDTH(a1)	
.20:	rts

snk_dw::
;dwidth while moving or attacking
	dc.w		12,12,12,12,12,12,12,12,16,16,16,20,20,24,24,24,24,24,20,20,16,16,16,12,12,12,12,12,12,12

adjbspos::
;adjust the position of the boss enemies with separate parts
	tst.b	bossmade				;see if the last enemy has been created yet
	beq.b	.90					;if boss enemy has not been created, exit

	move.w	levelx4,d0
	lea		boss_adj,a0
	move.l	(a0,d0.w),a0
	jsr		(a0)					;go to boss adjustment routine for current level
.90:	rts

adboss00::
;desert robot
	tst.w	enemy0+O_DESC
	bmi.b	.10						;don't adjust position of bottom piece if it is exploding
	move.w	enemy1+O_XPOS,enemy0+O_XPOS
	add.w	#48,enemy0+O_XPOS
	move.w	enemy1+O_YPOS,enemy0+O_YPOS
	add.w	#148,enemy0+O_YPOS
.10:
	tst.w	enemy1+O_DESC
	bpl.b	.30
	or.b		#DELETE_OBJ,enemy0+O_TYPE	;make sure bottom piece disappears when top piece explodes
	rts
.30:
	cmp.b	#2,levstatus
	beq.b	.70
	cmp.b	#1,gameover
	beq.b	.70
	cmp.b	#0,voicestatus+2		;see if spinning sound ended
	bne.b	.50					;if it is still playing, leave it alone
	move.w	#DESRBT0_SND,d0
	move.l	#$3FFF,d1				;xpos to determine pan value
	move.w	#2,d2				;voice number
	bsr		playvoice				;d0 = sample number, d1 = sound xpos
.50:
	cmp.b	#0,voicestatus+3		;see if spinning sound ended
	bne.b	.70					;if it is still playing, leave it alone
	move.w	#DESRBT1_SND,d0
	move.l	#$3FFF,d1				;xpos to determine pan value
	move.w	#3,d2				;voice number
	bsr		playvoice				;d0 = sample number, d1 = sound xpos
.70:
.90:	rts

adboss01::
;skull
;drawing order - arm, neck, ribs, back horn, head, front horn, nose horn

	cmp.b	#EN_ATTACK,en_action+4
	bne.b	.05
	move.b	#EN_ATTACK,en_action+1	;neck
	move.b	en_an_time+4,en_an_time+1
	move.b	en_an_step+4,en_an_step+1
	move.b	#EN_ATTACK,en_action+3	;back horn
	move.b	en_an_time+4,en_an_time+3
	move.b	en_an_step+4,en_an_step+3
	move.b	#EN_ATTACK,en_action+5	;front horn
	move.b	en_an_time+4,en_an_time+5
	move.b	en_an_step+4,en_an_step+5
	move.b	#EN_ATTACK,en_action+6	;nose horn
	move.b	en_an_time+4,en_an_time+6
	move.b	en_an_step+4,en_an_step+6

.05:	clr.w	d1
	clr.w	d0
	tst.w	enemy0+O_DESC
	bmi.b	.20					;don't adjust explosion
	move.b	en_an_step,d0			;get arm anim step
	lea		arm_dw,a0
	move.b	(a0,d0.w),d1			;get arm dwidth
	move.w	d1,enemy0+O_DWIDTH
	move.w	d1,enemy0+O_IWIDTH

.20:
	tst.w	enemy5+O_DESC
	bmi.b	.30					;don't adjust explosion
	move.b	en_an_step+5,d0		;get front horn anim step
	lea		hornf_dw,a0
	move.b	(a0,d0.w),d1			;get front horn dwidth
	move.w	d1,enemy5+O_DWIDTH
	move.w	d1,enemy5+O_IWIDTH

.30:
	move.w	enemy2+O_XPOS,d0		;get ribs xpos
	move.w	enemy2+O_YPOS,d1		;get ribs ypos

	lea		enemy0,a0				;arm object
	lea		arm_xy,a1
	move.b	en_an_step,d3			;arm anim step
	bsr		adj_skul

	lea		enemy1,a0				;neck object
	lea		neck_xy,a1
	move.b	en_an_step+1,d3		;neck anim step
	bsr		adj_skul

	lea		enemy3,a0				;back horn object
	lea		hornb_xy,a1
	move.b	en_an_step+3,d3		;back horn anim step
	bsr		adj_skul

	lea		enemy4,a0				;head object
	lea		head_xy,a1
	move.b	en_an_step+4,d3		;head anim step
	bsr		adj_skul

	lea		enemy5,a0				;front horn object
	lea		hornf_xy,a1
	move.b	en_an_step+5,d3		;front horn anim step
	bsr		adj_skul

	lea		enemy6,a0				;nose horn object
	lea		hornn_xy,a1
	move.b	en_an_step+6,d3		;nose horn anim step
	bsr		adj_skul

	tst.w	enemy4+O_DESC
	bpl.b	.90
	or.b		#DELETE_OBJ,enemy0+O_TYPE	;arm
	or.b		#DELETE_OBJ,enemy1+O_TYPE	;neck
	or.b		#DELETE_OBJ,enemy2+O_TYPE	;ribs
	or.b		#DELETE_OBJ,enemy3+O_TYPE	;back horn
	or.b		#DELETE_OBJ,enemy5+O_TYPE	;front horn
	or.b		#DELETE_OBJ,enemy6+O_TYPE	;nose horn
.90:	rts

adj_skul::
;a0 = enemy object header
;a1 = xy table
;d0 = ribs xpos
;d1 = ribs ypos
;d3 = anim step
	tst.w	O_DESC(a0)
	bmi.b	.90					;don't adjust explosion
	and.w	#$00FF,d3				;clear high byte
	lsl.w	#2,d3				;anim step * 4
	clr.w	d7
	move.w	(a1,d3.w),d7
	add.w	d0,d7				;add ribs xpos
	move.w	d7,O_XPOS(a0)

	add.w	#2,d3				;go to ypos
	move.w	(a1,d3.w),d7
	add.w	d1,d7				;add ribs ypos
	move.w	d7,O_YPOS(a0)
.90:	rts

neck_xy::
	dc.w		19,-50	;0
	dc.w		19,-50	;0
	dc.w		19,-50	;0
	dc.w		19,-50	;0
	dc.w		19,-50	;0
	dc.w		15,-38	;1
	dc.w		13,-28	;2
	dc.w		15,-38	;1
	dc.w		19,-50	;0
	dc.w		19,-50	;0
	dc.w		19,-50	;0
	dc.w		19,-50	;0
	dc.w		19,-50	;0
	dc.w		21,-50	;3
	dc.w		24,-50	;4
	dc.w		21,-50	;3

head_xy::
	dc.w		-44,-90	;0
	dc.w		-44,-90	;0
	dc.w		-44,-90	;0
	dc.w		-43,-94	;1
	dc.w		-37,-90	;2
	dc.w		-42,-76	;3
	dc.w		-52,-62	;4
	dc.w		-49,-78	;5
	dc.w		-44,-90	;0
	dc.w		-44,-90	;0
	dc.w		-44,-90	;0
	dc.w		-44,-90	;0
	dc.w		-44,-90	;0
	dc.w		-29,-92	;6
	dc.w		 -9,-94	;7
	dc.w		-29,-92	;6

arm_xy::
	dc.w		-113,22	;0
	dc.w		-71,-112	;1
	dc.w		-20,-138	;2
	dc.w		-53,-110	;3
	dc.w		-103,-26	;4
	dc.w		-114,20	;5

arm_dw::
	dc.b		 32		;0
	dc.b		 20		;1
	dc.b		  8		;2
	dc.b		 16		;3
	dc.b		 28		;4
	dc.b		 32		;5
	.even
hornb_xy::
	dc.w		-25,-168		;0
	dc.w		-25,-168		;0
	dc.w		-25,-168		;0
	dc.w		-25,-168		;0
	dc.w		-25,-168		;0
	dc.w		-38,-148		;1
	dc.w		-51,-126		;2
	dc.w		-38,-150		;3
	dc.w		-25,-168		;0
	dc.w		-35,-148		;4
	dc.w		-41,-128		;5
	dc.w		-34,-152		;6
	dc.w		-25,-168		;0
	dc.w		-35,-154		;7
	dc.w		-41,-144		;8
	dc.w		-35,-154		;7

hornf_dw::
	dc.b		  8		;0
	dc.b		 16		;1
	dc.b		 16		;2
	dc.b		 12		;3
	dc.b		  8		;0
	dc.b		  8		;4
	dc.b		  8		;5
	dc.b		  8		;6
	dc.b		  8		;0
	dc.b		  8		;0
	dc.b		  8		;0
	dc.b		  8		;0
	dc.b		  8		;0
	dc.b		  8		;7
	dc.b		  8		;8
	dc.b		  8		;7
	.even
hornf_xy::
	dc.w		21,-140		;0
	dc.w		-11,-116		;1
	dc.w		-25,-104		;2
	dc.w		-2,-124		;3
	dc.w		21,-140		;0
	dc.w		4,-108		;4
	dc.w		-11,-80		;5
	dc.w		6,-112		;6
	dc.w		21,-140		;0
	dc.w		21,-140		;0
	dc.w		21,-140		;0
	dc.w		21,-140		;0
	dc.w		21,-140		;0
	dc.w		26,-154		;7
	dc.w		27,-176		;8
	dc.w		26,-154		;7

hornn_xy::
	dc.w		-50,-76		;0
	dc.w		-50,-76		;0
	dc.w		-50,-76		;0
	dc.w		-50,-78		;0
	dc.w		-50,-76		;0
	dc.w		-61,-36		;1
	dc.w		-66,-2		;2
	dc.w		-60,-40		;3
	dc.w		-50,-76		;0
	dc.w		-50,-76		;0
	dc.w		-50,-76		;0
	dc.w		-50,-76		;0
	dc.w		-50,-76		;0
	dc.w		-36,-74		;4
	dc.w		-17,-80		;5
	dc.w		-36,-74		;4

adboss02::
;cave robot
	tst.w	enemy0+O_DESC
	bpl.b	.20					
	move.l	#-4,tablestart+(2*taboff)	;turn off spinning sound when robot is dead
	rts
.20:
	cmp.b	#1,gameover
	beq.b	.50
	cmp.b	#EN_MOVING,en_action
	bne.b	.50
	cmp.b	#0,voicestatus+2		;see if spinning sound ended
	bne.b	.50					;if it is still playing, leave it alone
	move.w	#CVROBOT0_SND,d0
	move.w	enemy0+O_XPOS,d1		;xpos to determine pan value
	move.w	#2,d2				;voice number
	bsr		playvoice				;d0 = sample number, d1 = sound xpos

	move.b	en_an_step,d0
	and.w	#$FF,d0
	lsl.w	#3,d0					;anim step * 8
	add.b	en_an_chg,d0				;add counter
	lea		cvrbtsnd,a0
	lsl.w	#2,d0
	lea		tablestart+(2*taboff),a1
	move.l	(a0,d0.w),(9*4,a1)

.50:	tst.b	player+O_TYPE
	bmi.b	.90						;don't shoot if player is not on screen
	cmp.b	#0,en_an_chg
	bne.b	.90
	cmp.b	#0,en_an_step
	bne.b	.90
	lea		enemy0,a1
	move.w	#0,d6
	move.w	#CVRBSH0,d1				;shot type
	bsr		shootbul

.90:	rts

cvrbtsnd::
;48 steps (8 spinning steps, step changes every 6 frames)
	dc.l		$0300,	$0500,	$0800,	$0A00,	$0D00,	$1000
	dc.l		$1300,	$1600,	$1800,	$1B00,	$1E00,	$2000
	dc.l		$2000,	$2300,	$2600,	$2800,	$2B00,	$2E00
	dc.l		$3000,	$3300,	$3600,	$3900,	$3C00,	$3F00
	dc.l		$4000,	$3F00,	$3C00,	$3900,	$3600,	$3300
	dc.l		$3000,	$2E00,	$2B00,	$2800,	$2600,	$2300
	dc.l		$2000,	$1E00,	$1B00,	$1800,	$1600,	$1300
	dc.l		$1000,	$0D00,	$0A00,	$0800,	$0500,	$0300


adboss03::
;quetzal
;drawing order - back arm, body, front arm, tail

	cmp.b	#1,gameover
	beq.b	.10
	cmp.b	#0,en_an_chg+1
	bne.b	.10
	cmp.b	#0,en_an_step+1
	bne.b	.10
	move.w	#QUET0_SND,d0
	move.w	enemy1+O_XPOS,d1		;xpos to determine pan value
	move.w	#2,d2				;voice number
	bsr		playvoice				;d0 = sound number, d1 = sound xpos
.10:
	clr.w	d1
	clr.w	d0
	tst.w	enemy0+O_DESC
	bmi.b	.30					;don't adjust explosion
	move.w	enemy1+O_XPOS,enemy0+O_XPOS
	add.w	#17,enemy0+O_XPOS
	move.w	enemy1+O_YPOS,enemy0+O_YPOS
	add.w	#124,enemy0+O_YPOS
.30:
	tst.w	enemy2+O_DESC
	bmi.b	.50					;don't adjust explosion
	move.w	enemy1+O_XPOS,enemy2+O_XPOS
	add.w	#30,enemy2+O_XPOS
	move.w	enemy1+O_YPOS,enemy2+O_YPOS
	add.w	#114,enemy2+O_YPOS
.50:
	tst.w	enemy3+O_DESC
	bmi.b	.60
	move.w	enemy1+O_XPOS,enemy3+O_XPOS
	add.w	#101,enemy3+O_XPOS
	move.w	enemy1+O_YPOS,enemy3+O_YPOS
	add.w	#124,enemy3+O_YPOS
.60:
	tst.w	enemy1+O_DESC
	bpl.b	.90
	or.b		#DELETE_OBJ,enemy0+O_TYPE	;back arm
	or.b		#DELETE_OBJ,enemy2+O_TYPE	;front arm
	or.b		#DELETE_OBJ,enemy3+O_TYPE	;tail
.90:	rts

adboss04::
;air robot
	cmp.b	#0,en_an_chg
	bne.b	.90
	cmp.b	#0,en_an_step
	bne.b	.50
	move.w	#AIRRBT0_SND,d0
	move.w	enemy0+O_XPOS,d1		;xpos to determine pan value
	move.w	#2,d2				;voice number
	bsr		playvoice				;d0 = sound number, d1 = sound xpos

.50:	clr.w	d0
	move.b	en_an_step,d0
	lsl.w	#1,d0
	lea		airrbt_y,a0
	move.w	(a0,d0.w),d0
	add.w	enemy0+O_YPOS,d0
	move.w	d0,enemy0+O_YPOS
.90:	rts

airrbt_y::
;add this to air robot ypos when anim step changes
	dc.w		-54		;from 7 to 0
	dc.w		0		;from 0 to 1
	dc.w		68		;from 1 to 2
	dc.w		40		;from 2 to 3
	dc.w		2		;from 3 to 4
	dc.w		-2		;from 4 to 5
	dc.w		-2		;from 5 to 6
	dc.w		-52		;from 6 to 7

adboss05::
;serpent
;drawing order - left wing, body, right wing

	cmp.b	#EN_ATTACK,en_action+1
	bne.b	.05
	move.b	#EN_ATTACK,en_action	;left wing
	move.b	en_an_time+1,en_an_time
	move.b	en_an_step+1,en_an_step
	move.b	#EN_ATTACK,en_action+2	;right wing
	move.b	en_an_time+1,en_an_time+2
	move.b	en_an_step+1,en_an_step+2

.05:	clr.w	d1
	clr.w	d0
	tst.w	enemy2+O_DESC
	bmi.b	.30					;don't adjust explosion
	move.b	en_an_step+2,d0		;get right wing anim step
	lea		rwng_xy,a1
	cmp.b	#EN_ATTACK,en_action+2
	bne.b	.10
	lea		rwng_xya,a1
.10:	lea		enemy2,a0				;right wing object
	move.b	en_an_step+2,d3		;right wing anim step
	bsr		adj_serp

.30:
	tst.w	enemy0+O_DESC
	bmi.b	.60					;don't adjust explosion
	clr.w	d0
	clr.w	d1
	move.b	en_an_step,d0			;get left wing anim step
	lea		lwng_dw,a2
	lea		lwng_xy,a1
	cmp.b	#EN_ATTACK,en_action
	bne.b	.35
	lea		lwng_dwa,a2
	lea		lwng_xya,a1
.35:	move.b	(a2,d0.w),d1			;get left wing dwidth
	move.w	d1,enemy0+O_DWIDTH
	move.w	d1,enemy0+O_IWIDTH
	lea		enemy0,a0				;left wing object
	move.b	en_an_step,d3			;left wing anim step
	bsr		adj_serp
.60:
	tst.w	enemy1+O_DESC
	bpl.b	.90
	or.b		#DELETE_OBJ,enemy0+O_TYPE	;left wing
	or.b		#DELETE_OBJ,enemy2+O_TYPE	;right wing

.90:	rts

adj_serp::
;a0 = enemy object header
;a1 = xy table
;d3 = anim step
	tst.w	O_DESC(a0)
	bmi.b	.90					;don't adjust explosion
	and.w	#$00FF,d3				;clear high byte
	lsl.w	#2,d3				;anim step * 4
	move.w	(a1,d3.w),d7
	add.w	enemy1+O_XPOS,d7		;add body xpos
	move.w	d7,O_XPOS(a0)

	add.w	#2,d3				;go to ypos
	move.w	(a1,d3.w),d7
	add.w	enemy1+O_YPOS,d7		;add body ypos
	move.w	d7,O_YPOS(a0)
.90:	rts

lwng_dw::
	dc.b		40,40,40,40,40,48,48,48
lwng_dwa::
	dc.b		40,40,40,40,40,40,48,48,48
	.even
lwng_xy::
	dc.w		10,	-12		;0
	dc.w		17,	-34		;1
	dc.w		16,	-42		;2
	dc.w		8,	-34		;3
	dc.w		5,	6		;5
	dc.w		3,	18		;6
	dc.w		1,	4		;7
	dc.w		3,	-10		;8
lwng_xya::
	dc.w		10,	-12		;0
	dc.w		17,	-34		;1
	dc.w		16,	-42		;2
	dc.w		8,	-34		;3
	dc.w		6,	-16		;4
	dc.w		5,	6		;5
	dc.w		3,	18		;6
	dc.w		1,	4		;7
	dc.w		3,	-10		;8

rwng_xy::
	dc.w		48,	76		;0
	dc.w		52,	74		;1
	dc.w		47,	76		;2
	dc.w		41,	78		;3
	dc.w		39,	78		;5
	dc.w		37,	78		;6
	dc.w		34,	78		;7
	dc.w		39,	76		;8
rwng_xya::
	dc.w		48,	76		;0
	dc.w		52,	74		;1
	dc.w		47,	76		;2
	dc.w		41,	78		;3
	dc.w		39,	78		;4
	dc.w		39,	78		;5
	dc.w		37,	78		;6
	dc.w		34,	78		;7
	dc.w		39,	76		;8

	.even

adboss06::
;weird robot
	move.w	enemy1+O_XPOS,d0		;xpos of body
	move.w	enemy1+O_YPOS,d1		;ypos of body
	clr.w	d2
	move.b	en_an_step+1,d2		;body animation step (2nd enemy)
	lsl.w	#1,d2				;2 bytes for each table entry

	tst.w	enemy0+O_DESC
	bmi.b	.20					;don't adjust explosion
;right arm position
	move.w	d0,d3				;get body xpos
	add.w	#3,d3
	move.w	d3,enemy0+O_XPOS
	move.w	d1,d3				;get body ypos
	add.w	#18,d3
	move.w	d3,enemy0+O_YPOS
.20:
	tst.w	enemy2+O_DESC
	bmi.b	.30					;don't adjust explosion
;tail position
	lea		wtl_x,a0
	move.w	(a0,d2.w),d3
	add.w	d0,d3				;add body xpos
	move.w	d3,enemy2+O_XPOS
	lea		wtl_y,a0
	move.w	(a0,d2.w),d3
	add.w	d1,d3				;add body ypos
	move.w	d3,enemy2+O_YPOS
.30:
	tst.w	enemy3+O_DESC
	bmi.b	.40					;don't adjust explosion
;left arm position
	move.w	d0,d3				;get body xpos
	sub.w	#16,d3
	move.w	d3,enemy3+O_XPOS
	move.w	d1,d3				;get body ypos
	add.w	#2,d3
	move.w	d3,enemy3+O_YPOS
.40:
	tst.w	enemy1+O_DESC
	bpl.b	.90
	or.b		#DELETE_OBJ,enemy0+O_TYPE	;right arm
	or.b		#DELETE_OBJ,enemy2+O_TYPE	;tail
	or.b		#DELETE_OBJ,enemy3+O_TYPE	;left arm
.90:
	rts
;tables for each animation step of the body
wtl_x::	dc.w		34,28,29,32,37,38				;add to body xpos to get tail xpos
wtl_y::	dc.w		226,226,226,224,224,224			;add to body ypos to get tail ypos

adboss07::
;mud man
	tst.w	enemy0+O_DESC
	bmi.b	.90					;don't adjust explosion
	clr.w	d0
	clr.w	d1
	move.b	en_an_step,d0			;get anim step
	lea		mud_dw,a0
	move.b	(a0,d0.w),d1			;get dwidth
	move.w	d1,enemy0+O_DWIDTH
	move.w	d1,enemy0+O_IWIDTH
	cmp.b	#EN_ATTACK,en_action
	bne.b	.90
	cmp.b	#0,en_an_chg
	bne.b	.90
	lea		mud_x,a0
	lsl.w	#1,d0				;anim step * 2
	move.w	(a0,d0.w),d1
	add.w	d1,enemy0+O_XPOS

.90:	rts

mud_x::
	dc.w		0	;from 0 to 0
	dc.w		12	;from 0 to 1
	dc.w		-34	;from 1 to 2
	dc.w		0	;from 2 to 3
	dc.w		9	;from 3 to 4
	dc.w		-73	;from 4 to 5
	dc.w		20	;from 5 to 6
	dc.w		32	;from 6 to 7
	dc.w		34	;from 7 to 0
mud_dw::
	dc.b		20,24,40,40,32,56,48,32,20
	.even

adboss08::
;city boss robot
	move.w	enemy0+O_XPOS,d0
	add.w	#1,d0
	move.w	d0,enemy1+O_XPOS
	move.w	enemy0+O_YPOS,d0
	sub.w	#18,d0
	move.w	d0,enemy1+O_YPOS

	tst.w	enemy0+O_DESC
	bpl.b	.90
	or.b		#DELETE_OBJ,enemy1+O_TYPE	;head
.90:	rts

adboss09::
;oddit
	tst.w	enemy1+O_DESC
	bmi		.80					;don't adjust explosion
	move.w	enemy1+O_XPOS,enemy0+O_XPOS
	move.w	enemy1+O_YPOS,enemy0+O_YPOS
.80:
	tst.w	enemy1+O_DESC
	bpl.b	.90
	or.b		#DELETE_OBJ,enemy0+O_TYPE
.90:
	rts

adboss10::
	rts


an_en_shots::
	lea		en_shot0,a0			;first enemy shot
	lea		en_sh_cnt,a1			;when to change en_sh_anm
	lea		en_sh_anm,a2			;enemy shot animation step
	lea		shot_data,a5			;object data
	clr.w	d5					;count shots
.10:
	tst.b	O_TYPE(a0)
	bmi.b	.50					;skip if delete flag is on
	addq.b	#1,(a1,d5.w)			;increase en_sh_cnt
	cmp.b	#4,(a1,d5.w)			;see if it is time to change anim step
	blt.b	.30					;don't change anim step if counter < 4
	clr.b	(a1,d5.w)				;reset en_sh_cnt
	addq.b	#1,(a2,d5.w)			;increase en_sh_anm
	cmp.b	#4,(a2,d5.w)			;4 anim steps for each shot
	blt.b	.30
	clr.b	(a2,d5.w)				;reset animation step
.30:
	move.w	O_DESC(a0),d0			;get enemy shot type
	lsl.w	#4,d0				;for each enemy - 4 anim steps * 4 bytes for each step
	clr.w	d1
	move.b	(a2,d5.w),d1			;get current anim step for this enemy
	lsl.w	#2,d1				;4 bytes for each step
	add.w	d1,d0
	move.l	(a5,d0.w),O_DATA(a0)	;set object data
.50:
	adda.l	#OBJ_SIZE,a0			;next object header
	addq.w	#1,d5				;enemy shot counter
	cmp.w	#MAX_ENEMY_SHOTS,d5
	blt.b	.10
	rts

get_en_distance::
	lea		enemy0,a0				;first enemy
	lea		dir_to_plr,a3			;direction from enemy to player
	lea		dirtomag,a4			;direction from enemy to magnet
	lea		track_dirs,a5
	lea		track_xy,a6			;distances away to player to aim for
	clr.w	d6					;count enemies
.10:	tst.b	O_TYPE(a0)			;see if enemy is active
	bmi		.60					;skip enemy if not active
	move.w	O_DESC(a0),d0
	bmi		.60					;don't do explosion
	clr.w	d3					;init quadrant number
	lsl.w	#2,d0				;enemy type * 4
	move.w	(a6,d0.w),d5			;get X distance away from player to aim for
	add.w	player+O_XPOS,d5		;add player xpos
	move.w	O_XPOS(a0),d1			;get enemy xpos
	sub.w	d5,d1				;enemy xpos - player xpos + offset
	bpl.b	.20
	neg.w	d1					;get absolute value of horiz distance
	addq.w	#2,d3				;horiz dir is right, use right quadrants
.20:	move.w	2(a6,d0.w),d5			;get Y distance away from player to aim for
	add.w	player+O_YPOS,d5		;add player ypos
	move.w	O_YPOS(a0),d2
	sub.w	d5,d2				;enemy ypos - player ypos + offset
	bpl.b	.30
	neg.w	d2					;get absolute value of vert distance
	addq.w	#4,d3				;horiz dir is down, use lower quadrants
.30:	bsr		got_quad				;sets d0 to offset for track_dirs
	move.b	(a5,d0.w),(a3,d6.w)		;save dir_to_plr

	tst.b	specweap+O_TYPE
	bmi.b	.60
	cmp.w	#MAGNET,specweap+O_DESC
	bne.b	.60
	clr.w	d3					;init quadrant number
	move.w	O_XPOS(a0),d1			;get enemy xpos
	sub.w	specweap+O_XPOS,d1		;enemy xpos - magnet xpos
	bpl.b	.40
	neg.w	d1					;get absolute value of horiz distance
	addq.w	#2,d3				;horiz dir is right, use right quadrants
.40:	move.w	O_YPOS(a0),d2
	sub.w	specweap+O_YPOS,d2		;enemy ypos - magnet ypos
	bpl.b	.50
	neg.w	d2					;get absolute value of vert distance
	addq.w	#4,d3				;horiz dir is down, use lower quadrants
.50:	bsr		got_quad				;sets d0 to offset for track_dirs
	move.b	(a5,d0.w),(a4,d6.w)		;save direction to magnet

.60:	adda.l	#OBJ_SIZE,a0			;next enemy object header
	addq.w	#1,d6				;enemy counter
	cmp.w	#TOTAL_ENEMIES,d6
	blt		.10
;get_enemy_dir
	cmp.w	#PLR_PLAY,player+O_DESC	;see if player is playing the game
	bne		.90					;if not, turn off tracking so enemies move away
	lea		enemy0,a0
	lea		en_moves,a1
	lea		dir_to_plr,a2
	lea		enemydir,a3
	lea		dirtomag,a4			;direction to magnet
	lea		en_action,a5
	lea		in_form,a6			;if enemy is in formation
	clr.w	d6
.70:	tst.b	O_TYPE(a0)			;see if enemy is active
	bmi.b	.80					;next enemy if this one is not active
	move.w	O_DESC(a0),d0			;get enemy type
	bmi.b	.80					;enemy is explosion if >= $80
	tst.b	specweap+O_TYPE
	bmi.b	.72
	cmp.w	#MAGNET,specweap+O_DESC
	bne		.72
	cmp.w	#FIRST_BOSS_ENEMY,O_DESC(a0)
	bge.b	.72
	move.b	(a4,d6.w),(a3,d6.w)		;use dirtomag as enemydir
	bra		.80
.72:
	cmp.b	#$FF,(a6,d6.w)			;enemy not in formation if $FF
	bne.b	.80					;if enemy is in formation, don't use dir to plr
	lsl.w	#2,d0				;enemy type * 4
	cmp.b	#EN_ATTACK,(a5,d6.w)
	bne.b	.75
	cmp.b	#1,1(a1,d0.w)			;see if enemy tracks player during an attack
	bra.b	.78
.75:	cmp.b	#1,(a1,d0.w)			;see if enemy tracks player while not attacking
.78:	bne.b	.80					;if not, next enemy
	move.b	(a2,d6.w),(a3,d6.w)		;use dir_to_plr as enemydir
	cmp.b	#8,(a3,d6.w)
	bge.b	.80					;if not moving right, don't need to check if enemy can move right
	cmp.b	#1,2(a1,d0.w)			;1 if enemy can move to the right
	beq.b	.80
	move.b	#12,(a3,d6.w)			;move left if tracking enemy can't move to the right
.80:	adda.l	#OBJ_SIZE,a0			;next enemy object header
	addq.w	#1,d6				;enemy counter
	cmp.w	#TOTAL_ENEMIES,d6
	blt		.70
.90:	rts

got_quad::
;d1 is absolute value of horizontal distance
;d2 is absolute value of vertical distance
;d3 is the offset for the quad table
;don't change a0, a3-a5, d6 in here
	cmp.w	d1,d2
	bge.b	vertmore				;vert dist > horiz distance
horizmore:						;horiz distance > vert distance here
	add.b	#1,d3				;use 2nd offset from quadofst table for track_dirs
	exg		d1,d2				;switch horiz and vert distances so lower one is in d1
vertmore:							;vert distance > horiz distance here
	mulu		#100,d1				;smaller distance * 100
	and.l	#$FFFF,d1				;remove high word
	tst.w	d2					;see if larger distance is 0
	bne.b	.80					;if not 0, use it as is
	moveq.l	#1,d2				;if larger distance is 0 (both are 0), avoid divide by zero error
.80:	divu		d2,d1				;smaller distance * 100 / vert = percentage
	and.l	#$FFFF,d1				;remove remainder in high
	divu		#34,d1				;divide result into thirds
	move.w	d1,d0				;save the result of 0, 1 or 2
	lea		quadofst,a2
	add.b	(a2,d3.w),d0			;add the offset from the quadofst table to 0, 1 or 2
.90:	rts
quadofst::						;offsets for track_dirs table
;first number is used if vert distance > horiz distance
;second number is used if horiz distance > vert distance
	dc.b		21,18				;quadrant 0 (dirs  0,15,14 --- dirs 12,13,14)
	dc.b		 0, 3				;quadrant 1 (dirs  0, 1, 2 --- dirs  4, 3, 2)
	dc.b		12,15				;quadrant 2 (dirs  8, 9,10 --- dirs 12,11,10)
	dc.b		 9, 6				;quadrant 3 (dirs  8, 7, 6 --- dirs  4, 5, 6)

en_shoot::
;a1 is enemy object header
;d6 is enemy number
	movem.l	d0-d6/a0-a6,-(sp)
	move.w	O_DESC(a1),d0			;get enemy_type
	lsl.w	#1,d0				;enemy type * 2
	lea		en_shtch,a3			;if enemy should change type after shooting
	move.w	(a3,d0.w),O_DESC(a1)	;new enemy type if necessary
	lea		shot_types,a3
	and.l	#$FFFF,d0				;clear high word
	add.l	d0,a3
	move.l	seed+12,d0
	and.w	#1,d0
	clr.w	d1
	move.b	(a3,d0.w),d1			;get shot type for this enemy
	bsr		shootbul
	movem.l	(sp)+,d0-d6/a0-a6
	rts

shootbul::
;a1 is enemy object header
;d6 is enemy number
;d1 is shot type
	clr.w	d5
	lea		en_shot0,a0			;first enemy shot object
	lea		en_sh_dir,a2
	lea		en_sh_speed,a4
	lea		en_fired,a5
.10:	tst.b	O_TYPE(a0)
	bpl		.50					;if positive, bullet is already active
	and.b	#$7F,O_TYPE(a0)		;turn on the bullet object
	move.w	d1,O_DESC(a0)
	lea		sh_usetg,a3
	lea		en_sh_tg,a6
	move.b	(a3,d1.w),(a6,d5.w)		;set whether shot uses a target
	cmp.b	#1,(a6,d5.w)
	bne.b	.15
	move.w	d5,d2				;leave d5 unchanged
	lsl.w	#1,d2
	lea		sh_targx,a3
	move.w	player+O_XPOS,(a3,d2.w)
	lea		sh_targy,a3
	move.w	player+O_YPOS,(a3,d2.w)
.15:
	move.b	#1,(a5,d6.w)			;set en_fired flag
	lea		en_sh_cnt,a3
	clr.b	(a3,d5.w)				;reset shot animation counter
	lea		en_sh_anm,a3
	clr.b	(a3,d5.w)				;reset shot animation step
	lea		shotdirs,a3
	move.b	(a3,d1.w),d2			;get direction for this type of shot
	bpl.b	.40					;use direction immediately if not special case
	cmp.b	#$FF,d2	 			;$FF if shot should go toward player
	bne.b	.20
	lea		dir_to_plr,a3
	move.b	(a3,d6.w),d2			;use dir_to_plr for shot direction
	bra.b	.40
.20:	cmp.b	#$FE,d2				;$FE if shot uses any random direction
	bne.b	.24
	move.l	seed,d2
	and.l	#$F,d2				;make direction 0 - 15
	bra.b	.40
.24:	cmp.b	#$FD,d2				;$FD if shot uses random left direction
	bne.b	.28
	move.l	seed,d2
	and.l	#3,d2				;0 - 7
	add.b	#10,d2				;make direction 10 - 13
	bra.b	.40
.28:	cmp.b	#$FC,d2				;$FC if shot uses any random left direction
	bne.b	.32
	move.l	seed,d2
	and.l	#7,d2				;0 - 7
	add.b	#8,d2				;make direction 8 - 15
	bra.b	.40
.32:
	cmp.b	#$FB,d2				;$FB if shot uses any random right direction
	bne.b	.40
	move.l	seed,d2
	and.l	#7,d2				;0 - 7
;	bra		.40

.40:	move.b	d2,(a2,d5.w)			;save direction for this shot

	lea		en_sh_dp,a3			;pixel depth
	move.b	(a3,d1.w),O_DEPTH(a0)	;get pixel depth for this type of shot
	lea		en_sh_fp,a3			;first pixel
	move.b	(a3,d1.w),O_FIRSTPIX(a0)
	lea		shot_speeds,a3
	move.b	(a3,d1.w),(a4,d5.w)		;get speed for this type of shot
	lsl.w	#1,d1				;change shot type to shot type * 2
	lea		en_sh_dwidth,a3
	move.w	(a3,d1.w),O_DWIDTH(a0)	;get dwidth for this type of shot
	move.w	(a3,d1.w),O_IWIDTH(a0)
	lea		en_sh_ht,a3
	move.w	(a3,d1.w),O_HEIGHT(a0)	;get height for this type of shot
	lsl.w	#1,d1				;change shot type from * 2 to * 4
	move.w	O_XPOS(a1),d2			;get enemy xpos
	lea		shot_pos,a3			;table of starting distances from enemies
	add.w	(a3,d1.w),d2			;add horizontal distance from top left corner
	move.w	d2,O_XPOS(a0)			;starting horiz position for shot
	move.w	O_YPOS(a1),d0			;get enemy ypos
	add.w	2(a3,d1.w),d0			;add vertical distance from top left corner
	move.w	d0,O_YPOS(a0)			;starting vert position for shot

	cmp.w	#DESRBSH0,O_DESC(a0)
	bne.b	.45
	cmp.w	player+O_XPOS,d2		;compare player xpos to shot xpos
	bge.b	.45
	move.w	#DESRBSH1,O_DESC(a0)
.45:

	lea		enfirsnd,a3			;sounds to play when enemy shoots
	move.w	O_DESC(a1),d1			;enemy type
	clr.w	d0
	move.b	(a3,d1.w),d0
	bmi.b	.90					;no sample if $FF
	move.w	O_XPOS(a0),d1			;xpos to determine pan value
	bsr		playsnd				;d0 = sample number, d1 = sound xpos
	bra.b	.90					;restore the stack before leaving
.50:	adda.l	#OBJ_SIZE,a0
	addq.w	#1,d5
	cmp.w	#MAX_ENEMY_SHOTS,d5
	blt		.10
.90:
	rts


move_en_shots::
	bsr		get_sh_dist

	lea		en_shot0,a1	 		;first enemy shot
	lea		en_sh_dir,a2
	lea		en_sh_speed,a3
	move.w	#ENEMY_SHOT_LEFT,d2		;left limit
	move.w	#ENEMY_SHOT_RIGHT,d3	;right limit
	move.w	#ENEMY_SHOT_TOP,d4		;top limit
	move.w	#ENEMY_SHOT_BOTTOM,d5	;bottom limit
	clr.w	d6
.10:
	tst.b	O_TYPE(a1)
	bmi.b	.50					;if not active, do next one

	clr.l	d0
	move.b	(a3,d6.w),d0			;normal speed
	lsl.w	#5,d0				;multiply speed * 16 directions for each speed * 2 bytes for each direction

	clr.l	d1
	move.b	(a2,d6.w),d1			;get shot direction
	add.w	d1,d0				;add direction to speed * 32
	add.w	d1,d0				;add direction again because each direction uses 2 bytes
	bsr		move_obj
	tst.b	limitflag
	beq.b	.50
.45:	or.b		#DELETE_OBJ,O_TYPE(a1)	;turn off shot when off screen
.50:
	adda.l	#OBJ_SIZE,a1			;next object header
	addq.w	#1,d6
	cmp.w	#MAX_ENEMY_SHOTS,d6
	blt		.10
	rts

get_sh_dist::
	lea		en_shot0,a0			;first enemy shot
	lea		sh_targx,a1			;X target
	lea		sh_targy,a6			;Y target (got_quad uses a2)
	lea		en_sh_tg,a3			;if shot uses a target
	lea		en_sh_dir,a4			;shot direction
	lea		track_dirs,a5
	clr.w	d6					;count shots
.10:	tst.b	O_TYPE(a0)			;see if shot is active
	bmi		.60					;skip shot if not active
	move.w	O_DESC(a0),d0
	bmi		.60					;don't do explosion
	cmp.b	#1,(a3,d6.w)			;see if shot uses a target
	bne.b	.60
	clr.w	d3					;init quadrant number
	move.w	d6,d0				;get shot number
	lsl.w	#1,d0				;shot number * 2
	move.w	(a1,d0.w),d5			;get X target to aim for
	move.w	O_XPOS(a0),d1			;get shot xpos
	sub.w	d5,d1				;shot xpos - target xpos
	bpl.b	.20
	neg.w	d1					;get absolute value of horiz distance
	addq.w	#2,d3				;horiz dir is right, use right quadrants
.20:	move.w	(a6,d0.w),d5			;get Y target to aim for
	move.w	O_YPOS(a0),d2
	sub.w	d5,d2				;shot ypos - shot ypos
	bpl.b	.30
	neg.w	d2					;get absolute value of vert distance
	addq.w	#4,d3				;horiz dir is down, use lower quadrants
.30:
	cmp.w	#5,d1
	bge.b	.50
	cmp.w	#5,d2
	bge.b	.50
	lea		en_sh_tg,a6
	clr.b	(a6,d6.w)				;cancel use of target when shot reaches target
	bra.b	.60
.50:	bsr		got_quad				;sets d0 to offset for track_dirs
	move.b	(a5,d0.w),(a4,d6.w)		;save shot direction

.60:	adda.l	#OBJ_SIZE,a0			;next enemy shot object header
	addq.w	#1,d6				;enemy shot counter
	cmp.w	#MAX_ENEMY_SHOTS,d6
	blt		.10
.90:	rts


grnd_obj::
;this will only create an enemy if an enemy object is available that
;is less than the maximum ground enemy number (max_g_en)
	tst.b	newtilfl
	beq		.90					;don't create new ground object if new tile flag is not set

	move.w	levelx4,d0
	lea		glisttbl,a1
	move.l	(a1,d0.w),a1			;address of ground object list for current level
	cmp.l	#0,a1
	beq		.90					;no ground objects if 0
	move.w	curbktile,d0
	cmp.w	#256,d0				;size of glist table
	bge		.90					;don't go past end of table
	cmp.b	#$FF,(a1,d0.w)			;if $FF, don't create any object
	beq.b	.90
	cmpa.l	#glistbon,a1
	beq		mk_ring
	cmp.b	#STATION,(a1,d0.w)
	beq		mk_stat
	clr.l	d1
	move.b	(a1,d0.w),d1			;get the type of object
	clr.w	d5					;count enemies
	lea		enemy0,a0				;first enemy
.10:	tst.b	O_TYPE(a0)
	bpl.b	.50					;if already on, do next one
	move.w	d1,O_DESC(a0)			;save enemy or object to create
	lea		en_xstart,a1
	lsl.w	#1,d1				;enemy type * 2
	move.w	(a1,d1.w),O_XPOS(a0)
	lea		en_ystart,a1
	lsl.w	#1,d1				;change to enemy type * 4
	move.w	2(a1,d1.w),d2			;get limit for amount to subtract from ypos
	move.l	seed,d0				;get a random number
	and.w	d2,d0				;reduce random number
	move.w	(a1,d1.w),d3			;get lowest ypos for object
	sub.w	d0,d3				;move object up a random amount
	and.w	#$FFFE,d3				;make sure ypos is even
	move.w	d3,O_YPOS(a0)			;save the final ypos for the object
	bra		set_en_info			;set height,dwidth,iwidth,data,health,speed,direction

.50:	adda.l	#OBJ_SIZE,a0			;next object header
	addq.w	#1,d5
	cmp.w	max_g_en,d5			;highest enemy number that can be a ground enemy
	blt.b	.10
.90:	rts

mk_ring::
	clr.l	d1
	move.b	(a1,d0.w),d1			;get the type of object
	clr.w	d5					;count enemies
	lea		enemy0,a0				;first enemy
.10:	tst.b	O_TYPE(a0)
	bpl		.50					;if already on, do next one
	move.w	d1,O_DESC(a0)			;save enemy or object to create
	move.w	#SCRN_RIGHT,O_XPOS(a0)
	move.l	seed,d0
	and.l	#127,d0
	add.w	#SCRN_TOP+20,d0
	move.w	d0,O_YPOS(a0)			;save the final ypos for the object
	bsr		set_en_info			;set height,dwidth,iwidth,data,health,speed,direction

	move.w	O_DESC(a0),d4
	sub.w	#RINGL0,d4			;make it 0 - 2
	lsl.w	#1,d4				;object type * 2
	move.w	O_YPOS(a0),d6			;get ypos of back part of ring
	move.w	levelx4,d0
	lea		frinftbl,a0
	move.l	(a0,d0.w),a5			;A5 = DATA (address of list of data addresses for foreground objects)
	movea.l	a5,a0				;need to set a0 to address of heights
	adda.l	#64,a0				;A0 = HEIGHT (skip 16 data addresses * 4 bytes each)
	movea.l	a0,a3				;need to set a3 to address of widths
	adda.l	#32,a3				;A3 = WIDTH (skip 16 heights * 2 bytes each)
	movea.l	a3,a2				;need to set a2 to address of dwidths
	adda.l	#32,a2				;A2 = DWIDTH (skip 16 widths * 2 bytes each)
	lea		front0,a6				;first foreground object header
	move.w	#TOTAL_FRONT_OBJS-1,d0
.30:	tst.b	O_TYPE(a6)			;object is turned on if positive
	bpl.b	.40					;need to find an object that is turned off
	move.b	#TRANS_ON,O_FLAGS(a6)	;assume object is not flipped
	cmp.b	#(0*2),d4
	bne.b	.32
	move.w	#SCRN_RIGHT+27,d7		;adjust xpos
	sub.w	#48,d6				;adjust ypos
	bra.b	.38
.32:	cmp.b	#(1*2),d4
	bne.b	.34
	move.w	#SCRN_RIGHT+22,d7		;adjust xpos
	sub.w	#32,d6				;adjust ypos
	bra.b	.38
.34:	move.w	#SCRN_RIGHT+11,d7		;adjust xpos
	sub.w	#22,d6				;adjust ypos
.38:	move.w	d7,O_XPOS(a6)
	move.w	d6,O_YPOS(a6)
	and.b	#$7F,O_TYPE(a6)		;turn object on
	move.w	(a0,d4.w),O_HEIGHT(a6)
	move.w	(a2,d4.w),O_DWIDTH(a6)
	move.w	O_DWIDTH(a6),O_IWIDTH(a6)
	lsl.w	#1,d4				;change 2 * object number to 4 * object number (1 long per object)
	move.l	(a5,d4.w),O_DATA(a6)	;save address in foreground object header
	lsr.w	#2,d4				;change back to object number
	move.w	d4,O_DESC(a6)
	bra.b	.90
.40:	adda.l	#OBJ_SIZE,a6			;next foreground object
	dbra		d0,.30
	bra.b	.90
.50:	adda.l	#OBJ_SIZE,a0			;next object header
	addq.w	#1,d5
	cmp.w	max_g_en,d5			;highest enemy number that can be a ground enemy
	blt		.10
.90:	rts

mk_stat::
	move.w	levelx2,d0
	lea		statypos,a1
	move.w	(a1,d0.w),d1
	move.w	d1,statn+O_YPOS	;set station ypos for current level
	sub.w	#112,d1
	move.w	d1,statnflg+O_YPOS
	move.w	#SCRN_RIGHT,statn+O_XPOS
	move.w	#SCRN_RIGHT+38,statnflg+O_XPOS
	and.b	#$7F,statn+O_TYPE
	and.b	#$7F,statnflg+O_TYPE
	rts

mv_stat::
	tst.b	statn+O_TYPE
	bmi		.90
;animate flag here
	add.b	#1,flagcnt
	cmp.b	#7,flagcnt
	blt.b	.20
	clr.b	flagcnt
	add.b	#1,flagstp
	cmp.b	#7,flagstp
	blt.b	.20
	clr.b	flagstp
.20:	clr.w	d0
	move.b	flagstp,d0
	lsl.w	#2,d0
	lea		flagdta,a0
	move.l	(a0,d0.w),statnflg+O_DATA

	move.w	scrlspd,d1
	move.w	statnflg+O_XPOS,d0
	sub.w	d1,d0
	move.w	d0,statnflg+O_XPOS
	move.w	statn+O_XPOS,d0
	sub.w	d1,d0
	move.w	d0,statn+O_XPOS
	tst.w	d0
	bpl.b	.90
	cmp.w	#-192,d0
	bge.b	.90
	or.b		#DELETE_OBJ,statn+O_TYPE
	or.b		#DELETE_OBJ,statnflg+O_TYPE
.90:	rts

flagdta::
	dc.l		statflg0,statflg1,statflg2,statflg3,statflg4,statflg5,statflg6

create_en::
;this creates an air enemy, first trying to use the objects above max_g_en
;if none of those objects are available, it will try to use one of the ground enemy objects
	clr.b	active_enemies			;initialize active enemy counter
	lea		enemy0,a0				;first enemy object header
	move.w	#TOTAL_ENEMIES-1,d0
.02:	tst.b	O_TYPE(a0)			;if delete flag is on, don't increase counter
	bmi.b	.04
	addq.b	#1,active_enemies		;increase active enemy counter
.04:	adda.l	#OBJ_SIZE,a0			;next enemy object header
	dbra		d0,.02

	cmp.b	#0,levstatus			;see if end of level has been reached
	beq.b	.08
	cmp.b	#2,levstatus			;see if scrolling is speeding up at end of level
	beq		.20					;if scrolling fast at end of level, no enemies
	cmp.b	#1,levstatus			;see if scrolling has stopped at end of level
	bne.b	.08
	tst.b	active_enemies			;see if there are no enemies left
	bne		.20
	bsr		ck_boss
	rts

.08:	cmp.w	#PLR_PLAY,player+O_DESC
	bne.b	.20					;don't make enemies if player is not playing

	move.w	odomback,d0
	lsr.w	#4,d0				;divide by 16 (new enemy every 16 pixels)
	cmp.w	#1024,d0				;size of elist table
	bge.b	.20					;don't go past end of table
	cmp.w	cur_en,d0				;compare old offset (cur_en) to new offset for elist
	beq.b	.20					;not time for a new enemy yet
	move.w	d0,cur_en				;save new offset for enemy list table
	move.w	levelx4,d1
	lea		elisttbl,a2
	move.l	(a2,d1.w),a2			;address of elist to use
	cmpa.l	#0,a2				;no enemy list if 0
	beq.b	.20
	move.b	(a2,d0.w),d0			;get enemy type from table
	cmp.b	#99,d0				;don't create an enemy if 99
	beq.b	.20

	move.w	#TOTAL_ENEMIES-1,d5		;count enemies
	lea		enemy9,a0				;last enemy
.10:	tst.b	O_TYPE(a0)
	bpl.b	.15					;if enemy is on, skip it
	tst.w	O_DESC(a0)			;enemy is an explosion if >= $80
	bpl.b	.30
.15:	suba.l	#OBJ_SIZE,a0			;next object header
	dbra		d5,.10
.20:	rts
.30:
	and.w	#$FF,d0				;clear high byte if necessary
	move.w	d0,O_DESC(a0)			;save enemy type that was set earlier

	lea		en_appear_flag,a4
	cmp.b	#1,(a4,d0.w)			;see if enemy has appearing animation
	beq.b	.35					;if appearing, start on screen somewhere
	move.w	#SCRN_RIGHT,O_XPOS(a0)	;start off screen
	bra.b	.38
.35:
	jsr		random
	and.l	#$FF,d0				;0 - 255
	add.w	#192,d0				;add minimum xpos so xpos is somewhere on right part of screen
	move.w	d0,O_XPOS(a0)
.38:
	lea		en_ystart,a1
	move.w	O_DESC(a0),d0
	lsl.w	#2,d0				;enemy type * 4
	move.l	seed,d1
	and.l	#$1FF,d1				;get 0 - 511
	add.w	(a1,d0.w),d1			;add minimum ypos
	cmp.w	2(a1,d0.w),d1			;compare to maximum ypos
	blt.b	.50					;if less than maximum, use this ypos
	lsr.w	#1,d1				;cut ypos in half if it is too high
.50:	move.w	d1,O_YPOS(a0)			;save the final ypos for the object

	bsr		set_en_info			;set height,dwidth,iwidth,data,health,speed,direction
.60:
	rts

mk_form::
;see if it is time to create a formation of enemies
	move.w	odomback,d0
	and.w	#$3F,d0				;reduce to position within current left tile
	cmp.w	#$1F,d0				;check in middle of tile so formation is not created when tile is blitted
	bne		.90

	move.w	levelx4,d0
	lea		forms,a1
	move.l	(a1,d0.w),a1			;address of formation list for current level
	cmp.l	#0,a1
	beq		.90					;no formations if 0
	move.w	curbktile,d1
	cmp.w	#256,d1				;size of formlist table
	bge		.90					;don't go past end of table
	clr.l	d0
	move.b	(a1,d1.w),d0			;if $FF, don't create formation
	cmp.b	#$FF,d0				;check formation number
	beq.b	.90
	lea		formtbl,a2
	move.w	d0,d7				;get formation number
	lsl.w	#2,d7
	move.l	(a2,d7.w),a2			;address of formXXin table
	lea		in_form,a1			;formation number for each enemy
	lea		enemydir,a3
	lea		en_speed,a4
	lea		en_usept,a5
	lea		enemy9,a0				;last enemy
	moveq.l	#TOTAL_ENEMIES-1,d5		;count enemy objects
.10:	tst.b	O_TYPE(a0)			;see if object is active
	bpl.b	.80					;if object is being used, try another
	move.w	(a2)+,d1
	cmp.w	#$8000,d1				;end of table
	beq.b	.90
	move.w	d1,O_DESC(a0)			;set object desc
	move.w	(a2)+,O_XPOS(a0)		;set object xpos
	move.w	(a2)+,O_YPOS(a0)		;set object ypos

	movem.l	d0/a0-a5,-(sp)
	bsr		set_en_info
	movem.l	(sp)+,d0/a0-a5

	move.b	d0,(a1,d5.w)			;set formation number (set_en_info set it to $FF)
	move.w	(a2)+,d7
	move.b	d7,(a3,d5.w)			;replace direction that was set by set_en_info
	move.w	(a2)+,d7
	move.b	d7,(a4,d5.w)			;replace speed that was set by set_en_info
	move.b	#$FF,(a5,d5.w)			;don't use pattern
.80:	suba.l	#OBJ_SIZE,a0			;next object header
	dbra		d5,.10
.90:
	rts

ck_boss::
;at this point, there are no active enemy objects
	tst.b	bossmade				;see if the last enemy has been created yet
	beq		.30					;if boss enemy has not been created and is now gone, end the level
	move.b	#2,levstatus			;if boss enemy has not been created and is now gone, end the level
	move.w	#2,d0
	bsr		voiceoff				;turn off voice used by bosses
	move.w	#3,d0
	bsr		voiceoff				;turn off voice used by bosses
	rts
.30:	move.b	#1,bossmade			;set flag
	bsr		ld_decmp				;load decompression code into GPU
	move.l	#q65,a3
	bsr		load_dq
	move.w	levelx4,d0
	lea		boss_tbl,a0
	move.l	(a0,d0.w),a0
	jsr		(a0)					;go to boss creation routine
	bsr		ld_bldsc				;load scaled object list builder code into GPU
	bsr		bssnd_on
.90:	rts

dodecomp::
;A0 = address of table with info for decompression
;D0 = number of items to decompress
	subq.w	#1,d0				;subtract 1 for loop counter
.10:	move.l	(a0)+,In_Adr			;address of compressed data
	move.l	(a0)+,Out_Adr			;set destination address
	move.l	(a0)+,Out_Width		;number of 8 pixel blocks in destination area
	move.l	(a0)+,Out_E_Width		;setting for blitter
	bsr		decomp
	dbra		d0,.10
	rts
;tables for loading bosses
;address of compressed data, destination address, width/8, width for blitter
bs00tbl:
	dc.l		destop,	destop0,		24,	WID192		;top piece
	dc.l		desbot,	desbot0,		4,	WID32		;bottom piece
	dc.l		desbsht,	desbssh0,		6,	WID48		;shot
bs01tbl:
	dc.l		ribs,	skribs,		12,	WID96		;ribs
	dc.l		neck,	skneck00,		6,	WID48		;neck
	dc.l		head,	skhead00,		10,	WID80		;head
	dc.l		arm0,	skarm00,		16,	WID128		;arm
	dc.l		arm1,	skarm01,		10,	WID80		;arm
	dc.l		arm2,	skarm02,		4,	WID32		;arm
	dc.l		arm3,	skarm03,		8,	WID64		;arm
	dc.l		arm4,	skarm04,		14,	WID112		;arm
	dc.l		hornb,	skhrnb00,		8,	WID64		;back horn
	dc.l		hornf0,	skhrnf00,		4,	WID32		;front horn
	dc.l		hornf1,	skhrnf01,		8,	WID64		;front horn
	dc.l		hornf2,	skhrnf03,		6,	WID48		;front horn
	dc.l		hornn,	skhrnn00,		4,	WID32		;nose horn
bs02tbl:
	dc.l		cvatk,	cvboss00,		20,	WID160		;attacking
	dc.l		cvspin,	cvboss07+16,	24,	WID192		;spinning
bs03tbl:
	dc.l		quetbod,	quetbd00,		24,	WID192		;body
	dc.l		quetarb,	quetab00,		10,	WID80		;back arm
	dc.l		quetarf,	quetaf00,		10,	WID80		;front arm
	dc.l		quettl,	quettl00,		12,	WID96		;tail
	dc.l		quetsht,	quetsht0,		6,	WID48		;shot
bs04tbl:
	dc.l		airboss,	airboss0,		20,	WID160
bs05tbl:
	dc.l		serpbod,	serp00,		28,	WID224		;body
	dc.l		serplw0,	serplw00,		20,	WID160		;left wing
	dc.l		serplw1,	serplw06,		24,	WID192		;left wing
	dc.l		serprw,	serprw00,		20,	WID160		;right wing
	dc.l		serpsht,	serpsht0,		6,	WID48		;shot
bs06tbl:
	dc.l		wbody,	wboss00,		20,	WID160		;body
	dc.l		wtail,	wboss06,		10,	WID80		;tail
	dc.l		wrarm,	wboss12,		10,	WID80		;right arm
	dc.l		wlarm,	wboss16,		16,	WID128		;left arm
bs07tbl:
	dc.l		mud0,	mud00,		10,	WID80
	dc.l		mud1,	mud01,		12,	WID96
	dc.l		mud2,	mud02,		20,	WID160
	dc.l		mud3,	mud04,		16,	WID128
	dc.l		mud4,	mud05,		28,	WID224
	dc.l		mud5,	mud06,		24,	WID192
	dc.l		mudsht,	mudshot,		4,	WID32
bs08tbl:
	dc.l		citybs,	citybs00,		16,	WID128
	dc.l		cityhd,	cityhd00,		6,	WID48
	dc.l		ctysh0,	citysh00,		4,	WID32
	dc.l		ctysh1,	citysh04,		4,	WID32
bs09tbl:
	dc.l		cty21,	tile21,		8,	WID64
	dc.l		oddcld,	oddcld00,		14,	WID112
	dc.l		oddit0,	oddit00,		14,	WID112
	dc.l		oddit1,	oddit06,		14,	WID112

do_mask::
;A0 = address of table with mask info
;D0 = number of masks
	subq.w	#1,d0					;subtract 1 for loop counter
.10:
	move.l	B_CMD,d7
	btst.l	#0,d7
	beq.b	.10
	move.l	(a0)+,A1_BASE				;destination address
	move.l	(a0)+,d1					;blitter width
	move.l	d1,d2
	or.l		#(PITCH1|PIXEL16|XADDPIX),d1
	move.l	d1,A1_FLAGS				;destination
	or.l		#(PITCH1|PIXEL1|XADDPIX),d2
	move.l	d2,A2_FLAGS				;source
	move.l	(a0)+,B_COUNT				;height, width of source data
	move.l	(a0)+,d1					;blitter steps
	move.l	d1,A1_STEP				;1 in Y step size, negative width in X step size
	move.l	d1,A2_STEP				;1 in Y step size, negative width in X step size
	move.l	(a0)+,UNCOMP_START
	move.l	(a0)+,d1					;size of mask / 8
	add.l	#screen,d1
	move.l	d1,UNCOMP_END				;stop uncomp at this address
	bsr		blitmask
	dbra		d0,.10
	rts
;tables for loading boss masks
;A1_BASE				destination address
;width for blitter
;B_COUNT				height, width
;A1_STEP and A2_STEP	1, negative width
;UNCOMP_START			address of compressed mask
;size of mask / 8
msk00tbl:
	dc.l		destop0,		WID192,	$00F600C0,	$0001FF40,	destopm,	(192*246/8)
	dc.l		desbot0,		WID32,	$00C000E0,	$0001FF20,	desbotm,	(224*192/8)
	dc.l		desbssh0,		WID48,	$001C0030,	$0001FFD0,	desbsh_m,	(48*28/8)
msk01tbl:
	dc.l		skribs,		WID96,	$00280060,	$0001FFA0,	ribs_m,	(96*40/8)
	dc.l		skneck00,		WID48,	$00840030,	$0001FFD0,	neck_m,	(48*132/8)
	dc.l		skhead00,		WID80,	$01E30050,	$0001FFB0,	head_m,	(80*483/8)
	dc.l		skarm00,		WID128,	$002C0080,	$0001FF80,	arm0_m,	(128*44/8)
	dc.l		skarm01,		WID80,	$00500050,	$0001FFB0,	arm1_m,	(80*80/8)
	dc.l		skarm02,		WID32,	$00580020,	$0001FFE0,	arm2_m,	(32*88/8)
	dc.l		skarm03,		WID64,	$00500040,	$0001FFC0,	arm3_m,	(64*80/8)
	dc.l		skarm04,		WID112,	$00280070,	$0001FF90,	arm4_m,	(112*40/8)
	dc.l		skhrnb00,		WID64,	$014D0040,	$0001FFC0,	hornb_m,	(64*333/8)
	dc.l		skhrnf00,		WID32,	$00DC0020,	$0001FFE0,	hornf0_m,	(32*220/8)
	dc.l		skhrnf01,		WID64,	$002F0040,	$0001FFC0,	hornf1_m,	(64*47/8)
	dc.l		skhrnf03,		WID48,	$001E0030,	$0001FFD0,	hornf2_m,	(48*30/8)
	dc.l		skhrnn00,		WID32,	$00730020,	$0001FFE0,	hornn_m,	(32*115/8)
msk03tbl:
	dc.l		quetbd00,		WID192,	$050000C0,	$0001FF40,	qutbodm,	(192*1280/8)
	dc.l		quetab00,		WID80,	$01200050,	$0001FFB0,	qutarbm,	(80*288/8)
	dc.l		quetaf00,		WID80,	$01300050,	$0001FFB0,	qutarfm,	(80*304/8)
	dc.l		quettl00,		WID96,	$03D00060,	$0001FFA0,	quttlm,	(96*976/8)
	dc.l		quetsht0,		WID48,	$00100030,	$0001FFD0,	qutshtm,	(48*16/8)
msk04tbl:
	dc.l		airboss0,		WID160,	$03E600A0,	$0001FF60,	airbosm,	(160*998/8)
msk05tbl:
	dc.l		serp00,		WID224,	$02B500E0,	$0001FF20,	srpbodm,	(224*693/8)
	dc.l		serplw00,		WID160,	$019C00A0,	$0001FF60,	srplw0m,	(160*412/8)
	dc.l		serplw06,		WID192,	$008F00C0,	$0001FF40,	srplw1m,	(192*143/8)
	dc.l		serprw00,		WID160,	$029800A0,	$0001FF60,	srprwm,	(160*664/8)
	dc.l		serpsht0,		WID48,	$00180030,	$0001FFD0,	srpshtm,	(48*24/8)
msk06tbl:
	dc.l		wboss00,		WID160,	$030600A0,	$0001FF60,	wbody_m,	(160*774/8)
	dc.l		wboss06,		WID80,	$013E0050,	$0001FFB0,	wtail_m,	(80*318/8)
	dc.l		wboss12,		WID80,	$010C0050,	$0001FFB0,	wrarm_m,	(80*268/8)
	dc.l		wboss16,		WID128,	$02B00080,	$0001FF80,	wlarm_m,	(128*688/8)
msk07tbl:
	dc.l		mud00,		WID80,	$00CA0050,	$0001FFB0,	mud0_m,	(80*202/8)
	dc.l		mud01,		WID96,	$00CC0060,	$0001FFA0,	mud1_m,	(96*204/8)
	dc.l		mud02,		WID160,	$019A00A0,	$0001FF60,	mud2_m,	(160*410/8)
	dc.l		mud04,		WID128,	$01990080,	$0001FF80,	mud3_m,	(128*409/8)
	dc.l		mud05,		WID224,	$00C900E0,	$0001FF20,	mud4_m,	(224*201/8)
	dc.l		mud06,		WID192,	$00CF00C0,	$0001FF40,	mud5_m,	(192*207/8)
	dc.l		mudshot,		WID32,	$00200020,	$0001FFE0,	mudshtm,	(32*32/8)
msk08tbl:
	dc.l		citybs00,		WID128,	$00AE0080,	$0001FF80,	citybs_m,	(128*174/8)
	dc.l		cityhd00,		WID48,	$01180030,	$0001FFD0,	cityhd_m,	(48*280/8)
	dc.l		citysh00,		WID32,	$002C0020,	$0001FFE0,	ctysh0_m,	(32*44/8)
	dc.l		citysh04,		WID32,	$001E0020,	$0001FFE0,	ctysh1_m,	(32*30/8)
msk09tbl:
	dc.l		oddcld00,		WID112,	$02B80070,	$0001FF90,	oddcld_m,	(112*696/8)
	dc.l		oddit00,		WID112,	$04B00070,	$0001FF90,	oddit0_m,	(112*1200/8)
	dc.l		oddit06,		WID112,	$04B00070,	$0001FF90,	oddit1_m,	(112*1200/8)

mkboss00::
;make boss enemy for first space level
;this is the desert robot
	move.l	#bs00tbl,a0			;table with decompression info
	move.w	#3,d0				;number of objects to decompress
	bsr		dodecomp

	move.l	#destop0,ADJBLACK_START
	move.l	#desbssh1+(48*32*2),ADJBLACK_END
	bsr		adjblak

	bsr		ld_uncmp

	move.l	#msk00tbl,a0
	move.w	#3,d0
	bsr		do_mask

;copy the 2 frames of the shot and horiz flip them so they can be used as another type of shot
	move.l	#PITCH1|PIXEL16|WID48|XADDPIX|XSIGNSUB,A1_FLAGS	;description of destination area
	move.l	#PITCH1|PIXEL16|WID48|XADDPIX|XSIGNADD,A2_FLAGS	;description of source area
	move.l	#desbssh2,A1_BASE				;destination address
	move.l	#desbssh0,A2_BASE				;source address
	move.l	#0,A2_PIXEL					;start at 0,0 of source image
	move.l	#$0000002F,A1_PIXEL				;Y,X position to write data in destination area
	move.l	#$001C0030,B_COUNT				;inner loop = 28 (copy both frames), outer loop = 48
	move.l	#$00010030,A1_STEP				;1 in Y step size, negative width in X step size
	move.l	#UPDA1|SRCEN|LFU_A|LFU_AN,B_CMD	;turn on blitter

	move.w	#1,d5				;count enemies
	lea		enemy1,a0				;enemy number
	move.w	#DESRBTT,O_DESC(a0)
	move.w	#SCRN_RIGHT,O_XPOS(a0)	;start off screen
	bsr		set_en_info			;set height,dwidth,iwidth,data,health,speed,direction
	move.b	#12,enemydir+1			;move to the left at first
	move.w	#200,O_YPOS(a0)

	move.w	#0,d5				;enemy number
	lea		enemy0,a0				;first enemy
	move.w	#DESRBTB,O_DESC(a0)
	move.w	#SCRN_RIGHT,O_XPOS(a0)	;start off screen
	bsr		set_en_info			;set height,dwidth,iwidth,data,health,speed,direction
	move.w	#SCRN_TOP+300,O_YPOS(a0)

	rts

mkboss01::
;make boss enemy for desert2 level
;this is the cow skull
	move.l	#bs01tbl,a0
	move.w	#13,d0
	bsr		dodecomp

	move.l	#skhead00,ADJBLACK_START
	move.l	#skarm00,ADJBLACK_END	;only adjblack for head
	bsr		adjblak

	bsr		ld_uncmp

	move.l	#msk01tbl,a0
	move.w	#13,d0
	bsr		do_mask

;blit the shots from rom to ram
;32 x 8
;total of 512 bytes, or 128 longs
	move.l	#PITCH1|PIXEL32|WID128|XADDPHR,d0
	move.l	d0,A1_FLAGS					;destination
	move.l	d0,A2_FLAGS					;source
	move.l	#skullsh0,A1_BASE				;destination address
	move.l	#skullsht,A2_BASE				;source address
	move.l	#0,A2_PIXEL					;start at 0,0 of source image
	move.l	#0,A1_PIXEL					;Y,X position to write data in destination area
	move.l	#$00010080,B_COUNT				;inner loop = 1, outer loop = 128
	move.l	#$0001FF80,A1_STEP				;1 in Y step size, negative width in X step size
	move.l	#UPDA1|SRCEN|LFU_A|LFU_AN,B_CMD	;turn on blitter

	move.w	#2,d5				;enemy number
	lea		enemy2,a0				;first enemy
	move.w	#SKULLRIB,O_DESC(a0)
	move.w	#SCRN_RIGHT+273,O_XPOS(a0)	;start off screen
	bsr		set_en_info			;set height,dwidth,iwidth,data,health,speed,direction

	move.w	#0,d5				;enemy number
	lea		enemy0,a0				;first enemy
	move.w	#SKULLARM,O_DESC(a0)
	move.w	enemy2+O_XPOS,O_XPOS(a0)	;start off screen
	bsr		set_en_info			;set height,dwidth,iwidth,data,health,speed,direction

	move.w	#1,d5				;enemy number
	lea		enemy1,a0				;first enemy
	move.w	#SKULLNECK,O_DESC(a0)
	move.w	enemy2+O_XPOS,O_XPOS(a0)	;start off screen
	bsr		set_en_info			;set height,dwidth,iwidth,data,health,speed,direction

	move.w	#3,d5				;enemy number
	lea		enemy3,a0				;first enemy
	move.w	#SKULLHB,O_DESC(a0)
	move.w	enemy2+O_XPOS,O_XPOS(a0)	;start off screen
	bsr		set_en_info			;set height,dwidth,iwidth,data,health,speed,direction

	move.w	#4,d5				;enemy number
	lea		enemy4,a0				;first enemy
	move.w	#SKULLHD,O_DESC(a0)
	move.w	enemy2+O_XPOS,O_XPOS(a0)	;start off screen
	bsr		set_en_info			;set height,dwidth,iwidth,data,health,speed,direction

	move.w	#5,d5				;enemy number
	lea		enemy5,a0				;first enemy
	move.w	#SKULLHF,O_DESC(a0)
	move.w	enemy5+O_XPOS,O_XPOS(a0)	;start off screen
	bsr		set_en_info			;set height,dwidth,iwidth,data,health,speed,direction

	move.w	#6,d5				;enemy number
	lea		enemy6,a0				;first enemy
	move.w	#SKULLHN,O_DESC(a0)
	move.w	enemy6+O_XPOS,O_XPOS(a0)	;start off screen
	bsr		set_en_info			;set height,dwidth,iwidth,data,health,speed,direction

	move.w	bkground+O_YPOS,d0
	add.w	#410,d0				;ypos is 205 lines from top of background
	move.w	d0,enemy0+O_YPOS		;arm
	move.w	d0,enemy1+O_YPOS		;neck
	move.w	d0,enemy2+O_YPOS		;ribs
	move.w	d0,enemy3+O_YPOS		;back horn
	move.w	d0,enemy4+O_YPOS		;head
	move.w	d0,enemy5+O_YPOS		;front horn
	move.w	d0,enemy6+O_YPOS		;nose horn

	clr.b	levstatus
	add.w	#448,odomend
	move.w	#SCROLL_SPEED,scrlspd

	rts

mkboss02::
;make boss enemy for second space level
;this is the cave robot
	move.l	#bs02tbl,a0
	move.w	#2,d0
	bsr		dodecomp

	move.l	#cvboss00,ADJBLACK_START
	move.l	#cvbssh0,ADJBLACK_END
	bsr		adjblak

	bsr		ld_uncmp

	move.l	#cvboss00,A1_BASE		;destination address
	move.l	#PITCH1|PIXEL16|WID160|XADDPIX,A1_FLAGS
	move.l	#PITCH1|PIXEL1|WID128|XADDPIX,A2_FLAGS
	move.l	#$046E0080,B_COUNT		;height, width of source data
	move.l	#$0001FF80,A1_STEP		;1 in Y step size, negative width in X step size
	move.l	#$0001FF80,A2_STEP		;1 in Y step size, negative width in X step size
	move.l	#cvatk_m,UNCOMP_START
	move.l	#screen+(128*1134/8),UNCOMP_END
	bsr		blitmask

.10:	move.l	B_CMD,d0
	btst.l	#0,d0
	beq.b	.10

;attacking robot frames are 128 wide, object is 160 wide
;object is put at left side of buffer, so erase the right 32 pixels
	move.l	#PITCH1|PIXEL32|WID80|XADDPHR,A1_FLAGS
	move.l	#cvboss00,A1_BASE			;destination address
	move.l	#$00000040,A1_PIXEL			;ypos = 0, xpos = 64
	move.l	#$0001FFF0,A1_STEP			;high = Y step, low = negative width
	move.l	#$0001FFF0,A2_STEP			;high = Y step, low = negative width
	move.l	#$046E0010,B_COUNT			;high = height, low = width
	move.l	#$0,B_PATD				;write 0's
	move.l	#$0,B_PATD+4
	move.l	#PATDSEL|UPDA1|UPDA2,B_CMD


	move.l	#cvboss07+16,A1_BASE	;destination address
	move.l	#PITCH1|PIXEL16|WID192|XADDPIX,A1_FLAGS
	move.l	#PITCH1|PIXEL1|WID160|XADDPIX,A2_FLAGS
	move.l	#$051000A0,B_COUNT		;height, width of source data
	move.l	#$0001FF60,A1_STEP		;1 in Y step size, negative width in X step size
	move.l	#$0001FF60,A2_STEP		;1 in Y step size, negative width in X step size
	move.l	#cvspn_m,UNCOMP_START
	move.l	#screen+(160*1296/8),UNCOMP_END
	bsr		blitmask

.20:	move.l	B_CMD,d0
	btst.l	#0,d0
	beq.b	.20

;spinning robot frames are 160 wide, object is 192 wide
;object is 8 pixels from the left side of the buffer
;so erase pixels 0-7 and 168-191
	move.l	#PITCH1|PIXEL32|WID96|XADDPHR,A1_FLAGS
	move.l	#cvboss07,A1_BASE			;destination address
	move.l	#$00000000,A1_PIXEL			;ypos = 0, xpos = 0
	move.l	#$0001FFFC,A1_STEP			;high = Y step, low = negative width
	move.l	#$0001FFFC,A2_STEP			;high = Y step, low = negative width
	move.l	#$05100004,B_COUNT			;high = height, low = width
	move.l	#PATDSEL|UPDA1|UPDA2,B_CMD

	move.l	#$00000054,A1_PIXEL			;ypos = 0, xpos = 0
	move.l	#$0001FFF4,A1_STEP			;high = Y step, low = negative width
	move.l	#$0001FFF4,A2_STEP			;high = Y step, low = negative width
	move.l	#$0510000C,B_COUNT			;high = height, low = width
	move.l	#PATDSEL|UPDA1|UPDA2,B_CMD


;blit the shots from rom to ram
;32 x 16, 16 bits= 1024 bytes
;24 x 20, 16 bits = 960 bytes
;total of 1984 bytes
	move.l	#PITCH1|PIXEL32|WID16|XADDPHR,d0
	move.l	d0,A1_FLAGS					;destination
	move.l	d0,A2_FLAGS					;source
	move.l	#cvbssh0,A1_BASE				;destination address
	move.l	#cvbssht0,A2_BASE				;source address
	move.l	#0,A2_PIXEL					;start at 0,0 of source image
	move.l	#0,A1_PIXEL					;Y,X position to write data in destination area
	move.l	#$001F0010,B_COUNT				;inner loop = 31, outer loop = 16
	move.l	#$0001FFF0,A1_STEP				;1 in Y step size, negative width in X step size
	move.l	#UPDA1|SRCEN|LFU_A|LFU_AN,B_CMD	;turn on blitter

	clr.w	d5					;count enemies
	lea		enemy0,a0				;first enemy
	move.w	#CVROBOT,O_DESC(a0)
	move.w	#SCRN_RIGHT,O_XPOS(a0)	;start off screen
	bsr		set_en_info			;set height,dwidth,iwidth,data,health,speed,direction

	move.b	#12,enemydir			;move to the left at first
	move.w	#110,O_YPOS(a0)

	rts

mkboss03::
;make boss enemy for cave level
;this is the snake
	move.l	#bs03tbl,a0
	move.w	#5,d0
	bsr		dodecomp

	move.l	#quetbd00,ADJBLACK_START
	move.l	#quetab15+(80*18*2),ADJBLACK_END
	bsr		adjblak
	move.l	#quetaf00,ADJBLACK_START
	move.l	#quetsht0,ADJBLACK_END
	bsr		adjblak

	bsr		ld_uncmp

	move.l	#msk03tbl,a0
	move.w	#5,d0
	bsr		do_mask

	move.w	#1,d5				;enemy number
	lea		enemy1,a0				;enemy object
	move.w	#QUETBODY,O_DESC(a0)
	move.w	#SCRN_RIGHT,O_XPOS(a0)	;start off screen
	bsr		set_en_info			;set height,dwidth,iwidth,data,health,speed,direction
	move.b	#12,enemydir+1			;move to the left at first
	move.w	#SCRN_BOTTOM-200,enemy1+O_YPOS

	move.w	#0,d5				;enemy number
	lea		enemy0,a0				;first enemy
	move.w	#QUETARMB,O_DESC(a0)
	move.w	#SCRN_RIGHT,O_XPOS(a0)	;start off screen
	bsr		set_en_info			;set height,dwidth,iwidth,data,health,speed,direction
	move.w	#SCRN_BOTTOM-200,O_YPOS(a0)

	move.w	#2,d5				;enemy number
	lea		enemy2,a0				;first enemy
	move.w	#QUETARMF,O_DESC(a0)
	move.w	#SCRN_RIGHT,O_XPOS(a0)	;start off screen
	bsr		set_en_info			;set height,dwidth,iwidth,data,health,speed,direction
	move.w	#SCRN_BOTTOM-200,O_YPOS(a0)

	move.w	#3,d5				;enemy number
	lea		enemy3,a0				;first enemy
	move.w	#QUETTAIL,O_DESC(a0)
	move.w	#SCRN_RIGHT,O_XPOS(a0)	;start off screen
	bsr		set_en_info			;set height,dwidth,iwidth,data,health,speed,direction
	move.w	#SCRN_BOTTOM-200,O_YPOS(a0)

	rts

mkboss04::
;make boss enemy for third space level
;this is the air robot
	move.l	#bs04tbl,a0
	move.w	#1,d0
	bsr		dodecomp

	move.l	#airboss0,ADJBLACK_START
	move.l	#airboss0+(160*1000*2),ADJBLACK_END
	bsr		adjblak

	bsr		ld_uncmp

	move.l	#msk04tbl,a0
	move.w	#1,d0
	bsr		do_mask

;blit the shot from rom to ram (16 x 13, 16 bit)
	move.l	#PITCH1|PIXEL32|WID8|XADDPHR,d0
	move.l	d0,A1_FLAGS					;destination
	move.l	d0,A2_FLAGS					;source
	move.l	#airboss8,A1_BASE				;destination address
	move.l	#airbossh,A2_BASE				;source address
	move.l	#0,A2_PIXEL					;start at 0,0 of source image
	move.l	#0,A1_PIXEL					;Y,X position to write data in destination area
	move.l	#$000D0008,B_COUNT				;inner loop = 13, outer loop = 8
	move.l	#$0001FFF8,A1_STEP				;1 in Y step size, negative width in X step size
	move.l	#UPDA1|SRCEN|LFU_A|LFU_AN,B_CMD	;turn on blitter

	clr.w	d5					;count enemies
	lea		enemy0,a0				;first enemy
	move.w	#AIRROBOT,O_DESC(a0)
	move.w	#SCRN_RIGHT,O_XPOS(a0)	;start off screen
	bsr		set_en_info			;set height,dwidth,iwidth,data,health,speed,direction

	move.b	#12,enemydir			;move to the left at first
	move.w	#140,O_YPOS(a0)

	rts

mkboss05::
;make boss enemy for air world
;this is the serpent
	move.l	#bs05tbl,a0
	move.w	#5,d0
	bsr		dodecomp

	bsr		ld_uncmp

	move.l	#msk05tbl,a0
	move.w	#5,d0
	bsr		do_mask

	lea		enemy1,a0				;first enemy
	move.w	#SERPBODY,O_DESC(a0)
	move.w	#SCRN_RIGHT,O_XPOS(a0)	;start off screen
	move.w	#1,d5				;enemy number
	bsr		set_en_info			;set height,dwidth,iwidth,data,health,speed,direction
	move.w	#180,O_YPOS(a0)

	lea		enemy0,a0				;tail
	move.w	#SERPWNGL,O_DESC(a0)
	move.w	enemy1+O_XPOS,O_XPOS(a0)
	add.w	#0,O_XPOS(a0)
	move.w	#0,d5				;enemy number
	bsr		set_en_info			;set height,dwidth,iwidth,data,health,speed,direction
	move.w	enemy1+O_YPOS,O_YPOS(a0)

	lea		enemy2,a0				;first enemy
	move.w	#SERPWNGR,O_DESC(a0)
	move.w	enemy1+O_XPOS,O_XPOS(a0)
	add.w	#0,O_XPOS(a0)
	move.w	#2,d5				;enemy number
	bsr		set_en_info			;set height,dwidth,iwidth,data,health,speed,direction
	move.w	enemy1+O_YPOS,O_YPOS(a0)

	rts

mkboss06::
;make boss enemy for old desert space level
;this is the weird robot
	move.l	#bs06tbl,a0
	move.w	#4,d0
	bsr		dodecomp

	move.l	#wboss00,ADJBLACK_START
	move.l	#wboss16+(128*688*2),ADJBLACK_END
	bsr		adjblak

	bsr		ld_uncmp

	move.l	#msk06tbl,a0
	move.w	#4,d0
	bsr		do_mask

;blit the shots from rom to ram
;12 x 12, 8 x 8
;total of 416 bytes, or 104 longs
	move.l	#PITCH1|PIXEL32|WID8|XADDPHR,d0
	move.l	d0,A1_FLAGS					;destination
	move.l	d0,A2_FLAGS					;source
	move.l	#wshot00,A1_BASE				;destination address
	move.l	#wshots,A2_BASE				;source address
	move.l	#0,A2_PIXEL					;start at 0,0 of source image
	move.l	#0,A1_PIXEL					;Y,X position to write data in destination area
	move.l	#$000D0008,B_COUNT				;inner loop = 13, outer loop = 8
	move.l	#$0001FFF8,A1_STEP				;1 in Y step size, negative width in X step size
	move.l	#UPDA1|SRCEN|LFU_A|LFU_AN,B_CMD	;turn on blitter

	lea		enemy1,a0				;first enemy
	move.w	#WRDBODY,O_DESC(a0)
	move.w	#SCRN_RIGHT,O_XPOS(a0)	;start off screen
	move.w	#1,d5				;enemy number
	bsr		set_en_info			;set height,dwidth,iwidth,data,health,speed,direction
	move.w	#160,O_YPOS(a0)

	lea		enemy2,a0				;tail
	move.w	#WRDTAIL,O_DESC(a0)
	move.w	enemy1+O_XPOS,O_XPOS(a0)
	add.w	#0,O_XPOS(a0)
	move.w	#2,d5				;enemy number
	bsr		set_en_info			;set height,dwidth,iwidth,data,health,speed,direction
	move.w	enemy1+O_YPOS,O_YPOS(a0)

	lea		enemy0,a0				;first enemy
	move.w	#WRDRARM,O_DESC(a0)
	move.w	enemy1+O_XPOS,O_XPOS(a0)
	add.w	#0,O_XPOS(a0)
	move.w	#0,d5				;enemy number
	bsr		set_en_info			;set height,dwidth,iwidth,data,health,speed,direction
	move.w	enemy1+O_YPOS,O_YPOS(a0)

	lea		enemy3,a0				;first enemy
	move.w	#WRDLARM,O_DESC(a0)
	move.w	enemy1+O_XPOS,O_XPOS(a0)
	add.w	#0,O_XPOS(a0)
	move.w	#3,d5				;enemy number
	bsr		set_en_info			;set height,dwidth,iwidth,data,health,speed,direction
	move.w	enemy1+O_YPOS,O_YPOS(a0)

	move.b	#12,enemydir+1			;move to the left at first

	rts

mkboss07::
;make boss enemy for the swamp level
;this is the mud man
	move.l	#bs07tbl,a0
	move.w	#7,d0
	bsr		dodecomp

	move.l	#mud00,ADJBLACK_START
	move.l	#mudshot+(32*32*2),ADJBLACK_END
	bsr		adjblak

	bsr		ld_uncmp

	move.l	#msk07tbl,a0
	move.w	#7,d0
	bsr		do_mask

	clr.w	d5					;count enemies
	lea		enemy0,a0				;first enemy
	move.w	#MUDMAN,O_DESC(a0)
	move.w	#SCRN_RIGHT+320,O_XPOS(a0)	;start off screen
	bsr		set_en_info			;set height,dwidth,iwidth,data,health,speed,direction
	move.w	#SCRN_BOTTOM-430,O_YPOS(a0)
	move.b	#12,enemydir			;move to the left at first

	clr.b	levstatus
	add.w	#448,odomend
	move.w	#SCROLL_SPEED,scrlspd

	rts

mkboss08::
;make boss enemy for the city space level
;this is the robot with the rocket engine
	move.l	#bs08tbl,a0
	move.w	#4,d0
	bsr		dodecomp

	move.l	#citybs00,ADJBLACK_START
	move.l	#citysh04+(32*30*2),ADJBLACK_END
	bsr		adjblak

	bsr		ld_uncmp

	move.l	#msk08tbl,a0
	move.w	#4,d0
	bsr		do_mask

	lea		enemy0,a0				;first enemy
	move.w	#CITYBOD,O_DESC(a0)
	move.w	#SCRN_RIGHT,O_XPOS(a0)
	clr.w	d5					;enemy number
	bsr		set_en_info			;set height,dwidth,iwidth,data,health,speed,direction
	move.w	#100,O_YPOS(a0)

	lea		enemy1,a0				;head
	move.w	#CITYHD,O_DESC(a0)
	move.w	enemy0+O_XPOS,O_XPOS(a0)
	add.w	#0,O_XPOS(a0)
	move.w	#1,d5				;enemy number
	bsr		set_en_info			;set height,dwidth,iwidth,data,health,speed,direction
	move.w	enemy0+O_YPOS,O_YPOS(a0)
	move.b	#12,enemydir			;move to the left at first

	rts

mkboss09::
;make boss enemy for the city level
;make oddit
	move.l	#bs09tbl,a0
	move.w	#4,d0
	bsr		dodecomp

	move.l	#oddit00,ADJBLACK_START
	move.l	#oddit11+(112*200*2),ADJBLACK_END
	bsr		adjblak

	bsr		ld_uncmp

	move.l	#msk09tbl,a0
	move.w	#3,d0
	bsr		do_mask

;blit the shot from rom to ram
;32 x 14
	move.l	#PITCH1|PIXEL32|WID16|XADDPHR,d0
	move.l	d0,A1_FLAGS					;destination
	move.l	d0,A2_FLAGS					;source
	move.l	#odditsh0,A1_BASE				;destination address
	move.l	#odditsht,A2_BASE				;source address
	move.l	#0,A2_PIXEL					;start at 0,0 of source image
	move.l	#0,A1_PIXEL					;Y,X position to write data in destination area
	move.l	#$000E0010,B_COUNT				;inner loop = 14, outer loop = 16
	move.l	#$0001FFF0,A1_STEP				;1 in Y step size, negative width in X step size
	move.l	#UPDA1|SRCEN|LFU_A|LFU_AN,B_CMD	;turn on blitter

	lea		enemy0,a0				;first enemy
	move.w	#ODDITCLD,O_DESC(a0)
	move.w	#SCRN_RIGHT+330,O_XPOS(a0)
	clr.w	d5					;enemy number
	bsr		set_en_info			;set height,dwidth,iwidth,data,health,speed,direction
	move.w	#SCRN_TOP+40,O_YPOS(a0)

	lea		enemy1,a0				;head
	move.w	#ODDIT,O_DESC(a0)
	move.w	enemy0+O_XPOS,O_XPOS(a0)
	move.w	#1,d5				;enemy number
	bsr		set_en_info			;set height,dwidth,iwidth,data,health,speed,direction
	move.w	#SCRN_TOP+40,O_YPOS(a0)

	move.b	#12,enemydir			;move to the left at first
	move.b	#12,enemydir+1			;move to the left at first

	clr.b	levstatus
	add.w	#512,odomend
	move.w	#SCROLL_SPEED,scrlspd
	rts

mkboss10::
	rts

split_enemy::
;(a3,d1.w) is the first of the new enemies that will be created
;a1 points to the object header for the object that got hit
	movem.l	d0-d6/a0-a6,-(sp)
	move.l	(a3,d1.w),d4			;get 4 new enemy types, 1 in each byte
	lea		enemy9,a0				;last enemy
	moveq.l	#TOTAL_ENEMIES-1,d5		;count enemy objects
	moveq.l	#3,d6				;count new objects that are created
.10:	tst.b	O_TYPE(a0)			;see if object is active
	bpl.b	.80					;if object is being used, try another
.20:	tst.b	d4
	bpl.b	.30					;only create enemy if this byte in D4 is an enemy number
	lsr.l	#8,d4				;check next byte in d4
	dbra		d6,.20
	bra.b	.90
.30:	move.w	O_XPOS(a1),O_XPOS(a0)	;use old object xpos
	move.w	O_YPOS(a1),O_YPOS(a0)	;use old object ypos
	cmp.w	#SCORPSML,d4
	bne.b	.40
	add.w	#96,O_XPOS(a0)
	add.w	#90,O_YPOS(a0)
.40:	clr.w	d0
	move.b	d4,d0
	move.w	d0,O_DESC(a0)			;use enemy type as object desc
	bsr		set_en_info
	lea		en_usept,a3
	move.b	#$FF,(a3,d5.w)			;don't use formation
.50:
	lsr.l	#8,d4				;get next byte out of the long
	dbra		d6,.80				;go to next enemy object unless all 4 bytes in D4 have been checked
	bra.b	.90					;exit if all 4 bytes have been checked
.80:	suba.l	#OBJ_SIZE,a0			;next object header
	dbra		d5,.10
.90:	movem.l	(sp)+,d0-d6/a0-a6
	rts

set_en_info::
;this sets a bunch of information for an enemy object that is being created
;a0 points to the new enemy object
;O_DESC(a0) is already set to enemy_type
;d4 is enemy type
;d5 is the enemy number
;don't change a1,d4,d5,d6 in here
	clr.b	O_TYPE(a0)			;turn enemy on by clearing negative bit, set to type 0, unscaled
	clr.l	d1					;must be clr.l for adding to en_alt_table
	move.w	O_DESC(a0),d1			;get enemy type
	lsl.w	#2,d1				;enemy type * 4
	lea		en_ht_dw,a2			;enemy height, dwidth, iwidth
	move.w	(a2,d1.w),O_HEIGHT(a0)	;set enemy height
	move.w	2(a2,d1.w),O_DWIDTH(a0)	;set enemy dwidth
	move.w	2(a2,d1.w),O_IWIDTH(a0)	;set enemy iwidth
	move.b	#TRANS_ON,O_FLAGS(a0)
	lea		atktable,a2			;table of atk_chnc values
	move.l	seed+4,d0
	and.w	#3,d0				;0 - 3
	add.w	d1,d0				;add enemy_type * 4
	lea		atk_chnc,a3			;atk_chnc for each enemy
	move.b	(a2,d0.w),(a3,d5.w)		;save atk_chnc for current enemy number
	move.w	d5,d2				;get enemy number
	lsl.w	#1,d2				;enemy number * 2
	lsr.w	#1,d1				;change enemy type * 4 to enemy type * 2
	lea		health_table,a2		;health for each type of enemy
	lea		en_health,a3			;health for active enemies
	move.w	(a2,d1.w),(a3,d2.w)		;save initial enemy health value
	clr.w	d0
	move.b	lvlsdone,d0
	lsr.w	#1,d0
	add.w	d0,(a3,d2.w)			;add 1 health for each pair of levels that have been completed

	lea		en_altmv,a2			;if alternate moving animation should be used
	lea		en_alt_table,a3		;settings for en_altmv
	add.l	d1,a3				;add enemy type * 2 to table address
	move.l	seed+12,d0
	and.w	#1,d0				;get 0 or 1
	move.b	(a3,d0.w),(a2,d5.w)		;set en_altmv
	lsl.w	#2,d1				;change enemy_type * 2 to enemy_type * 8
	lea		en_spd_table,a2
	move.l	seed+12,d0
	and.w	#7,d0				;8 possible speeds for each enemy type
	add.w	d1,d0				;add enemy type * 8
	lea		en_speed,a3
	move.b	(a2,d0.w),(a3,d5.w)		;save speed for current enemy
	lsl.w	#2,d1				;change enemy_type * 8 to enemy_type * 32
	lea		en_dir_table,a2		;table of possible directions for each enemy
	jsr		random
	cmp.w	#SCRN_RIGHT,O_XPOS(a0)
	blt.b	.40					;if enemy is on the screen, use any direction
	and.w	#15,d0				;pick one of the last 15 directions
	add.w	#16,d0				;start at the 16th direction in the table
.40:	and.w	#31,d0				;31 possible directions for each enemy
	add.w	d1,d0				;add enemy_type * 32
	lea		enemydir,a3			;table of directions for each enemy
	move.b	(a2,d0.w),(a3,d5.w)		;save new direction
	lea		en_action,a2
	move.b	#EN_MOVING,d0			;assume enemy will start moving
	move.w	O_DESC(a0),d1			;get enemy_type
	move.b	#4,O_DEPTH(a0)			;set O_DEPTH to 16 bits
	lea		en_appear_flag,a3
	cmp.b	#1,(a3,d1.w)			;1 if enemy has appearing animation
	bne.b	.50
	move.b	#EN_APPEAR,d0			;start appearing animation
.50:	move.b	d0,(a2,d5.w)			;set en_action to moving or appearing
	lea		en_pat,a2
	lea		en_usept,a3
	move.b	(a2,d1.w),(a3,d5.w)		;set en_usept
	lea		in_form,a2
	move.b	#$FF,(a2,d5.w)			;assume enemy is not in a formation
	lea		en_mvlmt,a2			;en_mvlmt for each enemy number
	lea		en_mvlim,a3			;en_mvlmt for each type of enemy
	move.b	(a3,d1.w),(a2,d5.w)		;set en_mvlmt
	lea		en_an_step,a3
	clr.b	(a3,d5.w)				;reset anim step
	lea		en_an_chg,a3
	clr.b	(a3,d5.w)				;reset anim change counter
	lea		en_an_time,a2
	lea		en_chg_times,a3		;table of times for each en_action
	lsl.w	#2,d1				;multiply enemy type * 4 (4 total actions per enemy)
	and.w	#$FF,d0				;make sure d0 has only en_action in low byte
	add.w	d1,d0				;add enemy type * 4
	move.b	(a3,d0.w),(a2,d5.w)		;get limit for en_an_chg depending on en_action
	lea		en_fired,a3
	clr.b	(a3,d5.w)				;reset en_fired flag
	lea		en_mvcnt,a3
	clr.b	(a3,d5.w)				;reset en_mvcnt
	move.w	d5,d0				;can't change d5
	lsl.w	#1,d0				;enemy number * 2
	lea		en_type,a3
	move.w	O_DESC(a0),(a3,d0.w)	;save enemy type

	lea		en_ptinf,a2
	clr.l	d2
	move.w	O_DESC(a0),d2
	lsl.w	#4,d2				;enemy type * 16
	add.l	d2,a2				;set a2 to start of info for this enemy type
	lea		en_formx,a3
	move.w	(a2)+,d1
	cmp.w	#-1,d1				;use enemy ypos if -1
	bne.b	.55
	move.w	O_XPOS(a0),d1
.55:	move.w	d1,(a3,d0.w)
	lea		en_formy,a3
	move.w	(a2)+,d1
	cmp.w	#-1,d1
	bne.b	.60
	move.w	O_YPOS(a0),d1
.60:	move.w	d1,(a3,d0.w)
	lea		en_rad,a3
	move.w	(a2)+,d2
	move.w	d2,(a3,d0.w)
	lea		en_newrd,a3
	move.w	d2,(a3,d0.w)
	lea		en_theta,a3
	move.w	(a2)+,d2
	move.w	d2,(a3,d0.w)
	lea		en_formc,a3
	move.w	(a2)+,(a3,d0.w)
	lea		en_frmlm,a3
	move.w	(a2),(a3,d0.w)

	lea		en_limit,a3
	clr.l	d2
	move.w	O_DESC(a0),d2
	lsl.w	#3,d2				;enemy type * 8
	add.l	d2,a3
	lea		en_lim,a2
	lsl.w	#2,d0				;enemy number * 8
	move.w	(a3)+,(a2,d0.w)
	move.w	(a3)+,2(a2,d0.w)
	move.w	(a3)+,4(a2,d0.w)
	move.w	(a3)+,6(a2,d0.w)

	rts

damage_enemy::
;a1 points to enemy object header that was hit
;d7 is amount of damage to inflict on enemy
;d6 is the enemy number that was hit
	movem.l	d0-d6/a0-a6,-(sp)
	move.w	d6,d2				;need to leave d6 alone
	lsl.w	#1,d2				;2 bytes for each enemy
	lea		en_health,a3
	move.w	(a3,d2.w),d0			;get enemy health
	bmi		.90					;enemy is already dead of health is negative, or it can't be damaged
	sub.w	d7,(a3,d2.w)			;enemy health - damage to inflict
	bmi.b	.15					;enemy destroyed if damage value is < 0
	lea		enhitsnd,a3			;sounds to play when enemy gets hit but not destroyed
	move.w	O_DESC(a1),d1
	clr.w	d0
	move.b	(a3,d1.w),d0
	bmi.b	.90					;no sample if $FF
	move.w	O_XPOS(a1),d1			;xpos to determine pan value
	bsr		playsnd				;d0 = sample number, d1 = sound xpos
	clr.w	d7					;return that enemy was not destroyed
	bra.b	.90

.15:	move.w	#1,d7				;return that enemy was destroyed
	move.w	O_DESC(a1),d1
	lsl.w	#2,d1				;4 bytes for each score amount
	lea		en_pt_table,a3
	move.l	(a3,d1.w),d0
	bsr		addscore				;add.l d0 to score
	move.w	O_DESC(a1),d1
	lsl.w	#2,d1				;enemy type * 4
	lea		en_dead_table,a3		;what happens to enemy when it dies
	move.b	(a3,d1.w),d0
	bmi.b	.20					;if positive, enemy splits into 2 new enemies
	bsr		split_enemy
	bra.b	.40
.20:	cmp.b	#$FE,(a3,d1.w)			;if $FE, enemy releases powerup
	bne.b	.40					;if $FF, enemy just explodes
	bsr		make_pwrup
	bra.b	.80
.40:	cmp.b	#$FD,(a3,d1.w)			;if $FD, enemy has dying animation
	bne.b	.80
	lea		en_action,a3
	move.b	#EN_DYING,(a3,d6.w)
	lea		en_an_chg,a3
	clr.b	(a3,d6.w)				;reset animation counter
	lea		en_an_step,a3
	clr.b	(a3,d6.w)				;reset animation step
	bra.b	.90					;no explosion
.80:	bsr		start_explosion
.90:	movem.l	(sp)+,d0-d6/a0-a6
	rts


