*************************************************************************
*	REALLY FUCKING FAST REALTIME BYTE RUN 1 COMPRESSER		*
*		BY -BATFINK- OF QUARTZ IN THE YEAR OF 1992		*
*	NEEDED FOR REALTIME COMPRESSION OF DIGITISED IMAGES		*
*************************************************************************
;DIFFERS FROM IFF COMPRESSION IN SEVERAL WAYS
;I)   ONLY 3 BYTE RUNS OR ABOVE ARE CODED AS REPLICATE RUNS.
;II)  120 BYTE CHUNKS ARE CODED IN 1 PASS (RATHER THAN 1 RASTER)
;III) DATA IS CODED AS 1 DATA LUMP RATHER THAN ILBM STYLE.


	include	df1:include/custom_registers.i

	section	crunch,code_c


	lea	Planes(pc),a0
	move.l	#DecDat,d0
	moveq	#4-1,d7
.Pploop:
	move.w	d0,6(a0)
	swap	d0
	move.w	d0,2(a0)
	swap	d0
	add.l	#40*256,d0
	addq.l	#8,a0
	dbra	d7,.Pploop

	move.l	4,a6
	lea	Custom,a5
	jsr	Forbid(a6)

	move.w	Dmaconr(a5),d0
	or.w	#$8000,d0
	move.w	d0,OldDma
	move.w	#$7fff,Dmacon(a5)
	move.l	#MyCop,Cop1lch(a5)
	move.w	#0,Copjump1(a5)
	move.w	#$83c0,Dmacon(a5)

	lea	SourceDat(pc),a2
	move.l	#DestDat,a3
	moveq.l	#0,d2
	moveq	#4-1,d6
.PlLoop:
	move.w	#256/2-1,d7
.CrunchLoop:
	move.l	a2,a0
	move.l	a3,a1
	bsr	Compress		;Compress rasterline
	lea	80(a2),a2		;Nxt Source Raster
	lea	(a3,d0.w),a3		;Keep Pos In Crunch Buffer
	add.l	d0,d2
	dbra	d7,.CrunchLoop
	dbra	d6,.PlLoop
	move.l	d2,d0			;d0=sizeof

	move.w	#$007,MyCOl
	move.w	d0,l

	bsr	DeCompress		;Decompress Image

.Mouse:	btst	#6,$bfe001
	bne	.Mouse

	lea	Gfxname(pc),a1
	clr.l	d0
	jsr	Openlibrary(a6)
	move.l	d0,a0
	move.w	#$7fff,Dmacon(a5)
	move.l	38(a0),Cop1lch(a5)
	move.w	#0,Copjump1(a5)
	move.w	OldDma(pc),Dmacon(a5)
	jsr	Permit(a6)
	RTS


l:	dc.w	0

MyCop:
	dc.w	Diwstrt,$3081
	dc.w	Diwstop,$30c1
	dc.w	Ddfstrt,$38
	dc.w	Ddfstop,$d0
	dc.w	Bplcon0,$1000*4
	dc.w	Bpl1mod,0
	dc.w	Bpl2mod,0

	dc.w	Colour00
MyCol:	dc.w	$000f

	dc.w	$0180,$0fff,$0182,$0aaa,$0184,$0555,$0186,$0000
	dc.w	$0188,$0d0d,$018a,$0fad,$018c,$0f00,$018e,$0842
	dc.w	$0190,$0040,$0192,$0a52,$0194,$0fe0,$0196,$00a0
	dc.w	$0198,$00d0,$019a,$0ba0,$019c,$0870,$019e,$001f

Planes:	
	dc.w	Bpl1pth,0
	dc.w	Bpl1ptl,0
	dc.w	Bpl2pth,0
	dc.w	Bpl2ptl,0
	dc.w	Bpl3pth,0
	dc.w	Bpl3ptl,0
	dc.w	Bpl4pth,0
	dc.w	Bpl4ptl,0


	dc.w	$ffff,$fffe
	
OldDma:	dc.w	0
Gfxname:dc.b	'graphics.library',0
	even




;>>>>>>>>>> COMPRESS <<<<<<<<<<

BrCompress:
	
;---------- d0=Scratch d1=Scratch d2=Match
;---------- d4=Literal Counter d5=Replicate counter d7=Loop
;---------- a0=Source Data a1=Dest Data a2/a3=Internal ^'s

Compress:
	movem.l	d2-d7/a2-a6,-(sp)
	move.w	#80-1,d7	;1 Rasterline
	move.l	a0,a2
	move.l	a1,a3
	moveq.l	#0,d4		;Clr Copy Counter
	moveq.l	#0,d5		;Clr Replicate Counter

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

.CompressLoop:
	move.b	(a0),d2		;Match Byte = Data Byte
	add.b	d5,d4		;Copy Cnt. + Replicate Cnt.
	move.b	#-1,d5		;Replicate Cnt.=0
	move.b	#1,d1		;Use Scratch to speed up Loop
.RunLoop:
	add.b	d1,d5		;Replicate Cnt. +1	
	cmp.b	(a0)+,d2	;Nxt Data Byte = Match Byte?	
	dbne	d7,.RunLoop	;Within The Raster

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

.EndRun:
	subq.l	#1,a0		;Correct Data ^
	tst.b	d7
	bpl.b	.Norm
	cmp.b	#3,d5
	blt.b	.UpCopy
	add.b	#1,d5
	bra	.FlushIt
.UpCopy:
	add.b	#1,d4
	bra	.FlushIt

.Norm:	
	cmp.b	#3,d5
	blt.b	.CompressLoop	;Anything to replicate?

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

.FlushIt:
	tst.b	d4		;Anything to copy?
	beq.b	.NoCopy		
	sub.b	d1,d4		;Correct for loop/decompress -1
	move.b	d4,d1		
	neg.b	d1		;Copy Cnt. +tve -> -tve
	move.b	d1,(a1)+	;Insert "Copy" "Info" Byte
.CopyLoop:
	move.b	(a2)+,(a1)+	;Insert "Copy" Data
	dbra	d4,.CopyLoop
	clr.w	d4		;Copy Cnt. = 0

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

.NoCopy:			
	lea	(a2,d5.w),a2	;Increment ^ past replicated data
	subq.b	#1,d5		;Correct For Decompression
	bmi.b	.FlushError	;Invalid value caused by flush?
	move.b	d5,(a1)+	;Insert "Replicate" "Info" byte
	move.b	d2,(a1)+	;Insert "Replicate" "Data" byte
	clr.b	d5		;Replicate Cnt. = 0

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

	tst.b	d7		;Finished Raster Line?
	bpl.b	.CompressLoop
.FlushError:
	sub.l	a3,a1
	move.l	a1,d0		;Got sizeof
	movem.l	(sp)+,d2-d7/a2-a6
	RTS			;* EXIT *

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






;>>>>>>>>>> DECOMPRESS CODE! <<<<<<<<<<


Decompress:
	movem.l	d2-d7/a2-a6,-(sp)
	move.l	#DestDat,a0
	move.l	#DecDat,a1
	lea	(a0,d0.w),a2
.DecomLoop:
	clr.w	d0
	move.b	(a0)+,d0		;Get info Byte
	bmi	.Copy

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

	move.b	(a0)+,d1		;Get replicate byte
.RepliLoop:
	move.b	d1,(a1)+
	dbra	d0,.RepliLoop
	bra	.DoneSec	

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

.Copy:
	neg.b	d0
.CopyLoop:
	move.b	(a0)+,(a1)+
	dbra	d0,.CopyLoop

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

.DoneSec
	cmp.l	#DecDatEnd,a1
	blt	.DecomLoop
	movem.l	(sp)+,d2-d7/a2-a6
	RTS



Sourcedat:
	incbin	df0:testpic
SDatEnd:

DestDat:
	blk.b	40960
DDatEnd:

DecDat:
	blk.b	40960
DecDatEnd:
