*** 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
|