Re: Commodore 15 Second disk format routine disassembled

From: Dave McMurtrie <cbm-hackers_at_commodore.international>
Date: Mon, 13 Apr 2026 17:36:19 -0400
Message-Id: <e27fec9f-6b99-4a7c-a11d-0863cc25ac52_at_app.fastmail.com>
Hi Spiro,

I'm the person who uploaded the 15 second format disassembly to GitHub, and was happy to see your reply. I have a few questions:

> First: The routines I disassembled never tried to measure the track
> length. They just wrote was worked for them. This approach can work if
> your gaps are conservative enough, that is, rather shorter than longer.

I'm curious why shorter is better. It looks like in practice, Commodore DOS 2.6 calculates a value around 7-8 bytes for the outer tracks, then 12 or so bytes for the inner tracks. From "Inside Commodore DOS" page 34: "The gap is designed to be long enough so that if you write a data block on a day when your drive is turning slightly faster than 300 rpm, you won't overwrite the start of the next sector." This also indicates too long is preferred over too short. It seems like it's more risky to have a too-short gap value than too-long.

15 second format uses a hard-coded GAP2 value of 8 bytes for all 35 tracks. I feel as though this could be fraught with peril, but it appears to work.

I'd love to hear your thoughts on this.

> 2. To write the track, first clear a memory on the track (overwritten
>    with $55) that can be used to later measure the last GAP.

Commodore DOS 2.6 does this -- it writes a full track of $55 gap bytes before it starts writing sectors. 15 second format skips this. With the CBM DOS version, the leftover space after the last sector and inter-sector gap have been written, whatever is left over between the last sector and the first sector will be the previously written $55 gap bytes. I'd guess the 15 second format routine could risk that leftover space containing a valid sync mark and header/data block data if formatting a previously used disk.

I look forward to your reply.

Thanks!

Dave


----- Original message -----
From: Spiro Trikaliotis <ml-cbmhackers_at_trikaliotis.net>
To: cbm-hackers_at_musoftware.de
Subject: Re: Commodore 15 Second disk format routine disassembled
Date: Sunday, April 12, 2026 4:33 AM

Hello,

* On Sat, Apr 11, 2026 at 10:50:07AM +0200 André Fachat wrote:
> 
> Am 11. April 2026 10:41:54 schrieb Francesco Messineo
> 
> I think all the routines do away with the verify. What my routine - IIRC - also
> removed was the measurement of the drive speed and thus track length in bytes
> that the original does (every track?). That's probably why it failed on other
> drives.
> 
> My guess is, without having looked at the code yet, that the working routine
> measures it on the first track and then just calculates the gaps for all the
> other tracks.

as I have worked on a fast formatter years later, I can also add to it.

First: The routines I disassembled never tried to measure the track
length. They just wrote was worked for them. This approach can work if
your gaps are conservative enough, that is, rather shorter than longer.

For cbmformat
https://github.com/OpenCBM/OpenCBM/tree/master/opencbm/cbmformat (and,
later, https://github.com/OpenCBM/OpenCBM/tree/master/opencbm/cbmforng),
WoMo and I used something that we *believe* no other used (but we may be
wrong).

From memory:

1. First, write track 1 with a pre-defined gap. For reasons given below,
   this GAP is very conservative, that is, it should be shorter than
   needed, but not longer under any circumstances!

2. To write the track, first clear a memory on the track (overwritten
   with $55) that can be used to later measure the last GAP.

3. Then, start writing all sectors with the known GAP

4. After we switched back to read, measure the number of GCR byte we
   read before the next SYNC comes.
   If the number of byte is "in the range of" the the GAP we have
   used, the GAP seems to be correct. Calculate how much to increate the
   GAP from the number of byte, and re-start with step 2

5. Now, check if the next SYNC introduces the block header of sector
   0 of the track. If not, the write failed. That is, the GAP was too
   long!

   As we do not know how much too long, we shorten the GAP very
   aggressively (IIRC, we half it) and retry formatting this track
   (step 2)

6. If it succedded (and no verify was demanded by the user on the
   command-line), we change to the next track. If we change the speed
   zone with this, we adjust the GAP with given differences we have
   pre-calculated.

   If the last track was done, we are done. Otherwise, repeat with step
   2 for the new track

 
What came out of it:

1. The first track almost always needs 2 round in order to format it.
    That's because the GAP is very conservative.

2. If the GAP is too large, we have to take 3 rounds: First, we write
   the track which is too long. As we do not know how much too long, we
   halve the GAP and try again. As this try is almost always too short,
   we need the 3rd try with the right GAP.

   That's why the first assumed GAP in step 1 is so conservative.

3. This scheme works very reliably in general with 1541-II and 1571
   drives (which are direct driven). The 1541-I is a little bit more
   problematic and needs the one or the other extra round in some cases.
   That's why the test for the remaining bytes in step 4 has to be "in
   the range of" the GAP. The 1541 needs a much more relaxed check, or
   chances are it will never succeed.

4. We found a strange mystery: Using our approach, step 5 failed every
   now and then. Debugging it, we found that it was written correctly.
   However, the test "thought" it was wrong.
   Inverstigating into it, we found that this problem occurs if we
   generate an empty data block of $00/$00/$00 (like the 2031, 4040 and
   early 154x drives used. If we change this pattern to $00/$01/$01/...
   (first track) and $4B/$01/$01/... (all other tracks) like the 1541
   and later do it, this problem did not appear that often anymore!

   We even took this here to cbm-hackers:
   https://www.softwolves.com/arkiv/cbm-hackers/10/10471.html
   We assumed (but could never proove) that the drive has a problem
   when reading data immediately after switching from writing to
   reading, that it needs some time to settle.

5. The 1571 and 1541-II had other mysteries I do not remember
   completely. ;)

6. For direct driven drives, this schemes resulted in almost always
   needing 1 extra rotation for the first track only, but not more. The
   belt-driven 1541 is special, it takes an extra rotation every now and
   then, but we could reduce this considerably.

7. Of course, we need a little bit more than 1 rotation for writing
   because we wait for the next SYNC block and read it to find out if
   the GAP was right.

8. To be really reliable, we need the verification step, thus, we need 2
   rotations per track.
   Note that while analyzing it, we found out that the original 1541
   format routine also has a bug in which it will not recognize a
   specific type of error. I would have to look it up to find out what
   the problem was, I do not remember the details.

Regards,
Spiro

-- 
https://spiro.trikaliotis.net/



-- 
Dave McMurtrie
www.commodore.international
Received on 2026-04-13 22:36:19

Archive generated by hypermail 2.4.0.