High Performance Computing

 

[Cygwin Tips] [Floppy Disks] [NAG Toolpack 2.5] [Web PNG images] [Controlling symbol scope in C]

 

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.