***------------------------------------------------------------------------ *** This is the ultimate Data-Decrunch-Routine *** for Crunch-Mania V1.4 *** (c) 1991 by FRESH THRASH of CERBERUS, 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!" 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 **--------------------------------------------------------------- OverlapDecrunch: movem.l d0-d7/a0-a6,-(sp) cmp.l #"CrM!",(a0)+ bne.s .NotCrunched 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.s .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.s .CopyLoop move.l (a2)+,(a3)+ ;in case of ... .NoCopy: move.l a0,a2 bsr.s FastDecruncher .NotCrunched: movem.l (sp)+,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,-(sp) cmp.l #"CrM!",(a0)+ bne.s .NotCrunched tst.w (a0)+ ;skip MinSecDist move.l (a0)+,d1 ;OrgLen move.l (a0)+,d2 ;CrLen move.l a0,a2 bsr.s FastDecruncher .NotCrunched: movem.l (sp)+,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 **------------------------------------------------------------------- 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 ;nächste Bits nach vorne bringen sub.w d1,d7 ;d7:Anz Bits, die noch im Wort sind bgt.s .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 ;nächstes 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