2

I recently added support for .scl images files to my Ghidra module which already supported .trd images. They are both representations of TR-DOS floppy disks as used mainly on Spectrum clones from Russia and East Europe.

I found a few sketchy docs for the .scl format but this one on a lost site in the Web Archive is the best.

In all docs I could find the format is:

  • signature
  • 1-byte field (n below) for the number of files on the image
  • n * 14-byte records for the files, of which the byte at offset 13 is the number of sectors
  • x * 256-byte records for disk sectors used by each file in the directory, in order

Very very simple. There's no padding or alignment. It's not even a full image representing all tracks and sectors, just those used by the files. It's a read-only image format. Emulators typically transform an .scl image into a .trd image to use it, which is a full image format.

But when I implemented it I found that the number of bytes I was consuming was not the entire length of the image file. Since some sectors contained repeated garbage between the end of the file data and the end of the sector data I thought I had it all wrong.

Finally I realized I actually did have it right and I could read all the files correctly with my code, but that there really were more bytes in the files after all, than what seemed to be needed according to the docs.

It turned out that all the .scl files I had downloaded had precisely 4 extra bytes at the end. I could not recognize any pattern in the values of the bytes. Trimming the bytes off did not cause any apparent errors loading any of the files from the images into the Fuse Spectrum emulator. New .scl files created by Fuse also have it.

(I did try looking at the Fuse code for .scl files, but I'm no longer that great at perfectly understanding source code in the wild.)

Does anybody know if these four bytes are:

  1. totally spurious?
  2. an optional extension introduced by one emulator but not needed?
  3. actually needed but I missed something in the docs and I'm either missing the error or there is no error and resulting glitches are very subtle and don't happen to cause crashes?

If .scl files are mostly made by the same software, or copy-pasted code from the same source, and cause no ill-effects, then it would make sense.

4

Look carefully at the docs again (Web Archive one).

"The file bodies are stored after the directory entries. Basic program and data array files have an addition at the end of the file."

If it is basic program, there are 4 bytes: 2 fixed values 127,170 and autostart line number 0.. 9999. If it is data array, there are also 4 bytes: 2 fixed values 127,170, 1 byte unused and 1 byte specifying variable.

It is very possible that for other files there are also 4 bytes appended for code simplicity/symmetry.

Edit:

I have looked at Fuse emulator source codes (sourceforge.net/p/fuse-emulator), function write_scl( FILE *file, disk_t *d ) ). It's seems that 4 bytes at end are actualy checksum of all file data. Algorithm is quite simple:

SUM = 597;  /* sum of "SINCLAIR" */
for(b in data) {
  sum += b;
}

and then write sum in big endian order:

 head[0] = sum & 0xff;
 head[1] = ( sum >> 8 ) & 0xff;
 head[2] = ( sum >> 16 ) & 0xff;
 head[3] = ( sum >> 24 ) & 0xff;
 fwrite( head, 4, 1, file ) 
| improve this answer | |
  • Oh I forgot to mention that when typing my question. I was actually aware of them and using them. When I was testing my code I thought I was seeing these footers on each file, and ignoring one in a pevious file would throw out all the subsequent offsets, which I didn't see. But maybe my testing was not thorough so I'll check again and get back to you. Thanks for pointing this out! Oh as file sizes are given in whole sectors, in the case where a file length happens to be the same length as a sector these four bytes require a second sector of data. But I only ever saw 4 extra bytes not 8, 12 etc – hippietrail May 26 at 6:37
  • 1
    I have looked at Fuse emulator source codes (sourceforge.net/p/fuse-emulator/fuse/ci/master/tree/peripherals/… line 2636, write_scl( FILE *file, disk_t *d ) ). It's seems that 4 bytes at end are actualy checksum of all file data. Algorithm is quite simple:SUM = 597; for(b in data) {sum += b;} and at end write sum in big endian order head[0] = sum & 0xff; head[1] = ( sum >> 8 ) & 0xff; head[2] = ( sum >> 16 ) & 0xff; head[3] = ( sum >> 24 ) & 0xff; fwrite( head, 4, 1, file ) – ufok May 26 at 8:25
  • Oh great stuff! I did check all my SCL files and I was seeing all the 4-byte file footers inside the declared file lengths and the footer size was a constant 4 bytes irregardless of the number of files included that would or wouldn't each have footers. If you update your answer I will accept it as the correct answer. Searching specifically for checksums relating to this I found confirmation on a Russian Spectrum hacking site: +? (04) - 4-byte Checksum (sum of all previous bytes SCL file.) – hippietrail May 26 at 8:33

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service, privacy policy and cookie policy

Not the answer you're looking for? Browse other questions tagged or ask your own question.