; TITANIC CRUNCHER
	opt	c-
I_setclr=$8000
I_inten=$4000
I_ciab=$2000
I_aud=$3c0
I_Blit=$40
I_Vbl=$20
I_Cop=$10
I_Kb=8
I_Soft=4
I_Disk=2

D_setclr=$8000
D_init=$200
D_priB=$400
D_Btpl=$100
D_Copp=$80
D_Blit=$40
D_sprt=$20
D_disk=$10

I_SET=I_setclr!I_inten
D_CON=D_setclr!D_init!D_copp!D_Btpl!D_Blit

	section	titanic,code

start:
	bra	start2

	dc.l $ABCD		; magic
file:	ds.l 4

DosName	dc.b 'dos.library',0

ptBufLoad	
	dc.l 0
ptNextBufLoad
	dc.l 0
wbport	dc.l 0

hunktab	dc.l $10374

TitanicsMessage:
	dc.b 'TEAM17 present FULL CONTACT. loading ...',0
	ds.b	3

MsgPort	dc.l 0
; ---------------------------------------------------------------------------

start2:
	movem.l	d0-a3/a5-a6,-(sp)	; save all registers but A4 (jump program)

	suba.l	a1,a1		; own task
	movea.l	4.w,a6
	jsr	-$126(a6)	; FindTask(name) (a1)
	movea.l	d0,a4
	tst.l	$AC(a4)		; pr_cli
	bne.s	DosCLI
	lea	$5C(a4),a0
	lea	wbport(pc),a1
WB:
	move.l	a0,(a1)
	movea.l	4.w,a6
	jsr	-$180(a6)	; WaitPort(port) (a0)
	jsr	-$174(a6)	; GetMsg(port) (a0)
	lea	MsgPort(pc),a1
	move.l	d0,(a1)

DosCLI:
	lea	DosName(pc),a1	; "dos.library"
	moveq	#0,d0
	movea.l	4.w,a6
	jsr	-$228(a6)	; OpenLib
	movea.l	d0,a5		; DosBase
	bne.s	okDOSLIB	; OutPut()
	movem.l	(sp)+,d0-a3/a5-a6
	moveq	#0,d0
	rts	
; --------------------------------- MESSAGE

okDOSLIB:
;	jsr	-$3C(a5)	; OutPut()
;	move.l	d0,d1
;	beq.s	noOutputCli
;	lea	TitanicsMessage(pc),a0 ; "TITANICS-Cruncher	decrunches while load"...
;	move.l	a0,d2
;	tst.b	(a0)
;	beq.s	noOutputCli
;.lenmess
;	tst.b	(a0)+
;	bne.s	.lenmess
;	move.b	#$A,-1(a0)
;	move.l	a0,d3
;	sub.l	d2,d3
;	jsr	-$30(a5)	; Write(file,buffer,len) (d1,d2,d3)

noOutputCli:
	bsr	BootInit
;-------------------------------- START READ/DEPACK DATAS
Load	move.l	file(pc),d1
	moveq	#0,d2
	move.l	hunktab(pc),d2	; position
	moveq	#-1,d3		; offset : end
	jsr	-$42(a5)	; Seek(file,position,offset) (d1,d2,d3)
; 
	move.l	#$1400,d0	; bytesize of BUFLOAD read/unpack
	moveq	#0,d1
	jsr	-$C6(a6)	; AllocMem(bytesize,req) (d0,d1)
; 
	lea	start(pc),a4	; Prog Base
	move.l	d0,ptBufLoad-start(a4)
	bne.s	continue
	movea.l	a5,a1
	jsr	-$19E(a6)	; no BufLoad : Close Dos Lib
	movem.l	(sp)+,d0-a3/a5-a6
	moveq	#0,d0
	rts	
; 
continue:
	addi.l	#$1400,d0
	move.l	d0,ptNextBufLoad-start(a4)

	bsr	DosRead

	move.l	(a0)+,d7
	move.l	d7,d6
	movea.l	$FFFFFFFC,a1
	adda.l	a1,a1
	adda.l	a1,a1
	move.l	a1,-(sp)

_loop0:
	move.l	(a0)+,d0
	cmpa.l	ptNextBufLoad(pc),a0
	bne.s	ok
	bsr	DosRead

ok:
	move.l	d0,d1
	andi.l	#$FFFFFF,d0
	addq.l	#8,d0
	move.l	d0,d5
	rol.l	#8,d1
	andi.l	#7,d1
	addi.l	#$10000,d1
	movem.l	d5-a1,-(sp)
	jsr	-$C6(a6)
	movem.l	(sp)+,d5-a1
	tst.l	d0
	beq	EXITNOMEM

	addq.l	#4,d0
	move.l	d0,d1
	lsr.l	#2,d0
	move.l	d0,(a1)
	movea.l	d1,a1
	move.l	d5,-4(a1)
	dbf	d6,_loop0
	clr.l	(a1)
	movea.l	(sp)+,a4

LOOP:
	movea.l	(a4),a4
	adda.l	a4,a4
	adda.l	a4,a4
	move.l	(a0)+,d0
	cmpa.l	ptNextBufLoad(pc),a0
	bne.s	noread
	bsr	DosRead

noread:
	tst.l	d0
	bne.s	dpack
	dbf	d7,LOOP
	bra.s	EndRead
; 

dpack:
	lea	4(a4),a1
	move.l	-8(a1),d0
	subq.l	#8,d0
	tst.l	d0
	beq.s	unpacked
	bsr	Depack

unpacked:
	move.l	(a0)+,d0
	cmpa.l	ptNextBufLoad(pc),a0
	bne.s	_skipread0
	bsr	DosRead

_skipread0:
	tst.l	d0
	beq.s	_next
	movea.l	$FFFFFFFC,a3
	adda.l	a3,a3
	adda.l	a3,a3
	move.l	(a0)+,d1
	cmpa.l	ptNextBufLoad(pc),a0
	bne.s	_skipread1
	bsr	DosRead

_skipread1:
	movea.l	(a3),a3
	adda.l	a3,a3
	adda.l	a3,a3
	dbf	d1,_skipread1
	move.l	a3,d2
	addq.l	#4,d2

looptest:
	move.l	(a0)+,d1
	cmpa.l	ptNextBufLoad(pc),a0
	bne.s	_skipread
	bsr	DosRead

_skipread:
	add.l	d2,4(a4,d1.l)
	subq.l	#1,d0
	bne.s	looptest
	bra.s	unpacked
; 

_next:
	dbf	d7,LOOP
;-------------------------------------------------
EndRead:
	movea.l	ptBufLoad(pc),a1
	move.l	#$1400,d0
	jsr	-$D2(a6)	; FreeMem
	movea.l	a5,a1
	jsr	-$19E(a6)	; Close	DosLib
	movea.l	$FFFFFFFC,a0
	adda.l	a0,a0
	adda.l	a0,a0
	movea.l	(a0),a4		; get unpacked offset
	adda.l	a4,a4
	adda.l	a4,a4
	addq.l	#4,a4
	movea.l	wbport(pc),a0
	lea	$14(a0),a0	; memory list
	movea.l	MsgPort(pc),a1
	move.l	a1,d0
	beq.s	startprog
	movea.l	4.w,a6
	jsr	-$F0(a6)	; AddHead(list,node) (a0,a1)
;---------------------------------------------------
startprog:
.wait	andi.w	#$80,$dff01e		; interrupt channel 0 ?
	beq.s	.wait
;.wait	tst.w	flagend
;	bne.s	.wait

	move.l	#blanksnd,$dff0A0
	move.l	#blanksnd,$dff0B0
	move.w	#2,$dff0A4
	move.w	#2,$dff0B4

	move.w	#$3,$dff096		; start dma audio off
	move.w	#$180,$dff09a		; stop interrupt audio

	movea.l	pVBR(pc),a1
	move.l 	oldirq(pc),$70(a1)		;restore VB vector

	movem.l	(sp)+,d0-a3/a5-a6

	jsr	(a4)			; START UNPACKED PROGRAM
	
	bra	BootEnd
; 

EXITNOMEM:
	addq.l	#4,sp
	clr.l	(a1)
	movem.l	(sp)+,d0-a3/a5-a6
	rts

; --------------------------------------------------------------------------- READ PACKED DATA
DosRead:
	movem.l	d0-d7/a1-a6,-(sp)

	move.l	file(pc),d1
	move.l	ptBufLoad(pc),d2
	move.l	#$1400,d3
	jsr	-$2A(a5)	; read (file,buf,len) (d1,d2,d3)

	movem.l	(sp)+,d0-d7/a1-a6
	movea.l	ptBufLoad(pc),a0
	rts
; ----------------------------------------------------------------------------- DEPACKER
Depack:
		lea	(a1,d0.l),a2
		moveq	#0,d0

loc_0_260:
		lsl.l	#1,d0
		bne.s	loc_0_268
		bsr.w	pread

loc_0_268:
		bcs.s	loc_0_2A2
		lsl.l	#1,d0
		bne.s	loc_0_272
		bsr.w	pread

loc_0_272:
		bcs.s	loc_0_28C
		moveq	#2,d1
		bsr.s	sub_0_2E8
		move.w	d2,d3

loc_0_27A:
		moveq	#7,d1
		bsr.s	sub_0_2E8
		nop	
		move.b	d2,(a1)+
		dbf	d3,loc_0_27A
		cmpa.l	a1,a2
		bgt.s	loc_0_260
		rts	

loc_0_28C:
		moveq	#7,d1
		bsr.s	sub_0_2E8
		addq.w	#2,d2
		neg.w	d2
		move.b	(a1,d2.w),(a1)+
		move.b	(a1,d2.w),(a1)+
		cmpa.l	a1,a2
		bgt.s	loc_0_260
		rts	

loc_0_2A2:
		moveq	#1,d1
		bsr.s	sub_0_2E8
		cmp.w	#2,d2
		bgt.s	loc_0_2DE
		beq.s	loc_0_2CC
		moveq	#8,d1
		add.w	d2,d1
		moveq	#2,d3
		add.w	d2,d3
		bsr.s	sub_0_2E8
		add.w	d3,d2
		addq.w	#1,d2
		neg.w	d2

loc_0_2BE:
		move.b	(a1,d2.w),(a1)+
		dbf	d3,loc_0_2BE
		cmpa.l	a1,a2
		bgt.s	loc_0_260
		rts	

loc_0_2CC:
		moveq	#7,d1
		bsr.s	sub_0_2E8
		move.w	d2,d3
		addq.w	#2,d3
		moveq	#$B,d1
		bsr.s	sub_0_2E8
		addq.w	#3,d2
		neg.w	d2
		bra.s	loc_0_2BE

loc_0_2DE:
		moveq	#7,d1
		bsr.s	sub_0_2E8
		move.w	d2,d3
		addq.w	#8,d3
		bra.s	loc_0_27A

; 


sub_0_2E8:
		moveq	#0,d2

loc_0_2EA:
		lsl.l	#1,d0
		bne.s	loc_0_2F0
		bsr.s	pread

loc_0_2F0:
		roxl.w	#1,d2
		dbf	d1,loc_0_2EA
		rts	
; 

pread:
		move.l	(a0)+,d0
		cmpa.l	ptNextBufLoad(pc),a0
		bne.s	_noread
		bsr	DosRead

_noread:
		move	#$10,ccr
		roxl.l	#1,d0
		rts	
; end of 'CODE'

;****************************************************************
GetVBR:	;dc.w $4e7a,$c801	;hex for "movec VBR,a4"
	dc.l	$4e7a0801	; movec vbr,d0
	rte			;return from Supervisor mode

WaitEOF:				;wait for end of frame
	bsr.s WaitBlitter
	move.w #$138,d0
WaitRaster:				;Wait for scanline d0. Trashes d1.
.ln:	move.l 4(a6),d1
	lsr.l #1,d1
	lsr.w #7,d1
	cmp.w d0,d1
	bne.s .ln			;wait until it matches (eq)
	rts

AllOff:	move.w #$7fff,d2		;clear all bits
	move.w d2,$96(a6)		;in DMACON,
	move.w d2,$9a(a6)		;INTENA,
IntReqD2:
	move.w d2,$9c(a6)		;and INTREQ
	move.w d2,$9c(a6)		;twice for A4000 compatibility
	rts

WaitBlitter:				;wait until blitter is finished
	tst.w (a6)			;for compatibility with A1000
.loop:	btst #6,2(a6)
	bne.s .loop
	rts
;-------------------------------------------------------------------
BootInit:
	movem.l	d0-d7/a0-a6,-(sp)
    *** MiniWrapper by Photon ***
	move.l	4.w,a6			;Exec library base address in a6
	sub.l	d0,d0
	btst	#0,297(a6)		;68000 CPU?
	beq.s	.yes68k
	lea	GetVBR(PC),a5		;else fetch vector base address to a4:
	jsr	-30(a6)			;enter Supervisor mode

	move.l	d0,pVBR
    *--- save view+coppers ---*

.yes68k:	lea	GFXLIB(PC),a1		;either way return to here and open
	jsr	-408(a6)		;graphics library
	tst.l	d0			;if not OK,
	beq	Load			;exit program.
	move.l	d0,a5			;a5=gfxbase
	move.l	d0,gfxbase

	move.l	a5,a6
	move.l	34(a6),oldosscreen
	sub.l	a1,a1			;blank screen to trigger screen switch
	jsr	-222(a6)		;on Amigas with graphics cards

    *--- save int+dma ---*

	lea	$dff000,a6
	bsr	WaitEOF			;wait out the current frame
	move.w	$1c(a6),oldintena	;save intena+intreq
	move.w	$1e(a6),oldintreq
	BSET	#7,OLDINTENA
	BSET	#7,OLDINTREQ
	move.w	2(a6),d0		;and dma
	ori.w	#$8200,d0
	move.w	d0,olddma
	movea.l	pVBR(pc),a4
	move.l	$70(a4),oldirq		;and also the VB int vector for sport.
;	bsr.s	AllOff			;turn off all interrupts+DMA

;	ifd	AUDIOINT
	lea	interruptaud(pc),a0
	move.l	a0,$70(a4)
;	endc

	bset    #1,$BFE001		; Filter PassBass - Power Led OFF

	lea	CopperListBoot,a0
	move.l	a0,$80(a6)
	move.w	#0,$88(a6)
; pic
	move.l	#bootpic,d0	; 2 plans 40*48
	lea	CLbpl,a0
	moveq	#2-1,d1
	move.l	#40*48,d2
	bsr	Inst_plans

	move.l	#blanksnd,d0	; sprites off
	lea	CLspr,a0
	moveq	#8-1,d1
	move.l	#0,d2
	bsr	Inst_plans

	move.w	#$20,$96(a6)	; sprites off
	move.w	#D_CON,$96(a6)

;	move.w	#I_SET,$9a(a6)
;	move.w	#D_CON,$96(a6)
	move.w	#$c180,$9a(a6)		; start interrupt audio
; sound	channel 0
	move.l	#bootsnd,$A0(a6)	; address sound
	move.w	#61000/2,$A4(a6)	; len in word $7724=30500.w=61000 .b (ee48)
	move.w	#428,$A6(a6)		; period
	move.w	#64,$A8(a6)		; volume
 ; sound channel 1
	move.l	#bootsnd,$B0(a6)	;
	move.w	#61000/2,$B4(a6)
	move.w	#428,$B6(a6)
	move.w	#64,$B8(a6)
 
	move.w	#$8003,$96(a6)		; start dma audio on
	movem.l	(sp)+,d0-d7/a0-a6
	rts

BootEnd:
	movem.l	d0-d7/a0-a6,-(sp)
	lea	$dff000,a6
;	bsr 	WaitEOF			;wait out the demo's last frame
;	bsr.s 	AllOff			;turn off all interrupts+DMA
;	movea.l	pVBR(pc),a4
;	move.l 	oldirq(pc),$70(a4)		;restore VB vector
;	MOVE.L	4.W,A6
	MOVE.W	OLDINTENA(PC),$9A(a6)
	MOVE.W	OLDINTREQ(PC),$9C(a6)
	move.w	OLDDMA(PC),$96(a6)
;	LEA	GFXLIB(PC),A1
;	JSR	-408(A6)
	movea.l	gfxlib(pc),a5
	MOVE.L	38(A5),$80(a6)
	move.l	$32(a5),$84(a6)
	move.w	$dff088,d0
;	addq.w #1,d2			;$7fff->$8000 = master enable bit
;	or.w d2,(sp)
;	move.w (sp)+,$dff096	;restore DMA
;	or.w d2,
;	move.w d0,$dff09a	;restore interrupt mask
;	or.w (sp)+,d2
;	bsr IntReqD2			;restore interrupt requests

	move.l a5,a6
	move.l oldosscreen(pc),a1
	jsr -222(a6)			;restore OS screen

    *--- close lib+exit ---*

	move.l a6,a1			;close graphics library
	move.l 4.w,a6
	jsr -414(a6)
	
	movem.l	(sp)+,d0-d7/a0-a6
	moveq	#0,d0
	rts

;--------------
interruptaud:
	movem.l	a0-a6/d0-d7,-(sp)
	lea	$dff000,a6

; aud 0
	andi.w	#$80,$1e(a6)		; interrupt channel 0 ?
	beq.s	.aud1

	move.l	#blanksnd,$a0(a6)
	move.w	#2,$a4(a6)

	subq.w	#1,flagint
	move.b	#0,flagend

	move.w	#$80,$9c(a6)		; interrupt aud 0 finished
	bra	.noint
; aud 1
.aud1
	andi.w	#$100,$1e(a6)		; interrut channel 1 ?
	beq.s	.noint

	move.l	#blanksnd,$b0(a6)
	move.w	#2,$b4(a6)

	subq.w	#1,flagint
	move.b	#0,flagend

	move.w	#$100,$9c(a6)		; interrupt aud 1 finished
.noint	movem.l	(sp)+,a0-a6/d0-d7
	rte

Inst_plans:		
	move.w	d0,6(a0)
	swap	d0			
	move.w 	d0,2(a0)
	swap	d0
	tst.w	d1
	beq.s	.fin
	add.l	d2,d0
	addq.l	#8,a0
	subq.w	#1,d1
	bra.s	inst_plans
.fin	rts
* --------------------------------------------
pVBR	dc.l	0
oldcopper1 dc.l	0
oldcopper2 dc.l	0
gfxbase	dc.l	0
oldintena dc.w	0
oldintreq dc.w	0
olddma	dc.w	0
oldirq	dc.l	0
oldosscreen dc.l	0
flagint	dc.w	2
flagend	dc.b	-1
	even
* --------------------------------------------
GFXLIB:		DC.B	"graphics.library",0,0
		EVEN

	section	chip,data_c

CopperListBoot
	dc.w	$96,$20
	dc.w	$96,D_CON

	dc.w	$8e,$9381,$90,$c3c1
	dc.w	$92,$38,$94,$d0
	dc.w	$100,$2200
	dc.w	$108,0,$10a,0
	dc.w	$102,0,$104,0

CLspr	dc.l	$1200000,$1220000
	dc.l	$1240000,$1260000
	dc.l	$1280000,$12a0000
	dc.l	$12c0000,$12e0000
	dc.l	$1300000,$1320000
	dc.l	$1340000,$1360000
	dc.l	$1380000,$13a0000
	dc.l	$13c0000,$13e0000

CLbpl	dc.l	$E00000,$E20000	; 1
	dc.l	$E40000,$E60000	; 2
	
	dc.l	$1800000,$1820CCC
	dc.l	$1840888,$1860333

	dc.l -2

;---- 20k
bootpic	incbin	"fcload.rw"	; 40*48*2
bootsnd	incbin	"fcsound.rw"	; "team 7 presents" 44*512=22528
blanksnd ds.l	3
