home
***
CD-ROM
|
disk
|
FTP
|
other
***
search
/
Brotikasten
/
BROTCD01.iso
/
exoten
/
msx
/
unzip.pma
/
UNZIP15.Z80
Wrap
Text File
|
1991-06-29
|
22KB
|
1,611 lines
; UNZIP.Z80
;
; Dissolves MS-DOS ZIP files.
;
Vers equ 15
;
;
; Version 1.5 -- june 1, 1991 -- Howard Goldstein
; Fixed bug at WILDLP which was causing an output spec of "dir:"
; not to work correctly. Corrected problems that were causing
; writes to disk when a non-matching member file was being skipped.
; Changed "disk full" logic to close and erase partial output file
; and abort the program immediately. Made several minor changes to
; allow assembly with ZMAC or M80.
; Version 1.4 -- May 16, 1991 -- Bruce Morgen
; Fixed bug at "setusr" and added output filename wildcard
; support. If the selected output filespec is NOT wild,
; (and d: or dir: alone IS wild) UNZIP will exit after the
; first extraction. Boy, do I have a headache....
; Version 1.3 -- May 12, 1991 -- Gene Pizzetta
; Some quick and dirty mods to make this utility more useful.
; The original has to be the most God-awful source code I've
; ever come across. It is totally uncommented, and I have
; no idea what kind of strange assembler it was written for.
; This code now assembles with SLR's Z80ASM and it's a little
; more orderly.
;
; New syntax:
; UNZIP {dir:}zipfile {dir:}{afn}
; Under ZCPR3 "dir" can be a DU or DIR spec; otherwise, just
; a drive. If no destination is given, member files are checked
; and listed. If a destination is given, member files are
; extracted if they match "afn" if given, otherwise the entire
; ZIPfile is extracted.
;
; You can now abort this thing with ^C (and the partial output
; file, if any, will be closed and erased). Usage screen now
; responds to "//". This program still needs a lot of work.
; It's probably not bullet-proof and testing has been very
; limited, but it seems to work.
;
; Version 1.2 -- July 3, 1990 -- David P. Goodenough
;
; System addresses
;
wboot equ 0
bdos equ 5
infcb equ 5Ch
altfcb equ 6Ch
;
; BDOS service functions
;
conout equ 2
dircon equ 6
fopen equ 15
fclose equ 16
ferase equ 19
fread equ 20
fwrite equ 21
fmake equ 22
getdrv equ 25
setdma equ 26
setusr equ 32
;
; Other
;
STRSIZ equ 256
DLE equ 144
max_bits equ 13
init_bits equ 9
hsize equ 8192
first_ent equ 257
clear equ 256
maxcmax equ 1 shl max_bits
maxSF equ 256
_code equ 0
_value equ 2
_bitlength equ 3
_entries equ 0
_maxlength equ 2
_entry equ 4
_sf_tree_ equ 4 + 4 * maxSF
;
; ASCII
;
CtrlC equ 03h
CR equ 0Dh
LF equ 0Ah
CtrlZ equ 1Ah
;
.z80
aseg
org 100h
;
jp start
;
db 'Z3ENV',1
Z3EAdr: dw 0
;
start: ld (oldstk),sp ; save old stack here for future use
ld sp,(6) ; set the stack pointer
call ilprt
db 'UNZIP Version '
db Vers/10+'0','.',Vers mod 10+'0',' - DPG',CR,LF,0
ld a,(infcb+1) ; filename?
cp ' '
jp z,usage
cp '/'
jp z,usage
;
wasfil: ld de,altfcb
ld a,(de) ; output drive given?
ld (opfcb),a ; store it in output file control block
ld (mode),a ; set the mode (non-zero = extract)
call getusr ; get input and output users, if ZCPR3
ld hl,mtchfcb
ld bc,11
inc de
ld a,(de)
cp 20h
jr z,wildfill
ex de,hl
ldir
ld a,(altfcb)
or a
jr nz,filldn
ld c,getdrv
call bdos
inc a
ld (opfcb),a ; store it in output file control block
ld (mode),a ; set the mode (non-zero = extract)
jr filldn
wildfill:
ld b,c
wildlp: ld (hl),'?'
inc hl
djnz wildlp
filldn: ld a,(infcb+9) ; check for filetype
cp 20h
jr nz,wasext
ld hl,+('I' shl 8) + 'Z' ; set default type to ZIP
ld (infcb+9),hl
ld a,'P'
ld (infcb+11),a
wasext: call setin ; log input user
ld de,infcb
ld c,fopen
call bdos ; try and open ZIP file
inc a
jr nz,openok ; ok
call ilprt ; complain and fall through to exit
db 'Couldn''t find ZIP file',CR,LF,0
;
; All exits point here for possible future enhancements, such
; as elimination of warm boot.
;
exit: jp wboot
;
sigerr: call ilprt
db 'Bad signature in ZIP file',CR,LF,0
jr exit
;
openok: call getword
ld de,-(('K' shl 8) + 'P')
add hl,de
ld a,h
or l
jr nz,sigerr
call getword
dec l
jr nz,nocfhs
dec h
dec h
jr nz,sigerr
call pcfh
jr openok
;
nocfhs: dec l
dec l
jr nz,nolfhs
ld a,h
sub 4
jr nz,sigerr
call plfh
jr openok
;
nolfhs: dec l
dec l
jr nz,sigerr
ld a,h
sub 6
jr nz,sigerr
call pecd
jr exit
;
pcfh: ld b,12
pcfhl1: push bc
call getword
pop bc
djnz pcfhl1
call getword
push hl
call getword
push hl
call getword
pop de
pop bc
push hl
push de
push bc
ld b,6
pcfhl2: push bc
call getword
pop bc
djnz pcfhl2
pop hl
ld de,junk
call getstring
pop hl
ld de,junk
call getstring
pop hl
ld de,junk
call getstring
ret
;
pecd: ld b,8
pecdl: push bc
call getword
pop bc
djnz pecdl
call getword
ld de,junk
call getstring
ret
;
plfh: ld de,lfh
ld hl,endlfh-lfh
call getstring
ld hl,opfcb+1
ld de,opfcb+2
ld bc,33
ld (hl),b
ldir
ld de,junk
ld hl,(fnl)
call getstring
ld de,junk + 20
ld hl,(efl)
call getstring
ld de,junk
ld hl,opfn
ld b,8
call scanfn
ld a,(de)
cp '.'
jr nz,nodot
inc de
nodot: ld b,3
call scanfn
ld hl,init
ld de,vars
ld bc,endinit-init
ldir
ld a,(mode)
resmod: ld (curmode),a
or a
jr z,extrct
mtched: call setout ; log output user
ld de,opfcb ; see if output file already exists
ld c,fopen
call bdos
inc a
jr nz,exists
ld b,11
ld hl,opfn
ld de,mtchfcb
mtchlp: ld a,(de)
ld c,(hl)
inc hl
inc de
cp '?'
jr z,mtch1
res 7,c
cp c
jr nz,nomtch
mtch1: djnz mtchlp
jr creok ; (nope, so continue)
nomtch: ld hl,junk
call pstr
call ilprt
db ' doesn''t match',0
jr noex
exists: ld hl,junk ; it exists, so skip it
call pstr
call ilprt
db ' exists',0
noex: call ilprt
db ' -- not extracting ',0
xor a
jr resmod
;
extrct: xor a
ld (zipeof),a
ld a,(curmode)
or a
jr nz,doext
call ilprt
db 'Checking ',0
jr pjunk
;
creok: call setout
ld de,opfcb ; create output file
ld c,fmake
call bdos
inc a
jr nz,opnok1
call ilprt
db 'Error creating ',0
ld hl,junk
call pstr
jr noex
;
opnok1: call ilprt
db 'Extracting ',0
pjunk: ld hl,junk
call pstr
doext: call ilprt
db ' -- ',0
ld hl,counting
inc (hl)
ld a,(cm)
or a
jr nz,case1
case0w: ld a,(zipeof)
and 1
jr nz,closeo
savcs0: call getbyte
call outbyte
jr case0w
;
case1: dec a
jr nz,case2p
call unshrink
jr closeo
;
case2p: dec a
cp 4
jr nc,tryimp
call unreduce
jr closeo
;
tryimp: jr nz,badzip
call unimplode
jr closeo
;
badzip: call ilprt
db 'Unknown compression method',CR,LF,0
ret
;
closeo: ld hl,zipeof
dec (hl)
inc hl
dec (hl)
ld a,(curmode)
or a
jr z,nocls
; jr nz,nocls
ld hl,wrtpt
ld a,(hl)
or a
jr z,noflsh
ld de,opbuf
ld c,setdma
call bdos
call setout
ld de,opfcb
ld c,fwrite
call bdos
noflsh: call setout
ld de,opfcb
ld c,fclose
call bdos
nocls: ld hl,crc32
ld de,crc
scf
ld bc,4 shl 8
crcclp: ld a,(de)
adc a,(hl)
push af
or c
ld c,a
pop af
inc hl
inc de
djnz crcclp
ld a,c
or a
jr z,crcok
call ilprt
db 'CRC error',CR,LF,0
jr wildck
;
crcok: call ilprt
db 'CRC OK',CR,LF,0
wildck: ld a,(curmode)
or a
ret z
ld hl,mtchfcb
ld bc,11
ld a,'?'
cpir
jp nz,exit
ret
;
getchla:
call getcode
ld (code),hl
ld a,(zipeof)
and 1
ret
;
savstk: ld hl,(stackp)
dec hl
ld (stackp),hl
ld (hl),a
ret
;
getcode:
ld a,(codesize)
readbits:
ld hl,8000h
bitlp: push af
push hl
getbit: ld hl,bleft
dec (hl)
jp m,readbt
dec hl
rr (hl)
pop hl
rr h
rr l
pop af
dec a
jr nz,bitlp
finbit: srl h
rr l
jr nc,finbit
ld a,l
ret
;
readbt: push hl
call getbyte
pop hl
ld (hl),8
dec hl
ld (hl),a
jr getbit
;
scanfn: ld a,(de)
cp '.'
jr z,nocopy
or a
jr z,nocopy
inc de
dec b
jp m,scanfn
ld (hl),a
inc hl
jr scanfn
;
nocopy: dec b
ret m
ld (hl),' '
inc hl
jr nocopy
;
ilprt: pop hl
call pstr
jp (hl)
;
pstr: ld a,(hl)
or a
ret z
push hl
ld e,a
ld c,conout
call bdos
pop hl
inc hl
jr pstr
;
getstring:
ld a,h
or l
ld (d