home *** CD-ROM | disk | FTP | other *** search
- ; SZDD decruncher by Kyzer/CSG <kyzer@4u.net>
- ; $VER: SZDD.c 1.1 (19.06.2000)
- ; v1.1: better xfd name, eliminated 4k buffer
- ;
- ; based on "ms-expand" by Daniel Risacher <magnus@mit.edu> and someone else
- ; http://www.im.lcs.mit.edu/~magnus/ms-expand.c
- ;
- ; Header:
- ; 4 bytes : "SZDD"
- ; 4 bytes : $88,$F0,$27,$33
- ; 2 bytes : random value? (seen $41,$00 and $41,$39)
- ; 4 bytes : A,B,C,D. unpacked size of file is (D<<24)|(C<<16)|(B<<8)|(A)
- ;
- ; Compressed data format:
- ; - one header byte, whose bits from LSB (0) to MSB (7) dictate the format
- ; of the next 8 elements
- ; - if a bit is set, the next element is a single byte literal
- ; - otherwise, the next element is a repeat: two bytes, %AAAAAAAA, %BBBBCCCC
- ; where offset = %BBBBAAAAAAAA and length is %CCCC + 3
- ;
- ; A virtual 4096 byte wraparound window must be kept by the decruncher.
- ; A wraparound pointer starts at 4096-16 and each outputted byte must be
- ; written at that position and the pointer advanced by one. The buffer
- ; starts off filled with zeroes. The offsets of the compressed data refer
- ; to an absolute position in this buffer, which may be before the pointer,
- ; or after it.
- ;
- ; It seems that there can often be superfluous data at the end of a file -
- ; I can only go by the uncompressed size, so I can only really test running
- ; out of source data. Some files end in the middle of a run, so I can't
- ; test if they exactly reach the endpoint and no more.
-
- SZDD_WNDSIZE=4096
- SZDD_WNDMASK=4095
- SZDD_MINLEN=14
- SZDD_OVERRUN=144
-
- include exec/memory.i
- include libraries/xfdmaster.i
- include lvo/exec_lib.i
-
- IFD TEST
- include xfdExeHead.a
- ENDC
-
- ForeMan dc.l $70FF4E75,XFDF_ID ; id
- dc.w XFDF_VERSION ; foreman version
- dcb.w 5,0 ; reserved stuff
- dc.l SZDDslv ; first slave
- SZDDslv dc.l 0
- dc.w XFDS_VERSION,39
- dc.l SZDDnam
- dc.w XFDPFF_DATA!XFDPFF_RECOGLEN!XFDPFF_USERTARGET,0
- dc.l SZDD_recog,SZDD_decrunch,0,0
- dc.l 0,SZDD_MINLEN
-
- SZDD_recog
- cmp.l #"SZDD",(a0)
- bne.s .fail
- move.l 10(a0),d0
- rol.w #8,d0
- swap d0
- rol.w #8,d0
- move.l d0,xfdrr_FinalTargetLen(a1)
- add.l #SZDD_OVERRUN,d0
- move.l d0,xfdrr_MinTargetLen(a1)
- moveq #1,d0 ; return success
- rts
- .fail moveq #0,d0
- rts
-
- SZDD_decrunch
- movem.l d2-d7/a2-a6,-(sp)
- move.l a0,a4 ; a4 = BufferInfo
-
- move.l xfdbi_SourceBuffer(a4),a0 ; a0 = src
- move.l a0,a2
- adda.l xfdbi_SourceBufLen(a4),a2 ; a2 = ends
- adda.w #14,a0
- move.l xfdbi_UserTargetBuf(a4),a1 ; a1 = dest
- move.l a1,a3
- adda.l xfdbi_TargetBufSaveLen(a4),a3 ; a3 = endd
- move.l a1,d3 ; d3 = start
-
- move.w #SZDD_WNDSIZE-16,d7 ; d7 = posn
- move.w #SZDD_WNDMASK,d6 ; d6 = bufmask
-
- .mainlp move.b (a0)+,d5 ; d5 = bits
- moveq #0,d4 ; d4 = mask
- .bitlp btst.b d4,d5
- beq.s .rep
-
- ; literal
- move.b (a0)+,(a1)+
- addq.w #1,d7
- bra.s .nxtbit
-
- .rep ; repeat
- moveq #0,d0
- move.b (a0)+,d0 ; d0 = offset
- move.b (a0)+,d1 ; d1 = length
-
- moveq #0,d2
- move.b d1,d2
- asl.w #4,d2
- move.b #0,d2
- or.w d2,d0
-
- andi.w #$f,d1
- addq.b #3,d1
-
- and.w d6,d7
- cmp.w d0,d7
- bhi.s .noadd ; if (offset <= posn) don't add WNDSIZE
- add.w #SZDD_WNDSIZE,d7; [or bset #12,d7 - but that's no shorter]
- .noadd lea (a1,d0.w),a5 ; a5 = rep, = dest+offset-posn
- suba.w d7,a5
- add.w d1,d7 ; posn += length
-
- .clr cmp.l a5,d3 ; if rep >= base, don't do clearing
- bcs.s .noclr
- clr.b (a1)+ ; clear one byte
- addq.l #1,a5 ; rep++
- subq.w #1,d1 ; length--
- beq.s .nxtbit
- bra.s .clr
- .noclr move.b (a5)+,(a1)+ ; *dest++=*rep++
- subq.w #1,d1 ; while (length--)
- bne.s .noclr
-
- .nxtbit cmp.l a1,a3 ; if dest >= endd, stop now
- bcs.s .done
-
- addq.l #1,d4 ; next bit, from 0-7
- cmp.b #8,d4
- bcs.s .bitlp ; if d4<8, goto .bitlp
-
- cmp.l a0,a2
- bcc.s .mainlp ; if src < ends, go back to main loop
-
- .corupt move.w #XFDERR_CORRUPTEDDATA,xfdbi_Error(a4)
- moveq #0,d0
- bra.s .exit
- .done clr.w xfdbi_Error(a4)
- moveq #1,d0
- .exit movem.l (sp)+,d2-d7/a2-a6
- rts
-
-
- SZDDnam dc.b '(SZDD) Microsoft Data Cruncher',0
- dc.b '$VER: SZDD 1.1 (19.06.2000) by <kyzer@4u.net>',0
-