home *** CD-ROM | disk | FTP | other *** search
- .printx Reading ZFUTILS.Z80
- ;===========================================================================
- ;
- ; ZFUTILS.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).
-
- if unsqz
- usqhdr: ld a,(s$fcb+10) ; Get 2nd character of file extension.
- and 7fh ; mask off SYStem attribute
- 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,(bdosptr+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
- endif ;unsqz
- ;---------------------------------------------------------------------------
-
-
- ; 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
-
- ; End of ZFUTILS.Z80
-