*** LNX (LyNX containers) *** Document revision: 1.3 *** Last updated: March 11, 2004 *** Compiler/Editor: Peter Schepers *** Contributors/sources: Marko Makela C= Software that handles this type: LyNX 'LING'X UTILITY (Ultimate Lynx) - Create/Dissolve LNX hybrid archive OMEGA-Q II (Dissovle only) 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" ":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 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 . 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