Floppy Disk Controller: Difference between revisions

Added some notes, fixed one error
[unchecked revision][unchecked revision]
m (→‎Controller Reset: - 2nd formatting error)
(Added some notes, fixed one error)
Line 1:
== Overview and Documentation ==
The Floppy Disk Controller (FDC) is a (legacy) device that controls hardware for access tointernal 3.5/5.25 inch floppy disks.disk Theredrive aredevices aon rangedesktop ofx86 chips that havesystems.
There are a range of chips that have been produced for this function andwhich include: 8272A, 82078, 82077SL & 82077AA. The 82077AA is the most advanced, and has been produced since 1991. For more
advanced, and has been produced since 1991. For more recent systems, a model of that chip has been embedded in the motherboard chipset. (So pay close attention to that datasheet, below.)
(So pay close attention to that datasheet, below.)
 
=== Accessing Floppies in Real Mode ===
For bootloaders or OSes that run with the CPU remaining in [[Real Mode]], use [[BIOS (PC)#BIOS functions|BIOS Function]] INT13h AH=2 (read) or AH=3 (write) to access
Usefloppy BIOS function INT13h AH=2 (read) or AH=3 (write)drives. You need to know the "drive number" (typically 0 or 1), and put that value in DL.
More detailed info can be found in the [[ATA in x86 RealMode (BIOS)]] article, because accessing a floppy is identical to accessing a hard disk
(using CHS) in Real modeMode. The rest of this article deals with creating Protected Mode drivers for the floppy subsystem.
 
=== Accessing USB Floppy Drives ===
Line 33 ⟶ 35:
In the olden days, there used to be 5.25 inch low-density, high-density, and single-sided drives. There used to be media
for each of these drive types. There also used to be 3.5 inch low density media. None of this really exists anymore. The only
actual hardware you will typically run into anymorenow is 3.5 inch, 1.44MB drives.
 
A 1.44MB floppy disk hasis usually formatted with 80 cylinders, 2 sides, and 18 sectors per track. The drive records the two sides with two "heads" that
with two "heads" that are bolted together. They cannot seek independently. The "track" on one side of a disk is always exactly opposite the
opposite the track on the other side of the disk. (There is a misconception about this in many floppy driver code examples.) You only
You only need to seek one head to find a particular cylinder, so that both heads may read/write that cylinder.
 
=== CHS ===
Line 86 ⟶ 88:
There were several generations of floppy controller chips on several generations of 80286 computers, before
the 82077AA chip existed. The 82077AA was built to emulate all of them, by setting various pins on the chip to 5 volts.
The three modes are: PC-AT mode, PS/2 mode, and Model 30 mode. The mode you will typically see on emulators is Model 30 Mode.
The only mode you will ever see on any hardware that still runs is PS/2 mode. ItIn isthe unfortunatedocumentation, that emulators get this wrong,you
can ignore the Model 30 and PC-AT modes. Or you can try to handle all three, by only using registers and commands that are identical
but the only real effect from it is in the logic for testing "Disk Change" (see below). In the documentation, you
can ignore PC-AT modes. Or you can try to handle all three, by only using registers and commands that are identical
in all 3 modes.
 
=== Most commands run "silently" ===
There are only a few commands/conditions that produce interrupts: a reset (in polling mode only), Seek, Recalibrate, or one of the (several kinds of)many
read/write/verify/format commands. ManySeveral commands do not produce any result bytes, either. If you want to verify that a silent
command actually worked, just about the only thing you can do is use the Dumpreg command to check the current state of the
controller.
Line 100 ⟶ 101:
=== Timing Issues ===
On real hardware, there are definite timing issues. Seek delays and motor delays are just what any programmer would expect. It
would be nice if the drive would send an IRQ when the motor was up to speed, but it doesn'tdoes not. The thing that you '''don't'''may not
expect is that youquite new hardware may still need a microsecondartificial delaydelays between each "command/parameter" bytebytes. thatThere youis outputa tobit in the FDC, even on machines as recent as PentiumMSR
to test, to know when the next byte can be sent. It is not a good idea to simply hardcode specific delays between output bytes.
166 systems. This can be done by, for example, reading port 0x3F6 (the ATA alternate status port) 10 times. Or, you can just decide
If you really feel you must do that, though, then a 400ns delay (consisting of reading the MSR port 4 times and discarding the
that the floppy is a low priority device, and swap out the driver between each output byte. Wasting an entire microsecond of CPU
results) is probably adequate. Looping 20 times, and testing the value of the RMQ bit in the MSR each time, should always be
time just to make FDC commands run as quickly as possible seems unreasonable.
a sufficient "timeout".
 
== Registers ==
Line 264 ⟶ 266:
Alternately, you can always set both of them, for maximum compatibility with ancient chipsets.
 
The bottom 2 bits specify the data transfer rate to/from the drive. You want both bits set to zero for a 1.44MB or 1.2M floppy drive.
So generally, you want to set CCR to zero just once, after bootup (because the BIOS may not have done it, unless it booted a floppy disk).
 
Note: a reset procedure does not affect this register. However, if you have drives of different types on the bus which
use different datarates, then you need to switch the datarate when you select the other drive. It also seems to be possible
to modify this register while the FDC is in "reset state".
 
Datarates used for setting either DSR or CCR:
 
<pre>
Datarate value Drive Type
1Mbps 3 2.88M
500Kbps 0 1.44M, 1.2M
250Kbps 2
</pre>
 
Note: There is also a 300Kbps setting (value = 1), butand youa should250Kbps neversetting use(value it;= 250Kbps2) but they are only used for isutterly powerupobsolete defaultdrives/media.
 
=== Important Bitflags that depend on the Mode ===
 
==== DIR register, Disk Change bit ====
Note: many sources say that you must turn on the drive motor bit before you access the DIR register for a selected drive.
This claim needs further testing.
 
This bit (bit 7, value = 0x80) could be very useful, if it actually works for you. It is supposed to tell you if the floppy door was
Line 289 ⟶ 293:
bit until you have tested the functionality on real hardware.
 
Basically, you want to keep a flag for whether there is media in theeach drive. if Disk Change is "true" and there was media,
the OS should get a signal that the previous media was ejected., and the driver should automatically recalibrate the drive
for the new media. The recalibration serves two purposes. The heads may have moved when the new media was inserted, and the
recalibrate will correct for this. Also, the recalibrate will clear the Disk Change flag to "false" if there is '''new''' media
in the drive. You find out initially whether there is media in the drives by issuing Recalibrate commands to all the drives
(see the [[#Reinitialization|reinitialization]] procedure below).
 
If a drive has no media in it, and the driver wants to automatically check for new media, it can periodically do a ResetSeek procedure on the drive/controller.command
on the drive. If Disk Change remains "true", then the drive is still empty. If it goes "false", it means that a new floppy has been inserted,
floppy has been inserted, and the OS should get a "media inserted" signal. On some/most hardware, it is possible to
simply toggle the drive motor bit off and then on again, to achieve the same result as doing a Seek (Linux calls this a "twaddle").
 
But there is a problem. As the section title says, the problem is that the '''value''' of the Disk Change bitflag depends
on the mode. And there are 3 possible modes.
And the idiots at Intel who made this chip failed utterly in giving you a definitive way of figuring out the mode.
Line 308 ⟶ 317:
 
If you ignore PC-AT mode, then you can tell whether Disk Change is true or false by looking at the other bits in upper DIR.
Bits 4, 5, and 6 of DIR tell you what value of Disk Change is "true". Usually "true" = 01 on real hardware.
 
The workaround (to do ONCE): Read DIR. Assume that the current value of Disk Change means "true". Send a Recalibrate command.
Line 353 ⟶ 362:
If you really want to try using non-essential bitflags that are mode-dependent, you will need to look in the
datasheet linked below for their locations and meanings. Including them would add too much extraneous info to
this article. As mentioned in the case of the Disk Change bit, it is not logically possible to completely
this article.
determine what mode the controller chip is in, so it is not really possible to know the meaning of any bitflag,
if there is any ambiguity between modes.
 
== Programming Details ==
Line 364 ⟶ 375:
# Get an IRQ6 at the end of the execution phase, but '''only if the command HAS an execution phase'''.
# Read any "result bytes" produced by the command (the "result phase").
# The commands "Recalibrate", "Seek", and "Seek Relative" do not have a result phase, and require an additional "Sense Interrupt" command to be sent.
 
And then you are ready for the next command. See below for more detail on how to issue a command.
 
=== Motor Delays ===
Note: the Linux floppy driver sourcecode has a comment that claims that turning on the motor for drive 2 or drive 3
When you turn the motor on, it takes quite a few milliseconds to "spinup" -- to reach the (stabilized) speed needed for data transfer.
on a floppy bus can completely lock up some systems. This claim seems unlikely?
The controller has electronics to handle a large variation in rotation speed, but it has its limits.
If you start reading/writing immediately after the motor is turned on, "the PLL will fail to lock on to the data signal" and you'll get an error.
 
Note2: modern floppy drives ignore the motor bits, and only spin the disk when they think they need to.
After you're done reading (or writing), you should typically wait an additional 2 seconds to turn the motor off. (It may also be smart
 
When you turn thea floppy drive motor on, it takes quite a few milliseconds to "spinup" -- to reach the (stabilized) speed needed for data transfer.
needed for data transfer. The controller has electronics to handle a large variation in rotation speed, but it has its limits.
If you start reading/writing immediately after the motor is turned on, "the PLL will fail to lock on to the data signal" and you'll will get an error.
 
After you're are done reading (or writing), you should typically wait an additional 2 seconds to turn the motor off. (It may also be smart
to seek the heads back to cylinder 0 just before turning the motor off.) You could leave the motor on longer,
but it might give the user the idea that the floppy is still transferring data and that it's taking an awfully long time.
Line 581 ⟶ 597:
* Configure command = 0x13
* First parameter byte = 0
* Second parameter byte = (implied seek enable << 6) | (fifo enable'''DIS'''able << 5) | (polling enable << 4) | thresh_val (= threshold - 1)
* Third parameter byte = precomp_val = 0
* No result bytes.
Line 841 ⟶ 857:
* [http://bos.asmhackers.net/docs/floppy/snippet_9/fdc.c GazOS] (C,GPL)
* [http://bos.asmhackers.net/docs/floppy/snippet_5/FLOPPY.ASM RDOS] (ASM, GPL)
* [http://www.gelato.unsw.edu.au/lxr/source/drivers/block/floppy.c Linux] (C,GPL)
 
[[Category:Storage]]
Anonymous user