Understanding the Atari DOS 2 File Format
90K per disk
In ANALOG Computing Issue 8, Tony Messina writes about the DOS disk format in his Utility column. In this column he discusses the DOS disk format, focusing on the data, directory and boot sectors.
I loved reading about this again to refresh my memory on how this all worked. Atari single-sided disks held just 90K. There were 720 sectors, each 128 bytes in length. That totals 92,160 bytes, which is not much at all by today’s standards.
So let’s talk a bit about the directory sectors, which consist of the sectors from 361 to 368.
Each directory sector can contain a directory entry that is 16 bytes, organized as follows:
Byte 0: Status bits that are divided into these bits:
Bit 0: File open for output
Bit 1: DOS 2 file
Bit 2: Unused
Bit 3: File in use
Bit 4: Unused
Bit 5: File is locked
Bit 6: File in use
Bit 7: File deleted
Bytes 1-2: Length of file (Little Endian)
Bytes 3-4: Start sector of file (Little Endian)
Bytes 5-12: The name of the file.
Bytes 13-15: The file extension.
Overall, this is a pretty simple format. With 16 bytes per entry that means there can be 8 entries per directory sector. And since there are only 8 directory sectors that means there is a maximum of 64 files per disk (and there is no such thing as subdirectories).
Many Atari disks are available today as ATR files, which are a data dump (92,176 bytes) of an actual floppy’s data with a 16-byte header. It occurred to me that I could make a small app to display the files on an ATR disk image using the above information.
And so I did. Here is the app showing the directory of one of my disks:
I built this using Xojo because I work there and it’s great for tools like this
. The main bit of Xojo code is this:Var diskFile As FolderItem
diskFile = FolderItem.ShowOpenFileDialog("")
If diskFile = Nil Then Return
Var Input As BinaryStream
Var diskData As MemoryBlock
input = BinaryStream.Open(diskFile)
Var rawSectors() As String
rawSectors.Add("")
Var header As String
If diskFile.Name.Right(3) = "atr" Then
// This is an ATR disk, so read in its header
If Not input.EndOfFile Then
header = input.Read(16)
End If
End If
While Not input.EndOfFile
rawSectors.Add(input.Read(128))
Wend
input.Close
For dir As Integer = 361 To 368
Var dirSectorData As MemoryBlock
dirSectorData = rawSectors(dir)
// There are 8 directory entries per sector, each 16 bytes
For i As Integer = 0 To 7
Var entry As MemoryBlock
entry = dirSectorData.MidB(i * 16, 16)
Var status As Integer = entry.Int8Value(0)
If status <> 0 Then
Var length As Integer = entry.Int16Value(1)
Var start As Integer = entry.Int16Value(3)
Var name As String = entry.StringValue(5, 8).Trim
Var ext As String = entry.StringValue(13, 3).Trim
DirectoryList.AddRow(name + "." + ext, length.ToString)
End If
Next
Next
Currently this app only shows you the names and size (in sectors) of the files on the disk image. I want to improve it by moving this all into classes, actually use the header to get the disk sector size and also use the Start sector of the file to export the selected file off the disk.
You can download the app to give it a try with your own ATR files.
Xojo is a cross-platform development tool that can make apps for Windows, macOS, Linux, web, iOS (with Android in testing).
That’s a nice any easy use of XOJO. Maybe it could be expanded to allow not only file to be exported but move to another ATR to make your own disk image. Also it would be good to capture the file names, size and disk ID and store in a SQLite database to make it easy to fine you favourite game or utility. Gives me some ideas. Good work Paul.