How to identify an unknown disk using Fdutils

Introduction

This howto document describes how to read disks with non-standard low level formats using fdutils. It applies to disk which use different sector sizes, non standard densities, a different number of cylindrers (CP/M disks, Commodore disks). It does not apply to disks which merely have a different filesystem (high level format).

The most useful program for exploring disks is fdrawcmd. It allows to issue raw floppy controller commands. I recommend that you use the most recent fdutils (5.2) with the most recent patch (2805), as some earlyer versions may have bugs which make some of the following tests fail without reason.

Finding out the data transfer rate

First, you need to find out the data transfer rate (roughly the density: high, double, single).

For this, you try out fdrawcmd readid 0 rate=x, where x is 0, 1, 2, 3 If no rate is supplied, fdrawcmd assumes rate=0

Example:
> fdrawcmd readid 0 rate=0 need_seek track=0
0: 0
1: 0
2: 0
3: 0
4: 0
5: 1
6: 2
disk change

The first 3 output bytes are error codes. The first byte should be below 7 (i.e. the example above succeeded). The last four bytes is a sector header. Byte 3 is the cylinder (here: 0), byte 4 is the head (here: 0). Byte 5 is the sector number (here: 1) of the sector which happened to be near the R/W head when the command was issued. Byte 6 is the sector size code. Size code 0 means 128 bytes per sector, size code 1 means 256 bytes per sector, size code 2 means 512 bytes per sector, etc (i.e. size doubles with each increment).

So, you try out all 4 rates until you get one that succeeds (byte 0 <= 7). If none matches, try adding the FM keyword (to use FM coding instead of MFM).

Example:
fdrawcmd readid 0 rate=0 fm need_seek track=0

If none of the eight combinations (4 rates with fm, 4 rates without fm) doesn't work, then the disk probably is not readable on PC hardware. Remember: the controller plays a role that is as important, if not more, than the drive. So the fact that a device uses a normal PC drive is not necessarily indicative that disks written by that device can be read on a PC.

On the other hand, if one combination matches, we have some good chance to get at the contents of that disk. Use the same fm/rate combination with all fdrawcmd's shown below.

Finding out the number of sides (heads)

Next we have to find out if the disk is double sided or single sided:
> fdrawcmd readid 4 rate=x fm need_seek track=0
The 4 means to check the other head. If you get output such as the following, then it is ok:
> fdrawcmd readid 4 rate=0 need_seek track=0
0: 4
1: 0
2: 0
3: 0
4: 1
5: 2
6: 2
disk change
If byte 4 is greater than 7, we have an error, and the disk is probably single sided. However, there are some weird formats in existence which use a different density at the second side and on the following cylinders. So, in case of failure, it might be worthwhile to try out all 8 combinations too.

Finding out how many cylinders there are, and how they are spaced

Next, let's find out whether cylinders are doublespaced or not. Especially, on older drives, the head had to be moved by two physical cylinders instead of 1 logical cylinder.

For this, seek to physical cylinder 2, and do again a readid.

> fdrawcmd readid 4 rate=0 need_seek track=2
0: 4
1: 0
2: 0
3: 2
4: 1
5: 7
6: 2
no disk change

Carefully watch byte 3 (logical cylinder). If this is 1, then we have a disk with only one logical track per two physical tracks. This is for instance the case with double density 5 1/4 disks. If on the other hand byte 3 is 2, then we have a normal disk, where one logical track corresponds exactly to one physical track. Let's call this a disk with doublespaced tracks.

Again, if byte 0 is greater than 7, we have an error. A different density might be used on track 2 and it might be worthwhile to try out all 8 rate/fm combinations.

Same exercise with the number of cylinders. Seek to track 81, 80, 79, 78, 77 until you can read the track. Use the rate/fm combination from track 2: no nead to try out all 8 combinations here, it is very rare that density changes again after the first track. N.B. If you have a disk with double spaced tracks, try only the even numbers:
> fdrawcmd readid 4 rate=0 need_seek track=78
...

Finding out the sector numbering scheme

For the next step, we have to determine the sector numbering scheme. Calling fdrawcmd several times in a row gives a good sampling of the sectors which can occur on a track. You can also attempt reading particular sectors if you want to probe for their existence:
> fdrawcmd read  phead lcyl lhead secnr secsiz  nrsect gap size2 \
length=length rate=x need_seek track=pcyl

phead
the physical head: 0 for one side, 4 for the other.

The next 4 parameters are the sector header of the sector to be read, just as in the last 4 return bytes of the readid command

lcyl
the logical cylinder number (the one in the header)
lhead
the logical head number (the one in the header).
secnr
the sector number
secsiz
is the sizecode (see above)
nrsect
the total number of sectors per track (set this to zero if unknown)
gap
no longer used by the floppy disk controller, usually you put 0x1b, just in case
size2
is usually not used either: usually you supply 0xff
pcyl
the physical cylinder number (the cylinder where to seek to). length is the number of bytes to read. Must be an integral number of sectors.
Example:
> fdrawcmd read 0  1 0 1 2  0 0x1b 0xff length=10240 need_seek track=1 >/dev/null
remaining= 1024
0: 40
1: 4
2: 0
3: 1
4: 0
5: 13
6: 2
no disk change

This command attempts to read 10240 bytes starting at sector 1/0/2/2 (track 1, head 0, number 2, size 512) on physical track 1, and physical head 0.

The system returns an error, and says 1024 bytes remain to be read (remainging=). This means that there are 18 sectors on that track (20 - 2).

Remember: on disks with doublespaced tracks, the physical cylinder has to be the double of the logical cylinder.

It might also be interesting to probe for sector 0.

Some CP/M systems have highly unusual numbering conventions, so don't be discouraged if you see them:

  • Some systems number sectors continously accross sides. For example head 0 has sectors 1-10, and head 1 has 11-20.
  • Some systems invert both heads: physical head 0 is logical head 1, and vice versa.
  • Some systems number tracks continously accross sides. For example, side 0 contains tracks 1-77, and side 1 contains 78-154.
  • Although most systems start numbering sectors at 1, some may start at 0.
  • Although most systems start numbering tracks at 0, some may start at 1.

    Using setfdprm to read the disk

    If the disk is not too unusal, you can configure your finding into the floppy driver using setfdprm, and can then use dd or cat to read the disk.

    Example:
     setfdprm /dev/fd0 sect=40 hd ssize=128 cyl=80
     cat /dev/fd0 >image
    

    If the format is unusual enough, you unfortunately have to read the disk track by track using the above-mentioned fdrawcmd commands.

    Cpmtools

    Once you have access to the disk, you can read the raw data from your disk. You do not yet have access to the individual files. For this, you need a filesystem-level utility, such as mtools for disks with a Dos filesystem, or cpmtools. Most disks that use non-standard low-level formats are actually CP/M disks. The low level image can be accessed using the cpmtools utility. The cpomtools package contains, among others, a cpmls and a cmpcp file, useful for listing CP/M directories, and copying files.

    Compilation of Cpmtools

    Cmptools needs the curses library, which is has been superceded by the ncurses library. If you no longer have access to ncurses, you'll get the following error message:
    
    gcc -g -o fsed.cpm fsed.cpm.o -lcurses
    /usr/i486-linux/bin/ld: cannot open -lcurses: No such file or directory 
    

    You can still compile the tools by replacing the following line in the Makefile:
    
    LIBCURSES=      -lcurses
    
    by:
    
    LIBCURSES=      -lncurses
    

    Using Cpmtools

    With the cpmtools, you can either work directly on the floppy disk (for thos formats where an image is available), or first extract the image, and then work on that image. The examples below show how to use cpmtools to work directly on the floppy disk. Note You need to use the setfdprm command before you can access the disk using cpmtools. The setfdprm command only needs to be issued before the first cpmtools command on that disk.
    
    > setfdprm /dev/fd0 sect=40 hd ssize=128 cyl=80
    > cpmls /dev/fd0
    
    Copying file test from the CP/M disk to the current Unix directory:
    
    > cpmcp 0:test .
    


    Alain Knaff
    Last modified: Mon Oct 9 08:03:44 CEST 2000