***************************************************************************** * DataDecrunch d0 Destroyed! * --------------------------------------------------------------------------- * Checks for known data decrunchers then attempts to decrunch the data if * it recognises the cruncher it was compressed with. * * Please note that when unpacking "CrunchMania" data the DESTINATION can be * as little as 14 bytes infront of the SOURCE. Also note that only a SOURCE * ptr is required when exploding "Imploded" data, as source=destination. * * INPUTS ; a0=Source Packdata pointer a1=Destination Adr for Unpacked data * OUTPUTS; d0=If failed returns error code of -1 in d0 ***************************************************************************** XDEF _Decrunch _Decrunch: movem.l d1-d7/a0-a6,-(sp) ; save registers lea IDJmp(pc),a6 ; get ptr to ID`s Table move.l a6,a5 ; make copy of ptr move.l (a0),d1 ; source ID to check against search_id: cmpa.l (a5)+,d1 ; check an ID Entry from table beq.s CallIt ; found the correct ID? tst.w (a5)+ ; is this last entry in table? bne.s search_id ; if not.. keep searching... moveq #-1,d0 ; must be an unknown cruncher movem.l (sp)+,d1-d7/a0-a6 ; restore registers rts CallIt move.w (a5)+,d1 jsr (a6,d1.w) ; call decruncher routine movem.l (sp)+,d1-d7/a0-a6 ; restore registers rts IDJmp: dc.l "CrM2" ;00 - "CrunchMania LZHuffman" dc.w LZHuffman-IDJmp dc.l "CrM!" ;01 - "CrunchMania Normal" dc.w CrunchMania-IDJmp dc.l "IMP!" ;02 - "Imploder Data" dc.w Explode-IDJmp dc.l 0 ;ID - "End of table" CrunchMania addq.l #6,a0 ; skip min 2nd dist & header move.l (a0)+,d1 ; get Original Length (unpacked Size) move.l (a0)+,d2 ; get Crunched Length (packed Size) move.l a0,a2 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 mussen 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.w .DecrEnd ;a1=a5: fertig (a1d0:Bits d6:Akt Wort lsr.l d1,d6 ;nachste 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 ;nachstes Wort holen rol.l d7,d6 ;und zuruckrotieren .GBNoLoop: add.w d1,d1 ;*2 (in Tab sind Ws) and.w .AndData-2(pc,d1.w),d0 ;unerwunschte Bits rausschmeiBen rts .AndData: dc.w %1,%11,%111,%1111,%11111,%111111,%1111111 dc.w %11111111,%111111111,%1111111111 dc.w %11111111111,%111111111111 dc.w %1111111111111,%11111111111111 ******************************************************************************* * CrunchMania LZHuffman Decompression * ---------------------------------------------------------------------------- * INPUTS : a1 = Destination * a2 = Source ******************************************************************************* LZHuffman: move.l a0,a2 addq.l #6,a2 ;skip ID & Minimum 2nd distance move.l (a2)+,d1 ;original size move.l (a2)+,d2 ;packed length move.l a1,a5 ;Decrunched Anfang (hier Ende des Decrunchens) add.l d1,a1 add.l d2,a2 lea 2(a1),a6 move.w -(a2),d0 move.l -(a2),d6 moveq #$10,d7 sub.w d0,d7 lsr.l d7,d6 move.w d0,d7 moveq #$10,d3 lz2: lea $49E(a6),a0 move.l d2,(a0)+ move.l d2,(a0)+ move.l d2,(a0)+ move.l d2,(a0)+ move.l d2,(a0)+ move.l d2,(a0)+ move.l d2,(a0)+ move.l d2,(a0)+ move.l d2,(a0)+ move.l d2,(a0)+ move.l d2,(a0)+ move.l d2,(a0)+ move.l d2,(a0)+ move.l d2,(a0)+ move.l d2,(a0)+ move.l d2,(a0)+ lea $4BE(a6),a0 lea $9E(a6),a4 moveq #9,d2 bsr.w lz15 lea $49E(a6),a0 lea $80(a6),a4 moveq #4,d2 bsr.w lz15 lea $4BE(a6),a3 lea -2(a6),a4 bsr.w lz19 lea $49E(a6),a3 lea $1E(a6),a4 bsr.w lz19 moveq #$10,d1 bsr.s lz12 move.w d0,d5 lea $9E(a6),a0 lea -$1E(a0),a5 lz4: move.l a6,a4 bsr.s lz8 btst #8,d0 bne.s lz7 move.w d0,d4 lea $20(a6),a4 exg a0,a5 bsr.s lz8 exg a0,a5 move.w d0,d1 move.w d0,d2 bne.s lz5 moveq #1,d1 moveq #$10,d2 lz5: bsr.s lz12 bset d2,d0 lea 1(a1,d0.w),a3 lz6: move.b -(a3),-(a1) dbra d4,lz6 move.b -(a3),-(a1) move.b -(a3),d0 lz7: move.b d0,-(a1) dbra d5,lz4 moveq #1,d1 bsr.s lz12 bne.w lz2 rts ;all done.. exit here! lz8: moveq #0,d1 lz9: subq.w #1,d7 beq.s lz10 lsr.l #1,d6 bra.s lz11 lz10: moveq #$10,d7 move.w d6,d0 lsr.l #1,d6 swap d6 move.w -(a2),d6 swap d6 lsr.w #1,d0 lz11: addx.w d1,d1 move.w (a4)+,d0 cmp.w d1,d0 bls.s lz9 add.w $3E(a4),d1 add.w d1,d1 move.w (a0,d1.w),d0 rts lz12: move.w d6,d0 lsr.l d1,d6 sub.w d1,d7 bgt.s lz13 add.w d3,d7 ror.l d7,d6 move.w -(a2),d6 rol.l d7,d6 lz13: add.w d1,d1 and.w .AndData-2(pc,d1.w),d0 rts .AndData: 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 lz15: movem.l d1-d5/a3,-(sp) moveq #4,d1 bsr.s lz12 move.w d0,d5 subq.w #1,d5 moveq #0,d4 sub.l a3,a3 lz16: addq.w #1,d4 move.w d4,d1 cmp.w d2,d1 ble.s lz17 move.w d2,d1 lz17: bsr.s lz12 move.w d0,(a0)+ add.w d0,a3 dbra d5,lz16 move.w a3,d5 subq.w #1,d5 lz18: move.w d2,d1 bsr.s lz12 move.w d0,(a4)+ dbra d5,lz18 movem.l (sp)+,d1-d5/a3 rts lz19: movem.l d0-d7,-(sp) moveq #14,d7 moveq #-1,d4 moveq #0,d2 move.l d2,d3 moveq #1,d1 move.w d2,(a4)+ lz20: move.w (a3)+,d6 move.w d3,$40(a4) move.w -2(a4),d0 add.w d0,d0 sub.w d0,$40(a4) add.w d6,d3 mulu d1,d6 add.w d6,d2 move.w d2,(a4)+ add.w d2,d2 dbra d7,lz20 movem.l (sp)+,d0-d7 rts ; ; explode: ; ; In: a0.l=*buffer ; Out: d0.l=0:Error; -1:Ok ; Explode: movem.l d2-d5/a2-a4,-(sp) 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.s ex00 subq.l #1,a3 ex00: lea -28(sp),sp move.l sp,a1 moveq #6,d0 ex01: move.l (a2)+,(a1)+ dbf d0,ex01 move.l sp,a1 moveq #0,d4 ex02: tst.l d2 beq.s ex04 ex03: move.b -(a3),-(a4) subq.l #1,d2 bne.s ex03 ex04: cmp.l a4,a0 blo.s ex07 lea 28(sp),sp moveq #-1,d0 cmp.l a3,a0 beq.s ex06 ex05: moveq #0,d0 ex06: movem.l (sp)+,d2-d5/a2-a4 tst.l d0 rts ex07: add.b d3,d3 bne.s ex08 move.b -(a3),d3 addx.b d3,d3 ex08: bcc.s ex20 add.b d3,d3 bne.s ex09 move.b -(a3),d3 addx.b d3,d3 ex09: bcc.s ex19 add.b d3,d3 bne.s ex10 move.b -(a3),d3 addx.b d3,d3 ex10: bcc.s ex18 add.b d3,d3 bne.s ex11 move.b -(a3),d3 addx.b d3,d3 ex11: bcc.s ex17 add.b d3,d3 bne.s ex12 move.b -(a3),d3 addx.b d3,d3 ex12: bcc.s ex13 move.b -(a3),d4 moveq #3,d0 bra.s ex21 ex13: add.b d3,d3 bne.s ex14 move.b -(a3),d3 addx.b d3,d3 ex14: addx.b d4,d4 add.b d3,d3 bne.s ex15 move.b -(a3),d3 addx.b d3,d3 ex15: addx.b d4,d4 add.b d3,d3 bne.s ex16 move.b -(a3),d3 addx.b d3,d3 ex16: addx.b d4,d4 addq.b #6,d4 moveq #3,d0 bra.s ex21 ex17: moveq #5,d4 moveq #3,d0 bra.s ex21 ex18: moveq #4,d4 moveq #2,d0 bra.s ex21 ex19: moveq #3,d4 moveq #1,d0 bra.s ex21 ex20: moveq #2,d4 moveq #0,d0 ex21: moveq #0,d5 move.w d0,d1 add.b d3,d3 bne.s ex22 move.b -(a3),d3 addx.b d3,d3 ex22: bcc.s ex25 add.b d3,d3 bne.s ex23 move.b -(a3),d3 addx.b d3,d3 ex23: bcc.s ex24 move.b extab0(pc,d0.w),d5 addq.b #8,d0 bra.s ex25 ex24: moveq #2,d5 addq.b #4,d0 ex25: move.b extab1(pc,d0.w),d0 ex26: add.b d3,d3 bne.s ex27 move.b -(a3),d3 addx.b d3,d3 ex27: addx.w d2,d2 subq.b #1,d0 bne.s ex26 add.w d5,d2 moveq #0,d5 move.l d5,a2 move.w d1,d0 add.b d3,d3 bne.s ex28 move.b -(a3),d3 addx.b d3,d3 ex28: bcc.s ex31 add.w d1,d1 add.b d3,d3 bne.s ex29 move.b -(a3),d3 addx.b d3,d3 ex29: bcc.s ex30 move.w 8(a1,d1.w),a2 addq.b #8,d0 bra.s ex31 ex30: move.w 0(a1,d1.w),a2 addq.b #4,d0 ex31: move.b $10(a1,d0.w),d0 ex32: add.b d3,d3 bne.s ex33 move.b -(a3),d3 addx.b d3,d3 ex33: addx.l d5,d5 subq.b #1,d0 bne.s ex32 addq.w #1,a2 add.l d5,a2 add.l a4,a2 ex34: move.b -(a2),-(a4) subq.b #1,d4 bne.s ex34 bra ex02 extab0: dc.l $60A0A12 extab1: dc.l $1010101,$2030304,$405070E .