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

  1. ; ==================================================================
  2. ;                      xpkNUKE assembler routines
  3. ; ==================================================================
  4.  
  5.     INCLUDE    AINCLUDE:IncDirs.i *sets all includedirs, needed for my ASM
  6.     INCLUDE    DUKE/xpkLibDUKE.i
  7.  
  8.     XDEF    _AsmPack
  9.     XDEF    _AsmUnpack
  10.     XDEF    NoReadN
  11.  
  12. tmp    EQUR    D0
  13. two    EQUR    D1
  14. len    EQUR    D2
  15. off    EQUR    D3
  16. i    EQUR    D5
  17. look    EQUR    D6
  18. arg    EQUR    D7
  19.  
  20. lst    EQUR    A3
  21. buf    EQUR    A5
  22. nxt    EQUR    A6
  23.  
  24.     STRUCTURE NukeData,0
  25.     CPTR    inbuf
  26.     CPTR    outbuf
  27.     CPTR    last
  28.     CPTR    next
  29.     CPTR    cwri
  30.     CPTR    uwri
  31.     CPTR    uend
  32.     CPTR    delpos
  33.     UWORD    ulen
  34.     UWORD    clen
  35.     UWORD    ustop
  36.     UWORD    ustart
  37.     UWORD    ucount
  38.     UWORD    scanrange
  39.     UWORD    room1
  40.     UWORD    room2
  41.     UWORD    room4
  42.     UWORD    roomN
  43.     UWORD    data1
  44.     UWORD    data2
  45.     ULONG    data4
  46.     ULONG    dataN
  47.     CPTR    dest1
  48.     CPTR    dest2
  49.     CPTR    dest4
  50.     CPTR    destN
  51.     ULONG    dummy
  52.     CPTR    contbuf
  53.     ULONG    flags
  54.     LABEL    nd_sizeof
  55.  
  56. starts:    dc.w    0,0,4,10
  57.  
  58. dists:    dc.w    $0010,$0040,$0100,$0200
  59.     dc.w    $0010,$0080,$0200,$0800,$2000,$4000
  60.     dc.w    $0020,$0080,$0200,$0800,$2000,$4000
  61.  
  62.     dc.w    4,6,8,9
  63.     dc.w    4,7,9,11,13,14
  64.     dc.w    5,7,9,11,13,14
  65.  
  66.     dc.w    0,1,2,3
  67.     dc.w    4,5,6,7,8,9
  68.     dc.w    10,11,12,13,14,15
  69.  
  70. modes    dc.w    4,6,8,9
  71.     dc.w    4,7,9,11,13,14
  72.     dc.w    5,7,9,11,13,14
  73.  
  74. adds    dc.w    $0000,$0010,$0050,$0150
  75.     dc.w    $0000,$0010,$0090,$0290,$0a90,$2a90
  76.     dc.w    $0000,$0020,$00a0,$02a0,$0aa0,$2aa0
  77.  
  78.     dc.w    c2-TwoBitLen,c2-TwoBitLen,c2-TwoBitLen,c2-TwoBitLen
  79.     dc.w    c3-TwoBitLen,c3-TwoBitLen,c3-TwoBitLen,c3-TwoBitLen
  80.     dc.w    c3-TwoBitLen,c3-TwoBitLen
  81.     dc.w    0,0,0,0,0,0
  82.  
  83. WRITE0:    MACRO
  84. 30$    SUBQ.W    #1,room1(A4)
  85.     BCC.B    90$
  86.  
  87.     move.l    dest1(a4),a0
  88.     move.w    data1(a4),(a0)
  89.     move.l    cwri(a4),dest1(a4)
  90.     addq.l    #2,cwri(a4)
  91.     move.w    #15,room1(a4)
  92.  
  93. 90$    asl.w    data1(a4)
  94.     ENDM
  95.  
  96. WRITE1:    MACRO
  97. 31$    subq.w    #1,room1(a4)
  98.     bcc.s    91$
  99.  
  100.     move.l    dest1(a4),a0
  101.     move.w    data1(a4),(a0)
  102.     move.l    cwri(a4),dest1(a4)
  103.     addq.l    #2,cwri(a4)
  104.     move.w    #15,room1(a4)
  105.  
  106. 91$    asl.w    data1(a4)
  107.     addq.w    #1,data1(a4)
  108.     ENDM
  109.  
  110.  
  111.  
  112. WRITE2:    MACRO
  113. 32$    subq.w    #2,room2(a4)
  114.     bcc.s    92$
  115.  
  116.     move.l    dest2(a4),a0
  117.     move.w    data2(a4),(a0)
  118.     move.l    cwri(a4),dest2(a4)
  119.     addq.l    #2,cwri(a4)
  120.     move.w    #14,room2(a4)
  121.  
  122. 92$    asl.w    data2(a4)
  123.     asl.w    data2(a4)
  124.     or.w    arg,data2(a4)
  125.     ENDM
  126.  
  127.  
  128.  
  129. WRITE4:    MACRO
  130. 34$    subq.w    #4,room4(a4)
  131.     bcc.s    94$
  132.  
  133.     move.l    dest4(a4),a0
  134.     move.l    data4(a4),(a0)
  135.     move.l    cwri(a4),dest4(a4)
  136.     addq.l    #4,cwri(a4)
  137.     move.w    #28,room4(a4)
  138.     clr.l    data4(a4)
  139.  
  140. 94$    move.l    data4(a4),tmp
  141.     or.w    arg,tmp
  142.     ror.l    #4,tmp
  143.     move.l    tmp,data4(a4)
  144.     ENDM
  145.  
  146.  
  147.  
  148. WRITEN:    MACRO            ; d0,arg,a0
  149. 38$    moveq    #0,d0
  150.     move.l    dataN(a4),d0
  151.     asl.l    arg,d0
  152.     or.l    off,d0
  153.  
  154.     sub.w    arg,roomN(a4)
  155.     bcc.s    99$
  156.  
  157.     move.w    roomN(a4),arg
  158.     neg.w    arg
  159.     ror.l    arg,d0
  160.     move.l    destN(a4),a0
  161.     move.w    d0,(a0)
  162.     move.l    cwri(a4),destN(a4)
  163.     addq.l    #2,cwri(a4)
  164.     rol.l    arg,d0
  165.     neg.w    arg
  166.     add.w    #16,arg
  167.     move.w    arg,roomN(a4)
  168.  
  169. 99$    move.l    d0,dataN(a4)
  170.     ENDM
  171.  
  172.  
  173.  
  174. UNCOMP:    MACRO
  175.     addq.w    #1,ucount(a4)
  176.     bne.s    9$
  177.     move.w    i,ustart(a4)    ; first uncompressed
  178. 9$
  179.     ENDM
  180.  
  181.  
  182.  
  183. WRUNCO:            ; d2=number, Cc,  -d0, -a0, -a1
  184. ;    movem.l    a0-a6/d0-d7,-(sp)    ; DEBUG
  185. ;    bsr    _stat2
  186. ;    movem.l    (sp)+,a0-a6/d0-d7
  187.  
  188.     WRITE0
  189.     move.w    #-1,ucount(a4)    ; reset ucount
  190.  
  191.     move.w    ustart(a4),d0    ; write bytes
  192.     lea    -1(buf,d0.w),a0
  193.     move.l    uwri(a4),a1
  194.     move.w    d7,d0
  195. ;;;    lsr.w    #1,d0
  196. ;;;    bcc.s    86$
  197. 85$    move.b    (a0)+,-(a1)
  198. ;;;86$    move.b    (a0)+,-(a1)
  199.     dbra    d0,85$
  200.     move.l    a1,uwri(a4)
  201.  
  202.     tst.w    d7
  203.     bne.s    long
  204.     WRITE1
  205.     bra    uexit    ; len OK
  206.  
  207. long    move.w    d7,d0
  208.     WRITE0
  209. loop    cmp.w    #3,d0
  210.     ble.s    last3
  211.     moveq    #0,d7
  212.     WRITE2
  213.     subq.w    #3,d0
  214.     bra.s    loop
  215.  
  216. last3    neg.w    d0
  217.     moveq    #3,d7
  218.     and.w    d0,d7
  219.     WRITE2
  220.  
  221. uexit    rts
  222.  
  223.  
  224.  
  225. _AsmPack:
  226.     movem.l    d2-d7/a2-a6,-(sp)
  227. ;    illegal        ; Debug
  228.     bsr    init
  229.  
  230.     moveq    #0,d0
  231.     moveq    #0,two
  232.     moveq    #0,d7
  233. ;================= Main loop
  234. mainloop:
  235. ;    movem.l    a0-a6/d0-d7,-(sp)    ; DEBUG
  236. ;    bsr    _stat3
  237. ;    movem.l    (sp)+,a0-a6/d0-d7
  238.  
  239.     moveq    #0,two
  240.     move.b    -1(buf,i.w),two
  241.     asl.w    #8,two
  242.     move.b    0(buf,i.w),two
  243.     add.l    two,two
  244.  
  245. ;================= Test compressable
  246.     move.w    0(lst,two.l),look
  247.     bne.s    byterunchk
  248.  
  249. ;================= Not compressable
  250. uncompressable
  251.     UNCOMP
  252.     move.w    i,0(lst,two.l)
  253.     addq.w    #1,i
  254.  
  255.     cmp.w    ustop(a4),i
  256.     blt.s    mainloop
  257.     bra    mainexit
  258.  
  259. ;================= Byterun
  260. byterunchk
  261.     move.b    -1(buf,i.w),d0
  262.     cmp.b    0(buf,i.w),d0
  263.     bne.s    getmatch
  264.  
  265.     lea    1(buf,i.w),a0
  266.     move.l    a0,a1
  267.  
  268.     move.w    ustop(a4),d4
  269.     sub.w    i,d4
  270. 1$    cmp.b    (a0)+,d0
  271.     dbne    d4,1$
  272.  
  273.  
  274.     move.l    a0,len
  275.     cmp.l    uend(a4),len
  276.     ble.s    3$
  277.     move.l    uend(a4),len
  278. 3$    sub.l    a1,len
  279.     cmp.w    #2,len
  280.     ble.s    getmatch ; ble
  281.  
  282.     moveq    #1,off
  283.     subq.w    #1,len
  284.  
  285.     UNCOMP
  286.     addq.w    #1,i
  287.     bra    gooddeal
  288.  
  289. ;================= Getmatch
  290. getmatch
  291.  
  292.     cmp.w    scanrange(a4),i    ; do we have to start deleting old entries?
  293.     bls.s    nodel
  294.  
  295.     moveq    #0,d7
  296.     move.w    i,d7
  297.     sub.w    scanrange(a4),d7
  298.     add.w    d7,d7
  299.     lea    0(nxt,d7.l),a1
  300.  
  301.     move.l    delpos(a4),a0
  302.     moveq    #0,d7
  303. 1$    move.l    d7,(a0)+    ; del two entries at once.
  304.     cmp.l    a0,a1
  305.     bcc.s    1$
  306.     move.l    a0,delpos(a4)
  307.  
  308. nodel
  309.     move.w    i,d4        ; lowlim = i-scanrange
  310.     sub.w    scanrange(a4),d4
  311.     bcc.s    1$
  312.     moveq    #0,d4
  313. 1$
  314.     lea    1(buf,i.w),a0    ; maxlenpos= buf+i+1
  315.     move.l    a0,d2
  316.     addq.l    #1,d2
  317.     move.l    a0,d0        ; cmpstart = buf+i+1
  318.     move.b    (a0),d7        ; testbyte = buf[i+1]
  319.  
  320.     move.l    buf,d3        ; foundpos = scanbuf+look
  321.     add.l    look,d3
  322.     addq.l    #2,d3
  323.  
  324.     move.l    buf,a2        ; testbase= buf
  325.     move.w    i,(nxt)        ; next[0]=i
  326.  
  327.     bra.s    ientry
  328.  
  329. ;================= Inner loop
  330. couldbemax:
  331.     lea    1(buf,look.w),a0    ; cmp1= scanbase+look
  332.     move.l    d0,a1        ; cmp2= scanstart
  333. 1$
  334.     cmpm.b    (a0)+,(a1)+    ; while(*cmp1++==*cmp2++)
  335.     beq.s    1$        ;   ;
  336.  
  337.     cmp.l    a1,d2        ; if( len>=maxlen )
  338.     bcc.s    NoNewMax
  339.  
  340. ;    tst.w    look
  341. ;    beq.s    FoundBestMatch
  342.  
  343.     cmp.w    d4,look        ;    if( look<=lowlim )
  344.     bls.s    FoundBestMatch    ;        goto QuitII
  345.  
  346.     sub.l    d2,a2        ;    testbase+= maxlen-len
  347.     add.l    a1,a2
  348.     move.l    a1,d2        ;    maxlenpos= len
  349.     move.l    a0,d3        ;    foundpos = cmp1
  350.     move.b    -(a1),d7    ;    testbyte = *(cmp2-1)
  351. NoNewMax:
  352.  
  353. ;================= Inner sanctum
  354. InnerInner:
  355.     add.w    look,look
  356.     move.w    0(nxt,look.l),look    ; look=Next[look]
  357. ientry    cmp.b    1(a2,look.w),d7
  358.     beq.s    1$
  359.  
  360.     add.w    look,look
  361.     move.w    0(nxt,look.l),look    ; look=Next[look]
  362.     cmp.b    1(a2,look.w),d7
  363.     bne.s    InnerInner
  364.  
  365. 1$    cmp.w    i,look
  366.     bne.s    couldbemax
  367.  
  368. ;================= Compute offs
  369.  
  370. FoundBestMatch:
  371.     sub.l    d2,off        ; offset = foundpos-maxlenpos
  372.     neg.l    off
  373.  
  374. ;    cmp.w    scanrange(a4),d0
  375. ;    ble.s    ok
  376. ;bug    nop
  377.  
  378. gotoffs    cmp.l    uend(a4),len
  379.     ble.s    nooverr
  380. overr    move.l    uend(a4),len
  381. nooverr    sub.l    d0,len        ; maxlen= maxlenpos-cmpstart
  382.     moveq    #0,d0
  383.  
  384.  
  385. ;================= Check if good deal
  386.     cmp.w    #1,len
  387.     bgt.s    gooddeal
  388.     cmp.w    #$150,off    ; FIXME!  (fixed CvR V1.03)
  389.     bcs.s    gooddeal
  390.  
  391.     moveq    #0,d7
  392.     move.w    i,d7
  393.     add.l    d7,d7
  394.     move.w    0(lst,two.l),0(nxt,d7.l)
  395.     bra    uncompressable
  396.  
  397. ;================= Compressable
  398. gooddeal
  399.     move.w    ucount(a4),d7    ; write uncompressed
  400.     blt.s    1$
  401.     jsr    WRUNCO
  402.     bra.s    hadunco
  403. 1$    WRITE1
  404.  
  405. hadunco
  406. ;    movem.l    a0-a6/d0-d7,-(sp)    ; DEBUG
  407. ;    bsr    _stat
  408. ;    movem.l    (sp)+,a0-a6/d0-d7
  409.  
  410.  
  411.     move.l    len,d0
  412.     cmp.w    #3,d0
  413.     ble.s    getmode
  414.     moveq    #3,d0
  415. ;================= Getmode
  416.  
  417. getmode    lea    starts(pc),a2
  418.     add.w    d0,d0
  419.     move.w    0(a2,d0.w),d0
  420.  
  421.     lea    dists(pc),a2
  422.     add.w    d0,d0
  423.     add.w    d0,a2
  424.  
  425. 2$    cmp.w    (a2),off
  426.     blt.s    wrmode
  427. 3$    sub.w    (a2)+,off
  428.     cmp.w    (a2),off
  429.     bge.s    3$
  430.  
  431. wrmode    move.w    64(a2),d7
  432.     WRITE4
  433.  
  434. wroffs    move.w    32(a2),d7
  435.     WRITEN
  436.  
  437.     cmp.w    #2,len
  438.     ble    genentries
  439.  
  440. ;================= Write len
  441. wrlen    move.l    len,d0
  442.     cmp.w    #5,d0
  443.     bgt.s    longlen
  444.  
  445.     subq.w    #3,d0
  446.     not.w    d0
  447.     moveq    #3,d7
  448.     and.w    d0,d7
  449.     WRITE2
  450.     bra    genentries
  451.  
  452. longlen    moveq    #0,d7
  453.     WRITE2
  454.     subq.w    #6,d0
  455. 1$    cmp.w    #14,d0
  456.     ble.s    last15
  457.     moveq    #0,d7
  458.     move.l    d0,-(sp)
  459.     WRITE4
  460.     move.l    (sp)+,d0
  461.     sub.w    #15,d0
  462.     bra.s    1$
  463.  
  464. last15    not.w    d0
  465.     moveq    #15,d7
  466.     and.w    d0,d7
  467.     WRITE4
  468.  
  469. ;================= Gen entries
  470. genentries
  471.     lea    1(buf,i.w),a0
  472.     move.w    i,d7
  473.     add.w    d7,d7
  474.     lsr.l    #1,two
  475.  
  476. ;    cmp.w    #1,off    ;
  477. ;    bne.s    entry    ;
  478.  
  479. ;    add.w    len,i    ;
  480. ;    addq.w    #1,i    ;
  481. ;    bra.s    mainchk    ;
  482.  
  483.     bra.s    entry
  484.  
  485. eloop    lsl.w    #8,two
  486.     move.b    (a0)+,two
  487. entry    lea    0(lst,two.l),a1
  488.     add.l    two,a1
  489.     move.w    (a1),0(nxt,d7.l)
  490.     move.w    i,(a1)
  491.     addq.w    #2,d7
  492.     addq.w    #1,i
  493.     dbra    len,eloop
  494.  
  495. ;================= End
  496. mainchk
  497. ;;;    add.l    two,two    ; not needed, since mainloop does recalculate it
  498.     cmp.w    ustop(a4),i
  499.     blt    mainloop
  500. mainexit
  501.     bsr    flush
  502.     bsr    compact
  503.  
  504.     movem.l    (sp)+,d2-d7/a2-a6
  505.     rts
  506.  
  507. ;======================================================================
  508. init    moveq    #0,d0
  509.     move.w    d0,room1(a4)
  510.     move.w    d0,room2(a4)
  511.     move.w    d0,room4(a4)
  512.     move.w    d0,roomN(a4)
  513.  
  514.     move.w    d0,data1(a4)
  515.     move.w    d0,data2(a4)
  516.     move.l    d0,data4(a4)
  517.     move.l    d0,dataN(a4)
  518.  
  519.     lea    dummy(a4),a0
  520.     move.l    a0,dest1(a4)
  521.     move.l    a0,dest2(a4)
  522.     move.l    a0,dest4(a4)
  523.     move.l    a0,destN(a4)
  524.  
  525.     move.l    last(a4),lst
  526.     move.l    inbuf(a4),buf
  527.     move.l    next(a4),nxt
  528.  
  529.     move.l    nxt,delpos(a4)
  530.     move.w    #$6a90,scanrange(a4)    ; $6aa0
  531.     subq.w    #1,scanrange(a4)
  532.  
  533.     move.l    outbuf(a4),cwri(a4)
  534.     move.l    outbuf(a4),a0
  535.     add.w    clen(a4),a0
  536.     move.l    a0,uwri(a4)
  537.  
  538.     move.l    inbuf(a4),a0
  539.     add.w    ulen(a4),a0
  540.     move.l    a0,uend(a4)
  541.  
  542.     move.w    ulen(a4),ustop(a4)
  543.     subq.w    #1,ustop(a4)
  544.  
  545.     moveq    #1,i
  546.     moveq    #0,two
  547.     moveq    #0,look
  548.  
  549.     move.w    #-1,ucount(a4)
  550.     move.w    #0,ustart(a4)
  551.     rts
  552.  
  553. ;======================================================================
  554. flush
  555.     cmp.w    ulen(a4),i
  556.     beq.s    just1
  557.     UNCOMP
  558. just1    UNCOMP
  559.     move.w    ucount(a4),d7
  560.     bsr    WRUNCO
  561.  
  562.     move.l    dest1(a4),a0
  563.     move.w    data1(a4),d0
  564.     move.w    room1(a4),d1
  565.     lsl.w    d1,d0
  566.     move.w    d0,(a0)
  567.  
  568.     move.l    dest2(a4),a0
  569.     move.w    data2(a4),d0
  570.     move.w    room2(a4),d1
  571.     lsl.w    d1,d0
  572.     move.w    d0,(a0)
  573.  
  574.     move.l    dest4(a4),a0
  575.     move.l    data4(a4),d0
  576.     move.w    room4(a4),d1
  577.     lsr.l    d1,d0
  578.     move.l    d0,(a0)
  579.  
  580.     move.l    destN(a4),a0
  581.     move.w    dataN+2(a4),d0
  582.     move.w    roomN(a4),d1
  583.     lsl.w    d1,d0
  584.     move.w    d0,(a0)
  585.  
  586.     rts
  587.  
  588.  
  589. ;======================================================================
  590. compact    move.l    uwri(a4),d0
  591.     sub.l    cwri(a4),d0
  592.     bge.s    3$
  593.  
  594.     moveq    #-1,d0
  595.     bra.s    exitc
  596.  
  597. 3$    move.l    uwri(a4),a2
  598.     move.l    outbuf(a4),a0
  599.     add.w    clen(a4),a0
  600.     sub.l    uwri(a4),a0
  601.     move.l    a0,d2
  602.     move.l    cwri(a4),a1
  603.  
  604. 1$    move.l    a1,d0
  605.     add.l    d2,d0
  606.     moveq    #3,d1
  607.     and.l    d0,d1
  608.     beq.s    copy
  609.     move.b    #$FB,(a1)+
  610.     bra.s    1$
  611.  
  612. copylp    move.b    (a2)+,(a1)+
  613. copy    dbra    d2,copylp
  614.  
  615.     move.l    a1,d0
  616.     sub.l    outbuf(a4),d0
  617. exitc    rts
  618.  
  619. ; d0=cmpstart     a0=cmp1
  620. ; d1=twochars+    a1=cmp2
  621. ; d2=maxlenpos    a2=testbase
  622. ; d3=foundpos     a3=lst+
  623. ; d4=lowerlimit   a4=
  624. ; d5=i+           a5=buf+
  625. ; d6=look+        a6=nxt+
  626. ; d7=testbyte     a7=
  627.  
  628. ;***************************************************************************
  629.  
  630.  
  631. _AsmUnpack
  632.     movem.l    d2-d7/a3-a6,-(a7)
  633.     MOVEA.L    A1,A5            ; only because of Maxon A5 problem
  634.     moveq    #16,d0
  635.     move.l    d0,a3
  636.     lea    modes,a6
  637.     moveq    #0,d0
  638.     moveq    #0,d1
  639.     move.w    #$8000,d2
  640.     move.w    #$8000,d3
  641.     moveq    #0,d4
  642.     moveq    #0,d5
  643.     moveq    #0,d6
  644.     moveq    #0,d7
  645.     bsr    TestCompressed
  646.     move.l    a0,d0
  647.     movem.l    (a7)+,d2-d7/a3-a6
  648.     rts
  649.  
  650. ; d0 mode        a0 writepos
  651. ; d1 offslen/offset    a1 copysrc
  652. ; d2 1bit_data        a2 writeend
  653. ; d3 2bits_data        a3 16
  654.  
  655. ; d4 4bits_data        a4 byteread
  656. ; d5 4bits_in        a5 wordread
  657. ; d6 xbits_data        a6 table
  658. ; d7 -xbits_in        a7
  659.  
  660. Compressed:
  661.     dbra    d5,NoRead4        ; 70    Read 4 bits (mode)
  662.     moveq    #7,d5            ; 8
  663.     move.l    (a5)+,d4        ; |
  664.     add.l    d4,d4            ; |
  665. NoRead4:                ;
  666.     moveq    #30,d0            ; 70
  667.     and.w    d4,d0            ; |
  668.     roxr.l    #4,d4            ; |
  669.                     ; |
  670.     move.w    0(a6,d0.w),d1        ; |
  671.                     ; |
  672.     clr.w    d6            ; |
  673.     rol.l    d1,d6            ; |    Read n bits (offset)
  674.     add.w    d1,d7            ; |     ble jumps on N|(Z^V)
  675.     ble.s    NoReadN            ; |    the add does never set V
  676.     moveq    #0,d1            ; 35
  677.     move.w    (a5)+,d1        ; |
  678.     asl.l    d7,d1            ; |    
  679.     swap    d1            ; |
  680.     or.l    d1,d6            ; |
  681.     sub.w    a3,d7            ; |
  682. NoReadN:                ;
  683.     move.l    a0,a1            ; 70
  684.     add.w    32(a6,d0.w),d6        ; |
  685.     sub.w    d6,a1            ; |
  686.                     ; |
  687.     move.w    64(a6,d0.w),d0        ; |
  688.     jmp    TwoBitLen(pc,d0.w)
  689.  
  690. TwoBitLen:
  691.     move.b    (a1)+,(a0)+        ; 21
  692.     move.b    (a1)+,(a0)+        ; |
  693.     move.b    (a1)+,(a0)+        ; |
  694.                     ; |
  695.     moveq    #0,d0            ; |    Read 2 bits (clen1)
  696.     add.w    d3,d3            ; |
  697.     bne.s    NoRead2x        ; |
  698.     move.w    (a5)+,d3        ; 1
  699.     addx.w    d3,d3            ; |
  700. NoRead2x:                ;
  701.     addx.w    d0,d0            ; 9
  702.     add.w    d3,d3            ; |
  703.     addx.w    d0,d0            ; |
  704.  
  705.     add.w    d0,d0
  706.     jmp    CJTable(pc,d0.w)
  707. CJTable:
  708.     bra.s    Tab15
  709. c3:    move.b    (a1)+,(a0)+        ; 21
  710. c2:    move.b    (a1)+,(a0)+        ; 21
  711.     move.b    (a1)+,(a0)+        ; |
  712.  
  713. ;----------------------------------------
  714. TestCompressed:                ;
  715.     add.w    d2,d2            ; 70    Read 1 (cbit)
  716.     bcc.s    Uncompressed        ; |
  717.     bne.s    Compressed        ; |
  718.     move.w    (a5)+,d2        ; 4
  719.     addx.w    d2,d2            ; |
  720.     bcs.s    Compressed        ; 70
  721. ;----------------------------------------
  722.  
  723. Uncompressed:                ;
  724.     add.w    d2,d2            ; 30    Read 1 (ulen1)
  725.     bne.s    1$            ; |
  726.     move.w    (a5)+,d2        ; 2
  727.     addx.w    d2,d2            ; |
  728. 1$                    ;
  729.     bcc.s    Copy3Entry        ; 30
  730.     move.b    -(a4),(a0)+        ; 15
  731. TestExit:                ; |
  732.     cmp.l    a2,a0            ; |
  733.     blt    Compressed        ; |
  734.     rts
  735.  
  736. CopyThree:
  737.     move.b    -(a4),(a0)+        ; 9
  738.     move.b    -(a4),(a0)+        ; |
  739.     move.b    -(a4),(a0)+        ; |
  740. Copy3Entry:
  741.     moveq    #0,d0            ; 30    Read 2 (ulen2)
  742.     add.w    d3,d3            ; |
  743.     bne.s    NoRead2a        ; |
  744.     move.w    (a5)+,d3        ; 4
  745.     addx.w    d3,d3            ; |
  746. NoRead2a:                ;
  747.     addx.w    d0,d0            ; 30
  748.     add.w    d3,d3            ; |
  749.     addx.w    d0,d0            ; |
  750.     add.w    d0,d0            ; |
  751.     jmp    UJTable(pc,d0.w)    ; |
  752.  
  753. UJTable:
  754.     bra.s    CopyThree        ; 3
  755.     move.b    -(a4),(a0)+        ; 7
  756.     move.b    -(a4),(a0)+        ; 10
  757.     move.b    -(a4),(a0)+        ; 15
  758.     move.b    -(a4),(a0)+        ; 15
  759.     cmp.l    a2,a0            ; |
  760.     blt    Compressed        ; |
  761.     rts                ;
  762.  
  763. ;---------------------------------------
  764. FJTable:
  765.     moveq    #0,d0
  766.     move.b    (a1)+,(a0)+        ; |
  767.     move.b    (a1)+,(a0)+        ; |
  768.     move.b    (a1)+,(a0)+        ; |
  769.  
  770.     move.b    (a1)+,(a0)+        ; |
  771.     move.b    (a1)+,(a0)+        ; |
  772.     move.b    (a1)+,(a0)+        ; |
  773.     move.b    (a1)+,(a0)+        ; |
  774.  
  775.     move.b    (a1)+,(a0)+        ; |
  776.     move.b    (a1)+,(a0)+        ; |
  777.     move.b    (a1)+,(a0)+        ; |
  778.     move.b    (a1)+,(a0)+        ; |
  779.  
  780.     move.b    (a1)+,(a0)+        ; |
  781. Tab15    move.b    (a1)+,(a0)+        ; |
  782.     move.b    (a1)+,(a0)+        ; |
  783.     move.b    (a1)+,(a0)+        ; |
  784.     tst.b    d0
  785.     bne.s    TestCompressed
  786.  
  787.     dbra    d5,1$
  788.     moveq    #7,d5
  789.     move.l    (a5)+,d4
  790.     add.l    d4,d4
  791. 1$
  792.     moveq    #30,d0
  793.     and.w    d4,d0
  794.     roxr.l    #4,d4
  795.  
  796.     jmp    FJTable(pc,d0.w)
  797.  
  798.     END
  799.