How to use direct block access commands in Commodore DOS

Commodore-Logo-PaddedWe can access each sector’s raw data on Commodore disk drives with direct block access commands. Supported drives include the 1541, 1571, the VICE emulator as well as the SD2IEC card reader (for the most part).

Each single sided floppy contains 35 sectors, while a double sided 1571 formatted disk contains 70 sectors. Each track contains between 17 and 21 sectors depending on how far inside or outside they are. Each sector contains 255 bytes we can read or write.

Sectors are the same as blocks: only the directory refers to them as “blocks” and shows us how many we have available.

We’ll need to open two channels to our disk drives: a command channel and a data channel. Here’s how to do it:

Writing data to a sector

115 input "message to write";a$
120 input "track to write";t
130 input "sector to write";s
140 open 15,8,15
150 open 5,8,5,"#"
160 print#5,a$
170 print#15,"u2";5;0;t;s
180 close 15:close 5
190 end

In this little app we’ll ask the user to type a message (no special characters like commas please) that we want to write to a specific track and sector. Next we’ll open the command channel (15) and a data channel (5). We need to specify that we’d like to use a direct access commands by printing a # symbol first, then we’ll deliver our data using PRINT#.

Once delivered, we’ll issue a U2 command (a simpler version of B-W or BLOCK-WRITE) with track and sector information to write our data to the disk. We can deliver up to 255 characters this way.

Reading data from a sector

To read our data back, we’ll do something like this:

120 input "track to read";t
130 input "sector to read";s
140 open 15,8,15
150 open 5,8,5,"#"
160 print#15,"u1";5;0;t;s
170 for i=1  to 20
180 get#5,a$:if a$="" then a$=chr$(0)
190 print a$
200 next
210 close 5:close 15

Much like before, we’ll ask the user to provide which track and sector we want to read raw data from. We’ll open the command channel and a data channel, issuing # again to let the drive know that we want to use direct access commands. Then we’ll use the U1 command with track and sector information to make the drive read our data (U1 is a simplified version of B-R or BLOCK-READ).

In this app I’m only reading the first 20 characters from the sector using GET#. INPUT# can be used, although this may lead to errors due to errors when special characters are in a sector. We can read up to 255 characters this way.

Marking blocks as allocated

When we write arbitrary data to a floppy, we must be cautious not to overwrite data that already exists. For example, writing arbitrary data to track 18 would destroy the floppy’s directory.

Likewise, we need to tell the CBM DOS that certain sectors should not be used if we’ve written data to such sectors, otherwise it will be overwritten by standard save operations. This is where another direct access command comes in: BLOCK-ALLOCATE, or B-A.

Here’s how it works:

10 input "track to allocate";t
20 input "sector to allocate";s
30 open 15,8,15
40 print#15,"b-a";8;t;s
50 close 15
60 print "consider it done!"

Here we use only the command channel to issue the B-A command, asking the DOS to mark said sector as “in use”. As a result it won’t be overwritten by a standard save operation. Note that in line 40, we need to specify the drive address rather than the channel number, together with the track and sector information.

If you display the floppy’s directory before and after this command, you’ll notice that each time a sector is marked as allocated, one less free block appears at the bottom.

Marking blocks as free

The opposite of allocating blocks is to free them up again, or in other words, let the DOS know that such sectors can be used to store data by standard save operations. For that we can use the B-F or BLOCK-FREE command.

Here’s how:

10 input "track to free up";t
20 input "sector to free up";s
30 open 15,8,15
40 print#15,"b-f";8;t;s
50 close 15
60 print "consider it done!"

All parameters work the same as B-A. If you free up a sector and display the floppy’s directory, you’ll notice an additional free block at the bottom of the list.

Special SD2IEC considerations

Note that the B-A and B-F commands only work with real floppy drives as well as the VICE emulator. They are not supported on the SD2IEC card reader (although the B-R and B-W commands work fine when a disk image is mounted).

Just thought I’d mention it.

How many sectors are in each track of a CBM DOS disk?

Very good question! Tracks on the outside of the disk have more sectors (or blocks) than those on the inside of a disk. That’s because there’s a bigger magnetic surface area on the outside than on the inside, so more sectors can be crammed in.

Here’s how Commodore have split those tracks into sectors on 1541 formatted GCR disks:

  • Tracks 1-17: 21 sectors (0-21)
  • Tracks 18-24: 19 sectors (0-18)
  • Tracks 25-30: 18 sectors (0-17)
  • Tracks 31-35: 17 sectors (0-16)

On 1571 formatted GCR disks, we also have the second side of the disk available:

  • Tracks 36-52: 21 sectors (0-21)
  • Tracks 53-59: 19 sectors (0-18)
  • Tracks 60-65: 18 sectors (0-17)
  • Tracks 66-70: 17 sectors (0-16)

If you ever try to access a sector that does not exist, you’ll receive an error 66, “Illegal track or sector”.

You can leave a comment on my original post.