;crunch stuff! ; ;(c) 1991, 92 by Thomas Schwarz, all rights reserved ; ;includes imploder/deploder/crmdecrunch ; bra _startcrunch ;0 bra _decrunch ;4 bra _crm ;8 bra _ppdecrunch ;12 ; implode: ; ; In: a0.l=*buffer ; a1.l=*info routine (d0.l=0:break; -1:continue) ; d0.l=data length ; d1.l=crunch mode ; ; Out: d0.l=<0:user break; 0:error; <>0:crunched length ; ;------------------------------------------------ _startcrunch: MOVE.l d0,a0 MOVE.l d1,d0 ; LEA $100000,a0 LEA Own(pc),a1 ; MOVE.l #30000,d0 MOVEQ #8,d1 ; MOVE.w #$4000,$dff09a ; System Off BSR Implode ; MOVE.w #$c000,$dff09a ; System On RTS ;------------------------------------------------ Own: MOVE.w d1,$dff180 BTST #6,$bfe001 BNE own1 MOVEQ #0,d0 BRA own2 own1: MOVEQ #-1,d0 own2: RTS ;------------------------------------------------ Implode: MOVEM.l d2-d7/a2-a6,-(a7) MOVE.w #$57,d2 im01: CLR.w -(a7) DBF d2,im01 MOVE.l a7,a6 MOVE.l a5,2(a6) CMP.l #$40,d0 BCS im23 LSR.l #8,d1 SCS (a6) LSR.l #8,d1 CMP.b #12,d1 BCS im02 MOVEQ #0,d1 im02: MOVE.l a1,6(a6) MOVE.l a0,10(a6) MOVE.l a0,$22(a6) MOVE.l a0,$26(a6) MOVE.l d0,$12(a6) ADD.l d0,a0 MOVE.l a0,14(a6) LEA imtab0(pc),a0 LSL.w #2,d1 MOVE.l 0(a0,d1.w),d1 ADDQ.l #1,d1 CMP.l d0,d1 BLS im03 MOVE.l d0,d1 SUBQ.l #1,d1 im03: MOVE.l d1,$1A(a6) SUBQ.l #1,d1 MOVEQ #0,d0 im04: CMP.l (a0)+,d1 BLS im05 ADDQ.b #1,d0 BRA im04 im05: MOVE.b d0,1(a6) LEA $A4(a6),a1 MOVEQ #12,d1 MULU d1,d0 LEA imtab1(pc),a0 ADD.l d0,a0 SUBQ.w #1,d1 im06: MOVE.b (a0)+,(a1)+ DBF d1,im06 LEA $74(a6),a1 LEA $A4(a6),a0 MOVEQ #11,d1 im07: MOVE.b (a0)+,d0 MOVEQ #0,d2 BSET d0,d2 MOVE.l d2,(a1)+ DBF d1,im07 LEA $74(a6),a0 LEA $84(a6),a1 MOVEQ #7,d1 im08: MOVE.l (a0)+,d0 ADD.l d0,(a1)+ DBF d1,im08 TST.b (a6) BEQ im11 LEA $74(a6),a1 MOVEQ #7,d0 im09: MOVE.l (a1)+,d1 MOVE.w d1,(a2)+ DBF d0,im09 LEA $A4(a6),a1 MOVEQ #11,d0 im10: MOVE.b (a1)+,(a2)+ DBF d0,im10 im11: MOVE.b #7,$2D(a6) im12: BSR im26 BNE im22 BSR im28 BEQ im15 BSR im55 BNE im13 MOVE.l $22(a6),a0 MOVE.l $26(a6),a1 MOVE.b (a0),(a1) ADDQ.l #1,$22(a6) ADDQ.l #1,$26(a6) ADDQ.l #1,$30(a6) ADDQ.l #1,$1E(a6) CMP.l #$4012,$30(a6) BCS im12 BRA im15 im13: MOVE.b $5C(a6),d0 MOVE.l $60(a6),d1 BSR im37 MOVE.b $5E(a6),d0 MOVE.w $66(a6),d1 BSR im37 MOVE.b $5D(a6),d0 MOVE.w $64(a6),d1 CMP.b #13,d0 BNE im14 MOVE.l $26(a6),a0 MOVE.b d1,(a0)+ MOVE.l a0,$26(a6) MOVEQ #5,d0 MOVEQ #$1F,d1 im14: BSR im37 MOVEQ #0,d0 MOVE.b $2E(a6),d0 ADD.l d0,$22(a6) CLR.l $30(a6) BRA im12 im15: BSR im26 BNE im22 MOVE.l $22(a6),a0 MOVE.l $26(a6),a1 MOVE.b (a0),(a1) ADDQ.l #1,$22(a6) ADDQ.l #1,$26(a6) ADDQ.l #1,$30(a6) ADDQ.l #1,$1E(a6) MOVE.l $22(a6),d0 CMP.l 14(a6),d0 BNE im15 BSR im26 BNE im22 TST.b (a6) BNE im19 MOVE.l $26(a6),d0 SUB.l 10(a6),d0 CMP.l #12,d0 BCS im23 MOVE.l $12(a6),d1 SUB.l d0,d1 CMP.l #$36,d1 BLS im23 MOVE.l 10(a6),a1 MOVE.l $26(a6),a0 MOVE.l #$FF00,d7 BTST #0,d0 BEQ im16 MOVEQ #0,d7 ADDQ.l #1,d0 CLR.b (a0)+ im16: MOVE.l (a1),8(a0) MOVE.l #"IMP!",(a1) MOVE.l 4(a1),4(a0) MOVE.l $12(a6),4(a1) MOVE.l 8(a1),(a0) MOVE.l d0,8(a1) ADD.l #$2E,d0 MOVE.l d0,$16(a6) MOVE.l $30(a6),12(a0) MOVE.b $2C(a6),d1 AND.w #$FE,d1 MOVE.b $2D(a6),d0 BSET d0,d1 OR.w d7,d1 MOVE.w d1,$10(a0) LEA $74(a6),a1 ADD.w #$12,a0 MOVEQ #7,d0 im17: MOVE.l (a1)+,d1 MOVE.w d1,(a0)+ DBF d0,im17 LEA $A4(a6),a1 MOVEQ #11,d0 im18: MOVE.b (a1)+,(a0)+ DBF d0,im18 BRA im23 im19: MOVE.l $26(a6),d0 SUB.l 10(a6),d0 MOVE.l $12(a6),d1 SUB.l d0,d1 CMP.l #6,d1 BLS im23 MOVE.b $2C(a6),d1 AND.b #$FE,d1 MOVE.b $2D(a6),d2 BSET d2,d1 MOVE.l $26(a6),a0 BTST #0,d0 BEQ im20 MOVE.b d1,(a0)+ MOVE.l $30(a6),(a0) BRA im21 im20: MOVE.l $30(a6),(a0)+ MOVE.b d1,(a0) im21: ADDQ.l #5,d0 MOVE.l d0,$16(a6) BRA im23 im22: MOVEQ #-1,d0 BRA im24 im23: MOVE.l $16(a6),d0 im24: MOVE.w #$57,d2 im25: CLR.w (a7)+ DBF d2,im25 MOVEM.l (a7)+,d2-d7/a2-a6 TST.l d0 RTS ;------------------------------------------------ imtab0: Dc.l 128,256,512,1024,1792,3328,5376,9472,20736,37376,67840,67840 imtab1: Dc.l $5050505,$5050505,$6060606,$5060707,$6060606,$7070606 Dc.l $5060707,$7070707,$8080808,$5060708,$7070808,$8080909 Dc.l $6070708,$7080909,$8090A0A,$6070708,$709090A,$80A0B0B Dc.l $6070808,$709090A,$80A0B0C,$6070808,$709090A,$90A0C0D Dc.l $6070708,$709090C,$90A0C0E,$6070809,$7090A0C,$90B0D0F Dc.l $6070808,$70A0B0B,$90C0D10,$6080809,$70B0C0C,$90D0E11 imtab2: Dc.l $2060E,$1020304 imtab3: Dc.l $1010101,$2030304,$405070E imtab4: Dc.l $20002,$20002,$6000A,$A0012,$16002A,$8A4012 ;------------------------------------------------ im26: MOVE.l 6(a6),d0 BEQ im27 MOVE.l d0,a0 MOVE.l 14(a6),d0 SUB.l $22(a6),d0 MOVE.l $22(a6),d1 SUB.l $26(a6),d1 MOVEQ #0,d2 MOVE.b 1(a6),d2 MOVE.l 2(a6),a5 MOVE.l a6,-(a7) JSR (a0) MOVE.l (a7)+,a6 NOT.l d0 im27: TST.l d0 RTS ;------------------------------------------------ im28: MOVE.l $22(a6),a5 MOVE.l 14(a6),d4 MOVE.l a5,d0 ADDQ.l #1,d0 ADD.l $1A(a6),d0 CMP.l d4,d0 BLS im29 MOVE.l d4,d0 MOVE.l d0,d1 SUB.l a5,d1 CMP.l #3,d1 BCC im29 MOVEQ #0,d0 RTS ;------------------------------------------------ im29: MOVE.l d0,d5 MOVE.l a5,a2 ADDQ.l #1,a2 MOVE.l a2,a4 MOVEQ #1,d7 MOVE.b (a5),d3 LEA $34(a6),a3 im30: CMP.b (a2)+,d3 BEQ im32 CMP.b (a2)+,d3 BEQ im32 CMP.b (a2)+,d3 BEQ im32 CMP.b (a2)+,d3 BEQ im32 CMP.b (a2)+,d3 BEQ im32 CMP.b (a2)+,d3 BEQ im32 CMP.b (a2)+,d3 BEQ im32 CMP.b (a2)+,d3 BEQ im32 CMP.b (a2)+,d3 BEQ im32 CMP.b (a2)+,d3 BEQ im32 CMP.b (a2)+,d3 BEQ im32 CMP.b (a2)+,d3 BEQ im32 CMP.b (a2)+,d3 BEQ im32 CMP.b (a2)+,d3 BEQ im32 CMP.b (a2)+,d3 BEQ im32 CMP.b (a2)+,d3 BEQ im32 CMP.l a2,d5 BHI im30 im31: MOVEQ #-1,d0 RTS ;------------------------------------------------ im32: CMP.l a2,d5 BLS im31 MOVE.l a4,a0 MOVE.l a2,a1 CMPM.b (a0)+,(a1)+ BNE im30 CMPM.b (a0)+,(a1)+ BNE im35 CMPM.b (a0)+,(a1)+ BNE im34 MOVE.w #251,d0 im33: CMPM.b (a0)+,(a1)+ DBNE d0,im33 im34: CMP.l d4,a1 BLS im35 MOVE.l d4,a1 im35: MOVE.l a1,d6 SUB.l a2,d6 CMP.w d6,d7 BCC im30 MOVE.w d6,d7 CMP.w #8,d6 BHI im36 TST.b -2(a3,d6.w) BNE im30 MOVE.b d6,-2(a3,d6.w) MOVE.l a2,d0 SUB.l a5,d0 SUBQ.l #2,d0 MOVE.w d6,d1 LSL.w #2,d1 MOVE.l d0,0(a3,d1.w) BRA im30 im36: MOVE.b d6,7(a3) MOVE.l a2,d0 SUB.l a5,d0 SUBQ.l #2,d0 MOVE.l d0,$24(a3) CMP.b #$FF,d6 BNE im30 BRA im31 im37: MOVE.b $2C(a6),d2 MOVE.b $2D(a6),d3 MOVE.l $26(a6),a0 im38: LSR.l #1,d1 ROXR.b #1,d2 SUBQ.b #1,d3 BPL im39 MOVEQ #7,d3 MOVE.b d2,(a0)+ MOVEQ #0,d2 im39: SUBQ.b #1,d0 BNE im38 MOVE.l a0,$26(a6) MOVE.b d3,$2D(a6) MOVE.b d2,$2C(a6) RTS ;------------------------------------------------ im40: AND.l #$FF,d0 CMP.b #13,d0 BHI im42 CMP.b #5,d0 BHI im41 LEA imtab2(pc),a0 MOVE.b -2(a0,d0.w),$71(a6) MOVE.b 2(a0,d0.w),$69(a6) BRA im44 im41: SUBQ.b #6,d0 OR.b #$F0,d0 MOVE.b d0,$71(a6) MOVE.b #8,$69(a6) BRA im43 im42: MOVE.b #$1F,$70(a6) MOVE.b d0,$71(a6) MOVE.b #13,$69(a6) im43: MOVEQ #5,d0 im44: SUBQ.b #2,d0 MOVE.l $30(a6),d2 LEA imtab3(pc),a1 LEA imtab4(pc),a0 ADD.l d0,a0 ADD.l d0,a0 CMP.w (a0),d2 BCC im45 MOVE.b 0(a1,d0.w),d6 MOVE.b d6,d3 ADDQ.b #1,d3 MOVE.b #0,$73(a6) MOVEQ #0,d4 BRA im48 im45: CMP.w 8(a0),d2 BCC im46 MOVE.b 4(a1,d0.w),d6 MOVE.b d6,d3 ADDQ.b #2,d3 MOVE.b #2,$73(a6) MOVE.w (a0),d4 BRA im48 im46: CMP.w $10(a0),d2 BCS im47 MOVEQ #0,d0 RTS ;------------------------------------------------ im47: MOVE.b 8(a1,d0.w),d6 MOVE.b d6,d3 ADDQ.b #2,d3 MOVE.b #3,$73(a6) MOVE.w 8(a0),d4 im48: MOVE.b d3,$6A(a6) SUB.w d4,d2 MOVEQ #$10,d5 SUB.b d6,d5 LSL.w d5,d2 im49: ADD.w d2,d2 ROXL $72(a6) SUBQ.b #1,d6 BNE im49 LEA $A4(a6),a1 LEA $74(a6),a0 ADD.w d0,a0 ADD.w d0,a0 ADD.w d0,a0 ADD.w d0,a0 CMP.l (a0),d1 BCC im50 MOVE.b 0(a1,d0.w),d6 MOVE.b d6,d3 ADDQ.b #1,d3 MOVEQ #0,d7 MOVEQ #0,d4 BRA im53 im50: CMP.l $10(a0),d1 BCC im51 MOVE.b 4(a1,d0.w),d6 MOVE.b d6,d3 ADDQ.b #2,d3 MOVEQ #2,d7 MOVE.l (a0),d4 BRA im53 im51: CMP.l $20(a0),d1 BCS im52 MOVEQ #0,d0 RTS ;------------------------------------------------ im52: MOVE.b 8(a1,d0.w),d6 MOVE.b d6,d3 ADDQ.b #2,d3 MOVEQ #3,d7 MOVE.l $10(a0),d4 im53: MOVE.b d3,$68(a6) SUB.l d4,d1 MOVEQ #$20,d5 SUB.b d6,d5 LSL.l d5,d1 im54: ADD.l d1,d1 ADDX.l d7,d7 SUBQ.b #1,d6 BNE im54 MOVE.l d7,$6C(a6) MOVEQ #-1,d0 RTS ;------------------------------------------------ im55: CLR.w $2A(a6) CLR.b $2E(a6) LEA $34(a6),a4 LEA $3C(a6),a5 im56: MOVE.l (a5)+,d1 MOVE.b (a4)+,d0 BEQ im58 BSR im40 BEQ im58 MOVEQ #0,d0 MOVEQ #0,d1 MOVE.b -1(a4),d0 LSL.w #3,d0 ADD.b $69(a6),d1 ADD.b $68(a6),d1 ADD.b $6A(a6),d1 SUB.w d1,d0 BMI im58 CMP.w $2A(a6),d0 BCS im58 MOVE.w d0,$2A(a6) MOVE.b -1(a4),$2E(a6) LEA $5C(a6),a0 LEA $68(a6),a1 MOVEQ #12,d1 im57: MOVE.b (a1)+,(a0)+ DBF d1,im57 im58: MOVE.l a4,d0 SUB.l a6,d0 CMP.w #$3C,d0 BNE im56 CLR.l -(a4) CLR.l -(a4) TST.w $2E(a6) RTS ;------------------------------------------------ _decrunch: ;LEA $50000,a0 MOVE.l d0,a0 ;********************************** ;* FILE IMPLODER DECRUNCH ROUTINE * ;* FOR ASMONE ASSEMBLER * ;********************************** ; ; Entry: a0 = address of crunched file ; Exit: d0 = 0 error or d0 = -1 depack ok ; ; File structure to check: ; ; 0(a0) = 'IMP!' ; 4(a0) = len of depacked file ; 8(a0) = len of packed file-$32 ; A(a0) = here start the datas ; ; deplode: CMP.l #"IMP!",(a0) BNE I1802 MOVEM.l d2-d5/a2-a4,-(a7) MOVE.l a0,a3 MOVE.l a0,a4 TST.l (a0)+ ADD.l (a0)+,a4 ADD.l (a0)+,a3 MOVE.l a3,a2 MOVE.l (a2)+,-(a0) MOVE.l (a2)+,-(a0) MOVE.l (a2)+,-(a0) MOVE.l (a2)+,d2 MOVE.w (a2)+,d3 BMI I17EE SUBQ.l #1,a3 I17EE: LEA -$1C(a7),a7 MOVE.l a7,a1 MOVEQ #6,d0 I17F6: MOVE.l (a2)+,(a1)+ DBF d0,I17F6 MOVE.l a7,a1 BRA I1E70 I1802: MOVEQ #0,d0 RTS I1E70: TST.l d2 BEQ I1E7A I1E74: MOVE.b -(a3),-(a4) SUBQ.l #1,d2 BNE I1E74 I1E7A: CMP.l a4,a0 BCS I1E92 LEA $1C(a7),a7 MOVEQ #-$1,d0 CMP.l a3,a0 BEQ I1E8A MOVEQ #0,d0 I1E8A: MOVEM.l (a7)+,d2-d5/a2-a4 TST.l d0 RTS I1E92: ADD.b d3,d3 BNE I1E9A MOVE.b -(a3),d3 ADDX.b d3,d3 I1E9A: BCC I1F04 ADD.b d3,d3 BNE I1EA4 MOVE.b -(a3),d3 ADDX.b d3,d3 I1EA4: BCC I1EFE ADD.b d3,d3 BNE I1EAE MOVE.b -(a3),d3 ADDX.b d3,d3 I1EAE: BCC I1EF8 ADD.b d3,d3 BNE I1EB8 MOVE.b -(a3),d3 ADDX.b d3,d3 I1EB8: BCC I1EF2 MOVEQ #0,d4 ADD.b d3,d3 BNE I1EC4 MOVE.b -(a3),d3 ADDX.b d3,d3 I1EC4: BCC I1ECE MOVE.b -(a3),d4 MOVEQ #3,d0 SUBQ.b #1,d4 BRA I1F08 I1ECE: ADD.b d3,d3 BNE I1ED6 MOVE.b -(a3),d3 ADDX.b d3,d3 I1ED6: ADDX.b d4,d4 ADD.b d3,d3 BNE I1EE0 MOVE.b -(a3),d3 ADDX.b d3,d3 I1EE0: ADDX.b d4,d4 ADD.b d3,d3 BNE I1EEA MOVE.b -(a3),d3 ADDX.b d3,d3 I1EEA: ADDX.b d4,d4 ADDQ.b #5,d4 MOVEQ #3,d0 BRA I1F08 I1EF2: MOVEQ #4,d4 MOVEQ #3,d0 BRA I1F08 I1EF8: MOVEQ #3,d4 MOVEQ #2,d0 BRA I1F08 I1EFE: MOVEQ #2,d4 MOVEQ #1,d0 BRA I1F08 I1F04: MOVEQ #1,d4 MOVEQ #0,d0 I1F08: MOVEQ #0,d5 MOVE.w d0,d1 ADD.b d3,d3 BNE I1F14 MOVE.b -(a3),d3 ADDX.b d3,d3 I1F14: BCC I1F2C ADD.b d3,d3 BNE I1F1E MOVE.b -(a3),d3 ADDX.b d3,d3 I1F1E: BCC I1F28 MOVE.b I1F8C(pc,d0.w),d5 ADDQ.b #8,d0 BRA I1F2C I1F28: MOVEQ #2,d5 ADDQ.b #4,d0 I1F2C: MOVE.b I1F90(pc,d0.w),d0 I1F30: ADD.b d3,d3 BNE I1F38 MOVE.b -(a3),d3 ADDX.b d3,d3 I1F38: ADDX.w d2,d2 SUBQ.b #1,d0 BNE I1F30 ADD.w d5,d2 MOVEQ #0,d5 MOVE.l d5,a2 MOVE.w d1,d0 ADD.b d3,d3 BNE I1F4E MOVE.b -(a3),d3 ADDX.b d3,d3 I1F4E: BCC I1F6A ADD.w d1,d1 ADD.b d3,d3 BNE I1F5A MOVE.b -(a3),d3 ADDX.b d3,d3 I1F5A: BCC I1F64 MOVE.w 8(a1,d1.w),a2 ADDQ.b #8,d0 BRA I1F6A I1F64: MOVE.w 0(a1,d1.w),a2 ADDQ.b #4,d0 I1F6A: MOVE.b $10(a1,d0.w),d0 I1F6E: ADD.b d3,d3 BNE I1F76 MOVE.b -(a3),d3 ADDX.b d3,d3 I1F76: ADDX.l d5,d5 SUBQ.b #1,d0 BNE I1F6E ADDQ.w #1,a2 ADD.l d5,a2 ADD.l a4,a2 I1F82: MOVE.b -(a2),-(a4) DBF d4,I1F82 BRA I1E70 I1F8C: Dc.l $60A0A12 I1F90: Dc.l $1010101 Dc.l $2030304 Dc.l $405070E ;***------------------------------------------------------------------------ ;*** This is the ultimate Data-Decrunch-Routine ;*** For Crunch-Mania V1.7 ;*** (c) 1991, 92 by -;> Thomas Schwarz <+-, all rights reserved ;*** You may Use this piece of code as long as you don't claim that ;*** you have written it. In any Case the author (me) has To be ;*** mentioned someplace in your proggy. ;*** Note: Source- AND Destinationaddresses have To be always Even Addresses ;***------------------------------------------------------------------------ ;*** Here is the Format of the Header: ;*** Type Offset Contents Function ;*** LONG 0 "CrM!"/"CrM2" To recongnize crunched files ;*** WORD 4 Minimum Security Distance To savely decrunch Data when ;*** Source AND Dest is in the same ;*** Memoryblock ;*** LONG 6 Original Len Datalen before packing ;*** LONG 10 ($a) Crunched Len Datalen after packing without ;*** Header ;***------------------------------------------------------------------------ ;** Jump here To decrunch some Data with overlap check ;** You need some Memory directly in front of the Destination Area ;** which has To be as large as the MinSecDist ;** Load the Regs with: ;** a0: Adr of Source (with Header) ** a1: Adr of Dest ;**------------------------------------------------------------------------- ;Test = 0 ;set this to 1 to decrunch ram:Test ;*************************************************************************** ; ifne Test _crm: MOVE.l d0,a0 MOVE.l d0,a1 ; MOVE.l d0,_Data ; LEA _Data(pc),a0 ; LEA 14(a0),a1 ; BRA NormalDecrunch ; endc ;*----------- OverlapDecrunch: MOVEM.l d0-d7/a0-a6,-(a7) LEA FastDecruncher(pc),a5 MOVE.l (a0)+,d0 CMP.l #"CrM!",d0 BEQ.b decr LEA LZHDecruncher(pc),a5 CMP.l #"CrM2",d0 BNE.b NotCrunched decr: MOVEQ #0,d0 MOVE.w (a0)+,d0 ;MinSecDist MOVE.l (a0)+,d1 ;DestLen MOVE.l (a0)+,d2 ;SrcLen LEA 0(a0,d0.l),a2 CMP.l a1,a2 BLE.b NoCopy MOVE.l a0,a2 MOVE.l a1,a0 SUB.l d0,a0 ;MinSecDist abziehen MOVE.l a0,a3 MOVE.l d2,d7 LSR.l #2,d7 ;Longs CopyLoop: MOVE.l (a2)+,(a3)+ SUBQ.l #1,d7 BNE.b CopyLoop MOVE.l (a2)+,(a3)+ ;in case of ... NoCopy: MOVE.l a0,a2 JSR (a5) NotCrunched: MOVEM.l (a7)+,d0-d7/a0-a6 RTS ;**------------------------------------------------------------------------- ;** Jump here To decrunch some Data without any overlap checks ;** The Regs have To loaded with: ;** a0: Adr of Source (with Header) ;** a1: Adr of Dest ;**------------------------------------------------------------------------- NormalDecrunch: MOVEM.l d0-d7/a0-a6,-(a7) MOVE.l (a0)+,d0 LEA FastDecruncher(pc),a5 CMP.l #"CrM!",d0 BEQ.b decr2 LEA LZHDecruncher(pc),a5 CMP.l #"CrM2",d0 BNE.b NotCrunched2 decr2: TST.w (a0)+ ;skip MinSecDist MOVE.l (a0)+,d1 ;OrgLen MOVE.l (a0)+,d2 ;CrLen MOVE.l a0,a2 JSR (a5) NotCrunched2: MOVEM.l (a7)+,d0-d7/a0-a6 RTS ;**------------------------------------------------------------------------- ;** This is the pure Decrunch-Routine ;** The Registers have To be loaded with the following values: ;** a1: Adr of Destination (normal) ** a2: Adr of Source (packed) ;** d1: Len of Destination ** d2: Len of Source ;** Leave everything below this Line in its original state! ;**------------------------------------------------------------------------- FastDecruncher: MOVE.l a1,a5 ;Decrunched Anfang (hier Ende des Decrunchens) ADD.l d1,a1 ADD.l d2,a2 MOVE.w -(a2),d0 ;Anz Bits in letztem Wort MOVE.l -(a2),d6 ;1.LW MOVEQ #16,d7 ;Anz Bits SUB.w d0,d7 ;Anz Bits, die rotiert werden m|ssen LSR.l d7,d6 ;1.Bits an Anfang bringen MOVE.w d0,d7 ;Anz Bits, die noch im Wort sind MOVEQ #16,d3 MOVEQ #0,d4 DecrLoop: CMP.l a5,a1 BLE.l DecrEnd ;a1=a5: fertig (a1d0:Bits MOVE.w d6,d0 ;d6:Akt Wort LSR.l d1,d6 ;ndchste Bits nach vorne bringen SUB.w d1,d7 ;d7:Anz Bits, die noch im Wort sind BGT.b GBNoLoop ; add.w #16,d7 ;BitCounter korrigieren ADD.w d3,d7 ;BitCounter korrigieren ROR.l d7,d6 ;restliche Bits re rausschieben MOVE.w -(a2),d6 ;ndchstes Wort holen ROL.l d7,d6 ;und zur|ckrotieren GBNoLoop: ADD.w d1,d1 ;*2 (in Tab sind Ws) AND.w AndData-2(pc,d1.w),d0 ;unerw|nschte Bits rausschmei_en RTS ;*---------- AndData: Dc.w %1,%11,%111,%1111,%11111,%111111,%1111111 Dc.w %11111111,%111111111,%1111111111 Dc.w %11111111111,%111111111111 Dc.w %1111111111111,%11111111111111 ;*----------- DecrEnd: RTS ;a5: Start of decrunched Data ;*************************************************************************** OCmpTab = 0 OAddTab = 64 ORealTab = 128 OAnzPerBits = 1182 OBufLen = 1246+2 ;****************************** LZHDecruncher: LEA Tabbs+2(pc),a6 ; addq.l #2,a6 ADD.l d1,a1 ADD.l d2,a2 MOVE.w -(a2),d0 ;Anz Bits in letztem Wort MOVE.l -(a2),d6 ;1.LW MOVEQ #16,d7 ;Anz Bits SUB.w d0,d7 ;Anz Bits, die rotiert werden m|ssen LSR.l d7,d6 ;1.Bits an Anfang bringen MOVE.w d0,d7 ;Anz Bits, die noch im Wort sind MOVEQ #16,d3 BufLoop: LEA OAnzPerBits(a6),a0 MOVEQ #16-1,d2 clear: CLR.l (a0)+ DBF d2,clear LEA OAnzPerBits+32(a6),a0 LEA ORealTab+30(a6),a4 MOVEQ #9,d2 BSR ReadTab LEA OAnzPerBits(a6),a0 LEA ORealTab(a6),a4 MOVEQ #4,d2 BSR ReadTab LEA OAnzPerBits+32(a6),a3 LEA OCmpTab-2(a6),a4 BSR CalcCmpTab LEA OAnzPerBits(a6),a3 LEA OCmpTab+30(a6),a4 BSR CalcCmpTab MOVEQ #16,d1 BSR GetBits2 MOVE.w d0,d5 LEA ORealTab+30(a6),a0 LEA -30(a0),a5 decrloop2: ;** tabu: d3/d6/d7/a0-a2/a4 MOVE.l a6,a4 BSR ReadIt BTST #8,d0 BNE.b skip MOVE.w d0,d4 LEA OCmpTab+32(a6),a4 EXG a0,a5 BSR ReadIt EXG a0,a5 MOVE.w d0,d1 MOVE.w d0,d2 BNE.b sc1 MOVEQ #1,d1 MOVEQ #16,d2 sc1: BSR GetBits2 BSET d2,d0 sc2: LEA 1(a1,d0.w),a3 sloop: MOVE.b -(a3),-(a1) DBF d4,sloop MOVE.b -(a3),-(a1) MOVE.b -(a3),d0 skip: MOVE.b d0,-(a1) DBF d5,decrloop2 MOVEQ #1,d1 BSR GetBits2 BNE.w BufLoop BRA LZHDecrEnd ;*-----------******************* ReadIt: MOVEQ #0,d1 ;Nr Byte RIloop: SUBQ.w #1,d7 BEQ.b BTLoop LSR.l #1,d6 ;Bit rausschieben und Flags setzen BRA BTEnd BTLoop: MOVEQ #16,d7 ;hier kein add notwendig: d7 vorher 0 MOVE.w d6,d0 LSR.l #1,d6 ;Bit rausschieben und Flags setzen SWAP d6 ;ror.l #16,d6 MOVE.w -(a2),d6 ;ndchstes Wort holen SWAP d6 ;rol.l #16,d6 LSR.w #1,d0 ;Bit rausschieben und Flags setzen BTEnd: ROXL.w #1,d1 MOVE.w (a4)+,d0 CMP.w d1,d0 BLS.b RIloop ADD.w 62(a4),d1 ADD.w d1,d1 MOVE.w 0(a0,d1.w),d0 RTS ;*------------------------------------- GetBits2: ;d1:AnzBits->d0:Bits MOVE.w d6,d0 ;d6:Akt Wort LSR.l d1,d6 ;ndchste Bits nach vorne bringen SUB.w d1,d7 ;d7:Anz Bits, die noch im Wort sind BGT.b GBNoLoop2 ADD.w d3,d7 ;BitCounter korrigieren ROR.l d7,d6 ;restliche Bits re rausschieben MOVE.w -(a2),d6 ;ndchstes Wort holen ROL.l d7,d6 ;und zur|ckrotieren GBNoLoop2: ADD.w d1,d1 ;*2 (in Tab sind Ws) AND.w AndData2-2(pc,d1.w),d0 ;unerw|nschte Bits rausschmei_en RTS ;*---------- AndData2: Dc.w %1,%11,%111,%1111,%11111,%111111,%1111111 Dc.w %11111111,%111111111,%1111111111 Dc.w %11111111111,%111111111111 Dc.w %1111111111111,%11111111111111 Dc.w %111111111111111,%1111111111111111 ;*--------------------------------------- ReadTab: MOVEM.l d1-d5/a3,-(a7) MOVEQ #4,d1 BSR GetBits2 ;Anz AnzPerBits MOVE.w d0,d5 SUBQ.w #1,d5 MOVEQ #0,d4 SUB.l a3,a3 RTlop: ADDQ.w #1,d4 MOVE.w d4,d1 CMP.w d2,d1 BLE.b c1 MOVE.w d2,d1 c1: BSR GetBits2 MOVE.w d0,(a0)+ ADD.w d0,a3 DBF d5,RTlop MOVE.w a3,d5 SUBQ.w #1,d5 RTlp2: MOVE.w d2,d1 BSR GetBits2 MOVE.w d0,(a4)+ DBF d5,RTlp2 MOVEM.l (a7)+,d1-d5/a3 RTS ;************************************************************** CalcCmpTab: MOVEM.l d0-d7,-(a7) CLR.w (a4)+ MOVEQ #15-1,d7 MOVEQ #-1,d4 MOVEQ #0,d2 MOVEQ #0,d3 MOVEQ #1,d1 CClop: MOVE.w (a3)+,d6 MOVE.w d3,64(a4) MOVE.w -2(a4),d0 ADD.w d0,d0 SUB.w d0,64(a4) ADD.w d6,d3 MULU d1,d6 ADD.w d6,d2 MOVE.w d2,(a4)+ cont2: LSL.w #1,d2 DBF d7,CClop MOVEM.l (a7)+,d0-d7 RTS ;********************************************* LZHDecrEnd: ;LZHDecrLen equ *-LZHDecruncher RTS ;*********************************** Tabbs: Dc.w 0 ;unbedingt!!!!!!! CmpTab: Ds.w 16 ;Len Ds.w 16 ;Dist AddTab: Ds.w 16 ;Len Ds.w 16 ;Dist RealTab: Ds.w 527 ;Dist+Len AnzPerBits: Ds.w 32 ;Dist+Len ;*************************************************************************** ;** Leave everything above this Line in its original state! ; ifne Test _Data: Dc.l 0 ;IncBin work:decruncher.s ; Ds.l 10000 ; endc ;A0 : Start des gecr. Files ;A1 : Ende des gecr. Files ;A2 : Zieladresse an die decruncht werden soll _ppdecrunch: MOVEM.l d0-d7/a0-a6,-(a7) MOVE.l d0,a0 MOVE.l d1,a1 MOVE.l d2,a2 bsr dec MOVEM.l (a7)+,d0-d7/a0-a6 RTS dec: CMP.l #"PP20",(a0) BNE.b nopower LEA 4(a0),a5 ;Effiziens MOVE.l a1,a0 MOVE.l a2,a3 MOVEQ #3,d6 MOVEQ #7,d7 MOVEQ #1,d5 MOVE.l a3,a2 ; remember start of file MOVE.l -(a0),d1 ; get file length and empty bits TST.b d1 BEQ.b NoEmptyBits BSR ReadBit ; this will always get the next long (D5 = 1) SUBQ.b #1,d1 LSR.l d1,d5 ; get rid of empty bits NoEmptyBits: LSR.l #8,d1 ADD.l d1,a3 ; a3 = endfile LoopCheckCrunch: BSR ReadBit ; check if crunch or normal BCS.b CrunchedBytes NormalBytes: MOVEQ #0,d2 _Read2BitsRow: MOVEQ #1,d0 BSR ReadD1 ADD.w d1,d2 CMP.w d6,d1 BEQ.b _Read2BitsRow ReadNormalByte: MOVEQ #7,d0 BSR ReadD1 MOVE.b d1,-(a3) DBF d2,ReadNormalByte CMP.l a3,a2 BCS.b CrunchedBytes nopower:RTS ReadBit: LSR.l #1,d5 ; this will also set X if d5 becomes zero BEQ.b GetNextLong RTS GetNextLong: MOVE.l -(a0),d5 ROXR.l #1,d5 ; X-bit set by lsr above RTS ReadD1_SUB: SUBQ.w #1,d0 ReadD1: MOVEQ #0,d1 ReadBits: LSR.l #1,d5 ; this will also set X if d5 becomes zero BEQ.b GetNext RotX: ROXL.l #1,d1 DBF d0,ReadBits RTS GetNext: MOVE.l -(a0),d5 ROXR.l #1,d5 ; X-bit set by lsr above BRA RotX CrunchedBytes: MOVEQ #1,d0 BSR ReadD1 ; read code MOVEQ #0,d0 MOVE.b 0(a5,d1.w),d0 ; get number of bits of offset MOVE.w d1,d2 ; d2 = code = length-2 CMP.w d6,d2 ; if d2 = 3 check offset bit and read length BNE.b ReadOffset BSR ReadBit ; read offset bit (long/short) BCS.b LongBlockOffset MOVEQ #7,d0 LongBlockOffset: BSR ReadD1_SUB MOVE.w d1,d3 ; d3 = offset _Read3BitsRow: MOVEQ #2,d0 BSR ReadD1 ADD.w d1,d2 ; d2 = length-1 CMP.w d7,d1 ; cmp with #7 BEQ.b _Read3BitsRow BRA DecrunchBlock ReadOffset: BSR ReadD1_SUB ; read offset MOVE.w d1,d3 ; d3 = offset DecrunchBlock: ADDQ.w #1,d2 DecrunchBlockLoop: MOVE.b 0(a3,d3.w),-(a3) DBF d2,DecrunchBlockLoop EndOfLoop: CMP.l a3,a2 BCS.l LoopCheckCrunch RTS