;************************

	version = 9

;************************

; all my own utilities for storing data in the eeprom, and decoding etc

downeep::
	movem.l	a0/d0-d2,-(sp)
	movea.l	#eeprom_data,a0
	moveq	#63,d2		; counter
	moveq	#0,d1

.lp:	bsr	eeread
	move.w	d0,(a0)+
	addq.l	#1,d1
	dbra	d2,.lp

	bsr	checkvalid

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

sendeep::
	movem.l	a0/d0-d2,-(sp)

	bsr	makevalid

	movea.l	#eeprom_data,a0
	moveq	#63,d2		; counter
	moveq	#0,d1
.lp:	move.w	(a0)+,d0
	bsr	eewrite
	addq.l	#1,d1
	dbra	d2,.lp

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

checkvalid:			; make sure a Checkered Flag cart
	movea.l	#eeprom_data,a0
	move.w	Mark_data,d0
	cmp.w	(a0),d0
	seq	valid_eeprom.w
	bne.b	cart_reset

	bsr	make_checksum	; returns in d2
	cmp.w	(a0),d2		; compare the last word with the checksum
	seq	valid_eeprom.w
	bne.b	cart_reset
	rts

makevalid:
	bsr	make_checksum
	move.w	d2,(a0)		; and write the last with the checksum
	rts

make_checksum:
	movem.l	d0/d1,-(sp)
	movea.l	#eeprom_data,a0
	moveq	#62,d0		; read all but last word
	moveq	#0,d2
.lp:	move.w	(a0)+,d1
	eor.w	d1,d2
	rol.w	d1,d2
	dbra	d0,.lp
	movem.l	(sp)+,d0/d1
	rts

cart_reset::
	movea.l	#eeprom_data,a0
	move.w	Mark_data,(a0)+
	bsr	init_default
	bsr	data_copy
cart_refill::				; this is where to enter if you want to just update whats already there
	bsr	update_configuration
	bsr	build_new		; this appends compressed names/times *10 onto the output
	bsr	sendeep
	rts

build_new:
	movem.l	d0/a1-a3,-(sp)

	movea.w	#Fame_names,a1
	movea.w	#Fame_times,a2
	moveq	#9,d0
.lp:	bsr	packname
	move.b	(a2)+,(a0)+		; note that this has to be two bytes because the outgoing data won't be aligned
	move.b	(a2)+,(a0)+
	dbra	d0,.lp	

	movea.w	#Tour_names,a1
	movea.w	#Tour_times,a2
	movea.w	#Tour_points,a3
	moveq	#4,d0
.lp2:	bsr.b	packname
	move.b	(a3)+,(a0)+
	addq.l	#1,a2			; skip one because the ram copy is in longs
	move.b	(a2)+,(a0)+		; note that this has to be in bytes because the outgoing data won't be aligned
	move.b	(a2)+,(a0)+
	move.b	(a2)+,(a0)+
	dbra	d0,.lp2	

	movem.l	(sp)+,d0/a1-a3
	rts

packname:			; packs name at a1 (8 chars) into 5 bytes at a0
	movem.l	d0-d2,-(sp)

	moveq	#0,d0
	moveq	#5,d2		; start with first six chars = 30 bits

.lp:	lsl.l	#5,d0
	moveq	#$1f,d1
	and.b	(a1)+,d1
	or.b	d1,d0
	dbra	d2,.lp

	lsl.l	#2,d0
	moveq	#$1f,d1
	and.b	(a1),d1		; read next byte for high bits
	lsr.b	#3,d1		; leave two bits only
	or.b	d1,d0

	move.w	d0,d1
	swap	d0
	move.w	d0,d2
	rol.w	#8,d0
	move.b	d0,(a0)+
	move.b	d2,(a0)+

	move.w	d1,d2
	rol.w	#8,d1
	move.b	d1,(a0)+
	move.b	d2,(a0)+

	moveq	#0,d0
	moveq	#$1f,d1
	and.b	(a1)+,d1	; read 2nd to last byte
	or.b	d1,d0
	lsl.l	#5,d0
	moveq	#$1f,d1
	and.b	(a1)+,d1	; read last byte
	or.b	d1,d0

	move.b	d0,(a0)+

	movem.l	(sp)+,d0-d2
	rts
	
data_copy:
	movem.l	a1-a2,-(sp)
	movea.w	#Fame_names,a1
	movea.l	#Name_data,a2
	moveq	#19,d0
.lp1:	move.l	(a2)+,(a1)+
	dbra	d0,.lp1

	move.w	$f14002,d0		; read joy2 which includes system type etc
	moveq	#5,d1
	btst	#4,d0
	beq.b	.pal
	moveq	#6,d1
.pal:

	movea.w	#Fame_times,a1
	movea.l	#Time_data,a2
	moveq	#9,d0
.lp2:	move.w	d1,d2
	mulu	(a2)+,d2
	add.w	d1,d2
	subq.w	#1,d2
	move.w	d2,(a1)+
	dbra	d0,.lp2

tour:	movea.w	#Tour_names,a1
	movea.l	#Name_tour,a2
	moveq	#9,d0
.lp1:	move.l	(a2)+,(a1)+
	dbra	d0,.lp1

	movea.w	#Tour_times,a1
	movea.l	#Time_tour,a2
	moveq	#4,d0
.lp2:	move.w	d1,d2
	mulu	(a2)+,d2
	add.l	d1,d2
	subq.l	#1,d2
	move.l	d2,(a1)+
	dbra	d0,.lp2

	movea.w	#Tour_points,a1
	movea.l	#Point_tour,a2
	moveq	#4,d0
.lp3:	move.b	(a2)+,(a1)+
	dbra	d0,.lp3

	movem.l	(sp)+,a1-a2
	rts

read_fame::
	movem.l	d0-d3/a1-a3,-(sp)	; expand names from a0 to the bss segment

	movea.w	#Fame_names,a1
	movea.w	#Fame_times,a2
	moveq	#$1f,d3			; mask for one character
	moveq	#9,d0
.lp:	bsr.b	unpack_name
	move.b	(a0)+,(a2)+
	move.b	(a0)+,(a2)+
	dbra	d0,.lp

	movea.w	#Tour_names,a1
	movea.w	#Tour_times,a2
	movea.w	#Tour_points,a3
	moveq	#$1f,d3			; mask for one character
	moveq	#4,d0
.lp2:	bsr.b	unpack_name
	move.b	(a0)+,(a3)+
	clr.b	(a2)+			; skip
	move.b	(a0)+,(a2)+
	move.b	(a0)+,(a2)+
	move.b	(a0)+,(a2)+
	dbra	d0,.lp2


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

unpack_name:
	movem.l	d1/d2,-(sp)
	move.b	(a0)+,d2
	move.b	d2,d1		; 00000000xxxxxyyy
	lsr.b	#3,d1
;	add.b	d4,d1
	move.b	d1,(a1)+

	asl.w	#8,d2
	move.b	(a0)+,d2
	move.w	d2,d1		; xxxxxyyyyyzzzzza
	lsr.w	#6,d1
	and.w	d3,d1
;	add.b	d4,d1
	move.b	d1,(a1)+

	move.b	d2,d1		; --------yyzzzzza
	lsr.w	#1,d1
	and.w	d3,d1
;	add.b	d4,d1
	move.b	d1,(a1)+

	asl.w	#8,d2
	move.b	(a0)+,d2
	move.w	d2,d1		; yyzzzzzaaaaabbbb
	lsr.w	#4,d1
	and.w	d3,d1
;	add.b	d4,d1
	move.b	d1,(a1)+

	asl.w	#8,d2
	move.b	(a0)+,d2
	move.w	d2,d1		; aaaabbbbbcccccdd
	lsr.w	#7,d1
	and.w	d3,d1
;	add.b	d4,d1
	move.b	d1,(a1)+
	
	move.b	d2,d1		; --------bcccccdd
	lsr.w	#2,d1
	and.w	d3,d1
;	add.b	d4,d1
	move.b	d1,(a1)+

	asl.w	#8,d2
	move.b	(a0)+,d2
	move.w	d2,d1		; bcccccdddddeeeee
	lsr.w	#5,d1
	and.w	d3,d1
;	add.b	d4,d1
	move.b	d1,(a1)+

	and.w	d3,d2
;	add.b	d4,d2
	move.b	d2,(a1)+

	movem.l	(sp)+,d1/d2
	rts



key_configuration::		; reads key config and decodes into three different buttons

	movem.l	d0/a0,-(sp)
	moveq	#0,d0
	move.b	key_config.w,d0
	muls	#3,d0
	lea	key_contable-*-2(PC,d0),a0	; point at table and add offset all in one go !!

	move.b	(a0)+,key_accel.w
	move.b	(a0)+,key_brake.w
	move.b	(a0),key_cruis.w
	movem.l	(sp)+,d0/a0
	rts

key_contable:
	dc.b	FIRE_A,FIRE_B,FIRE_C
	dc.b	FIRE_A,FIRE_C,FIRE_B
	dc.b	FIRE_B,FIRE_A,FIRE_C
	dc.b	FIRE_B,FIRE_C,FIRE_A
	dc.b	FIRE_C,FIRE_A,FIRE_B
	dc.b	FIRE_C,FIRE_B,FIRE_A

update_configuration::		; to encode and re-write eeprom after changes and decode key config coding
	movem.l	d0-d2,-(sp)
	moveq	#0,d1
	bsr	key_configuration
	movea.l	#eeprom_data,a0
	move.w	Mark_data,(a0)+

	moveq	#0,d0
	move.b	car_colour.w,d0

	asl.w	#1,d0
	or.b	gear_type.w,d0

	asl.w	#4,d0
	or.b	track_no.w,d0

	asl.w	#3,d0
	or.b	key_config.w,d0

	asl.w	#2,d0
	or.b	map_spin.w,d0

	asl.w	#1,d0
	or.b	tach_set.w,d0

	move.w	(a0),d2
	eor.w	d2,d1
	eor.w	d0,d1
	move.w	d0,(a0)+

	move.b	qty_laps.w,d0
	move.b	(a0),d2
	eor.b	d2,d1
	eor.b	d0,d1
	move.b	d0,(a0)+

	move.w	music_volume.w,d0
	move.b	(a0),d2
	eor.b	d2,d1
	eor.b	d0,d1
	move.b	d0,(a0)+

	move.w	effects_volume.w,d0
	move.b	(a0),d2
	eor.b	d2,d1
	eor.b	d0,d1
	move.b	d0,(a0)+

	tst.l	d1
	sne	eeprom_change.w
	movem.l	(sp)+,d0-d2
	rts

read_configuration::
	movea.l	#eeprom_data+2,a0	; marker ignored, already tested when read eeprom
	moveq	#0,d0
	move.w	(a0)+,d0
	swap	d0			; placing bits in upper word as follows : 00cccgttttkkkmmt

	rol.l	#5,d0
	cmp.b	#5,d0			; check for valid colour number
	sgt	eeprom_error.w	
	move.b	d0,car_colour.w
	clr.b	d0

	rol.l	#1,d0
	move.b	d0,gear_type.w
	clr.b	d0

	rol.l	#4,d0
	cmp.b	#10,d0
	ble.b	.ok1
	st	eeprom_error.w
.ok1:	move.b	d0,track_no.w
	clr.b	d0

	rol.l	#3,d0
	cmp.b	#5,d0
	ble.b	.ok2
	st	eeprom_error.w
.ok2:	move.b	d0,key_config.w
	clr.b	d0

	rol.l	#2,d0
	cmp.b	#3,d0
	bne.b	.ok3
	st	eeprom_error.w
.ok3:	move.b	d0,map_spin.w
	clr.b	d0

	rol.l	#1,d0
	move.b	d0,tach_set.w

	move.b	(a0)+,qty_laps.w

	moveq	#0,d0
	move.b	(a0)+,d0
	move.w	d0,music_volume.w
	bsr	do_real_volume		; put the volume in place in the DSP

	move.b	(a0)+,d0
	move.w	d0,effects_volume.w

	tst.b	eeprom_error.w	;passes results of test back
	rts

Mark_data:
	dc.w	$CF00+version		; basic marker - non compressed - version code included to ensure continuity

Name_data:
	dc.b	'ROBERT@@'
	dc.b	'JUSTIN@@'
	dc.b	'JASON@@@'
	dc.b	'CHRIS@@@'
	dc.b	'STUART@@'
	dc.b	'TOBY@@@@'
	dc.b	'DAN@@@@@'
	dc.b	'NEAL@@@@'
	dc.b	'ALEX@@@@'
	dc.b	'JAMIE@@@'

Time_data:
	dc.w	330+version
	dc.w	280
	dc.w	336
	dc.w	305
	dc.w	287
	dc.w	365
	dc.w	264
	dc.w	310
	dc.w	282
	dc.w	328

Name_tour:
	dc.b	'PERFECT@'
	dc.b	'EXPERT@@'
	dc.b	'DRIVER@@'
	dc.b	'NOVICE@@'
	dc.b	'TRAINEE@'

Time_tour:
	dc.w	40800
	dc.w	43800
	dc.w	46800
	dc.w	49800
	dc.w	52800

Point_tour:
	dc.b	60
	dc.b	55
	dc.b	50
	dc.b	45
	dc.b	40

.even

; result data retained will be 10 set of 7 bytes allocated as follows :
; 5 bytes = 8 chars compressed text for the name
; 2 bytes = time in frames to complete race [limited to 18 minutes, may need to change lap limit !]

; that leaves 58 bytes of which we need :
; 4 bytes for configuration : 
;	5 bits music volume
;	5 bits fx volume
;	3 bits car colour [favourite]
;	1 bit gear type
;	3 bits drones qty
;	3 bits key configuration
;	4 bits track number [favourite]	
;	1 byte laps qty
; 2 bytes for identification

; the remaining 51 will hold tournament records - top 5
; 
; tournament data : name (8 compressed into 5 bytes)
;		  : points - 1 byte
;		  : time - 3 bytes (allowing up to 38 hrs, 50 min, 10 sec)
; the time has to be more than 1 word due to the immense time it could take to win a tournament
; total 45 bytes for 5 records leaving just enough for any late extra info. (6 bytes)

; more detailed info :

; car colour 0-5
; weather    0-3 not saved
; foil type  0-1 not saved - weather dependent
; tyre type  0-1 not saved - ditto
; gear type  0-1
; drone qty  1-5 
; race type  0-2 not saved - likely to want practice each time
; lap count  1-99 not saved
; track no.  0-9
; key config 0-5
; map type   0-2
; tacho sw   0-1

; total 6*2*6*10*3*2= 4320 = $10e0
; or 3+1+4+3+2+1 bits = 14 bits 

