Floppy Disk Controller: Difference between revisions

m
Bot: Replace deprecated source tag with syntaxhighlight
[unchecked revision][unchecked revision]
(Sixth read/write param is *NOT* sector count to transfer. It's EOT, last sector in track (see FDC datasheet). This error sat here so long thanks to succeeding in bochs / only silently failing on certain sectors in VBox.)
m (Bot: Replace deprecated source tag with syntaxhighlight)
 
(11 intermediate revisions by 5 users not shown)
Line 29:
subsystem is the primary remaining one that accesses the obsolete and terrible ISA DMA system for its data transfers.
 
=== How Many Controllers? One! Usually. ===
Each ribbon cable for floppy drives can support 2 drives. One floppy controller chip can control 2 floppy cables, for a total
of 4 drives. It is theoretically possible for a system to have more than one controller chip, but you will not find anymany existing systems with
more than one. If a system were to havehas more than one floppy controller, the second controller wouldwill be found at a base IO port address of 0x370.
 
Some systems also have a third floppy controller, but these are exceedingly rare. Most of these will have originally been disk
duplication systems. The third floppy controller can be found at a base IO port address of 0x360.
 
=== How Many Drives? ===
Line 67 ⟶ 70:
This can be described in C with the following code:
 
<sourcesyntaxhighlight lang="c">
void lba_2_chs(uint32_t lba, uint16_t* cyl, uint16_t* head, uint16_t* sector)
{
Line 74 ⟶ 77:
*sector = ((lba % (2 * FLOPPY_144_SECTORS_PER_TRACK)) % FLOPPY_144_SECTORS_PER_TRACK + 1);
}
</syntaxhighlight>
</source>
 
You would then send this data to the floppy controller.
Line 152 ⟶ 155:
The basic set of floppy registers can be found in the following enumeration:
 
<sourcesyntaxhighlight lang="c">
enum FloppyRegisters
{
Line 165 ⟶ 168:
CONFIGURATION_CONTROL_REGISTER = 0x3F7 // write-only
};
</syntaxhighlight>
</source>
 
All commands, parameter information, result codes, and disk data transfers go through the FIFO port.
Line 182 ⟶ 185:
They are the following:
 
=== FIFO and Tape Drive Registers ===
FIFO: The FIFO register may not have a 16byte buffer in all modes, but this is a minor difference that does not really affect its operation.
 
=== Tape Drive Register ===
TDR: The Tape Drive Register is identical in all modes, but it is useless (you will never find functional equipment that requires it).
 
TDR: The Tape Drive Register is a R/W register which is identical in all modes. According to the documentation for the Intel 82077AA, the two least significant bits form a number between 1 and 3 (0 is an invalid value, drive 0 may not be selected) that assigns tape support to one particular drive out of four total drives. It is probably irrelevant for modern uses, is not supported by any emulator and is probably not worth implementing support for unless you have all the real hardware to test this functionality on.
 
=== DOR bitflag definitions ===
Line 510 ⟶ 515:
with a * and a comment.
 
<sourcesyntaxhighlight lang="c">
enum FloppyCommands
{
Line 524 ⟶ 529:
READ_DELETED_DATA = 12,
FORMAT_TRACK = 13, // *
DUMPREG = 14,
SEEK = 15, // * seek both heads to cylinder X
VERSION = 16, // * used during initialization, once
Line 534 ⟶ 540:
SCAN_HIGH_OR_EQUAL = 29
};
</syntaxhighlight>
</source>
 
==== "Deleted sectors" ====
Deleted sectors is a legacy feature, dating back to the 1970s, when IBM data entry terminals stored a single database record in each (128 byte) floppy sector, and a record could be marked as deleted by writing a different address mark before the sector. This feature was almost never used with IBM PC and compatibles – exceptions were occasional abuse by copy protection schemes, and (possibly) hiding bad sectors. Few (if any) emulators emulate this functionality, and many late model FDCs didn't implement it.
 
The "WRITE_DELETED_DATA" command can be used to create a deleted sector, and the "READ_DELETED_DATA" command can be used to read one back.
 
==== Option bits ====
Line 544 ⟶ 555:
===== Bit MF =====
Value = 0x40. "MFM" magnetic encoding mode. Always set it for read/write/format/verify operations.
 
A zero value represents the old "single density" FM format, which (on IBM PCs) was only used by 8-inch floppies (which were extremely rare). Few people ever used FM format, except for data interchange with non-PC systems (such as CP/M or minicomputers). Later model FDCs (e.g. Intel 82078) dropped support for it.
 
===== Bit SK =====
Value = 0x20. Skip mode. IgnoreThis thisskips bit"deleted andsectors" leave(see itexplanation cleared,in unlesssection you have a really good reason not toabove).
 
Ignore this bit and leave it cleared, unless you have a really good reason not to.
 
==== Status Registers ====
Line 790 ⟶ 806:
The following code intentionally contains a common bug that causes an infinite loop (waiting for IRQ6) on most emulators.
 
<sourcesyntaxhighlight lang="c">
volatile byte ReceivedIRQ = false;
 
Line 814 ⟶ 830:
WaitForIRQ();
}
</syntaxhighlight>
</source>
 
Sure this code ''looks'' OK, but some emulators or floppy drives might manage to be faster than your code. What if you've just returned from
Line 820 ⟶ 836:
set it to false again and then infinitely loop, waiting for an IRQ that has already been received. It's usually better to do something like:
 
<sourcesyntaxhighlight lang="c">
volatile byte ReceivedIRQ = false;
 
Line 855 ⟶ 871:
outb(Controller.FIFO, headload_ndma);
}
</syntaxhighlight>
</source>
 
== Related Links ==
Line 877 ⟶ 893:
 
=== Implementations ===
* [httphttps://kodersgithub.com/cFDOS/fid051291340B94EC7F5D1A38EF6843466C0B07627Bkernel/blob/master/drivers/floppy.aspx?s=fdcasm freedosFreeDOS] (C, GPL)
* [http://bos.asmhackers.net/docs/floppy/snippet_9/fdc.c GazOS] (C, GPL)
* [http://bos.asmhackers.net/docs/floppy/snippet_5/FLOPPY.ASM RDOS] (Assembly, GPL)
* [httphttps://wwwgithub.gelato.unsw.edu.aucom/torvalds/linux/lxrblob/sourcemaster/drivers/block/floppy.c Linux] (C, GPL)
 
[[de:Floppy Disk Controller]]