home *** CD-ROM | disk | FTP | other *** search
/ Enigma Amiga Life 113 / EnigmaAmiga113CD.iso / software / sviluppo / xfd_developer / sources / asm / szdd.a < prev    next >
Encoding:
Text File  |  2000-06-27  |  3.8 KB  |  152 lines

  1. ; SZDD decruncher by Kyzer/CSG <kyzer@4u.net>
  2. ; $VER: SZDD.c 1.1 (19.06.2000)
  3. ; v1.1: better xfd name, eliminated 4k buffer
  4. ;
  5. ; based on "ms-expand" by Daniel Risacher <magnus@mit.edu> and someone else
  6. ; http://www.im.lcs.mit.edu/~magnus/ms-expand.c
  7. ;
  8. ; Header:
  9. ; 4 bytes : "SZDD"
  10. ; 4 bytes : $88,$F0,$27,$33
  11. ; 2 bytes : random value? (seen $41,$00 and $41,$39)
  12. ; 4 bytes : A,B,C,D. unpacked size of file is (D<<24)|(C<<16)|(B<<8)|(A)
  13. ; Compressed data format:
  14. ; - one header byte, whose bits from LSB (0) to MSB (7) dictate the format
  15. ;   of the next 8 elements
  16. ; - if a bit is set, the next element is a single byte literal
  17. ; - otherwise, the next element is a repeat: two bytes, %AAAAAAAA, %BBBBCCCC
  18. ;   where offset = %BBBBAAAAAAAA and length is %CCCC + 3
  19. ;
  20. ; A virtual 4096 byte wraparound window must be kept by the decruncher.
  21. ; A wraparound pointer starts at 4096-16 and each outputted byte must be
  22. ; written at that position and the pointer advanced by one. The buffer
  23. ; starts off filled with zeroes. The offsets of the compressed data refer
  24. ; to an absolute position in this buffer, which may be before the pointer,
  25. ; or after it.
  26. ;
  27. ; It seems that there can often be superfluous data at the end of a file -
  28. ; I can only go by the uncompressed size, so I can only really test running
  29. ; out of source data. Some files end in the middle of a run, so I can't
  30. ; test if they exactly reach the endpoint and no more.
  31.  
  32. SZDD_WNDSIZE=4096
  33. SZDD_WNDMASK=4095
  34. SZDD_MINLEN=14
  35. SZDD_OVERRUN=144
  36.  
  37.     include    exec/memory.i
  38.     include    libraries/xfdmaster.i
  39.     include    lvo/exec_lib.i
  40.  
  41.     IFD    TEST
  42.     include    xfdExeHead.a
  43.     ENDC
  44.  
  45. ForeMan    dc.l    $70FF4E75,XFDF_ID    ; id
  46.     dc.w    XFDF_VERSION        ; foreman version
  47.     dcb.w    5,0            ; reserved stuff
  48.     dc.l    SZDDslv            ; first slave
  49. SZDDslv    dc.l    0
  50.     dc.w    XFDS_VERSION,39
  51.     dc.l    SZDDnam
  52.     dc.w    XFDPFF_DATA!XFDPFF_RECOGLEN!XFDPFF_USERTARGET,0
  53.     dc.l    SZDD_recog,SZDD_decrunch,0,0
  54.     dc.l    0,SZDD_MINLEN
  55.  
  56. SZDD_recog
  57.     cmp.l    #"SZDD",(a0)
  58.     bne.s    .fail
  59.     move.l    10(a0),d0
  60.     rol.w    #8,d0
  61.     swap    d0
  62.     rol.w    #8,d0
  63.     move.l    d0,xfdrr_FinalTargetLen(a1)
  64.     add.l    #SZDD_OVERRUN,d0
  65.     move.l    d0,xfdrr_MinTargetLen(a1)
  66.     moveq    #1,d0            ; return success
  67.     rts
  68. .fail    moveq    #0,d0
  69.     rts
  70.  
  71. SZDD_decrunch
  72.     movem.l    d2-d7/a2-a6,-(sp)
  73.     move.l    a0,a4                ; a4 = BufferInfo
  74.  
  75.     move.l    xfdbi_SourceBuffer(a4),a0    ; a0 = src
  76.     move.l    a0,a2
  77.     adda.l    xfdbi_SourceBufLen(a4),a2    ; a2 = ends
  78.     adda.w    #14,a0
  79.     move.l    xfdbi_UserTargetBuf(a4),a1    ; a1 = dest
  80.     move.l    a1,a3
  81.     adda.l    xfdbi_TargetBufSaveLen(a4),a3    ; a3 = endd
  82.     move.l    a1,d3                ; d3 = start
  83.  
  84.     move.w    #SZDD_WNDSIZE-16,d7        ; d7 = posn
  85.     move.w    #SZDD_WNDMASK,d6        ; d6 = bufmask
  86.  
  87. .mainlp    move.b    (a0)+,d5            ; d5 = bits
  88.     moveq    #0,d4                ; d4 = mask
  89. .bitlp    btst.b    d4,d5
  90.     beq.s    .rep
  91.  
  92.     ; literal
  93.     move.b    (a0)+,(a1)+
  94.     addq.w    #1,d7
  95.     bra.s    .nxtbit
  96.  
  97. .rep    ; repeat
  98.     moveq    #0,d0
  99.     move.b    (a0)+,d0    ; d0 = offset
  100.     move.b    (a0)+,d1    ; d1 = length
  101.  
  102.     moveq    #0,d2
  103.     move.b    d1,d2
  104.     asl.w    #4,d2
  105.     move.b    #0,d2
  106.     or.w    d2,d0
  107.  
  108.     andi.w    #$f,d1
  109.     addq.b    #3,d1
  110.  
  111.     and.w    d6,d7
  112.     cmp.w    d0,d7
  113.     bhi.s    .noadd        ; if (offset <= posn) don't add WNDSIZE
  114.     add.w    #SZDD_WNDSIZE,d7; [or bset #12,d7 - but that's no shorter]
  115. .noadd    lea    (a1,d0.w),a5    ; a5 = rep, = dest+offset-posn
  116.     suba.w    d7,a5
  117.     add.w    d1,d7        ; posn += length
  118.  
  119. .clr    cmp.l    a5,d3        ; if rep >= base, don't do clearing
  120.     bcs.s    .noclr
  121.     clr.b    (a1)+        ; clear one byte
  122.     addq.l    #1,a5        ; rep++
  123.     subq.w    #1,d1        ; length--
  124.     beq.s    .nxtbit
  125.     bra.s    .clr
  126. .noclr    move.b    (a5)+,(a1)+    ; *dest++=*rep++
  127.     subq.w    #1,d1        ; while (length--)
  128.     bne.s    .noclr
  129.  
  130. .nxtbit    cmp.l    a1,a3        ; if dest >= endd, stop now
  131.     bcs.s    .done
  132.  
  133.     addq.l    #1,d4        ; next bit, from 0-7
  134.     cmp.b    #8,d4
  135.     bcs.s    .bitlp        ; if d4<8, goto .bitlp
  136.  
  137.     cmp.l    a0,a2
  138.     bcc.s    .mainlp        ; if src < ends, go back to main loop
  139.  
  140. .corupt    move.w    #XFDERR_CORRUPTEDDATA,xfdbi_Error(a4)
  141.     moveq    #0,d0
  142.     bra.s    .exit
  143. .done    clr.w    xfdbi_Error(a4)
  144.     moveq    #1,d0
  145. .exit    movem.l    (sp)+,d2-d7/a2-a6
  146.     rts
  147.  
  148.  
  149. SZDDnam    dc.b    '(SZDD) Microsoft Data Cruncher',0
  150.     dc.b    '$VER: SZDD 1.1 (19.06.2000) by <kyzer@4u.net>',0
  151.