;*---------------------------------------------------------------------------
;  :Program.	turrican.asm
;  :Contents.	Slave for "Turrican"
;		supports orginal "Rainbow Arts", "Innerprise" and
;		"AmigaFun" rerelease
;  :Author.	Wepl
;  :Version.	$Id: turrican.asm 1.2 1998/06/27 23:50:34 jah Exp jah $
;  :History.	31.03.97 initial
;		22.04.97 new 60000 and bb -> changes
;		28.04.97 copper preserved (install-waitpic)
;		05.05.97 rework files instead image, lots more
;		13.05.97 file "30" forgotten, delay on intro voice added
;		24.05.97 highscore saving fixed
;		25.05.97 cache enabled
;			 to version 4 evaluated (kinit removed)
;		27.05.97 blitter patches
;		24.06.97 keyboard routine fixed
;		22.07.97 copylock level 1,2,4,5 removed
;		24.07.97 voice wait improved
;			 blitter waits reworked and completed
;		29.07.97 random generator replaced because Access Fault's
;		31.07.97 support for second version started
;		01.08.97 extro fixed
;		09.08.97 keyboard stuff in install changed
;			 support for innerprise version completed
;			 blitwaits on endboss added
;		15.08.97 sp changed for install because crash with v2
;		17.08.97 basememsize for install increased from 7f000 -> 82000
;		20.08.97 level4 protection adapted for innerprise version
;		30.08.97 keyboard external
;		15.09.97 support for "AmigaFun" rerelease
;		27.06.98 cleanup for source code release
;  :Requires.	-
;  :Copyright.	Public Domain
;  :Language.	68000 Assembler
;  :Translator.	Barfly V1.131
;  :To Do.
;---------------------------------------------------------------------------*

;install		;if this label is set the install Slave will be created

	INCDIR	Includes:
	INCLUDE	whdload.i

	IFD	BARFLY
	IFND install
	OUTPUT	wart:turrican/turrican.slave
	ELSE
	OUTPUT	wart:turrican/install.slave
	ENDC
	BOPT	O+ OG+				;enable optimizing
	BOPT	ODd- ODe-			;disable mul optimizing
	BOPT	w4-				;disable 64k warnings
	SUPER					;disable supervisor warnings
	ENDC

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

.base		SLAVE_HEADER		;ws_Security + ws_ID
		dc.w	4		;ws_Version
		dc.w	WHDLF_NoError	;ws_Flags
		dc.l	$82000		;ws_BaseMemSize
		dc.l	$100		;ws_ExecInstall
		dc.w	_Start-.base	;ws_GameLoader
		dc.w	_dir-.base	;ws_CurrentDir
		dc.w	0		;ws_DontCache
_keydebug	dc.b	0		;ws_keydebug
	IFD install
_keyexit	dc.b	$45		;ws_keyexit = ESC
	ELSE
_keyexit	dc.b	$59		;ws_keyexit = F10
	ENDC
_dir		dc.b	"data",0

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

	IFD	BARFLY
	IFND	install
		dc.b	"$VER: Turrican.Slave by Wepl "
	ELSE
		dc.b	"$VER: Turrican Install.Slave by Wepl "
	ENDC
	DOSCMD	"WDate >T:date"
	INCBIN	"T:date"
		dc.b	0
	ENDC
	EVEN

;======================================================================
_Start	;	A0 = resident loader
;======================================================================

		lea	(_resload,pc),a1
		move.l	a0,(a1)
		
;======================================================================

	IFD install
		
;======================================================================

	;install keyboard quitter
		bsr	_SetupKeyboard

	;magic screen
		lea	_disk1,a0
		lea	$50000,a1
		bsr	_Picture
			waitbutton
		lea	_wait,a0
		lea	$50000,a1
		bsr	_Picture

	;load the loader
		MOVE.L	#$00060000,a0		;adr
		MOVE.L	#$00017e00,d1		;size
		MOVE.L	#$00000400,d0		;offset
		sub.l	a1,a1			;taglist
		movem.l	d1/a0,-(a7)
		move.l	(_resload),a3
		jsr	(resload_DiskLoadDev,a3)
	;save the loader
		movem.l	(a7),d0/a1
		lea	(_60000),a0
		jsr	(resload_SaveFile,a3)
	;	jsr	(resload_LoadFile,a3)
	;check version
		movem.l	(a7)+,d0/a0
		jsr	(resload_CRC16,a3)
		cmp.w	#$5346,d0
		beq	_version_1
		cmp.w	#$59fe,d0
		beq	_version_2
		bra	_badver
		
_version_1	skip	$17a-$16e,$6016e	;preserve copperlist
		JSR	$0006010C.L		;A6 = _custom !!!
		move.w	#INTF_SETCLR|INTF_INTEN|INTF_PORTS,(intena,a6)

	;load all files from disk and save them
						;A6 = $dff000
		lea	(.files),a4		;A4 file table
		move.l	#$1000,a5		;A5 address

.loop		movem.l	(a4),d0/d1		;starttrack + size
		move.l	a5,d2			;address
		movem.l	d5-d7/a4-a5,-(a7)
		jsr	$6057a			;loader
		movem.l	(a7)+,d5-d7/a4-a5
		
		movem.l	(a4)+,d0/d2
		bsr	_LongToStr		;a0 = name
		move.l	d2,d0			;size
		move.l	a5,a1			;address
		move.l	(_resload),a2
		jsr	(resload_SaveFile,a2)
		
		tst.l	(a4)
		bne	.loop

	;load and save the highscores
		movem.l	(.files),d0/d1		;starttrack + size
		move.l	#$40000,d2		;address
		jsr	$6057a			;loader
		lea	$40000,a0		;start
		move.l	a0,a1
		add.l	(.files+4),a1		;end
		lea	$100,a2			;dest
		jsr	$6078c			;PP decrunch
		jsr	$100+$8d0		;load highs
		bsr	_savehighs

	;quit this magic stuff
		bra	_exit

	;table of files
.files		dc.l	$12,$d4e4		;main exe
		dc.l	$1c,$11964
		dc.l	$28,$c474
		dc.l	$30,$1478
		DC.L	$31,$20BC8
		DC.L	$46,$22FA8
		DC.L	$5C,$1EBC0
		DC.L	$70,$2642C
		DC.L	$89,$20914
	;	DC.L	$9E			;end ?
		dc.l	0

_version_2	skip	$15e-$152,$60152	;preserve copperlist
		JSR	$000600f0		;A6 = _custom !!!
		move.w	#INTF_SETCLR|INTF_INTEN|INTF_PORTS,(intena,a6)

	;load all files from disk and save them
						;A6 = $dff000
		lea	(.files),a4		;A4 file table
		move.l	#$1000,a5		;A5 address

.loop		movem.l	(a4),d0/d1		;starttrack + size
		move.l	a5,d2			;address
		movem.l	d5-d7/a4-a5,-(a7)
		jsr	$6057a-$1c		;loader
		movem.l	(a7)+,d5-d7/a4-a5
		
		movem.l	(a4)+,d0/d2
		bsr	_LongToStr		;a0 = name
		move.l	d2,d0			;size
		move.l	a5,a1			;address
		move.l	(_resload),a2
		jsr	(resload_SaveFile,a2)
		
		tst.l	(a4)
		bne	.loop

	;load and save the highscores
		movem.l	(.files),d0/d1		;starttrack + size
		move.l	#$40000,d2		;address
		jsr	$6057a-$1c		;loader
		lea	$40000,a0		;start
		move.l	a0,a1
		add.l	(.files+4),a1		;end
		lea	$100,a2			;dest
		jsr	$6078c-$1c		;PP decrunch
		jsr	$100+$8d0		;load highs
		bsr	_savehighs

	;quit this magic stuff
		bra	_exit

	;table of files
.files		dc.l	$12,$d500		;main exe
		dc.l	$1c,$11964
		dc.l	$28,$c4f4
		dc.l	$30,$1478		;loading tfmx
		DC.L	$31,$20BC8		;level 1
		DC.L	$46,$22FA8		;level 2
		DC.L	$5C,$1EBC0		;level 3
		DC.L	$70,$26168		;level 4
		DC.L	$88,$20914		;level 5
		dc.l	0
		
;--------------------------------

_disk1		INCBIN	pics/pic_disk1.bin
_wait		INCBIN	pics/pic_waitesc.bin
_colors		INCLUDE	pics/pic_colors.i
		
;======================================================================

	INCLUDE	Sources:whdload/keyboard.s
	INCLUDE	Sources:whdload/picture.s

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

	ELSE
	
;======================================================================

		move.l	(_resload),a3			;A3 = resload

	;random area
		lea	$80000,a7
		bsr	_rnd_init
		
	;check for AmigaFun Version
		lea	_60000,a0
		jsr	(resload_GetFileSize,a3)
		tst.l	d0
		bne	_v1_v2

	;bootblock stuff
		move.l	#$400,d0			;offset
		move.l	#$18000,d1			;size
		moveq	#1,d2				;disk
		lea	$5fe00,a0			;data
		lea	($200,a0),a2			;A2 = 60000
		jsr	(resload_DiskLoad,a3)

		patch	$4fa(a2),_load_v3		;with cache
		patch	$57a(a2),_load_v3		;plain
		patch	$104(a2),_100_v3
	;the intro runs on 68030 but not on 68060 (bad compressor)
		skip	6,$36(a2)			;rainbow arts intro
		jmp	($8,a2)

_100_v3		lea	$603ae,a2			;orginal
		movem.l	d0-d1/a0-a1,-(a7)
		lea	$100,a0
		patch	$61c(a0),_load_v3		;with cache
		patch	$696(a0),_load_v3		;plain
		patch	$8d0(a0),_loadhighs
		patch	$95a(a0),_savehighs
		patchs	$3d0(a0),_p_v3

		move.l	a0,a1
		add.l	#112256,a1			;main size
		bsr	_fb				;fix bliter waits

		movem.l	(a7)+,d0-d1/a0-a1
		jmp	$100

_p_v3		jsr	(a0)
		move.l	a0,a2
		bsr	_out
		movem.l	(4,a7),d0-a6
		move.l	(a7)+,a0
		add.w	#15*4,a7
		jmp	(a0)

;--------------------------------
; d0 = starttrack
; d1 = size in bytes
; d2 = dest. address

_load_v3	mulu	#$1600,d0		;offset
		move.l	d2,a0			;data
		moveq	#1,d2			;disk
		move.l	(_resload),a2
		jsr	(resload_DiskLoad,a2)
		rts

;--------------------------------

	;enable caches
_v1_v2		move.l	#CACRF_EnableI,d0
		move.l	d0,d1
		jsr	(resload_SetCACR,a3)

	;bootblock stuff
		lea	_60000,a0
		lea	$60000,a1
		move.l	a1,a2
		jsr	(resload_LoadFileDecrunch,a3)
		move.l	d0,d7			;d7 = size IMPORTANT !!

	;check version
		move.l	a2,a0
		jsr	(resload_CRC16,a3)
		cmp.w	#$5346,d0
		beq	_version_1
		cmp.w	#$59fe,d0
		beq	_version_2
		bra	_badver
		
_version_1	patch	$4fa(a2),_load		;with cache
		patch	$57a(a2),_load		;plain
		patchs	$70(a2),_70
		patchs	$b6(a2),_b6		;to wait some time
		patch	$104(a2),_100_v1
		jmp	($8,a2)

_version_2	patch	$4de(a2),_load		;with cache
		patch	$55e(a2),_load		;plain
		patchs	$54(a2),_70
		patchs	$9a(a2),_9a		;to wait some time
		patch	$e8(a2),_100_v2
		jmp	($8,a2)

	;get event
_70		movem.l	d0/a0,-(a7)
		lea	(_ec),a0
		bsr	_getec
		move.l	d0,(a0)
		movem.l	(a7)+,d0/a0
		move.w	#$30,($9a,a6)		;orginal
		rts

_ec		dc.l	0

_b6		move.l	d0,-(a7)
.wait		bsr	_getec			;wait for end of logo
		sub.l	#170,d0
		cmp.l	(_ec),d0
		blo	.wait
		move.l	(a7)+,d0
		move.l	#$602d0,$6c		;orginal
		addq.l	#2,(a7)
		rts

_9a		move.l	d0,-(a7)
.wait		bsr	_getec			;wait for end of logo
		sub.l	#170,d0
		cmp.l	(_ec),d0
		blo	.wait
		move.l	(a7)+,d0
		move.l	#$602b4,$6c		;orginal
		addq.l	#2,(a7)
		rts

	;get event counter ciaa
_getec		moveq	#0,d0
		move.b	_ciaa+ciatodhi,d0
		lsl.w	#8,d0
		move.b	_ciaa+ciatodmid,d0
		lsl.l	#8,d0
		move.b	_ciaa+ciatodlow,d0
		rts

_100_v1		lea	$603ae,a2		;orginal
		bra	_100_v1_v2

_100_v2		lea	$60392,a2		;original

_100_v1_v2	movem.l	d0-d1/a0-a1,-(a7)

		lea	$100,a0
		patch	$61c(a0),_load		;with cache
		patch	$696(a0),_load		;plain
		patch	$8d0(a0),_loadhighs
		patch	$95a(a0),_savehighs
		patchs	$af4(a0),_pp20
	;	patchs	$6fe8(a0),_train
	;	patch	$6f74(a0),_kb

		move.l	a0,a1
		add.l	#112256,a1		;main size
		bsr	_fb			;fix bliter waits

		movem.l	(a7)+,d0-d1/a0-a1
		jmp	$100

;--------------------------------
;  15d=ff level skip
; 7ac9	  energy
; 7aaf    continues

	IFEQ 1
_train		lea	$7118,a0		;original
		moveq	#2,d2			;original
		cmp.b	#$5f,d0
		bne	.ret
		st	$15d
.ret		rts
	ENDC
	IFEQ 1
_kb		bsr	_kinit
		clr.b	$7128		;orginal
		clr.b	$216		;orginal
		rts			;orginal
	ENDC

;--------------------------------

_pp20		subq.l	#4,a7
		pea	(_out)
		move.l	(8,a7),(4,a7)
		move.l	(a7)+,(4,a7)
		cmp.l	#"PP20",(a0)
		rts

	;after unpacking
_out		cmp.l	#$00021c80,(a2)
		beq	.level1
		cmp.l	#$00020080,(a2)
		beq	.level2
		cmp.l	#$00023ee0,(a2)
		beq	.level3
		cmp.l	#$000219a0,(a2)
		beq	.level4
		cmp.l	#$00022000,(a2)
		beq	.level5
		cmp.l	#$6000000a,(a2)
		beq	.file28
		rts

	;fix no exit after Level 1-3
.level1		move.w	#$4e71,$1902(a2)	;copylock
		bra	.fb
	;fix deadlock on level 2
.level2		move.w	#$4e75,$f08(a2)
		bra	.fb
.level4		cmp.w	#$6708,$3a58(a2)
		bne	.fb
		move.b	#$60,$3a58(a2)		;beq -> bra  v1 (rainbow arts)
		move.b	#$60,$4722(a2)		;beq -> bra  v1 (rainbow arts)
		bra	.fb
.level5		move.b	#$60,$37e2(a2)		;beq -> bra
		move.b	#$60,$3a54(a2)		;beq -> bra ('FUCK YOU')
		move.b	#$60,$471e(a2)		;beq -> bra ('FUCK YOU')
		patchs	$3468(a2),.4_a0		;blitter
		patchs	$43e4(a2),.6_a0		;blitter
.level3
.fb		movem.l	d0-d1/a0-a1,-(a7)
		move.l	a2,a0			;A0 = start
		move.l	a2,a1
		add.l	#259840,a1		;A1 = end (level size)
		bsr	_fb
		movem.l	(a7)+,d0-d1/a0-a1
		tst.l	d0			;restore flags
		rts

.file28		movem.l	d0-d1/a0-a1,-(a7)
		move.l	a2,a0			;A0 = start
		move.l	a2,a1
		add.l	#50292,a1		;A1 = end (level size)
		bsr	_fb
		movem.l	(a7)+,d0-d1/a0-a1
		tst.l	d0			;restore flags
		rts

	;special blit stuff
.4_a0		move.w	(4,a0),($58,a6)
		bra	.wait
.6_a0		move.w	(6,a0),($58,a6)
.wait		BLITWAIT a6
		rts

	;fix area for blitter and rnd
_fb		movem.l	a0-a2,-(a7)
		lea	($d0),a2		;patch routine
		bsr	_blitfix_imm_58a6
		movem.l	(a7),a0-a2
		lea	($10),a2		;patch routine
		bsr	_blitfix_dn_58a6
		movem.l	(a7)+,a0-a2
		bra	_fix_rnd

;PATCHCOUNT

;--------------------------------
; fix bad random generator:
; and a lot variations of this
;	2078 01dc		move.l	($1dc).w,a0
;	3010			move.w	(a0),dx
;	54b8 01dc		addq.l	#2,($1dc).w
;	b1fc 00ff ffde		cmpa.l	#$ffffde,a0
;	6d08			blt.b	...
;	21fc 00fc 00d2 01dc	move.l	#$fc00d2,($1dc).w

RND_START = $80000
RND_STOP  = $82000

_rnd_init	lea	(RND_START),a0
		lea	(RND_STOP),a1
.fill		bsr	_Random
		move.w	d0,(a0)+
		cmp.l	a0,a1
		bne	.fill
		rts

_fix_rnd	move.l	#RND_START+$d2,($1dc)
.loop		cmp.l	#$21fc00fc,(a0)
		bne	.next
		cmp.l	#$00d201dc,(4,a0)
		bne	.next

		move.l	#RND_START+$d2,(2,a0)
		move.l	#RND_STOP-$22,(-6,a0)

.next		addq.l	#2,a0
		cmp.l	a0,a1
		bhs	.loop
		rts

	IFEQ 1
.loop		cmp.l	#$207801dc,(a0)
		bne	.next
		cmp.w	#$54b8,(6,a0)
		bne	.next
		cmp.l	#$01dcb1fc,(8,a0)
		bne	.next

		move.w	(4,a0),d0		;d0 = MOVE.W (A0),Dx
		and.w	#%0000111000000000,d0
		beq	.1
		or.w	#%1100000101000000,d0	;EXG Dx,D0
		move.w	d0,(a0)+
.1		move.w	#$4eb9,(a0)+		;JSR $xxxxxxxx.l
		pea	_Random
		move.l	(a7)+,(a0)+
		tst.w	d0
		beq	.2
		move.w	d0,(a0)+
.2		move.w	#$60<<8+18,(a0)+	;BRA.B
		tst.w	d0
		beq	.next
		subq.w	#4,(-2,a0)		;correct because 2x EXG

.next		addq.l	#2,a0
		cmp.l	a0,a1
		bhs	.loop
		rts
	ENDC

;--------------------------------
; random function
; IN:	-
; OUT:	D0 = UWORD random value

_Random		move.l	a0,-(a7)
		lea	(.rand),a0
		move.w	(vhposr+_custom),d0
		add.w	(a0),d0
		ror.w	#1,d0
		move.w	d0,(a0)
		move.l	(a7)+,a0
		rts

.rand		dc.w	$3f2b

;--------------------------------
; d0 = starttrack
; d1 = size in bytes
; d2 = dest. address
; $1978 = 6520 bytes per track

_load		movem.l	d0-d1/a0-a2,-(a7)
		bsr	_LongToStr
		move.l	d2,a1
		move.l	(_resload),a2
		jsr	(resload_LoadFileDecrunch,a2)
		movem.l	(a7)+,d0-d1/a0-a2
		rts

;--------------------------------

_loadhighs	movem.l	d0-d1/a0-a2,-(a7)
		move.l	(_resload),a2		;A2 = resload
		lea	_highsname,a0
		jsr	(resload_GetFileSize,a2)
		tst.l	d0
		beq	.end
		lea	_highsname,a0
		lea	$2d6,a1
		jsr	(resload_LoadFileDecrunch,a2)
		bsr	_crypt
.end		movem.l	(a7)+,d0-d1/a0-a2
		rts

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

	INCLUDE	Sources:whdload/blitfix_dn_58a6.s
	INCLUDE	Sources:whdload/blitfix_imm_58a6.s

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

	ENDC
	
;======================================================================

_savehighs	movem.l	d0-d2/a0-a3,-(a7)
		lea	_custom,a3
		move.w	(dmaconr,a3),d2
		move.w	#$7fff,(dmacon,a3)
		bsr	_crypt
		move.l	#$61*4,d0
		lea	_highsname,a0
		lea	$2d6,a1
		move.l	(_resload),a2
		jsr	(resload_SaveFile,a2)
		bsr	_crypt
		or.w	#$8000,d2
		move.w	d2,(dmacon,a3)
		movem.l	(a7)+,d0-d2/a0-a3
		rts

;----------------------------------------

_crypt		move	sr,d1
		or	#$700,sr
		lea	$2d6,a0
		move.w	#$61*4-1,d0
.lp		eor.b	d0,(a0)+
		dbf	d0,.lp
		move	d1,sr
		rts

;----------------------------------------
; IN:	D0 = LONG value
; OUT:	A0 = CPTR string

_LongToStr	lea	(.str),a0
		ror.l	#4,d0
		move.b	.list(PC,d0.w),(a0)+
		clr.w	d0
		rol.l	#4,d0
		move.b	.list(PC,d0.w),(a0)
		subq.w	#1,a0
		rts
		
.list		dc.b	"0123456789abcdef"
.str		ds.b	4
	
;--------------------------------

_60000		dc.b	"60000",0
_highsname	dc.b	"highs",0
_resload	dc.l	0			;address of resident loader

;--------------------------------

_badver		subq.l	#8,a7
		pea	TDREASON_WRONGVER
		bra	_end
_exit		pea	TDREASON_OK
		bra	_exit
_debug		pea	TDREASON_DEBUG
_end		move.w	#DMAF_DISK,(_custom+dmacon)	;for install
		move.l	(_resload),-(a7)
		addq.l	#resload_Abort,(a7)
		rts

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

	END

