home *** CD-ROM | disk | FTP | other *** search
/ CP/M / CPM_CDROM.iso / jsage / znode3 / uploads / zf11src.lbr / ZFUTILS.ZZ0 / ZFUTILS.Z80
Encoding:
Text File  |  1992-10-01  |  8.4 KB  |  333 lines

  1. .printx    Reading ZFUTILS.Z80
  2. ;===========================================================================
  3. ;
  4. ; ZFUTILS.Z80 - Utilities Code: Unsqueezing and CRC Modules
  5. ;
  6. ;===========================================================================
  7.  
  8.  
  9. ; 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
  10.  
  11.  
  12. ;    Read Header for Squeezed file
  13. ;
  14. ;    - Header Layout:
  15. ;
  16. ;      Length (bytes)        Description
  17. ;      --------------    ------------------------------------
  18. ;          2     Squeezed file flag - 0FF76h
  19. ;          2     File CRC
  20. ;         16 (max)    File ID (ASCIIZ string)
  21. ;          2     Numvals - # nodes in decode tree (Max 258)
  22. ;    Numvals     Decode tree entries
  23. ;             - Each node consists of 4 bytes:
  24. ;                - left child index/char  (2 bytes)
  25. ;                - right child index/char (2 bytes)
  26. ;             - Each half is encoded as follows:
  27. ;                - contains child index (1-100h) or character,
  28. ;                  where characters are encoded as negative
  29. ;                  values -(char+1).
  30. ;                - EOF is encoded as -(100h+1).
  31. ;
  32. ;
  33. ;      "Characters" refer to all different chars present in the original
  34. ;    file, as well as any added through run encoding. Runs of 3 or more
  35. ;    consecutive identical characters are encoded as char, DLE, count,
  36. ;    where count is a one byte field (0 - 0FFh).
  37.  
  38.      if    unsqz
  39. usqhdr:    ld    a,(s$fcb+10)    ; Get 2nd character of file extension.
  40.     and    7fh        ; mask off SYStem attribute
  41.     cp    'Q'        ; Potentially squeezed file?
  42.     ld    a,1        ; Assume error 1: not squeezed file.
  43.     jp    nz,usqhrt    ; Exit if not.
  44.  
  45.     ld    (usqeof+1),sp    ; Save sp in case of premature eof.
  46.  
  47. ;    Check Squeezed file Indicator
  48.  
  49.     call    getw        ; Get first word of file.
  50.     ld    de,recniz    ; Get squeeze file tag.
  51.     call    cmpdehl        ; Valid squeezed file?
  52.     ld    a,2        ; Assume error 2: ?q? file not squeezed.
  53.     jr    nz,usqhrt    ; Exit if not.
  54.  
  55. ;    Get Checksum for file
  56.  
  57.     call    getw        ; Get checksum from file
  58.     ld    (sqcksum),hl    ; And save for later check.
  59.  
  60. ;    Get original file ID.
  61.  
  62.     ld    hl,usqfid    ; Point to file id buffer.
  63. usqh0:    call    f0$get        ; Get id character from file.
  64.     jp    nz,usqeof    ; Exit if premature end-of-file
  65.     ld    (hl),a        ; Save character.
  66.     inc    hl
  67.     or    a        ; Zero has terminated filename.ext?
  68.     jr    nz,usqh0    ; Loop until terminator.
  69.  
  70.     ld    hl,usqfid    ; Point to file id buffer.
  71.     ld    de,d$fcb    ; And destination fcb
  72.     call    fname
  73.  
  74. ;    Get # nodes in decode table.
  75.  
  76.     call    getw        ; Get decode table size
  77.     ld    (numvals),hl    ; Set # of nodes in use.
  78.     ld    de,maxnode
  79.     call    cmpdehl        ; Compare to maximum value.
  80.     jr    nc,usqh1    ; Ok if # nodes <= maximum.
  81.  
  82.     ld    a,3        ; Error 3: illegal decode size.
  83.     jr    usqhrt        ; Exit.
  84.  
  85. ;    Ensure buffer is available for Unsqueeze.
  86.  
  87. usqh1:    add    hl,hl        ; Get # of bytes in decode table.
  88.     add    hl,hl
  89.     push    hl        ; Save decode table size
  90.  
  91.     ld    de,(bufstart)    ; Get address of start of work buffer.
  92.     add    hl,de        ; Get address of start of usq file buffer.
  93.     ld    (usqbuff@),hl    ; Save it.
  94.     ex    de,hl        ; De = buffer start addr (end of decode tbl)
  95.  
  96.     ld    hl,(bdosptr+1)    ; Get 'bdos' entry (fbase)
  97.  
  98.      if    not warmboot
  99.     ld    bc,-ccp_ln
  100.     add    hl,bc
  101.      endif            ; Not warmboot
  102.  
  103.     dec    hl
  104.     ex    de,hl        ; De = highest buffer address
  105.                 ; Hl = buffer start addr (end of decode tbl)
  106.     ld    a,e        ; Hl = de - hl = buffer size (bytes)
  107.     sub    l
  108.     ld    l,a
  109.     ld    a,d
  110.     sbc    a,h
  111.     ld    h,a
  112.     pop    de        ; Restore decode table size into counter reg.
  113.     jr    c,usqh1a    ; Error if start addr > end addr
  114.  
  115.     ld    b,7+1        ; Shift hl right 7 bits.
  116.     call    shiftlp        ; To divide by 128.
  117.  
  118.     ld    (urecmax),hl    ; Save maximum # of records during unsqueeze.
  119.     ld    a,h        ; Memory available for usq?
  120.     or    l
  121.     jr    nz,usqh2    ; Br if sufficient room for usq.
  122.  
  123. usqh1a:    ld    a,4        ; Error 4: insufficient work space.
  124.     jr    usqhrt        ; Exit.
  125.  
  126. ;    Load user decode table
  127.  
  128. usqh2:    ld    hl,(bufstart)    ; Node table starts at beginning of work buffer.
  129.  
  130. usqh3:    ld    a,d        ; Br if done reading decode table.
  131.     or    e
  132.     jr    z,usqh4
  133.  
  134.     call    f0$get        ; Get byte of decode entry.
  135.     ld    (hl),a        ; Save in decode table.
  136.     inc    hl
  137.  
  138.     dec    de        ; One byte of decode table loaded.
  139.     jr    usqh3        ; Continue.
  140.  
  141. usqh4:    xor    a        ; Header was ok.
  142.     ld    (repcnt),a    ; Zero repeat count.
  143.     ld    (curusq+1),a    ; Zero bits remaining in current byte.
  144.                 ; - force initial character read
  145. usqhrt:    ld    (usqflg),a
  146.     or    a
  147.     ret
  148.  
  149. ;    Unsqueeze next character from file.
  150. ;
  151. ;    - Normal return: A=character, Z set
  152. ;      Error return:  A=error code, Z reset.
  153.  
  154. usqnxt:    ld    a,(repcnt)    ; In middle of repeat sequence?
  155.     or    a
  156.     jr    z,usqn1        ; Br if not.
  157.  
  158.     dec    a        ; Last char repeated once again.
  159.     ld    (repcnt),a    ; Update count.
  160.     ld    a,(last)    ; Get last char.
  161.     cp    a        ; Flag success.
  162.     ret
  163.  
  164. usqn1:
  165.     ld    (usqeof+1),sp    ; Save sp in case of premature eof.
  166.  
  167.     call    usqchr        ; Decode next character.
  168.     cp    dle        ; Data link escape?
  169.     jr    nz,usqn2    ; Continue if not.
  170.     call    usqchr        ; Decode next char.
  171.     or    a        ; Must be 0 if really a dle.
  172.     jr    nz,usqn3    ; No, was (char, dle, count).
  173.  
  174.     ld    a,dle        ; Dle found. was encoded as dle,0
  175.     cp    a        ; Flag success.
  176.     ret
  177.  
  178. usqn2:    ld    (last),a    ; Save current character.
  179.     cp    a        ; Flag success.
  180.     ret
  181.  
  182. usqn3:    dec    a        ; Adjust repeat count for first occurance
  183.     dec    a        ; And this repetition.
  184.     ld    (repcnt),a    ; Store remaining repeat count.
  185.     ld    a,(last)    ; Get character to be repeated.
  186.     cp    a        ; Flag success.
  187.     ret
  188.  
  189. usqchr:    ld    bc,0        ; Start at beginning of tree.
  190.     ld    de,(curusq)    ; Get file byte and bit number.
  191.  
  192. usqch1:    ld    a,d        ; Get # bits remaining in current byte.
  193.     or    a
  194.     jr    nz,usqch2    ; Br if not empty.
  195.  
  196.     call    f0$get        ; Get next byte from file.
  197.     jr    nz,usqeof    ; Br if premature eof.
  198.     ld    e,a        ; Save byte.
  199.     ld    d,8        ; 8 bits available.
  200.  
  201. usqch2:    dec    d        ; Update # bits remaining in current byte.
  202.     ld    a,e
  203.     rrca
  204.     ld    e,a        ; Shift current bit into carry flag.
  205.     ld    hl,(bufstart)    ; Node table starts at beginning of work buffer.
  206.     jr    nc,usqch3    ; Br if left child desired.
  207.     inc    hl        ; Point to right child.
  208.     inc    hl
  209.  
  210. usqch3:    add    hl,bc        ; Offset into decode table.
  211.     add    hl,bc
  212.     add    hl,bc
  213.     add    hl,bc
  214.     ld    c,(hl)        ; Get entry containing next child / char
  215.     inc    hl
  216.     ld    b,(hl)
  217.  
  218.     ld    a,b
  219.     and    80h        ; Has character been found?
  220.     jr    z,usqch1    ; Br if not.
  221.  
  222.     ld    (curusq),de    ; Update file byte and bit number.
  223.  
  224.     ld    a,b        ; Get compiment of unsqueezed character.
  225.     cp    seof        ; Special end-of-file?
  226.     ld    a,eof
  227.     jr    z,geteof    ; Br if so.
  228.  
  229.     ld    a,c        ; Get actual unsqueezed character.
  230.     cpl
  231.     cp    a        ; Flag success.
  232.     ret
  233.  
  234. geteof:    pop    hl        ; Move up one level on the stack.
  235.     or    a        ; Flag success.
  236.     ret            ; Return to original caller.
  237.  
  238. ;    Error 5 -Premature EOF while unsqueezing file.
  239.  
  240. usqeof:    ld    sp,0        ; Reset sp to entry value
  241.     ld    a,5        ; Error 5: premature eof
  242.     jr    usqhrt        ; Exit.
  243.  
  244. ;    Get Word from file
  245. ;    - Word assumed to be in low byte, high byte order
  246. ;    - On exit, HL contains word.
  247.  
  248. getw:    call    f0$get        ; Get character from file.
  249.     jr    nz,usqeof    ; Br if premature eof.
  250.     ld    l,a        ; Get low char in l.
  251.     call    f0$get        ; Get character from file.
  252.     jr    nz,usqeof    ; Br if premature eof
  253.     ld    h,a        ; Get high char in h
  254.     ret
  255.      endif    ;unsqz
  256. ;---------------------------------------------------------------------------
  257.  
  258.  
  259. ; V F I L E R     C R C      S U B R O U T I N E S
  260.  
  261.  
  262. ; INITCRC - initialize tables for fast CRC calculations
  263.  
  264. initcrc:
  265.     ld    hl,(crctbl)
  266.     ld    c,0        ; Table index
  267. gloop:    ex    de,hl
  268.     ld    hl,0        ; Initialize crc register pair
  269.     ld    a,c
  270.     push    bc        ; Save index in c-reg
  271.     ld    b,8
  272.     xor    h
  273.     ld    h,a
  274. lloop:    add    hl,hl
  275.     jr    nc,lskip
  276.     ld    a,10h        ; Generator is x^16 + x^12 + x^5 + x^0 as..
  277.     xor    h        ; Recommended by ccitt for asynchronous..
  278.     ld    h,a        ; Communications.  produces the same..
  279.     ld    a,21h        ; Results as public domain programs..
  280.     xor    l        ; Chek, comm7, mdm7, and modem7.
  281.     ld    l,a
  282. lskip:
  283.     djnz    lloop
  284.     pop    bc
  285.     ex    de,hl        ; De now has crc, hl pointing into table.
  286.     ld    (hl),d        ; Store high byte of crc..
  287.     inc    h
  288.     ld    (hl),e        ; And store low byte.
  289.     dec    h
  290.     inc    hl        ; Move to next table entry
  291.     inc    c        ; Next index
  292.     jr    nz,gloop
  293.     ret
  294.  
  295.  
  296. ;  UPDCRC - Update CRC Accumulator
  297.  
  298. updcrc:    push    bc        ; Update 'crc'..
  299.     push    hl        ; Accumulator..
  300.     ld    de,(crcval)    ; Pick up partial remainder
  301.     ld    b,0
  302.     xor    d
  303.     ld    c,a
  304.     ld    hl,(crctbl)
  305.     add    hl,bc
  306.     ld    a,(hl)
  307.     xor    e
  308.     ld    d,a
  309.     inc    h
  310.     ld    e,(hl)
  311.     ld    (crcval),de
  312.     pop    hl
  313.     pop    bc
  314.     ret
  315.  
  316.  
  317. ;  UPDCKSUM - Update USQ Checksum Accumulator
  318. ;    - HL -> last unsqueezed char.
  319.  
  320. updcksum:
  321.     push    de
  322.     push    hl
  323.     ld    d,0        ; Clear high byte
  324.     ld    e,(hl)        ; Get character in low byte
  325.     ld    hl,(cksumval)    ; Pick up partial remainder
  326.     add    hl,de        ; Accumulate checksum
  327.     ld    (cksumval),hl    ; Update checsum accumulator
  328.     pop    hl
  329.     pop    de
  330.     ret
  331.  
  332. ; End of ZFUTILS.Z80
  333.