*** LNX (LyNX containers)
*** Document revision: 1.3
*** Last updated: March 11, 2004
*** Contributors/sources: Marko Makela

  Written by Will Corley (and subsequently cloned  and  rewritten  by  many
others like "Willie" or "S.B."'s "Ultimate Lynx"), this format is  designed
around the sector size of the 1541. It consists of  "blocks"  of  254  bytes
each (256 if we are on a real 1541 or a D64 due to  the  inclusion  of  the
track/sector info at the beginning of each sector).

  One word of warning: the  Lynx  utility  "Ultimate  Lynx"  can  sometimes
create LNX containers which do *not* have the sector data block-aligned  to
254-byte boundaries. If they are not aligned, the  files  contained  within
will be corrupt when extracted.

  When these files  are  on  *any*  other  format  they  do  not  have  the
track/sector info, and therefore use only 254 bytes/block. Here is  a  dump
of the directory header of one permutation of the layout...

      00 01 02 03 04 05 06 07 08 09 0A 0B 0C 0D 0E 0F        ASCII
      -----------------------------------------------   ----------------
0000: 01 08 5B 08 0A 00 97 35 33 32 38 30 2C 30 3A 97   ..[.???53280,0:?
0010: 35 33 32 38 31 2C 30 3A 97 36 34 36 2C C2 28 31   53281,0:?646,+(1
0020: 36 32 29 3A 99 22 93 11 11 11 11 11 11 11 11 22   62):?"?........"
0030: 3A 99 22 20 20 20 20 20 55 53 45 20 4C 59 4E 58   :?"?????USE?LYNX
0040: 20 54 4F 20 44 49 53 53 4F 4C 56 45 20 54 48 49   ?TO?DISSOLVE?THI
0050: 53 20 46 49 4C 45 22 3A 89 31 30 00 00 00 0D 20   S?FILE":?10???.?
0060: 31 20 20 2A 4C 59 4E 58 20 58 56 20 20 42 59 20   1??*LYNX?XV??BY?
0070: 57 49 4C 4C 20 43 4F 52 4C 45 59 0D 20 34 20 0D   WILL?CORLEY.?4?.
0080: 34 21 5A 4F 4E 45 20 4F 46 20 44 2D 2F 41 56 54   4!ZONE?OF?D-/AVT
0090: 0D 20 37 31 20 0D 50 0D 20 31 36 30 20 0D 31 21   .?71?.P.?160?.1!
00A0: 5A 4F 4E 45 20 4F 46 20 44 2D 2F 41 56 54 0D 20   ZONE?OF?D-/AVT.?
00B0: 37 35 20 0D 50 0D 20 31 35 31 20 0D 32 21 5A 4F   75?.P.?151?.2!ZO
00C0: 4E 45 20 4F 46 20 44 2D 2F 41 56 54 0D 20 31 37   NE?OF?D-/AVT.?17
00D0: 30 20 0D 50 0D 20 32 34 39 20 0D 33 21 5A 4F 4E   0?.P.?249?.3!ZON
00E0: 45 20 4F 46 20 44 2D 2F 41 56 54 0D 20 31 35 38   E?OF?D-/AVT.?158
00F0: 20 0D 50 0D 20 31 33 38 20 0D 00 00 00 00 00 04   ?.P..138?.??????
0100: 1A 00 1A 08 05 08 E0 00 FF C2 0D 85 0F 04 39 03   .?....???++?..9.

  It starts out with a BASIC program which, when loaded and  run,  displays
the message "Use LYNX to dissolve this file". The actual message  and  size
of the program can change. Usually, its 94 bytes long, from $0000 to $005D.

10 POKE53280,0:POKE53281,0:POKE646,PEEK(162):PRINT"<CLS><DOWN><DOWN><DOWN>
   <DOWN><DOWN><DOWN><DOWN><DOWN>":PRINT"     USE LYNX TO DISSOLVE THIS
   FILE":GOTO10

      00 01 02 03 04 05 06 07 08 09 0A 0B 0C 0D 0E 0F        ASCII
      -----------------------------------------------   ----------------
0000: 01 08 5B 08 0A 00 97 35 33 32 38 30 2C 30 3A 97   ..[.???53280,0:?
0010: 35 33 32 38 31 2C 30 3A 97 36 34 36 2C C2 28 31   53281,0:?646,+(1
0020: 36 32 29 3A 99 22 93 11 11 11 11 11 11 11 11 22   62):?"?........"
0030: 3A 99 22 20 20 20 20 20 55 53 45 20 4C 59 4E 58   :?"?????USE?LYNX
0040: 20 54 4F 20 44 49 53 53 4F 4C 56 45 20 54 48 49   ?TO?DISSOLVE?THI
0050: 53 20 46 49 4C 45 22 3A 89 31 30 00 00 00 .. ..   S?FILE":?10???..

  Following this is the "signature" of the container, as well as  the  size
of the directory (in blocks) and the number of  directory  entries  in  the
container. These are stored in CBM lower case (ASCII for the most part), it
is delimited by <CR> after each entry (except the directory  block  size!),
and has spaces on both sides of the numbers. Normally  the  signature  will
contain the string "LYNX" somewhere.

  You will note that the numbers (and filetype)  stored  in  both  the  LNX
signature and the directory entries are unusual in that they are stored  in
ASCII, not binary (like the D64 entries). The  only  explanation  for  this
seems to be that the utilities used on the C64 to create  them  were  using
the INPUT# and PRINT# routines. These will  store  numbers  as  ASCII,  not
binary, and will truncate with a <CR>.

0050: .. .. .. .. .. .. .. .. .. .. .. .. .. .. 0D 20   ................
0060: 31 20 20 2A 4C 59 4E 58 20 58 56 20 20 42 59 20   1??*LYNX?XV??BY?
0070: 57 49 4C 4C 20 43 4F 52 4C 45 59 0D 20 34 20 0D   WILL?CORLEY.?4?.

  Note:  some  files  have  been  found  which  do  *NOT*  conform  to  the
established LNX header/directory structure.  They  do  not  contain  spaces
after the numbers in the directories, or contain extra spaces  in  the  LNX
header. Such files might give trouble Un-Lynxing on a real C64, and they do
not appear to have been created by Will Corley's standard "LyNX" program.

  So in the above example, we have a directory of 1 block (254 bytes) long,
the file was created by "LYNX XV BY WILL CORLEY", and we have 4 entries  in
the directory. The total directory length is 1 block * 254 bytes=254 bytes.
Therefore at byte $00FE, the program data will start. If the directory size
was 3 blocks, the data would start at $02FA. I do not know what the maximum
size is for either number (dir size/entry total), but it would seem  to  be
that since the 1541 only can  store  144  files,  these  numbers  would  be
limited accordingly.

0080: 34 21 5A 4F 4E 45 20 4F 46 20 44 2D 2F 41 56 54   4!ZONE?OF?D-/AVT
0090: 0D 20 37 31 20 0D 50 0D 20 31 36 30 20 0D .. ..   .?71?.P.?160?...

  This is the first directory entry called "4!ZONE OF D-/AVT".  The  layout
has the filename  (in  PETASCII,  typically  padded  to  16  characters  by
shifted-spaces), followed by the size of the file in blocks of  254  bytes,
the file type (P, S, R, U), and the LSU byte (see "INTRO.TXT" document  for
description of "LSU")

  If the file type is REL, this entry is the  RECORD  size,  and  the  next
entry is the last block size. If the file type is not REL, the  next  entry
will be the next filename.

0090: .. .. .. .. .. .. .. .. .. .. .. .. .. .. 31 21   ..............1!
00A0: 5A 4F 4E 45 20 4F 46 20 44 2D 2F 41 56 54 0D 20   ZONE?OF?D-/AVT.?
00B0: 37 35 20 0D 50 0D 20 31 35 31 20 0D .. .. .. ..   75?.P.?151?.....

This is the second directory entry. It  follows  the  same  layout  as  the
first.

00B0: .. .. .. .. .. .. .. .. .. .. .. .. 32 21 5A 4F   ............2!ZO
00C0: 4E 45 20 4F 46 20 44 2D 2F 41 56 54 0D 20 31 37   NE?OF?D-/AVT.?17
00D0: 30 20 0D 50 0D 20 32 34 39 20 0D 33 21 5A 4F 4E   0?.P.?249?.3!ZON
00E0: 45 20 4F 46 20 44 2D 2F 41 56 54 0D 20 31 35 38   E?OF?D-/AVT.?158
00F0: 20 0D 50 0D 20 31 33 38 20 0D .. .. .. .. .. ..   ?.P.?138?.......

This is the third and fourth entry.

00F0: .. .. .. .. .. .. .. .. .. .. 00 00 00 00 .. ..   ..........????..

  The remaining bytes are unused, and exist simply as  filler  to  pad  the
directory so as it takes up to its alloted space (recall it is one block of
254 bytes). Once the directory has ended,  the  real  file  information  is
stored. Since in this example the directory is only 1 block long, the  file
info starts at byte $00FE...

00F0: .. .. .. .. .. .. .. .. .. .. .. .. .. .. 00 04   ..............?.
0100: 1A 00 1A 08 05 08 E0 00 FF C2 0D 85 0F 04 39 03   .?....???+.?..9.

  The files are also stored so that they take up the full multiples of  254
bytes. This does result in a little dead space at  the  end  of  each  file
stored, but its a small price to pay for how easy it is  to  construct  and
break up files on a real C64.

  When an LNX file is created, a new file is created on the disk containing
all the necessary information about the files it is going to  contain  such
as  the  BASIC  program,  signature  and  central  directory.  The   header
track/sector link is then pointed to the beginning of the first  file.  The
last sector track/sector link of the first file  is  then  pointed  to  the
start of the second file and so on, until the  last  file  is  added.  This
method makes creating LNX's very quick!

  The advantage to this method is that *no* files are moved or  compressed,
they are simply "linked" together by changing the t/s links to  create  one
large file (hence the name LNX).

  REL file entries are a little more special. The first blocks of the  file
contain the side sector info, followed by  normal  program/data.  The  only
usefulness in containing this side-sector info is so that you don't have to
allocate them after extracting the file, but just change the t/s  links  to
point to the new records.

  One disadvantage to its use on the PC is the lack of a  better  laid  out
central directory, one that had the same number  of  bytes  used  for  each
entry, like the D64, T64, or ARK, and had a user-definable directory  size,
also like the D64/T64. That makes it difficult to add files to an  existing
container on a PC, but 64COPY and Star  Commander  can  add/delete  to  LNX
files.

---------------------------------------------------------------------------

What it takes to support LNX:

  There are many good points to the LNX format,  making  it  only  somewhat
difficult to support. LNX files contain a signature, have a  provision  for
multi-block directories, the files and directory are block-aligned  to  254
byte boundaries, REL files are handled, and you can  store  more  than  144
files (if you want to).

  There is one bad point to LNX files and that is the individual  directory
entry size is not set (like D64's 32 bytes). They are stored in ASCII (like
LBR format), making the entry size  variable.  This  makes  adding/deleting
files difficult in that the directory has to be re-written quite a bit.

  One other bad thing that has developed over time is that many people have
written their own "lynxing" programs, and have deviated from  the  standard
layout. There are many styles of LNX files, earlier versions being somewhat
different from the later ones, but more importantly is there are LNX  files
which don't work with the normal "Will Corley" unLYNXing utilities.

---------------------------------------------------------------------------

Overall Good/Bad of LNX Files:

  Good
  ----
  * Supports the standard 16-char filename,

  * Filenames padded with the standard $A0 character

  * Allows for directory customization, as zero-length files are allowed

  * Expandable central directory

  * Supports REL files

  * It is a very well established file format, many utilities available  to
    work with them

  * Has a file signature

  * Filenames can have 00's in them(?)



  Bad
  ---
  * There are too  many  LNX  programs  out  there,  too  many  LNX  header
    variations, and not all of the utilities make compatible LNX containers

  * Has a very badly laid-out header (ASCII,  not  binary  byte  oriented).
    Each directory entry has a variable length

  * It is not easy to re-write the header and central directory. With  file
    additions/deletions, it is *usually* necessary to re-write  the  entire
    file

  * Since files are stored in block sizes of 254-bytes,  each  stored  file
    usually has some extra lost space

  * Can't store special file attribute bits

  * Does not store GEOS