Version 1.0; 10-SEP-2018.
With the introduction of new tools for the development of Commodore 64 art on modern systems, there has arisen a need for a universal standard image format for the storing and transferring of Commodore image formats between programs, including original hardware.
This specification proposes just such a format that is simple to understand, simple to parse -- even on original hardware -- and simple to implement.
Unlike modern image formats where the image is composed of pixels, a Commodore image can consist of multiple separate layers of different format, including text-characters (PETSCII), separate colour data and global colour such as the foreground / background colour.
Therefore a format is needed that can store the individual parts of an image, but also leave irrelevant parts out.
The file extension is ".pet"
The PET file format consists of blocks of data split into 254-byte "sectors". This is done to make reading on original hardware very simple, where a disk sector is exactly 254 bytes. A parser can read and process the file a sector at a time and not have to seek backward or forward.
The last sector in a PET file can be truncated, that is have no padding bytes to fill a full sector. All sectors other than last must, of course, be a full 254 bytes. Unused space within a sector should be zero-filled.
The first block of data is the meta-data block and consists of 1 sector (254-bytes). It stores various image meta-data and properties.
The first four bytes of the meta-data block (and therefore, the file itself) form the "magic number" used to identify a PET file. The four bytes are the characters "PET" and a version number character all in PETSCII; that is, the first four bytes of a file (in hexadecimal) will be:
$50 ("P"), $45 ("E"), $54 ("T"), $31 ("1")
This version number of "1" will only be changed should the file format change to an encoding that would be incompatible with the "version 1" specification.
If your program encounters a version number that is not "1" (in PETSCII), it should not parse the file any further!
Immediately following the "PET1" magic-number is the meta-data table. This table consists of a set of names and values, each entry in the meta-data table consists of 8 bytes.
The table ends when you come across a name consisting of four nulls (0, 0, 0, 0). A further four bytes exist (reserved for future use), like any other entry, but these have no defined value. Your parser should skip over these when reading, and write four zeroes when writing a file. I.e., you should not preserve these bytes if your parser does not understand them.
-
The first 4 bytes are a name; see the headings on each different name
-
The next four bytes depend upon the name, see below
If the meta-data table contains no entries other than the terminator (0, 0, 0, 0), the file is still considered "valid", but you should stop parsing and inform the user that the file "contains no image data".
The meta-data names allowed are as follows:
Allows embedding an author's name.
The 4 name bytes used are "AUTH" ($41, $55, $54, $48
). The next one byte gives an offset in bytes from the beginning of the sector to some PETSCII text stored anywhere within the sector.
If multiple such meta-data ID entries exist, consider this to mean more than one author
"TITL" ($54, $49, $54, $45
): Title; PETSCII text. A title for the image
"DATE" ($44, $41, $54, $45
): Date-time for the image; PETSCII numerals:
...
"DESC" ($44, $45, $52, $43
): Description; PETSCII text. A long form description of the image
"EDIT" ($45, $44, $49, $54
): Editor; PETSCII text. The editor used to produce the image, e.g. "PETMATE"
...
...
First, here, I also wrote a primitive viewer, for this format. Granted, it's calling C64 OS routines, but that's the point. The routines decrease the amount of code necessary to get something done. To write a similar viewer for the bare KERNAL rom you'd have to actually write out the 16-bit loops for reading in the two blocks of 1000 bytes.
https://gist.github.com/gnacu/c5ad52836290c925a93a707a77c7662e
Ignoring the meta data, because, that's a valid thing to do, this viewer program is just 89 bytes, including validation of the magic and version number.
Next, to answer your question: "the format you describe leaves absolutely no room for expansion at all"
PETSCII images have been structured exactly the same way for almost 40 years. The machine is small. The world is simple. That's half the fun. And, if you're looking for future expandability, that's the point of the version number. If at some future date a significant interest in a few additional fields (or the ability to specify different screen resolutions, etc) comes about, then release a version 2 of the spec.
Look at this page: http://codebase64.org/doku.php?id=base:c64_grafix_files_specs_list_v0.03
It lists ~41 (I may have miscounted) C64 bitmapped image formats. (PETSCII art is not among them.) They are all as simple, perhaps simpler, than the format I propose. A PETSCII image file format should look at home on that page, alongside those other formats.
I was able to write both a creator and a viewer, in a matter of an hour, for my proposed format. You do the same, and then if it's easy and simple to implement with a reasonably small code footprint, then at least you have an argument that it's a good and suitable format for the platform.
Oh, before I forget. Thinking about sectors, and how they're 254 byte chunks, is not useful in my opinion. The KERNAL has no special support for loading in 254 byte chunks, nor for skipping over unnecessary sectors. If you take a 16 byte string field, and align it but ultimately let it sit inside its own entire 254 byte sector, you'll waste a huge amount of space on disk, and you'll force the user to load in gobs of empty space from the disk, over a very slow bus. You can only profit from sector layout tricks (like GEOS does with its VLIR format) if you marry yourself to the 1541 and write your code to send special commands to its DOS. It's 2018, SD2IEC is very popular. So, that's a bad idea.