home *** CD-ROM | disk | FTP | other *** search
/ ftp.barnyard.co.uk / 2015.02.ftp.barnyard.co.uk.tar / ftp.barnyard.co.uk / cpm / walnut-creek-CDROM / ENTERPRS / CPM / UTILS / S / UNZIP12.ARK / UNZIP12.Z < prev   
Text File  |  1989-09-27  |  17KB  |  1,417 lines

  1. .var    STRSIZ    256
  2. .var    EXTRACT    'E'
  3. .var    bdos    5
  4. .var    open    0x0f
  5. .var    close    0x10
  6. .var    read    0x14
  7. .var    write    0x15
  8. .var    create    0x16
  9. .var    setdma    0x1a
  10. .var    infcb    0x5c
  11. .var    DLE    144
  12. .var    max_bits 13
  13. .var    init_bits 9
  14. .var    hsize    8192
  15. .var    first_ent 257
  16. .var    clear    256
  17. .var    maxcmax    1 << max_bits
  18.  
  19.     jr    start
  20.     db    '\r'
  21. usage:    db    'Usage: UNZIP ZIPFILE [E]\r\n'
  22.     db    'E - extract files\r\n'
  23.     db    '    default is to just list files\r\n\0',0x1a
  24. start:    ld    sp,(6)        ; set the stack pointer
  25.     call    ilprt
  26.     db    'UNZIP  V1.2 - DPG  1990\r\n\n\0'
  27.     ld    a,(0x5d)    ; filename?
  28.     cp    ' '
  29.     jr    nz,wasfil
  30.     ld    hl,usage
  31.     call    pstr
  32.     rst    0
  33. wasfil:    ld    a,(0x6d)    ; option letter?
  34. .useg
  35. mode:    ds    1
  36. .dseg
  37. zipeof:    db    2
  38. counting:
  39.     db    0
  40. .cseg
  41.     xor    EXTRACT        ; 'E' for extract
  42.     ld    (mode),a    ; set the mode
  43.     ld    a,(0x65)
  44.     cp    0x20
  45.     jr    nz,wasext
  46.     ld    hl,['I' << 8] + 'Z'
  47.     ld    (0x65),hl
  48.     ld    a,'P'
  49.     ld    (0x67),a    ; install .ZIP extent
  50. wasext:    ld    de,0x5c
  51.     ld    c,open
  52.     call    bdos        ; try and open it
  53.     inc    a
  54.     jr    nz,openok    ; ok
  55.     call    ilprt
  56.     db    'Couldn\'t find ZIP file\r\n\0'
  57.     rst    0        ; complain and exit
  58. sigerr:    call    ilprt
  59.     db    'Bad signature in ZIP file\r\n\0'
  60.     rst    0
  61. openok:    call    getword
  62.     ld    de,-[['K' << 8] + 'P']
  63.     add    hl,de
  64.     ld    a,h
  65.     or    l
  66.     jr    nz,sigerr
  67.     call    getword
  68.     dec    l
  69.     jr    nz,nocfhs
  70.     dec    h
  71.     dec    h
  72.     jr    nz,sigerr
  73.     call    pcfh
  74.     jr    openok
  75. nocfhs:    dec    l
  76.     dec    l
  77.     jr    nz,nolfhs
  78.     ld    a,h
  79.     sub    4
  80.     jr    nz,sigerr
  81.     call    plfh
  82.     jr    openok
  83. nolfhs:    dec    l
  84.     dec    l
  85.     jr    nz,sigerr
  86.     ld    a,h
  87.     sub    6
  88.     jr    nz,sigerr
  89.     call    pecd
  90.     rst    0
  91.  
  92. pcfh:    ld    b,12
  93. pcfhl1:    push    bc
  94.     call    getword
  95.     pop    bc
  96.     djnz    pcfhl1
  97.     call    getword
  98.     push    hl
  99.     call    getword
  100.     push    hl
  101.     call    getword
  102.     pop    de
  103.     pop    bc
  104.     push    hl
  105.     push    de
  106.     push    bc
  107.     ld    b,6
  108. pcfhl2:    push    bc
  109.     call    getword
  110.     pop    bc
  111.     djnz    pcfhl2
  112.     pop    hl
  113.     ld    de,junk
  114. .useg
  115. junk:    ds    STRSIZ
  116. .cseg
  117.     call    getstring
  118.     pop    hl
  119.     ld    de,junk
  120.     call    getstring
  121.     pop    hl
  122.     ld    de,junk
  123.     call    getstring
  124.     ret
  125.  
  126. pecd:    ld    b,8
  127. pecdl:    push    bc
  128.     call    getword
  129.     pop    bc
  130.     djnz    pecdl
  131.     call    getword
  132.     ld    de,junk
  133.     call    getstring
  134.     ret
  135.  
  136. .useg
  137. lfh:
  138. vnte:    ds    2
  139. gpbf:    ds    2
  140. cm:    ds    2
  141. lmft:    ds    2
  142. lmfd:    ds    2
  143. crc:    ds    4
  144. cs:    ds    4
  145. ucs:    ds    4
  146. fnl:    ds    2
  147. efl:    ds    2
  148. endlfh:
  149.     ds    1
  150. .cseg
  151.  
  152. plfh:    ld    de,lfh
  153.     ld    hl,{endlfh - lfh}
  154.     call    getstring
  155.     ld    hl,opfcb
  156.     ld    de,opfcb + 1
  157.     ld    bc,32
  158.     ld    (hl),b
  159.     ldir
  160. .useg
  161. opfcb:    ds    1
  162. opfn:    ds    8
  163. opext:    ds    3
  164.     ds    4 + 16 + 1
  165. .cseg
  166.     ld    de,junk
  167.     ld    hl,(fnl)
  168.     call    getstring
  169.     ld    de,junk + 20
  170.     ld    hl,(efl)
  171.     call    getstring
  172.     ld    de,junk
  173.     ld    hl,opfn
  174.     ld    b,8
  175.     call    scanfn
  176.     ld    a,(de)
  177.     cp    '.'
  178.     jr    nz,nodot
  179.     inc    de
  180. nodot:    ld    b,3
  181.     call    scanfn
  182.     ld    hl,init
  183.     ld    de,vars
  184.     ld    bc,{endinit - init}
  185.     ldir
  186. .useg
  187. bitbuf:    ds    1
  188.  
  189. .useg
  190. vars:
  191. .dseg
  192. init:
  193.  
  194. .useg
  195. bleft:    ds    1
  196. .dseg
  197.     db    0
  198. .useg
  199. wrtpt:    ds    1
  200. .dseg
  201.     db    0
  202. .useg
  203. outpos:    ds    4
  204. .dseg
  205.     dw    0,0
  206. .useg
  207. crc32:
  208.     ds    4
  209. .dseg
  210.     dw    -1,-1
  211. endinit:
  212. .useg
  213. curmode:
  214.     ds    1
  215. .cseg
  216.  
  217.     ld    a,(mode)
  218. resmod:    ld    (curmode),a
  219.     or    a
  220.     jr    nz,extrct
  221.     ld    de,opfcb
  222.     ld    c,0x0f
  223.     call    bdos
  224.     inc    a
  225.     jr    z,creok
  226.     ld    hl,junk
  227.     call    pstr
  228.     call    ilprt
  229.     db    ' already exists\0'
  230. noex:    call    ilprt
  231.     db    ' -- not extracting\0'
  232.     ld    a,0xff
  233.     jr    resmod
  234. extrct:    xor    a
  235.     ld    (zipeof),a
  236.     ld    a,(curmode)
  237.     dec    a
  238.     jp    m,doext
  239.     call    ilprt
  240.     db    'Checking \0'
  241.     jr    pjunk
  242. creok:    ld    de,opfcb
  243.     ld    c,create
  244.     call    bdos
  245.     inc    a
  246.     jr    nz,opnok1
  247.     call    ilprt
  248.     db    'Error creating \0'
  249.     ld    hl,junk
  250.     call    pstr
  251.     jr    noex
  252. opnok1:    call    ilprt
  253.     db    'Extracting \0'
  254. pjunk:    ld    hl,junk
  255.     call    pstr
  256. doext:    call    ilprt
  257.     db    ' -- \0'
  258.     ld    hl,counting
  259.     inc    (hl)
  260.     ld    a,(cm)
  261.     or    a
  262.     jr    nz,case1
  263. case0w:    ld    a,(zipeof)
  264.     and    1
  265.     jr    nz,closeo
  266. savcs0:    call    getbyte
  267.     call    outbyte
  268.     jr    case0w
  269. case1:    dec    a
  270.     jr    nz,case2p
  271.     call    unshrink
  272.     jr    closeo
  273. case2p:    dec    a
  274.     cp    4
  275.     jr    nc,tryimp
  276.     call    unreduce
  277.     jr    closeo
  278. tryimp:    jr    nz,badzip
  279.     call    unimplode
  280.     jr    closeo
  281. badzip:    call    ilprt
  282.     db    'Unknown compression method\r\n\0'
  283.     ret
  284. closeo:    ld    hl,zipeof
  285.     dec    (hl)
  286.     inc    hl
  287.     dec    (hl)
  288.     ld    a,(mode)
  289.     or    a
  290.     jr    nz,nocls
  291.     ld    hl,wrtpt
  292.     ld    a,(hl)
  293.     or    a
  294.     jr    z,noflsh
  295.     ld    de,opbuf
  296. .useg
  297. opbuf:    ds    128
  298. .cseg
  299.     ld    c,setdma
  300.     call    bdos
  301.     ld    de,opfcb
  302.     ld    c,write
  303.     call    bdos
  304. noflsh:    ld    de,opfcb
  305.     ld    c,close
  306.     call    bdos
  307. nocls:    ld    hl,crc32
  308.     ld    de,crc
  309.     scf
  310.     ld    bc,4 << 8
  311. crcclp:    ld    a,(de)
  312.     adc    a,(hl)
  313.     push    af
  314.     or    c
  315.     ld    c,a
  316.     pop    af
  317.     inc    hl
  318.     inc    de
  319.     djnz    crcclp
  320.     ld    a,c
  321.     or    a
  322.     jr    z,crcok
  323.     call    ilprt
  324.     db    'CRC error\r\n\0'
  325.     ret
  326. crcok:    call    ilprt
  327.     db    'CRC OK\r\n\0'
  328.     ret
  329.  
  330. getchla:
  331.     call    getcode
  332.     ld    (code),hl
  333.     ld    a,(zipeof)
  334.     and    1
  335.     ret
  336.  
  337. savstk:
  338.     ld    hl,(stackp)
  339.     dec    hl
  340.     ld    (stackp),hl
  341.     ld    (hl),a
  342.     ret
  343.  
  344. getcode:
  345.     ld    a,(codesize)
  346. readbits:
  347.     ld    hl,0x8000
  348. bitlp:    push    af
  349.     push    hl
  350. getbit:    ld    hl,bleft
  351.     dec    (hl)
  352.     jp    m,readbt
  353.     dec    hl
  354.     rr    (hl)
  355.     pop    hl
  356.     rr    h
  357.     rr    l
  358.     pop    af
  359.     dec    a
  360.     jr    nz,bitlp
  361. finbit:    srl    h
  362.     rr    l
  363.     jr    nc,finbit
  364.     ld    a,l
  365.     ret
  366. readbt:    push    hl
  367.     call    getbyte
  368.     pop    hl
  369.     ld    (hl),8
  370.     dec    hl
  371.     ld    (hl),a
  372.     jr    getbit
  373.  
  374. scanfn:    ld    a,(de)
  375.     cp    '.'
  376.     jr    z,nocopy
  377.     or    a
  378.     jr    z,nocopy
  379.     inc    de
  380.     dec    b
  381.     jp    m,scanfn
  382.     ld    (hl),a
  383.     inc    hl
  384.     jr    scanfn
  385. nocopy:    dec    b
  386.     ret    m
  387.     ld    (hl),' '
  388.     inc    hl
  389.     jr    nocopy
  390.  
  391. ilprt:    pop    hl
  392.     call    pstr
  393.     jp    (hl)
  394.  
  395. pstr:    ld    a,(hl)
  396.     or    a
  397.     ret    z
  398.     push    hl
  399.     ld    e,a
  400.     ld    c,2
  401.     call    bdos
  402.     pop    hl
  403.     inc    hl
  404.     jr    pstr
  405.  
  406. getstring:
  407.     ld    a,h
  408.     or    l
  409.     ld    (de),a
  410.     ret    z
  411.     push    de
  412.     push    hl
  413.     call    getbyte
  414.     pop    hl
  415.     pop    de
  416.     ld    (de),a
  417.     inc    de
  418.     dec    hl
  419.     jr    getstring
  420.  
  421. getword:
  422.     call    getbyte
  423.     push    af
  424.     call    getbyte
  425.     pop    hl
  426.     ld    l,h
  427.     ld    h,a
  428.     ret
  429.  
  430. getbyte:
  431.     ld    a,(zipeof)
  432.     and    1
  433.     ld    a,0x1a
  434.     ret    nz
  435.     ld    a,(counting)
  436.     or    a
  437.     jr    z,skpdci
  438.     ld    hl,(cs)
  439.     ld    de,(cs + 2)
  440.     ld    a,d
  441.     or    e
  442.     or    h
  443.     or    l
  444.     jr    nz,noteof
  445.     ld    hl,zipeof
  446.     inc    (hl)
  447.     ld    a,0x1a
  448.     ret
  449. noteof:    ld    a,h
  450.     or    l
  451.     dec    hl
  452.     ld    (cs),hl
  453.     jr    nz,skpdci
  454.     dec    de
  455.     ld    (cs + 2),de
  456. skpdci:    ld    hl,readpt
  457. .dseg
  458. readpt:    db    0
  459. .cseg
  460.     ld    a,(hl)
  461.     or    a
  462.     jr    nz,ptok
  463.     ld    de,0x80
  464.     ld    (hl),e
  465.     push    hl
  466.     ld    c,setdma
  467.     call    bdos
  468.     ld    de,infcb
  469.     ld    c,read
  470.     call    bdos
  471.     or    a
  472.     pop    hl
  473.     jr    nz,ateof
  474. ptok:    ld    a,(hl)
  475.     inc    (hl)
  476.     ld    l,a
  477.     ld    h,0
  478.     ld    a,(hl)
  479.     ret
  480. ateof:    ld    a,0x1a
  481.     ret
  482.  
  483. outb:
  484.     ld    hl,(outpos)
  485.     push    hl
  486.     push    af
  487.     ld    a,h
  488.     and    0x1f
  489.     ld    h,a
  490.     pop    af
  491.     ld    de,outbuf
  492.     add    hl,de
  493.     ld    (hl),a
  494.     pop    hl
  495.     inc    hl
  496.     ld    (outpos),hl
  497.     push    af
  498.     ld    a,h
  499.     or    l
  500.     jr    nz,nopos
  501.     ld    hl,(outpos + 2)
  502.     inc    hl
  503.     ld    (outpos + 2),hl
  504. nopos:    pop    af
  505.  
  506. outbyte:
  507.     push    af
  508.     call    updcrc
  509.     ld    hl,(ucs)
  510.     ld    de,(ucs + 2)
  511.     ld    a,h
  512.     or    l
  513.     dec    hl
  514.     ld    (ucs),hl
  515.     jr    nz,tsthl0
  516.     dec    de
  517.     ld    (ucs + 2),de
  518. tsthl0:    ld    a,h
  519.     or    l
  520.     or    d
  521.     or    e
  522.     jr    nz,noeof
  523.     ld    hl,zipeof
  524.     inc    (hl)
  525. noeof:    ld    a,(mode)
  526.     or    a
  527.     jr    nz,popret
  528.     ld    hl,wrtpt
  529.     ld    a,(hl)
  530.     add    a,a
  531.     jr    nc,wptok
  532.     ld    de,opbuf
  533.     ld    c,setdma
  534.     call    bdos
  535.     ld    de,opfcb
  536.     ld    c,write
  537.     call    bdos
  538.     or    a
  539.     jr    z,wptok
  540.     ld    (mode),a
  541.     call    ilprt
  542.     db    'Write Error\r\n\0'
  543. popret:    pop    af
  544.     ret
  545. wptok:    jr    nz,nofilb
  546.     ld    hl,opbuf
  547.     ld    de,opbuf + 1
  548.     ld    bc,127
  549.     ld    (hl),0x1a
  550.     ldir
  551.     xor    a
  552.     ld    (wrtpt),a
  553. nofilb:    pop    af
  554.     ld    hl,wrtpt
  555.     inc    (hl)
  556.     ld    l,(hl)
  557.     ld    h,0
  558.     ld    de,opbuf - 1
  559.     add    hl,de
  560.     ld    (hl),a
  561.     ret
  562.  
  563. updcrc:    ld    hl,(crc32)
  564.     ld    de,(crc32 + 2)
  565.     ld    c,a
  566.     ld    b,8
  567. crclp:    ld    a,l
  568.     xor    c
  569.     srl    c
  570.     srl    d
  571.     rr    e
  572.     rr    h
  573.     rr    l
  574.     rra
  575.     jr    nc,noxor
  576.     ld    a,d
  577.     xor    0xed
  578.     ld    d,a
  579.     ld    a,e
  580.     xor    0xb8
  581.     ld    e,a
  582.     ld    a,h
  583.     xor    0x83
  584.     ld    h,a
  585.     ld    a,l
  586.     xor    0x20
  587.     ld    l,a
  588. noxor:    djnz    crclp
  589.     ld    (crc32),hl
  590.     ld    (crc32 + 2),de
  591.     ret
  592.  
  593. unshrink:
  594.     ld    a,init_bits
  595.     ld    (codesize),a
  596.     ld    hl,[1 << init_bits] - 1;
  597.     ld    (maxcode),hl
  598.     ld    hl,first_ent
  599.     ld    (free_ent),hl
  600.     ld    hl,prefix_of
  601.     ld    de,prefix_of + 1
  602.     ld    bc,512
  603.     ld    (hl),c
  604.     ldir
  605.     ld    bc,16386 - 512
  606.     ld    (hl),-1
  607.     ldir
  608.     ld    hl,suffix_of
  609. sol:    ld    (hl),c
  610.     inc    hl
  611.     inc    c
  612.     jr    nz,sol
  613.     call    getchla
  614.     ld    (oldcode),hl
  615.     ret    nz
  616.     ld    a,l
  617.     ld    (finchar),a
  618.     call    outbyte
  619. unshlp:    ld    hl,stack + 8192
  620.     ld    (stackp),hl
  621.     ld    a,(zipeof)
  622.     and    1
  623.     ret    nz
  624. clrlp:    call    z,getchla
  625.     ret    nz
  626.     ld    a,h
  627.     dec    a
  628.     or    l
  629.     jr    nz,noclr
  630.     call    getchla
  631.     ld    a,h
  632.     or    a
  633.     jr    nz,clrlp
  634.     dec    l
  635.     jr    z,bumpcs
  636.     dec    l
  637.     call    z,partial_clear
  638.     jr    clrlp
  639. bumpcs:    ld    hl,codesize
  640.     inc    (hl)
  641.     ld    a,(hl)
  642.     cp    max_bits
  643.     ld    hl,maxcmax
  644.     jr    z,atmax
  645.     ld    hl,1
  646. maxclp:    add    hl,hl
  647.     dec    a
  648.     jr    nz,maxclp
  649.     dec    hl
  650. atmax:    ld    (maxcode),hl
  651.     jr    clrlp
  652. noclr:    ld    (incode),hl
  653.     add    hl,hl
  654.     ld    de,prefix_of
  655.     add    hl,de
  656.     ld    a,(hl)
  657.     inc    hl
  658.     and    (hl)
  659.     inc    a
  660.     ld    hl,(code)
  661.     jr    nz,noKwKw
  662.     ld    a,(finchar)
  663.     call    savstk
  664.     ld    hl,(oldcode)
  665. noKwKw:    ex    de,hl
  666. staklp: ld    hl,suffix_of
  667.     add    hl,de
  668.     ld    a,(hl)
  669.     call    savstk
  670.     ld    hl,0x0100
  671.     or    a
  672.     sbc    hl,de
  673.     jr    nc,unstak
  674.     ld    hl,prefix_of
  675.     add    hl,de
  676.     add    hl,de
  677.     ld    e,(hl)
  678.     inc    hl
  679.     ld    d,(hl)
  680.     jr    staklp
  681. unstak:    ld    (finchar),a
  682.     ld    de,(stackp)
  683. unslp:    ld    hl,stack + 8192
  684.     or    a
  685.     sbc    hl,de
  686.     jr    z,newent
  687.     ld    a,(de)
  688.     inc    de
  689.     push    de
  690.     call    outbyte
  691.     pop    de
  692.     jr    unslp
  693. newent:    ld    hl,(free_ent)
  694.     ld    (code),hl
  695.     ex    de,hl
  696.     ld    hl,0x1fff
  697.     or    a
  698.     sbc    hl,de
  699.     jr    c,full
  700.     ld    hl,prefix_of
  701.     add    hl,de
  702.     add    hl,de
  703.     ld    bc,(oldcode)
  704.     ld    (hl),c
  705.     inc    hl
  706.     ld    (hl),b
  707.     ld    hl,suffix_of
  708.     add    hl,de
  709.     ld    a,(finchar)
  710.     ld    (hl),a
  711. getfre:    inc    de
  712.     ld    hl,0x1fff
  713.     or    a
  714.     sbc    hl,de
  715.     jr    c,full1
  716.     ld    hl,prefix_of
  717.     add    hl,de
  718.     add    hl,de
  719.     ld    a,(hl)
  720.     inc    hl
  721.     and    (hl)
  722.     inc    a
  723.     jr    nz,getfre
  724. full1:    ld    (free_ent),de
  725. full:    ld    hl,(incode)
  726.     ld    (oldcode),hl
  727.     jp    unshlp
  728.  
  729. partial_clear:
  730.     ld    de,first_ent
  731. l8:    ld    hl,(free_ent)
  732.     or    a
  733.     sbc    hl,de
  734.     jr    z,br8
  735.     ld    hl,prefix_of + 1
  736.     add    hl,de
  737.     add    hl,de
  738.     set    7,(hl)
  739.     inc    de
  740.     jr    l8
  741. br8:    ld    de,first_ent
  742. l9:    ld    hl,(free_ent)
  743.     or    a
  744.     sbc    hl,de
  745.     jr    z,br9
  746.     ld    hl,prefix_of
  747.     add    hl,de
  748.     add    hl,de
  749.     push    de
  750.     ld    e,(hl)
  751.     inc    hl
  752.     ld    d,(hl)
  753.     res    7,d
  754.     ld    hl,first_ent - 1
  755.     or    a
  756.     sbc    hl,de
  757.     jr    nc,ei10
  758.     ld    hl,prefix_of + 1
  759.     add    hl,de
  760.     add    hl,de
  761.     res    7,(hl)
  762. ei10:    pop    de
  763.     inc    de
  764.     jr    l9
  765. br9:    ld    de,first_ent
  766. l10:    ld    hl,(free_ent)
  767.     or    a
  768.     sbc    hl,de
  769.     jr    z,br10
  770.     ld    hl,prefix_of + 1
  771.     add    hl,de
  772.     add    hl,de
  773.     bit    7,(hl)
  774.     jr    z,ei11
  775.     ld    (hl),-1
  776.     dec    hl
  777.     ld    (hl),-1
  778. ei11:    inc    de
  779.     jr    l10
  780. br10:    ld    de,first_ent
  781. l11:    ld    hl,maxcmax
  782.     or    a
  783.     sbc    hl,de
  784.     jr    z,br11
  785.     ld    hl,prefix_of
  786.     add    hl,de
  787.     add    hl,de
  788.     ld    a,(hl)
  789.     inc    hl
  790.     and    (hl)
  791.     inc    a
  792.     jr    z,br11
  793.     inc    de
  794.     jr    l11
  795. br11:    ld    (free_ent),de
  796.     ret
  797.  
  798. loadfollowers:
  799.     ld    hl,Slen + 255
  800.     ld    b,0
  801. lflp:    push    bc
  802.     push    hl
  803.     ld    a,6
  804.     call    readbits
  805.     pop    hl
  806.     pop    de
  807.     ld    (hl),a
  808.     push    de
  809.     push    hl
  810.     dec    d
  811.     ld    hl,followers
  812.     call    shftadd
  813.     ld    b,a
  814.     or    a
  815.     jr    z,nofoll
  816. ldfllp:    push    hl
  817.     push    bc
  818.     ld    a,8
  819.     call    readbits
  820.     pop    bc
  821.     pop    hl
  822.     ld    (hl),a
  823.     inc    hl
  824.     djnz    ldfllp
  825. nofoll:    pop    hl
  826.     pop    bc
  827.     dec    hl
  828.     djnz    lflp
  829.     ret
  830.  
  831. .dseg
  832. _L_table:
  833.     db    0x7f, 0x3f, 0x1f, 0x0f
  834.  
  835. _D_shift:
  836.     db    0x07, 0x06, 0x05, 0x04
  837.  
  838. .useg
  839. L_table:
  840.     ds    1
  841. D_shift:
  842.     ds    1
  843.  
  844. .cseg
  845.  
  846. unreduce:
  847. .useg
  848. V:    ds    1
  849. nchar:    ds    1
  850. lchar:    ds    1
  851. ExState:
  852.     ds    1
  853. Len:    ds    2
  854. .cseg
  855.     ld    e,a
  856.     ld    d,0
  857.     ld    hl,_L_table
  858.     add    hl,de
  859.     ld    a,(hl)
  860.     ld    (L_table),a
  861.     ld    hl,_D_shift
  862.     add    hl,de
  863.     ld    a,(hl)
  864.     ld    (D_shift),a
  865.     xor    a
  866.     ld    (ExState),a
  867.     ld    (lchar),a
  868.     call    loadfollowers
  869. ur1:    ld    a,(zipeof)
  870.     and    1
  871.     ret    nz
  872.     call    slenlch
  873.     or    a
  874.     jr    nz,ur2
  875. ur4:    ld    a,8
  876.     call    readbits
  877.     jr    ur3
  878. ur2:    ld    a,1
  879.     call    readbits
  880.     dec    l
  881.     jr    z,ur4
  882.     call    slenlch
  883.     dec    a
  884.     or    1
  885.     ld    l,a
  886.     xor    a
  887. btlp:    inc    a
  888.     srl    l
  889.     jr    nz,btlp
  890.     call    readbits
  891.     ld    de,followers
  892.     add    hl,de
  893.     ld    de,(lchar - 1)
  894.     call    shftadd
  895.     ld    a,(hl)
  896. ur3:    ld    (nchar),a
  897.     ld    l,a
  898.     ld    a,(ExState)
  899.     or    a
  900.     jr    nz,ur5
  901.     ld    a,l
  902.     cp    DLE    
  903.     jr    nz,ur9
  904.     ld    a,1
  905.     ld    (ExState),a
  906.     jr    ur6
  907. ur5:    dec    a
  908.     jr    nz,ur7
  909.     ld    a,l
  910.     or    a
  911.     jr    z,ur10
  912.     ld    (V),a
  913.     ld    a,(L_table)
  914.     ld    h,a
  915.     and    l
  916.     cp    h
  917.     ld    l,a
  918.     ld    h,0
  919.     ld    (Len),hl
  920.     jr    nz,ur12
  921.     ld    a,2
  922.     jr    ur11
  923. ur10:    ld    (ExState),a
  924.     ld    a,DLE
  925. ur9:    call    outb
  926.     jr    ur6
  927. ur7:    dec    a
  928.     jr    nz,ur8
  929.     ld    a,l
  930.     ld    hl,Len
  931.     add    a,(hl)
  932.     ld    (hl),a
  933.     jr    nc,ur12
  934.     inc    hl
  935.     inc    (hl)
  936. ur12:    ld    a,3
  937.     jr    ur11
  938. ur8:    dec    a
  939.     jr    nz,ur13
  940.     ld    a,(D_shift)
  941.     ld    b,a
  942.     ld    a,(V)
  943. ur14:    srl    a
  944.     djnz    ur14
  945.     ld    h,a
  946.     inc    hl
  947.     ld    bc,(Len)
  948.     inc    bc
  949.     inc    bc
  950.     inc    bc
  951.     call    callback
  952. ur13:    xor    a
  953. ur11:    ld    (ExState),a
  954. ur6:    ld    a,(nchar)
  955.     ld    (lchar),a
  956.     jp    ur1
  957.  
  958. slenlch:
  959.     ld    hl,(lchar)
  960.     ld    h,0
  961.     ld    de,Slen
  962.     add    hl,de
  963.     ld    a,(hl)
  964.     ret
  965.  
  966. shftadd:
  967.     ld    e,0
  968.     srl    d
  969.     rr    e
  970.     srl    d
  971.     rr    e
  972.     add    hl,de
  973.     ret
  974.  
  975. callback:
  976.     push    bc
  977.     push    hl
  978.     ld    hl,(outpos)
  979.     ld    de,(outpos + 2)
  980.     pop    bc
  981.     or    a
  982.     sbc    hl,bc
  983.     jr    nc,cb2
  984.     dec    de
  985. cb2:    pop    bc
  986. cb3:    bit    7,d
  987.     jr    z,cb4
  988.     ld    a,b
  989.     or    c
  990.     jr    z,cb4
  991.     xor    a
  992.     call    outbp
  993.     inc    hl
  994.     ld    a,h
  995.     or    l
  996.     jr    nz,cb5
  997.     inc    de
  998. cb5:    dec    bc
  999.     jr    cb3
  1000. cb4:    ex    de,hl
  1001. cb6:    ld    a,b
  1002.     or    c
  1003.     ret    z
  1004.     ld    a,d
  1005.     and    0x1f
  1006.     ld    d,a
  1007.     ld    hl,outbuf
  1008.     add    hl,de
  1009.     ld    a,(hl)
  1010.     call    outbp
  1011.     inc    de
  1012.     dec    bc
  1013.     jr    cb6
  1014.  
  1015. outbp:    push    hl
  1016.     push    de
  1017.     push    bc
  1018.     call    outb
  1019.     pop    bc
  1020.     pop    de
  1021.     pop    hl
  1022.     ret
  1023.  
  1024. .var    maxSF        256
  1025.  
  1026. .var    _code        0
  1027. .var    _value        2
  1028. .var    _bitlength    3
  1029.  
  1030. .var    _entries    0
  1031. .var    _maxlength    2
  1032. .var    _entry        4
  1033.  
  1034. .var    _sf_tree_    4 + 4 * maxSF
  1035.  
  1036. .useg
  1037. ltp:    ds    1
  1038. mml:    ds    1
  1039. dictb:    ds    1
  1040. noswps:    ds    1
  1041. .cseg
  1042.  
  1043. readlengths:
  1044.     ld    a,8
  1045.     call    readbits
  1046.     ld    d,h
  1047.     ld    e,d
  1048.     inc    hl
  1049.     ld    b,h
  1050.     ld    c,l
  1051.     ld    (ix + _maxlength),e
  1052.     ld    (ix + _maxlength + 1),d
  1053.     push    ix
  1054.     pop    hl
  1055.     inc    hl
  1056.     inc    hl
  1057.     inc    hl
  1058. rl1:    ld    a,b
  1059.     or    c
  1060.     ret    z
  1061.     push    bc
  1062.     push    de
  1063.     push    hl
  1064.     ld    a,4
  1065.     call    readbits
  1066.     inc    a
  1067.     push    af
  1068.     ld    a,4
  1069.     call    readbits
  1070.     inc    a
  1071.     ld    b,a
  1072.     pop    af
  1073.     ld    c,a
  1074.     pop    hl
  1075.     pop    de
  1076.     ld    a,(ix + _maxlength)
  1077.     cp    c
  1078.     jr    nc,rl2
  1079.     ld    (ix + _maxlength),c
  1080. rl2:    inc    hl
  1081.     inc    hl
  1082.     inc    hl
  1083.     ld    (hl),e
  1084.     inc    hl
  1085.     ld    (hl),c
  1086.     inc    e
  1087.     djnz    rl2
  1088.     pop    bc
  1089.     dec    bc
  1090.     jr    rl1
  1091.  
  1092. sortlengths:
  1093.     ld    h,(ix + _entries + 1)
  1094.     ld    l,(ix + _entries)
  1095.     ld    b,h
  1096.     ld    c,l
  1097.     ld    (entrs),hl
  1098. .useg
  1099. entrs:    ds    2
  1100. .cseg
  1101. sl7:    srl    b
  1102.     rr    c
  1103. sl1:    ld    a,b
  1104.     or    c
  1105.     ret    z
  1106.     ld    (noswps),a
  1107.     push    ix
  1108.     ld    de,4
  1109.     add    ix,de
  1110.     push    ix
  1111.     pop    iy
  1112.     add    iy,bc
  1113.     add    iy,bc
  1114.     add    iy,bc
  1115.     add    iy,bc
  1116.     ld    hl,(entrs)
  1117.     or    a
  1118.     sbc    hl,bc
  1119. sl2:    ld    a,(ix + _bitlength)
  1120.     cp    (iy + _bitlength)
  1121.     jr    c,sl4
  1122.     jr    nz,sl3
  1123.     ld    a,(iy + _value)
  1124.     cp    (ix + _value)
  1125.     jr    nc,sl4
  1126. sl3:    ld    d,e
  1127. sl5:    ld    a,(ix)
  1128.     push    af
  1129.     ld    a,(iy)
  1130.     ld    (ix),a
  1131.     pop    af
  1132.     ld    (iy),a
  1133.     inc    ix
  1134.     inc    iy
  1135.     dec    d
  1136.     jr    nz,sl5
  1137.     ld    a,d
  1138.     ld    (noswps),a
  1139.     jr    sl6
  1140. sl4:    add    ix,de
  1141.     add    iy,de
  1142. sl6:    dec    hl
  1143.     ld    a,h
  1144.     or    l
  1145.     jr    nz,sl2
  1146.     pop    ix
  1147.     ld    a,(noswps)
  1148.     or    a
  1149.     jr    nz,sl7
  1150.     jr    sl1
  1151.  
  1152. .useg
  1153. lbl:    ds    1
  1154. .cseg
  1155.  
  1156. generatetrees:
  1157.     ld    l,(ix + _entries)
  1158.     ld    h,(ix + _entries + 1)
  1159.     ld    c,l
  1160.     ld    b,h
  1161.     push    ix
  1162.     pop    de
  1163.     add    hl,hl
  1164.     add    hl,hl
  1165.     add    hl,de
  1166.     push    hl
  1167.     pop    iy
  1168.     xor    a
  1169.     ld    d,a
  1170.     ld    e,a
  1171.     ld    h,a
  1172.     ld    l,a
  1173.     ld    (lbl),a
  1174. gt1:    ld    a,b
  1175.     or    c
  1176.     ret    z
  1177.     dec    bc
  1178.     add    hl,de    
  1179.     ld    a,(lbl)
  1180.     cp    (iy + _bitlength)
  1181.     jr    z,gt2
  1182.     ld    a,(iy + _bitlength)
  1183.     ld    (lbl),a
  1184.     sub    16
  1185.     ex    de,hl
  1186.     ld    hl,1
  1187.     jr    z,gt3
  1188. gt4:    add    hl,hl
  1189.     inc    a
  1190.     jr    nz,gt4
  1191. gt3:    ex    de,hl
  1192. gt2:    ld    (iy + _code),l
  1193.     ld    (iy + _code + 1),h
  1194.     push    de
  1195.     ld    de,-4
  1196.     add    iy,de
  1197.     pop    de
  1198.     jr    gt1
  1199.  
  1200. ldtrees:
  1201.     ld    a,(gpbf)
  1202.     rra
  1203.     ld    l,a
  1204.     and    1
  1205.     add    a,6
  1206.     ld    (dictb),a
  1207.     ld    a,l
  1208.     rra
  1209.     and    1
  1210.     ld    (ltp),a
  1211.     set    1,a
  1212.     ld    (mml),a
  1213.     ld    ix,lit_tree
  1214.     ld    hl,256
  1215.     call    nz,ld_tree
  1216.     ld    hl,64
  1217.     ld    ix,len_tree
  1218.     call    ld_tree
  1219.     ld    hl,64
  1220.     ld    ix,dist_tre
  1221.  
  1222. ld_tree:
  1223.     ld    (ix + _entries),l
  1224.     ld    (ix + _entries + 1),h
  1225.     call    readlengths
  1226.     call    sortlengths
  1227.     call    generatetrees
  1228.  
  1229. reversebits:
  1230.     push    ix
  1231.     pop    hl
  1232.     ld    e,(hl)
  1233.     inc    hl
  1234.     ld    d,(hl)
  1235. rb1:    inc    hl
  1236.     inc    hl
  1237.     inc    hl
  1238.     ld    c,(hl)
  1239.     ld    b,8
  1240. rb2:    srl    c
  1241.     adc    a,a
  1242.     djnz    rb2
  1243.     push    af
  1244.     inc    hl
  1245.     ld    c,(hl)
  1246.     ld    b,8
  1247. rb3:    srl    c
  1248.     adc    a,a
  1249.     djnz    rb3
  1250.     dec    hl
  1251.     ld    (hl),a
  1252.     pop    af
  1253.     inc    hl
  1254.     ld    (hl),a
  1255.     dec    de
  1256.     ld    a,d
  1257.     or    e
  1258.     jr    nz,rb1
  1259.     ret
  1260.  
  1261. readtree:
  1262.     push    ix
  1263.     pop    iy
  1264.     ld    de,4
  1265.     add    iy,de
  1266.     ld    b,d
  1267.     ld    e,d
  1268.     ld    h,d
  1269.     ld    l,d
  1270. rt1:    push    hl
  1271.     push    de
  1272.     push    bc
  1273.     ld    a,1
  1274.     call    readbits
  1275.     pop    af
  1276.     push    af
  1277.     or    a
  1278.     jr    z,rt2
  1279. rt3:    add    hl,hl
  1280.     dec    a
  1281.     jr    nz,rt3
  1282. rt2:    pop    bc
  1283.     pop    de
  1284.     add    hl,de
  1285.     ex    de,hl
  1286.     inc    b
  1287.     pop    hl
  1288. rt4:    ld    a,(iy + _bitlength)
  1289.     cp    b
  1290.     jr    nc,rt5
  1291.     push    de
  1292.     ld    de,4
  1293.     add    iy,de
  1294.     pop    de
  1295.     inc    hl
  1296.     ld    a,(ix + _entries)
  1297.     sub    l
  1298.     jr    nz,rt4
  1299.     ld    a,(ix + _entries + 1)
  1300.     sub    h
  1301.     jr    nz,rt4
  1302. rt6:    dec    a
  1303.     ret
  1304. rt5:    ld    a,(iy + _bitlength)
  1305.     cp    b
  1306.     jr    nz,rt1
  1307.     ld    a,(iy + _code)
  1308.     cp    e
  1309.     jr    nz,rt7
  1310.     ld    a,(iy + _code + 1)
  1311.     cp    d
  1312.     jr    nz,rt7
  1313.     ld    a,(iy + _value)
  1314.     ret
  1315. rt7:    push    de
  1316.     ld    de,4
  1317.     add    iy,de
  1318.     pop    de
  1319.     inc    hl
  1320.     ld    a,(ix + _entries)
  1321.     sub    l
  1322.     jr    nz,rt5
  1323.     ld    a,(ix + _entries + 1)
  1324.     sub    h
  1325.     jr    nz,rt5
  1326.     jr    rt6
  1327.  
  1328. unimplode:
  1329.     call    ldtrees
  1330. ui1:    ld    a,(zipeof)
  1331.     and    1
  1332.     ret    nz
  1333.     inc    a
  1334.     call    readbits
  1335.     or    a
  1336.     jr    z,ui2
  1337.     ld    a,(ltp)
  1338.     or    a
  1339.     jr    z,ui3
  1340.     ld    ix,lit_tree
  1341.     call    readtree
  1342.     jr    ui4
  1343. ui3:    ld    a,8
  1344.     call    readbits
  1345. ui4:    call    outb
  1346.     jr    ui1
  1347. ui2:    ld    a,(dictb)
  1348.     call    readbits
  1349.     push    hl
  1350.     ld    ix,dist_tre
  1351.     call    readtree
  1352.     ld    bc,(dictb - 1)
  1353. ui5:    add    hl,hl
  1354.     djnz    ui5
  1355.     pop    bc
  1356.     add    hl,bc
  1357.     push    hl
  1358.     ld    ix,len_tree
  1359.     call    readtree
  1360.     ld    l,a
  1361.     ld    h,0
  1362.     cp    63
  1363.     jr    nz,ui6
  1364.     push    hl
  1365.     ld    a,8
  1366.     call    readbits
  1367.     pop    de
  1368.     add    hl,de
  1369. ui6:    ld    de,(mml)
  1370.     ld    d,0
  1371.     add    hl,de
  1372.     ld    b,h
  1373.     ld    c,l
  1374.     pop    hl
  1375.     inc    hl
  1376.     call    callback
  1377.     jr    ui1
  1378.  
  1379. .useg
  1380. oldcode:
  1381.     ds    2
  1382. offset:
  1383.     ds    2
  1384. codesize:
  1385.     ds    1
  1386. maxcode:
  1387.     ds    2
  1388. free_ent:
  1389.     ds    2
  1390. finchar:
  1391.     ds    1
  1392. stackp:
  1393.     ds    2
  1394. incode:
  1395.     ds    2
  1396. code:
  1397.     ds    2
  1398.  
  1399. outbuf:
  1400. suffix_of:
  1401.     ds    8192
  1402.  
  1403. prefix_of:
  1404. Slen:
  1405. lit_tree:
  1406.     ds    _sf_tree_
  1407. len_tree:
  1408.     ds    _sf_tree_
  1409. dist_tre:
  1410.     ds    _sf_tree_
  1411.  
  1412.     ds    16384 + 2 - [3 * _sf_tree_]
  1413.  
  1414. followers:
  1415. stack:
  1416.     ds    16384
  1417.