home *** CD-ROM | disk | FTP | other *** search
/ Amiga MA Magazine 1998 #6 / amigamamagazinepolishissue1998.iso / packery / xpk_source / libraries / fast / compress2.a < prev    next >
Text File  |  1996-10-19  |  6KB  |  285 lines

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