OpenCores
URL https://opencores.org/ocsvn/floppyif/floppyif/trunk

Subversion Repositories floppyif

[/] [floppyif/] [trunk/] [doc/] [facts.txt] - Rev 3

Compare with Previous | Blame | View Log

------------------
Floppy Drive Facts
------------------

Compiled by: Joseph H. Allen

These facts have been gleaned from multiple sources including WD1770 data
sheet, 82077AA data sheet, floppy drive YD-702D-6238D and X1De-xxA data
sheets and logic analyzer trace of read data line.

Information for standard high density 3.5" floppy disk:

There are 80 cylinders, and two sides for a total of 160 tracks.

The disk rotates at 300 RPM (5 rotations / sec, 200ms / rotation).

The bit rate before encoding is 500 Kb/sec.  Two 'cells' are used per bit
for MFM: one clock cell and one data cell.  The cell rate is 1 M cells/sec.

One disk can thus store 2,000,000 bytes with all formatting overhead
discounted.

Data is stored as magnetic flux reversals.  When a flux reversal is
detected, a short negative pulse is generated on the read_data_l line.  When
a flux reversal is to be written, a short negative pulse is generated on the
write_data_l line.

Data is encoded as MFM (modified frequency modulation): each bit is sent as
two cells.  The first cell is the clock cell, the second is the data cell. 
A pulse in the data cell means the data bit is 1, no pulse in the data cell
means the data bit is 0.  To reduce the density of flux reversals, the clock
cell has a pulse only when the data cell is a 0 and the previous bit was
also a zero.  Otherwise no pulse is sent in the clock cell.

For example, to send 110010001 in MFM:

|   1   |   1   |   0   |   0   |   1   |   0   |   0   |   0   |   1   |
|   |   |   |   |   |   |   |   |   |   |   |   |   |   |   |   |   |   |
------_-------_-----------_-----------_-----------_-------_-----------_--

Unfortunately on inner cylinders the density is so high that there are some
ISI (inter symbol interference) effects: basically two flux reversals
recorded close together get spread apart if there are no surrounding flux
reversals to contain them.  To account for this, write data is
precompensated as follows (from WD177x data sheet):

X  1  1  0    Early
X  0  1  1    Late
0  0  0  1    Early
1  0  0  0    Late
----  -  -
  |   |  |
  |   |  +-- next bit
  |   +----- current bit
  +--------- previous bits

The flux reversal of the current bit is made 125us early or late as
indicated above.  If there is a long gap of no flux reversals followed by
two closely spaced flux reversals, the first reversal of the two is made
late.  If there are two closely spaced flux reversals followed by a long
gap, the second flux reversal of the two is made early.

[On which cylinder do we start precompensation?]

Byte/Sector Format
------------------

Bytes are transmitted MSB first.

This is the format of a single track, beginning with the index pulse:

Repeat Count   Byte
------------   -----
    80         4E      GAP 0
    12         00      SYNC
     3         C2*     Index hole address mark
     1         FC
    50         4E      GAP 1
total=146 bytes

repeat 18 times, once for each sector:
--------------------------------
    12         00      SYNC
     3         A1*     Header address mark
     1         FE
     1         Track
     1         Head
     1         Sector
     1         No. bytes
     2         CRC
    22         4E      GAP 2
    12         00      SYNC
     3         A1*     Data address mark
     1         FB or F8 (always write FB)
   512         data
     2         CRC
    84         4E      GAP 3
--------------------------------
total=658 * 18 = 11844 bytes

   510         4E      GAP 4
total=510 bytes

total for entire track=12500 bytes


Field values:
-------------

Track: 0 - 79

Head: 0 - 1

Sector: 1 - 18

No. bytes in sector code: 2=512  (0=128, 1=256, 3=1024, 4=2048, etc.)

Address marks have an illegal (non-MFM) clock pattern to make them unique
codes:

  Data    Clock
  ----    -----

   A1      0A   (normal clock pattern is "0E")
   C2      14   (normal clock pattern is "1C")

Other address marks used in older formats:

   FE      C7
   FC      D7
   FB      C7
   F8      C7

16-bit CRC uses polynomial: x^16 + x^12 + x^5 + 1

CRC accumulator is initialized to FFFF.

All bytes including the A1s and the two CRC byte are counted in the CRC
checker.  If the result is 0, the CRC check passes.

MSB of each byte is fed into CRC shift register first.

When CRC is appended to the data, the MS byte of the CRC accumulator is
appended first, then the LS byte.

The CRC bytes are fed into the CRC shift register MSB first (just like the
data bytes).

Some C code:

/* x^16 + x^12 + x^5 + 1 CRC */
/* Append remainder (contents of fcs) to message: MSB of remainder goes first. */
/* Next time through, remainder will be zero. */
/* fcs is typically initialized to 0xFFFF */

/* Update FCS after one new byte (note that the MSB is taken first even
   though the LSB is transmitted first) */

unsigned short serial_crc(unsigned short fcs,unsigned char c)
  {
  int i;
  for(i=0;i!=8;++i)
    {
    fcs = ((fcs&0x8000)>>15)^(c>>7) ? (fcs<<1)^0x1021 : (fcs<<1);

    c = (c<<1);
    }
  return fcs;
  }

Floppy drive connector pins
---------------------------

(this is the connector on the drive itself: beware of cable twist in IBM PC
floppy cable).

|   GND   | Signal |
     1        2      N.C. (high_density_l on older drives)
     3        4      N.C.
     5        6      N.C.
     7        8      index_l
     9       10      N.C.
    11       12      drive_select_l
    13       14      N.C.
    15       16      motor_on_l
    17       18      direction_l
    19       20      step_l
    21       22      write_data_l
    23       24      write_enable_l
    25       26      cylinder0_l (also called track0_l)
    27       28      write_protect_l
    29       30      read_data_l
    31       32      side_one_l
    33       34      disk_change_l

All signals use open collector TTL drivers.  Each input pin has 1K pullup to
5V.  TTL "7438" is a typical driver chip.  TTL "74LS14" is typical receiver
chip.

Inputs to drive:

 drive_select_l: the "in use" LED will turn on and the remaining signals are
 valid.

   Wait .5 us after drive_select_l going low before doing anything.

 motor_on_l: the spindle motor turns on when this is low and a disk is in the
 drive.  Drive select is ignored for this signal.

   Wait 200ms from motor_on_l to first step.

   Wait 500ms from motor_on_l before start writing.

 direction_l: when low, pulses on step_l move the head "in" towards the
 center or the disk (toward higher numbered cylinders).  When high, pulses on
 stop_l move the head "out" towards the edge of the disk (toward "cylinder 0").

   Wait 1 us from change on direction_l to step_l leading edge.

   Wait 1 us from step_l trailing edge to change on direction_l.

 step_l: each low going pulse moves the head by one cylinder (step occurs on
 rising edge).

   Step pulse should be at least 1us in length.

   The step rate is 3ms between pulses.

   However, if the direction is changed during stepping, 4ms is required.

   After the last step, wait 18ms for heads to settle before writing.

 side_one_l: when low, side 1 is selected, otherwise side 0 is selected. 
 After switching sides, a 100us delay is required before writing.

 write_data_l: each low going pulse records a flux reversal on the disk. 
 minimum pulse width is 125 us.  Flux reversal is recorded on leading edge
 (high to low) of pulse.

 write_enable_l: enable writing of data to disk when low.  When deactivated,
 wait 650us before stepping or changing sides because erase head could still
 be energized.

   Wait 4 us from write_enable_l to pulses on write_data_l.  Wait 4 us from
   last pulse on write_data_l to deactivate write_data_l.

Outputs from drive:

 cylinder0_l: when low, the head assembly is one positioned over the
 outermost cylinder.

   Max 2.9ms from last step to cylinder 0 detected.

   Max 17us for cylinder0_l to deactivate after stepping out of cylinder 0.

 index_l: a low going pulse whenever the index hole goes by the index hole
 optical sensor.

 write_protect_l: when low, indicates disk is write protected (write protect
 notch is open).

 read_data_l: a low going pulse of at least 125ns for each flux reversal. 
 Flux reversals are indicated by the leading (high to low) edge of pulse.

 disk_change_l: low initially and whenever drive door is opened.  Goes high
 when drive door is closed and after first step pulse has been received.

Floppy power connector
----------------------

Pin Signal
--- ------
 1  5V DC
 2  Ground
 3  Ground
 4  No connection (older drives need 12V here).

Compare with Previous | Blame | View Log

powered by: WebSVN 2.1.0

© copyright 1999-2024 OpenCores.org, equivalent to Oliscience, all rights reserved. OpenCores®, registered trademark.