mirror of
https://github.com/aaru-dps/docs.git
synced 2025-12-16 11:14:37 +00:00
227 lines
11 KiB
Plaintext
227 lines
11 KiB
Plaintext
|
||
*** LNX (LyNX containers)
|
||
*** Document revision: 1.3
|
||
*** Last updated: March 11, 2004
|
||
*** Compiler/Editor: Peter Schepers
|
||
*** 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
|
||
|