; blitter zap routine

Blitzap:
	movem.l	a0/d0-d1,-(sp)
	moveq	#0,d0
	move.l	#A1_BASE,a0
	moveq	#13,d1
.lp1:	move.l	d0,(a0)+
	dbra	d1,.lp1
	addq.l	#4,a0
	moveq	#15,d1
.lp2:	move.l	d0,(a0)+
	dbra	d1,.lp2
	movem.l	(sp)+,a0/d0-d1
	rts

;=================================================================
; new startup routine, intended to make startups more structured

start_from_scratch::
	clr.l	sound1st.w		; this will be used to identify a 'cold boot'
	move.l	#$70007,G_END		; very important hence early use
	move.l	#$70007,D_END

;	move.l	G_FLAGS,d0
;	and.w	#$800F,d0		; clears interrupt ability and other stuff, and sets to bank 0
;	bclr.l	#14,d0		; force GPU to run in bank 0
;	move.l	d0,G_FLAGS

;	moveq	#0,d0
;	move.w	d0,$f10002
;	move.w	d0,$f10000
;	move.l	d0,D_CTRL		; kill that dsp !
;	move.l	d0,G_CTRL		; and the GPU

;	moveq	#-1,d0
;	move.w	d0,VI			; disable vertical interrupt

	moveq.l	#0,d0
	move.l	d0,0.w			; special for OP security
	move.w	d0,INT1			; remove interrupts for now
	move.l	d0,blitsem.w
	move.w	d0,BG
	move.l	d0,BORD1
	move.l	d0,last_patch.w		; make sure that accidental music problems won't happen
;	move.l	Nuli,$100	;USER0 - set interrupts to just instantly return without ANYTHING sensible being done
	move.b	d0,gpu_ready.w
	move.b	d0,demo_mode.w

	bsr	Blitzap			; wipe all blitter registers jic, especially for relocater

	moveq.l	#4,d0
	move.l	d0,4.w

	bsr	Normal_generate		; first off put all the adjusted normals in place
	bsr	Patch_3d		; then adjust the pointers to point where the data will end up
	bsr	RAM_to_ROM		; move data segment up into ROM from RAM link address (if not already there)
	bsr	full_blank		; wipe all memory from $4000 to $200000
	bsr	downeep			; read all eeprom contents into RAM

	moveq.l	#-1,d0
	move.l	d0,key_mask.w
	move.b	#1,music.w	; set to music on by default

	rts

;==================================================================

Sys_setup::	; setup for variables required immediately - for interrupt routines etc
	movem.l	d0-d1,-(sp)
	move.w	#$100,Sound.w
	move.l	#mappix,Mapptr.w	; don't ask - it works.
	move.w	#255,speedo.w		; this is in fact writing 0 to speedo, and 255 to newolist

	move.w	$f14002,d0		; read joy2 which includes system type etc
	btst	#4,d0
	sne	d0			
	neg.b	d0
	move.b	d0,ntsc_type.w
	bne.b	.ntt
	move.w	#50,one_second.w
	move.l	#7<<10,d0			; pal offset for 3d - makes screen bigger, and triggers 25% scale
	move.l	d0,v_scale.w
	bra.b	.skt
.ntt:	move.w	#60,one_second.w
	moveq	#0,d0
	move.l	d0,v_scale.w

.skt:	movea.l	#MOBJ,a0
	move.l	#(MO3>>11),(a0)+
	move.l	#(MO3<<21)|(2<<14)|3,d0
	move.l	#($1Fa<<3),d1
	tst.b	ntsc_type.w
	bne.b	.ntsc
	add.l	#100<<3,d1
.ntsc:	or.l	d1,d0
	move.l	d0,(a0)+	; branch after line 250 to stop object
	move.l	#(use_list>>11),(a0)+
	move.l	#(use_list<<21)|(2<<14)|(24<<3)|3,(a0)+	; branch after line 12 to actual object list
	clr.l	(a0)+
	moveq.l	#4,d0
	move.l	d0,(a0)+
	movea.w	#use_list,a0		; place a stop object in the 'in use' list just to be safe
	clr.l	(a0)+
	move.l	d0,(a0)+

	move.w	#CLUT_table+$100,d0
	move.w	d0,CLUT_in.w
	move.w	d0,CLUT_out.w
	movem.l	(sp)+,d0-d1
	rts

;==================================================================

general_start_up::
	clr.w	program_area.w
	clr.w	counter.w
	bsr	Stack_zap	; write deadcode into stack area - primarily for debugging
	bsr	Data_reloc	; move data segment back into RAM from ROM
	bsr	Code_reloc	; put the main program code into RAM for speed during game
	bsr	Sys_setup	; set main system values
	bsr	Variable_setup	; clear various variables and initialise some
	bsr	set_screen_height
	bsr	Gen_setup	; temporary measure - need to split routine into parts required early or late *********
	bsr 	GPUWrite	; Halt the GPU and write the program into it. 
	bsr	VidOff		; switch to a stop object - this probably won't be needed in final version
	bsr 	VideoIni	; sets up the video control registers.
	bsr 	IntInit		; sets up video interrupt routine which acknowledges and resets the object list pointer
	move.w	#$6C1,VMODE	; switch to required display mode
	bsr	sync2
	rts

;==================================================================

Variable_setup::

	moveq.l	#0,d0		; zero numerous variables
	move.l	d0,gpusem.w
	move.l	d0,blitsem.w
	move.l	d0,speed.w
	move.l	d0,brakes.w
	move.l	d0,joy_edge.w
	move.l	d0,joy_cur.w
	move.l	d0,background.w	; background sky clearance colour
	move.l	d0,ground.w	; background ground clearance colour
	move.l	d0,colmin.w
	move.l	d0,colhlt.w
	move.l	d0,G_DIVCTRL	; set GPU for 32 bit divides
	move.l	d0,Zeroph.w
	move.l	d0,Zeroph+4.w

	move.l	d0,rota.w	; set collon as well
	move.l	d0,trailer.w	; set resetct as well
	move.l	d0,units.w	; set disnum as well
	move.w	d0,colrot.w
	move.w	d0,curr_twist.w
	move.b	d0,coldir.w
	move.b	d0,dead.w
	move.b	d0,out_of_control.w
	move.b	d0,display_mode.w
	move.b	d0,allow_clear.w
	move.b	d0,clear_done.w
	move.l	d0,viewmove.w

;	tst.l	gpusem.w
;	bne	Variable_setup	; force re-run if hasn't cleared

	moveq	#1,d0
	move.w	d0,num_players.w

	bsr	title_setup

	moveq.l	#-1,d0		; set others to -1
	move.l	d0,horizon.w
	move.l	d0,key_mask.w
	move.b	d0,request_delayed.w

	move.w	#axldis,axle_distance.w
	move.w	#160*112,sky_height.w
	move.w	#160*128,ground_height.w

	rts

;==================================================================

title_setup::

	clr.w	perspective.w
	move.l	#$77A0,GTarget.w	; these required for start-up screens
	move.b	#$c,GAmbient.w
	move.b	#$18,GBright.w
	move.w	#ibasez,ZBase.w

	rts

;==================================================================

Gen_setup::

	move.w	#$70f0,Palette.w
	move.b	#-4,cycdir.w

	move.w	#$2077,wheelx.w
	move.w	#$1077,wheely.w

	moveq	#0,d0
	moveq	#4,d1
	bsr	CLUT_write

	moveq	#0,d0
	moveq	#16,d1
	bsr	CLUT_write

	move.w	#$f080,d0
	moveq	#18,d1
	bsr	CLUT_write

	moveq	#0,d0
	moveq	#20,d1
	bsr	CLUT_write

	move.w	#$f080,d0
	moveq	#22,d1
	bsr	CLUT_write

	move.l	#$40000000,xspd.w	; sets both x and z values
	move.w	Varlist,disvar.w	; set up variable display to first entry
	move.l	#60000,splim.w

	move.l	G_FLAGS,d0
	and.w	#$800F,d0		; clears interrupt ability and other stuff, and sets to bank 0
	bclr.l	#14,d0			; force GPU to run in bank 0
	move.l	d0,G_FLAGS
	rts

;==================================================================


Cart_clear_code::
	movem.l	a0/d0-d3,-(sp)
	movea.l	#cockpit,a0
	moveq	#65,d0
	bsr	rldin

	bsr	cart_reset
	start_music ingreen
	move.w	#$5f,last_pitch.w	; this is to ensure correct pitch gets used each time, if the music is restarted
	tst.w	music_volume.w
	bne.b	.ski
	jsr	StopMusic

.ski:	movea.l	#reset_list+16,a0
	tst.b	ntsc_type.w
	bne.b	.ok
	lea	16(a0),a0
.ok:	bclr	#5,6(a0)		; put cart message on

	movem.l	(sp)+,a0/d0-d3
	rts

;==================================================================

Keystuff::
	bsr	readpad
	bsr	FX			; to allow 0 music off
	tst.b	allow_clear.w
	bne.b	Keyclear
	bsr	ResetKey
	rts

Keyclear:
	movem.l	d0/d1,-(sp)
	move.l	#(1<<KEY_STAR)|(1<<KEY_HASH)|(1<<OPTION),d1
	move.l	joy_cur.w,d0
	and.l	d1,d0
	cmp.l	d0,d1
	bne.b	.notc
	tas	clear_done.w
	bne.b	.notc			; limit to one single clear, requiring full reset to change
	bsr	Cart_clear_code
.notc:	moveq	#0,d0
	movem.l	(sp)+,d0/d1
	rts

Slow_roll:			; takes object number in d0, and rolls upwards in steps of 1 line for d1 steps
	movea.l	#reset_list,a0		; get address of object data
	asl.l	#4,d0			; scale up
	adda.l	d0,a0
	move.l	(a0),d2			; read current x pos

.lp:	bsr	sync
	bsr	sync			; second wait to slow roll down
	bsr	Keystuff
	add.l	#$28000,d2
	move.l	d2,(a0)
	move.l	joy_cur.w,d0
	and.l	#ANY_FIRE,d0
	dbne	d1,.lp
.exit:	rts

place_object::				; doesn't trash anything (yea!)
	move.w	(a0)+,40+Genstr+6
	move.l	(a0)+,40+Genstr+12
	move.l	(a0)+,40+Genstr+20
	bsr	Display_routine
	rts

move_to_next::				; trashes d1
	move.l	d0,-(sp)
	move.w	(a0)+,d1		; scale factor

	move.w	(a0)+,d0
	sub.w	40+Genstr+6,d0
	asr.w	d1,d0
	move.w	d0,rota.w

	move.l	(a0)+,d0
	sub.l	40+Genstr+12,d0
	asr.l	d1,d0
	move.l	d0,xstep.w

	move.l	(a0)+,d0
	sub.l	40+Genstr+20,d0
	asr.l	d1,d0
	move.l	d0,zstep.w

	moveq	#1,d0			; counter
	asl.l	d1,d0
	moveq	#0,d1
	bra	.dl

.lp:	move.w	rota.w,d1
	add.w	d1,40+Genstr+6

	move.l	xstep.w,d1
	add.l	d1,40+Genstr+12

	move.l	zstep.w,d1
	add.l	d1,40+Genstr+20

	bsr	Display_routine
	bsr	Keystuff
	move.l	joy_cur.w,d1
	and.l	#ANY_FIRE,d1
.dl:	dbne	d0,.lp

	move.l	(sp)+,d0
	rts

random_car:			; trashes d0,d1
	move.w	#6,d1
.agn:	bsr	Randx
	cmp.w	last_car.w,d0	; check no same
	beq.b	.agn
	move.w	d0,last_car.w	; retain for future reference
	muls	#20,d0	
	add.l	#Ncar,d0
	move.l	d0,Genstr+$44	; change to randomly selected car
	rts

Drive_in:				; trashes d0,a0,d1, returns eq if no keys pressed, ne if pressed
	moveq	#2,d0			; code for single car 3d data
	bsr	Mwrite			; read data
	lea	Position_data-*-2(PC),a0
	clr.w	Genstr+40+4		; cancels rotation value
	bsr	random_car

	move.w	(a0)+,d0		; loop counter
	bsr	place_object

.lp:	bsr	move_to_next
	move.l	joy_cur.w,d1
	and.l	#ANY_FIRE,d1
	dbne	d0,.lp
	
.exit:	rts
	
Multi_drive:
	move.w	#180,d1
	bsr	Wait_time
	bne	.exit

	moveq	#2,d2			; to allow 3 cars to be displayed before fall through to credit screen

.dr:	bsr	Drive_in
	bne	.exit

	move.w	#50,d1
	bsr	Wait_time
	bne	.exit

	bsr	move_to_next		; drives off screen
	dbra	d2,.dr			; and do the drive in again

.exit:	rts

anim_decode::
	movem.l	d0-d1/a1,-(sp)
	movea.l	#Gpu_data,a1
	move.l	d2,(a1)+		; write out source address
	move.l	d1,(a1)+		; write out target address

	clr.l	counter.w
	RunGPU	15
	waitgpu
	moveq	#3,d0
	bsr	floop
	move.l	blitsem.w,d2		; read new (follow-on) source address
	subq.l	#2,d2
	clr.l	blitsem.w		; must clear this in case someone else uses it (specifically sound !)
	movem.l	(sp)+,d0-d1/a1
	rts

Play_intro:
	movem.l	d0-d3,-(sp)

	move.l	#bit_store,d1		; output target address
	move.l	#introanim,d2		; input address
	moveq	#14,d0			; number of frame changes to play

.lp:	bsr	anim_decode
	bsr	Keystuff
	move.l	joy_cur.w,d3
	and.l	#ANY_FIRE,d3
	dbne	d0,.lp
	clr.l	blitsem.w		; to prevent instant hangup !
	tst.l	d3			; recover key test status after losing it above
.exit:	movem.l	(sp)+,d0-d3
	rts

Position_data:	; format : extra,y rotation, x position, z position, where extra is step count for first one, and scale value for subsequent ones
	init	3,$100,$8000.l,$b000.l		; 3 because its count-1, and last section is only for leaving
	init	$5,$180,0.l,$7800.l
	init	$2,$200,-$1000.l,$6000.l
	init	$3,$240,-$1400.l,$3000.l
	init	$3,$280,-$180.l,$a00.l
	init	$4,$300,$1000.l,$0.l		; if taken, drives off screen

.if 0
	init	3,$180,$b000.l,$b000.l		; 3 because its count-1, and last section is only for leaving
	init	$6,$1c0,0.l,$7800.l
	init	$3,$200,-$1000.l,$6000.l
	init	$3,$260,-$1800.l,$3000.l
	init	$3,$280,-$200.l,$a00.l
	init	$4,$380,$1000.l,$0.l		; if taken, drives off screen
.endif
;==================================================================

Wait_time::	; a general purpose routine, which will do nothing for a given time, or until any fire key
		; time is in frames, in d1, and all the time allow 0 to switch music on and off
		; trashes d0,d1, returns eq if no key pressed, ne if pressed.
	bsr	sync
	bsr	Keystuff
	move.l	joy_cur.w,d0
	and.l	#ANY_FIRE,d0
	dbne	d1,Wait_time
	rts	

;==================================================================

Fade_find::				; routine to scan the animated object structure and find the fade object
	bsr	sync
	movea.w	#anim_list,a0
.lp:	addq.l	#2,a0			; skip the object address
	move.w	(a0)+,d0
	beq.b	.none			; not really found, but hit end of list, so give up
	cmp.w	#2,d0
	ble.b	.multi
	cmp.w	#5,d0
	beq.b	.found
	lea	16(a0),a0
	bra	.lp
.multi:	move.w	(a0),d0
	addq.w	#1,d0
	asl.w	#2,d0
	adda.w	d0,a0
	bra	.lp
.none:	addq.l	#4,a0			; set it to point to somewhere harmless
.found:	move.w	a0,fade_address.w
	rts

Unfade::movem.l	a0/d0,-(sp)
	movea.w	fade_address.w,a0
	move.w	#$0100,(a0)		; write out the request
	bra.b	fin

Fade::	movem.l	a0/d0,-(sp)
	movea.w	fade_address.w,a0
	move.w	#$ff80,(a0)		; write out the request
fin:	st.b	fade_over.w		; wait for this to clear, and its all done
.lp:	stop	#$2000
	bsr	Keystuff
	move.l	joy_cur.w,d0
	and.l	#ANY_FIRE,d0
	bne.b	.exit
	tst.b	fade_over.w
	bne.b	.lp
.exit:	movem.l	(sp)+,d0/a0
	rts
	
Start_fade::				; just starts a fade, allowing other stuff to carry on whilst its occuring
	move.l	a0,-(sp)
	movea.w	fade_address.w,a0
	move.w	#$ff80,(a0)
	st.b	fade_over.w
	move.l	(sp)+,a0
	rts

Get_data:
	move.w	#$0080,d0
	moveq	#0,d1
	bsr	CLUT_write		; sets first CLUT entry, for shading overlay to be black at start

	moveq	#2,d0
	bsr	Request_3d		; get the 3d object data for intro screens

	movea.l	#Mapdisp,a0		; get the font required for stats screen.
	move.l	#fontaz,a1
	move.l	#fontpal,a2
	bsr	rlpin

	move.l	#Exdisp,a0		; expand checkered flag 
	moveq	#1,d0
	bsr	rldin			; NEW VERSION IS UNPALETTED and never likely to be ! (1100 colours)

	move.l	a0,d1			; target address
	move.l	#copyrt,d0		; source address
	move.l	#copyrte,d2
	sub.l	d0,d2			; length
	bsr	Blit_move
	rts

Clear_screens:
	move.l	#$25800,d0		; length of one screen
	move.l	#bit_store,d1		; start of screen
	bsr	Blank			; clear screen so that animotor can work

	bsr	Obj_blank		; clear a screen (the offscreen)
	bchg.b	#3,screen+3.w		; flip screen number
	bsr	Obj_blank		; clear a screen (the offscreen)
	rts

Show_logo:
	move.l	#Exdisp,a0	; output address
	moveq	#64,d0		; request rle item #64 - Rebellion Logo
	bsr	rldin		; decompress data
	movea.l	#ObjDef0,a0	; address of unpacked list (input)
	bsr 	ObjSetup	; set up an object list as defined in objdefs.s
	bsr	Fade_find
	bsr	Unfade		; display logo
	rts

Show_scores:
	moveq	#100,d1
	bsr	Wait_time
	bne.b	.exit
	bsr	Fade
	bne.b	.exit

	movea.l	#cockpit,a1		; screen to print to
	bsr	display_fame

.exit:	rts

Show_top_5:
	move.w	#180,d1
	bsr	Wait_time
	bne.b	.exit
	moveq	#0,d0
	bsr	Roll_object_down
	bne.b	.exit

	move.l	#$25800,d0		; one full screen
	move.l	#cockpit,d1		; start of screen
	bsr	Blank			; clear screen for text later

	movea.l	#cockpit,a1		; screen to print to
	bsr	display_top5
.exit:	rts


Show_credits:
	move.w	#150,d1
	bsr	Wait_time
	bne.b	.exit
	moveq	#0,d0
	bsr	Roll_object_down
	bne.b	.exit

	move.w	#$0080,d0
	moveq	#0,d1
	bsr	CLUT_write		; sets first CLUT entry, for shading overlay to be black at start

	move.l	#obj_store,a0		; display address
	move.l	#credits,a1		; compressed Atari credits screen
	move.l	#credpal,a2		; palette
	bsr	rlpin
	
	move.l	a0,a1			; hold temporarily for decoding second block

	movea.l	#ObjDef7,a0		; get object list set up
	bsr	ObjSetup
	bsr	Fade_find

	bsr	Unfade			; clear shading to display first sheet of credits
	bne.b	.exit

	move.l	a1,a0			; recover continuation address
	move.l	#credit2,a1		; Rebellion credits screen
	move.l	#credpal,a2		; palette
	bsr	rlpin			; outputs Rebellion graphics after Atari one, so that roll through can be smooth

	move.l	#$30000,d0		; blank to end of memory
	move.l	a0,d1			; start of screen
	bsr	Blank			; clear screen so credits can roll off into blackness

.exit:	rts

Roll_credits:
	move.w	#50,d1
	bsr	Wait_time
	bne.b	.exit

	moveq	#0,d0			; roll object 0 upwards
	move.w	#1024,d1		; distance to roll it
	bsr	Slow_roll
.exit:	rts


RedLine::
	bsr	title_setup
	RunGPU	12
	clr.b	display_mode.w		; no sky for this bit !!
	clr.l	ground.w		; and no ground colour !
	clr.l	viewmove.w		; and no shitty flickering
	bsr	Get_data
	bsr	Clear_screens
	st	allow_clear.w

	movea.l	#ObjDef4,a0
	tst.b	ntsc_type.w
	bne.b	.ook
	movea.l	#ObjDef4a,a0
.ook:	bsr	ObjSetup
	bsr	Fade_find
	bsr	Unfade
	bne.b	.exit

	bsr	Play_intro
	bne.b	.exit

	bsr	Multi_drive
	bne.b	.exit

	clr.b	allow_clear.w

.logo:	bsr	Fade		; because there ain't enough RAM to hold the current display AND 600Kb of credits graphics
	bne.b	.exit

	move.l	#$25800,d0		; one full screen
	move.l	#cockpit,d1		; start of screen
	bsr	Blank			; clear screen for text later

	bsr	Show_logo
	bne.b	.exit

.high:	bsr	Show_scores
	bne.b	.exit

.top:	bsr	Show_top_5
	bne.b	.exit

.cred:	bsr	Show_credits
	bne.b	.exit
	bsr	Roll_credits
;	bne.b	.exit		; will be needed when demo is in

;	bsr	Demo
	beq	RedLine


.exit:	bsr	VidOff
	moveq	#0,d0			; ensure clearance of shade
	moveq	#0,d1
	bsr	CLUT_write
	clr.b	allow_clear.w
	clr.b	demo_mode.w
	rts

basic_text_screen:
	movea.l	#ObjDef9,a0
	bsr	ObjSetup
	bsr	Fade_find
	moveq	#0,d0
	moveq	#0,d1
	bsr	CLUT_write
	rts

display_fame:
	bsr	basic_text_screen
	bsr	Print_fame

	moveq	#0,d0
	bsr	Roll_object_up
	rts

display_top5:
	bsr	basic_text_screen
	bsr	Print_top5

	moveq	#0,d0
	bsr	Roll_object_up
	rts

Print_fame::
	movea.l	#cockpit+$1400,a0
	moveq	#34,d0
	bsr	rldin
	moveq	#28,d2
	movea.w	#Fame_names,a0
	movea.w	#Fame_times,a4
	lea	Track_names-*-2(PC),a3
	movea.l	a0,a2			; because handling will be slightly erratic
	moveq	#9,d0

.lp:	moveq	#20,d1
	add.w	#16,d2
	bsr	Fame_line
	addq.l	#8,a2
	move.l	a2,a0
	dbra	d0,.lp
	rts

Print_top5::
	movea.l	#cockpit+$f00+$3c00,a0 ; 24 lines down
	moveq	#35,d0
	bsr	rldin
;	moveq	#24+24,d2

	lea	Tour_head-*-2(PC),a0
	bsr	Print_some		; prints column headings
	addq.w	#8,d2

	movea.w	#Tour_names,a0
	movea.w	#Tour_times,a4
	movea.w	#Tour_points,a3
	movea.l	a0,a2			; because handling will be slightly erratic
	moveq	#4,d0

.lp:	moveq	#64,d1
	add.w	#16,d2
	bsr	Tour_line
	addq.l	#8,a2
	move.l	a2,a0
	dbra	d0,.lp
	rts


Fame_line:
	move.l	d0,-(sp)
	exg	a0,a3			; use a3 to print name of track
	bsr	print_string_here	; prints one string and stops after the 0
	move.w	#168,d1
	exg	a0,a3
	bsr	print_name		; special routine because names use non-standard format
	move.w	#248,d1			; has to be here for longest name 'MMMMMMMM'
	moveq	#0,d0
	move.w	(a4)+,d0
	bsr	Blit_time
	move.l	(sp)+,d0
	rts

Tour_line:
	move.l	d0,-(sp)
	neg.w	d0
	addq.w	#5,d0
	bsr	Blit_digit
	add.w	#24,d1
	bsr	print_name
	move.w	#184,d1			; because name could end up anywhere
	moveq	#0,d0
	move.b	(a3)+,d0
	moveq	#2,d4
	bsr	Blit_number
	add.w	#16,d1
	move.l	(a4)+,d0
	bsr	Blit_time
	move.l	(sp)+,d0
	rts


print_name:
	movem.l	d0/d3,-(sp)
	moveq	#7,d3			; limit of 8 characters
.loop:	moveq	#$1f,d0
	and.b	(a0)+,d0
	beq.b	.done			; in case of inexplicable failure to read eeprom or just zeros marking end
	bsr	Blit_char
	bsr	move_forward_char
	bsr	perform_kerning
	dbra	d3,.loop
.done:	movem.l	(sp)+,d0/d3
	rts


;high_title:
;	dc.w	320-(12*10)/2,11
;	dc.b	"HALL^OF^FAME",0

Track_names:
	dc.b	"GREEN^VALLEY",0
	dc.b	"RIVER^MOUTH",0
	dc.b	"DESERT^PASS",0
	dc.b	"DEEP^WOOD",0
	dc.b	"THE^HOLE",0
	dc.b	"ISLAND^HOP",0
	dc.b	"THE^GORGE",0
	dc.b	"CONCRETE^CANYON",0
	dc.b	"SUNSET^STRIP",0
	dc.b	"ARCTIC^RUN",0

.even

Tour_head:	; text for tournament column headings
	dc.w	50,48+24
	dc.b	"POSN^^NAME^^^SCORE^_TIME",0
	dc.w	-1

.even
Tournament_setup::
	movem.l	a0/d0,-(sp)
	lea	Tournament_tracks-2-*(PC),a0
	moveq	#0,d0
	move.b	tourn_track.w,d0
	asl.w	#1,d0
	adda.w	d0,a0
	move.b	(a0)+,tourn_weather.w
	move.b	(a0)+,tourn_qty_laps.w
	move.b	car_colour.w,tourn_car_col.w
	cmp.b	#2,race_type.w
	bne.b	.ex
	move.b	tourn_weather.w,weather.w
	move.b	tourn_qty_laps.w,qty_laps.w
	move.b	tourn_track.w,track_no.w
.ex:	movem.l	(sp)+,a0/d0
	rts


Tournament_tracks::			; option data track by track - weather.b/laps.b

.if 0
	dc.b	0,2
	dc.b	1,2
	dc.b	0,2
	dc.b	2,2
	dc.b	2,2
	dc.b	0,2
	dc.b	1,2
	dc.b	1,2
	dc.b	0,2
	dc.b	0,2
	dc.b	0,2
.else
	dc.b	0,10
	dc.b	1,13
	dc.b	0,10
	dc.b	2,13
	dc.b	2,15
	dc.b	0,12
	dc.b	1,15
	dc.b	1,12
	dc.b	0,14
	dc.b	0,10
	dc.b	0,10
.endif
Track_init::				; initialise data for track number in d0
	movem.l	a0/d0,-(sp)
	movea.l	#Track_slow,a0
	asl.w	#1,d0		
	move.w	(a0,d0),slow_amount.w
	movem.l	(sp)+,a0/d0
	rts

Weather_init::				; initialise data that is weather dependent (track in d0 weather in d1)
	movem.l	d0-d1/a0,-(sp)
	movea.l	#Tcols,a0	
	asl.w	#5,d0		
	adda.l	d0,a0

	asl.w	#3,d1
	adda.w	d1,a0
	move.w	(a0)+,d0
	move.w	d0,ground.w
	move.w	d0,ground+2.w		; set both halves of ground fill colour
	clr.l	background.w
	move.w	(a0)+,d0
	move.l	d0,GTarget.w		; set depth cue target colour
	move.w	(a0)+,GAmbient.w	; writing both ambient and bright

	move.w	(a0)+,d0		; this is the background colour for putting in the CLUT
	move.w	d0,d1
	swap	d0
	move.w	d1,d0
	move.l	d0,sky_colour.w

	moveq	#0,d0			; this sets the colour for rain - clear if not in use
	moveq	#4,d1
	bsr	CLUT_write
	move.b	weather.w,d1
	cmpi.b	#1,d1
	bne.b	.nj
	move.w	#raincol,d0		; rain colour if rain is on
.nj:	moveq	#6,d1
	bsr	CLUT_write	

	move.w	#96,ZBase.w		; install new perspective 
	RunGPU	12			; install all the above data items in GPU registers [kept down here because a0 is corrupted]

	movem.l	(sp)+,d0-d1/a0
	rts


Weather_cue::				; make sure depth cuing is set for weather (only fog)
	movem.l	a0/d0,-(sp)
	cmpi.b	#2,d0			; test for FOG
	bne.b	.skip

	movea.l	#Genstr+$18+$a,a0	; depth cue adjustment
	moveq.l	#6,d0			; less one for dbra
.ddc:	move.w	#$1c,(a0)		; used to replace current value
	addq.l	#8,a0
	dbra	d0,.ddc

.skip:	movem.l	(sp)+,a0/d0
	rts


Sky_expand::				; given track no in d0, weather in d1
	movem.l	d0-d1/a0-a2,-(sp)
	movea.l	#bit_store,a0		; output area for sky background
	movea.l	#SkyList,a2		; pointers
	asl.w	#5,d0			; 8 longs per entry - pairs of 'picture,palette'
	adda.w	d0,a2
	asl.w	#3,d1			; for 2 longs at a time
	add.w	d1,a2
	movea.l	(a2)+,a1		; get pointer to input data
	move.l	(a2),d0			; get palette address
	beq.b	.lzs
	move.l	d0,a2
	bsr	rlpin
	movem.l	(sp)+,d0-d1/a0-a2
	rts

.lzs:	move.l	a1,lzinbuf		; input address as specified in skylist
	move.l	a0,lzoutbuf		; output address as normal
	move.l	#obj_store,lzworkbuf	; workspace is the currently invisible screen !!
	RunGPU	17			; do that thing !
	waitgpu
	movem.l	(sp)+,d0-d1/a0-a2
	rts

