home *** CD-ROM | disk | FTP | other *** search
/ ftp.barnyard.co.uk / 2015.02.ftp.barnyard.co.uk.tar / ftp.barnyard.co.uk / robot-pd / 22300.ZIP / 22300B.DSK / lzhrel.doc < prev    next >
Text File  |  1998-05-08  |  16KB  |  300 lines

  1.                       UNLZH.REL and CRLZH.REL Documentation
  2.                for Version 2.0 (with RUNTIME buffer allocation)
  3.                                    July  1991
  4.  
  5.                                     Abstract
  6.                                    ----------
  7.  
  8.    UNLZH.REL and CRLZH.REL contain assembly language routines for the decoding 
  9.    and generation of LZH-encoded files, respectively.  The routines need only 
  10.    be supplied with a pointer to a large scracth area and linkages to character 
  11.    input and character output routines to be used.  There are a few easily met 
  12.    functional requirements for the calling routine and I/O routine.
  13.  
  14.    No Z80 opcodes are used, so these routines may be used on 8080/8085/V20/Z80 
  15.    based machines.
  16.  
  17.    The coding contained within UNLZH.REL and CRLZH.REL are Copyright (c) 1989, 
  18.    1991 by Roger Warren and may not be used or reproduced on a for-profit 
  19.    basis.  Non-profit use is freely permitted.  The author will not be 
  20.    responsible for any damage, loss, etc.  caused by the use of these programs.
  21.  
  22.                         Version History and Compatibility
  23.                         ---------------------------------
  24.  
  25.    Version 1.1 was released in Sept. '89 and was the first public offering of 
  26.    LZH encoding for CP/M.
  27.  
  28.    Version 2.0 (July '91) introduces several improvements/changes:
  29.        More efficient encoding
  30.        Greater speed
  31.        More compact object code
  32.  
  33.    There are NO interface changes from the 1.x version.
  34.  
  35.    Of greatest importance is the encoding improvement.  This change, while 
  36.    generating even smaller output files, means that files compressed with 
  37.    version 2.x programs cannot be decoded by old 1.x programs.
  38.  
  39.    However, the version 2.x UNLZH module DYNAMICALLY ADJUSTS for 1.x encoded 
  40.    input files.  Thus, version 2.x of UNLZH can be used on all LZH-encoded 
  41.    files regardless of which algorithm version was used to encode the files.
  42.  
  43.    By extensive rewriting for size and speed, a 20% improvement in performance 
  44.    was achieved.  Since the LZH algorithm is intrinsically slow, this will be 
  45.    of great interest to many.  The recoding project allowed the incorporation 
  46.    of version 2.x extensions to the original algorithm while not appreciably 
  47.    affecting the code module size.
  48.  
  49.                                 Care and Feeding
  50.                                ------------------
  51.  
  52.    The infomation that follows documents both CRLZH.REL and UNLZH.REL.  One or 
  53.    both may be in the library this file is in, depending upon the nature of 
  54.    the program(s) it's bundled with...so ignore the superfluous information 
  55.    (if any).
  56.  
  57.    UNLZH.REL performs LZH decoding.  It's progamming interface is similar to 
  58.    the UNCR.REL it was made to mimic.  The programmer must provide the program 
  59.    with 8k of buffer space.  If RUNTIME buffer allocation is selected (it IS 
  60.    selected in the version supplied with LT, FCRLZH, CRLZH, and UCRLZH), a 
  61.    pointer to the buffer must be supplied in the H/L register pair when the 
  62.    routine is invoked.  If RUNTIME buffer allocation is not selected, the user 
  63.    must supply a PUBLIC symbol, UTABLE, which is the base of the provided 
  64.    buffer area.
  65.  
  66.    Once invoked, the routine allocates its own stack and 'stays in control' 
  67.    until the de-compression is completed (or an error is encountered).  The 
  68.    programmer must supply two routines GLZHUN and PLZHUN, via which UNLZH 
  69.    'GETS' bytes from the input stream and 'PUTS' bytes to the output stream, 
  70.    respectively.
  71.  
  72.  
  73.    UNLZH *DOES NOT* compute/process checksums, etc. on the  input file.  Any 
  74.    support of such features must be handled externally.
  75.  
  76.    GLZHUN and PLZHUN should save all registers except the A register and 
  77.    flags. GLZHUN must return the next character from the input stream in the A 
  78.    register.  GLZHUN should return with the CARRY flag RESET for a valid 
  79.    character, or with the CARRY flag SET when the end of the input stream is 
  80.    encountered (the content of the A reg should be zero in that case).
  81.  
  82.    Upon exit (return to the caller), UNLZH returns the following information:
  83.  
  84.               Carry reset (or A reg = 0) - Success
  85.               Carry set,  A reg = 1      - Newer version required
  86.               Carry set,  A reg = 2      - File not LZH endocoded
  87.               Carry set,  A reg = 3      - Bad or corrupt file
  88.               Carry set,  A reg = 4      - Insufficient memory
  89.  
  90.    UNLZH has 2 entry points, to be used as the programmer needs:
  91.  
  92.      UNLZH is the 'normal' entry point which expects the file to be completely 
  93.      REWOUND.  At this entry point, the entire file is processed - the 
  94.      standard header is examined, but not reported or acted upon.  By 
  95.      examining the return code, the programmer can discern if the file was, 
  96.      indeed, an LZH-encoded file and act accordingly.
  97.  
  98.      UNL is a secondary entry point which can be used when the programmer 
  99.      needs to process the standard header information (file name and stamp) 
  100.      and cannot (or doesn't want to) rewind the file.  When this entry point 
  101.      is invoked, the header (down to and including the stamps/comment 
  102.      terminating zero) must have been processed (so the next byte in the input 
  103.      stream will be the revision level).
  104.       
  105.    The revision level of UNLZH.REL performs is at the byte at UNLZH-1.  A hex 
  106.    value of 11 indicates version 1.1, etc.
  107.  
  108.    CRLZH.REL performs LZH encoding.  It's progamming interface is similar to 
  109.    the CRUNCH.REL it was made to mimic.    The programmer must provide the 
  110.    program with 20k of buffer space.  If RUNTIME buffer allocation is selected 
  111.    (it IS selected in the version supplied with LT, FCRLZH, CRLZH, and 
  112.    UCRLZH),a pointer to the buffer must be supplied in the H/L register pair 
  113.    when the routine is invoked.  If RUNTIME buffer allocation is not selected, 
  114.    the user must supply a PUBLIC symbol, CTABLE, which is the base of the 
  115.    provided buffer area.
  116.  
  117.    In addition, at invocation time the A register must contain a value for 
  118.    CRLZH to install in the 'CHECKSUM FLAG' portion of the file header (see 
  119.    below).  This byte, to be semi-compatible with C.B. Falconer's version of 
  120.    CRN for the 8080, is a subset of CRN's strategy byte:
  121.  
  122.                       value (hex)   meaning
  123.                       ----------------------------------------------------
  124.                            00       Standard modulo 65536 checksum is used
  125.                            10       CRC16 is used
  126.                            20,30    Unassigned
  127.  
  128.    SUPPORT FOR CHECK INFORMATION MUST BE EXTERNALLY PROVIDED IN THE 
  129.    USER-SUPPLIED I/O ROUTINES (see below).  THIS IS ALSO TRUE OF CRN...BUT WAS 
  130.    NOT EMPHASIZED!  CRLZH merely provides the support for posting the value in 
  131.    the output stream since it happens to 'follow' some of the information 
  132.    posted by CRLZH (see the header description, below).
  133.  
  134.    CRLZH supports no other features of the CRN's strategy byte, all other bits 
  135.    are ignored.
  136.  
  137.    Once invoked, the routine allocates its own stack and 'stays in control' 
  138.    until the de-compression is completed (or an error is encountered).  The 
  139.    programmer must supply two routines GLZHEN and PLZHEN, via which CRLZH 
  140.    'GETS' bytes from the input stream and 'PUTS' bytes to the output stream, 
  141.    respectively.
  142.  
  143.    CRLZH *DOES NOT* compute/process checksums, etc. on the  input file.  Any 
  144.    support of such features must be handled externally.  Specifically, the 
  145.    GLZHEN routine must provide for the accumulation of check information and 
  146.    the caller must write that check information to the output stream when 
  147.    CRLZH returns to the caller.
  148.  
  149.    GLZHEN and PLZHEN should save all registers except the A register and 
  150.    flags. GLZHEN must return the next character from the input stream in the A 
  151.    register.  GLZHEN should return with the CARRY flag RESET for a valid 
  152.    character, or with the CARRY flag SET when the end of the input stream is 
  153.    encountered (the content of the A reg should be zero in that case).  As a 
  154.    service to the user's output processor, every 256th call to PLZHEN is made 
  155.    with the Z flag set (for monitoring).  All other times the Z flag is reset.
  156.  
  157.    Upon exit (return to the caller), CRLZH returns the following information:
  158.  
  159.               Carry reset (or A reg = 0) - Success
  160.               Carry set,  A reg = 1      - File already LZH-Encoded,CRUNCHed or
  161.                                            SQueezed
  162.               Carry set,  A reg = 2      - File empty
  163.               Carry set,  A reg = 3      - Insufficient memory
  164.  
  165.    CRLZH has a single entry point at the label CRLZH.  The user must have 
  166.    placed the standard header information in the output stream and must have 
  167.    the input stream REWOUND prior to invoking CRLZH.
  168.  
  169.    The revision level of CRLZH.REL performs is at the byte at CRLZH-1.  A hex 
  170.    value of 11 indicates version 1.1, etc.
  171.  
  172.    Since CRLZH and UNLZH allocate their own stacks, the user is reminded not 
  173.    to make too large a use of that stack in the user-supplied I/O routines.  
  174.    In addition, if the user-supplied I/O routines decide to abort the CRLZH or 
  175.    UNLZH operation (due to operator keystrokes, for example), the user must 
  176.    take steps to restore his own stack.  Upon a normal (or error) return from 
  177.    CRLZH or UNLZH the user's stack is properly restored.
  178.  
  179.                            STANDARD HEADER information
  180.                           -----------------------------
  181.  
  182.    LZH encoding follows Steve Greenberg's CRUNCH file format.  The header 
  183.    contains information identifying compression format, original file name, 
  184.    etc:
  185.      field  size     value    Purpose
  186.    -----------------------------------------------------------------------  
  187.        1   1 byte    076h     Signifies compressed form
  188.        2   1 byte    0FDh     Signifies LZH encoding (0ff is for squeezed and
  189.                               0feh is for CRUNCHED)
  190.        3   variable  User     Original file name in the form name.ext Trailing
  191.                    supplied   blanks on the name portion should be suppressed,
  192.                               but a full 3 characters following the '.' should
  193.                               be used for the extension (i.e. no blank
  194.                               suppression).
  195.        4   variable  User     OPTIONAL.  Used for file comment/stamp.  If used
  196.                               the convention is that the comment is placed in
  197.                               square brackets [Like this].  Other information
  198.                               may be placed here (e.g., date stamp).  The
  199.                               logical restriction is that a binary zero must
  200.                               not be part of the comment and/or other informa-
  201.                               tion.
  202.        5   1 byte     00h     Signifies end of STANDARD HEADER
  203.    
  204.    For use of CRLZH, the user must supply all of the information above.
  205.  
  206.    For UNLZH, use of the UNLZH entry point causes UNLZH to expect to process 
  207.    the above information.  It will discard the file name and optional 
  208.    comment/stamp, but will examine the general form (first 2 fields for a 
  209.    match and general form of the rest of the header).  If the user chooses to 
  210.    use the UNL entry point, UNL will expect to process the first byte 
  211.    following the end of the standard header.
  212.  
  213.    What follows is the following:
  214.  
  215.      field  size     value    Purpose
  216.    -----------------------------------------------------------------------  
  217.        6   1 byte  variable   Identifies generating program revision level.
  218.                               (11H signifies program generated by version 1.1
  219.        7   1 byte  variable   Significant revision level.  Indicates major
  220.                               revision level of algorithm for decoding program
  221.                               compatability. (10h indicates significant
  222.                               revision 1.0)
  223.        8   1 byte  variable   Check type.  0=checksum, 1=CRC16, others
  224.                               currently undefined.
  225.        9   1 byte     05h     Currently a SPARE, set to 05H by convention.
  226.  
  227.    Following this is the compressed file, itself.
  228.  
  229.                  What LZH compression does and how it compares
  230.                 -----------------------------------------------
  231.  
  232.    FIRST - It's SLOW.  Much slower than CRUNCH.  About even with the old 
  233.    SQueeze.  It's the nature of the algorithm, but the current implementation 
  234.    contributes somewhat (more on that later).
  235.  
  236.    The most impressive aspect of the algorithm is that it compresses further 
  237.    than CRUNCH.  The nature of material being compressed is important - prose 
  238.    and high level language code will compress further.  Since the algorithm 
  239.    depends, in part, on patterns within the file being compressed, I was 
  240.    somewhat surprised to discover that it does a better job (in general) on 
  241.    .COM files than CRUNCH.  Personally, I was surprised to discover that LZH 
  242.    compression of CRUNCHed files is possible (but I've disabled that ability 
  243.    in this release)!
  244.  
  245.    Examples:
  246.     CRUNCH of SLR180.COM   106% ratio   (actually made a larger file)
  247.     CRLZH  of SLR180.COM    84% ratio
  248.     CRUNCH of TYPELZ22.Z80  45% ratio
  249.     CRLZH  of TYPELZ22.Z80  40% ratio
  250.     CRUNCH of 'C' source    45% ratio   (typical 'C' src selected at random)
  251.     CRLZH  of 'C' source    33% ratio   (same file as above)
  252.  
  253.                                 A small history
  254.                                -----------------
  255.  
  256.    I am NOT the originator of the LZH encoding.  The program that started my 
  257.    whole involvement in the introduction of this method of compression to the 
  258.    8-bit world bears the following opening comments:
  259.       /*
  260.       * LZHUF.C English version 1.0
  261.       * Based on Japanese version 29-NOV-1988
  262.       * LZSS coded by Haruhiko OKUMURA
  263.       * Adaptive Huffman Coding coded by Haruyasu YOSHIZAKI
  264.       * Edited and translated to English by Kenji RIKITAKE
  265.       */
  266.  
  267.    This 'C' program implemented the compression algorithm of the LHARC program 
  268.    which arrived on the US scene in the spring of '89.
  269.  
  270.    Being of a curious nature, I figured I'd play with the algorithm just to 
  271.    understand it (the internal comments were, indeed, sparse - leaving MUCH to 
  272.    the reader's contemplation/reverse engineering) while 'better minds' than I 
  273.    tackled it in earnest.
  274.  
  275.    Months passed.  I found that I was 'mastering' the algorithm (read that as 
  276.    demonstrating to myself that I understood it) by converting it piece-wise 
  277.    to assembly language.  After a while, I was left with a 'C' language main 
  278.    program, run time library, and I/O with the business end of the compression 
  279.    and decompression implemented entirely in assembly language.  Since the 
  280.    expected event of one of the 'heavies' in the PD and/or compression world 
  281.    releasing a CP/M version of the compression algorithm hadn't come to pass, 
  282.    I set about making a version myself.
  283.  
  284.    The natural choice was to prepare an analog to the CRUNCH.REL and UNCR.REL 
  285.    of Mr. Steven Greenberg and Mr. C.B. Falconer and append to/substitute in 
  286.    the existing, widely known programs for handling SQueezed and/or CRUNCHed 
  287.    files.
  288.  
  289.    I saw no reason to tamper with the format CRUNCH uses on the output file.  
  290.    Therefore, with the exception of taking the 'next' file type in sequence 
  291.    (SQueezed files begin with a 76h,FFh sequence; Crunched files with 76h,FEh; 
  292.    so LZH encoded files begin with 076h,FDh) and setting the revision levels 
  293.    in the header to appropriate values , there's no difference in the output 
  294.    file format.  So, you can probably coax your time/date stamping into 
  295.    operating on LZH encoded files.
  296.  
  297. R. Warren
  298. Sysop, The Elephant's Graveyard (Z-Node#9)
  299. 619-270-3148 (PCP area CASDI)
  300.