home *** CD-ROM | disk | FTP | other *** search
/ Computer Club Elmshorn Atari PD / CCE_PD.iso / pc / 0400 / CCE_0483.ZIP / CCE_0483.PD / LZH_SOUR.CE / HUFST.S < prev    next >
Text File  |  1992-04-10  |  38KB  |  1,667 lines

  1.  
  2. ;-----------------------------------------------------------------------
  3. ; This is a assembler-version of some parts of huf.c
  4. ;
  5. ; Coded in may 1990 by Thomas Quester
  6. ; Some of this code is reassembled C
  7. ;
  8. ; To get rid of scaling the array's, the values of dad, son, lson, rson
  9. ; hold the double value
  10. ;
  11. ;------------------------------------------------------------------------
  12.  
  13.  
  14.  
  15. ; -----------------------------------------------------------------------
  16. ;        Externals  
  17. ; -----------------------------------------------------------------------
  18.  
  19.         export Decode
  20.         export Encode
  21.         import EncodeEn
  22. ;        export EncodePo
  23. ;        export GetBit
  24. ;        import GetByte
  25.         import InitTree
  26.         export PatchF
  27. ;        export Putcode
  28.         export StartHuf
  29.         import _StdErrF
  30.         import _StdOutF
  31.         export blkcnt
  32.         export blocksize
  33. ;        import code_buf
  34.         export codesize
  35.         export crc
  36.         export crc_getc
  37.         export crctbl
  38. ;        import d_code
  39. ;        import d_len
  40.         export dad
  41.         import error
  42.         import ferror
  43.         import fgetc
  44.         import ungetc
  45.         export flg_n
  46.         import fputc
  47. ;        export freq
  48. ;        export getbuf
  49. ;        export getlen
  50.         import infile
  51. ;        import last_mat
  52.         export lson
  53. ;        import lson
  54. ;        export match_length
  55. ;        export match_position
  56.         import outfile
  57.         import outfname
  58. ;        import p_code
  59. ;        import p_len
  60.         import printcou
  61. ;        export prnt
  62. ;        export putbuf
  63. ;        export putlen
  64.         import rewind
  65.         export rson
  66. ;        export son
  67.         export text_buf
  68.         export textsize 
  69.         export    FileFits
  70.         import    fwrite
  71.     
  72. ; -----------------------------------------------------------------------
  73. ;        Constants
  74. ; -----------------------------------------------------------------------
  75.  
  76. N        equ 4096        ;Buffer size
  77. F        equ 60            ;lookahead buffer size
  78. THRESHOLD    equ 2
  79. N_CHAR        equ 256-THRESHOLD+F    ;kinds of characters (0..N_CHAR-1)
  80. T        equ N_CHAR*2-1        ;size of table
  81. R        equ T-1         ;position of root
  82. NIL        equ    N
  83. FOLD        equ    18
  84. MAX_FREQ    equ    $8000
  85.  
  86.  
  87. ; -----------------------------------------------------------------------
  88. ;        Putc (macro)
  89. ; -----------------------------------------------------------------------
  90.  
  91. outrec:     ds.l    1    ; 0 Speicherzeiger
  92.         ds.l    1    ; 4 Länge
  93.         ds.l    1    ; 8 Basispointer
  94.         ds.l    1    ; 12 basislänge
  95.  
  96. ; Simmuliere turbo-c's fwrite: D0 = 1
  97. ;                   a1 = zeiger auf FILE
  98. ;                a0 = buffer
  99. tcwrite:       ds.w    1
  100. my_fwrite:    move.l    d2,-(sp)
  101.         tst.b    tcwrite
  102.         beq    tc_fwrite
  103.         cmp.w    #1,d0
  104.         bne.b    tc_fwrite
  105.         move.l    (a1),d2
  106.         cmp.l    8(a1),d2
  107.         bne.b    tc_fwrite
  108.         move.w    16(a1),d2
  109.         movem.l d0-d1/a0-a2,-(sp)
  110.         move.l    a0,-(sp)
  111.         move.l    d1,-(sp)
  112.         move.w    d2,-(sp) 
  113.         move.w    #$40,-(sp)
  114.         trap    #1
  115.         lea    12(sp),sp        
  116.         movem.l (sp)+,d0-d1/a0-a2
  117.         move.l    (sp)+,d2
  118.         rts   
  119.         
  120.         
  121.  
  122. tc_fwrite:    move.l    (sp)+,d2
  123.         bra    fwrite
  124.  
  125. shipout:    movem.l d0-a6,-(sp)
  126.         lea    outrec(pc),a0
  127.  
  128.  
  129.         move.l    (a0),d1     ; ptr
  130.         sub.l    8(a0),d1    ; - basis
  131.         beq    ship2        ; Noch nie benutzt!
  132.         move.l    8(a0),a0    ; basis
  133.         move.l    outfile(pc),d0
  134.         beq.b    ship2
  135.         move.l    d0,a1
  136.         moveq.l #1,d0
  137. ;         btst     #0,d1
  138. ;         bcc.b     shipodd     ; schreibe ungerade byteanzahl
  139.         bsr    my_fwrite
  140. ship3:        movea.l outfile(pc),A0
  141.         bsr    ferror        ; if (ferror(outfile))
  142.         tst.w    D0
  143.         beq.b    ship2
  144.         movea.l outfname,A0
  145.         moveq    #$0E,D0
  146.         bsr    error        ; error(WTERR,outfname)
  147.  
  148. ship2:        lea    outrec(pc),a0
  149.         move.l    12(a0),4(a0)
  150.         move.l     8(a0),(a0)
  151.         movem.l (sp)+,d0-a6
  152.         rts
  153.         
  154. ;shipodd:     movem.l d0/d1/a0,-(sp)
  155. ;         subq.l  #1,d1
  156. ;         bsr     my_fwrite
  157. ;         movem.l (sp)+,d0/d1/a0
  158. ;         add.l     d1,a0
  159. ;         subq.l  #1,a0
  160. ;         moveq.l #1,d1
  161. ;         bsr     my_fwrite
  162. ;         bra.b     ship3        
  163.  
  164.         macro    fputc reg
  165.         local    putc1
  166.         lea    outrec(pc),a0
  167.         move.l    (a0),a1
  168.         move.b    reg,(a1)+
  169.         move.l    a1,(a0)
  170.         subq.l    #1,4(a0)
  171.         bpl.b  putc1
  172. ; Hier shipout
  173.         bsr    shipout
  174. putc1:           
  175.         endm
  176.  
  177.  
  178. OpenOut:    movem.l d0-d3/a0-a2,-(sp)
  179.         move.l    #-1,-(sp)
  180.         move.w    #$48,-(sp); Malloc
  181.         trap    #1
  182.         addq.l    #6,sp
  183.         sub.l    #20000,d0
  184.         move.l    d0,d3
  185.         move.l    d0,-(sp)
  186.         move.w    #$48,-(sp)
  187.         trap    #1
  188.         addq.l    #6,sp
  189.         lea    outrec(pc),a0
  190.         subq.l    #7,d3
  191.         move.l    d0,(a0)+
  192.         move.l    d3,(a0)+
  193.         move.l    d0,(a0)+
  194.         move.l    d3,(a0)+
  195.         movem.l (sp)+,d0-d3/a0-a2
  196.         rts
  197. CloseOut:    bsr    shipout
  198.         move.l    8+outrec(pc),-(sp)
  199.         move.w    #$49,-(sp)
  200.         trap    #1
  201.         addq.l    #6,sp
  202.         rts 
  203. ; -----------------------------------------------------------------------
  204. ;        getc (fgetc)
  205. ; -----------------------------------------------------------------------
  206.  
  207.         macro    getc
  208.         local    getc1
  209.         local    getc2
  210.         local    getceof
  211.         move.l    (a0),a1
  212.         cmpa.l    4(a0),a1
  213.         bcc    getc1
  214.         moveq.l #0,d0
  215.         move.b    (a1)+,d0
  216.         move.l    a1,(a0)
  217.         cmp.b    d0,d0        ; set equal flag
  218.         bra.b    getc2     
  219. getc1:        
  220.         bsr    fgetc
  221.         cmp.w    #$ffff,d0
  222.         beq.b    getceof
  223.         cmp.b    d0,d0        ; set equal-flag
  224.         bra.b    getc2
  225. getceof:    cmp.b    #0,d0        ; set not equal
  226. getc2:        
  227.         endm            
  228. ; Gets 2 bytes in d7
  229.  
  230.         macro    rgetc
  231.         local    getc1
  232.         local    getc2
  233.         move.l    (a0),a1
  234.         cmpa.l    4(a0),a1
  235.         bcs.b    getc1
  236.         movem.l d1-d2/a0-a2,-(sp)
  237.         bsr    fgetc
  238.         movem.l (sp)+,d1-d2/a0-a2
  239.         bra.b    getc2
  240. getc1:        moveq.l #0,d0
  241.         move.b    (a1)+,d0
  242.         move.l    a1,(a0)
  243. getc2:        
  244.         endm            
  245. ; Gets 2 bytes in d7
  246.  
  247.         macro    getw
  248.         local    Fits
  249.         local    getwEnd
  250.  
  251.         rgetc     
  252.         move.w    d0,d7
  253.         lsl.w    #8,d7
  254.         rgetc
  255.         move.b    d0,d7
  256. getwEnd:
  257.         endm
  258.  
  259.  
  260. ; -----------------------------------------------------------------------
  261. ;        crc_getc
  262. ; -----------------------------------------------------------------------
  263.  
  264.         macro    crcgetc
  265. ; int crc_getc(register FILE *stream)
  266. ; setcrc(ch)
  267.         move.w    crc-lson(a2),D1
  268.         move.w    d1,d2
  269.         eor.w    D0,D1        ; c ^ crc
  270.  
  271.  
  272.         and.w    #$ff,D1     ; & 0xff
  273.         add.w    D1,D1        ; d2=cardinal (crc ^ c) & $ff
  274.  
  275.         lea    crctbl-lson(a2),A1
  276.         lsr.w    #8,D2        ; d0=(crc >> 8)
  277.         move.w    0(A1,D1.w),D1    ; d1=crctbl[(crc ^ (ch)) & 0xff]
  278.         eor.w    D2,D1
  279.         move.w    D1,crc-lson(a2)
  280.         endm
  281.  
  282. ; -----------------------------------------------------------------------
  283. ;        putCode
  284. ; -----------------------------------------------------------------------
  285.  
  286. ; void Putcode(register int l, register int c)
  287.  
  288. ; d7 = putlen 
  289. ; register a2 = putlen
  290. ;     -2(a2)=putbuf
  291.         macro    putcode
  292.         local PutCode1
  293.         local PutCode2
  294.         movem.w D3-D4,-(SP)
  295.         move.w    D0,D4
  296.         move.w    D1,D3
  297.         move.b    d7,D2        ; d2=putlen
  298.         lsr.w    D2,D1
  299.         or.w    D1,d6        ; putbuf != c >> putlen
  300.  
  301.         add.b    D0,d7        ; putlen+=l
  302.         cmpi.b    #8,d7        ; putlen
  303.         bcs    PutCode2
  304.  
  305.         move.w    d6,D0        ; putbuf
  306.         lsr.w    #8,D0
  307.         fputc    d0        ; putc(putbuf,outfile)
  308. ; if ((putlen -= 8) >=8)
  309.         subq.b    #8,d7        ; putlen
  310.         cmpi.b    #8,d7        ; putlen
  311.         bcs.b    PutCode1
  312.  
  313.         fputc    d6        ; putc(putbuf,outfile)
  314.         addq.l    #2,codesize    ; codesize+=2
  315.         subq.b    #8,d7        ;putlen-=8
  316.  
  317.         move.w    D3,D0
  318.         move.b    D4,D1
  319.         sub.b    d7,D1        ; putlen
  320.         lsl.w    D1,D0
  321.         move.w    D0,d6        ; putbuf = c << (l-putlen)
  322.         bra.b    PutCode2
  323.  
  324. PutCode1:    move.w    d6,D0        ; putbuf
  325.         lsl.w    #8,D0
  326.         move.w    D0,d6        ; putbuf <<=8
  327.         addq.l    #1,codesize    ; codesize++
  328. PutCode2:    movem.w (SP)+,D3-D4
  329.         endm
  330.  
  331. ; -----------------------------------------------------------------------
  332. ;       Reconstract a tree
  333. ; -----------------------------------------------------------------------
  334.  
  335. reconst:    movem.l D0-A6,-(SP)
  336.         lea    freq,A0
  337.         lea    prnt-freq(a0),A1
  338.         lea    son-freq(a0),A2
  339.         bra.b    rcon_a
  340.  
  341. rcon:        movem.l D0-A6,-(SP)
  342. rcon_a:     moveq    #0,D0
  343.         moveq    #0,D1
  344. ; Collect leaf nodes in the first half of the table
  345. ; and relace the freq by (freq+1)/2
  346. rcon1:        cmpi.w    #2*T,0(A2,D1.w) ; if son[i] >= T
  347.         blt.b    rcon2
  348.         moveq    #1,D2
  349.         add.w    0(A0,D1.w),D2
  350.         lsr.w    #1,D2
  351.         move.w    D2,0(A0,D0.w)    ; freq[j] = (freq[i]+1)/2
  352.         move.w    0(A2,D1.w),0(A2,D0.w) ; son[j]=son[i]
  353.         addq.w    #2,D0        ; j++
  354. rcon2:        addq.w    #2,D1        ; i++
  355.         cmp.w    #2*T,D1     ; i < T
  356.         blo.b    rcon1
  357.  
  358. ; begin constructing tree by connecting sons
  359. ; for (i=0; j=N_CHAR; j < T; i+=2; j++) {
  360.  
  361.         move.w    #N_CHAR*2,D3
  362.         moveq    #0,D4
  363. rcon3:        moveq    #2,D0
  364.         add.w    D4,D0        ;       k=i+2
  365.         move.w    0(A0,D4.w),D6
  366.         add.w    0(A0,D0.w),D6    ; f=freq[i]+freq[k]
  367.         move.w    D6,0(A0,D3.w)    ; freq[j]=f
  368. ; for (k=j-1; f < freq[k]; k--);
  369.         moveq    #-2,D5
  370.         add.w    D3,D5
  371.         bra.b    rcon5
  372. rcon4:        subq.w    #2,D5
  373. rcon5:        cmp.w    0(A0,D5.w),D6
  374.         blo.b    rcon4
  375.  
  376.         addq.w    #2,D5
  377.         move.w    D3,D7
  378.         sub.w    D5,D7        ; l=(j-k) * 2
  379.  
  380.         lea    0(A0,D5.w),A3
  381.         bsr.b    movemem     ;nach oben schieben
  382.         move.w    D6,0(A0,D5.w)    ; freq[k]= f
  383.  
  384.         lea    0(A2,D5.w),A3
  385.         bsr.b    movemem
  386.  
  387.         move.w    D4,0(A2,D5.w)    ; son[k] = i
  388.  
  389.         addq.w    #4,D4        ; i+=2
  390.         addq.w    #2,D3        ; j++
  391.         cmp.w    #2*T,D3
  392.         blo.b    rcon3
  393.  
  394. ; connect prnt
  395. ; for (i=0; i<T; i++) {
  396.         moveq    #0,D0
  397. rcon6:        move.w    0(A2,D0.w),D1
  398.         move.w    D0,0(A1,D1.w)
  399.         cmp.w    #2*T,D1
  400.         blt.b    rcon7        ; if ((k=son[j]) >= T) {
  401.         move.w    D0,0(A1,D1.w)    ; prnt[k] = i
  402.         bra.b    rcon8
  403. rcon7:        move.w    D0,0(A1,D1.w)    ; prnt[k] = i
  404.         move.w    D0,2(A1,D1.w)    ; prnt[k+1] = i;
  405. rcon8:        addq.w    #2,D0
  406.         cmp.w    #2*T,D0
  407.         blo.b    rcon6
  408.         movem.l (SP)+,D0-A6
  409.         rts
  410.  
  411. movemem:    adda.w    D7,A3
  412.         lea    2(A3),A4
  413.         move.w    D7,D0
  414.         bra.b    movemem2
  415. movemem1:    move.w    -(A3),-(A4)
  416.         subq.w    #2,D0
  417. movemem2:    bne.b    movemem1
  418.         rts
  419. ; -----------------------------------------------------------------------
  420. ;        update
  421. ; -----------------------------------------------------------------------
  422.  
  423.  
  424. ; void update(int c);
  425. ; register int i,j,k,l;
  426. ; register D3 = c
  427. ; register D1 = k
  428. ; register D2 = l
  429. ; register A1 = son
  430.  
  431. ; register D5 = cardinal c
  432. ; a4 = freq[c]
  433.  
  434. ;uses: d0,d1,d2,d5
  435. ;      a0,a1,a2,a3,a4,a6
  436. ; expects:   a2 = freq        d2 = 2*T
  437. ;         a4 = son
  438.         macro    update
  439.         local    upd_1
  440.         local    upd_2
  441.         local    upd_2a
  442.         local    upd_2b
  443.         local    upd_3
  444.         local    upd_4
  445.         local    upd_5
  446.         local    upd_6
  447.         local    updx
  448.         local    updx1
  449.         local    updrecon
  450.  
  451.         tst.w    R*2(A2)  ; if freq[R] == MAX_FREQ
  452.         bmi    updrecon
  453.  
  454. upd_1:        lea    prnt-freq(a2),A0     ; A0 = prnt
  455.  
  456.         move.w    0(a0,d0.w),d0
  457. ; do {
  458.         lea    0(A2,d0.w),A1    ; A1 = freq[c]
  459.         addq.w    #1,(A1)     ; freq[c]++
  460.  
  461. ; Ab hier: l=d5
  462. ; if the order is disturbed, exchange nodes
  463.         cmpm.w    (A1)+,(a1)+    ; if k>freq[l=c+1])
  464.         bcs.b    upd_2b
  465.  
  466. upd_2a:     move.w    0(a0,d0.w),d0
  467.         beq.b    updx
  468. ; do {
  469. upd_2:        lea    0(A2,d0.w),A1    ; A1 = freq[c]
  470.         addq.w    #1,(A1)     ; freq[c]++
  471.  
  472. ; Ab hier: l=d5
  473. ; if the order is disturbed, exchange nodes
  474.         cmpm.w    (A1)+,(a1)+    ; if k>freq[l=c+1])
  475.         bcc.b    upd_2a
  476.  
  477. ; while k > freq[++l]
  478. upd_2b:     subq.w    #1,-4(a1)
  479.         move.w    -4(a1),d1
  480. upd_3:        cmp.w    (a1)+,D1
  481.         beq.b    upd_3        ; while (k>freq[++l]);
  482.         subq.l    #4,a1
  483.         addq.w    #1,(a1)
  484.  
  485.         sub.l    A2,a1
  486.  
  487.         move.w    0(a4,d0.w),d4    ; i=son[c]
  488.         move.w    a1,(a0,d4.w)    ;prnt[i]=l
  489.  
  490.         cmp.w    d2,d4          ; if i<T
  491.         bge.b    upd_4
  492.         move.w    a1,2(A0,d4.w)    ; prnt[i+1]=l
  493.  
  494. upd_4:        move.w    0(A4,a1.w),D1          ; j=son[l]
  495.         move.w    d4,0(A4,a1.w)        ; son[l]=j
  496.  
  497.         move.w    d0,(A0,d1.w)    ; prnt[j] = c
  498.  
  499.         cmp.w    d2,D1          ; if j<T
  500.         bge.b    upd_5
  501.         move.w    d0,2(A0,d1.w)    ; prnt[j+1]=c
  502.  
  503. upd_5:        move.w    D1,0(a4,d0.w)    ; son[c]=j
  504.         move.w    a1,d0
  505. upd_6:        move.w    0(a0,d0.w),d0
  506.         beq.b    updx1
  507. ; do {
  508.         lea    0(A2,d0.w),A1    ; A1 = freq[c]
  509.         addq.w    #1,(A1)     ; freq[c]++
  510. ;         move.w  (A1)+,D1      ; k=freq[c]
  511.  
  512. ; Ab hier: l=d5
  513. ; if the order is disturbed, exchange nodes
  514.         cmp.w    (A1)+,(a1)+    ; if k>freq[l=c+1])
  515.         bcc.b    upd_6 
  516.         bra.b    upd_2b
  517. ; while k > freq[++l]
  518. updrecon:    bsr    reconst
  519.         bra    upd_1
  520. updx1:        
  521. updx:        
  522.         endm
  523.  
  524. ; -----------------------------------------------------------------------
  525. ;       EncodeChar
  526. ; -----------------------------------------------------------------------
  527.  
  528. ; void EncodeChar(unsigned c);
  529. ; register unsigned i;
  530. ; register int j,k;
  531. ; D5 = c
  532. ; D3 = i
  533. ; d4 = j
  534. ; d0 = k
  535.         macro    EncodeCh
  536.         local    Enchar1
  537.         local    Enchar2
  538.         local    Enchar3
  539.         local    Enchar4
  540.         local    Enchar5
  541.         local    Enchar6
  542.         move.w    d5,-(SP)
  543.         move.w    #2*R,d2
  544.         move.w    D0,D5        ; c
  545.         moveq    #0,D1        ;i=0
  546.         move.l    d1,a1        ;j=0
  547.         moveq    #0,d4        ;shift=0
  548.         lea    prnt-rson(a3),A0
  549.         add.w    #T,D0        ; T
  550.         add.w    D0,D0
  551.         move.w    0(A0,D0.w),D0    ; k=prnt[c+T]
  552. ; while
  553. ; if (k & 1) i +=0x8000
  554. Enchar1:    addq.w    #1,d4
  555.         btst    #1,D0
  556.         beq.b    Enchar2
  557.         lsr.w    d4,d1
  558.         add.w    d4,a1
  559.         moveq    #0,d4
  560.         add.w    #$8000,d1
  561. Enchar2:    move.w    0(A0,D0.w),D0    ; k=prnt[k]
  562.         cmp.w    d2,D0          ; R
  563.         bne.b    Enchar1
  564.  
  565. ; putcode(j,i)
  566. Enchar5:    add.w    d4,a1
  567.         move.w    a1,D0
  568.         lsr.w    d4,d1
  569.         lea    freq-rson(a3),a2
  570.         putcode
  571. ; update(c)
  572.         move.w    D5,D0
  573.         add.w    D0,D0
  574.         lea    freq-rson(a3),a2
  575.         lea    son-rson(a3),a4
  576.         move.w    #2*T,D2
  577.         add.w    d2,d0
  578.         update           
  579.         move.w    (SP)+,D5
  580.         endm 
  581.  
  582.  
  583.  
  584. ; -----------------------------------------------------------------------
  585. ;        EncodePosition
  586. ; -----------------------------------------------------------------------
  587.  
  588. ; void EncodePosition(unsigned c)
  589. ; register unsigned i;
  590.  
  591.         macro    EncodePo
  592.         move.w    D0,d4
  593.  
  594.         lsr.w    #6,D0
  595.         move.w    D0,D2        ; i = c >> 6
  596.  
  597.         lea    p_code(pc),A0
  598.         moveq    #0,D1
  599.         move.b    0(A0,D2.w),D1
  600.         lsl.w    #8,D1        ; p_code[i] << 8
  601.  
  602. ;         lea     p_len,A1
  603.         moveq    #0,D0
  604.         move.b    p_len-p_code(A0,D2.w),D0   ; p_len[i]
  605.         putcode         ; putcode(p_len[i],p_code[i] <<8)
  606.  
  607.         moveq    #$3F,D1
  608.         and.w    d4,D1
  609.         moveq    #$0A,D0
  610.         lsl.w    D0,D1
  611.         moveq    #6,D0
  612.         putcode
  613.         endm
  614.  
  615.  
  616. ; -----------------------------------------------------------------------
  617. ;        DeleteNode
  618. ; -----------------------------------------------------------------------
  619.  
  620. ; void DeleteNode(int p);        D5 = P
  621. ; register int q;
  622.  
  623. ; register D5 = p    ; D4 = cardinal p
  624. ; register D1 = q    ; D2 = cardinal q
  625. ; register D3 = temp
  626.  
  627. ; register A0 = dad
  628. ; register A2 = rson
  629. ; register A3 = lson
  630. ; register A4 = *rson[p]
  631. ; register A5 = *lson[p]
  632.  
  633.  
  634. ; WARNING: THE FOLLOWING REGISTERS MUST BE DEFINED:
  635. ;
  636. ; A2 = lson
  637. ; A3 = rson
  638. ; a4 = dad
  639. ; A5 = text_buf
  640.  
  641.         macro    DeleteNo
  642.         local    DNode_1
  643.         local    DNode_2
  644.         local    DNode_3
  645.         local    DNode_4
  646.         local    DNode_5
  647.         local    DNode_6
  648.         local    DNode_7
  649.         local    DNode_8
  650.         local    DNode_9
  651.         local    DNodex1
  652.         local    DNodex2
  653.         move.w    #2*NIL,D7
  654.         cmp.w    0(a4,d5.w),d7        ; if dad[p] == NIL
  655.         beq.b    DNode_9         ;     return
  656.         cmp.w    0(A3,d5.w),d7        ; if rson[p] == NIL
  657.         beq.b    DNodex1
  658.         move.w    0(a2,d5.w),d2
  659.         cmp.w    d2,d7            ; if lson[p] == NIL
  660.         beq.b    DNodex2     
  661. DNode_2:    move.w    0(a3,d2.w),d1
  662.         cmp.w    d1,d7
  663.         beq.b    DNode_5
  664. ; do { q=rson[q] } while (rson[q] != NIL}
  665. DNode_3:    move.w d2,d1
  666.         move.w    0(A3,D2.w),D2
  667.         cmp.w    D7,D2
  668.         bne.b    DNode_3
  669.         move.w    d1,d2
  670. DNode_4:    
  671. ; d2 = q    |  d5 = p     |  d1/d0 = temp |
  672. ; a2 = lson |  a3 = rson |  a4      = dad  |
  673.  
  674.         move.w    0(a2,d2.w),d0        ; lson[q]
  675.         move.w    0(a4,d2.w),d1        ; dad[q]
  676.         move.w    d0,0(a3,d1.w)        ; rson[dad[q]]=lson[q]
  677.         move.w    d1,0(a4,d0.w)        ; dad[lson[q]]=dad[q]
  678.         move.w    0(a2,d5.w),d1        ; lson[p]
  679.         move.w    d1,0(a2,d2.w)        ; lson[q]=lson[p]
  680.         move.w    d2,0(a4,d1.w)        ; dad[lson[p]]=q
  681.  
  682.  
  683.  
  684. DNode_5:    move.w    (a3,d5.w),d0
  685.         move.w    d0,0(A3,D2.w)    ; rson[q] = rson[p]
  686.         move.w    D2,0(A4,d0.w)    ; dad[rson[p]] = q
  687. DNode_6:    move.w    0(a4,d5.w),d0      ; dad[p]
  688.         move.w    d0,0(A4,D2.w) ; dad[q]=dad[p]
  689.  
  690.         cmp.w    0(A3,d0.w),D5
  691.         bne.b    DNode_7     ; if rson[dad[p]]=p
  692. ; else ..
  693.         move.w    D2,0(A3,d0.w)    ; rson[dad[p]]=q
  694.         bra.b    DNode_8
  695. DNodex1:    move.w    0(a2,d5.w),d2        ; q=lson[p]
  696.         bra.b    DNode_6
  697. DNodex2:    move.w    0(a3,d5.w),d2        ; q=rson[p]
  698.         bra.b    DNode_6
  699. DNode_7:    move.w    D2,0(A2,d0.w)    ; lson[dad[p]]=q
  700. DNode_8:    move.w    D7,0(a4,d5.w)
  701. DNode_9: 
  702.         endm
  703.  
  704. ; -----------------------------------------------------------------------
  705. ;        InsertNode
  706. ; -----------------------------------------------------------------------
  707.  
  708. ; void InsertNode(int r);
  709. ; rester int i,p,cmp;
  710. ; unsigned char *key;
  711. ; unigned c;
  712.  
  713. ; register D1 = cmp
  714. ; register D2 = p
  715. ; register A1 = *key
  716. ; register a2 = rson
  717. ; register A3 = lson
  718.  
  719. ; WARNING: THE FOLLOWING REGISTERS MUST BE DEFINED:
  720. ;
  721. ; A2 = lson
  722. ; A3 = rson
  723. ; A4 = dad
  724.  
  725.  
  726.         macro    InsertNo
  727.         local    INode_1
  728.         local    INode_1a
  729.         local    INode_2
  730.         local    INode_3
  731.         local    INode_3a
  732.         local    INode_4
  733.         local    INode_6
  734.         local    INode_6e1
  735.         local    INode_6odd
  736.         local    INode_7
  737.         local    INode_8
  738.         local    INode_9
  739.         local    INode_10
  740.         local    INode_11
  741.         local    INode_12
  742.         local    INode_14
  743.         local    Encode_L1
  744.         movem.l a6/d3,-(sp)
  745.  
  746.         move.w    d6,d1
  747.         lea    0(A5,D1.w),A1    ; key=&text_buf[r]
  748.  
  749.         move.w    (A1)+,D2    ; key[0]
  750.         add.w    #N+1,D2     ; p= N+1+key[0]
  751.         add.w    D2,D2        ; cardinal
  752.         move.w    #2*NIL,d3
  753.         move.w    d3,0(A2,D1.w)    ; rson[r] = NIL
  754.         move.w    d3,0(A3,D1.w)    ; lson[r] = NIL
  755.  
  756. ; for ...
  757. ;         lea     dad-lson(a2),A4
  758. INode_1a:    move.w    d2,a6
  759.         move.w    0(A3,D2.w),d2    ; rson[p]
  760.         cmp.w    d3,d2        ; if rson[p] != NIL
  761.         bne.b    INode_6     ; p=rson[p] else
  762.  
  763. INode_2:    move.w    a6,d2
  764.         move.w    D1,0(a3,d2.w)    ; rson[p] = r
  765.         move.w    D2,0(A4,D1.w)    ; dad[r] = p
  766.         bra    INode_14
  767.  
  768. INode_4:    move.w    a6,d2
  769.         move.w    D1,0(a2,d2.w)    ; lson[p] = r
  770.         move.w    D2,0(A4,D1.w)    ; dad[r] = p
  771.         bra    INode_14
  772. INode_3a:    bge.b    INode_1a
  773. INode_3:    move.w    d2,a6
  774.         move.w    0(A2,D2.w),d2    ; d2=lson[p]
  775.         cmp.w    d3,d2        ; if lson[p] != NIL
  776.         beq.b    INode_4
  777.  
  778. ; for (i=1; i<F; i++)
  779. INode_6:    move.l    a1,A0        ; key[1] (Siehe oben (a0)+)
  780.         lea    2(A5,D2.w),A6    ; text_buf[p+1]
  781.         cmpm.w    (a0)+,(a6)+    ; this saves MUTCH time
  782.         bne.b    INode_3a    ; and also (why?) some bytes
  783.         cmpm.l    (a0)+,(a6)+
  784.         bne.b    INode_3a
  785.  
  786.         rept    20
  787.         cmpm.l    (a0)+,(a6)+
  788.         bne.b    INode_8
  789.         endm
  790.         moveq    #7,D0         
  791. INode_7:    cmpm.l    (A0)+,(A6)+
  792.         dbne    D0,INode_7
  793.  
  794. INode_8:    beq.b    INode_10     
  795.         bhi.b    INode_3
  796.         move.w    d2,a6
  797.         move.w    0(A3,D2.w),d2    ; rson[p]
  798.         cmp.w    d3,d2        ; if rson[p] != NIL
  799.         bne.b    INode_6     ; p=rson[p] else
  800.  
  801.         move.w    a6,d2
  802.         move.w    D1,0(a3,d2.w)    ; rson[p] = r
  803.         move.w    D2,0(A4,D1.w)    ; dad[r] = p
  804.         bra    INode_14
  805. Encode_L1:    move.w    D1,0(A3,d0.w)
  806.         move.w    d3,0(a4,d2.w)    ; dad[p] = NIL
  807.         bra.b    INode_14
  808. ;  break
  809. INode_10:    ; d2 = p   a2 = lson   a4 = dad   
  810.         ; d1 = r   a3 = rson
  811.         move.w    0(a2,d2.w),d0        ; d0 = lson[p]
  812.         move.w    d1,0(a4,d0.w)        ;   dad[lson[p]]=r
  813.         move.w    d0,0(a2,d1.w)        ;   lson[r]=lson[p]
  814.         move.w    0(a3,d2.w),d0        ; d0=rson[p]
  815.         move.w    d1,0(a4,d0.w)        ;   dad[rson[p]]=r
  816.         move.w    d0,0(a3,d1.w)        ;   rson[r]=rson[p]
  817.         move.w    0(a4,d2.w),d0        ; dad[r]=dad[p]
  818.         move.w    d0,(a4,d1.w)
  819.         cmp.w    0(A3,d0.w),D2
  820.         beq.b    Encode_L1
  821.         move.w    D1,0(A2,D0.w)        ; lson[dad[p]] = r
  822. INode_12:    move.w    d3,0(a4,d2.w)        ; dad[p] = NIL
  823. INode_14:     
  824.         movem.l (sp)+,a6/d3
  825.         endm
  826.  
  827.         macro    MatchInsertNo
  828.         local    INode_1
  829.         local    INode_1a
  830.         local    INode_2
  831.         local    INode_3
  832.         local    INode_3a
  833.         local    INode_4
  834.         local    INode_6
  835.         local    INode_7
  836.         local    INode_8
  837.         local    INode_9
  838.         local    INode_9a
  839.         local    INode_10
  840.         local    INode_12
  841.         local    INode_14
  842.         local    Encode_L1
  843.         movem.l a6,-(sp)
  844.         movem.w D3-D5,-(SP)
  845.         moveq    #1,D1        ; cmp=1
  846.         move.w    #2*NIL,d5
  847. ;         add.w     D6,D6
  848.         lea    0(A5,D6.w),A1    ; key=&text_buf[r]
  849.  
  850.         move.w    (A1)+,D2    ; key[0]
  851.         add.w    #N+1,D2     ; p= N+1+key[0]
  852.         add.w    D2,D2        ; cardinal
  853.  
  854.         move.w    D5,0(A2,D6.w)    ; rson[r] = NIL
  855.         move.w    D5,0(A3,D6.w)    ; lson[r] = NIL
  856.  
  857. ; match_position=d7
  858. ; match_length=d0
  859.         moveq    #0,d0        ; match_length=0
  860. ;         clr.w     match_length-lson(a2)      ; match_length=0
  861. ; for ...
  862. ;         lea     dad-lson(a2),A4
  863. INode_1:    tst.b    D1        ; if (cmp > 0) {
  864.         blt.b    INode_3
  865. INode_1a:    move.w    d2,a6
  866.         move.w    0(A3,D2.w),d2    ; rson[p]
  867.         cmp.w    d5,d2        ; if rson[p] != NIL
  868.         bne.b    INode_6     ; p=rson[p] else
  869.  
  870. INode_2:    move.w    a6,d2
  871.         move.w    D6,0(a3,d2.w)    ; rson[p] = r
  872.         move.w    D2,0(A4,D6.w)    ; dad[r] = p
  873.         bra    INode_14
  874.  
  875. INode_4:    move.w    a6,d2
  876.         move.w    D6,0(a2,d2.w)    ; lson[p] = r
  877.         move.w    D2,0(A4,D6.w)    ; dad[r] = p
  878.         bra    INode_14
  879. INode_3a:    bge.b    INode_1a
  880. INode_3:    move.w    d2,a6
  881.         move.w    0(A2,D2.w),d2    ; d7=lson[p]
  882.         cmp.w    d5,d2        ; if lson[p] != NIL
  883.         beq.b    INode_4
  884.  
  885. ; for (i=1; i<F; i++)
  886. INode_6:    move.l    a1,A0        ; key[1] (Siehe oben (a0)+)
  887.         lea    2(A5,D2.w),A6    ; text_buf[p+1]
  888.         cmpm.l    (a0)+,(a6)+    ; this saves MUTCH time
  889.         bne.b    INode_3a    ; and also (why?) some bytes
  890.         cmpm.w    (a0)+,(a6)+
  891.         bne.b    INode_3a
  892.         moveq    #F-5,D3
  893. INode_7:    cmpm.w    (A0)+,(A6)+
  894.         dbne    D3,INode_7
  895.  
  896. INode_8:    beq    INode_9a
  897.         shi    d1        ; cmp=key[i]-text_buf[p+1]
  898.         not    d3
  899.         add.w    #F,d3
  900.  
  901.         cmp.w    d0,D3        ; if i>match_length
  902.         ble.b    INode_1
  903. INode_9:    move.w    D6,D7
  904.         sub.w    D2,D7        ; r-p
  905.         and.w    #2*$0FFF,D7      ; (r-p) & (N-1)
  906.         subq.w    #2,D7        ; ((r-p) & (N-1)) -1 = match_pos
  907.  
  908.         move.w    D3,d0        ; match_length=i
  909.         tst.b    D1        ; if (cmp > 0) {
  910.         blt    INode_3
  911.         move.w    d2,a6
  912.         move.w    0(A3,D2.w),d2    ; rson[p]
  913.         cmp.w    d5,d2        ; if rson[p] != NIL
  914.         bne.b    INode_6     ; p=rson[p] else
  915.  
  916.  
  917.         move.w    a6,d2
  918.         move.w    D6,0(a3,d2.w)    ; rson[p] = r
  919.         move.w    D2,0(A4,D6.w)    ; dad[r] = p
  920.         bra    INode_14
  921. INode_9a:    not    d3
  922.         add.w    #F,d3
  923.         move.w    D6,D7
  924.         sub.w    D2,D7        ; r-p
  925.         and.w    #2*$0FFF,D7      ; (r-p) & (N-1)
  926.         subq.w    #2,D7        ; ((r-p) & (N-1)) -1 = match_pos
  927.  
  928.         move.w    D3,d0        ; match_length=i
  929. ;  break
  930. INode_10:    
  931.         move.w    0(a2,d2.w),d4        ; d4 = lson[p]
  932.         move.w    d6,0(a4,d4.w)        ;   dad[lson[p]]=r
  933.         move.w    d4,0(a2,d6.w)        ;   lson[r]=lson[p]
  934.         move.w    0(a3,d2.w),d4        ; d4=rson[p]
  935.         move.w    d6,0(a4,d4.w)        ;   dad[rson[p]]=r
  936.         move.w    d4,0(a3,d6.w)        ;   rson[r]=rson[p]
  937.         move.w    0(a4,d2.w),d4
  938.         move.w    d4,0(a4,d6.w)        ; dad[r]=dad[p]
  939.  
  940.         cmp.w    0(A3,D4.w),D2
  941.         beq.b    Encode_L1
  942.  
  943.         move.w    D6,0(A2,D4.w)    ; lson[dad[p]] = r
  944.  
  945. INode_12:    move.w    d5,0(a4,d2.w)  ; dad[p] = NIL
  946.         bra.b    INode_14
  947. Encode_L1:    move.w    D6,0(A3,D4.w)
  948.         move.w    d5,0(a4,d2.w)    ; dad[p] = NIL
  949. INode_14:    move.w    d0,match_length-lson(a2)
  950.         move.w    d7,match_position-lson(a2)
  951.         movem.w (SP)+,D3-D5
  952.         movem.l (sp)+,a6
  953.         endm
  954.  
  955.  
  956. ; -----------------------------------------------------------------------
  957. ;        InitTree
  958. ; -----------------------------------------------------------------------
  959.  
  960. InitTree:    lea    rson,A0
  961.         lea    2*N+2(A0),A1    ; rson[N+1]
  962.         move.w    #N+1,D0     ; i=N+1
  963.         bra.b    ITree2
  964. ITree1:     move.w    #2*N,(A1)+    ; NIL
  965.         addq.w    #1,D0
  966. ITree2:     cmp.w    #$1100,D0
  967.         ble.b    ITree1
  968.         lea    dad,A1
  969.         moveq    #0,D0
  970.         bra.b    ITree4
  971. ITree3:     move.w    #2*N,(A1)+
  972.         addq.w    #1,D0
  973. ITree4:     cmp.w    #N,D0        ; N
  974.         blt.b    ITree3
  975.         rts
  976.  
  977. ; -----------------------------------------------------------------------
  978. ;        StartHuff
  979. ; -----------------------------------------------------------------------
  980.  
  981.  
  982. StartHuf:    movem.l D3-D4/A2-A3,-(SP)
  983.         lea    freq,A0
  984.         movea.l A0,A1        ; freqp=freq
  985.         lea    son,A2        ; sonp=son
  986.         lea    2*T+prnt,A3    ; prnpt=&prntp[T]
  987. ; for(i=0; i<N_CHAR; i++) {
  988.         move.w    #2*T,D1     ; iT=T
  989.         moveq    #0,D4
  990.         moveq    #0,D0           ; i=0
  991.         bra.b    SHuff2
  992. SHuff1:     move.w    #1,(A1)+    ; *freq++=1
  993.         move.w    D1,(A2)+    ; *sonp++=iT++
  994.         addq.w    #2,D1
  995.         move.w    D4,(A3)+    ; *prntp++=i;
  996.         addq.w    #1,D0
  997.         addq.w    #2,D4
  998. SHuff2:     cmp.w    #$013A,D0
  999.         blt.b    SHuff1
  1000. ; }
  1001.         moveq    #0,D0           ; i=0
  1002.         move.w    #N_CHAR*2,D4
  1003.         move.w    #N_CHAR,D1    ; j=N_CHAR
  1004.         movea.l A0,A1        ;freqp=freq
  1005.         lea    2*N_CHAR+son,A2 ; sonp=&son[N_CHAR]
  1006.         lea    prnt,A3     ; prntp=prnt
  1007. ; while (j<=R) {
  1008.         bra.b    SHuff4
  1009. SHuff3:     move.w    (A1)+,D2
  1010.         add.w    (A1)+,D2
  1011.         move.w    D1,D3
  1012.         add.w    D3,D3
  1013.         move.w    D2,0(A0,D3.w)    ; freq[j] = *freqp++ + *freqp++
  1014.         move.w    D0,(A2)+    ; *sonp++=i
  1015.         move.w    D4,(A3)+    ; *prntp++=j
  1016.         move.w    D4,(A3)+    ; *prntp++=j
  1017.         addq.w    #4,D0        ; i+=2
  1018.         addq.w    #1,D1        ; j+=1
  1019.         addq.w    #2,D4
  1020. SHuff4:     cmp.w    #R,D1
  1021.         ble.b    SHuff3
  1022. ; }
  1023.         move.w    #$FFFF,$04E6(A0) ;freq[T]=0xffff
  1024.         clr.w    2*R+prnt    ; prnt[R]=0
  1025.         movem.l (SP)+,D3-D4/A2-A3
  1026.         rts
  1027.  
  1028. ; -----------------------------------------------------------------------
  1029. ;        Encode
  1030. ; -----------------------------------------------------------------------
  1031.  
  1032. ; void Encode(void);
  1033. ; register int i,r,s,c;
  1034. ; register int len,last_match_length
  1035. ; long printcount,printsize;
  1036.  
  1037. ; register D4 = c
  1038. ; register D5 = s
  1039. ; register D6 = r
  1040. ; register A2 = *textsize
  1041. ; 4(sp) = printcount;
  1042. Encode:     movem.l D3-D7/A2-A6,-(SP)
  1043.         move.b    #0,tcwrite
  1044.         bsr    OpenOut
  1045.         lea    -$0A(SP),SP
  1046.         lea    lson,A2
  1047.         lea    rson-lson(a2),A3
  1048.         lea    dad-lson(a2),a4
  1049.  
  1050.         move.l    textsize-lson(A2),D0
  1051.         beq    enc_23        ; if (textsize==0) return
  1052.         lea    text_buf-lson(a2),A5
  1053.         moveq    #0,D1
  1054.         move.b    D1,putlen  ; putlen=0
  1055.         moveq    #0,D2
  1056.         move.b    D1,D2
  1057.         move.w    D2,putbuf    ; putbuf=0
  1058. ; printcount=printsize < 4096L? printsize : 4096L
  1059.         move.l    D0,(SP)
  1060.         cmp.l    blocksize(pc),D0
  1061.         bge.b    enc_1
  1062.         bra.b    enc_2
  1063. enc_1:        move.l    blocksize(pc),D0
  1064. enc_2:        move.l    D0,4(SP)
  1065.         cmpi.w    #$40,blkcnt-lson(a2)       ; if blkcnt > MAXBLK
  1066.         bls.b    enc_3
  1067.         move.w    #$40,blkcnt-lson(a2)       ; blkcnt = MAXBLK
  1068. enc_3:        movea.l infile(pc),A0
  1069.         bsr    rewind        ; rewind(infile)
  1070.         clr.l    textsize-lson(A2)         ; textsize=0
  1071.  
  1072.         bsr    StartHuf
  1073.         bsr    InitTree
  1074.         moveq    #0,D5        ; s=0
  1075.         move.w    #N-F,D6     ; r=N-F
  1076.  
  1077. ; for(i=s; i<r;i++)
  1078.         move.w    D5,D7
  1079.         movem.l D0/A5,-(SP)
  1080.         add.w    d7,d7
  1081.         lea    0(A5,D7.w),A5
  1082.         lsr.w    #1,d7
  1083.         move.w    D6,D0
  1084.         sub.w    D7,D0
  1085.         sub.w    #1,D0
  1086. enc_4:        move.w    #$20,(A5)+    ; textbuf[i]=' '
  1087.         dbra    D0,enc_4
  1088.         movem.l (SP)+,D0/A5
  1089.  
  1090. ; for(len=0;len<F && (c=crc_getc(infile)) != EOF; len++)
  1091.         moveq    #0,D3
  1092.         move.l    A5,-(SP)
  1093.         add.w    d6,d6
  1094.         lea    0(A5,D6.w),A5
  1095.         lsr.w    #1,d6
  1096.         bra.b    enc_6
  1097. enc_5:        addq.l    #1,a5
  1098.         move.b    D4,(A5)+    ; text_buf[r+len]=c
  1099.         addq.w    #1,D3        ; len++
  1100. enc_6:        cmp.w    #F,D3
  1101.         bge.b    enc_7
  1102.         move.l    infile(pc),A0
  1103.         getc
  1104.         bne.b    enc_7        ; Ist EOF
  1105.         crcgetc         ; c=crc_getc(infile)
  1106.         move.w    D0,D4
  1107.         bra.b    enc_5
  1108. ; end for
  1109. enc_7:        movea.l (SP)+,A5
  1110.         move.w    D3,D0
  1111.         ext.l    D0
  1112.         move.l    D0,textsize-lson(A2)         ; textsize=len
  1113.  
  1114. ; for(i=1; i<=F; i++)
  1115.         moveq    #F-1,D7
  1116.         move.w    D6,-(SP)
  1117.         subq.w    #1,D6
  1118. enc_8:        add.w    d6,d6         
  1119.         InsertNo    ; InsertNode(r-i)         ***
  1120.         lsr.w    d6
  1121.         subq.w    #1,D6
  1122. enc_9:        dbra    D7,enc_8
  1123.         move.w    (SP)+,D6
  1124.         add.w    d6,d6
  1125.             MatchInsertNo         ; InsertNode(r)         ***
  1126.         add.w    d5,d5
  1127. enc_10:     lea    match_length-lson(A2),A6
  1128.  
  1129.         cmp.w    (A6),D3
  1130.         bge.b    enc_11        ; if (match_length > len)
  1131.         move.w    D3,(A6)     ;    match_lengt=len
  1132. enc_11:     move.b    putlen(pc),d7
  1133.         move.w    d6,d1
  1134.         move.w    d6,-(sp)
  1135.         move.w    putbuf(pc),d6
  1136.         cmpi.w    #2,(A6)
  1137.         bgt    enc_12        ; if match_length <=THRESHOLD
  1138.         move.w    #1,(A6)     ;    match_length=1
  1139.         moveq    #0,D0
  1140.         move.w    (A5,D1.w),D0
  1141.             EncodeCh    ; EncodeChar(text_buf[r])
  1142.         bra    enc_13
  1143. enc_12:     move.w    (A6),D0
  1144.         add.w    #$FD,D0
  1145.             EncodeCh    ; EncodeChar(255-THRESHOLD+match_length)
  1146.         move.w    match_position-rson(a3),D0
  1147.         lsr.w    #1,d0
  1148.             EncodePo    ; EncodePosition(match_position)
  1149. enc_13:     move.b    d7,putlen
  1150.         move.w    d6,putbuf
  1151.         move.w    (sp)+,d6
  1152.         lea    lson-rson(a3),a2
  1153.         lea    dad-rson(a3),a4 
  1154. ; for(i=0;i<last_match_length && (c=crc_getc(infile))!= EOF;i++)
  1155.         move.w    (a6),D0
  1156.  
  1157.         moveq.l #0,d4
  1158.         move.w    D0,D4
  1159.         add.l    D4,textsize-lson(a2)
  1160.         lea    2*N(A5),A6
  1161.         dbra    d4,enc_14
  1162. enc_14a:    subq.w    #1,d3
  1163.         bra    enc_15
  1164. enc_14b:    InsertNo
  1165. enc_14:     DeleteNo        ; DeleteNode(s)
  1166.         move.w    #2*$fff,d7
  1167.         movea.l infile(pc),a0
  1168.         getc
  1169.         bne    enc_14a     ; Ist EOF
  1170.         crcgetc         ; c=crc_getc(infile)
  1171.         move.w    d0,0(A5,D5.w)    ; text_buf[s]=c;
  1172.         cmp.w    #2*(F-1),D5
  1173.         bge.b    enc_15        ; if (s<F-1)
  1174.         move.w    d0,0(A6,D5.w)    ; text_buf[s+N]=c;
  1175. enc_15:   
  1176.         addq.w    #2,D5
  1177.         and.w    d7,D5
  1178.         addq.w    #2,D6
  1179.         and.w    d7,D6
  1180. enc_16:     dbra    d4,enc_14b
  1181.         MatchInsertNo
  1182. ; end for
  1183. ; if ((textsize +=i) >= printcount && i>0)
  1184. enc_17:     tst.w    d3
  1185.         beq.b    enc_22
  1186.         move.l    textsize-lson(A2),D1
  1187.         cmp.l    4(SP),D1
  1188.         blt    enc_10
  1189.         move.b    flg_n-lson(a2),D1
  1190.         bne    enc_10        ; if (!flg_n)
  1191.         move.w    blkcnt-lson(a2),D2
  1192.         bls.b    enc_18        ; if (blknct>0)
  1193.         lea    _StdOutF,A0
  1194.         moveq    #'*',D0
  1195.         bsr    fputc        ; putc('o',stderr)
  1196.         subq.w    #1,blkcnt-lson(a2)       ; blkcnt--;
  1197. enc_18:     move.l    blocksize(pc),d0
  1198.         add.l    d0,4(SP)    ; pritncount+=4096L
  1199.         move.l    4(SP),D0
  1200.         cmp.l    (SP),D0
  1201.         ble    enc_10        ; if (printcount>printsize)
  1202.         move.l    (SP),4(SP)    ;    printcount=printsize
  1203.         bra    enc_10        ; while(len>0)
  1204.  
  1205. enc_22:     move.b    putlen,d0
  1206.         beq.b    enc_23
  1207.         move.w    putbuf,d0
  1208.         lsr.w    #8,d0
  1209.         fputc    d0
  1210.         addq.l    #1,codesize
  1211. enc_23:     lea    $0A(SP),SP
  1212.         bsr    CloseOut
  1213.         movem.l (SP)+,D3-D7/A2-A6
  1214.         rts
  1215.  
  1216. ;**************************************************************************
  1217. ;**        Stuff for use with Decode                 **
  1218. ;**************************************************************************
  1219.  
  1220. ; -----------------------------------------------------------------------
  1221. ;        DecodeChar
  1222. ;  this is mixed with GetBit !
  1223. ; -----------------------------------------------------------------------
  1224.  
  1225.         macro    DecodeCh 
  1226.         local    GBit
  1227.         local    GBit1
  1228.         local    GBit2
  1229.         local    GBit4
  1230.         local    GBit5
  1231.         local    DeC3
  1232.         local    DeC4
  1233.         local    DeC2
  1234.         move.w    2*R(A4),D1    ; C = son[R]
  1235.         move.l    #2*T,d2
  1236.         cmp.w    d2,D1        ;  while c < T
  1237.         bcc.b    DeC3        
  1238.  
  1239. GBit:        dbra    d6,GBit4    ; keine Bits mehr da ?
  1240.         movea.l infile(pc),A0
  1241.         getw
  1242.         moveq    #15,d6
  1243.         bra    GBit4
  1244.         
  1245. GBit4:        add.w    d7,d7        ; getbuf << 1 & if (getbuf>0)
  1246.         bge.b    GBit5
  1247.         addq.w    #2,d1        ; c+=getbit()
  1248. GBit5:                    ; getlen--
  1249.         move.w    0(A4,D1.w),D1    ; c=son[c]
  1250.  
  1251. DeC2:        cmp.w    d2,D1        ;  while c < T
  1252.         bcs.b    GBit
  1253. DeC3:        move.w    d1,d0
  1254.         sub.w    d2,D1        ; C -= T
  1255.         swap    d1
  1256.         
  1257.         update
  1258.         swap    d1
  1259.         move.w    d1,d0
  1260.         lsr.w    D0         ; Ausgleich für Arrays
  1261.         endm
  1262.  
  1263.  
  1264. ; -----------------------------------------------------------------------
  1265. ;        DecodePosition
  1266. ; -----------------------------------------------------------------------
  1267.  
  1268.         macro    DecodePo
  1269.         local    Dpos1
  1270.         local    Dpos2
  1271.         local    Dpos3
  1272.         local    D1Pos1
  1273.         local    D1Pos2
  1274.         local    Dnpos
  1275.         local    GetBit1
  1276.         local    GetBit2
  1277.         local    GetBit4
  1278.         local    GetBit5
  1279.         local    GetByte1
  1280.         local    GetByte2
  1281.         local    GetByte3
  1282.         local    GetByte4
  1283.         local    x
  1284.         moveq    #8,d4                     
  1285. ; while getlen<=8 {
  1286.         cmp.b    d4,d6
  1287.         bgt.b    GetByte4
  1288. ;   i=getc(infile)
  1289. GetByte1:    movea.l infile(pc),A0
  1290.         rgetc
  1291. ;   getbuf |= i << 8 - getlen
  1292.         move.w    d4,D1;        d4=8
  1293.         sub.b    d6,D1
  1294.         lsl.w    D1,D0
  1295.         or.w    D0,d7
  1296. ;   getlen+=8
  1297.         add.b    d4,d6
  1298. GetByte4:
  1299. ; i=getbuf;
  1300.         and.l    #$ffff,d7
  1301.         lsl.l    #8,d7
  1302.         swap    d7
  1303.         sub.w    d4,d6
  1304.         lea    d_code(pc),A0
  1305.         moveq    #0,D4
  1306.         move.b    0(A0,D7.w),D4
  1307.         add.l    #d_len-d_code,a0
  1308.         moveq    #0,D2
  1309.         move.b    0(A0,D7.w),d2
  1310.         lsl.w    #6,D4
  1311.         swap    d7
  1312.         subq.w    #2,d2
  1313. Dpos1:        move.w    d6,d6        ; <8 bits availale?
  1314.         bgt.b    GetBit5      ; getlen = 0?
  1315.         movea.l infile(pc),A0
  1316.         getw
  1317.         moveq    #16,d6    
  1318. GetBit5:    move.w    d2,d0    
  1319.         cmp.w    d6,d0
  1320.         blt.b    GetBit6
  1321.         move.w    d6,d0
  1322. GetBit6:    lsl.l    d0,d7
  1323.         sub.w    d0,d6
  1324.         sub.w    d0,d2
  1325. Dpos2:        bne.b    Dpos1         ; nächstes bit
  1326.         swap    d7
  1327.         moveq    #$3f,d0
  1328.         and.w    d7,d0
  1329.         swap    d7
  1330. Dpos3:        or.w    D4,D0
  1331.         endm
  1332.  
  1333. ; -----------------------------------------------------------------------
  1334. ;        Decode
  1335. ; -----------------------------------------------------------------------
  1336.  
  1337. Decode:     movem.l D3-D7/A2-A6,-(SP)
  1338.         subq.w    #6,SP
  1339.         move.b    #1,tcwrite
  1340.         bsr    OpenOut
  1341.         move.l    infile(pc),a0
  1342.         bsr    fgetc
  1343.         bsr    ungetc
  1344. ; if textsize == 0
  1345.         
  1346.         move.l    textsize,D0
  1347. ;    return
  1348.         beq    Dcode19
  1349. ; getlen = 0
  1350.         moveq    #0,D1
  1351.         move.b    D1,d6
  1352. ; getbuf = 0
  1353.         moveq    #0,D2
  1354.         move.b    D1,D2
  1355.         move.w    D2,d7
  1356. ; printcount=textsize<blocksize ? textsize
  1357.         cmp.l    blocksize,D0
  1358.         bge.b    Dcode1
  1359.         bra.b    Dcode2
  1360. Dcode1:
  1361.         move.l    blocksize(pc),D0
  1362. Dcode2:
  1363.         move.l    D0,(SP)
  1364. ; if (blkcnt > MAXBLK)
  1365.         cmpi.w    #$40,blkcnt
  1366.         bls.b    Dcode3
  1367. ;  MAXBLK = blkcnt
  1368.         move.w    #$40,blkcnt
  1369. Dcode3:
  1370. ; StartHuff()
  1371.         bsr    StartHuf
  1372. ; for (i=0; i<N-F;i++)
  1373.         moveq    #0,D4
  1374.         lea    text_buf,A5
  1375.         bra.b    Dcode5
  1376. Dcode4:
  1377. ;    text_buf[i] = ' '
  1378.         move.b    #$20,0(A5,D4.w)
  1379.         addq.w    #1,D4
  1380. Dcode5:
  1381.         cmp.w    #$0FC4,D4
  1382.         blt.b    Dcode4
  1383. ; r = N-F;
  1384.         move.w    #$0FC4,D5
  1385. ; for (count = 0; count < textsize;) {
  1386.         lea    crctbl,A6
  1387.         move.w    crc-crctbl(a6),A3
  1388.         lea    son-crctbl(a6),a4
  1389.         lea    freq-crctbl(a6),a2
  1390.         clr.l    delen-son(a4)
  1391.         bra    Dcode16
  1392. Dcode6:
  1393. ;  c=DecodeCh()
  1394.         DecodeCh
  1395. ;  if (c<256) {
  1396.         cmp.w    #$0100,D0
  1397.         bge.b    Dcode8
  1398. ;      text_buf[r++]=c;
  1399.         move.b    D0,0(A5,D5.w)
  1400.         addq.w    #1,D5
  1401. ;     if (outfile != NULL)
  1402. ;       putc(c,outfile)
  1403.         fputc d0
  1404. Dcode7:
  1405.  
  1406. ;     setcrc(c)
  1407.         move.w    A3,D1
  1408.         eor.w    D0,D1
  1409.         and.w    #$FF,D1
  1410.         add.l    D1,D1
  1411.         move.w    A3,D2
  1412.         lsr.w    #8,D2
  1413.         move.w    0(A6,D1.w),D0
  1414.         eor.w    D2,D0
  1415.         move.w    D0,A3
  1416.  
  1417. ;      r & = (N-1)
  1418.         and.w    #$fff,D5
  1419. ;      count ++;
  1420.         addq.l    #1,delen-son(A4)
  1421. ; } else {
  1422.         bra    Dcode12
  1423. Dcode8:
  1424. ;     i= (r-DecodePosition()-1) & (N-1)
  1425.         move.w    d0,d3
  1426.         DecodePo
  1427.         move.w    D5,D4
  1428.         sub.w    D0,D4
  1429.         subq.w    #1,D4
  1430.         move.w    #$fff,d2
  1431.         and.w    d2,D4
  1432.         
  1433.         exg.l    d3,d4
  1434. ;     j = c - 255+THRESHOLD
  1435.         add.w    #$FF03-1,D4
  1436. ;     for (k=0; k<j; k++) {
  1437.         
  1438.         exg.l    a3,d6
  1439.         addq.l    #1,delen-son(A4)
  1440.         ext.l    d4
  1441.         add.l    d4,delen-son(a4)
  1442.         lea    outrec(pc),a0
  1443.         move.l    (a0)+,a1    ; len
  1444.  
  1445. Dcode9:
  1446. ;     c=text_buf[(i+k) & (N-1)]
  1447.         and.w    d2,D3
  1448.         move.b    0(A5,D3.w),D0
  1449. ;     text_buf[r++] = c;
  1450.         move.b    D0,0(A5,D5.w)
  1451.         addq.w    #1,D5
  1452. ;     r &=(N-1)
  1453.         and.w    d2,D5
  1454. ;     if (outfile!=NULL)
  1455. ;         putc(c,outfile)
  1456.  
  1457.         move.b    d0,(a1)+
  1458.         subq.l    #1,(a0)
  1459.         bpl.b    Dcode10
  1460. ; Hier shipout    
  1461.         move.l    a1,outrec
  1462.         bsr    shipout
  1463.         lea    outrec(pc),a0
  1464.         move.l    (a0)+,a1    ; Memory
  1465. Dcode10:
  1466. ;     setcrc(c)
  1467.         move.w    d6,D1
  1468.         eor.b    D0,D6
  1469.         and.w    #$FF,D6
  1470.         add.w    D6,D6
  1471.         lsr.w    #8,D1
  1472.         move.w    0(A6,D6.w),D6
  1473.         eor.w    D1,D6
  1474. ;     count++;
  1475. ;   }
  1476.         addq.w    #1,D3
  1477. Dcode11:    dbra    d4,Dcode9
  1478.         move.l    a1,outrec
  1479.         exg.l    a3,d6
  1480. Dcode12:
  1481. ;   if (count >= printcount) {
  1482.         move.l    delen-son(a4),d0
  1483.         cmp.l    (SP),d0
  1484.         bcs.b    Dcode16a
  1485. ;      if (!flg_n) {
  1486.         move.b    flg_n-son(A4),D0
  1487.         bne.b    Dcode14
  1488. ;      if (blkcnt > 0) {
  1489.         move.w    blkcnt-son(a4),D1
  1490.         bls.b    Dcode13
  1491. ;      putc('*',stderr)
  1492.         lea    _StdOutF,A0
  1493.         moveq    #$2A,D0
  1494.         bsr    fputc
  1495. ;      blkcnt--
  1496.         subq.w    #1,blkcnt-son(a4)
  1497. ;    }
  1498. Dcode13:
  1499. ;    printcount +=blocksize;
  1500.         move.l    blocksize(pc),D0
  1501.         add.l    D0,(SP)
  1502. ;    if (printcount > textsize)
  1503.         move.l    (SP),D1
  1504.         cmp.l    textsize-son(a4),D1
  1505.         ble.b    Dcode14
  1506. ;    printcount = textsize);
  1507.         move.l    textsize-son(a4),(SP)
  1508. Dcode14:
  1509. ;   if (outfile != NULL && ferror(outfile))
  1510.         move.l    outfile(pc),D0
  1511.         beq.b    Dcode16
  1512.         movea.l D0,A0
  1513.         bsr    ferror
  1514.         tst.w    D0
  1515. Dcode15:                ;
  1516.         bne.b    Dcode17
  1517. Dcode16:    move.l    delen-son(a4),d0
  1518. Dcode16a:    cmp.l    textsize-son(a4),D0
  1519.         bcs    Dcode6
  1520. Dcode17:
  1521. ;    if (!flg_n && blkcnt > 0)
  1522.         move.b    flg_n-son(a4),D0
  1523.         bne.b    Dcode18
  1524. ;        putc('*',stderr)
  1525.         move.w    blkcnt-son(a4),D1
  1526.         bls.b    Dcode18
  1527.         lea    _StdOutF,A0
  1528.         moveq    #$2A,D0
  1529.         bsr    fputc
  1530. Dcode18:
  1531. ;    if (outfile != NULL && ferror(outfile) {
  1532.         move.l    outfile(pc),D0
  1533.         beq.b    Dcode19
  1534.         movea.l D0,A0
  1535.         bsr    ferror
  1536.         tst.w    D0
  1537.         beq.b    Dcode19
  1538. ;      error(WTERR,outfile)
  1539.         movea.l outfname,A0
  1540.         moveq    #$0E,D0
  1541.         bsr    error
  1542. Dcode19:    move.w    a3,crc-crctbl(a6)
  1543.         addq.w    #6,SP
  1544.         bsr    CloseOut
  1545.         movem.l (SP)+,D3-D7/A2-A6
  1546.         rts
  1547.  
  1548.  
  1549. putbuf:     ds.w    1
  1550. putlen:     ds.b    1
  1551.         even
  1552. outfile:    ds.l    1
  1553. infile:     ds.l    1
  1554. blocksize:    ds.l    1
  1555.  
  1556. p_len:    dc.b    $03, $04, $04, $04, $05, $05, $05, $05
  1557.     dc.b    $05, $05, $05, $05, $06, $06, $06, $06
  1558.     dc.b    $06, $06, $06, $06, $06, $06, $06, $06
  1559.     dc.b    $07, $07, $07, $07, $07, $07, $07, $07
  1560.     dc.b    $07, $07, $07, $07, $07, $07, $07, $07
  1561.     dc.b    $07, $07, $07, $07, $07, $07, $07, $07
  1562.     dc.b    $08, $08, $08, $08, $08, $08, $08, $08
  1563.     dc.b    $08, $08, $08, $08, $08, $08, $08, $08
  1564.  
  1565. p_code: dc.b    $00, $20, $30, $40, $50, $58, $60, $68
  1566.     dc.b    $70, $78, $80, $88, $90, $94, $98, $9C
  1567.     dc.b    $A0, $A4, $A8, $AC, $B0, $B4, $B8, $BC
  1568.     dc.b    $C0, $C2, $C4, $C6, $C8, $CA, $CC, $CE
  1569.     dc.b    $D0, $D2, $D4, $D6, $D8, $DA, $DC, $DE
  1570.     dc.b    $E0, $E2, $E4, $E6, $E8, $EA, $EC, $EE
  1571.     dc.b    $F0, $F1, $F2, $F3, $F4, $F5, $F6, $F7
  1572.     dc.b    $F8, $F9, $FA, $FB, $FC, $FD, $FE, $FF
  1573.  
  1574. ;    for decoding
  1575. d_code: dc.b    $00, $00, $00, $00, $00, $00, $00, $00
  1576.     dc.b    $00, $00, $00, $00, $00, $00, $00, $00
  1577.     dc.b    $00, $00, $00, $00, $00, $00, $00, $00
  1578.     dc.b    $00, $00, $00, $00, $00, $00, $00, $00
  1579.     dc.b    $01, $01, $01, $01, $01, $01, $01, $01
  1580.     dc.b    $01, $01, $01, $01, $01, $01, $01, $01
  1581.     dc.b    $02, $02, $02, $02, $02, $02, $02, $02
  1582.     dc.b    $02, $02, $02, $02, $02, $02, $02, $02
  1583.     dc.b    $03, $03, $03, $03, $03, $03, $03, $03
  1584.     dc.b    $03, $03, $03, $03, $03, $03, $03, $03
  1585.     dc.b    $04, $04, $04, $04, $04, $04, $04, $04
  1586.     dc.b    $05, $05, $05, $05, $05, $05, $05, $05
  1587.     dc.b    $06, $06, $06, $06, $06, $06, $06, $06
  1588.     dc.b    $07, $07, $07, $07, $07, $07, $07, $07
  1589.     dc.b    $08, $08, $08, $08, $08, $08, $08, $08
  1590.     dc.b    $09, $09, $09, $09, $09, $09, $09, $09
  1591.     dc.b    $0A, $0A, $0A, $0A, $0A, $0A, $0A, $0A
  1592.     dc.b    $0B, $0B, $0B, $0B, $0B, $0B, $0B, $0B
  1593.     dc.b    $0C, $0C, $0C, $0C, $0D, $0D, $0D, $0D
  1594.     dc.b    $0E, $0E, $0E, $0E, $0F, $0F, $0F, $0F
  1595.     dc.b    $10, $10, $10, $10, $11, $11, $11, $11
  1596.     dc.b    $12, $12, $12, $12, $13, $13, $13, $13
  1597.     dc.b    $14, $14, $14, $14, $15, $15, $15, $15
  1598.     dc.b    $16, $16, $16, $16, $17, $17, $17, $17
  1599.     dc.b    $18, $18, $19, $19, $1A, $1A, $1B, $1B
  1600.     dc.b    $1C, $1C, $1D, $1D, $1E, $1E, $1F, $1F
  1601.     dc.b    $20, $20, $21, $21, $22, $22, $23, $23
  1602.     dc.b    $24, $24, $25, $25, $26, $26, $27, $27
  1603.     dc.b    $28, $28, $29, $29, $2A, $2A, $2B, $2B
  1604.     dc.b    $2C, $2C, $2D, $2D, $2E, $2E, $2F, $2F
  1605.     dc.b    $30, $31, $32, $33, $34, $35, $36, $37
  1606.     dc.b    $38, $39, $3A, $3B, $3C, $3D, $3E, $3F
  1607.  
  1608. d_len:    dc.b    $03, $03, $03, $03, $03, $03, $03, $03
  1609.     dc.b    $03, $03, $03, $03, $03, $03, $03, $03
  1610.     dc.b    $03, $03, $03, $03, $03, $03, $03, $03
  1611.     dc.b    $03, $03, $03, $03, $03, $03, $03, $03
  1612.     dc.b    $04, $04, $04, $04, $04, $04, $04, $04
  1613.     dc.b    $04, $04, $04, $04, $04, $04, $04, $04
  1614.     dc.b    $04, $04, $04, $04, $04, $04, $04, $04
  1615.     dc.b    $04, $04, $04, $04, $04, $04, $04, $04
  1616.     dc.b    $04, $04, $04, $04, $04, $04, $04, $04
  1617.     dc.b    $04, $04, $04, $04, $04, $04, $04, $04
  1618.     dc.b    $05, $05, $05, $05, $05, $05, $05, $05
  1619.     dc.b    $05, $05, $05, $05, $05, $05, $05, $05
  1620.     dc.b    $05, $05, $05, $05, $05, $05, $05, $05
  1621.     dc.b    $05, $05, $05, $05, $05, $05, $05, $05
  1622.     dc.b    $05, $05, $05, $05, $05, $05, $05, $05
  1623.     dc.b    $05, $05, $05, $05, $05, $05, $05, $05
  1624.     dc.b    $05, $05, $05, $05, $05, $05, $05, $05
  1625.     dc.b    $05, $05, $05, $05, $05, $05, $05, $05
  1626.     dc.b    $06, $06, $06, $06, $06, $06, $06, $06
  1627.     dc.b    $06, $06, $06, $06, $06, $06, $06, $06
  1628.     dc.b    $06, $06, $06, $06, $06, $06, $06, $06
  1629.     dc.b    $06, $06, $06, $06, $06, $06, $06, $06
  1630.     dc.b    $06, $06, $06, $06, $06, $06, $06, $06
  1631.     dc.b    $06, $06, $06, $06, $06, $06, $06, $06
  1632.     dc.b    $07, $07, $07, $07, $07, $07, $07, $07
  1633.     dc.b    $07, $07, $07, $07, $07, $07, $07, $07
  1634.     dc.b    $07, $07, $07, $07, $07, $07, $07, $07
  1635.     dc.b    $07, $07, $07, $07, $07, $07, $07, $07
  1636.     dc.b    $07, $07, $07, $07, $07, $07, $07, $07
  1637.     dc.b    $07, $07, $07, $07, $07, $07, $07, $07
  1638.     dc.b    $08, $08, $08, $08, $08, $08, $08, $08
  1639.     dc.b    $08, $08, $08, $08, $08, $08, $08, $08
  1640.  
  1641.         bss
  1642.  
  1643. match_position: ds.w    1
  1644. match_length:    ds.w    1
  1645. crctbl:     ds.w    256
  1646. crc:        ds.w    1
  1647. freq:        ds.w    T+1
  1648. prnt:        ds.w    T+N_CHAR
  1649. son:        ds.w    T
  1650. delen:        ds.l    1
  1651. textsize:    ds.l    1
  1652. getbuf:     ds.w    1
  1653. getlen:     ds.b    1
  1654.         even
  1655. FileFits:    ds.w    1        ; 1, wenn Datei passt
  1656. text_buf:    ds.w    N+F-1
  1657. flg_n:        ds.b    1
  1658.         even
  1659. blkcnt:     ds.l    1
  1660. lson:        ds.w    N+1
  1661. rson:        ds.w    N+257
  1662. dad:        ds.w    N+1
  1663.  
  1664. codesize:    ds.l    1
  1665.         even
  1666.         end
  1667.