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
Text File  |  2000-06-30  |  8KB  |  328 lines

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