home *** CD-ROM | disk | FTP | other *** search
/ Oakland CPM Archive / oakcpm.iso / sigm / vol197 / unsq86.lib < prev   
Encoding:
Text File  |  1984-10-17  |  9.8 KB  |  345 lines

  1.  
  2. ;    -------------------------------------------------------------
  3. ;    UNSQ.LIB is a library file to be used with Digital Research's
  4. ;    ED.CMD to insert the set of subroutines which it contains
  5. ;    into another program. The purpose of these subroutines is to
  6. ;    read text from a file which has been squeezed by a program
  7. ;    such as SQ.COM (SIG/M 58.26).
  8. ;
  9. ;    UNSQ.LIB is divided into several sections, which can be left
  10. ;    as they are, or integrated into the host program, according
  11. ;    to your sense of orderliness. There are two subroutines that
  12. ;    will be most likely to be called upon - unii and onsq. The
  13. ;    first should be called for initialization, because it reads
  14. ;    in the code directory and sets it up. It also separates out
  15. ;    the file's checksum and the unsqueezed file name. The second
  16. ;    is to be called each time that a character is to be taken out
  17. ;    of the squeezed file.
  18. ;
  19. ;    UNSQ.LIB assumes that the host program contains the following
  20. ;    three subroutines:
  21. ;
  22. ;        ibyt - which will deliver one character from an
  23. ;               external input stream each time it is called.
  24. ;               the external stream can be taken from memory,
  25. ;               from a buffer that is periodically replenished
  26. ;               from disk, or whatever.
  27. ;
  28. ;        ufil - which will dispose of the characters forming
  29. ;               the unsqueezed file name one by one. It might
  30. ;               ignore them, store them in some file control
  31. ;               block, or make some other use of them.
  32. ;
  33. ;        ferm - which will type a fatal error message on the
  34. ;               console and then return to CP/M - or take any
  35. ;               other action which is desired.
  36. ;
  37. ;             UNSQ.LIB  Copyright (C) 1984
  38. ;            Universidad Autonoma de Puebla
  39. ;                July 14, 1984
  40. ;
  41. ;    [Harold V. McIntosh, 14 July 1984]
  42. ;    -------------------------------------------------------------
  43.  
  44. ;    -------------------------------------------------------------
  45. ;    Section 1.  Equivalences defining constants.
  46. ;
  47. ;            CR, LF are used in the messages, and are
  48. ;            traditionally defined in each program. 
  49. ;
  50. ;            csiz is the expected maximum number of
  51. ;            characters which have been coded; 256
  52. ;            is appropriate if all possible bytes may
  53. ;            have been encoded.
  54. ;
  55. ;            <iden> = <FF76> but some other pair
  56. ;            might sometimes be used to mark a squeezed
  57. ;            file
  58.  
  59. CR    equ    0DH
  60. LF    equ    0AH
  61.  
  62. csiz    equ    256
  63. iden    equ    0FF76H
  64.  
  65. ;    -----------------------------------------------------------
  66. ;    Section 2.  Initialization.
  67. ;
  68. ;        <call unii> will initialize two necessary variables
  69. ;        (rcnt, roco), then start reading the squeezed file.
  70. ;        This file must previously have been opened, and its
  71. ;        suitability checked - eg that it has extension ?Q?.
  72. ;        It may even have already been loaded into memory.
  73. ;        All interaction with it is through <call ibyt>, and
  74. ;        the only requirement is that ibyt start reading the
  75. ;        file from the beginning.
  76. ;
  77. ;        unii goes through the following sequence:
  78. ;
  79. ;            check squeezed marker <FF76>
  80. ;            read and store checksum
  81. ;            read, make available name for original file
  82. ;            check the length of the code dictionary
  83. ;            load and store the code dictionary
  84. ;
  85. ;        unii will offer a fatal error message if
  86. ;
  87. ;            the marker <iden> is not present
  88. ;            space will not accomodate the code table
  89. ;
  90. ;        unii requires two host subroutines:
  91. ;
  92. ;            ibyt returns the next byte from the source
  93. ;            ufil disposes of the original file name
  94. ;
  95. ;        No assumptions should be made concerning conservation
  96. ;        of the 8080 registers by unii.
  97. ;
  98. ;        unii will alter the following memory registers:
  99. ;
  100. ;            rcnt - repeated character - set to 0
  101. ;            roco - count bits/byte - set to 1
  102. ;            cksm - checksum - set to file's checksum
  103. ;            dode - code table - loaded with dictionary
  104.  
  105. ;    Initializations.
  106.  
  107. unii:    mov    rcnt,0            ;repetition count
  108.     mov    roco,1            ;bit rotation counter
  109.  
  110. ;    Set up code table. Squeezed files seem to begin with the
  111. ;    hexadecimal word (FF76) stored in Intel byte order, which
  112. ;    would not be likely to start an unsqueezed file.
  113.  
  114. cota:    call    iwor            ;fetch one byte from input stream
  115.     cmp    bx,iden
  116.     jz    rchk            ;mssg: 'not squeezed file'
  117.     mov    dx,(offset nsqz)    ;'not a squeezed file'
  118.     jmp    ferm            ;fatal error message
  119.  
  120. ;    The "squeezed" marker is followed by a two-byte checksum,
  121. ;    which is the simple sum of all the one-byte characters in
  122. ;    the source file, carried as a two byte sum modulo 2**16.
  123.  
  124. rchk:    call    iwor            ;fetch two bytes from input stream
  125.     mov    cksm,bx            ;checksum
  126.  
  127. ;    Unsqueezed file name. It is an ASCII sequence, may be lower
  128. ;    case if SQ.COM received it in response to a prompt, ending
  129. ;    with a zero byte. Some trash may be present if SQ.COM wasn't
  130. ;    used correctly. If the file name is to be used for something,
  131. ;    such as defining an output file or checking the file type,
  132. ;    this is the place to insert the appropriate code.
  133.  
  134. luup:    call    ibyt            ;fetch one byte from input stream
  135.     push    ax
  136.     call    ufil            ;process unsqueezed filename
  137.     pop    ax
  138.     or    al,al
  139.     jnz    luup
  140.  
  141. ;    Load code dictionary. It is preceded by its two-byte length,
  142. ;    and consists of a series of pairs of two-byte addresses. For
  143. ;    each bit in the code, select the first element (0) or the
  144. ;    second (1) element of the pair. If the pair is positive, it
  145. ;    is the table entry (code + 4*index) at which to continue with
  146. ;    the next bit. If the pair is negative, it is the complement
  147. ;    of the coded ASCII character (low order byte except for [end]).
  148.  
  149. ldic:    call    iwor            ;fetch two bytes from input stream
  150.     cmp    bx,(offset csiz)
  151.     jc    ldii
  152.     jz    ldii
  153.     mov    dx,(offset ntab)    ;'insufficient dictionary'
  154.     jmp    ferm            ;fatal error message
  155.  
  156. ldii:    add    bx,bx
  157.     add    bx,bx
  158.     mov    cx,bx
  159.     mov    si,(offset code)    ;decoding table
  160. ldij:    push    cx
  161.     push    si
  162.     call    ibyt            ;fetch one byte from input stream
  163.     mov    [si],al
  164.     pop    si
  165.     pop    cx
  166.     inc    si
  167.     loop    ldij
  168.     ret
  169.  
  170. ;    ----------------------------------------------------------
  171. ;    Section 3.  Read next unsqueezed byte.
  172. ;
  173. ;            <call onby> will withdraw a sufficient
  174. ;            number of bits from the source file to
  175. ;            generate one byte, returning it in the
  176. ;            accumulator. The end of the source file
  177. ;            will be signified by c = 1; otherwise
  178. ;            c = 0 will prevail. Reading of the source
  179. ;            file may terminate before this condition
  180. ;            is reached, for example if the source
  181. ;            was an ASCII file terminating with ^Z,
  182. ;            or a HEX file terminated by a final line.
  183. ;
  184. ;            The preservation of registers cannot be
  185. ;            guaranteed; surround <call onby> with
  186. ;            pushes and pops is such continuity is
  187. ;            required.
  188. ;
  189. ;            onby will solicit the fatal error message
  190. ;            subroutine if the [eof] marker signified
  191. ;            by c = 1 has been reached without the
  192. ;            checksum having balanced. This protection
  193. ;            can be secured for files that were not
  194. ;            read in their entirity by reading out the
  195. ;            remaining bytes in a dummy loop.
  196. ;
  197. ;            onby alters the following memory registers:
  198. ;
  199. ;                lach - last character deposited
  200. ;                rcnt - repetition count
  201. ;                roco - rotating bit counter
  202. ;                roby - rotating byte
  203. ;                cksm - checksum
  204.  
  205. ;    Type unsqueezed code. Beware of the [end] marker,
  206. ;    and also the repeat marker 90H which occurs in the
  207. ;    combination <char><90H><count>. When count is zero,
  208. ;    90H itself is intended; otherwise <char> is to be
  209. ;    repeated <count> times, including the occurrence just
  210. ;    before 90H was seen.
  211.  
  212. onsq:    mov    al,rcnt            ;repetition count
  213.     or    al,al
  214.     jnz    onsr
  215.     call    dnch            ;decode next character
  216.     jc    vchk            ;verify the checksum
  217.     cmp    al,090H            ;repeat last character
  218.     jnz    onsu            ;normal character
  219.     call    dnch            ;decode next character
  220.     or    al,al
  221.     jz    onss
  222.     dec    al
  223. onsr:    dec    al
  224.     mov    rcnt,al            ;repetition count
  225.     mov    al,lach
  226.     jmp    achk
  227.  
  228. onss:    mov    al,090H
  229.     jmp    achk
  230.  
  231. onsu:    mov    lach,al            ;last character typed
  232. ;    jmp    achk
  233.  
  234. ;    Accumulate checksum.
  235.  
  236. achk:    mov    ah,0
  237.     sub    cksm,ax
  238.     stc
  239.     cmc
  240. achr:    ret
  241.  
  242. ;    Verify the checksum.
  243.  
  244. vchk:    cmp    cksm,0000        ;checksum
  245.     stc
  246.     jz    achr
  247.     mov    dx,(offset chno)    ;'Checksum failure.'
  248.     jmp    ferm            ;fatal error message
  249.  
  250. ;    Decode next character.
  251.  
  252. dnch:    mov    bx,(offset code)    ;decoding table
  253. dncr:    call    ibit            ;read next bit
  254.     jnc    dncs            ;skip for 1, stay for 0
  255.     inc    bx
  256.     inc    bx
  257. dncs:    mov    ax,[bx]            ;get next offset
  258.     cmp    ax,0FEFFH        ;FEFF means [end]
  259.     jz    dnct
  260.     or    ax,ax
  261.     jns    dncu            ;p means new offset
  262.     not    al            ;m means complemented char
  263.     stc
  264.     cmc
  265.     ret
  266.  
  267. dnct:    stc                ;flag [end] with carry bit
  268.     ret
  269.  
  270. ;    Calculate <code>+4*<offset>.
  271.  
  272. dncu:    mov    bx,(offset code)    ;decoding table
  273.     add    ax,ax
  274.     add    ax,ax
  275.     add    bx,ax
  276.     jmp    dncr
  277.  
  278. ;    Read one bit at a time.
  279.  
  280. ibit:    dec    roco            ;bit rotation counter
  281.     jnz    ibiu
  282.     mov    roco,8
  283.     call    ibyt            ;fetch one byte from input stream
  284.     mov    roby,al            ;rotating byte
  285. ibiu:    rcr    roby,1            ;rotating byte
  286.     ret
  287.  
  288. ;    Read one word.
  289.  
  290. iwor:    call    ibyt            ;fetch one byte from input stream
  291.     mov    bl,al
  292.     push    bx
  293.     call    ibyt            ;fetch one byte from input stream
  294.     pop    bx
  295.     mov    bh,al
  296.     ret
  297.  
  298. ;    -----------------------------------------------------------
  299. ;    Section 4.  Host subroutines.
  300. ;
  301. ;            The following subroutines must be provided
  302. ;            by the host program:
  303. ;
  304. ;                ibyt - deliver the next byte from
  305. ;                the source program, in register A,
  306. ;                on each call. Need not preserve any
  307. ;                8080 registers.
  308. ;
  309. ;                ufil - must absorb one byte from
  310. ;                register A on each call. These bytes
  311. ;                will be the information that is
  312. ;                nominally the name of the source
  313. ;                file, SOURCE.EXT, including the dot.
  314. ;                ufil should be prepared for possible
  315. ;                variants, however. ufil will be given
  316. ;                final zero byte to signal the end of
  317. ;                the bytestream it will receive. Of
  318. ;                course, ufil could be imbedded in
  319. ;                place of a call to it.
  320. ;
  321. ;                ferm - send a fatal error message to
  322. ;                the console. Normally control would
  323. ;                return to CP/M, but some other action
  324. ;                may be taken.
  325.  
  326. ibyt:    ret        ;fetch byte from the input stream
  327. ufil:    ret        ;process unsqueezed filename
  328. ferm:    ret        ;fatal error message
  329.  
  330. ;    -------------------------------------------------------------
  331. ;    Section 5.  Messages and memory locations used by the program.
  332.  
  333. ntab    db    CR,LF,'Insufficient dictionary space.$'
  334. nsqz    db    CR,LF,'Not a squeezed file.$'
  335. chno    db    CR,LF,'Checksum failure.$'
  336.  
  337. lach    rb    1            ;last character typed
  338. rcnt    rb    1            ;repetition count
  339. roco    rb    1            ;rotating bit counter
  340. roby    rb    1            ;rotating byte
  341. cksm    rw    1            ;checksum
  342. code    rb    4*csiz            ;decoding table
  343.  
  344.     end
  345.