home *** CD-ROM | disk | FTP | other *** search
/ Magazyn Amiga Shareware Floppies / ma54.dms / ma54.adf / xpkFAST_V1_03 / compress2.s < prev    next >
Text File  |  1993-10-17  |  6KB  |  275 lines

  1.     XDEF    compress_slow
  2.  
  3. ;On entry:
  4. ;    a0 = InBuf
  5. ;    a1 = OutBuf
  6. ;    a2 = HashTab
  7. ;    d0 = InLen
  8.  
  9.     CODE
  10.  
  11. COMPRESSREGS    reg    a3-a6/d1-d7
  12. compress_slow:
  13.     movem.l COMPRESSREGS,-(sp)
  14.     move.l    a0,d1        ; d1=src+src_len+2
  15.     add.l    d0,d1        ; since all srcpointers are
  16.     addq.l    #2,d1        ; 2 to big we need this +2 !
  17.  
  18.     moveq.l #$FFFFFFFC,d2
  19.     and.l    d0,d2
  20.     add.l    a1,d2
  21.     move.l    d2,a4        ; a4=dst+(src_len & ~3)
  22.  
  23.     movem.l a1/a4,-(sp)     ; save dst and dst_end for later use
  24.  
  25. ;;;    lea    $40000(a2),a6   ; a6=hh a6-$40000 == hash
  26.     moveq.l #4,d0
  27.     swap    d0
  28.     move.l    a2,a6
  29.     add.l    d0,a6
  30.  
  31.     moveq.l #0,d0
  32.     move.w    #$10FF,d2
  33. hfill:    move.l    d0,(a2)+        ; fill hash with $00000000
  34.     move.l    d0,(a2)+        ; hash is $1100*$10 = $11000 longs big
  35.     move.l    d0,(a2)+
  36.     move.l    d0,(a2)+
  37.     move.l    d0,(a2)+
  38.     move.l    d0,(a2)+
  39.     move.l    d0,(a2)+
  40.     move.l    d0,(a2)+
  41.     move.l    d0,(a2)+
  42.     move.l    d0,(a2)+
  43.     move.l    d0,(a2)+
  44.     move.l    d0,(a2)+
  45.     move.l    d0,(a2)+
  46.     move.l    d0,(a2)+
  47.     move.l    d0,(a2)+
  48.     move.l    d0,(a2)+
  49.     dbra    d2,hfill
  50.  
  51.     moveq.l #-1,d0        ; d0 = 4*hash_fkt(s,s+1,s+2)
  52.     move.b    (a0)+,d0        ; a0 += 2
  53.     lsl.w    #8,d0
  54.     move.b    (a0)+,d0
  55.     add.b    (a0),d0
  56.     lsl.l    #2,d0
  57.  
  58.     move.l    a0,0(a6,d0.l)   ; hash[hash_val]=s
  59.  
  60.     move.l    #$00000FFF,d4
  61.  
  62.     subq.l    #2,a4
  63.     move.l    a4,a3        ; get place to put next ctrl_word
  64.     moveq.l #1,d7        ; initialize ctrl_word with $0001
  65.  
  66.     move.l    a0,d2
  67.     sub.l    d4,d2        ; d2 = src - 4095
  68.  
  69. ;;here:    bra.s    here
  70.  
  71. ;    bra.s    do_literal    ; The first one is always a literal.
  72.  
  73.                 ;REGISTER MAP
  74.                 ;============
  75.  
  76. ;    a0 source
  77. ;    a1 destination byte stream    (post increment)
  78. ;    a2 Temporary
  79. ;    a3 place to put control word in output
  80. ;    a4 destination word stream    (pre decrement)
  81. ;    a5 Temporary
  82. ;    a6 hashtable
  83. ;    a7 Stack pointer. Don't touch!
  84.  
  85. ;    d0 Temporary
  86. ;    d1 End of input+2
  87. ;    d2 src - 4095
  88. ;    d3 match_offset , match_len
  89. ;    d4 Constant 4095
  90. ;    d5 work pointer into LZ77-window
  91. ;    d6 Temporary
  92. ;    d7 Buffers the current control word.
  93.  
  94. ;;;---------------------------------------------------------------------------
  95.  
  96. do_literal:
  97.     move.b    -2(a0),(a1)+    ; write literal
  98.  
  99.     moveq.l #-1,d0        ; increment src
  100.     move.b    -1(a0),d0
  101.     lsl.w    #8,d0
  102.     move.b    (a0)+,d0    ; ++a0
  103.     addq.l    #1,d2        ; d2+=1  d2==src-4095
  104.     add.b    (a0),d0
  105.     lsl.l    #2,d0        ; d0 = hash_fkt(src[-2],src[-1],src[0])
  106.  
  107.     move.l    0(a6,d0.l),d5   ; d5 = wrk = hash[hash_val]
  108.     move.l    a0,0(a6,d0.l)   ; hash[hash_val] = src
  109.  
  110.     move.l    a0,d0
  111.     and.l    d4,d0
  112.     asl.w    #2,d0        ; clears X
  113.     move.l    d5,0(a6,d0.l)   ; hh[src&$FFF] = [old]hash[hash_val] {== wrk}
  114.  
  115. insctl:    addx.w    d7,d7        ; inject X-Flag into ctrl_word
  116.     bcc.s    eloop        ; control not full
  117.  
  118.     move.w    d7,(a3)         ; write ctrl_word to it's place
  119.     subq.l    #2,a4
  120.     move.l    a4,a3        ; get place to put next ctrl_word
  121.  
  122.     moveq.l #1,d7        ; initialize ctrl_word with $0001
  123.     cmp.l    d1,a0        ; Has src reached src_end?
  124.     bcc    end_control_done
  125.  
  126. eloop:    cmp.l    d2,d5            ; is wrk below the limit
  127.     bcs.s    do_literal        ; is wrk < src - 4095
  128.     moveq.l    #1,d3        ; Initializations for iloop
  129.                 ; match_ofs,match_len-1 = 0,1
  130.  
  131. iloop:    move.l    a0,a2
  132.     move.l    d5,a5
  133.  
  134. MATCH    MACRO
  135.     cmp.b    (a2)+,(a5)+
  136.     bne.s    \1
  137.     ENDM
  138.  
  139.     MATCH    next    ; 2
  140.     MATCH    mism    ; 3
  141.     MATCH    mism    ; 4
  142.     MATCH    mism    ; 5
  143.     MATCH    mism    ; 6
  144.     MATCH    mism    ; 7
  145.     MATCH    mism    ; 8
  146.     MATCH    mism    ; 9
  147.     MATCH    mism    ;10
  148.     MATCH    mism    ;11
  149.     MATCH    mism    ;12
  150.     MATCH    mism    ;13
  151.     MATCH    mism    ;14
  152.     MATCH    mism    ;15
  153.     MATCH    mism    ;16
  154.     MATCH    mism    ;17
  155.     addq.l    #1,a5    ;18
  156. mism:    sub.l    d5,a5        ; a5=match_len-1
  157.  
  158.     cmp.w    a5,d3
  159.     bcc.s    next        ; new match is not longer than old one
  160.  
  161.     move.l    a0,d3
  162.     sub.l    d5,d3        ; d3 = src - wrk = match_ofs
  163.     swap    d3
  164.     move.w    a5,d3        ; match_ofs,match_len-1 is updated.
  165.  
  166.     cmp.b    #17,d3
  167.     bcc.s    docopy        ; match_len-1 >= 18-1
  168.  
  169. next:    and.l    d4,d5            ; d5=wrk & $00000FFF
  170.     lsl.w    #2,d5
  171.     move.l    0(a6,d5.l),d5           ; wrk=hh[wrk & $00000FFF]
  172.  
  173.     cmp.l    d2,d5            ; is wrk in range?
  174.     bcc.s    iloop            ; is wrk >= src - 4095 ?
  175.  
  176.  
  177. finished_chain:
  178.     cmp.b    #2,d3
  179.     bcs    do_literal
  180.  
  181. docopy:    moveq.l #17,d0
  182.     add.l    d0,d2
  183.     sub.b    d3,d0        ; d0=17-(match_len-1)
  184.     sub.l    d0,d2
  185.     addq.l    #1,d2        ; d2+=match_len
  186.  
  187.     swap    d3
  188.     asl.w    #4,d3
  189.     or.b    d0,d3        ; d3 = OOOOOOOO OOOOLLLL
  190.  
  191.     move.w    d3,-(a4)        ; write copyinfo
  192.  
  193.     swap    d3        ; d3.w = match_len - 1
  194.  
  195. incsrc: moveq.l #-1,d0        ; increment src
  196.     move.b    -1(a0),d0
  197.     lsl.w    #8,d0
  198.     move.b    (a0)+,d0
  199.     add.b    (a0),d0         ; ++a0
  200.  
  201.     move.l    a0,d6
  202.     and.l    d4,d6
  203.     asl.w    #2,d6
  204.  
  205.     asl.l    #2,d0        ; d0 = hash_fkt(src[-2],src[-1],src[0])
  206.                 ; Does set the X-Flag
  207.     move.l    0(a6,d0.l),d5   ; d5 = wrk = hash[hash_val]
  208.     move.l    a0,0(a6,d0.l)   ; hash[hash_val] = src
  209.  
  210.     move.l    d5,0(a6,d6.l)   ; hh[src&$FFF] = [old]hash[hash_val] {== wrk}
  211.  
  212.     dbra    d3,incsrc
  213.  
  214.     cmp.l    d1,a0        ; Has src reached src_end?
  215.     bcs    insctl        ; Insert the X-Flag[=1] into control
  216.  
  217. ;;;The main loop ends here.
  218. ;;;---------------------------------------------------------------------------
  219.                 ;FINALIZATION
  220.                 ;============
  221.  
  222.     add.l    d0,d0        ; Just set the Carry [d0 is junked]
  223. ; Fill the rest of the control.  Since the carry is set the 1st control
  224. ; inserted will be a copy item and the rest literals.
  225. FillControl:
  226.     addx.w    d7,d7
  227.     bcc.s    FillControl
  228.  
  229.     move.w    d7,(a3)         ;Write it to its output position
  230.     
  231.     subq.l    #2,a4        ; reserve space for next controlword
  232. end_control_done:
  233.     addq.l    #2,a4        ; Junk new controlword
  234.     movem.l (sp)+,d6/d7     ; Pop dst and dst_end
  235.  
  236.     ;Copy the literals after the word stream pointed to by a1.
  237.     move.l    a4,d0        ;d0:=Number of Bytes to increase a1
  238.     sub.l    a1,d0        ;till a1 and a4 are equally aligned.
  239.     bcc.s    did_compress
  240.  
  241. ;byte- and wordstream together do exceede the size of the output buffer.
  242.     moveq    #0,d0        ; return 0 to indicate overrun
  243.     bra.s    finish
  244.  
  245. did_compress:
  246.     moveq    #3,d1
  247.     and.w    d0,d1
  248.  
  249.     moveq.l #0,d0        ;pad a1 up to make a1 and a4 equally aligned.
  250.     bra.s    EFLoop
  251. FLoop:    move.b    d0,(a1)+
  252. EFLoop: dbra    d1,FLoop
  253.  
  254.     sub.l    a4,d7        ;d7:=size of wordstream
  255.  
  256.     lsr.l    #2,d7
  257.     bcc.s    ECLoop        ;make sure we do the move.l longword aligned.
  258.     move.w    (a4)+,(a1)+
  259. NoWord: bra.s    ECLoop
  260. CLoopH: swap    d7
  261. CLoop:    move.l    (a4)+,(a1)+
  262. ECLoop: dbra    d7,CLoop
  263.     swap    d7
  264.     dbra    d7,CLoopH
  265.  
  266.     move.l    a1,d0
  267.     sub.l    d6,d0            ;d0:=Final output length
  268. finish: movem.l (sp)+,COMPRESSREGS
  269.     rts
  270.  
  271. ;;;---------------------------------------------------------------------------
  272.  
  273.     END
  274.  
  275.