Floppy Disks
There is a good set of tools for manipulating most floppy disks under Linux.
If you do not already have them, you need the tools and documentation from
http://fdutils.linux.lu/. They are,
unfortunately, a bit cryptic to use so here are a few pointers:
- If you are using the first floppy drive, you probably don't need to
specify a drive. If you are using the second drive, specify drive=/dev/fd1
and add one to the drvsel parameter. So, to look at the ID bytes of a
(random) sector on the first head on the second drive you need something like
fdrawcmd drive=/dev/fd1 readid 1
need_seek track=0
and for the second head you need
fdrawcmd drive=/dev/fd1 readid 5
need_seek track=0
- Data transfer rates must be correct. You need rate=0 for high
density (like 1.2M on 5.25inch and 1.44M on 3.5 inch) , rate=1
for double density (like 360k, 720k) 5.25 inch and rate=2 for
double density (like 720k) 3.5 inch. See below for 8 inch drives.
- Don't forget that you also have to worry about the track density for some
disks: see the documentation at
http://fdutils.linux.lu.
- If you are trying things out, don't forget to reset the controller and
drive after
failed attempts at fdrawcmd:
floppycontrol --resetnow 2
fdrawcmd drive=/dev/fd1 recalibrate 1
fdrawcmd drive=/dev/fd1 recalibrate 1
- If you are trying to read a whole disk image using fdrawcmd, you can
read both sides of a single track in one command. It will not, however, step
to the next track. It's a bad idea to do the stepping inside the fdrawcmd read
command, as this will force a seek to track zero. Here is an example of a
reasonably efficient way to read an image of a 5.25 inch double density
8
sector/track double sided 80 track disk mounted in drive /dev/fd1:
#!/bin/bash
cat /dev/null > $1
floppycontrol --resetnow 2
fdrawcmd drive=/dev/fd1 rate=1 readid
1 need_seek track=0
for ((i=0;i<80;i++)) do
fdrawcmd
drive=/dev/fd1 seek 1 $i
fdrawcmd drive=/dev/fd1 rate=1 read 1 $i 0 1 2
8 0x1b
0xff length=8192 >> $1
done
gzip $1
To change the number of sectors/track, or the number of sides, you just
replace the 8 with the new number of sectors
and replace the 8192 with 512 * <number of
sectors> * <number of sides>. To change the number of tracks, just change the
80. The above version does no useful error
checking. A more robust approach checks that the reads read the correct number
of bytes.
#!/bin/bash
cat
/dev/null > $1
errfile=/tmp/$$_errs
track=-1
floppycontrol --resetnow 2
fdrawcmd drive=/dev/fd1 rate=1 readid 1 need_seek track=0 2> /dev/null
for ((i=0;i<80;i++))
do fdrawcmd drive=/dev/fd1 seek 1 $i 2> /dev/null
fdrawcmd drive=/dev/fd1 rate=1 read 1 $i 0 1 2 8 0x1b 0xff length=8192 >> $1 2>
$errfile
awk '/remaining=/ {if ( $2 != 0 ) { print "**ERROR**" ; exit (2) } }' $errfile
|| { track=$i ; break ; }
done
rm $errfile
if ((
track == -1 )) ; then gzip $1
exit 0
else rm
$1
echo "** READ FAILED AT TRACK $track **"
exit 2
fi
Finally, if you want to read 40 track disks on an 80 track drive, you
need to do a bit of arithmetic for the seek.
#!/bin/bash
cat /dev/null > $1
errfile=/tmp/$$_errs
track=-1
floppycontrol --resetnow 2
fdrawcmd drive=/dev/fd1 rate=1 readid 1 need_seek track=0 2> /dev/null
for ((i=0;i<40;i++)) do
let "p = 2 * i"
fdrawcmd drive=/dev/fd1 seek 1 $p 2> /dev/null
fdrawcmd drive=/dev/fd1 rate=1 read 1 $i 0 1 2 9 0x1b 0xff length=9216 >>
$1 2> $errfile
awk '/remaining=/ {if ( $2 != 0 ) { print "**ERROR**" ; exit (2) } }' $errfile
|| { track=$i ; break ; }
done
rm $errfile
if (( track == -1 )) ; then gzip $1
exit 0
else rm $1
echo "** 360k READ FAILED AT TRACK $track **"
exit 2
fi
- Once you have your disk image, you need to interpret it. The
mtools
will do a good job on most MSDOS-like formats (but see below). These other tools might be
useful for some legacy formats:
- MSDOS-style disks, also used by the Atari ST
The following table may be useful. All modern MSDOS-style floppies have a
BIOS parameter block in the first 512 byte sector. This gives complete
information about the layout of the disk. Very early versions of MSDOS
produced floppies without this block and relied on the media descriptor,
the first byte of the second sector, to give the disk layout. The most
common MSDOS formats are shown in green.
FORMAT |
MEDIA DESCRIPTOR |
USUAL MEDIA |
TRACKS |
SECTORS |
SIDES |
CLUSTER SIZE |
FAT TYPE |
FAT |
DIRECTORY |
160K |
FE |
5.25 inch |
40 |
8 |
1 |
1 = 512 byte |
12 bit |
1 sector |
4 sectors = 64 entries |
180K |
FC |
5.25 inch |
40 |
9 |
1 |
1 = 512 byte |
12 bit |
2 sector |
4 sectors = 64 entries |
320K |
FF |
5.25 inch |
40 |
8 |
2 |
2 = 1024 byte |
12 bit |
1 sector |
7 sectors = 112 entries |
360K |
FD |
5.25 inch |
40 |
9 |
2 |
2 = 1024 byte |
12 bit |
2 sector |
7 sectors = 112 entries |
720K |
F9 |
3.5 inch |
80 |
9 |
2 |
2 = 1024 byte |
12 bit |
3 sector |
7 sectors = 112 entries |
1.2Meg |
F9 |
5.25 inch HD |
80 |
15 |
2 |
1 = 512 byte |
12 bit |
7 sector |
14 sectors = 224 entries |
1.44Meg |
F0 |
3.5 inch |
80 |
18 |
2 |
1 = 512 byte |
12 bit |
9 sector |
14 sectors = 224 entries |
2.88Meg |
F0 |
3.5 inch HD |
80 |
36 |
2 |
2 = 1024 byte |
12 bit |
9 sector |
15 sectors = 240 entries |
|
F8 |
fixed disk |
|
|
|
|
12/16/32 bit |
|
|
- If you have a 8-inch drive, it should work too, although I have not
tried out mine yet. The most common formats were 77 tracks with 26 sectors
either single or double sided, recorded at 500kHz (rate=0) either
FM with a sector size of 128 or MFM with a sector size of 256.
|