UNC v2.1 UNC.REL is an adaptation of Steve Greenbergs UNCREL module to: a: Execute on 8080/8085/V20 processors. b: Modify error returns. Returned values are: 0 (no carry) No error, as UNCREL 1 (carry) Later version needed. 2 (carry) File/module is not crunched 3 (carry) File is corrupt. Possibly not crunched. 4 (carry) Insufficient memory or stack overflow. c: Added entry point UNC, is used just as UNCREL (described below), except that the input file/module has already been processed up to and including the initial 0 byte. This avoids the necessity of rewinding the file, BUT an uncrunched file (no initial id stamp) can cause unknown results. CAUTION. d: Added (data relative) entry points CODES and TROOM may be monitored (but not modified) by the application to detect "codes assigned" and "codes re-assigned" respect- ively (version 20 crunch format). TROOM monitors codes still unassigned for version 10 format. e: A single byte at UNCREL-1 contains the revision number. The remainder of this file is Mr. Greenbergs original document. C. B. Falconer (86/11/24) ------------- UNCREL.REL is a Microsoft / DRI compatible .REL file which makes it extremely easy for an application program to "uncrunch" files. All the programmer need supply is two routines- one which is capable of supplying one character at a time in the "A" register and one which will accept one character at a time. A single call to external entrypoint "UNCREL" will do the rest. This organization was chosen (ie UNCREL stays "in control", and calls the programmer's input and output routines, rather than vice-versa) because it is more consistent with the nature of the LZW algorithm. The algorithm may make 1, 2 or 3 consecutive calls for input without outputting anything, & then may output any number of characters before needing more input. Since an individual call is made for each byte needed or sup- plied, the user's routines can refill (or dump out) any input or output buffers at any appropriate time. If the programmer de- cides to terminate the uncrunch operation before its natural completion, it is simply necessary to reset the stack pointer and continue rather than RETurning to UNCREL. More detailed descrip- tion of operation follows: Programmer Supplied Routines, declared "PUBLIC". 1. One must be named "GETBYT". Each time this routine gets called by UNCREL, it should supply the next sequential byte in "A". The routine may make full use of all registers, but should not assume that they will be in any particular state the next time the routine is called. Basically, any pointers, etc., should be memory based. Note, however, that all usage of the alternate Z-80 registers has been eliminated from UNCREL. Thus an "alter- nate" scheme is to execute an EXX instruction at the beg and end of "GETBYT", in which case the registers will remain intact. 2. Another routine must be named "OUT". UNCREL calls this rou- tine each time it has a new character available for output. The character will be in register "A". All other conditions are as described above. What you (the programmer) must do: Simply make a single call to "UNCREL", which should be declared "EXTRN". This will initialize all tables, and then all activity will proceed until the file is completely uncrunched or an error is encountered. At that point, UNCREL will return to your pro- gram. If the carry flag is set, this was an error return. In this case reg "A" will contain a [non-zero] code identifying the type of error, if you are interested. If carry is clear, A will be zero, and this indicates that the entire operation has term- inated normally. What else you must do: BEFORE you make the call to UNCREL mentioned above, you should load "HL" with a pointer to a large block of memory (24k). The rest of the work is taken care of - UNCREL will figure the next page boundary and allocate various pointer for various tables it will build itself. It will also allocate a large stack area for itself within this block, and will initialize all any ram locs it needs. All of this is done at "run time". UNCREL can be reexec- uted multiple times if desired. Your stack will be returned to its previous value if UNCREL returns (either due to completion or error). If you decide to interrupt operation by not returning from one of its "GETBYT" or "OUT" calls, however, don't forget to reset the stack to your own value. Another EXTRN value named "ENDU" is made available for possible use. It is the end of the data area (DSEG) used by UNCREL. If you link in such a way that UNCREL is "on top", then this can be used as a reference for the beg of available memory after the program. More notes: Every byte of a crunched file, starting with the 76H and 0FEH header bytes, must be supplied in order. The header information is checked for some validity, although the file name is ignored. UNCREL will determine the version# when it gets to it and un- crunch accordingly, you needn't worry about this. If you need the filename, you must extract it yourself. The exact format of a crunched file is defined as a separate document LZDEF20.DOC. UNCREL does NOT read or compute the checksum, if that interests you you can do that yourself too. (Note: CRUNCH.COM & UNCR.COM v2.0 are not directly based on UNCREL. They always create and check the checksum respectively, of course). More notes: The LZW process is a continuously progressing forward process. You cannot go back. If you leave out just one byte, you will get results which become stranger and stranger, eventually becoming complete gibberish. (This is actually pretty interesting to watch, albeit frustrating if its not what you want).