******************************************************* ** XFD external decruncher for Chryseis Cruncher ** ** written and © 1994 by Georg Hörmann ** ******************************************************* OUTPUT "LIBS:xfd/Chryseis" SECTION Chryseis,CODE INCDIR "dh0:Include_Asm" ;change this as you need it INCLUDE "dh0:xfd/xfdmaster.i" ; xfdForeman structure MUST be first thing in all external decrunchers F_Chryseis moveq #-1,d0 ;security rts dc.l XFDF_ID ;id dc.w 1 ;version dc.w 0 dc.l 0,0 ;private dc.l S_Chryseis09 ;first slave ************************************************** ; xfdSlave structure: this one doesn't support segment decrunching S_Chryseis09 dc.l 0 ;no more slaves dc.w 1 ;version dc.w 33 ;master version dc.l N_Chryseis09 ;name dc.w XFDPFF_RELOC ;flags dc.w 0 dc.l RB_Chryseis09 ;recog buffer dc.l DB_Chryseis09 ;decrunch buffer dc.l 0 ;recog segment dc.l 0 ;decrunch segment N_Chryseis09 dc.b 'Chryseis Cruncher 0.9',0 even ;------------------------------------------------- ; Recog buffer function: receives buffer + length in a0/d0 RB_Chryseis09 cmp.l #$4bc+32,d0 ;min. file length for header and data ble.s .Exit cmp.w #$abcd,$2a(a0) ;some more verification bne.s .Exit cmp.w #$03f6,$4ba(a0) bne.s .Exit cmp.l #$208f205f,$42(a0) bne.s .Exit cmp.l #$4eba01c8,$46(a0) bne.s .Exit cmp.l #$49fa025c,$214(a0) bne.s .Exit moveq #1,d0 rts .Exit moveq #0,d0 rts ;------------------------------------------------- ;Decrunch buffer function: receives bufferinfo in a0 DB_Chryseis09 movem.l d2-d7/a2-a6,-(a7) move.l a0,a5 move.l xfdbi_SourceBuffer(a5),a2 ; first of all, we calculate the length of the decrunched file moveq #20,d2 ;3f3,0,x,0,x-1 lea $4bc(a2),a0 move.l (a0),d0 move.l d0,d3 ;amount hunks lsl.l #2,d0 add.l d0,d2 ;hunklens lea 12(a0,d0.l),a0 .CountAgain addq.l #8,d2 ;3ex,x move.w (a0)+,d0 move.w (a0)+,d1 cmp.w #$3eb,d1 bne.s .CountNoBSS addq.w #4,a0 bra.s .CountReloc .CountNoBSS and.w #$0fff,d0 beq.s .CountUncr move.l (a0),d0 add.l d0,a0 move.l (a0)+,d0 lsr.l #8,d0 add.l d0,d2 ;uncr hunklen bra.s .CountReloc .CountUncr move.l (a0)+,d0 add.l d0,d2 add.l d0,a0 .CountReloc addq.l #4,d2 ;end|reloc cmp.l #$3f2,(a0)+ beq.s .CountEnd .CountNextRel addq.l #4,d2 move.l (a0)+,d0 beq.s .CountReloc addq.l #1,d0 lsl.l #2,d0 add.l d0,d2 add.l d0,a0 bra.s .CountNextRel .CountEnd subq.l #1,d3 bne.s .CountAgain ; now we have the desired length and allocate the buffer move.l d2,d0 move.l d0,xfdbi_TargetBufSaveLen(a5) move.l d0,xfdbi_TargetBufLen(a5) move.l xfdbi_TargetBufMemType(a5),d1 move.l 4.w,a6 jsr -198(a6) move.w #XFDERR_NOMEMORY,xfdbi_Error(a5) move.l d0,xfdbi_TargetBuffer(a5) beq .Exit ; let's fill the buffer move.l d0,a3 move.l #$3f3,(a3)+ clr.l (a3)+ lea $4bc(a2),a2 move.l (a2),d0 move.l d0,d3 addq.w #3-1,d0 .CopyHeader move.l (a2)+,(a3)+ dbf d0,.CopyHeader .CopyAgain move.w (a2)+,d0 move.w (a2)+,d1 clr.w (a3)+ move.w d1,(a3)+ cmp.w #$3eb,d1 bne.s .NoBSS move.l (a2)+,d0 lsr.l #2,d0 move.l d0,(a3)+ bra.s .CopyReloc .NoBSS and.w #$0fff,d0 beq.s .CopyUncr move.l (a2),d1 add.l d1,a2 move.l (a2)+,d1 lsr.l #8,d1 lsr.l #2,d1 move.l d1,(a3)+ move.l a2,a0 move.l a3,a1 lsl.l #2,d1 add.l d1,a3 lsl.w #2,d0 move.l a2,-(a7) lea .EffTable-4(pc),a2 add.w d0,a2 bsr D_Chryseis move.l (a7)+,a2 bra.s .CopyReloc .CopyUncr move.l (a2)+,d0 lsr.l #2,d0 move.l d0,(a3)+ .CopyUncr1 move.l (a2)+,(a3)+ subq.l #1,d0 bne.s .CopyUncr1 .CopyReloc move.l (a2)+,d0 move.l d0,(a3)+ cmp.w #$3f2,d0 beq.s .CopyEnd .CopyNextRel move.l (a2)+,d0 move.l d0,(a3)+ beq.s .CopyReloc addq.l #1,d0 .CopyEntries move.l (a2)+,(a3)+ subq.l #1,d0 bne.s .CopyEntries bra.s .CopyNextRel .CopyEnd subq.l #1,d3 bne.s .CopyAgain ; successful exit moveq #1,d0 .Exit movem.l (a7)+,d2-d7/a2-a6 rts .EffTable dc.b 9,9,9,9 dc.b 9,10,10,10 dc.b 9,10,11,11 dc.b 9,10,12,12 dc.b 9,10,12,13 ************************************************** D_Chryseis movem.l d2-d5/a2/a3,-(a7) moveq #-1,d4 moveq #1,d5 move.l a1,a3 move.l -(a0),d1 tst.b d1 beq.s .Decr1 bsr.s .Decr5 subq.b #1,d1 lsr.l d1,d5 .Decr1 lsr.l #8,d1 add.l d1,a1 .Decr2 bsr.s .Decr5 bcs.s .Decr11 moveq #0,d2 .Decr3 moveq #1,d0 bsr.s .Decr8 add.w d1,d2 subq.w #3,d1 beq.s .Decr3 .Decr4 moveq #7,d0 bsr.s .Decr8 move.b d1,-(a1) cmp.l a3,a1 ; modified for dbeq d2,.Decr4 ; perfect error cmp.w d4,d2 ; detection beq.s .Decr11 bra.s .Decr17 .Decr5 lsr.l #1,d5 beq.s .Decr6 rts .Decr6 move.l -(a0),d5 roxr.l #1,d5 rts .Decr7 subq.w #1,d0 .Decr8 moveq #0,d1 .Decr9 lsr.l #1,d5 bne.s .Decr10 move.l -(a0),d5 roxr.l #1,d5 .Decr10 roxl.l #1,d1 dbra d0,.Decr9 rts .Decr11 moveq #1,d0 bsr.s .Decr8 moveq #0,d0 move.b (a2,d1.w),d0 move.w d1,d2 subq.w #3,d1 bne.s .Decr14 bsr.s .Decr5 bcs.s .Decr12 moveq #7,d0 .Decr12 bsr.s .Decr7 move.w d1,d3 .Decr13 moveq #2,d0 bsr.s .Decr8 add.w d1,d2 subq.w #7,d1 beq.s .Decr13 bra.s .Decr15 .Decr14 bsr.s .Decr7 move.w d1,d3 .Decr15 addq.w #1,d2 .Decr16 move.b (a1,d3.w),-(a1) cmp.l a3,a1 ; modified dbeq d2,.Decr16 ; for perfect cmp.w d4,d2 ; error detection beq.s .Decr2 .Decr17 movem.l (a7)+,d2-d5/a2/a3 rts END