*******************************************************************************
*
*	Written by LORD BLITTER
*
*	Christian MORANT
*	8, av. des Pagodes
*	1020 Brussels
*	Belgium
*
*	official dealer : BS1
*
*******************************************************************************

StartOfData	equ	$30000		Start of data
EndOfData	equ	$3E000		End of data
Destination	equ	$30000		Destination address
Offset		equ	$800		Maximum Offset

*******************************************************************************

		lea.l	StartOfData,A0		A0 = Start of data
		lea.l	EndOfData,A1		A1 = End of data
		lea.l	Destination,A2		A2 = Destination
		clr.w	D1			D1 = 0
		moveq.l	#1,D2			D2 = 1
		clr.l	D7			D7 = 0

noteocrunch	jsr	Crunch
		tst.b	D0			D0 = 0 ?
		beq.s	crunched		Yes

		addq.w	#1,D1			D1 = D1 + 1
		cmpi.w	#265,D1			D1 = 265 ?
		bne.s	nojmp			Nope

		jsr	dojmp

nojmp
crunched	cmp.l	A0,A1				A1 > A0 ?
		bgt.s	noteocrunch			Yes

		jsr	dojmp

		jsr	write1lwd
		move.l	D7,(A2)+

		lea.l	StartOfData,A0		A0 = Start of data
		lea.l	EndOfData,A1		A1 = End of data
		move.l	A1,D2			D2 = A1
		sub.l	A0,D2			D2 = D2 - A0
		move.l	D2,(A2)+

		clr.l	D0			D0 = 0
		clr.l	D1			D1 = 0
		clr.l	D2			D2 = 0
		clr.l	D3			D3 = 0
		clr.l	D4			D4 = 0
		clr.l	D5			D5 = 0

		lea.l	cnt,A3			A3 =
		movem.w	(A3)+,D0-D5		D0..D5 = 0

		movea.l	A2,A3			A3 = A2
		sub.l	A0,A3			A3 = A3 - A0

		lea.l	EndOfData,A4		A4 = End of data
		sub.l	A2,A4			A4 = A4 - A2
		illegal

*******************************************************************************

Crunch		move.l	A0,A3			A3 = Start of data
		add.l	#Offset,A3		Skip bytes
		cmp.l	A1,A3			A3 < End of data
		ble.s	nottop

		move.l	A1,A3			A3 = End of data

nottop		moveq.l	#1,D5			D5 = 1
		movea.l	A0,A5			A5 = Start of data
		addq.l	#1,A5			A5 = A5 + 1

CheckNextPair	move.b	(A0),D3			D3 = Hi-byte
		move.b	1(A0),D4		D4 = Lo-byte

quickfind	cmp.b	(A5)+,D3		D3 equal to next byte
		bne.s	contfind		Nope

		cmp.b	(A5),D4			D4 equal to next byte
		beq.s	lenfind			Yes

contfind	cmpa.l	A5,A3			A5 still within range ?
		bgt.s	quickfind		Yes, continue search
		jmp	endquickfind

*** *** *** *** *** *** *** *** *** *** *** *** *** *** *** *** *** *** *** ***

lenfind		subq	#1,A5
		movea.l	A0,A4			A4 = Start of data

ContinuScan	move.b	(A4)+,D3
		cmp.b	(A5)+,D3
		bne.s	FoundEnd

		cmp.l	A5,A3			A5 still within range ?
		bgt.s	ContinuScan

FoundEnd	move.l	A4,D3			D3 = end of equal bytes
		sub.l	A0,D3			D3 = size of equal bytes
		subq.l	#1,D3			D3 = D3 - 1
		cmp.l	D3,D5			1 > D3 ?
		bge.s	DontCrunch

		move.l	A5,D4
		sub.l	A0,D4
		sub.l	D3,D4
		subq	#1,D4

		cmp.l	#4,D3			D3 < 4 ?
		ble.s	DoSmallCrunch		Yes

		moveq.l	#6,D6
		cmp.l	#257,D3			D3 < 257 ?
		blt.s	DoLargeCrunch		Yes

		move.w	#256,D3			D3 = 256
DoLargeCrunch	bra.s	cont1

DoSmallCrunch	move.w	D3,D6			D6 = D3
		subq.w	#2,D6			D6 = D6 - 2
		lsl.w	#1,D6			D6 = D6 * 2

cont1		lea.l	table,A6
		cmp.w	(A6,D6.w),D4
		bge.s	DontCrunch

		move.l	D3,D5
		move.l	D4,MaxOffset
		move.b	D6,TableOffset

DontCrunch	cmp.l	A5,A3
		bgt.s	CheckNextPair

endquickfind	cmp.l	#1,D5
		beq.s	nothingfound

		jsr	dojmp

		move.b	TableOffset,D6
		move.l	MaxOffset,D3
		move.w	8(A6,D6.w),D0
		jsr	wD0bits

		move.w	16(A6,D6.w),D0
		beq.s	nolength
		move.l	D5,D3
		subq	#1,D3
		jsr	wD0bits

nolength	move.w	24(A6,D6.w),D0
		move.w	32(A6,D6.w),D3
		jsr	wD0bits

		addi.w	#1,40(A6,D6.w)
		addi.w	#1,$DFF180

		add.l	D5,A0
		clr.b	D0
		rts

nothingfound	move.b	(A0)+,D3
		moveq	#8,D0
		jsr	wD0bits
		moveq	#1,D0
		rts

*******************************************************************************

MaxOffset	dc.l	0
TableOffset	dc.w	0

*******************************************************************************

table
offst		dc.w	$0100,$0200,$0400,$1000
lnoff		dc.w	$0008,$0009,$000a,$000c
length		dc.w	$0000,$0000,$0000,$0008
cdlen		dc.w	$0002,$0003,$0003,$0003
code		dc.w	$0001,$0004,$0005,$0006

cnt		dc.w	0,0,0,0
cntjmp		dc.w	0,0

*******************************************************************************

dojmp		tst.w	D1			D1 = 0 ?
		beq.s	skipjmp			Yes

		move.w	D1,D3			D3 = D1
		clr.w	D1			D1 = 0

		cmp.w	#9,D3			D3 >= 9 ?
		bge.s	bigjmp			Yes

		addq.w	#1,cntjmp
		subq.w	#1,D3			D3 = D3 - 1
*		or.b	#%00000000,D3

		moveq	#5,D0			D0 = 5
		jmp	wD0bits

skipjmp		rts

bigjmp		addq.w	#1,cntjmp+2
		subi.w	#9,D3			D3 = D3 - 9
		or.w	#%0000011100000000,D3
		moveq	#11,D0			D0 = 11
		jmp	wD0bits

*** *** *** *** *** *** *** *** *** *** *** *** *** *** *** *** *** *** *** ***

wD0bits		subq.w	#1,D0			D0 = D0 - 1
copybits	lsr.l	#1,D3			D3 = D3 / 2
		roxl.l	#1,D2			D2 = D2 * 2
		bcs.s	writelwd
		dbra	D0,copybits

		rts

write1lwd	clr.w	D0			D0 = 0
writelwd	move.l	D2,(A2)+
		eor.l	D2,D7
		moveq	#1,D2			D2 = 1
		dbra	D0,copybits

		rts
