Browse Source

Import ttpack and ttbin2oth - now LGPLed, thanks to Pasi Ojala, Thomas Nussbaumer and Lionel Debroux.

git-svn-id: file:///var/svn/tigccpp/trunk@578 9552661e-59e3-4036-b4f2-dbe53926924f
kevinkofler 18 years ago
parent
commit
dcb1a07417

+ 1 - 4
tigcc/setup/CreateSourceZip.bat

@@ -7,17 +7,14 @@ SET TTPACKSRCDIR=E:\TI-89\Compilers\tigcc\tt\src\pctools
 
 MD a68k
 COPY "%A68KSRCDIR%\*.*" a68k
-MD ttpack
-FOR %%i IN ("%TTPACKSRCDIR%\..\..\readme.txt" "%TTPACKSRCDIR%\packhead.h" "%TTPACKSRCDIR%\revtools.h" "%TTPACKSRCDIR%\tt.h" "%TTPACKSRCDIR%\ttpack.c" "%TTPACKSRCDIR%\ttversion.h") DO COPY "%%i" ttpack
 
 DEL "%ZIPDIR%\tigccsrc.zip"
 CD ..\doc
 "%INFOZIPDIR%\zip.exe" -9 -r "doc.zip" Programs System -x CVS
 CD ..\setup
-"%INFOZIPDIR%\zip.exe" -9 -r "%ZIPDIR%\tigccsrc.zip" ..\Readme.txt ..\License.txt a68k ..\archive ..\components ..\doc\doc.zip ..\gcc ..\general ..\hsf2rc ..\ide ..\ld-tigcc ..\pstarter ..\setup\*.nsi ..\setup\*.ini ..\setup\*.bat ..\setup\makeall.pif ..\tigcc ..\tprbuilder ttpack -x CVS
+"%INFOZIPDIR%\zip.exe" -9 -r "%ZIPDIR%\tigccsrc.zip" ..\Readme.txt ..\License.txt a68k ..\archive ..\components ..\doc\doc.zip ..\gcc ..\general ..\hsf2rc ..\ide ..\ld-tigcc ..\pstarter ..\setup\*.nsi ..\setup\*.ini ..\setup\*.bat ..\setup\makeall.pif ..\tigcc ..\tprbuilder ..\ttpack -x CVS
 DEL ..\doc\doc.zip
 
 DELTREE /Y a68k
-DELTREE /Y ttpack
 
 ECHO Finished.

+ 228 - 0
tigcc/ttpack/bin2oth.c

@@ -0,0 +1,228 @@
+/******************************************************************************
+*
+* project name:    TIGCC Tools Suite
+* file name:       bin2oth.c
+* initial date:    22/08/2000
+* author:          thomas.nussbaumer@gmx.net
+* description:     converts a data buffer into an oth buffer and checks
+*                  for maximal length, too
+*
+* NOTE:  this routine is used in many tools, therefore it is implemented in a
+*        separately C file and included in the tools
+*
+* NOTE2: !!!! THIS SOURCECODE DEPENDS ON MINIMUM 32BIT INTEGERS !!!!
+*
+******************************************************************************/
+
+/*
+  This file is part of ttbin2oth.
+
+  This file is free software; you can redistribute it and/or
+  modify it under the terms of the GNU Lesser General Public
+  License as published by the Free Software Foundation; either
+  version 2.1 of the License, or (at your option) any later version.
+
+  As a special exception, UNMODIFIED copies of ttbin2oth may also be
+  redistributed or sold without source code, for any purpose. (The Lesser
+  General Public License restrictions do apply in other respects; for example,
+  they cover modification of the launcher.) This exception notice must be
+  removed on modified copies of this file.
+
+  This program is distributed in the hope that it will be useful,
+  but WITHOUT ANY WARRANTY; without even the implied warranty of
+  MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
+  Lesser General Public License for more details.
+
+  You should have received a copy of the GNU Lesser General Public
+  License along with this library; if not, write to the Free Software
+  Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA  02110-1301  USA
+*/
+
+#ifndef __BIN2OTH__
+#define __BIN2OTH__
+
+#include <stdio.h>
+#include <string.h>
+#include <stdlib.h>
+
+#include "tt.h"
+#include "strhead.h"
+
+#define TT_MAX_MEMBLOCK 65520
+#define TT_MAX_OTHDATA  (TT_MAX_MEMBLOCK - 2 - 7)
+
+//=============================================================================
+// returns a pointer to a newly allocated memory block which holds the
+// OTH file contents ready to flush into a file
+//
+// the length of the newly allocated memory block will be stored in outlength
+//
+// NOTE: the length of the extension may vary between 1 and 4 characters
+//       (no checks are performed on the type of the character)
+//=============================================================================
+unsigned char* DataBuffer2OTHBuffer(int            calctype,
+                                    char*          folder,
+                                    char*          varname,
+                                    char*          extension,
+                                    unsigned int   inlength,
+                                    unsigned char* indata,
+                                    unsigned int*  outlength)
+{
+    StrHeader*     psh;
+    unsigned int   checksum;
+    unsigned char* ptr;
+    unsigned int   size;
+    unsigned char* output;
+    int            ext_len;
+
+    if (!extension) {
+        fprintf(stderr,"ERROR: no extension given\n");
+        return 0;
+    }
+
+    ext_len = strlen(extension);
+    if (ext_len < 1 || ext_len > 4) {
+        fprintf(stderr,"ERROR: invalid OTH extension [%s]\n",extension);
+        return 0;
+    }
+
+
+    if (inlength > TT_MAX_OTHDATA) {
+        fprintf(stderr,"ERROR: length (%u) exceeds max. user data size (%u)\n",inlength,TT_MAX_OTHDATA);
+        return 0;
+    }
+
+    size = sizeof(StrHeader)+inlength+2+3+ext_len; // 6 == OTH bytes , 2 == checksum
+
+    if (!(output = (unsigned char*)malloc(size))) {
+        fprintf(stderr,"ERROR: cannot allocate %u bytes of memory\n",size);
+        return 0;
+    }
+
+    *outlength = size;
+    psh = (StrHeader*)output;
+    memset(psh,0,sizeof(StrHeader));
+
+    //-------------------------------------------------------------------
+    // fill up all the static fields
+    //-------------------------------------------------------------------
+    psh->fill1[0]=1;psh->fill1[1]=0;
+    psh->fill2[0]=0x01;psh->fill2[1]=0x00;psh->fill2[2]=0x52;
+    psh->fill2[3]=0x00;psh->fill2[4]=0x00;psh->fill2[5]=0x00;
+    psh->fill3[0]=0xA5;psh->fill3[1]=0x5A;psh->fill3[2]=0x00;
+    psh->fill3[3]=0x00;psh->fill3[4]=0x00;psh->fill3[5]=0x00;
+    psh->type[0]=0x1c;psh->type[1]=0x00;psh->type[2]=0x00;psh->type[3]=0x00;
+
+    //-------------------------------------------------------------------
+    // fill in the magic marker string depending on given calc type
+    //-------------------------------------------------------------------
+    if (calctype == CALC_TI89) strncpy(psh->signature,SIGNATURE_TI89,8);
+    else                       strncpy(psh->signature,SIGNATURE_TI92P,8);
+
+    //-------------------------------------------------------------------
+    // fill in folder and variable name
+    // if folder name pointer is NULL, use DEFAULT_FOLDER ("main")
+    //-------------------------------------------------------------------
+    if (!folder) strncpy(psh->folder,DEFAULT_FOLDER,8);
+    else         strncpy(psh->folder,folder,8);
+
+    strncpy(psh->name,varname,8);
+
+    //-------------------------------------------------------------------
+    // size holds the complete output size == filelength including header
+    //-------------------------------------------------------------------
+    psh->size[0] = (unsigned char)(size & 0xff);
+    psh->size[1] = (unsigned char)((size >> 8)  & 0xff);
+    psh->size[2] = (unsigned char)((size >> 16) & 0xff);
+    psh->size[3] = (unsigned char)((size >> 24) & 0xff);
+
+    //-------------------------------------------------------------------
+    // data size will hold user data size + OTH tag related bytes
+    //-------------------------------------------------------------------
+    size -= sizeof(StrHeader);
+    size -= 2;
+    psh->datasize[0] = (unsigned char)((size >> 8) & 0xff);
+    psh->datasize[1] = (unsigned char)(size & 0xff);
+
+    //-------------------------------------------------------------------
+    // copy complete indata
+    //-------------------------------------------------------------------
+    memcpy(output + sizeof(StrHeader),indata,inlength);
+
+    //-------------------------------------------------------------------
+    // append OTH bytes
+    //-------------------------------------------------------------------
+    ptr    = output + sizeof(StrHeader) + inlength;
+    *ptr++ = 0;
+
+    switch (ext_len) {
+        case 1:
+            *ptr++ = *extension;
+            *ptr++ = 0;
+            break;
+        case 2:
+            *ptr++ = *extension++;
+            *ptr++ = *extension;
+            *ptr++ = 0;
+            break;
+        case 3:
+            *ptr++ = *extension++;
+            *ptr++ = *extension++;
+            *ptr++ = *extension;
+            *ptr++ = 0;
+            break;
+        case 4:
+            *ptr++ = *extension++;
+            *ptr++ = *extension++;
+            *ptr++ = *extension++;
+            *ptr++ = *extension;
+            *ptr++ = 0;
+            break;
+    }
+    *ptr++ = 0xF8;
+
+    size = *outlength - sizeof(StrHeader);
+    ptr  = psh->datasize;
+
+    checksum = 0;
+    while (size--) checksum += *ptr++;
+
+    output[*outlength-2] = (unsigned char)(checksum & 0xff);
+    output[*outlength-1] = (unsigned char)((checksum >> 8) & 0xff);
+
+    return output;
+}
+
+#endif
+
+//#############################################################################
+//###################### NO MORE FAKES BEYOND THIS LINE #######################
+//#############################################################################
+//
+//=============================================================================
+// Revision History
+//=============================================================================
+//
+// Revision 1.7  2002/05/13 15:17:43  tnussb
+// statically header information fixed (thanx to Sebastian again)
+//
+// Revision 1.6  2002/05/13 14:09:56  tnussb
+// TT_MAX_OTHDATA ... corrected (thanx to Sebastian Reichelt)
+//
+// Revision 1.5  2002/03/14 09:00:56  tnussb
+// checking for define __BIN2OTH__ added at begin of file
+//
+// Revision 1.4  2002/03/13 22:05:41  tnussb
+// handles now between 1 and 4 characters for the extension
+//
+// Revision 1.3  2002/02/07 09:49:36  tnussb
+// all local includes changed, because header files are now located in pctools folder
+//
+// Revision 1.2  2000/08/23 19:37:14  Thomas Nussbaumer
+// changes due to headerfile and define renaming
+//
+// Revision 1.1  2000/08/23 01:09:44  Thomas Nussbaumer
+// initial version (extracted and clearified from ttbin2oth.c)
+//
+//
+//

+ 504 - 0
tigcc/ttpack/lgpl.txt

@@ -0,0 +1,504 @@
+		  GNU LESSER GENERAL PUBLIC LICENSE
+		       Version 2.1, February 1999
+
+ Copyright (C) 1991, 1999 Free Software Foundation, Inc.
+ 51 Franklin Street, Fifth Floor, Boston, MA  02110-1301  USA
+ Everyone is permitted to copy and distribute verbatim copies
+ of this license document, but changing it is not allowed.
+
+[This is the first released version of the Lesser GPL.  It also counts
+ as the successor of the GNU Library Public License, version 2, hence
+ the version number 2.1.]
+
+			    Preamble
+
+  The licenses for most software are designed to take away your
+freedom to share and change it.  By contrast, the GNU General Public
+Licenses are intended to guarantee your freedom to share and change
+free software--to make sure the software is free for all its users.
+
+  This license, the Lesser General Public License, applies to some
+specially designated software packages--typically libraries--of the
+Free Software Foundation and other authors who decide to use it.  You
+can use it too, but we suggest you first think carefully about whether
+this license or the ordinary General Public License is the better
+strategy to use in any particular case, based on the explanations below.
+
+  When we speak of free software, we are referring to freedom of use,
+not price.  Our General Public Licenses are designed to make sure that
+you have the freedom to distribute copies of free software (and charge
+for this service if you wish); that you receive source code or can get
+it if you want it; that you can change the software and use pieces of
+it in new free programs; and that you are informed that you can do
+these things.
+
+  To protect your rights, we need to make restrictions that forbid
+distributors to deny you these rights or to ask you to surrender these
+rights.  These restrictions translate to certain responsibilities for
+you if you distribute copies of the library or if you modify it.
+
+  For example, if you distribute copies of the library, whether gratis
+or for a fee, you must give the recipients all the rights that we gave
+you.  You must make sure that they, too, receive or can get the source
+code.  If you link other code with the library, you must provide
+complete object files to the recipients, so that they can relink them
+with the library after making changes to the library and recompiling
+it.  And you must show them these terms so they know their rights.
+
+  We protect your rights with a two-step method: (1) we copyright the
+library, and (2) we offer you this license, which gives you legal
+permission to copy, distribute and/or modify the library.
+
+  To protect each distributor, we want to make it very clear that
+there is no warranty for the free library.  Also, if the library is
+modified by someone else and passed on, the recipients should know
+that what they have is not the original version, so that the original
+author's reputation will not be affected by problems that might be
+introduced by others.
+
+  Finally, software patents pose a constant threat to the existence of
+any free program.  We wish to make sure that a company cannot
+effectively restrict the users of a free program by obtaining a
+restrictive license from a patent holder.  Therefore, we insist that
+any patent license obtained for a version of the library must be
+consistent with the full freedom of use specified in this license.
+
+  Most GNU software, including some libraries, is covered by the
+ordinary GNU General Public License.  This license, the GNU Lesser
+General Public License, applies to certain designated libraries, and
+is quite different from the ordinary General Public License.  We use
+this license for certain libraries in order to permit linking those
+libraries into non-free programs.
+
+  When a program is linked with a library, whether statically or using
+a shared library, the combination of the two is legally speaking a
+combined work, a derivative of the original library.  The ordinary
+General Public License therefore permits such linking only if the
+entire combination fits its criteria of freedom.  The Lesser General
+Public License permits more lax criteria for linking other code with
+the library.
+
+  We call this license the "Lesser" General Public License because it
+does Less to protect the user's freedom than the ordinary General
+Public License.  It also provides other free software developers Less
+of an advantage over competing non-free programs.  These disadvantages
+are the reason we use the ordinary General Public License for many
+libraries.  However, the Lesser license provides advantages in certain
+special circumstances.
+
+  For example, on rare occasions, there may be a special need to
+encourage the widest possible use of a certain library, so that it becomes
+a de-facto standard.  To achieve this, non-free programs must be
+allowed to use the library.  A more frequent case is that a free
+library does the same job as widely used non-free libraries.  In this
+case, there is little to gain by limiting the free library to free
+software only, so we use the Lesser General Public License.
+
+  In other cases, permission to use a particular library in non-free
+programs enables a greater number of people to use a large body of
+free software.  For example, permission to use the GNU C Library in
+non-free programs enables many more people to use the whole GNU
+operating system, as well as its variant, the GNU/Linux operating
+system.
+
+  Although the Lesser General Public License is Less protective of the
+users' freedom, it does ensure that the user of a program that is
+linked with the Library has the freedom and the wherewithal to run
+that program using a modified version of the Library.
+
+  The precise terms and conditions for copying, distribution and
+modification follow.  Pay close attention to the difference between a
+"work based on the library" and a "work that uses the library".  The
+former contains code derived from the library, whereas the latter must
+be combined with the library in order to run.
+
+		  GNU LESSER GENERAL PUBLIC LICENSE
+   TERMS AND CONDITIONS FOR COPYING, DISTRIBUTION AND MODIFICATION
+
+  0. This License Agreement applies to any software library or other
+program which contains a notice placed by the copyright holder or
+other authorized party saying it may be distributed under the terms of
+this Lesser General Public License (also called "this License").
+Each licensee is addressed as "you".
+
+  A "library" means a collection of software functions and/or data
+prepared so as to be conveniently linked with application programs
+(which use some of those functions and data) to form executables.
+
+  The "Library", below, refers to any such software library or work
+which has been distributed under these terms.  A "work based on the
+Library" means either the Library or any derivative work under
+copyright law: that is to say, a work containing the Library or a
+portion of it, either verbatim or with modifications and/or translated
+straightforwardly into another language.  (Hereinafter, translation is
+included without limitation in the term "modification".)
+
+  "Source code" for a work means the preferred form of the work for
+making modifications to it.  For a library, complete source code means
+all the source code for all modules it contains, plus any associated
+interface definition files, plus the scripts used to control compilation
+and installation of the library.
+
+  Activities other than copying, distribution and modification are not
+covered by this License; they are outside its scope.  The act of
+running a program using the Library is not restricted, and output from
+such a program is covered only if its contents constitute a work based
+on the Library (independent of the use of the Library in a tool for
+writing it).  Whether that is true depends on what the Library does
+and what the program that uses the Library does.
+  
+  1. You may copy and distribute verbatim copies of the Library's
+complete source code as you receive it, in any medium, provided that
+you conspicuously and appropriately publish on each copy an
+appropriate copyright notice and disclaimer of warranty; keep intact
+all the notices that refer to this License and to the absence of any
+warranty; and distribute a copy of this License along with the
+Library.
+
+  You may charge a fee for the physical act of transferring a copy,
+and you may at your option offer warranty protection in exchange for a
+fee.
+
+  2. You may modify your copy or copies of the Library or any portion
+of it, thus forming a work based on the Library, and copy and
+distribute such modifications or work under the terms of Section 1
+above, provided that you also meet all of these conditions:
+
+    a) The modified work must itself be a software library.
+
+    b) You must cause the files modified to carry prominent notices
+    stating that you changed the files and the date of any change.
+
+    c) You must cause the whole of the work to be licensed at no
+    charge to all third parties under the terms of this License.
+
+    d) If a facility in the modified Library refers to a function or a
+    table of data to be supplied by an application program that uses
+    the facility, other than as an argument passed when the facility
+    is invoked, then you must make a good faith effort to ensure that,
+    in the event an application does not supply such function or
+    table, the facility still operates, and performs whatever part of
+    its purpose remains meaningful.
+
+    (For example, a function in a library to compute square roots has
+    a purpose that is entirely well-defined independent of the
+    application.  Therefore, Subsection 2d requires that any
+    application-supplied function or table used by this function must
+    be optional: if the application does not supply it, the square
+    root function must still compute square roots.)
+
+These requirements apply to the modified work as a whole.  If
+identifiable sections of that work are not derived from the Library,
+and can be reasonably considered independent and separate works in
+themselves, then this License, and its terms, do not apply to those
+sections when you distribute them as separate works.  But when you
+distribute the same sections as part of a whole which is a work based
+on the Library, the distribution of the whole must be on the terms of
+this License, whose permissions for other licensees extend to the
+entire whole, and thus to each and every part regardless of who wrote
+it.
+
+Thus, it is not the intent of this section to claim rights or contest
+your rights to work written entirely by you; rather, the intent is to
+exercise the right to control the distribution of derivative or
+collective works based on the Library.
+
+In addition, mere aggregation of another work not based on the Library
+with the Library (or with a work based on the Library) on a volume of
+a storage or distribution medium does not bring the other work under
+the scope of this License.
+
+  3. You may opt to apply the terms of the ordinary GNU General Public
+License instead of this License to a given copy of the Library.  To do
+this, you must alter all the notices that refer to this License, so
+that they refer to the ordinary GNU General Public License, version 2,
+instead of to this License.  (If a newer version than version 2 of the
+ordinary GNU General Public License has appeared, then you can specify
+that version instead if you wish.)  Do not make any other change in
+these notices.
+
+  Once this change is made in a given copy, it is irreversible for
+that copy, so the ordinary GNU General Public License applies to all
+subsequent copies and derivative works made from that copy.
+
+  This option is useful when you wish to copy part of the code of
+the Library into a program that is not a library.
+
+  4. You may copy and distribute the Library (or a portion or
+derivative of it, under Section 2) in object code or executable form
+under the terms of Sections 1 and 2 above provided that you accompany
+it with the complete corresponding machine-readable source code, which
+must be distributed under the terms of Sections 1 and 2 above on a
+medium customarily used for software interchange.
+
+  If distribution of object code is made by offering access to copy
+from a designated place, then offering equivalent access to copy the
+source code from the same place satisfies the requirement to
+distribute the source code, even though third parties are not
+compelled to copy the source along with the object code.
+
+  5. A program that contains no derivative of any portion of the
+Library, but is designed to work with the Library by being compiled or
+linked with it, is called a "work that uses the Library".  Such a
+work, in isolation, is not a derivative work of the Library, and
+therefore falls outside the scope of this License.
+
+  However, linking a "work that uses the Library" with the Library
+creates an executable that is a derivative of the Library (because it
+contains portions of the Library), rather than a "work that uses the
+library".  The executable is therefore covered by this License.
+Section 6 states terms for distribution of such executables.
+
+  When a "work that uses the Library" uses material from a header file
+that is part of the Library, the object code for the work may be a
+derivative work of the Library even though the source code is not.
+Whether this is true is especially significant if the work can be
+linked without the Library, or if the work is itself a library.  The
+threshold for this to be true is not precisely defined by law.
+
+  If such an object file uses only numerical parameters, data
+structure layouts and accessors, and small macros and small inline
+functions (ten lines or less in length), then the use of the object
+file is unrestricted, regardless of whether it is legally a derivative
+work.  (Executables containing this object code plus portions of the
+Library will still fall under Section 6.)
+
+  Otherwise, if the work is a derivative of the Library, you may
+distribute the object code for the work under the terms of Section 6.
+Any executables containing that work also fall under Section 6,
+whether or not they are linked directly with the Library itself.
+
+  6. As an exception to the Sections above, you may also combine or
+link a "work that uses the Library" with the Library to produce a
+work containing portions of the Library, and distribute that work
+under terms of your choice, provided that the terms permit
+modification of the work for the customer's own use and reverse
+engineering for debugging such modifications.
+
+  You must give prominent notice with each copy of the work that the
+Library is used in it and that the Library and its use are covered by
+this License.  You must supply a copy of this License.  If the work
+during execution displays copyright notices, you must include the
+copyright notice for the Library among them, as well as a reference
+directing the user to the copy of this License.  Also, you must do one
+of these things:
+
+    a) Accompany the work with the complete corresponding
+    machine-readable source code for the Library including whatever
+    changes were used in the work (which must be distributed under
+    Sections 1 and 2 above); and, if the work is an executable linked
+    with the Library, with the complete machine-readable "work that
+    uses the Library", as object code and/or source code, so that the
+    user can modify the Library and then relink to produce a modified
+    executable containing the modified Library.  (It is understood
+    that the user who changes the contents of definitions files in the
+    Library will not necessarily be able to recompile the application
+    to use the modified definitions.)
+
+    b) Use a suitable shared library mechanism for linking with the
+    Library.  A suitable mechanism is one that (1) uses at run time a
+    copy of the library already present on the user's computer system,
+    rather than copying library functions into the executable, and (2)
+    will operate properly with a modified version of the library, if
+    the user installs one, as long as the modified version is
+    interface-compatible with the version that the work was made with.
+
+    c) Accompany the work with a written offer, valid for at
+    least three years, to give the same user the materials
+    specified in Subsection 6a, above, for a charge no more
+    than the cost of performing this distribution.
+
+    d) If distribution of the work is made by offering access to copy
+    from a designated place, offer equivalent access to copy the above
+    specified materials from the same place.
+
+    e) Verify that the user has already received a copy of these
+    materials or that you have already sent this user a copy.
+
+  For an executable, the required form of the "work that uses the
+Library" must include any data and utility programs needed for
+reproducing the executable from it.  However, as a special exception,
+the materials to be distributed need not include anything that is
+normally distributed (in either source or binary form) with the major
+components (compiler, kernel, and so on) of the operating system on
+which the executable runs, unless that component itself accompanies
+the executable.
+
+  It may happen that this requirement contradicts the license
+restrictions of other proprietary libraries that do not normally
+accompany the operating system.  Such a contradiction means you cannot
+use both them and the Library together in an executable that you
+distribute.
+
+  7. You may place library facilities that are a work based on the
+Library side-by-side in a single library together with other library
+facilities not covered by this License, and distribute such a combined
+library, provided that the separate distribution of the work based on
+the Library and of the other library facilities is otherwise
+permitted, and provided that you do these two things:
+
+    a) Accompany the combined library with a copy of the same work
+    based on the Library, uncombined with any other library
+    facilities.  This must be distributed under the terms of the
+    Sections above.
+
+    b) Give prominent notice with the combined library of the fact
+    that part of it is a work based on the Library, and explaining
+    where to find the accompanying uncombined form of the same work.
+
+  8. You may not copy, modify, sublicense, link with, or distribute
+the Library except as expressly provided under this License.  Any
+attempt otherwise to copy, modify, sublicense, link with, or
+distribute the Library is void, and will automatically terminate your
+rights under this License.  However, parties who have received copies,
+or rights, from you under this License will not have their licenses
+terminated so long as such parties remain in full compliance.
+
+  9. You are not required to accept this License, since you have not
+signed it.  However, nothing else grants you permission to modify or
+distribute the Library or its derivative works.  These actions are
+prohibited by law if you do not accept this License.  Therefore, by
+modifying or distributing the Library (or any work based on the
+Library), you indicate your acceptance of this License to do so, and
+all its terms and conditions for copying, distributing or modifying
+the Library or works based on it.
+
+  10. Each time you redistribute the Library (or any work based on the
+Library), the recipient automatically receives a license from the
+original licensor to copy, distribute, link with or modify the Library
+subject to these terms and conditions.  You may not impose any further
+restrictions on the recipients' exercise of the rights granted herein.
+You are not responsible for enforcing compliance by third parties with
+this License.
+
+  11. If, as a consequence of a court judgment or allegation of patent
+infringement or for any other reason (not limited to patent issues),
+conditions are imposed on you (whether by court order, agreement or
+otherwise) that contradict the conditions of this License, they do not
+excuse you from the conditions of this License.  If you cannot
+distribute so as to satisfy simultaneously your obligations under this
+License and any other pertinent obligations, then as a consequence you
+may not distribute the Library at all.  For example, if a patent
+license would not permit royalty-free redistribution of the Library by
+all those who receive copies directly or indirectly through you, then
+the only way you could satisfy both it and this License would be to
+refrain entirely from distribution of the Library.
+
+If any portion of this section is held invalid or unenforceable under any
+particular circumstance, the balance of the section is intended to apply,
+and the section as a whole is intended to apply in other circumstances.
+
+It is not the purpose of this section to induce you to infringe any
+patents or other property right claims or to contest validity of any
+such claims; this section has the sole purpose of protecting the
+integrity of the free software distribution system which is
+implemented by public license practices.  Many people have made
+generous contributions to the wide range of software distributed
+through that system in reliance on consistent application of that
+system; it is up to the author/donor to decide if he or she is willing
+to distribute software through any other system and a licensee cannot
+impose that choice.
+
+This section is intended to make thoroughly clear what is believed to
+be a consequence of the rest of this License.
+
+  12. If the distribution and/or use of the Library is restricted in
+certain countries either by patents or by copyrighted interfaces, the
+original copyright holder who places the Library under this License may add
+an explicit geographical distribution limitation excluding those countries,
+so that distribution is permitted only in or among countries not thus
+excluded.  In such case, this License incorporates the limitation as if
+written in the body of this License.
+
+  13. The Free Software Foundation may publish revised and/or new
+versions of the Lesser General Public License from time to time.
+Such new versions will be similar in spirit to the present version,
+but may differ in detail to address new problems or concerns.
+
+Each version is given a distinguishing version number.  If the Library
+specifies a version number of this License which applies to it and
+"any later version", you have the option of following the terms and
+conditions either of that version or of any later version published by
+the Free Software Foundation.  If the Library does not specify a
+license version number, you may choose any version ever published by
+the Free Software Foundation.
+
+  14. If you wish to incorporate parts of the Library into other free
+programs whose distribution conditions are incompatible with these,
+write to the author to ask for permission.  For software which is
+copyrighted by the Free Software Foundation, write to the Free
+Software Foundation; we sometimes make exceptions for this.  Our
+decision will be guided by the two goals of preserving the free status
+of all derivatives of our free software and of promoting the sharing
+and reuse of software generally.
+
+			    NO WARRANTY
+
+  15. BECAUSE THE LIBRARY IS LICENSED FREE OF CHARGE, THERE IS NO
+WARRANTY FOR THE LIBRARY, TO THE EXTENT PERMITTED BY APPLICABLE LAW.
+EXCEPT WHEN OTHERWISE STATED IN WRITING THE COPYRIGHT HOLDERS AND/OR
+OTHER PARTIES PROVIDE THE LIBRARY "AS IS" WITHOUT WARRANTY OF ANY
+KIND, EITHER EXPRESSED OR IMPLIED, INCLUDING, BUT NOT LIMITED TO, THE
+IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
+PURPOSE.  THE ENTIRE RISK AS TO THE QUALITY AND PERFORMANCE OF THE
+LIBRARY IS WITH YOU.  SHOULD THE LIBRARY PROVE DEFECTIVE, YOU ASSUME
+THE COST OF ALL NECESSARY SERVICING, REPAIR OR CORRECTION.
+
+  16. IN NO EVENT UNLESS REQUIRED BY APPLICABLE LAW OR AGREED TO IN
+WRITING WILL ANY COPYRIGHT HOLDER, OR ANY OTHER PARTY WHO MAY MODIFY
+AND/OR REDISTRIBUTE THE LIBRARY AS PERMITTED ABOVE, BE LIABLE TO YOU
+FOR DAMAGES, INCLUDING ANY GENERAL, SPECIAL, INCIDENTAL OR
+CONSEQUENTIAL DAMAGES ARISING OUT OF THE USE OR INABILITY TO USE THE
+LIBRARY (INCLUDING BUT NOT LIMITED TO LOSS OF DATA OR DATA BEING
+RENDERED INACCURATE OR LOSSES SUSTAINED BY YOU OR THIRD PARTIES OR A
+FAILURE OF THE LIBRARY TO OPERATE WITH ANY OTHER SOFTWARE), EVEN IF
+SUCH HOLDER OR OTHER PARTY HAS BEEN ADVISED OF THE POSSIBILITY OF SUCH
+DAMAGES.
+
+		     END OF TERMS AND CONDITIONS
+
+           How to Apply These Terms to Your New Libraries
+
+  If you develop a new library, and you want it to be of the greatest
+possible use to the public, we recommend making it free software that
+everyone can redistribute and change.  You can do so by permitting
+redistribution under these terms (or, alternatively, under the terms of the
+ordinary General Public License).
+
+  To apply these terms, attach the following notices to the library.  It is
+safest to attach them to the start of each source file to most effectively
+convey the exclusion of warranty; and each file should have at least the
+"copyright" line and a pointer to where the full notice is found.
+
+    <one line to give the library's name and a brief idea of what it does.>
+    Copyright (C) <year>  <name of author>
+
+    This library is free software; you can redistribute it and/or
+    modify it under the terms of the GNU Lesser General Public
+    License as published by the Free Software Foundation; either
+    version 2.1 of the License, or (at your option) any later version.
+
+    This library is distributed in the hope that it will be useful,
+    but WITHOUT ANY WARRANTY; without even the implied warranty of
+    MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
+    Lesser General Public License for more details.
+
+    You should have received a copy of the GNU Lesser General Public
+    License along with this library; if not, write to the Free Software
+    Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA  02110-1301  USA
+
+Also add information on how to contact you by electronic and paper mail.
+
+You should also get your employer (if you work as a programmer) or your
+school, if any, to sign a "copyright disclaimer" for the library, if
+necessary.  Here is a sample; alter the names:
+
+  Yoyodyne, Inc., hereby disclaims all copyright interest in the
+  library `Frob' (a library for tweaking knobs) written by James Random Hacker.
+
+  <signature of Ty Coon>, 1 April 1990
+  Ty Coon, President of Vice
+
+That's all there is to it!
+
+

+ 96 - 0
tigcc/ttpack/packhead.h

@@ -0,0 +1,96 @@
+/******************************************************************************
+*
+* project name:    TIGCC Tools Suite 
+* file name:       packhead.h
+* initial date:    14/08/2000
+* author:          thomas.nussbaumer@gmx.net 
+* description:     header definition of compressed data
+*
+******************************************************************************/
+
+/*
+  This file is part of the TIGCC Tools Suite.
+
+  This file is free software; you can redistribute it and/or
+  modify it under the terms of the GNU Lesser General Public
+  License as published by the Free Software Foundation; either
+  version 2.1 of the License, or (at your option) any later version.
+
+  As a special exception, UNMODIFIED copies of some TIGCC Tools Suite utilities
+  may also be redistributed or sold without source code, for any purpose. (The
+  Lesser General Public License restrictions do apply in other respects; for
+  example, they cover modification of the launcher.) Please refer to the main
+  source file for the individual utility as to whether this is the case for a
+  particular tool. This exception notice must be removed on modified copies of
+  this file.
+
+  This program is distributed in the hope that it will be useful,
+  but WITHOUT ANY WARRANTY; without even the implied warranty of
+  MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
+  Lesser General Public License for more details.
+
+  You should have received a copy of the GNU Lesser General Public
+  License along with this library; if not, write to the Free Software
+  Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA  02110-1301  USA
+*/
+
+#ifndef __PACKHEAD_H__
+#define __PACKHEAD_H__
+
+
+#define MAGIC_CHAR1     'T'
+#define MAGIC_CHAR2     'P'
+
+#define MAX_RLE_ENTRIES 31
+
+// size = 16 bytes 
+typedef struct {
+    unsigned char origsize_lo; // original size lowbyte
+    unsigned char origsize_hi; // original size highbyte
+    unsigned char magic1;      // must be equal to MAGIC_CHAR1
+    unsigned char magic2;      // must be equal to MAGIC_CHAR2
+    unsigned char compsize_lo; // compressed size lowbyte
+    unsigned char compsize_hi; // compressed size lowbyte
+    unsigned char esc1;        // escape >> (8-escBits)
+    unsigned char notused3;
+    unsigned char notused4;
+    unsigned char esc2;        // escBits
+    unsigned char gamma1;      // maxGamma + 1
+    unsigned char gamma2;      // (1<<maxGamma)
+    unsigned char extralz;     // extraLZPosBits
+    unsigned char notused1;
+    unsigned char notused2;
+    unsigned char rleentries;  // rleUsed
+} PackedHeader;
+
+
+#define GetUnPackedSize(p)  (unsigned int)((p)->origsize_lo | ((p)->origsize_hi << 8))
+#define IsPacked(p)         ((p)->magic1 == MAGIC_CHAR1 && (p)->magic2 == MAGIC_CHAR2)
+
+
+typedef struct { 
+    unsigned char value[MAX_RLE_ENTRIES];
+} RLEEntries;
+
+
+#endif
+
+
+//#############################################################################
+//###################### NO MORE FAKES BEYOND THIS LINE #######################
+//#############################################################################
+//
+//=============================================================================
+// Revision History
+//=============================================================================
+//
+// Revision 1.3  2000/08/20 15:24:28  Thomas Nussbaumer
+// macros to get unpacked size and to check if packed added
+//
+// Revision 1.2  2000/08/16 23:08:55  Thomas Nussbaumer
+// magic characters changed to TP ... t(igcc tools) p(acked file)
+//
+// Revision 1.1  2000/08/14 22:49:57  Thomas Nussbaumer
+// initial version
+//
+// 

+ 132 - 0
tigcc/ttpack/revtools.h

@@ -0,0 +1,132 @@
+/******************************************************************************
+*
+* project name:    TIGCC Tools Suite
+* file name:       revtools.h
+* initial date:    23/08/2000
+* author:          thomas.nussbaumer@gmx.net
+* description:     macros for automatic handling of version number output
+*                  which is in sync with the CVS version number
+*
+* examine one of the pctools source codes to see how it works ;-)
+*
+******************************************************************************/
+
+/*
+  This file is part of the TIGCC Tools Suite.
+
+  This file is free software; you can redistribute it and/or
+  modify it under the terms of the GNU Lesser General Public
+  License as published by the Free Software Foundation; either
+  version 2.1 of the License, or (at your option) any later version.
+
+  As a special exception, UNMODIFIED copies of some TIGCC Tools Suite utilities
+  may also be redistributed or sold without source code, for any purpose. (The
+  Lesser General Public License restrictions do apply in other respects; for
+  example, they cover modification of the launcher.) Please refer to the main
+  source file for the individual utility as to whether this is the case for a
+  particular tool. This exception notice must be removed on modified copies of
+  this file.
+
+  This program is distributed in the hope that it will be useful,
+  but WITHOUT ANY WARRANTY; without even the implied warranty of
+  MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
+  Lesser General Public License for more details.
+
+  You should have received a copy of the GNU Lesser General Public
+  License along with this library; if not, write to the Free Software
+  Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA  02110-1301  USA
+*/
+
+//-----------------------------------------------------------------------------
+// [Usage]
+//
+// (1) include this file into your tool
+//
+//
+// (2) AFTER (!!) all includes put the following lines into your source code:
+//
+// #ifdef CVS_FILE_REVISION
+// #undef CVS_FILE_REVISION
+// #endif
+// ----------------------------------------------------------------------------
+// DON'T EDIT THE NEXT REVISION BY HAND! THIS IS DONE AUTOMATICALLY BY THE
+// CVS SYSTEM !!!
+// ----------------------------------------------------------------------------
+// #define CVS_FILE_REVISION "$Revision: 1.1 $"
+//
+// It must be placed AFTER (!!) all includes otherwise the macros may be
+// expanded wrong where you use them. For example: if you have added the above
+// lines at the top of your file and include afterwards a file which does
+// the same, the version of the included file will be used further due to the
+// #undef CVS_FILE_REVISION. Everything clear?
+//
+//
+// (3) to output the cvs revision number you can now to a simple:
+//
+// printf(CVSREV_PRINTPARAMS)
+//
+// if your file has, for example, the revision 1.3 the following string will
+// be printed:  v1.03
+//
+// the prefix before the subversion is used to get equal-sized output strings
+// for mainversions between 1 ... 9 and subversion between 1 .. 99
+//
+// if your program leaves that range and you need to have equal-sized output
+// strings you have to implement it by your own by using the
+// CVSREV_MAIN and CVSREV_SUB macros which returns the main and sub versions
+// as plain integers. if there is something wrong with your revision string
+// CVSREV_MAIN and/or CVSREV_SUB will deliver 0, which is no valid CVS main
+// or subversion number.
+//
+// i will suggest that you use the CVS system. its simple to handle, keeps
+// track of your revisions and their history and with the smart macros below
+// you haven't to worry anymore about the version output strings of your
+// program. if you want a special version number you can force CVS at every
+// time to give this version number to your program (0 is not allowed as
+// main and subversion number - thats the only pity)
+//
+// within this tools suite every tool will use the automatic version handling
+// but the tool suite version number itself will be handled "by hand".
+// this number shouldn't change that quickly as with the tools.
+//
+//-----------------------------------------------------------------------------
+#ifndef __REV_TOOLS_H__
+#define __REV_TOOLS_H__
+#include <stdio.h>
+#include <stdlib.h>
+#include <string.h>
+
+//-----------------------------------------------------------------------------
+// just used internally
+//-----------------------------------------------------------------------------
+#define CVS_TRUNC_PREFIX    ((strlen((CVS_FILE_REVISION))<=11) ? 0 : (CVS_FILE_REVISION+11))
+#define CVS_FIND_COMMA      (strchr(CVS_TRUNC_PREFIX,'.'))
+#define CVSREV_MAIN         (int)(!(CVS_TRUNC_PREFIX) ? 0 : atoi(CVS_TRUNC_PREFIX))
+#define CVSREV_SUB          (int)(!(CVS_TRUNC_PREFIX) ? 0 : (!(CVS_FIND_COMMA) ? 0 : atoi(CVS_FIND_COMMA+1)))
+
+//-----------------------------------------------------------------------------
+// NOTE: THE FOLLOWING MACRO WILL ONLY HANDLE MAIN VERSION < 10 AT CONSTANT
+//       LENGTH !!!
+//       (subversions from 1 .. 99 are mapped to 01 .. 99)
+//
+// the following macro may be used to setup a printf(),sprintf() or fprintf()
+// call
+//-----------------------------------------------------------------------------
+#define CVSREV_PRINTPARAMS  "v%d.%02d",CVSREV_MAIN,CVSREV_SUB
+
+
+#define PRINT_ID(name)  {fprintf(stdout,"\n");fprintf(stdout, name" ");\
+                         fprintf(stdout,CVSREV_PRINTPARAMS);\
+                         fprintf(stdout," - TIGCC Tools Suite v"TTV_MAIN TTV_SUB"\n" \
+                                       "(c) thomas.nussbaumer@gmx.net "__DATE__" "__TIME__"\n\n");}
+
+
+
+
+
+
+#endif
+
+//#############################################################################
+//###################### NO MORE FAKES BEYOND THIS LINE #######################
+//#############################################################################

+ 83 - 0
tigcc/ttpack/strhead.h

@@ -0,0 +1,83 @@
+/******************************************************************************
+*
+* project name:    TIGCC Tools Suite 
+* file name:       strhead.h
+* initial date:    13/08/2000
+* author:          thomas.nussbaumer@gmx.net 
+* description:     header structure of a TI string or OTH variable stored on
+*                  the PC
+*
+******************************************************************************/
+
+/*
+  This file is part of ttbin2oth.
+
+  This file is free software; you can redistribute it and/or
+  modify it under the terms of the GNU Lesser General Public
+  License as published by the Free Software Foundation; either
+  version 2.1 of the License, or (at your option) any later version.
+
+  As a special exception, UNMODIFIED copies of ttbin2oth may also be
+  redistributed or sold without source code, for any purpose. (The Lesser
+  General Public License restrictions do apply in other respects; for example,
+  they cover modification of the launcher.) This exception notice must be
+  removed on modified copies of this file.
+
+  This program is distributed in the hope that it will be useful,
+  but WITHOUT ANY WARRANTY; without even the implied warranty of
+  MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
+  Lesser General Public License for more details.
+
+  You should have received a copy of the GNU Lesser General Public
+  License along with this library; if not, write to the Free Software
+  Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA  02110-1301  USA
+*/
+
+#ifndef __STRHEAD_H__
+#define __STRHEAD_H__
+
+typedef struct {
+    char          signature[8]; // "**TI92P*" or "**TI89**"
+    unsigned char fill1[2];     // 01 00
+    char          folder[8];    // folder name
+    char          desc[40];     // ---- not used ----
+    unsigned char fill2[6];     // 01 00 52 00 00 00
+    char          name[8];      // varname
+    unsigned char type[4];      // 0C 00 00 00
+    unsigned char size[4];      // complete file size (including checksum)
+    unsigned char fill3[6];     // A5 5A 00 00 00 00
+    unsigned char datasize[2];  // data size
+}
+StrHeader;
+
+#endif
+
+//#############################################################################
+//###################### NO MORE FAKES BEYOND THIS LINE #######################
+//#############################################################################
+//
+//=============================================================================
+// Revision History
+//=============================================================================
+//
+// Revision 1.1  2000/08/23 20:31:13  Thomas Nussbaumer
+// renamed from pc_strdef.h
+//
+//
+// ---------------------------------------------------------------------------
+// revision info before file was renamed
+// ---------------------------------------------------------------------------
+// Revision 1.4  2000/08/23 01:05:00  Thomas Nussbaumer
+// minor comment added
+//
+// Revision 1.3  2000/08/20 15:25:24  Thomas Nussbaumer
+// bug fixed: size[] and datasize[] must be unsigned
+//
+// Revision 1.2  2000/08/13 20:24:51  Thomas Nussbaumer
+// some definitions moved to tt.h
+//
+// Revision 1.1  2000/08/13 16:02:13  Thomas Nussbaumer
+// initial version
+//
+//
+//

+ 71 - 0
tigcc/ttpack/tt.h

@@ -0,0 +1,71 @@
+/******************************************************************************
+*
+* project name:    TIGCC Tools Suite 
+* file name:       tt.h
+* initial date:    13/08/2000
+* author:          thomas.nussbaumer@gmx.net 
+* description:     generic definitions for TIGCC Tools Suite
+*
+******************************************************************************/
+
+/*
+  This file is part of the TIGCC Tools Suite.
+
+  This file is free software; you can redistribute it and/or
+  modify it under the terms of the GNU Lesser General Public
+  License as published by the Free Software Foundation; either
+  version 2.1 of the License, or (at your option) any later version.
+
+  As a special exception, UNMODIFIED copies of some TIGCC Tools Suite utilities
+  may also be redistributed or sold without source code, for any purpose. (The
+  Lesser General Public License restrictions do apply in other respects; for
+  example, they cover modification of the launcher.) Please refer to the main
+  source file for the individual utility as to whether this is the case for a
+  particular tool. This exception notice must be removed on modified copies of
+  this file.
+
+  This program is distributed in the hope that it will be useful,
+  but WITHOUT ANY WARRANTY; without even the implied warranty of
+  MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
+  Lesser General Public License for more details.
+
+  You should have received a copy of the GNU Lesser General Public
+  License along with this library; if not, write to the Free Software
+  Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA  02110-1301  USA
+*/
+
+#ifndef __TT_H__
+#define __TT_H__
+
+#define CALC_TI89    0
+#define CALC_TI92P   1
+
+#define SIGNATURE_TI89   "**TI89**"
+#define SIGNATURE_TI92P  "**TI92P*" 
+
+#define DEFAULT_FOLDER   "main"
+
+#define DEFAULT_ITEMS_PER_LINE  10
+
+#endif
+
+//#############################################################################
+//###################### NO MORE FAKES BEYOND THIS LINE #######################
+//#############################################################################
+//
+//=============================================================================
+// Revision History
+//=============================================================================
+//
+// Revision 1.3  2000/08/23 20:29:43  Thomas Nussbaumer
+// added a 'P' to the TI92p definitions
+//
+// Revision 1.2  2000/08/23 01:04:41  Thomas Nussbaumer
+// corrected signature of TI92p
+//
+// Revision 1.1  2000/08/13 20:24:16  Thomas Nussbaumer
+// initial version
+//
+//
+//
+//

+ 292 - 0
tigcc/ttpack/ttbin2oth.c

@@ -0,0 +1,292 @@
+/******************************************************************************
+*
+* project name:    TIGCC Tools Suite
+* file name:       ttbin2oth.c
+* initial date:    14/08/2000
+* author:          thomas.nussbaumer@gmx.net
+* description:     enwraps inputfile into a custom TI89 and TI92 variable
+*
+******************************************************************************/
+
+/*
+  This file is part of ttbin2oth.
+
+  This file is free software; you can redistribute it and/or
+  modify it under the terms of the GNU Lesser General Public
+  License as published by the Free Software Foundation; either
+  version 2.1 of the License, or (at your option) any later version.
+
+  As a special exception, UNMODIFIED copies of ttbin2oth may also be
+  redistributed or sold without source code, for any purpose. (The Lesser
+  General Public License restrictions do apply in other respects; for example,
+  they cover modification of the launcher.) This exception notice must be
+  removed on modified copies of this file.
+
+  This program is distributed in the hope that it will be useful,
+  but WITHOUT ANY WARRANTY; without even the implied warranty of
+  MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
+  Lesser General Public License for more details.
+
+  You should have received a copy of the GNU Lesser General Public
+  License along with this library; if not, write to the Free Software
+  Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA  02110-1301  USA
+*/
+
+#ifndef __TTBIN2OTH__
+#define __TTBIN2OTH__
+
+// if EMBEDDED_USE is defined, than we use this sourcefile from within another
+// sourcefile
+
+#ifndef EMBEDDED_USE
+
+#include <stdio.h>
+#include <string.h>
+#include <stdlib.h>
+
+#include "ttversion.h"
+#include "revtools.h"
+#include "tt.h"
+#include "strhead.h"
+
+#ifdef CVS_FILE_REVISION
+#undef CVS_FILE_REVISION
+#endif
+//-----------------------------------------------------------------------------
+// DON'T EDIT THE NEXT REVISION BY HAND! THIS IS DONE AUTOMATICALLY BY THE
+// CVS SYSTEM !!!
+//-----------------------------------------------------------------------------
+#define CVS_FILE_REVISION "$Revision: 1.1 $"
+
+
+//=============================================================================
+// outputs usage information of this tool
+//=============================================================================
+void PrintUsage() {
+#ifndef EMBEDDED_USE
+    PRINT_ID("TTBin2OTH");
+#endif
+    fprintf(USAGE_OUT, "Usage: ttbin2oth [flags] <-89 | -92> <extension> <infile> <varname> [folder]\n\n" \
+                       "       -quiet    ...  don't output standard messages\n"                           \
+                       "       -strip    ...  MUST be set if the input is already a TI file\n"            \
+                       "                      (generates a temporary file called bin2oth.tmp for\n"       \
+                       "                      the stripped inputfile)\n"                                  \
+                       "       -89       ...  generate a TI89 file\n"                                     \
+                       "       -92       ...  generate a TI92p file\n\n"                                  \
+                       "       extension ...  on-calc extension (up to 4 characters)\n"                   \
+                       "       varname   ...  on-calc variable name (up to 8 characters)\n"               \
+                       "       folder    ...  on-calc destination folder (OPTIONAL)\n\n"                  \
+                       "       enwraps file into a custom TI89 or TI92p variable with given <extension>\n"\
+                       "       NOTE1: the extension length may vary between 1 and 4 characters\n"         \
+                       "       NOTE2: the output filename is generated by taking the given varname and\n" \
+                       "              appending \".89y\" or \".9xy\" to it.\n"                            \
+                       "       NOTE3: if a generated file CAN'T BE UPLOADED, you are probably using a\n"  \
+                       "              reserved AMS name for your variable. Just try another name in\n"    \
+                       "              this case.\n\n");
+}
+
+#endif
+
+#include "bin2oth.c"
+
+#ifndef EMBEDDED_USE
+#define EMBEDDED_USE
+#include "ttstrip.c"
+#undef EMBEDDED_USE
+#else
+#include "ttstrip.c"
+#endif
+
+//=============================================================================
+// ... just a stupid main ...
+//=============================================================================
+#ifndef EMBEDDED_USE
+int main(int argc,char *argv[]) {
+#else
+int TTBin2OTH(int argc,char *argv[]) {
+#endif
+    char*          infile    = NULL;
+    char*          folder    = NULL;
+    char*          name      = NULL;
+    char*          extension = NULL;
+    int            calctype  = -1;
+    int            strip     = 0;
+    FILE*          ifp;
+    FILE*          ofp;
+    char           outfile[1024];
+    unsigned char* buffer;
+    int            length;
+    unsigned char* outbuffer;
+    unsigned int   outlength;
+    int            n;
+    char*          tmpfilename = "bin2oth.tmp";
+    int            quiet = 0;
+
+    // check for too less arguments
+    if (argc < 4) {
+#ifndef EMBEDDED_USE
+        PrintUsage();
+#endif
+        return 1;
+    }
+
+    // parse arguments
+    for (n=1; n<argc; n++) {
+        if (!strcmp(argv[n], "-89"))         calctype  = CALC_TI89;
+        else if (!strcmp(argv[n], "-92"))    calctype  = CALC_TI92P;
+        else if (!strcmp(argv[n], "-strip")) strip     = 1;
+        else if (!strcmp(argv[n], "-quiet")) quiet     = 1;
+        else if (argv[n][0] == '-') {
+            fprintf(stderr,"ERROR: invalid option %s",argv[n]);
+            return 1;
+        }
+        else if (!extension) extension = argv[n];
+        else if (!infile)    infile    = argv[n];
+        else if (!name)      name      = argv[n];
+        else if (!folder)    folder    = argv[n];
+        else {
+#ifndef EMBEDDED_USE
+            PrintUsage();
+#endif
+            return 1;
+        }
+    }
+
+    // check if all necessary arguments are supplied
+    if (!infile || !name || calctype == -1 || !extension) {
+#ifndef EMBEDDED_USE
+        PrintUsage();
+#endif
+        return 1;
+    }
+
+    n = strlen(extension);
+    if (n<1 || n>4) {
+        fprintf(stderr,"ERROR: extension length must be between 1 and 4 characters\n");
+        return 1;
+    }
+
+    if (strip) {
+        char* params[4];
+        params[0] = "";
+        params[1] = "-quiet";
+        params[2] = infile;
+        params[3] = tmpfilename;
+        if (TTStrip(4,params)) {
+            fprintf(stderr,"ERROR: stripping inputfile %s failed\n",infile);
+            return 1;
+        }
+        infile = tmpfilename;
+    }
+
+#ifndef EMBEDDED_USE
+    if (!quiet) PRINT_ID("TTBin2OTH");
+#endif
+
+
+    if (!(ifp = fopen(infile,"rb"))) {
+        fprintf(stderr,"ERROR: cannot open inputfile %s\n",infile);
+        if (strip) remove(tmpfilename);
+        return 1;
+    }
+
+    if (calctype == CALC_TI89) sprintf(outfile,"%s.89y",name);
+    else                       sprintf(outfile,"%s.9xy",name);
+
+    if (!(ofp = fopen(outfile,"wb"))) {
+        fprintf(stderr,"ERROR: cannot open outputfile %s\n",outfile);
+        fclose(ifp);
+        if (strip) remove(tmpfilename);
+        return 1;
+    }
+
+    // read infile into buffer
+    fseek(ifp,0,SEEK_END);
+    length = ftell(ifp);
+    buffer = (unsigned char*)malloc(length);
+    if (!buffer) {
+        fprintf(stderr,"ERROR: cannot allocate memory (%d bytes)\n",length);
+        fclose(ifp);
+        fclose(ofp);
+        if (strip) remove(tmpfilename);
+        return 1;
+    }
+    rewind(ifp);
+    fread(buffer,1,length,ifp);
+    fclose(ifp);
+
+    outbuffer = DataBuffer2OTHBuffer(calctype,folder,name,extension,length,buffer,&outlength);
+
+    n = 0;
+
+    if (!outbuffer) {
+        n = 1;
+    }
+    else {
+        if (fwrite(outbuffer,outlength,1,ofp) != 1) {
+            fprintf(stderr,"ERROR: cannot write %u bytes to outputfile to %s\n",outlength,outfile);
+            n = 1;
+        }
+        else {
+            if (!quiet) fprintf(stdout,"%u bytes written to %s\n",outlength,outfile);
+        }
+        free(outbuffer);
+    }
+
+    free(buffer);
+    fclose(ofp);
+
+    if (strip) remove(tmpfilename);
+    return n;
+}
+
+#endif
+
+//#############################################################################
+//###################### NO MORE FAKES BEYOND THIS LINE #######################
+//#############################################################################
+//
+//=============================================================================
+// Revision History
+//=============================================================================
+//
+// Revision 1.10  2002/05/07 16:33:46  tnussb
+// generic commit
+//
+// Revision 1.9  2002/05/07 15:58:46  tnussb
+// usage text modified (NOTE3 added)
+//
+// Revision 1.8  2002/03/14 09:01:44  tnussb
+// (1) supports now between 1 and 4 characters as extension
+// (2) new flag "-quiet" added (suppress standard messages)
+// (3) new flag "-strip" added (strip TI header before OTH generation)
+//     With this new flag it is possible to convert any TI file in
+//     one step into an OTH file without the need of using TTStrip
+//     before.
+// (4) Usage text completely rewritten
+//
+// Revision 1.7  2002/03/04 14:32:41  tnussb
+// now tool can be used as embedded version from within other tools
+// by defining EMBEDDED_VERSION before including the sourcefile
+//
+// Revision 1.6  2002/02/07 09:49:36  tnussb
+// all local includes changed, because header files are now located in pctools folder
+//
+// Revision 1.5  2000/11/28 00:41:15  Thomas Nussbaumer
+// unnecessary local function PrintId() removed
+//
+// Revision 1.4  2000/11/28 00:04:21  Thomas Nussbaumer
+// using now USAGE_OUT stream for usage info
+//
+// Revision 1.3  2000/08/23 19:40:44  Thomas Nussbaumer
+// using now automatic version display (revtools.h)
+//
+// Revision 1.2  2000/08/23 01:13:35  Thomas Nussbaumer
+// wrapper function exported to own file bin2oth.c
+//
+// Revision 1.1  2000/08/14 21:43:16  Thomas Nussbaumer
+// initial version
+//
+//
+//
+//

+ 2224 - 0
tigcc/ttpack/ttpack.c

@@ -0,0 +1,2224 @@
+/******************************************************************************
+*
+* project name:    TIGCC Tools Suite
+* file name:       ttpack.c
+* initial date:    14/08/2000
+* authors:         albert@cs.tut.fi
+*                  thomas.nussbaumer@gmx.net
+* description:     packing program
+*
+* -----------------------------------------------------------------------------
+*
+* based on code from Pasi 'Albert' Ojala, albert@cs.tut.fi
+* Pucrunch 1997-2005 by Pasi 'Albert' Ojala, a1bert@iki.fi
+* Pucrunch is under GNU LGPL:
+*  See http://creativecommons.org/licenses/LGPL/2.1/ or
+*      http://www.gnu.org/copyleft/lesser.html
+*
+*  The decompression code is distributed under the
+*  WXWindows Library Licence:
+*  See http://www.wxwidgets.org/licence3.txt
+*
+*  In short: binary version of the decompression code can
+*  accompany the compressed data or used in decompression
+*  programs.
+*
+* heavily reduced to fit to the needs by thomas.nussbaumer@gmx.net
+*
+******************************************************************************/
+
+#ifndef __TTPACK__
+#define __TTPACK__
+
+// if EMBEDDED_USE is defined, than we use this sourcefile from within another
+// sourcefile
+
+#ifndef EMBEDDED_USE
+
+#include <stdio.h>
+#include <stdlib.h>
+#include <string.h>
+#include <math.h>
+#include <ctype.h>
+#include <time.h>
+
+#include "tt.h"          // generic defines
+#include "ttversion.h"   // tigcc tools suite version info
+#include "revtools.h"    // used for id displaying
+#include "packhead.h"    // compressed header definition
+
+#ifdef CVS_FILE_REVISION
+#undef CVS_FILE_REVISION
+#endif
+//-----------------------------------------------------------------------------
+// DON'T EDIT THE NEXT REVISION BY HAND! THIS IS DONE AUTOMATICALLY BY THE
+// CVS SYSTEM !!!
+//-----------------------------------------------------------------------------
+#define CVS_FILE_REVISION "$Revision: 1.1 $"
+
+//=============================================================================
+// outputs usage information of this tool
+//=============================================================================
+void PrintUsage() {
+    PRINT_ID("TTPack");
+    fprintf(USAGE_OUT, "Usage: ttpack [-<flags>] <infile> <outfile>\n"               \
+                       "       -quiet    don't output standard messages (unsets v)\n"\
+                       "       -hti      treat input as hex textinput\n"             \
+                       "       -hto      generate hex textoutput\n"                  \
+                       "       -fdelta   use delta-lz77 -- shortens some files\n"    \
+                       "       e<val>    force escape bits\n"                        \
+                       "       r<val>    restrict lz search range\n"                 \
+                       "       n         no RLE/LZ length optimization\n"            \
+                       "       s         full statistics\n"                          \
+                       "       v         verbose (unsets -quiet)\n"                  \
+                       "       p<val>    force extralzposbits\n"                     \
+                       "       m<val>    max len 5..7 (2*2^5..2*2^7)\n");
+}
+
+#endif
+
+#define FIXF_MACHMASK  0xff
+#define FIXF_WRAP	   256
+#define FIXF_DLZ	   512
+
+
+#define F_VERBOSE    (1<<0)
+#define F_STATS      (1<<1)
+#define F_AUTO       (1<<2)
+#define F_NOOPT      (1<<3)
+#define F_AUTOEX     (1<<4)
+#define F_TEXTINPUT  (1<<5)
+#define F_TEXTOUTPUT (1<<6)
+#define F_NORLE      (1<<9)
+#define F_ERROR      (1<<15)
+
+#ifndef min
+#define min(a,b) ((a<b)?(a):(b))
+#endif
+
+
+#define LRANGE          (((2<<maxGamma)-3)*256) /* 0..125, 126 -> 1..127 */
+#define MAXLZLEN        (2<<maxGamma)
+#define MAXRLELEN       (((2<<maxGamma)-2)*256) /* 0..126 -> 1..127 */
+#define DEFAULT_LZLEN   LRANGE
+
+
+
+unsigned short *rle, *elr, *lzlen, *lzpos;
+unsigned short *lzlen2, *lzpos2;
+int *length, inlen;
+unsigned char *indata, *mode, *newesc;
+unsigned short *backSkip;
+
+
+enum MODE {
+    LITERAL = 0,
+    LZ77    = 1,
+    RLE     = 2,
+    DLZ     = 3,
+    MMARK   = 4
+};
+
+int lzopt          = 0;
+int maxGamma       = 7;
+int reservedBytes  = 2;
+int escBits        = 2;
+int escMask        = 0xc0;
+int extraLZPosBits = 0;
+int rleUsed        = 31;
+
+
+unsigned char rleLen[256];
+int lenValue[256];
+int lrange, maxlzlen, maxrlelen;
+
+int gainedEscaped = 0;
+int gainedRle = 0, gainedSRle = 0, gainedLRle = 0;
+int gainedLz = 0, gainedRlecode = 0;
+int gainedDLz = 0, timesDLz = 0;
+
+int timesEscaped = 0, timesNormal = 0;
+int timesRle = 0, timesSRle = 0, timesLRle = 0;
+int timesLz = 0;
+
+int lenStat[8][4];
+
+unsigned char rleValues[32] = {1,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,
+                               0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0};
+int rleHist[256];
+
+
+
+
+#define OUT_SIZE 65536
+unsigned char outBuffer[OUT_SIZE];
+int outPointer = 0;
+int bitMask    = 0x80;
+
+int quiet      = 0;
+
+
+void TTPackInit(void) {
+    int i;
+
+    rleValues[0] = 1;
+    for (i=1;i<32;i++) rleValues[i] = 0;
+
+    for (i=0;i<256;i++) {
+        rleLen[i]   = 0;
+        lenValue[i] = 0;
+        rleHist[i]  = 0;
+    }
+
+    for (i=0;i<OUT_SIZE;i++) outBuffer[i] = 0;
+
+    lrange = 0, maxlzlen = 0, maxrlelen = 0;
+
+
+    gainedEscaped = 0;
+    gainedRle = 0, gainedSRle = 0, gainedLRle = 0;
+    gainedLz = 0, gainedRlecode = 0;
+    gainedDLz = 0, timesDLz = 0;
+
+    timesEscaped = 0, timesNormal = 0;
+    timesRle = 0, timesSRle = 0, timesLRle = 0;
+    timesLz = 0;
+
+    lrange         = 0;
+    maxlzlen       = 0;
+    maxrlelen      = 0;
+    outPointer     = 0;
+    bitMask        = 0x80;
+    lzopt          = 0;
+    maxGamma       = 7;
+    reservedBytes  = 2;
+    escBits        = 2;
+    escMask        = 0xc0;
+    extraLZPosBits = 0;
+    rleUsed        = 31;
+    rle            = NULL;
+    elr            = NULL;
+    lzlen          = NULL;
+    lzpos          = NULL;
+    lzlen2         = NULL;
+    lzpos2         = NULL;
+    length         = NULL;
+    inlen          = 0;
+    indata         = NULL;
+    mode           = NULL;
+    newesc         = NULL;
+    backSkip       = NULL;
+}
+
+
+
+//=============================================================================
+// the packing code
+//=============================================================================
+int SavePack(int flags,int type, unsigned char *data, int size, char *target,
+             int start, int escape, unsigned char *rleValues,
+             int endAddr, int extraLZPosBits,int memStart, int memEnd)
+{
+    FILE *fp = NULL;
+
+    int  i;
+
+    if (!data)   return 10;
+    if (!target) fp = stdout;
+
+    if ((type & FIXF_MACHMASK) == 0) {
+        /* Save without decompressor */
+
+        if (fp || (fp = fopen(target, "wb"))) {
+            PackedHeader   cth;
+            RLEEntries     re;
+
+            cth.origsize_lo  = inlen & 0xff;
+            cth.origsize_hi  = (inlen >> 8);
+            cth.magic1       = MAGIC_CHAR1;
+            cth.magic2       = MAGIC_CHAR2;
+            cth.compsize_lo  = (size + rleUsed + sizeof(PackedHeader)) & 0xff;
+            cth.compsize_hi  = (size + rleUsed + sizeof(PackedHeader)) >> 8;
+            cth.esc1         = (escape >> (8-escBits));
+            cth.notused3     = 0; // just to make sure it has a defined value
+            cth.notused4     = 0; // just to make sure it has a defined value
+            cth.esc2         = escBits;
+            cth.gamma1       = maxGamma + 1;
+            cth.gamma2       = (1 << maxGamma);
+            cth.extralz      = extraLZPosBits;
+            cth.notused1     = 0; // just to make sure it has a defined value
+            cth.notused2     = 0; // just to make sure it has a defined value
+            cth.rleentries   = rleUsed;
+
+            for(i=0; i<rleUsed; i++) re.value[i] = rleValues[i+1];
+
+            if (flags & F_TEXTOUTPUT) {
+                unsigned int loop;
+                unsigned int written;
+                for (i=0;i<sizeof(PackedHeader);i++,written++) {
+                    fprintf(fp,"0x%02x,",*(((unsigned char*)&cth)+i));
+                    if ((!(written % DEFAULT_ITEMS_PER_LINE)) && written) fputc('\n',fp);
+                }
+                for (i=0;i<cth.rleentries;i++,written++) {
+                    fprintf(fp,"0x%02x,",re.value[i]);
+                    if (!(written % DEFAULT_ITEMS_PER_LINE)) fputc('\n',fp);
+                }
+                for (loop=0;loop < size;loop++,written++) {
+                    if (loop < size - 1)  fprintf(fp,"0x%02x,",data[loop]);
+                    else                  fprintf(fp,"0x%02x",data[loop]);
+                    if (!(written % DEFAULT_ITEMS_PER_LINE)) fputc('\n',fp);
+                }
+            }
+            else {
+                fwrite(&cth, 1, sizeof(PackedHeader), fp); // write header
+                fwrite(&re,  1, cth.rleentries, fp);       // write rle values
+                fwrite(data, size, 1, fp);                 // write compressed data
+                if(fp != stdout) fclose(fp);
+            }
+            return 0;
+        }
+        fprintf(stderr, "ERROR: Could not open %s for writing\n", target);
+        return 10;
+    }
+
+    fprintf(stderr, "FATAL: invalid type!!\n");
+    return 10;
+}
+
+
+
+//=============================================================================
+//
+//=============================================================================
+void FlushBits(void) {
+    if (bitMask != 0x80) outPointer++;
+}
+
+
+//=============================================================================
+//
+//=============================================================================
+void PutBit(int bit) {
+    if (bit && outPointer < OUT_SIZE) outBuffer[outPointer] |= bitMask;
+    bitMask >>= 1;
+
+    if (!bitMask) {
+        bitMask = 0x80;
+        outPointer++;
+    }
+}
+
+
+//=============================================================================
+//
+//=============================================================================
+void PutValue(int value) {
+    int bits = 0, count = 0;
+
+    while (value>1) {
+        bits = (bits<<1) | (value & 1); /* is reversed compared to value */
+        value >>= 1;
+        count++;
+        PutBit(1);
+    }
+
+    if (count<maxGamma) PutBit(0);
+
+    while (count--) {
+        PutBit((bits & 1));     /* output is reversed again -> same as value */
+        bits >>= 1;
+    }
+}
+
+
+
+//--------------------------------------------
+// why not initializing value lenValue[0] ????
+//--------------------------------------------
+//=============================================================================
+//
+//=============================================================================
+void InitValueLen() {
+    int i;
+
+    // could be heavily optimized, but isn't necessary
+    for (i=1; i<256; i++) {
+        int count = 0;
+
+        if (i<2)        count = 0;  /* 1       */
+        else if (i<4)   count = 1;  /* 2-3     */
+        else if (i<8)   count = 2;  /* 4-7     */
+        else if (i<16)  count = 3;  /* 8-15    */
+        else if (i<32)  count = 4;  /* 16-31   */
+        else if (i<64)  count = 5;  /* 32-63   */
+        else if (i<128) count = 6;  /* 64-127  */
+        else if (i<256) count = 7;  /* 128-255 */
+
+        lenValue[i] = 2*count;
+        if (count<maxGamma) lenValue[i]++;
+    }
+}
+
+
+#define LenValue(a) (lenValue[a])
+
+
+//=============================================================================
+//
+//=============================================================================
+void PutNBits(int byte, int bits) {
+    while (bits--)
+        PutBit((byte & (1<<bits)));
+}
+
+
+
+
+//=============================================================================
+//
+//=============================================================================
+int OutputNormal(int *esc, unsigned char *data, int newesc) {
+    timesNormal++;
+    if ((data[0] & escMask) == *esc) {
+        PutNBits((*esc>>(8-escBits)), escBits); /* escBits>=0 */
+        PutBit(0);
+        PutBit(1);
+        PutBit(0);
+
+        *esc = newesc;
+        PutNBits((*esc>>(8-escBits)), escBits); /* escBits>=0 */
+        PutNBits(data[0], 8-escBits);
+
+        gainedEscaped += escBits + 3;
+        timesEscaped++;
+        return 1;
+    }
+    PutNBits(data[0], 8);
+    return 0;
+}
+
+
+//=============================================================================
+//
+//=============================================================================
+void OutputEof(int *esc) {
+    /* EOF marker */
+    PutNBits((*esc>>(8-escBits)), escBits);     /* escBits>=0 */
+    PutValue(3);        /* >2 */
+    PutValue((2<<maxGamma)-1);  /* Maximum value */
+    FlushBits();
+}
+
+
+//=============================================================================
+//
+//=============================================================================
+void PutRleByte(int data) {
+    int index;
+
+    for (index = 1; index < 32; index++) {
+        if (data == rleValues[index]) {
+            if (index==1)       lenStat[0][3]++;
+            else if (index<=3)  lenStat[1][3]++;
+            else if (index<=7)  lenStat[2][3]++;
+            else if (index<=15) lenStat[3][3]++;
+            else if (index<=31) lenStat[4][3]++;
+
+            gainedRlecode += 8 - LenValue(index);
+
+            PutValue(index);
+            return;
+        }
+    }
+    PutValue(32 + (data>>3));
+
+    gainedRlecode -= LenValue(32+(data>>3)) + 3;
+
+    PutNBits(data, 3);
+
+    lenStat[5][3]++;
+}
+
+
+
+
+//=============================================================================
+//
+//=============================================================================
+void InitRleLen() {
+    int i;
+
+    for (i=0; i<256; i++) rleLen[i] = LenValue(32 + 0) + 3;
+    for (i=1; i<32; i++) rleLen[rleValues[i]] = LenValue(i);
+}
+
+#define LenRleByte(d) (rleLen[d])
+
+
+//=============================================================================
+//
+//=============================================================================
+int LenRle(int len, int data) {
+    int out = 0;
+
+    do {
+        if (len == 1) {
+            out += escBits + 3 + 8;
+            len = 0;
+        }
+        else if (len <= (1<<maxGamma)) {
+            out += escBits + 3 + LenValue(len-1) + LenRleByte(data);
+            len = 0;
+        }
+        else {
+            int tmp = min(len, maxrlelen);
+            out += escBits + 3 + maxGamma + 8 +
+                        LenValue(((tmp-1)>>8)+1) + LenRleByte(data);
+            len -= tmp;
+        }
+    } while (len);
+    return out;
+}
+
+
+//=============================================================================
+//
+//=============================================================================
+int OutputRle(int *esc, unsigned char *data, int rlelen) {
+    int len = rlelen, tmp;
+
+    while (len) {
+        if (len >= 2 && len <= (1<<maxGamma)) {
+            /* Short RLE */
+            if (len==2)        lenStat[0][2]++;
+            else if (len<=4)   lenStat[1][2]++;
+            else if (len<=8)   lenStat[2][2]++;
+            else if (len<=16)  lenStat[3][2]++;
+            else if (len<=32)  lenStat[4][2]++;
+            else if (len<=64)  lenStat[5][2]++;
+            else if (len<=128) lenStat[6][2]++;
+            else if (len<=256) lenStat[6][2]++;
+
+            PutNBits((*esc>>(8-escBits)), escBits);     /* escBits>=0 */
+            PutBit(0);
+            PutBit(1);
+            PutBit(1);
+            PutValue(len-1);
+            PutRleByte(*data);
+
+            tmp = 8*len -escBits -3 -LenValue(len-1) -LenRleByte(*data);
+            gainedRle += tmp;
+            gainedSRle += tmp;
+
+            timesRle++;
+            timesSRle++;
+            return 0;
+        }
+        if (len<3) {
+            while (len--)
+                OutputNormal(esc, data, *esc);
+            return 0;
+        }
+
+        if (len <= maxrlelen) {
+            /* Run-length encoding */
+            PutNBits((*esc>>(8-escBits)), escBits);     /* escBits>=0 */
+
+            PutBit(0);
+            PutBit(1);
+            PutBit(1);
+
+            PutValue((1<<maxGamma) + (((len-1)&0xff)>>(8-maxGamma)));
+
+            PutNBits((len-1), 8-maxGamma);
+            PutValue(((len-1)>>8) + 1);
+            PutRleByte(*data);
+
+            tmp = 8*len -escBits -3 -maxGamma -8 -LenValue(((len-1)>>8)+1)
+                -LenRleByte(*data);
+            gainedRle += tmp;
+            gainedLRle += tmp;
+
+            timesRle++;
+            timesLRle++;
+            return 0;
+        }
+
+        /* Run-length encoding */
+        PutNBits((*esc>>(8-escBits)), escBits); /* escBits>=0 */
+
+        PutBit(0);
+        PutBit(1);
+        PutBit(1);
+
+        PutValue((1<<maxGamma) + (((maxrlelen-1)&0xff)>>(8-maxGamma)));
+
+        PutNBits((maxrlelen-1) & 0xff, 8-maxGamma);
+        PutValue(((maxrlelen-1)>>8)+1);
+        PutRleByte(*data);
+
+        tmp = 8*maxrlelen -escBits -3 -maxGamma -8
+            -LenValue(((maxrlelen-1)>>8)+1) -LenRleByte(*data);
+        gainedRle += tmp;
+        gainedLRle += tmp;
+        timesRle++;
+        timesLRle++;
+        len -= maxrlelen;
+        data += maxrlelen;
+    }
+    return 0;
+}
+
+
+//=============================================================================
+//
+//=============================================================================
+int LenLz(int lzlen, int lzpos) {
+    if (lzlen==2) {
+        if (lzpos <= 256) return escBits + 2 + 8;
+        else              return 100000;
+    }
+
+    return escBits + 8 + extraLZPosBits +
+           LenValue(((lzpos-1)>>(8+extraLZPosBits))+1) +
+           LenValue(lzlen-1);
+}
+
+
+//=============================================================================
+//
+//=============================================================================
+int OutputLz(int *esc, int lzlen, int lzpos, char *data, int curpos) {
+    if (lzlen==2)        lenStat[0][1]++;
+    else if (lzlen<=4)   lenStat[1][1]++;
+    else if (lzlen<=8)   lenStat[2][1]++;
+    else if (lzlen<=16)  lenStat[3][1]++;
+    else if (lzlen<=32)  lenStat[4][1]++;
+    else if (lzlen<=64)  lenStat[5][1]++;
+    else if (lzlen<=128) lenStat[6][1]++;
+    else if (lzlen<=256) lenStat[7][1]++;
+
+    if (lzlen >= 2 && lzlen <= maxlzlen) {
+        int tmp;
+
+        PutNBits((*esc>>(8-escBits)), escBits); /* escBits>=0 */
+
+        tmp = ((lzpos-1)>>(8+extraLZPosBits))+2;
+        if (tmp==2)         lenStat[0][0]++;
+        else if (tmp<=4)    lenStat[1][0]++;
+        else if (tmp<=8)    lenStat[2][0]++;
+        else if (tmp<=16)   lenStat[3][0]++;
+        else if (tmp<=32)   lenStat[4][0]++;
+        else if (tmp<=64)   lenStat[5][0]++;
+        else if (tmp<=128)  lenStat[6][0]++;
+        else if (tmp<=256)  lenStat[6][0]++;
+
+        if (lzlen==2) {
+            PutValue(lzlen-1);
+            PutBit(0);
+            if (lzpos > 256) fprintf(stderr,"ERROR at %d: lzpos too long (%d) for lzlen==2\n",curpos, lzpos);
+        }
+        else {
+            PutValue(lzlen-1);
+            PutValue( ((lzpos-1) >> (8+extraLZPosBits)) +1);
+            PutNBits( ((lzpos-1) >> 8), extraLZPosBits);
+        }
+        PutNBits(((lzpos-1) & 0xff) ^ 0xff, 8);
+
+        gainedLz += 8*lzlen -LenLz(lzlen, lzpos);
+        timesLz++;
+        return 3;
+    }
+    fprintf(stderr, "ERROR: lzlen too short/long (%d)\n", lzlen);
+    return lzlen;
+}
+
+
+
+/* Non-recursive version */
+/* NOTE! IMPORTANT! the "length" array length must be inlen+1 */
+
+//=============================================================================
+//
+//=============================================================================
+int OptimizeLength(int optimize) {
+    int i;
+
+    length[inlen] = 0;          /* one off the end, our 'target' */
+    for (i=inlen-1; i>=0; i--) {
+        int r1 = 8 + length[i+1], r2, r3;
+
+        if (!lzlen[i] && !rle[i] && (!lzlen2 || !lzlen2[i])) {
+            length[i] = r1;
+            mode[i] = LITERAL;
+            continue;
+        }
+
+        /* If rle>maxlzlen, skip to the start of the rle-maxlzlen.. */
+        if (rle[i] > maxlzlen && elr[i] > 1) {
+            int z = elr[i];
+
+            i -= elr[i];
+
+            r2 = LenRle(rle[i], indata[i]) + length[i+ rle[i]];
+            if (optimize) {
+                int ii, mini = rle[i], minv = r2;
+
+                int bot = rle[i] - (1<<maxGamma);
+                if (bot < 2)
+                    bot = 2;
+
+                for (ii=mini-1; ii>=bot; ii--) {
+                    int v = LenRle(ii, indata[i]) + length[i + ii];
+                    if (v < minv) {
+                        minv = v;
+                        mini = ii;
+                    }
+                }
+                if (minv != r2) {
+                    lzopt += r2 - minv;
+                    rle[i] = mini;
+                    r2 = minv;
+                }
+            }
+            length[i] = r2;
+            mode[i] = RLE;
+
+            for (; z>=0; z--) {
+                length[i+z] = r2;
+                mode[i+z] = RLE;
+            }
+            continue;
+        }
+        r3 = r2 = r1 + 1000; /* r3 >= r2 > r1 */
+
+        if (rle[i]) {
+            r2 = LenRle(rle[i], indata[i]) + length[i+ rle[i]];
+
+            if (optimize) {
+                int ii, mini = rle[i], minv = r2;
+
+                /* Check only the original length and all shorter
+                   lengths that are power of two.
+
+                   Does not really miss many 'minimums' this way,
+                   at least not globally..
+
+                   Makes the assumption that the Elias Gamma Code is
+                   used, i.e. values of the form 2^n are 'optimal' */
+                ii = 2;
+                while (rle[i] > ii) {
+                    int v = LenRle(ii, indata[i]) + length[i + ii];
+                    if (v < minv) {
+                        minv = v;
+                        mini = ii;
+                    }
+                    ii <<= 1;
+                }
+                if (minv != r2) {
+                    lzopt += r2 - minv;
+                    rle[i] = mini;
+                    r2 = minv;
+                }
+            }
+        }
+        if (lzlen[i]) {
+            r3 = LenLz(lzlen[i], lzpos[i]) + length[i + lzlen[i]];
+
+            if (optimize && lzlen[i]>2) {
+                int ii, mini = lzlen[i], minv = r3;
+                int topLen = LenLz(lzlen[i], lzpos[i])
+                    - LenValue(lzlen[i]-1);
+
+                /* Check only the original length and all shorter
+                   lengths that are power of two.
+
+                   Does not really miss many 'minimums' this way,
+                   at least not globally..
+
+                   Makes the assumption that the Elias Gamma Code is
+                   used, i.e. values of the form 2^n are 'optimal' */
+                ii = 4;
+                while (lzlen[i] > ii) {
+                    int v = topLen + LenValue(ii-1) + length[i + ii];
+                    if (v < minv) {
+                        minv = v;
+                        mini = ii;
+                    }
+                    ii <<= 1;
+                }
+                /*
+                  Note:
+                  2-byte optimization checks are no longer done
+                  with the rest, because the equation gives too long
+                  code lengths for 2-byte matches if extraLzPosBits>0.
+                  */
+                /* Two-byte rescan/check */
+                if (backSkip[i] && backSkip[i] <= 256) {
+                    /* There are previous occurrances (near enough) */
+                    int v = LenLz(2, (int)backSkip[i]) + length[i + 2];
+
+                    if (v < minv) {
+                        minv = v;
+                        mini = 2;
+                        lzlen[i] = mini;
+                        r3 = minv;
+                        lzpos[i] = (int)backSkip[i];
+                    }
+                }
+                if (minv != r3 && minv < r2) {
+                    lzopt += r3 - minv;
+                    lzlen[i] = mini;
+                    r3 = minv;
+                }
+            }
+        }
+
+        if (r2 <= r1) {
+            if (r2 <= r3) {
+                length[i] = r2;
+                mode[i]   = RLE;
+            }
+            else {
+                length[i] = r3;
+                mode[i]   = LZ77;
+            }
+        }
+        else {
+            if (r3 <= r1) {
+                length[i] = r3;
+                mode[i]   = LZ77;
+            }
+            else {
+                length[i] = r1;
+                mode[i]   = LITERAL;
+            }
+        }
+        if (lzlen2 && lzlen2[i] > 3) {
+            r3 = escBits + 2*maxGamma + 16 + LenValue(lzlen2[i]-1) + length[i + lzlen2[i]];
+            //r3 = LenDLz(lzlen2[i], lzpos2[i]) + length[i + lzlen2[i]];
+            if (r3 < length[i]) {
+                length[i] = r3;
+                mode[i]   = DLZ;
+            }
+        }
+    }
+    return length[0];
+}
+
+
+/*
+    The algorithm in the OptimizeEscape() works as follows:
+    1) Only unpacked bytes are processed, they are marked
+       with MMARK. We proceed from the end to the beginning.
+       Variable A (old/new length) is updated.
+    2) At each unpacked byte, one and only one possible
+       escape matches. A new escape code must be selected
+       for this case. The optimal selection is the one which
+       provides the shortest number of escapes to the end
+       of the file,
+        i.e. A[esc] = 1+min(A[0], A[1], .. A[states-1]).
+       For other states A[esc] = A[esc];
+       If we change escape in this byte, the new escape is
+       the one with the smallest value in A.
+    3) The starting escape is selected from the possibilities
+       and mode 0 is restored to all mode 3 locations.
+
+ */
+
+//=============================================================================
+//
+//=============================================================================
+int OptimizeEscape(int *startEscape, int *nonNormal) {
+    int  i, j, states = (1<<escBits);
+    long minp = 0, minv = 0, other = 0;
+    long a[256]; /* needs int/long */
+    long b[256]; /* Remembers the # of escaped for each */
+    int  esc8 = 8-escBits;
+
+    for (i=0; i<256; i++) b[i] = a[i] = -1;
+
+    if (states>256) {
+        fprintf(stderr, "Escape optimize: only 256 states (%d)!\n",states);
+        return 0;
+    }
+
+    /* Mark those bytes that are actually outputted */
+    for (i=0; i<inlen; ) {
+        switch (mode[i]) {
+            case DLZ:
+                other++;
+                i += lzlen2[i];
+                break;
+
+            case LZ77:
+                other++;
+                i += lzlen[i];
+                break;
+
+            case RLE:
+                other++;
+                i += rle[i];
+                break;
+
+            /*case LITERAL:*/
+            default:
+                mode[i++] = MMARK; /* mark it used so we can identify it */
+                break;
+        }
+    }
+
+    for (i=inlen-1; i>=0; i--) {
+        /* Using a table to skip non-normal bytes does not help.. */
+        if (mode[i] == MMARK) {
+            int k = (indata[i] >> esc8);
+
+            /* Change the tag values back to normal */
+            mode[i] = LITERAL;
+
+            /*
+                k are the matching bytes,
+                minv is the minimum value,
+                minp is the minimum index
+             */
+
+            newesc[i] = (minp << esc8);
+            a[k] = minv + 1;
+            b[k] = b[minp] + 1;
+            if (k==minp) {
+                /* Minimum changed -> need to find a new minimum */
+                /* a[k] may still be the minimum */
+                minv++;
+                for (k=states-1; k>=0; k--) {
+                    if (a[k] < minv) {
+                        minv = a[k];
+                        minp = k;
+                        /*
+                            There may be others, but the first one that
+                            is smaller than the old minimum is equal to
+                            any other new minimum.
+                         */
+                        break;
+                    }
+                }
+            }
+        }
+    }
+
+    /* Select the best value for the initial escape */
+    if (startEscape) {
+        i = inlen;      /* make it big enough */
+        for (j=states-1; j>=0; j--) {
+            if (a[j] <= i) {
+                *startEscape = (j << esc8);
+                i = a[j];
+            }
+        }
+    }
+    if (nonNormal)
+        *nonNormal = other;
+    return b[startEscape ? (*startEscape>>esc8) : 0];
+}
+
+
+//=============================================================================
+// Initialize the RLE byte code table according to all RLE's found so far O(n)
+//=============================================================================
+void InitRle(int flags) {
+    int p, mr, mv, i;
+
+    for (i=1; i<32; i++) {
+        mr = -1;
+        mv = 0;
+
+        for (p=0; p<256; p++) {
+            if (rleHist[p] > mv) {
+                mv = rleHist[p];
+                mr = p;
+            }
+        }
+        if (mv>0) {
+            rleValues[i] = mr;
+            rleHist[mr] = -1;
+        } else
+            break;
+    }
+    InitRleLen();
+}
+
+
+//=============================================================================
+// Initialize the RLE byte code table according to RLE's actually used O(n)
+//=============================================================================
+void OptimizeRle(int flags) {
+    int p, mr, mv, i;
+
+    if ((flags & F_NORLE)) {
+        rleUsed = 0;
+        return;
+    }
+    if (flags & F_STATS) fprintf(stderr, "RLE Byte Code Re-Tune, RLE Ranks:\n");
+
+    for (p=0; p<256; p++) rleHist[p] = 0;
+
+    for (p=0; p<inlen; ) {
+        switch (mode[p]) {
+            case DLZ:
+                p += lzlen2[p];
+                break;
+            case LZ77:
+                p += lzlen[p];
+                break;
+
+            case RLE:
+                rleHist[indata[p]]++;
+                p += rle[p];
+                break;
+
+            default:
+                p++;
+                break;
+        }
+    }
+
+    for (i=1; i<32; i++) {
+        mr = -1;
+        mv = 0;
+
+        for (p=0; p<256; p++) {
+            if (rleHist[p] > mv) {
+                mv = rleHist[p];
+                mr = p;
+            }
+        }
+        if (mv>0) {
+            rleValues[i] = mr;
+            if (flags & F_STATS) {
+                fprintf(stderr, " %2d.0x%02x %-3d ", i, mr, mv);
+                if (!((i - 1) % 6)) fprintf(stderr, "\n");
+            }
+            rleHist[mr] = -1;
+        }
+        else {
+            break;
+        }
+    }
+    rleUsed = i-1;
+
+    if (flags & F_STATS)
+        if (((i - 1) % 6)!=1) fprintf(stderr, "\n");
+    InitRleLen();
+}
+
+
+//=============================================================================
+//
+//=============================================================================
+int PackLz77(int lzsz, int flags, int *startEscape,int endAddr, int memEnd, int type)
+{
+    int i, j, outlen, p, headerSize;
+    int escape;
+    unsigned char *hashValue;
+    unsigned char *a;
+    int k;
+
+    unsigned short *lastPair;
+    unsigned short err_occured = 0;
+
+    int rescan = 0;
+
+
+
+
+    if (lzsz < 0 || lzsz > lrange) {
+        fprintf(stderr, "LZ range must be from 0 to %d (was %d). Set to %d.\n",
+                lrange, lzsz, lrange);
+        lzsz = lrange;
+    }
+    if (lzsz > 65535) {
+        fprintf(stderr,
+                "LZ range must be from 0 to 65535 (was %d). Set to 65535.\n",
+                lzsz);
+        lzsz = 65535;
+    }
+    if (!lzsz) fprintf(stderr, "Warning: zero LZ range. Only RLE packing used.\n");
+
+    InitRleLen();
+    length = (int *)calloc(sizeof(int), inlen + 1);
+    mode   = (unsigned char  *)calloc(sizeof(unsigned char),  inlen);
+    rle    = (unsigned short *)calloc(sizeof(unsigned short), inlen);
+    elr    = (unsigned short *)calloc(sizeof(unsigned short), inlen);
+    lzlen  = (unsigned short *)calloc(sizeof(unsigned short), inlen);
+    lzpos  = (unsigned short *)calloc(sizeof(unsigned short), inlen);
+    if ((type & FIXF_DLZ)) {
+        lzlen2  = (unsigned short *)calloc(sizeof(unsigned short), inlen);
+        lzpos2  = (unsigned short *)calloc(sizeof(unsigned short), inlen);
+    }
+    else {
+        lzlen2 = lzpos2 = NULL;
+    }
+    newesc    = (unsigned char  *)calloc(sizeof(unsigned char),  inlen);
+    backSkip  = (unsigned short *)calloc(sizeof(unsigned short), inlen);
+    hashValue = (unsigned char  *)malloc(inlen);
+    lastPair  = (unsigned short *)calloc(sizeof(unsigned short), 256*256);
+
+
+    /* error checking */
+    if (!length || !mode || !rle || !elr || !lzlen || !lzpos || !newesc ||
+        !lastPair || !backSkip
+        || ((type & FIXF_DLZ) && (!lzlen2 || !lzpos2))
+        || !hashValue)
+    {
+        fprintf(stderr, "ERROR: Memory allocation failed!\n");
+        err_occured = 1;
+        goto errorexit;
+    }
+
+    i = 0;
+    j = 0;
+    a = indata + inlen;
+    for (p=inlen-1; p>=0; p--) {
+        k = j;
+        j = i;
+        i = *--a;       /* Only one read per position */
+        hashValue[p] = i*3 + j*5 + k*7; /* 7.95 % */
+    }
+
+    /* Detect all RLE and LZ77 jump possibilities */
+    for (p=0; p<inlen; p++) {
+        if (flags & F_VERBOSE) {
+            if (!(p & 2047)) {
+                fprintf(stderr, "\r%d ", p);
+                fflush(stderr);     /* for SAS/C */
+            }
+        }
+        /* check run-length code - must be done, LZ77 search needs it! */
+        if (rle[p] <= 0) {
+            unsigned char *a = indata + p;
+            int val = *a++; /* if this were uchar, it would go to stack..*/
+            int top = inlen - p;
+            int rlelen = 1;
+
+            /* Loop for the whole RLE */
+            while (rlelen<top && *a++ == (unsigned char)val) rlelen++;
+
+            if (rlelen>=2) {
+                rleHist[indata[p]]++;
+
+                for (i=rlelen-1; i>=0; i--) {
+                    rle[p+i] = rlelen-i;
+                    elr[p+i] = i;       /* For RLE backward skipping */
+                }
+
+            }
+        }
+
+        /* check LZ77 code */
+        if (p+rle[p]+1<inlen) {
+            int bot = p - lzsz, maxval, maxpos, rlep = rle[p];
+            unsigned char hashCompare = hashValue[p];
+
+            /*
+                There's always 1 equal byte, although it may
+                not be marked as RLE.
+             */
+            if (rlep <= 0)
+                rlep = 1;
+            if (bot < 0)
+                bot = 0;
+            bot += (rlep-1);
+
+            /*
+                First get the shortest possible match (if any).
+                If there is no 2-byte match, don't look further,
+                because there can't be a longer match.
+             */
+            i = (int)lastPair[ (indata[p]<<8) | indata[p+1] ] -1;
+            if (i>=0 && i>=bot) {
+                /* Got a 2-byte match at least */
+                maxval = 2;
+                maxpos = p-i;
+
+                /*
+                    A..AB       rlep # of A's, B is something else..
+
+                    Search for bytes that are in p + (rlep-1), i.e.
+                    the last rle byte ('A') and the non-matching one
+                    ('B'). When found, check if the rle in the compare
+                    position (i) is long enough (i.e. the same number
+                    of A's at p and i-rlep+1).
+
+                    There are dramatically less matches for AB than for
+                    AA, so we get a huge speedup with this approach.
+                    We are still guaranteed to find the most recent
+                    longest match there is.
+                 */
+
+                i = (int)lastPair[(indata[p+(rlep-1)]<<8) | indata[p+rlep]] -1;
+                while (i>=bot /* && i>=rlep-1 */) {   /* bot>=rlep-1, i>=bot  ==> i>=rlep-1 */
+
+                    /* Equal number of A's ? */
+                    if (!(rlep-1) || rle[i-(rlep-1)]==rlep) {   /* 'head' matches */
+                        /* rlep==1 ==> (rlep-1)==0 */
+                        /* ivanova.run: 443517 rlep==1,
+                           709846 rle[i+1-rlep]==rlep */
+
+                        /*
+                            Check the hash values corresponding to the last
+                            two bytes of the currently longest match and
+                            the first new matching(?) byte. If the hash
+                            values don't match, don't bother to check the
+                            data itself.
+                         */
+                        if (
+                            hashValue[i+maxval-rlep-1] == hashCompare
+                           ) {
+                            unsigned char *a = indata + i+2;    /* match  */
+                            unsigned char *b = indata + p+rlep-1+2;/* curpos */
+                            int topindex = inlen-(p+rlep-1);
+
+                            /* the 2 first bytes ARE the same.. */
+                            j = 2;
+                            while (j < topindex && *a++==*b++)
+                                j++;
+
+                            if (j + rlep-1 > maxval) {
+                                int tmplen = j+rlep-1, tmppos = p-i+rlep-1;
+
+                                if (tmplen > maxlzlen)
+                                    tmplen = maxlzlen;
+
+                                /* Accept only versions that really are shorter */
+                                if (tmplen*8 - LenLz(tmplen, tmppos) >
+                                    maxval*8 - LenLz(maxval, maxpos)) {
+                                    maxval = tmplen;
+                                    maxpos = tmppos;
+                                    hashCompare = hashValue[p+maxval-2];
+                                }
+                                if (maxval == maxlzlen)
+                                    break;
+                            }
+                        }
+                    }
+                    if (!backSkip[i])
+                        break; /* No previous occurrances (near enough) */
+                    i -= (int)backSkip[i];
+                }
+
+                /*
+                    If there is 'A' in the previous position also,
+                    RLE-like LZ77 is possible, although rarely
+                    shorter than real RLE.
+                 */
+                if (p && rle[p-1] > maxval) {
+                    maxval = rle[p-1] - 1;
+                    maxpos = 1;
+                }
+                /*
+                    Last, try to find as long as possible match
+                    for the RLE part only.
+                 */
+                if (maxval < maxlzlen && rlep > maxval) {
+                    bot = p - lzsz;
+                    if (bot < 0)
+                        bot = 0;
+
+                    /* Note: indata[p] == indata[p+1] */
+                    i = (int)lastPair[indata[p]*257] -1;
+                    while (/* i>= rlep-2 &&*/ i>=bot) {
+                        if (elr[i] + 2 > maxval) {
+                            maxval = min(elr[i] + 2, rlep);
+                            maxpos = p - i + (maxval-2);
+                            if(maxval == rlep)
+                                break; /* Got enough */
+                        }
+                        i -= elr[i];
+                        if (!backSkip[i])
+                            break; /* No previous occurrances (near enough) */
+                        i -= (int)backSkip[i];
+                    }
+                }
+                if (p+maxval > inlen) {
+                    fprintf(stderr,"Error @ %d, lzlen %d, pos %d - exceeds inlen\n",p, maxval, maxpos);
+                    maxval = inlen - p;
+                }
+                if (maxpos<=256 || maxval > 2) {
+                    if (maxpos < 0) fprintf(stderr, "Error @ %d, lzlen %d, pos %d\n",p, maxval, maxpos);
+                    lzlen[p] = (maxval<maxlzlen)?maxval:maxlzlen;
+                    lzpos[p] = maxpos;
+                }
+            }
+        }
+
+        /* check LZ77 code again, ROT1..255 */
+        if ((type & FIXF_DLZ) && p+rle[p]+1<inlen) {
+        int rot;
+
+        for (rot = 1; rot < 255; rot++) {
+            int bot = p - /*lzsz*/256, maxval, maxpos, rlep = rle[p];
+            unsigned char valueCompare = (indata[p+2] + rot) & 0xff;
+
+            if (rlep <= 0) rlep = 1;
+            if (bot < 0)   bot = 0;
+            bot += (rlep-1);
+
+            i = (int)lastPair[ (((indata[p] + rot) & 0xff)<<8) |
+                                ((indata[p+1] + rot) & 0xff) ] -1;
+            if (i>=0 && i>=bot) {
+                maxval = 2;
+                maxpos = p-i;
+
+                /*
+                    A..AB       rlep # of A's, B is something else..
+
+                    Search for bytes that are in p + (rlep-1), i.e.
+                    the last rle byte ('A') and the non-matching one
+                    ('B'). When found, check if the rle in the compare
+                    position (i) is long enough (i.e. the same number
+                    of A's at p and i-rlep+1).
+
+                    There are dramatically less matches for AB than for
+                    AA, so we get a huge speedup with this approach.
+                    We are still guaranteed to find the most recent
+                    longest match there is.
+                 */
+
+                i = (int)lastPair[(((indata[p+(rlep-1)] + rot) & 0xff)<<8) |
+                                   ((indata[p+rlep] + rot) & 0xff)] -1;
+                while (i>=bot /* && i>=rlep-1 */) {   /* bot>=rlep-1, i>=bot  ==> i>=rlep-1 */
+
+                    /* Equal number of A's ? */
+                    if (!(rlep-1) || rle[i-(rlep-1)]==rlep) {   /* 'head' matches */
+                        /* rlep==1 ==> (rlep-1)==0 */
+                        /* ivanova.run: 443517 rlep==1,
+                           709846 rle[i+1-rlep]==rlep */
+
+                        /*
+                            Check the hash values corresponding to the last
+                            two bytes of the currently longest match and
+                            the first new matching(?) byte. If the hash
+                            values don't match, don't bother to check the
+                            data itself.
+                         */
+                        if (indata[i+maxval-rlep+1] == valueCompare) {
+                            unsigned char *a = indata + i+2;    /* match  */
+                            unsigned char *b = indata + p+rlep-1+2;/* curpos */
+                            int topindex = inlen-(p+rlep-1);
+
+                            /* the 2 first bytes ARE the same.. */
+                            j = 2;
+                            while (j < topindex && *a++==((*b++ + rot) & 0xff))
+                                j++;
+
+                            if (j + rlep-1 > maxval) {
+                                int tmplen = j+rlep-1, tmppos = p-i+rlep-1;
+
+                                if (tmplen > maxlzlen)
+                                    tmplen = maxlzlen;
+
+                                /* Accept only versions that really are shorter */
+                                if (tmplen*8 - LenLz(tmplen, tmppos) >
+                                    maxval*8 - LenLz(maxval, maxpos)) {
+                                    maxval = tmplen;
+                                    maxpos = tmppos;
+
+                                    valueCompare = (indata[p+maxval] + rot) & 0xff;
+                                }
+                                if (maxval == maxlzlen)
+                                    break;
+                            }
+                        }
+                    }
+                    if (!backSkip[i])
+                        break; /* No previous occurrances (near enough) */
+                    i -= (int)backSkip[i];
+                }
+
+                if (p+maxval > inlen) {
+                    fprintf(stderr,"Error @ %d, lzlen %d, pos %d - exceeds inlen\n",p, maxval, maxpos);
+                    maxval = inlen - p;
+                }
+                if (maxval > 3 && maxpos <= 256 &&
+                    (maxval > lzlen2[p] ||
+                     (maxval == lzlen2[p] && maxpos < lzpos2[p]))) {
+                    if (maxpos < 0)
+                        fprintf(stderr, "Error @ %d, lzlen %d, pos %d\n",p, maxval, maxpos);
+                    lzlen2[p] = (maxval<maxlzlen)?maxval:maxlzlen;
+                    lzpos2[p] = maxpos;
+                }
+            }
+        }
+        if (lzlen2[p] <= lzlen[p] || lzlen2[p] <= rle[p]) {
+            lzlen2[p] = lzpos2[p] = 0;
+        }
+        }
+
+        /* Update the two-byte history ('hash table') &
+           backSkip ('linked list') */
+        if (p+1<inlen) {
+            int index = (indata[p]<<8) | indata[p+1];
+            int ptr = p - (lastPair[index]-1);
+
+            if (ptr > p || ptr > 0xffff)
+                ptr = 0;
+
+            backSkip[p] = ptr;
+            lastPair[index] = p+1;
+        }
+    }
+    if ((flags & F_NORLE)) {
+        for (p=1; p<inlen; p++) {
+            if (rle[p-1]-1 > lzlen[p]) {
+                lzlen[p] = (rle[p]<maxlzlen)?rle[p]:maxlzlen;
+                lzpos[p] = 1;
+            }
+        }
+        for (p=0; p<inlen; p++) {
+            rle[p] = 0;
+        }
+    }
+
+    if (flags & F_VERBOSE) {
+        fprintf(stderr, "\rChecked: %d \n", p);
+        fflush(stderr);
+    }
+
+
+    /* Initialize the RLE selections */
+    InitRle(flags);
+
+    /* Check the normal bytes / all ratio */
+    if ((flags & F_AUTO)) {
+        int mb, mv;
+
+        if (flags & F_VERBOSE) {
+            fprintf(stderr, "Selecting the number of escape bits.. ");
+            fflush(stderr);
+        }
+
+        /*
+            Absolute maximum number of escaped bytes with
+            the escape optimize is 2^-n, where n is the
+            number of escape bits used.
+
+            This worst case happens only on equal-
+            distributed normal bytes (01230123..).
+            This is why the typical values are so much smaller.
+         */
+
+        mb = 0;
+        mv = 8*OUT_SIZE;
+        for (escBits=1; escBits<9; escBits++) {
+            int escaped, other = 0, c;
+
+            escMask = (0xff00>>escBits) & 0xff;
+
+            /* Find the optimum path for selected escape bits (no optimize) */
+            OptimizeLength(0);
+
+            /* Optimize the escape selections for this path & escBits */
+            escaped = OptimizeEscape(&escape, &other);
+
+            /* Compare value: bits lost for escaping -- bits lost for prefix */
+            c = (escBits+3)*escaped + other*escBits;
+            if (flags & F_STATS) {
+                fprintf(stderr, " %d:%d", escBits, c);
+                fflush(stderr); /* for SAS/C */
+            }
+            if (c < mv) {
+                mb = escBits;
+                mv = c;
+            } else {
+                /* minimum found */
+                break;
+            }
+            if (escBits==4 && (flags & F_STATS)) fprintf(stderr, "\n");
+        }
+        if (mb==1) {    /* Minimum was 1, check 0 */
+            int escaped;
+
+            escBits = 0;
+            escMask = 0;
+
+            /* Find the optimum path for selected escape bits (no optimize) */
+            OptimizeLength(0);
+            /* Optimize the escape selections for this path & escBits */
+            escaped = OptimizeEscape(&escape, NULL);
+
+            if ((flags & F_STATS)) {
+                fprintf(stderr, " %d:%d", escBits, 3*escaped);
+                fflush(stderr); /* for SAS/C */
+            }
+            if (3*escaped < mv) {
+                mb = 0;
+                /* mv = 3*escaped; */
+            }
+        }
+        if ((flags & F_STATS)) fprintf(stderr, "\n");
+
+        if (flags & F_VERBOSE) fprintf(stderr, "Selected %d-bit escapes\n", mb);
+        escBits = mb;
+        escMask = (0xff00>>escBits) & 0xff;
+    }
+
+
+    if (!(flags & F_NOOPT)) {
+        if (flags & F_VERBOSE) {
+            fprintf(stderr, "Optimizing LZ77 and RLE lengths...");
+            fflush(stderr);
+        }
+    }
+
+    /* Find the optimum path (optimize) */
+    OptimizeLength((flags & F_NOOPT)?0:1);
+    if (flags & F_STATS) {
+        if (!(flags & F_NOOPT)) fprintf(stderr, " gained %d units.\n", lzopt/8);
+    }
+    else {
+        if (flags & F_VERBOSE) fprintf(stderr, "\n");
+    }
+
+    if (1 || (flags & F_AUTOEX)) {
+        long lzstat[5] = {0,0,0,0,0}, i, cur = 0, old = extraLZPosBits;
+
+        if (flags & F_VERBOSE) {
+            fprintf(stderr, "Selecting LZPOS LO length.. ");
+            fflush(stderr);
+        }
+
+        for (p=0; p<inlen; ) {
+            switch (mode[p]) {
+            case LZ77:
+                extraLZPosBits = 0;
+                lzstat[0] += LenLz(lzlen[p], lzpos[p]);
+                extraLZPosBits = 1;
+                lzstat[1] += LenLz(lzlen[p], lzpos[p]);
+                extraLZPosBits = 2;
+                lzstat[2] += LenLz(lzlen[p], lzpos[p]);
+                extraLZPosBits = 3;
+                lzstat[3] += LenLz(lzlen[p], lzpos[p]);
+                extraLZPosBits = 4;
+                lzstat[4] += LenLz(lzlen[p], lzpos[p]);
+                p += lzlen[p];
+                break;
+            case DLZ:
+                p += lzlen2[p];
+                break;
+            case RLE:
+                p += rle[p];
+                break;
+
+            default:
+                p++;
+                break;
+            }
+        }
+        for (i=0; i<5; i++) {
+            if (flags & F_STATS) fprintf(stderr, " %ld:%ld", i + 8, lzstat[i]);
+
+            if (lzstat[i] < lzstat[cur]) cur = i;
+        }
+        extraLZPosBits = (flags & F_AUTOEX)?cur:old;
+
+        if (flags & F_STATS) fprintf(stderr, "\n");
+
+        if (flags & F_VERBOSE) {
+            fprintf(stderr, "Selected %d-bit LZPOS LO part\n",extraLZPosBits + 8);
+            if (cur != old) fprintf(stderr,"Note: Using option -p%ld you may get better results.\n",cur);
+        }
+        /* Find the optimum path (optimize) */
+        if (extraLZPosBits != old) OptimizeLength((flags & F_NOOPT)?0:1);
+    }
+    if (1) {
+        long stat[4] = {0,0,0,0};
+
+        for (p=0; p<inlen; ) {
+            switch (mode[p]) {
+            case LZ77:
+                if ((lzpos[p] >> 8)+1 > (1<<maxGamma))
+                    stat[3]++;
+                if (lzlen[p] > (1<<maxGamma))
+                    stat[0]++;
+                p += lzlen[p];
+                break;
+
+            case RLE:
+                if (rle[p] > (1<<(maxGamma-1))) {
+                    if (rle[p] <= (1<<maxGamma))
+                        stat[1]++;
+
+                }
+                p += rle[p];
+                break;
+            case DLZ:
+                p += lzlen2[p];
+                break;
+            default:
+                p++;
+                break;
+            }
+        }
+        /* TODO: better formula.. */
+        if (maxGamma < 7 && stat[0] + stat[1] + stat[3] > 10) {
+            if (flags & F_VERBOSE) fprintf(stderr,"Note: Using option -m%d you may get better results.\n",maxGamma+1);
+        }
+        if (maxGamma > 5 && stat[0] + stat[1] + stat[3] < 4) {
+            if (flags & F_VERBOSE) fprintf(stderr,"Note: Using option -m%d you may get better results.\n",maxGamma-1);
+        }
+    }
+
+    /* Optimize the escape selections */
+    OptimizeEscape(&escape, NULL);
+    if (startEscape) *startEscape = escape;
+    OptimizeRle(flags); /* Retune the RLE selections */
+
+    if (flags & F_VERBOSE) {
+        int oldEscape = escape;
+        if (flags & F_VERBOSE) printf("normal RLE  LZLEN LZPOS(absolute)\n\n");
+
+        for (p=0; p<inlen; ) {
+            switch (mode[p]) {
+            case LZ77:
+                mode[p - lzpos[p]] |= MMARK; /* Was referred to by lz77 */
+                p += lzlen[p];
+                break;
+            case RLE:
+                p += rle[p];
+                break;
+            case DLZ:
+                mode[p - lzpos2[p]] |= MMARK; /* Was referred to by lz77 */
+                p += lzlen2[p];
+                break;
+        /*  case LITERAL:
+            case MMARK:*/
+            default:
+                p++;
+                break;
+            }
+        }
+
+        j = 0;
+        for (p=0; p<inlen; p++) {
+            switch (mode[p]) {
+            case MMARK | DLZ:
+            case DLZ:
+                if (j==p) {
+                    if (flags & F_VERBOSE) printf(">");
+                    j += lzlen2[p];
+                } else
+                    printf(" ");
+                if (lzpos2) {
+                    if (flags & F_VERBOSE) printf(" %04x*%03d*+%02x", lzpos2[p], lzlen2[p],(indata[p] - indata[p-lzpos2[p]]) & 0xff);
+                }
+                if (flags & F_VERBOSE) printf(" 001   %03d   %03d  %04x(%04x)  %02x %s\n",
+                                              rle[p],lzlen[p],lzpos[p],p-lzpos[p],indata[p],
+                                              (mode[p] & MMARK)?"#":" ");
+                break;
+            case MMARK | LITERAL:
+            case LITERAL:
+                if (flags & F_VERBOSE) {
+                    if (j==p) printf(">");
+                    else      printf(" ");
+
+                    if (lzpos2) {
+                        printf(" %04x %03d +%02x", lzpos2[p], lzlen2[p],
+                               (indata[p] - indata[p-lzpos2[p]]) & 0xff);
+                    }
+                }
+                if (j==p) {
+                    if (flags & F_VERBOSE) {
+                        printf("*001*  %03d   %03d  %04x(%04x)  %02x %s %02x",
+                               rle[p], lzlen[p], lzpos[p], p-lzpos[p], indata[p],
+                               (mode[p] & MMARK)?"#":" ", newesc[p]);
+                    }
+                    if ((indata[p] & escMask) == escape) {
+                        escape = newesc[p];
+                        if (flags & F_VERBOSE) printf("«");
+                    }
+                    if (flags & F_VERBOSE) printf("\n");
+                    j += 1;
+                } else {
+                    if (flags & F_VERBOSE) printf("*001*  %03d   %03d  %04x(%04x)  %02x %s %02x\n",
+                                                  rle[p], lzlen[p], lzpos[p], p-lzpos[p], indata[p],
+                                                  (mode[p] & MMARK)?"#":" ", newesc[p]);
+                }
+                break;
+            case MMARK | LZ77:
+            case LZ77:
+                if (j==p) {
+                    if (flags & F_VERBOSE) printf(">");
+                    j += lzlen[p];
+                } else
+                    if (flags & F_VERBOSE) printf(" ");
+                if (lzpos2) {
+                    if (flags & F_VERBOSE) printf(" %04x %03d +%02x", lzpos2[p], lzlen2[p],
+                                                  (indata[p] - indata[p-lzpos2[p]]) & 0xff);
+                }
+                if (flags & F_VERBOSE) printf(" 001   %03d  *%03d* %04x(%04x)  %02x %s\n",
+                                              rle[p], lzlen[p], lzpos[p], p-lzpos[p], indata[p],
+                                              (mode[p] & MMARK)?"#":" ");
+                break;
+            case MMARK | RLE:
+            case RLE:
+                if (j==p) {
+                    if (flags & F_VERBOSE) printf(">");
+                    j += rle[p];
+                } else
+                    if (flags & F_VERBOSE) printf(" ");
+                if (lzpos2) {
+                    if (flags & F_VERBOSE) printf(" %04x %03d +%02x", lzpos2[p], lzlen2[p],
+                                                  (indata[p] - indata[p-lzpos2[p]]) & 0xff);
+                }
+                if (flags & F_VERBOSE) printf(" 001  *%03d*  %03d  %04x(%04x)  %02x %s\n",
+                                              rle[p], lzlen[p], lzpos[p], p-lzpos[p], indata[p],
+                                              (mode[p] & MMARK)?"#":" ");
+                break;
+            default:
+                j++;
+                break;
+            }
+            mode[p] &= ~MMARK;
+        }
+        escape = oldEscape;
+    }
+
+    for (p=0; p<inlen; ) {
+        switch (mode[p]) {
+        case LITERAL: /* normal */
+            length[p] = outPointer;
+
+            OutputNormal(&escape, indata+p, newesc[p]);
+            p++;
+            break;
+
+        case DLZ:
+            for (i=0; i<lzlen2[p]; i++) length[p+i] = outPointer;
+
+            PutNBits((escape>>(8-escBits)), escBits);
+            PutValue(lzlen2[p]-1);
+            PutValue((2<<maxGamma)-1);
+            PutNBits((indata[p] - indata[p-lzpos2[p]]) & 0xff, 8);
+            PutNBits(((lzpos2[p]-1) & 0xff) ^ 0xff, 8);
+            gainedDLz += 8*lzlen2[p] -(escBits + LenValue(lzlen2[p]-1) + 2*maxGamma + 16);
+            timesDLz++;
+            p += lzlen2[p];
+            break;
+
+        case LZ77: /* lz77 */
+
+            /* Not possible for smaller backSkip table
+               (the table is overwritten during previous use) */
+            /* Re-search matches to get the closest one */
+            if (lzopt && lzlen[p] > 2 && lzlen[p] > rle[p]) {
+                int bot = p - lzpos[p] + 1, i;
+                unsigned short rlep = rle[p];
+
+                if (!rlep)
+                    rlep = 1;
+                if (bot < 0)
+                    bot = 0;
+                bot += (rlep-1);
+
+                i = p - (int)backSkip[p];
+                while (i>=bot /* && i>=rlep-1 */) {
+                    /* Equal number of A's ? */
+                    if (rlep==1 || rle[i-rlep+1]==rlep) {       /* 'head' matches */
+                        unsigned char *a = indata + i+1;        /* match  */
+                        unsigned char *b = indata + p+rlep-1+1; /* curpos */
+                        int topindex = inlen-(p+rlep-1);
+
+                        j = 1;
+                        while (j < topindex && *a++==*b++)
+                            j++;
+
+                        if (j + rlep-1 >= lzlen[p]) {
+                            int tmppos = p-i+rlep-1;
+
+                            rescan +=
+                                LenLz(lzlen[p], lzpos[p]) -
+                                LenLz(lzlen[p], tmppos);
+                            lzpos[p] = tmppos;
+                            break;
+                        }
+                    }
+                    if (!backSkip[i])
+                        break; /* No previous occurrances (near enough) */
+                    i -= (int)backSkip[i];
+                }
+            }
+
+            for (i=0; i<lzlen[p]; i++)
+                length[p+i] = outPointer;
+            OutputLz(&escape, lzlen[p], lzpos[p], indata+p-lzpos[p], p);
+            p += lzlen[p];
+            break;
+
+        case RLE: /* rle */
+            for (i=0; i<rle[p]; i++)
+                length[p+i] = outPointer;
+            OutputRle(&escape, indata+p, rle[p]);
+            p += rle[p];
+            break;
+
+        default: /* Error Flynn :-) */
+            p++;
+            fprintf(stderr, "Internal error: mode %d\n", mode[p]);
+            break;
+        }
+    }
+    OutputEof(&escape);
+
+    i = inlen;
+    for (p=0; p<inlen; p++) {
+        int pos = (inlen - outPointer) + (int)length[p] - p;
+        i = min(i, pos);
+    }
+    if (i<0)
+        reservedBytes = -i + 2;
+    else
+        reservedBytes = 0;
+
+    // TOMTOM !!!
+
+    if (type & FIXF_MACHMASK == 0) {
+        headerSize = 16 + rleUsed;
+    } else
+    {
+        if (endAddr + reservedBytes + 3 > memEnd) {
+            type |= FIXF_WRAP;
+        } else {
+            type &= ~FIXF_WRAP;
+        }
+        headerSize = 47 + rleUsed - 31;
+    }
+    outlen = outPointer + headerSize;   /* unpack code */
+
+    if (flags & F_VERBOSE) fprintf(stderr, "In: %d, out: %d, ratio: %5.2f%% (%4.2f[%4.2f] b/B)"
+                                   ", gained: %5.2f%%\n",
+                                   inlen, outlen, (double)outlen*100.0/(double)inlen + 0.005,
+                                   8.0*(double)outlen/(double)inlen + 0.005,
+                                   8.0*(double)(outlen-headerSize+rleUsed+4)/(double)inlen + 0.005,
+                                   100.0 - (double)outlen*100.0/(double)inlen + 0.005);
+
+    if ((type & FIXF_DLZ)) {
+        if (flags & F_VERBOSE) {
+            fprintf(stderr, "Gained RLE: %d (S+L:%d+%d), DLZ: %d, LZ: %d, Esc: %d"
+                    ", Decompressor: %d\n",
+                    gainedRle/8, gainedSRle/8, gainedLRle/8, gainedDLz/8,
+                    gainedLz/8, -gainedEscaped/8, -headerSize);
+
+            fprintf(stderr, "Times  RLE: %d (%d+%d), DLZ: %d, LZ: %d, Esc: %d (normal: %d)"
+                    ", %d escape bit%s\n",
+                    timesRle, timesSRle, timesLRle, timesDLz,
+                    timesLz, timesEscaped, timesNormal,
+                    escBits, (escBits==1)?"":"s" );
+        }
+    }
+    else {
+        if (flags & F_VERBOSE) {
+            fprintf(stderr, "Gained RLE: %d (S+L:%d+%d), LZ: %d, Esc: %d"
+                    ", Decompressor: %d\n",
+                    gainedRle/8, gainedSRle/8, gainedLRle/8,
+                    gainedLz/8, -gainedEscaped/8, -headerSize);
+
+            fprintf(stderr, "Times  RLE: %d (%d+%d), LZ: %d, Esc: %d (normal: %d)"
+                    ", %d escape bit%s\n",
+                    timesRle, timesSRle, timesLRle,
+                    timesLz, timesEscaped, timesNormal,
+                    escBits, (escBits==1)?"":"s" );
+        }
+    }
+    if ((flags & F_STATS)) {
+        char *ll[] = {"2", "3-4", "5-8", "9-16", "17-32", "33-64",
+                            "65-128", "129-256"};
+        fprintf(stderr, "(Gained by RLE Code: %d, LZPOS LO Bits %d"
+                ", maxLen: %d, tag bit/prim. %4.2f)\n",
+                gainedRlecode/8 - rleUsed,
+                extraLZPosBits + 8,
+                (2<<maxGamma),
+                (double)((timesRle+timesLz)*escBits +
+                         timesEscaped*(escBits + 3))/
+                (double)(timesRle+timesLz+timesNormal) + 0.0049);
+
+        fprintf(stderr, "   LZPOS HI+2 LZLEN S-RLE RLEcode\n");
+        fprintf(stderr, "   ------------------------------\n");
+        for (i=0; i<=maxGamma; i++) {
+            fprintf(stderr, "%-7s %5d %5d", ll[i],
+                    lenStat[i][0], lenStat[i][1]);
+            if (i<maxGamma)
+                fprintf(stderr, " %5d", lenStat[i][2]);
+            else
+                fprintf(stderr, "     -");
+
+            if (i<6)
+                fprintf(stderr, "   %5d%s\n", lenStat[i][3], (i==5)?"*":"");
+            else
+                fprintf(stderr, "       -\n");
+        }
+        fprintf(stderr, "LZ77 rescan gained %d bytes\n", rescan/8);
+    }
+
+errorexit:
+    if (rle)       free(rle);
+    if (elr)       free(elr);
+    if (lzlen)     free(lzlen);
+    if (lzpos)     free(lzpos);
+    if (length)    free(length);
+    if (mode)      free(mode);
+    if (newesc)    free(newesc);
+    if (lastPair)  free(lastPair);
+    if (backSkip)  free(backSkip);
+    if (hashValue) free(hashValue);
+    return err_occured;
+}
+
+#define NO_HEX_CHARACTER       255
+
+//=============================================================================
+// converts hexdigit to number
+//=============================================================================
+unsigned char hex2int(unsigned char c) {
+    c = tolower(c);
+
+    if (c >= 'a' && c <= 'f') return c - 'a' + 10;
+    if (c >= '0' && c <= '9') return c - '0';
+    return NO_HEX_CHARACTER;
+}
+
+
+//=============================================================================
+// converts hex text into binary
+//=============================================================================
+int ConvertText2Bin(unsigned char* ib,int origlen) {
+    int           pos;
+    int           cnt = 0;
+    int           searchforendofline = 0;
+    int           len_after_convert  = 0;
+    unsigned char val;
+    unsigned char actual;
+
+    len_after_convert = 0;
+    for (pos = 0; pos < origlen;pos++) {
+        if (searchforendofline) {
+            if (ib[pos] == '\n') searchforendofline = 0;
+            continue;
+        }
+        if (ib[pos] == '/') {
+            cnt = 0;
+            if (pos < origlen-1 && ib[pos+1] == '/') searchforendofline = 1;
+            continue;
+        }
+
+        actual = hex2int(ib[pos]);
+        if (actual == NO_HEX_CHARACTER) {
+            cnt = 0;
+            continue;
+        }
+        if (cnt == 0) {
+            val = actual*16;
+            cnt++;
+        }
+        else {
+            val += actual;
+            cnt=0;
+            ib[len_after_convert++] = val;
+        }
+    }
+    return(len_after_convert);
+}
+
+
+//=============================================================================
+// as usual: the main, but a long one ...
+//=============================================================================
+#ifndef EMBEDDED_USE
+int main(int argc, char *argv[]) {
+#else
+int TTPack(int argc,char *argv[]) {
+#endif
+    int   startAddr   = 0x258;
+    int   flags       = F_AUTO | F_AUTOEX;
+    int   lzlen       = -1;
+    int   buflen;
+    int   newlen;
+    int   startEscape;
+    int   n;
+    char *fileIn  = NULL;
+    char *fileOut = NULL;
+    FILE *infp;
+
+    unsigned long timeused = clock();
+
+    int   memStart    = 0x801;
+    int   memEnd      = 0x10000;
+    int   type        = 0;
+
+    quiet = 0;
+
+
+    TTPackInit();
+
+
+    lrange    = LRANGE;
+    maxlzlen  = MAXLZLEN;
+    maxrlelen = MAXRLELEN;
+
+    InitValueLen();
+
+    for (n=1; n<argc; n++) {
+        if (!strcmp(argv[n], "-fnorle"))      flags |= F_NORLE;
+        else if (!strcmp(argv[n], "-fdelta")) type  |= FIXF_DLZ;
+        else if (!strcmp(argv[n], "-hti"))    flags |= F_TEXTINPUT;
+        else if (!strcmp(argv[n], "-hto"))    flags |= F_TEXTOUTPUT;
+        else if (!strcmp(argv[n], "-quiet"))  flags &= ~F_VERBOSE, quiet = 1;
+
+        else if (argv[n][0]=='-' || argv[n][0]=='/') {
+            int i = 1;
+            char *val, *tmp, c;
+            long tmpval;
+
+            while (argv[n][i]) {
+                switch (argv[n][i]) {
+
+                case 'n':       /* noopt, no rle/lzlen optimization */
+                    flags |= F_NOOPT;
+                    break;
+
+                case 's':
+                    flags |= F_STATS;
+                    break;
+
+                case 'v':
+                    flags |= F_VERBOSE;
+                    quiet = 0;
+                    break;
+
+                case 'h':
+                case '?':
+                    flags |= F_ERROR;
+                    break;
+
+                case 'r':
+                case 'm':
+                case 'e':
+                case 'p':
+                    c = argv[n][i]; /* Remember the option */
+                    if (argv[n][i+1]) {
+                        val = argv[n]+i+1;
+                    } else if (n+1 < argc) {
+                        val = argv[n+1];
+                        n++;
+                    } else {
+                        flags |= F_ERROR;
+                        break;
+                    }
+
+                    i = strlen(argv[n])-1;
+                    if (*val=='$') tmpval = strtol(val+1, &tmp, 16);
+                    else           tmpval = strtol(val, &tmp, 0);
+
+                    if (*tmp) {
+                        fprintf(stderr,"ERROR: invalid number: \"%s\"\n", val);
+                        flags |= F_ERROR;
+                        break;
+                    }
+
+                    switch (c) {
+                        case 'r':
+                            lzlen = tmpval;
+                            break;
+                        case 'm':
+                            maxGamma = tmpval;
+                            if (maxGamma < 5 || maxGamma > 7) {
+                                fprintf(stderr, "ERROR: Max length must be 5..7!\n");
+                                flags |= F_ERROR;
+                                maxGamma = 7;
+                            }
+                            lrange = LRANGE;
+                            maxlzlen = MAXLZLEN;
+                            maxrlelen = MAXRLELEN;
+                            InitValueLen();
+                            break;
+                        case 'e':
+                            escBits = tmpval;
+                            if (escBits < 0 || escBits > 8) {
+                                fprintf(stderr, "ERROR: Escape bits must be 0..8!\n");
+                                flags |= F_ERROR;
+                            }
+                            else flags &= ~F_AUTO;
+                            escMask = (0xff00>>escBits) & 0xff;
+                            break;
+                        case 'p':
+                            extraLZPosBits = tmpval;
+                            if (extraLZPosBits < 0 || extraLZPosBits > 4) {
+                                fprintf(stderr,"ERROR: Extra LZ-pos bits must be 0..4!\n");
+                                flags |= F_ERROR;
+                            }
+                            else flags &= ~F_AUTOEX;
+                            break;
+                    }
+                    break;
+
+                default:
+                    fprintf(stderr, "ERROR: Unknown option \"%c\"\n",argv[n][i]);
+                    flags |= F_ERROR;
+                }
+                i++;
+            }
+        } else {
+            if (!fileIn) {
+                fileIn = argv[n];
+            }
+            else if (!fileOut) {
+                fileOut = argv[n];
+            }
+            else {
+                fprintf(stderr, "ERROR: Only two filenames wanted!\n");
+                flags |= F_ERROR;
+            }
+        }
+    }
+
+    // input and output file
+    if ((flags & F_ERROR) || !fileIn || !fileOut) {
+#ifndef EMBEDDED_USE
+        PrintUsage();
+#endif
+        return 1;
+    }
+
+#ifndef EMBEDDED_USE
+    if (!quiet) PRINT_ID("TTPack");
+#endif
+
+    if (lzlen == -1) lzlen = DEFAULT_LZLEN;
+
+    if (fileIn) {
+        if (!(infp = fopen(fileIn, "rb"))) {
+            fprintf(stderr, "ERROR: Could not open %s for reading!\n", fileIn);
+            return 1;
+        }
+    }
+    else {
+        fprintf(stderr, "assuming stdin as text input.\nCtrl-C to abort, Ctrl-Z for EOF.\n");
+        infp = stdin;
+    }
+
+    /* Read in the data */
+    inlen  = 0;
+    buflen = 0;
+    indata = NULL;
+    while (1) {
+        if (buflen < inlen + lrange) {
+            unsigned char *tmp = realloc(indata, buflen + lrange);
+            if (!tmp) {
+                free(indata);
+                fprintf(stderr, "ERROR: realloc failed!\n");
+                return 1;
+            }
+            indata = tmp;
+            buflen += lrange;
+        }
+        newlen = fread(indata + inlen, 1, lrange, infp);
+        if (newlen <= 0) break;
+        inlen += newlen;
+    }
+
+    //-----------------------------------------------------------
+    // convert the input buffer from hex text to binary
+    // if the user asks for it
+    //-----------------------------------------------------------
+    if (flags & F_TEXTINPUT) inlen = ConvertText2Bin(indata,inlen);
+
+    if (infp != stdin) fclose(infp);
+
+
+    if (startAddr + inlen -1 > 0xffff) {
+        fprintf(stderr,"ERROR: File is too large to handle (>64936 Bytes)");
+        if (indata) free(indata);
+        return 1;
+    }
+
+    if (flags & F_VERBOSE) {
+        fprintf(stderr, "Load address 0x%04x=%d, Last byte 0x%04x=%d\n",
+                         startAddr, startAddr, startAddr+inlen-1, startAddr+inlen-1);
+        fprintf(stderr, "New load address 0x%04x=%d\n", memStart, memStart);
+    }
+
+    n = PackLz77(lzlen, flags, &startEscape, startAddr + inlen, memEnd, type);
+
+    if (!n) {
+        int endAddr = startAddr + inlen; /* end for uncompressed data */
+
+        if (endAddr - ((outPointer + 255) & ~255) < memStart + 3) {
+            /* would overwrite the decompressor, move a bit upwards */
+            if (flags & F_VERBOSE) fprintf(stderr,"$%x < $%x, decompressor overwrite possible, moving upwards\n",
+                                          endAddr - ((outPointer + 255) & ~255), memStart + 3);
+            endAddr = memStart + 3 + ((outPointer + 255) & ~255);
+        }
+
+        /* 3 bytes reserved for EOF */
+        /* bytes reserved for temporary data expansion (escaped chars) */
+        endAddr += 3 + reservedBytes;
+
+        if (!timesDLz) type &= ~FIXF_DLZ;
+
+        // type      ... may vary
+        // outBuffer ... static global array (65536 Bytes)
+
+        SavePack(flags,type, outBuffer, outPointer, fileOut,
+                 startAddr, startEscape, rleValues,
+                 endAddr, extraLZPosBits,
+                 memStart, memEnd);
+
+        timeused = clock()-timeused;
+        if (!timeused) timeused++;
+        if (flags & F_VERBOSE) fprintf(stderr,
+                                       "Compressed %d bytes in %4.2f seconds (%4.2f kB/sec)\n",
+                                       inlen,
+                                       (double)timeused/CLOCKS_PER_SEC,
+                                       (double)CLOCKS_PER_SEC*inlen/timeused/1024.0);
+        return 0;
+    }
+
+    if (indata) free(indata);
+    return n;
+}
+
+#endif
+
+//#############################################################################
+//###################### NO MORE FAKES BEYOND THIS LINE #######################
+//#############################################################################
+//
+//=============================================================================
+// Revision History
+//=============================================================================
+//
+// Revision 1.8  2002/03/14 10:47:41  tnussb
+// (1) new flag "-quiet" added (suppress standard messages)
+// (2) some error messages rewritten
+//
+// Revision 1.7  2002/03/04 14:32:42  tnussb
+// now tool can be used as embedded version from within other tools
+// by defining EMBEDDED_VERSION before including the sourcefile
+//
+// Revision 1.6  2002/02/07 09:49:37  tnussb
+// all local includes changed, because header files are now located in pctools folder
+//
+// Revision 1.5  2000/11/28 00:07:32  Thomas Nussbaumer
+// using now USAGE_OUT stream for usage info
+//
+// Revision 1.4  2000/08/23 20:10:56  Thomas Nussbaumer
+// header corrected
+//
+// Revision 1.3  2000/08/23 20:10:17  Thomas Nussbaumer
+// adapted to automatic version display (revtools.h)
+//
+// Revision 1.2  2000/08/20 15:30:11  Thomas Nussbaumer
+// minor correction of header
+//
+// Revision 1.1  2000/08/16 23:05:59  Thomas Nussbaumer
+// initial version
+//
+//

+ 49 - 0
tigcc/ttpack/ttversion.h

@@ -0,0 +1,49 @@
+/******************************************************************************
+*
+* project name:    TIGCC Tools Suite
+* file name:       ttversion.h
+* initial date:    13/08/2000
+* author:          thomas.nussbaumer@gmx.net
+* description:     TIGCC Tools Suite version definitions
+*
+******************************************************************************/
+
+/*
+  This file is part of the TIGCC Tools Suite.
+
+  This file is free software; you can redistribute it and/or
+  modify it under the terms of the GNU Lesser General Public
+  License as published by the Free Software Foundation; either
+  version 2.1 of the License, or (at your option) any later version.
+
+  As a special exception, UNMODIFIED copies of some TIGCC Tools Suite utilities
+  may also be redistributed or sold without source code, for any purpose. (The
+  Lesser General Public License restrictions do apply in other respects; for
+  example, they cover modification of the launcher.) Please refer to the main
+  source file for the individual utility as to whether this is the case for a
+  particular tool. This exception notice must be removed on modified copies of
+  this file.
+
+  This program is distributed in the hope that it will be useful,
+  but WITHOUT ANY WARRANTY; without even the implied warranty of
+  MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
+  Lesser General Public License for more details.
+
+  You should have received a copy of the GNU Lesser General Public
+  License along with this library; if not, write to the Free Software
+  Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA  02110-1301  USA
+*/
+
+#ifndef __TTVERSION_H__
+#define __TTVERSION_H__
+
+#define TTV_MAIN   "1.31"
+#define TTV_SUB    ""
+#define USAGE_OUT  stdout
+
+#endif
+
+//#############################################################################
+//###################### NO MORE FAKES BEYOND THIS LINE #######################
+//#############################################################################
+// no revision history for this file (should clear what changes, isn't it?)