STARTOFPACKEDDATA = $50000
DEPACKPOSITION = $50100

;example of how to call the depack routine
 LEA	STARTOFPACKEDDATA,A6
 LEA	DEPACKPOSITION,A5
 BSR	DEPACK

 CLR.W	-(SP)
 TRAP	#1


* LZH DEPACKER; For use with the JAM Packer V3.0 & 4.0
*
* USAGE:
* LEA $ADDRESS OF PACKED DATA,A5
* LEA $ADDRESS TO UNPACK DATA TO,A6
* BSR DEPACK
*
* NOTE: Must save registers before executing depack if original
*       contents are required.

RESET   MOVEM.W D0-D1/D3/D5,-(A7)
	MOVEA.L A1,A2
	MOVEQ   #$00,D2
	MOVEQ   #-$02,D4
	MOVEQ   #$00,D1
	MOVE.W  #$0139,D5
OUTER	ADDQ.W  #2,D4
	CMP.W   (A2)+,D7
	BHI.S   OUTER
	MOVE.W  $00(A3,D4.W),D3
	ADDQ.W  #1,D3
	LSR.W   #1,D3
	CMP.W   -$02(A3,D2.W),D3
	BLS.S 	BIDDLE
	MOVE.W  $00(A3,D1.W),D0
	ADD.W   $02(A3,D1.W),D0
	CMP.W   D0,D3
	BLS.S	BIDDLE
BITH	MOVE.W  D0,$00(A3,D2.W)
	MOVE.W  D1,$00(A1,D2.W)
	MOVE.W  D2,$00(A0,D1.W)
	MOVE.W  D2,$02(A0,D1.W)
	ADDQ.W  #2,D2
	ADDQ.L  #4,D1
	MOVE.W  $00(A3,D1.W),D0
	ADD.W   $02(A3,D1.W),D0
	CMP.W   D0,D3
	BHI.S	BITH
BIDDLE	MOVE.W  D3,$00(A3,D2.W)
	MOVE.W  $00(A1,D4.W),D0
	MOVE.W  D0,$00(A1,D2.W)
	MOVE.W  D2,$00(A0,D0.W)
	ADDQ.W  #2,D2
	DBF     D5,OUTER
MAKETABLE2
	MOVE.W  $00(A3,D1.W),D0
	ADD.W   $02(A3,D1.W),D0
	MOVE.W  D0,$00(A3,D2.W)
	MOVE.W  D1,$00(A1,D2.W)
	MOVE.W  D2,$00(A0,D1.W)
	MOVE.W  D2,$02(A0,D1.W)
	ADDQ.W  #2,D2
	ADDQ.L  #4,D1
	CMP.W   D7,D2
	BNE.S	MAKETABLE2
	MOVEM.W (A7)+,D0-D1/D3/D5
	RTS     

CREATE  MOVE.L	TABLE7(PC),A0
	LEA     TDATA1(PC),A1
	MOVEQ   #$00,D0
	MOVEQ   #$1F,D1
	MOVEQ   #$00,D2
LOOP1   MOVE.B  D0,(A0)+
	DBF     D1,LOOP1
	DBF     D2,EXIT1
	MOVE.W  (A1)+,D3
	MOVEQ   #$03,D2
EXIT1   ROL.W   #4,D3
	MOVE.W  D3,D1
	ANDI.W  #$000F,D1
	ADDQ.B  #4,D0
	BCC.S   LOOP1
	MOVE.L	TABLE8(PC),A0
	LEA     TDATA2(PC),A1
	MOVEQ   #$05,D0
	MOVEQ   #$03,D1
LOOP2   MOVE.B  $00(A1,D0.W),D2
	EXT.W   D2
LOOP3   MOVE.B  D1,(A0)+
	DBF     D2,LOOP3
	ADDQ.W  #1,D1
	DBF     D0,LOOP2
	RTS

CREATE2 MOVE.L	TABLE1(PC),A0
	MOVE.L	TABLE5(PC),A1
	MOVE.L	TABLE4(PC),A2
	MOVEQ   #$01,D1
	MOVE.W  #$04E6,D2
	MOVEQ   #$00,D4
	MOVE.W  #$0139,D0
CONTINUE
	MOVE.W  D1,(A0)+
	MOVE.W  D2,(A1)+
	MOVE.W  D4,(A2)+
	ADDQ.W  #2,D2
	ADDQ.W  #2,D4
	DBF     D0,CONTINUE
	MOVE.L	TABLE1(PC),A0
	MOVE.L	TABLE2(PC),A3
	MOVE.L	TABLE6(PC),A1
	MOVE.L	TABLE3(PC),A2
	MOVE.W  #$0274,D2
	MOVEQ   #$00,D4
	MOVE.W  #$0138,D0
DOMORE	MOVE.W  (A0)+,D1
	ADD.W   (A0)+,D1
	MOVE.W  D1,(A3)+
	MOVE.W  D4,(A1)+
	MOVE.W  D2,(A2)+
	MOVE.W  D2,(A2)+
	ADDQ.W  #4,D4
	ADDQ.W  #2,D2
	DBF     D0,DOMORE
	MOVE.W  #$FFFF,(A3)
	CLR.W   (A2)
	RTS     

RESTORE BSR     RESET
	BRA     BACK

TABLE1 DC.L 00
TABLE2 DC.L 00
TABLE3 DC.L 00
TABLE4 DC.L 00
TABLE5 DC.L 00
TABLE6 DC.L 00
TABLE7 DC.L 00
TABLE8 DC.L 00

EXIT
	ADDQ.L	#4,A7
	RTS

DEPACK
	LEA	TABLE1(PC),A0
	MOVE.L	#0,(A0)		;SET UP RELATIVE TABLE OFFSETS
	MOVE.L	#$274,4(A0)
	MOVE.L	#$4E8,8(A0)
	MOVE.L	#$9CE,12(A0)
	MOVE.L	#$C42,16(A0)
	MOVE.L	#$EB6,20(A0)
	MOVE.L	#$112A,24(A0)
	MOVE.L	#$122A,28(A0)

	MOVE.L	A7,D1		;GET STACK POSITON
	sub.l	#$1500,D1	;TABLES START ADDRESS IN D1
				;STORE UNDER STACK (NASTY!)
	MOVE.W	#7,D0
TABLOOP
	ADD.L	D1,(A0)+	;ADD TABLE BASE ADDRESS TO OFFSETS
	DBF	D0,TABLOOP
	
	BSR	CREATE
	BSR     CREATE2
	MOVE.L	TABLE3(PC),A0
	MOVE.L	TABLE5(PC),A1
	MOVE.L	TABLE1(PC),A3
	MOVE.L  A6,-(A7)
	ADD.L	4(A5),A6
	ADD.L	8(A5),A5
	ADD.L	#$0C,A5
	MOVE.L	A6,A4

	MOVE.W	#59,D0		;MOVE 60 SPACES TO END OF UNPACKED AREA
SPACES	MOVE.B	#$20,(A4)+	;NOTE: SHOULD PROBABLY SAVE THIS AREA
	DBF	D0,SPACES	;      BEFORE WIPING IT OUT!

	MOVEQ   #$08,D6
	MOVE.B  -(A5),D5
	MOVE.W  #$04E6,D7
	MOVE.L	TABLE8(PC),A4

TOP	MOVE.W	#$222,$FFFF8240.W
	MOVE.W  #0,$FFFF8240.W
	CMPA.L  (A7),A6
	BLE	EXIT

	MOVE.W  $04E4(A1),D0
MORE	DBF     D6,NOTEMPTY
	MOVEQ   #$07,D6
	MOVE.B  -(A5),D5
NOTEMPTY
	ADD.B   D5,D5
	BCC.S   ZERO
	ADDQ.W  #2,D0
ZERO	MOVE.W  $00(A1,D0.W),D0
	CMP.W   D7,D0
	BLT.S   MORE
	MOVE.W  D0,D1
	SUB.W   D7,D0
	MOVE.W  $04E4(A3),D4
	BMI	RESTORE

BACK	MOVE.W  $00(A0,D1.W),D1
SCAN	LEA     $00(A3,D1.W),A2
	ADDQ.W  #1,(A2)
	CMPM.W  (A2)+,(A2)+
	BCS.S   FRSTGTR
	MOVE.W  $00(A0,D1.W),D1
	BNE.S   SCAN
	LSR.W   #1,D0
	CMP.W   #$0100,D0
	BGE.S   GTE256
WRITE	MOVE.B	D0,-(A6)
	BRA.S   TOP

FRSTGTR SUBQ.W  #1,-$0004(A2)
	MOVE.W  -$0004(A2),D4
SAME	CMP.W   (A2)+,D4
	BEQ.S   SAME
	SUBQ.L  #4,A2
	ADDQ.W  #1,(A2)
	SUBA.L  A3,A2
	MOVE.W  $00(A1,D1.W),D4
	MOVE.W  A2,$00(A0,D4.W)
	CMP.W   D7,D4
	BCC.S   SKIP
	MOVE.W  A2,$02(A0,D4.W)
SKIP	MOVE.W  $00(A1,A2.W),D2
	MOVE.W  D4,$00(A1,A2.W)
	MOVE.W  D1,$00(A0,D2.W)
	CMP.W   D7,D2
	BCC.S   SKIP2
	MOVE.W  D1,$02(A0,D2.W)
SKIP2   MOVE.W  D2,$00(A1,D1.W)
	MOVE.W  $00(A0,A2.W),D1
	BNE.S   SCAN
	LSR.W   #1,D0
	CMP.W   #$0100,D0
	BLT.S   WRITE
GTE256	MOVE.B  -1(A5),D1
	MOVEQ   #$00,D2
	LSR.B   D6,D1
	OR.B    D5,D1
	MOVE.B  $00(A4,D1.W),D2
	SUB.W   D2,D6
	BPL.S   POSITIVE
	MOVE.B  -(A5),D5
	MOVE.B  D5,D4
	ADDQ.W  #2,D6
	BMI.S   OVERFLOW
	BEQ.S   MODD4
	LSR.B   #1,D4
	LSL.B   #7,D5
	BRA.S   MODD4
READONE MOVE.B  -(A5),D5
	MOVE.B  D5,D4
	LSL.B   #6,D5
	MOVEQ   #$02,D6
	LSR.B   D6,D4
	BRA.S   DOCOPY
POSITIVE
	BEQ.S   READONE
	MOVE.B (A5),D5
	SUBQ.W  #6,D6
OVERFLOW
	NEG.W   D6
	LSL.B   D6,D5
	MOVE.B  D5,D4
	MOVE.B  -(A5),D5
	MOVE.B  D5,D2
	LSL.B   D6,D5
	SUBQ.W  #8,D6
	NEG.W   D6
	LSR.B   D6,D2
	OR.B    D2,D4
MODD4   ANDI.W  #$003F,D4
DOCOPY	MOVE.L	TABLE7(PC),A0
	MOVE.B  (A0,D1.W),D2
	LSL.W   #4,D2
	OR.B    D4,D2
	;NEG.W   D2
	LEA     $01(A6,D2.W),A0
	SUBI.W  #$00FE,D0
	MOVE.W  D0,D1
COPY	MOVE.B  -(A0),D0
	MOVE.B  D0,-(A6)
	DBF     D1,COPY
	MOVE.L	TABLE3(PC),A0
	BRA	TOP

TDATA2	DC.W	$0F2F
	DC.W	$2F3F
	DC.W	$2F1F
TDATA1
	DC.W	$FFF7
	DC.W	$7777
	DC.W	$7773
	DC.W	$3333
	DC.W	$3333
	DC.W	$3331
	DC.W	$1111
	DC.W	$1111
	DC.W	$1111
	DC.W	$1111
	DC.W	$1111
	DC.W	$1110
	DC.L	$00
	DC.L	$00
