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 / UTILS / SQUSQ / SQUEEZER.DOC < prev    next >
Text File  |  2000-06-30  |  24KB  |  545 lines

  1. USAGE AND RECOMPILATION DOCUMENTATION FOR:         8/29/81
  2.      SQ.COM    1.5  File squeezer
  3.      USQ.COM   1.5  File unsqueezer
  4.      FLS.COM   1.1  Ambiguous file name expander
  5.  
  6. DISTRIBUTION RIGHTS:
  7. I   allow  unrestricted  non-profit  distribution  of   this 
  8. software  and  invite  users groups  to  spread  it  around. 
  9. However,  any distribution for profit requires my permission 
  10. in  advance.  This applies only to the above listed programs 
  11. and their program source and documentation files.  I do sell  
  12. other software.
  13.  
  14. PURPOSE:
  15. The file squeezer,  SQ, compresses files into a more compact 
  16. form.  This provides:
  17.      1.   Faster transmission by modem.
  18.      2.   Fewer diskettes to distribute a program  package. 
  19.           (Include USQ.COM and instructions, both unsqueezed.)
  20.      3.   Fewer diskettes for archival storage.
  21.  
  22. Any file can be squeezed,  but program source files and text 
  23. files  benefit the most,  typically shrinking by 35%.  Files 
  24. containing only a limited character set,  such as dictionary 
  25. files,  may shrink as much as 48%.  Squeezed files look like 
  26. gibbersh and must be unsqueezed before they can be used.
  27.  
  28. The  unsqueezer,  USQ,  expands  squeezed files  into  exact 
  29. duplicates  of the original or provides a quick,  unsqueezed 
  30. display  of  the  tops  of  (or  all  of)  squeezed   files. 
  31. Unsqueezing requires only a single pass.
  32.  
  33. Both SQ and USQ accept batches of work specified by lists of 
  34. file  names  (with  drives  if  needed)  and   miscellaneous 
  35. options. They accept these parameters in any of three ways:
  36.  
  37.      1. On the CP/M command line.
  38.      2. From the console keyboard.
  39.      3. From a file.
  40.  
  41. The  FLS program can be used (on the same command line!)  to 
  42. expand parameter lists containing wild-card (ambiguous) file 
  43. names into lists with the specific file names required by SQ 
  44. and USQ.
  45.  
  46. This  combination of programs allows you to issue  a  single 
  47. command which will produce many squeezed or unsqueezed files 
  48. from and to various diskettes. For example, to unsqueeze all 
  49. squeezed  ASM files on drive B and send the results to drive 
  50. C  and also unsqueeze all squeezed TXT files on drive A  and 
  51. send the results to drive D:
  52.      A>fls c: b:*.aqm d: *.tqt |usq
  53. For detailed instructions see USAGE.
  54. This  DOES  run under plain old vanilla CP/M!  Many  of  the 
  55. smarts  are buried in the COM files in the form  of  library 
  56. routines  provided  with the BDS C package  (available  from 
  57. Lifeboat).
  58.  
  59. The  above example simulates a "pipe" (indicated by the "|") 
  60. by sending the "console" output of the fls.com program to  a 
  61. temporary  file  and  then running the sq.com  program  with 
  62. options  which  cause  it to read its  parameters  from  its 
  63. "console" input, which is really redirected to come from the 
  64. temporary file.
  65.  
  66. Note that programs written in BDS C tend to be GOable. That is
  67. if you do A>save 0 GO and run a C program (just one - no pipes)
  68. then you can rerun it without reading it from disk by using GO
  69. as its name and giving the usual parameters. This works because
  70. BDS C doesn't support initialized static variables. The program
  71. has to initialize everything dynamically, so it cleans up for
  72. each rerun.
  73.  
  74. THEORY:
  75. The  data  in the file is treated at the byte  level  rather 
  76. then  the word level,  and can contain absolutely  anything. 
  77. The compression is in two stages: first repeated byte values 
  78. are  compressed  and  then a  Huffman  code  is  dynamically 
  79. generated  to match the properties of each particular  file. 
  80. This requires two passes over the source data.
  81.  
  82. The  decoding  table is included in the  squeezed  file,  so 
  83. squeezing  short  files can actually  lengthen  them.  Fixed 
  84. decoding  tables  are not used because  English and  various 
  85. computer  languages vary greatly as to upper and lower  case 
  86. proportions  and  use of special  characters.  Much  of  the 
  87. savings  comes  from  not  assigning codes  to  unused  byte 
  88. values.
  89.  
  90. More detailed comments are included in the source files.
  91.  
  92. USAGE TUTORIAL:
  93. As usual, you have to learn how to tell the programs what to 
  94. do  (i.e.,  what parameters to type after the program name). 
  95. First I will introduce the various possibilities by example. 
  96. Then I will summarize the rules.
  97.  
  98. In  the simplest case either SQ or USQ can simply  be  given 
  99. one or more file names (with or without drive names):
  100.      A>sq xyz.asm
  101.      A>sq thisfile.doc b:thatfile.doc
  102. will   create  squeezed  files  xyz.aqm,   thisfile.dqc  and 
  103. thatfile.dqc,  all  on the current drive,  A.  The  original 
  104. files are not disturbed. Note that the names of the squeezed 
  105. files are generated by rules - you don't specify them.
  106.  
  107. Likewise,
  108.      A>usq xyz.aqm
  109. will  create file xyz.asm on the A  drive,  overwriting  the 
  110. original.  (The  original name is recreated from information 
  111. stored in the squeezed version.) The squeezed version is not 
  112. disturbed.
  113.  
  114. Each file name is processed in order,  and you can list  all 
  115. the files you can fit in a command.  The file names given to 
  116. SQ and USQ must be specific. You will learn below how to use 
  117. the FLS program to expand patterns like *.asm (all files  of 
  118. type  asm) into a list of specific names and feed them  into 
  119. SQ or USQ.
  120.  
  121. The above examples let the destination drive default to  the 
  122. current logged drive, which was shown in the prompt to be A. 
  123. You can change the destination drive as often as you like in 
  124. the parameter list. For example,
  125.      A>sq x.aqm b: y.aqm z.aqm c: d:s.aqm
  126. will create x.aqm on the current drive,  A,  y.aqm and z.aqm 
  127. on the B drive and s.aqm on the C drive. Note that the first 
  128. three originals are on drive A and the last one is on  drive 
  129. D.  Remember  that each parameter is processed in order,  so 
  130. you must change the destination drive before you specify the 
  131. files to be created on that drive.
  132.  
  133. Eventually you will have diskettes with many squeezed  files 
  134. on  them and you will wonder what is in which file.  If they 
  135. weren't  squeezed you would use the TYPE command to look  at 
  136. the  comments at the beginning of the  files.  But  squeezed 
  137. files  just  make  a mess on your CRT screen when  you  TYPE 
  138. them,  so  I have provided the required feature as a preview 
  139. option to the USQ program.
  140.      A>usq -10 x.bqs b:y.aqm
  141. will  not take the time to create unsqueezed files.  Instead 
  142. it  will  unsqueeze  the first 10 lines  of  each  file  and 
  143. display  them  on your console.  The display from each  file 
  144. consists of the file names, the data and a formfeed (FF).
  145. Also,
  146.      A>usq - c:xyz.mqc
  147. will  unsqueeze  and display the first 65,535 lines  of  any 
  148. files listed. That's the biggest number you can give it, and 
  149. is intended to display the whole file.
  150.  
  151. This   preview  option  also  ensures  that  the   data   is 
  152. displayable.  The  parity bit is stripped off (some Wordstar 
  153. files  use  it for format control) and any  unusual  control 
  154. characters  are  converted to periods.  You'll see  some  of 
  155. these  at  the end of the files as the CP/M end of  file  is 
  156. treated  as  data  and  the  remainder  of  the  sector   is 
  157. displayed.
  158.  
  159. You are now familiar with all of the operational  parameters 
  160. of SQ and USQ.  But so far you have always typed them on the 
  161. command line which caused the program to be run. For reasons 
  162. which  will become apparent later,  I have also provided  an 
  163. interactive  mode.   If  there  are  no  parameters  (except 
  164. directed  i/o  parameters,  described later) on the  command 
  165. line,  SQ  and USQ will prompt with an asterisk  and  accept 
  166. parameters from the console keyboard. Each parameter must be 
  167. followed  by  RETURN and will be processed  immediately.  An 
  168. empty  command (just RETURN) will cause the program to  exit 
  169. back  to  CP/M.  Try it - it will help you  understand  what 
  170. follows.
  171.  
  172. Now lets get into directed i/o, which will be new to most of 
  173. you,  but will save you so much work you will wonder how you 
  174. ever got along without it.
  175.  
  176. Perhaps you frequently squeeze or unsqueeze the same list of 
  177. files  and you would like to type the list once and be  done 
  178. with it. Use an editor (or FLS, described below) to create a 
  179. file  with  one  parameter per line.  For  example  call  it 
  180. commands.lst.
  181.  
  182. Then,
  183. A>sq <commands.lst
  184. will  cause the command list file to be read as if you  were 
  185. typing it!
  186.  
  187. That was redirected console input.  Now assume that you have 
  188. a very long list of files to squeeze or unsqueeze and  while 
  189. you  are  taking a nap the progress comments and maybe  some 
  190. error  comments  scroll  off  the  screen.  Redirecting  the 
  191. console   output   will  let  you  capture   the   progress 
  192. information  in a file so you can check it later.  The error 
  193. comments will have the screen to themselves.
  194.  
  195. For example,
  196. A>sq <commands.lst >out
  197. will send the progress comments to the file "out", which you 
  198. can TYPE later.  The routine display of the program name and 
  199. version, etc., will still go to the console.
  200.  
  201. A more practical example is to send that information to  the 
  202. console and to the file.
  203. A>sq <commands.lst +out
  204. will do that.
  205.  
  206. Redirected  input  and output are independent - you  can  do 
  207. either, both or neither.
  208.  
  209. There is one more form of redirection called a "pipe". It is 
  210. by far the most important to you.  Recall that I promised to 
  211. tell  you how to use ambiguous file names such as *.asm (all 
  212. files  of  type asm on the current default drive)  or  *.?q? 
  213. (all files having a "q" as the second letter of their type). 
  214. That last example just happens to mean "all squeezed files", 
  215. assuming  you don't have any other files with such  a  silly 
  216. name (I hope).
  217.  
  218. I  have  provided  a program called FLS  which  is  intended 
  219. primarily for use in pipes. Here is an example:
  220. A>fls c: x.asm y*.asm >temp.$$$
  221. will  simply  pass the first two parameters through  to  the 
  222. console output,  which is being redirected to a file  called 
  223. temp.$$$.  But  the third parameter will be replaced by  all 
  224. the  files  on the current drive which are of type  asm  and 
  225. have names beginning with y.
  226.  
  227. FLS  is  smart  enough to know that a letter followed  by  a 
  228. colon and nothing else is a destination drive name  intended 
  229. for  SQ or USQ.  It will also treat any parameter  beginning 
  230. with  a  - (minus sign) as an option to be  passed  through. 
  231. Anything  else  is considered a file name or pattern and  is 
  232. checked against the directory of the appropriate drive.
  233.  
  234. Therefore you could use:
  235. A>fls b: c:*.aqm *.aqm -10 stuff.dqc >temp.$$$
  236. A>usq <temp.$$$
  237. A>era temp.$$$
  238. to unsqueeze all files of type aqm on drives C and A and put 
  239. the unsqueezed files on drive B,  and then preview the first 
  240. 10 lines of file stuff.dqc.
  241.  
  242. Here  is where the pipe comes in.  The above three  commands 
  243. can be abbreviated as:
  244. A>fls b: c:*.aqm *.aqm -10 stuff.dqc |usq
  245.  
  246. That  little  "|" is the pipe option and it causes  the  FLS 
  247. output to be redirected to a temporary file and when that is 
  248. done  it  actually  runs USQ for you with the  proper  input 
  249. redirection and then erases the temporary file.
  250.  
  251. If  that  isn't  enough,  you  can still  use  the  +  or  > 
  252. redirection  option  at the end of that line to capture  the 
  253. console output from USQ.
  254. A>fls b: c:*.aqm *.aqm -10 stuff.dqc |usq >out
  255.  
  256. If you plan your comments carefully you can produce a single 
  257. file containing an abstract of an entire library of squeezed 
  258. files in one step!
  259. A>fls -25 *.?q? |usq >abstract
  260.  
  261. One  final point.  Anywhere you specify a file name you  can 
  262. specify a drive in front of it.  That applies to redirection 
  263. and well as files to be squeezed and unsqueezed.  If a  name 
  264. begins  with a - (minus sign) it will look like an option to 
  265. FLS unless you put a drive name in front of it (b:-sq.077).
  266.  
  267. USAGE SUMMARY:
  268. The previous section gradually presented the various options 
  269. by example. This section gives a condensed and more abstract 
  270. description  and is intended for reference.  If you couldn't 
  271. see  the forest for the trees,  maybe this will give  you  a 
  272. better view.
  273.  
  274. The parameter handling of these programs is straightforward. 
  275. Parameters  fall into two classes:  directed i/o options and 
  276. operational parameters . Note that parameters read from files 
  277. or  from the console are not forced to upper case,  but  the 
  278. internal  file  handling routines all treat  lower  case  as 
  279. upper case.
  280.  
  281. When  a  file to be written already exists,  it  is  quietly 
  282. overwritten.
  283.  
  284.  
  285.  
  286. Directed I/O parameters:
  287. The  first  action  taken by these programs  is  to  process 
  288. directed  i/o parameters from the CP/M command  line.  These 
  289. parameters are optional and take the forms:
  290.  
  291.      <file     read console input from file
  292.      >file     send most console output to file
  293.      +file     send most console output to file and console
  294.      |pgm ...  send most console output to a temporary file
  295.                then run PGM.COM and take console input
  296.                from the temporary file. "..." represent the
  297.                parameters for PGM. This is called "piping".
  298.  
  299. Only  one input and one output redirection can apply to each 
  300. program. After the program has arranged for any directed i/o 
  301. parameters to be obeyed they are deleted from the  parameter 
  302. list seen by the rest of the program.
  303.  
  304. Operational parameters:
  305. The   program  then  checks  if  there  are  any   remaining 
  306. parameters from the CP/M command line.  If there  are,  they 
  307. are obeyed. If and only if there are no remaining parameters 
  308. on  the  command line,  the program prompts for them at  the 
  309. console.  If  console input has been directed to a file  one 
  310. parameter  is  read and obeyed from each line of  the  file. 
  311. Otherwise,  the  user  follows each typed parameter  with  a 
  312. RETURN and an empty command exits the program.
  313.  
  314. Each  operational parameter is obeyed without looking  ahead 
  315. to  other  parameters,  so options should precede  the  file 
  316. names to which they apply.
  317.  
  318. SQ operational parameters are a list of the following types:
  319.      drive:         set the current destination drive
  320.      filename       file to be squeezed
  321.      drive:filename  "   "    "    "
  322.      -            Toggle debug mode (dumps tables)
  323.  
  324. SQ does not change the files being squeezed. New, squeezed 
  325. files are created on the destination drive (defaults to  the 
  326. current drive) with names derived from the original name but 
  327. with  the second letter of the file type (extention) changed 
  328. to Q.  When there is no type, QQQ is used. The original name 
  329. is saved in the squeezed file.
  330.  
  331. USQ  operational  parameters  are a list  of  the  following 
  332. types:
  333.      drive:         set the current destination drive
  334.      filename       file to be squeezed
  335.      drive:filename  "   "    "    "
  336.      -count         Preview (display on the console) the first
  337.                     "count"  lines  of  each   file,   where 
  338.                     "count" is a number from 1 to 65535.
  339.  
  340. If  the  -count  option IS NOT in effect  then  USQ  creates 
  341. unsqueezed  versions of the listed files on the  destination 
  342. drive,  which  defaults to the current  logged  drive.  Each 
  343. unsqueezed  file is CRC checked against the CRC value of the 
  344. original file, which is part of the squeezed file.
  345.  
  346. The  -count  option is for  previewing  squeezed  files.  It 
  347. allows  you  to  skim  through a group  of  squeezed  files, 
  348. peeking  at  the first "count" lines in each.  The  >  or  + 
  349. output  redirection  option could be used  to  capture  this 
  350. information  in a file,  along with the corresponding  file 
  351. names, thus forming an abstract of the files on a disk.
  352.  
  353. When  the  -count option is used the CRC check is  cancelled 
  354. and  the  output is forced into printable form by  stripping 
  355. the  parity bit and changing most unprintable characters  to 
  356. periods.  The exceptions are CR,  LF, TAB and FF. The output 
  357. from  each file is terminated by an FF.  PIP can be used  to 
  358. strip FFs and provide formatted printing if desired. "Count" 
  359. defaults to the maximum value,  65,535,  in case you want to 
  360. look at a whole file.
  361.  
  362. FLS operational parameters:  FLS is a "filter",  which means 
  363. it  accepts input from the console input or command line and 
  364. transforms the input according to a set of rules to  produce 
  365. console  output.  That's fine for getting familiar with FLS, 
  366. but to make it useful you "pipe" its output to the input  of 
  367. SQ or USQ.
  368.  
  369. Any FLS parameter which is of the form:
  370.      drive:
  371. or   -anything
  372. is  copied  to console output unchanged.
  373.  
  374. Any  other  FLS operational parameter is treated as  a  file 
  375. name and is checked against the directory of the appropriate 
  376. drive. If it contains * or ? it is replaced by a list of all 
  377. the files which fit the pattern.  If nothing is found in the 
  378. directory  an error comment is sent to the console,  even if 
  379. normal console output has been redirected to a file.
  380.  
  381. IMPORTANT:  when  using  a pipe from FLS or any other  input 
  382. redirection to get the file list,  etc.,  on which USQ or SQ 
  383. are  to operate you must NOT put any parameters  other  than 
  384. redirection  following  the program  name.  The  operational 
  385. parameters must be all together in the input parameter list. 
  386. Example:
  387.  
  388. A>fls -10  b:*.cq |usq +saveout
  389. is  the  proper way to preview the top (first 10  lines)  of 
  390. each  squeezed  .C file on the B drive.  The -10  is  passed 
  391. through  FLS  to USQ.  The results will be displayed on  the 
  392. console  and  saved in file "saveout" on the  A  drive.  The 
  393. saveout  file lets you confirm the list of  processed  files 
  394. even  if  the display scrolls off the screen  while  running 
  395. unattended.
  396.  
  397. In summary, i/o redirection parameters (those prefixed by +, 
  398. <,  >,  or |) always follow the command to which they apply, 
  399. but  operational parameters  (destination  drive,  -options) 
  400. must be with the file name list.
  401.  
  402. EXAMPLES:
  403. 1. Unsqueeze all squeezed files on the current drive and put 
  404. the resulting unsqueezed files on the same drive.
  405.      A>fls *.?q? |usq
  406.  
  407. 2.  Look  at  the first 10 lines of every squeezed  file  on 
  408. drive B.
  409.     A>fls -10 b:*.?Q? |usq
  410. note  that since the file names for USQ came from  FLS,  the 
  411. count option had to come from there too.
  412.  
  413. 4.  Squeeze all .ASM files on the B and C drives and put the 
  414. squeezed files on the D drive.
  415.      A>fls d: b:*.asm c:*.asm |sq
  416. Note that if d:  had not been first the squeezed files would 
  417. have gone to the A drive.
  418.  
  419. 5.  Squeeze file xyz.c on the A drive and put the results on 
  420. the A drive.
  421.      A>sq xyz.c
  422.  
  423. 6.  Build  a  parameter list of all ASM files on drive C  in 
  424. file XX.PAR and view it on the console.
  425.      A>fls c:*.asm +xx.par
  426.  
  427. 7. Use the above list to squeeze the files to the A drive.
  428.      A>sq <xx.par
  429.  
  430. 8. As above, but results to the B drive.
  431.      A>b:
  432.      B>a:sq <a:xx.par
  433.  
  434. 9.  Squeeze  all ASM and C files on the A drive and put  the 
  435. results on the B drive. Capture the progress comments in the 
  436. file "out" without displaying them.
  437.      A>fls b: *.asm *.c |sq >out
  438.  
  439. 10.  Preview  the first 24 lines of each squeezed  ASM  file 
  440. THEN unsqueeze them (unless stopped via cntl-C).
  441.      A>fls -24 *.aqm a: *.aqm |usq
  442. Note  that  specification  of a  destination  drive  cancels 
  443. previewing.
  444.  
  445. RECOMPILATION:
  446. These programs are written in C and the instructions are for 
  447. the BDS C compiler. The libraries must have been adapted for 
  448. directed i/o as described in DIO2.C.
  449.  
  450. The  procedures below indicate the various C language source 
  451. files  (file  type .C) required to  recompile.  Those  files 
  452. contain  #include statements which cause header files  (file 
  453. type  .H) to be read and compiled.  The BDSCIO.H header file 
  454. contains information about your system,  including how  much 
  455. space  to reserve for file buffers.  You should use your own 
  456. version of this file.
  457.  
  458. The source files DIO2.C, SQDIO.C and USQDIO.C are identical! 
  459. If you only get one,  just use PIP to create the rest.  They 
  460. are separate only to provide separate CRL files,  which  are 
  461. needed  because of the different external variable  options. 
  462. Note  that  they  do  not  include  all  the  header  files, 
  463. therefore  the  other  source  files must  include  the  dio 
  464. related headers first.
  465.  
  466. DIO.C is supplied with BDS C.  The above three files  differ 
  467. from  the official version only by a change to the  dioflush 
  468. function to ensure TEMPIN.$$$ is deleted before another file 
  469. is renamed to that name.  (CP/M is stupid enough to make two 
  470. files of the same name!).
  471.  
  472. The  procedure for building the SQ.COM,  USQ.COM and FLS.COM 
  473. files  from  their source files follows.  Note that  I  have 
  474. renamed  the  first phase of the BDS C compiler  to  CC.COM. 
  475. Also  I will assume the BDS C package is on drive D and  the 
  476. SQ  and USQ related files are on B along with  BDSCIO.H  and 
  477. DIO.H.
  478.  
  479. Each  CC command produces a CRL file with specific addresses 
  480. for  external variables.  If you recompile a file  with  the 
  481. same  value in the -e option you don't have to recompile the 
  482. other  files,  just  do the desired CC and then  repeat  the 
  483. entire CLINK.
  484.  
  485. CLINK's -s option prints statistics. Top of memory means the 
  486. current TPA. Stack space is what's left over. These programs 
  487. require  stack  space for local  variables,  including  some 
  488. healthy i/o buffers.  Also some functions are recursive.  If 
  489. SQ doesn't have several K of stack space it will probably go 
  490. crazy and do almost anything.
  491.  
  492. If you have .CQ and .HQ files instead of .C and .H files you
  493. must use USQ, probably with FLS, as described above to make
  494. the .C and .H files.
  495.  
  496. For SQ (note not all use -o):
  497. D>cc b:sq.c -o -e3600
  498. D>a:pip b:sqdio.c=b:dio2.c
  499. D>cc b:sqdio.c -e3600
  500. D>cc b:tr1.c -o -e3600
  501. D>cc b:tr2.c -o -e3600
  502. D>cc b:io.c -o -e3600
  503. D>cc b:sqdebug.c -e3600
  504. D>clink b:sq sqdio tr2 tr1 io sqdebug -s
  505.  
  506. The linker will display some statistics. Check that the last 
  507. code  address is less than the start address of the external 
  508. variables (3600 in this example).  If not,  repeat the above 
  509. with a higher address in the -e options.
  510.  
  511. For USQ (note not all use -o):
  512. D>cc b:usq.c -o -e2900
  513. D>a:pip b:usqdio.c=b:dio2.c
  514. D>cc b:usqdio.c -e2900
  515. D>cc b:utr.c -o -e2900
  516. D>clink b:usq usqdio utr -s
  517.  
  518. Check the addresses as described above.
  519.  
  520. For FLS:
  521. D>cc b:fls.c
  522. D>cc b:dio2.c
  523. D>clink b:fls dio2
  524.  
  525. IN CASE OF TROUBLE:
  526. I  welcome  suggestions  and  bug  reports,   but  you  must 
  527. understand that some of the ideas I get would involve almost 
  528. as much program development as the original package.  I have 
  529. what I want and (I hope) what most users want,  so I am  not 
  530. motivated  to  spend  many more  months  creating  something 
  531. entirely  different  which  just  happens  to  involve  data 
  532. compression. The data compression routines are probably less 
  533. than  half of this package,  and are designed to operate  on 
  534. large blocks of data, such as files.
  535.  
  536. The - option recently added to SQ can be used to dump critical
  537. tables if you are having trouble and need to ask for help. Just
  538. run the program with control-P on the command line to get hard
  539. copy. The last table gives the lengths of the bit codes used.
  540.  
  541.         Dick Greenlaw
  542.                 251 Colony Ct.
  543.                 Gahanna, Ohio 43230
  544.                 614-475-0172 weekends and evenings
  545.