home *** CD-ROM | disk | FTP | other *** search
/ Brotikasten / BROTCD01.iso / exoten / msx / unzip.pma / UNZIP15.Z80
Text File  |  1991-06-29  |  22KB  |  1,611 lines

  1. ; UNZIP.Z80
  2. ;
  3. ;    Dissolves MS-DOS ZIP files.
  4. ;
  5. Vers    equ    15
  6. ;
  7. ;
  8. ; Version 1.5 -- june 1, 1991 -- Howard Goldstein
  9. ;    Fixed bug at WILDLP which was causing an output spec of "dir:"
  10. ;    not to work correctly.  Corrected problems that were causing
  11. ;    writes to disk when a non-matching member file was being skipped.
  12. ;    Changed "disk full" logic to close and erase partial output file
  13. ;    and abort the program immediately.  Made several minor changes to
  14. ;    allow assembly with ZMAC or M80.
  15.  
  16. ; Version 1.4 -- May 16, 1991 -- Bruce Morgen
  17. ;    Fixed bug at "setusr" and added output filename wildcard
  18. ;    support.  If the selected output filespec is NOT wild,
  19. ;    (and d: or dir: alone IS wild) UNZIP will exit after the
  20. ;    first extraction.  Boy, do I have a headache....
  21.  
  22. ; Version 1.3 -- May 12, 1991 -- Gene Pizzetta
  23. ;    Some quick and dirty mods to make this utility more useful.
  24. ;    The original has to be the most God-awful source code I've
  25. ;    ever come across.  It is totally uncommented, and I have
  26. ;    no idea what kind of strange assembler it was written for.
  27. ;    This code now assembles with SLR's Z80ASM and it's a little
  28. ;    more orderly.
  29. ;
  30. ;    New syntax:
  31. ;        UNZIP {dir:}zipfile {dir:}{afn}
  32. ;    Under ZCPR3 "dir" can be a DU or DIR spec; otherwise, just
  33. ;    a drive.  If no destination is given, member files are checked
  34. ;    and listed.  If a destination is given, member files are
  35. ;    extracted if they match "afn" if given, otherwise the entire
  36. ;    ZIPfile is extracted.
  37. ;
  38. ;    You can now abort this thing with ^C (and the partial output
  39. ;    file, if any, will be closed and erased).  Usage screen now
  40. ;    responds to "//".  This program still needs a lot of work.
  41. ;    It's probably not bullet-proof and testing has been very
  42. ;    limited, but it seems to work.
  43. ;
  44. ; Version 1.2 -- July 3, 1990 -- David P. Goodenough
  45. ;
  46. ; System addresses
  47. ;
  48. wboot    equ    0
  49. bdos    equ    5
  50. infcb    equ    5Ch
  51. altfcb    equ    6Ch
  52. ;
  53. ; BDOS service functions
  54. ;
  55. conout    equ    2
  56. dircon    equ    6
  57. fopen    equ    15
  58. fclose    equ    16
  59. ferase    equ    19
  60. fread    equ    20
  61. fwrite    equ    21
  62. fmake    equ    22
  63. getdrv    equ    25
  64. setdma    equ    26
  65. setusr    equ    32
  66. ;
  67. ; Other
  68. ;
  69. STRSIZ    equ    256
  70. DLE    equ    144
  71. max_bits equ    13
  72. init_bits equ    9
  73. hsize    equ    8192
  74. first_ent equ    257
  75. clear    equ    256
  76. maxcmax    equ    1 shl max_bits
  77. maxSF    equ    256
  78. _code    equ    0
  79. _value    equ    2
  80. _bitlength equ    3
  81. _entries equ    0
  82. _maxlength equ    2
  83. _entry    equ    4
  84. _sf_tree_ equ    4 + 4 * maxSF
  85. ;
  86. ; ASCII
  87. ;
  88. CtrlC    equ    03h
  89. CR    equ    0Dh
  90. LF    equ    0Ah
  91. CtrlZ    equ    1Ah
  92. ;
  93.     .z80
  94.     aseg
  95.     org    100h
  96. ;
  97.     jp    start
  98. ;
  99.     db    'Z3ENV',1
  100. Z3EAdr:    dw    0
  101. ;
  102. start:    ld    (oldstk),sp    ; save old stack here for future use
  103.     ld    sp,(6)        ; set the stack pointer
  104.     call    ilprt
  105.     db    'UNZIP  Version '
  106.     db    Vers/10+'0','.',Vers mod 10+'0','  -  DPG',CR,LF,0
  107.     ld    a,(infcb+1)    ; filename?
  108.     cp    ' '
  109.     jp    z,usage
  110.     cp    '/'
  111.     jp    z,usage
  112. ;
  113. wasfil:    ld    de,altfcb
  114.     ld    a,(de)        ; output drive given?
  115.     ld    (opfcb),a    ; store it in output file control block
  116.     ld    (mode),a    ; set the mode (non-zero = extract)
  117.     call    getusr        ; get input and output users, if ZCPR3
  118.     ld    hl,mtchfcb
  119.     ld    bc,11
  120.     inc    de
  121.     ld    a,(de)
  122.     cp    20h
  123.     jr    z,wildfill
  124.     ex    de,hl
  125.     ldir
  126.     ld    a,(altfcb)
  127.     or    a
  128.     jr    nz,filldn
  129.     ld    c,getdrv
  130.     call    bdos
  131.     inc    a
  132.     ld    (opfcb),a    ; store it in output file control block
  133.     ld    (mode),a    ; set the mode (non-zero = extract)
  134.     jr    filldn
  135. wildfill:
  136.     ld    b,c
  137. wildlp:    ld    (hl),'?'
  138.     inc    hl
  139.     djnz    wildlp
  140. filldn:    ld    a,(infcb+9)    ; check for filetype
  141.     cp    20h
  142.     jr    nz,wasext
  143.     ld    hl,+('I' shl 8) + 'Z'    ; set default type to ZIP
  144.     ld    (infcb+9),hl
  145.     ld    a,'P'
  146.     ld    (infcb+11),a
  147. wasext:    call    setin        ; log input user
  148.     ld    de,infcb
  149.     ld    c,fopen
  150.     call    bdos        ; try and open ZIP file
  151.     inc    a
  152.     jr    nz,openok    ; ok
  153.     call    ilprt        ; complain and fall through to exit
  154.     db    'Couldn''t find ZIP file',CR,LF,0
  155. ;
  156. ; All exits point here for possible future enhancements, such
  157. ; as elimination of warm boot.
  158. ;
  159. exit:    jp    wboot
  160. ;
  161. sigerr:    call    ilprt
  162.     db    'Bad signature in ZIP file',CR,LF,0
  163.     jr    exit
  164. ;
  165. openok:    call    getword
  166.     ld    de,-(('K' shl 8) + 'P')
  167.     add    hl,de
  168.     ld    a,h
  169.     or    l
  170.     jr    nz,sigerr
  171.     call    getword
  172.     dec    l
  173.     jr    nz,nocfhs
  174.     dec    h
  175.     dec    h
  176.     jr    nz,sigerr
  177.     call    pcfh
  178.     jr    openok
  179. ;
  180. nocfhs:    dec    l
  181.     dec    l
  182.     jr    nz,nolfhs
  183.     ld    a,h
  184.     sub    4
  185.     jr    nz,sigerr
  186.     call    plfh
  187.     jr    openok
  188. ;
  189. nolfhs:    dec    l
  190.     dec    l
  191.     jr    nz,sigerr
  192.     ld    a,h
  193.     sub    6
  194.     jr    nz,sigerr
  195.     call    pecd
  196.     jr    exit
  197. ;
  198. pcfh:    ld    b,12
  199. pcfhl1:    push    bc
  200.     call    getword
  201.     pop    bc
  202.     djnz    pcfhl1
  203.     call    getword
  204.     push    hl
  205.     call    getword
  206.     push    hl
  207.     call    getword
  208.     pop    de
  209.     pop    bc
  210.     push    hl
  211.     push    de
  212.     push    bc
  213.     ld    b,6
  214. pcfhl2:    push    bc
  215.     call    getword
  216.     pop    bc
  217.     djnz    pcfhl2
  218.     pop    hl
  219.     ld    de,junk
  220.     call    getstring
  221.     pop    hl
  222.     ld    de,junk
  223.     call    getstring
  224.     pop    hl
  225.     ld    de,junk
  226.     call    getstring
  227.     ret
  228. ;
  229. pecd:    ld    b,8
  230. pecdl:    push    bc
  231.     call    getword
  232.     pop    bc
  233.     djnz    pecdl
  234.     call    getword
  235.     ld    de,junk
  236.     call    getstring
  237.     ret
  238. ;
  239. plfh:    ld    de,lfh
  240.     ld    hl,endlfh-lfh
  241.     call    getstring
  242.     ld    hl,opfcb+1
  243.     ld    de,opfcb+2
  244.     ld    bc,33
  245.     ld    (hl),b
  246.     ldir
  247.     ld    de,junk
  248.     ld    hl,(fnl)
  249.     call    getstring
  250.     ld    de,junk + 20
  251.     ld    hl,(efl)
  252.     call    getstring
  253.     ld    de,junk
  254.     ld    hl,opfn
  255.     ld    b,8
  256.     call    scanfn
  257.     ld    a,(de)
  258.     cp    '.'
  259.     jr    nz,nodot
  260.     inc    de
  261. nodot:    ld    b,3
  262.     call    scanfn
  263.     ld    hl,init
  264.     ld    de,vars
  265.     ld    bc,endinit-init
  266.     ldir
  267.     ld    a,(mode)
  268. resmod:    ld    (curmode),a
  269.     or    a
  270.     jr    z,extrct
  271. mtched:    call    setout        ; log output user
  272.     ld    de,opfcb    ; see if output file already exists
  273.     ld    c,fopen
  274.     call    bdos
  275.     inc    a
  276.     jr    nz,exists
  277.     ld    b,11
  278.     ld    hl,opfn
  279.     ld    de,mtchfcb
  280. mtchlp:    ld    a,(de)
  281.     ld    c,(hl)
  282.     inc    hl
  283.     inc    de
  284.     cp    '?'
  285.     jr    z,mtch1
  286.     res    7,c
  287.     cp    c
  288.     jr    nz,nomtch
  289. mtch1:    djnz    mtchlp
  290.     jr    creok        ; (nope, so continue)
  291. nomtch:    ld    hl,junk
  292.     call    pstr
  293.     call    ilprt
  294.     db    ' doesn''t match',0
  295.     jr    noex
  296. exists:    ld    hl,junk        ; it exists, so skip it
  297.     call    pstr
  298.     call    ilprt
  299.     db    ' exists',0
  300. noex:    call    ilprt
  301.     db    ' -- not extracting  ',0
  302.     xor    a
  303.     jr    resmod
  304. ;
  305. extrct:    xor    a
  306.     ld    (zipeof),a
  307.     ld    a,(curmode)
  308.     or    a
  309.     jr    nz,doext
  310.     call    ilprt
  311.     db    'Checking ',0
  312.     jr    pjunk
  313. ;
  314. creok:    call    setout
  315.     ld    de,opfcb    ; create output file
  316.     ld    c,fmake
  317.     call    bdos
  318.     inc    a
  319.     jr    nz,opnok1
  320.     call    ilprt
  321.     db    'Error creating ',0
  322.     ld    hl,junk
  323.     call    pstr
  324.     jr    noex
  325. ;
  326. opnok1:    call    ilprt
  327.     db    'Extracting ',0
  328. pjunk:    ld    hl,junk
  329.     call    pstr
  330. doext:    call    ilprt
  331.     db    ' -- ',0
  332.     ld    hl,counting
  333.     inc    (hl)
  334.     ld    a,(cm)
  335.     or    a
  336.     jr    nz,case1
  337. case0w:    ld    a,(zipeof)
  338.     and    1
  339.     jr    nz,closeo
  340. savcs0:    call    getbyte
  341.     call    outbyte
  342.     jr    case0w
  343. ;
  344. case1:    dec    a
  345.     jr    nz,case2p
  346.     call    unshrink
  347.     jr    closeo
  348. ;
  349. case2p:    dec    a
  350.     cp    4
  351.     jr    nc,tryimp
  352.     call    unreduce
  353.     jr    closeo
  354. ;
  355. tryimp:    jr    nz,badzip
  356.     call    unimplode
  357.     jr    closeo
  358. ;
  359. badzip:    call    ilprt
  360.     db    'Unknown compression method',CR,LF,0
  361.     ret
  362. ;
  363. closeo:    ld    hl,zipeof
  364.     dec    (hl)
  365.     inc    hl
  366.     dec    (hl)
  367.     ld    a,(curmode)
  368.     or    a
  369.     jr    z,nocls
  370. ;    jr    nz,nocls
  371.     ld    hl,wrtpt
  372.     ld    a,(hl)
  373.     or    a
  374.     jr    z,noflsh
  375.     ld    de,opbuf
  376.     ld    c,setdma
  377.     call    bdos
  378.     call    setout
  379.     ld    de,opfcb
  380.     ld    c,fwrite
  381.     call    bdos
  382. noflsh:    call    setout
  383.     ld    de,opfcb
  384.     ld    c,fclose
  385.     call    bdos
  386. nocls:    ld    hl,crc32
  387.     ld    de,crc
  388.     scf
  389.     ld    bc,4 shl 8
  390. crcclp:    ld    a,(de)
  391.     adc    a,(hl)
  392.     push    af
  393.     or    c
  394.     ld    c,a
  395.     pop    af
  396.     inc    hl
  397.     inc    de
  398.     djnz    crcclp
  399.     ld    a,c
  400.     or    a
  401.     jr    z,crcok
  402.     call    ilprt
  403.     db    'CRC error',CR,LF,0
  404.     jr    wildck
  405. ;
  406. crcok:    call    ilprt
  407.     db    'CRC OK',CR,LF,0
  408. wildck:    ld    a,(curmode)
  409.     or    a
  410.     ret    z
  411.     ld    hl,mtchfcb
  412.     ld    bc,11
  413.     ld    a,'?'
  414.     cpir
  415.     jp    nz,exit
  416.     ret
  417. ;
  418. getchla:
  419.     call    getcode
  420.     ld    (code),hl
  421.     ld    a,(zipeof)
  422.     and    1
  423.     ret
  424. ;
  425. savstk:    ld    hl,(stackp)
  426.     dec    hl
  427.     ld    (stackp),hl
  428.     ld    (hl),a
  429.     ret
  430. ;
  431. getcode:
  432.     ld    a,(codesize)
  433. readbits:
  434.     ld    hl,8000h
  435. bitlp:    push    af
  436.     push    hl
  437. getbit:    ld    hl,bleft
  438.     dec    (hl)
  439.     jp    m,readbt
  440.     dec    hl
  441.     rr    (hl)
  442.     pop    hl
  443.     rr    h
  444.     rr    l
  445.     pop    af
  446.     dec    a
  447.     jr    nz,bitlp
  448. finbit:    srl    h
  449.     rr    l
  450.     jr    nc,finbit
  451.     ld    a,l
  452.     ret
  453. ;
  454. readbt:    push    hl
  455.     call    getbyte
  456.     pop    hl
  457.     ld    (hl),8
  458.     dec    hl
  459.     ld    (hl),a
  460.     jr    getbit
  461. ;
  462. scanfn:    ld    a,(de)
  463.     cp    '.'
  464.     jr    z,nocopy
  465.     or    a
  466.     jr    z,nocopy
  467.     inc    de
  468.     dec    b
  469.     jp    m,scanfn
  470.     ld    (hl),a
  471.     inc    hl
  472.     jr    scanfn
  473. ;
  474. nocopy:    dec    b
  475.     ret    m
  476.     ld    (hl),' '
  477.     inc    hl
  478.     jr    nocopy
  479. ;
  480. ilprt:    pop    hl
  481.     call    pstr
  482.     jp    (hl)
  483. ;
  484. pstr:    ld    a,(hl)
  485.     or    a
  486.     ret    z
  487.     push    hl
  488.     ld    e,a
  489.     ld    c,conout
  490.     call    bdos
  491.     pop    hl
  492.     inc    hl
  493.     jr    pstr
  494. ;
  495. getstring:
  496.     ld    a,h
  497.     or    l
  498.     ld    (d