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
/
CPM
/
ZCPR33
/
S-Z
/
VFILER43.LBR
/
VFUTILS.LZB
/
VFUTILS.LIB
Wrap
Text File
|
2000-06-30
|
8KB
|
328 lines
;===========================================================================
;
; VFUSQ.Z80 - Utilities Code: Unsqueezing and CRC Modules
;
;===========================================================================
; V F I L E R U N S Q U E E Z E S U B R O U T I N E S
; Read Header for Squeezed file
;
; - Header Layout:
;
; Length (bytes) Description
; -------------- ------------------------------------
; 2 Squeezed file flag - 0FF76h
; 2 File CRC
; 16 (max) File ID (ASCIIZ string)
; 2 Numvals - # nodes in decode tree (Max 258)
; Numvals Decode tree entries
; - Each node consists of 4 bytes:
; - left child index/char (2 bytes)
; - right child index/char (2 bytes)
; - Each half is encoded as follows:
; - contains child index (1-100h) or character,
; where characters are encoded as negative
; values -(char+1).
; - EOF is encoded as -(100h+1).
;
;
; "Characters" refer to all different chars present in the original
; file, as well as any added through run encoding. Runs of 3 or more
; consecutive identical characters are encoded as char, DLE, count,
; where count is a one byte field (0 - 0FFh).
usqhdr: ld a,(s$fcb+10) ; Get 2nd character of file extension.
cp 'Q' ; Potentially squeezed file?
ld a,1 ; Assume error 1: not squeezed file.
jp nz,usqhrt ; Exit if not.
ld (usqeof+1),sp ; Save sp in case of premature eof.
; Check Squeezed file Indicator
call getw ; Get first word of file.
ld de,recniz ; Get squeeze file tag.
call cmpdehl ; Valid squeezed file?
ld a,2 ; Assume error 2: ?q? file not squeezed.
jr nz,usqhrt ; Exit if not.
; Get Checksum for file
call getw ; Get checksum from file
ld (sqcksum),hl ; And save for later check.
; Get original file ID.
ld hl,usqfid ; Point to file id buffer.
usqh0: call f0$get ; Get id character from file.
jp nz,usqeof ; Exit if premature end-of-file
ld (hl),a ; Save character.
inc hl
or a ; Zero has terminated filename.ext?
jr nz,usqh0 ; Loop until terminator.
ld hl,usqfid ; Point to file id buffer.
ld de,d$fcb ; And destination fcb
call fname
; Get # nodes in decode table.
call getw ; Get decode table size
ld (numvals),hl ; Set # of nodes in use.
ld de,maxnode
call cmpdehl ; Compare to maximum value.
jr nc,usqh1 ; Ok if # nodes <= maximum.
ld a,3 ; Error 3: illegal decode size.
jr usqhrt ; Exit.
; Ensure buffer is available for Unsqueeze.
usqh1: add hl,hl ; Get # of bytes in decode table.
add hl,hl
push hl ; Save decode table size
ld de,(bufstart) ; Get address of start of work buffer.
add hl,de ; Get address of start of usq file buffer.
ld (usqbuff@),hl ; Save it.
ex de,hl ; De = buffer start addr (end of decode tbl)
ld hl,(bdos+1) ; Get 'bdos' entry (fbase)
if not warmboot
ld bc,-ccp_ln
add hl,bc
endif ; Not warmboot
dec hl
ex de,hl ; De = highest buffer address
; Hl = buffer start addr (end of decode tbl)
ld a,e ; Hl = de - hl = buffer size (bytes)
sub l
ld l,a
ld a,d
sbc a,h
ld h,a
pop de ; Restore decode table size into counter reg.
jr c,usqh1a ; Error if start addr > end addr
ld b,7+1 ; Shift hl right 7 bits.
call shiftlp ; To divide by 128.
ld (urecmax),hl ; Save maximum # of records during unsqueeze.
ld a,h ; Memory available for usq?
or l
jr nz,usqh2 ; Br if sufficient room for usq.
usqh1a: ld a,4 ; Error 4: insufficient work space.
jr usqhrt ; Exit.
; Load user decode table
usqh2: ld hl,(bufstart) ; Node table starts at beginning of work buffer.
usqh3: ld a,d ; Br if done reading decode table.
or e
jr z,usqh4
call f0$get ; Get byte of decode entry.
ld (hl),a ; Save in decode table.
inc hl
dec de ; One byte of decode table loaded.
jr usqh3 ; Continue.
usqh4: xor a ; Header was ok.
ld (repcnt),a ; Zero repeat count.
ld (curusq+1),a ; Zero bits remaining in current byte.
; - force initial character read
usqhrt: ld (usqflg),a
or a
ret
; Unsqueeze next character from file.
;
; - Normal return: A=character, Z set
; Error return: A=error code, Z reset.
usqnxt: ld a,(repcnt) ; In middle of repeat sequence?
or a
jr z,usqn1 ; Br if not.
dec a ; Last char repeated once again.
ld (repcnt),a ; Update count.
ld a,(last) ; Get last char.
cp a ; Flag success.
ret
usqn1:
ld (usqeof+1),sp ; Save sp in case of premature eof.
call usqchr ; Decode next character.
cp dle ; Data link escape?
jr nz,usqn2 ; Continue if not.
call usqchr ; Decode next char.
or a ; Must be 0 if really a dle.
jr nz,usqn3 ; No, was (char, dle, count).
ld a,dle ; Dle found. was encoded as dle,0
cp a ; Flag success.
ret
usqn2: ld (last),a ; Save current character.
cp a ; Flag success.
ret
usqn3: dec a ; Adjust repeat count for first occurance
dec a ; And this repetition.
ld (repcnt),a ; Store remaining repeat count.
ld a,(last) ; Get character to be repeated.
cp a ; Flag success.
ret
usqchr: ld bc,0 ; Start at beginning of tree.
ld de,(curusq) ; Get file byte and bit number.
usqch1: ld a,d ; Get # bits remaining in current byte.
or a
jr nz,usqch2 ; Br if not empty.
call f0$get ; Get next byte from file.
jr nz,usqeof ; Br if premature eof.
ld e,a ; Save byte.
ld d,8 ; 8 bits available.
usqch2: dec d ; Update # bits remaining in current byte.
ld a,e
rrca
ld e,a ; Shift current bit into carry flag.
ld hl,(bufstart) ; Node table starts at beginning of work buffer.
jr nc,usqch3 ; Br if left child desired.
inc hl ; Point to right child.
inc hl
usqch3: add hl,bc ; Offset into decode table.
add hl,bc
add hl,bc
add hl,bc
ld c,(hl) ; Get entry containing next child / char
inc hl
ld b,(hl)
ld a,b
and 80h ; Has character been found?
jr z,usqch1 ; Br if not.
ld (curusq),de ; Update file byte and bit number.
ld a,b ; Get compiment of unsqueezed character.
cp seof ; Special end-of-file?
ld a,eof
jr z,geteof ; Br if so.
ld a,c ; Get actual unsqueezed character.
cpl
cp a ; Flag success.
ret
geteof: pop hl ; Move up one level on the stack.
or a ; Flag success.
ret ; Return to original caller.
; Error 5 -Premature EOF while unsqueezing file.
usqeof: ld sp,0 ; Reset sp to entry value
ld a,5 ; Error 5: premature eof
jr usqhrt ; Exit.
; Get Word from file
; - Word assumed to be in low byte, high byte order
; - On exit, HL contains word.
getw: call f0$get ; Get character from file.
jr nz,usqeof ; Br if premature eof.
ld l,a ; Get low char in l.
call f0$get ; Get character from file.
jr nz,usqeof ; Br if premature eof
ld h,a ; Get high char in h
ret
;---------------------------------------------------------------------------
; V F I L E R C R C S U B R O U T I N E S
; INITCRC - initialize tables for fast CRC calculations
initcrc:
ld hl,(crctbl)
ld c,0 ; Table index
gloop: ex de,hl
ld hl,0 ; Initialize crc register pair
ld a,c
push bc ; Save index in c-reg
ld b,8
xor h
ld h,a
lloop: add hl,hl
jr nc,lskip
ld a,10h ; Generator is x^16 + x^12 + x^5 + x^0 as..
xor h ; Recommended by ccitt for asynchronous..
ld h,a ; Communications. produces the same..
ld a,21h ; Results as public domain programs..
xor l ; Chek, comm7, mdm7, and modem7.
ld l,a
lskip:
djnz lloop
pop bc
ex de,hl ; De now has crc, hl pointing into table.
ld (hl),d ; Store high byte of crc..
inc h
ld (hl),e ; And store low byte.
dec h
inc hl ; Move to next table entry
inc c ; Next index
jr nz,gloop
ret
; UPDCRC - Update CRC Accumulator
updcrc: push bc ; Update 'crc'..
push hl ; Accumulator..
ld de,(crcval) ; Pick up partial remainder
ld b,0
xor d
ld c,a
ld hl,(crctbl)
add hl,bc
ld a,(hl)
xor e
ld d,a
inc h
ld e,(hl)
ld (crcval),de
pop hl
pop bc
ret
; UPDCKSUM - Update USQ Checksum Accumulator
; - HL -> last unsqueezed char.
updcksum:
push de
push hl
ld d,0 ; Clear high byte
ld e,(hl) ; Get character in low byte
ld hl,(cksumval) ; Pick up partial remainder
add hl,de ; Accumulate checksum
ld (cksumval),hl ; Update checsum accumulator
pop hl
pop de
ret