User Tools

Site Tools


oric:hardware:floppy_disk_controller_wd1793

Overview

The FDC or Floppy Disc Controller handles the mechanics and transfer of bytes to and from (up to 4) disc drives and the Oric.

The Disk is a relatively large storage medium, many times the memory capacity of the Oric, therefore a scheme is used to allow easy mapping of the disc surface and selecting the drive. Floppy disks will be either single or double sided, and disc drives will also be either single or dual-headed. When using a double-sided in a single-headed drive (most 3“ drives are single-headed), the floppy has to be flipped over in order to read its second side. The FDC can control up to 4 Disc drives, where each one can be a different type. For example, attaching two 3.5”, a 3“ and a 5.25” is quite feasable.

The Disc surface is mapped into Tracks and Sectors.

A Track is simply a concentric ring on the surface of the disc, and each track is split into a number of sectors. The number of tracks, Sectors and size of sectors is left to the programmer.

However 3“ drives are limited to up to 42 tracks per side whilst 3.5” discs may go as high as 80.

Oric disk operating systems usually store 16 or 17 256-byte sectors in each track (Stratsed allows 18 sectors, but it is not as reliable). Randos and BDDOS use 512-byte sectors.

To calculate the number of bytes that can fit on a single disc, we will use this example for a double sided 3.5“ disc.

Their are 2 sides Their are 80 tracks on the surface of one side of the disc. Their are 18 sectors in each track. Each sector is 256 bytes long.

This means that the total capacity of a double sided 3.5” Disc will be 2*80*18*256 or 737,280 byte capacity.

FDC Registers

The FDC in the Microdisc system is memory mapped in the conventional I/O area of page 3 in the range $0310 to $0313. Additional I/O registers and latches in the Microdisc electronics are mapped in the $0314-$031B address range.

Each FDC register has a different function when written to or read from.

When written to (ie. STA $0310)

$0310 takes FDC commands

$0311 takes FDC Track Number

$0312 takes FDC Sector Number

$0313 takes FDC Data to place on the disc

$0314 to $0317 takes FDC Control(*2)

The remaining registers have no meaning when written to. *2 All locations in range act as the same register.

When Read from (ie. LDA $0310)

$0310 holds the FDC Status

$0313 holds the FDC Data read from a disc

$0314 to $0317 holds the FDC INTRQ state

$0318 to $031B holds the FDC DRQ state

The remaining registers have no meaning when read from.

For code examples, the following #defines have been used

        #define fdc_Command   $0310
        #define fdc_Status    $0310
        #define fdc_Track     $0311
        #define fdc_Sector    $0312
        #define fdc_Data      $0313
        #define fdc_Control   $0314
        #define fdc_DRQState  $0318

FDC Registers in focus

And now each register in closer detail

LocationR/WBitsDescription
$0310W0-7FDC Command

Generally the top 3 bits (B5 to B7) of this register define the Command whilst the lower 5 bits (B0 to B4) provide settings for the command used.

BitsCommandDescription
0000hVqrRestore(Seek Track 0)Upon receipt of this command, the TR00 input is sampled. If TR00 is active (low) indicating the head is positioned over track 0, the Track Register is loaded with zeroes and an interrupt is generated. If TR00 is not active, stepping pulses at a rate specified by the qr field are issued until the TR00 input is activated. At this time, the Track Register is loaded with zeroes and an interrupt is generated.
0001hVqrSeekThis command assumes that the Track Register contains the track number of the current position of the head and the Data Register contains the desired track number. The FDC will update the Track Register and issue stepping pulses in the appropriate direction until the contents of the Track Register are equal to the contents of the Data Register. An interrupt is generated at the completion of the command. Note: when using multiple drives, the track register must be updated for the drive selected before seeks are issued.
001ThVqrStepUpon receipt of this command, the FDC issues one stepping pulse to the disk drive. The stepping motor direction is the same as in the previous step command. An interrupt is generated at the end of the command.
010ThVqrStep-InUpon receipt of this command, the FDC issues one stepping pulse in the direction towards track 76. An interrupt is generated at the end of the command.
011ThVqrStep-OutUpon receipt of this command, the FDC issues one stepping pulse in the direction towards track 0. An interrupt is generated at the end of the command.
100mSEC0Read SectorUpon receipt of the command, the head is loaded, the busy status bit set and when an ID field is encountered that has the correct track number, correct sector number, correct side number, and correct CRC, the data field is presented to the computer. A DRQ is generated each time a byte is transferred to the DR. At the end of the Read operation, the type of Data Address Mark encountered in the data field is recorded in the Status Register (bit 5).
101mSECaWrite SectorUpon receipt of the command, the head is loaded, the busy status bit set and when an ID field is encountered that has the correct track number, correct sector number, correct side number, and correct CRC, a DRQ is generated. The FDC counts off 22 bytes (in double density) from the CRC field and the Write Gate output is made active if the DRQ is serviced (ie. the DR has been loaded by the computer). If DRQ has not been serviced, the command is terminated and the Lost Data status bit is set. If the DRQ has been serviced, 12 bytes of zeroes (in double density) are written to the disk, then the Data Address Mark as determined by the a0 field of the command. The FD179X then writes the data field and generates DRQ's to the computer. If the DRQ is not serviced in time for continuous writing the Lost Data Status bit is set and a byte of zeroes is written on the disk (the command is not terminated). After the last data byte has been written on the disk, the two-byte CRC is computed internally and written on the disk followed by one byte of logic ones.
11000E00Read AddressUpon receipt of the Read Address command, the head is loaded and the Busy Status bit is set. The next encountered ID field is then read in from the disk, and the six data bytes of the ID field are assembled and transferred to the DR, and a DRQ is generated for each byte. The six bytes of the ID field are : Track address, Side number, Sector address, Sector Length, CRC1, CRC2. Although the CRC bytes are transferred to the computer, the FDC checks for validity and the CRC error status bit is set if there is a CRC error. The track address of the ID field is written into the sector register so that a comparison can be made by the user. At the end of the operation, an interrupt is generated and the Busy status bit is reset.
11100E00Read TrackUpon receipt of the Read Track command, the head is loaded, and the busy status bit is set. Reading starts with the leading edge of the first encountered index pulse and continues until the next index pulse. All gap, header, and data bytes are assembled and transferred to the data register and DRQ's are generated for each byte. The accumulation of bytes is synchronized to each address mark encountered. An interrupt is generated at the completion of the command. The ID Address Mark, ID field, ID CRC bytes, DAM, Data and Data CRC bytes for each sector will be correct. The gap bytes may be read incorrectly during write-splice time because of synchronisation.
11110E00Write Track (formatting a track)Upon receipt of the Write Track command, the head is loaded and the Busy Status bit is set. Writing starts with the leading edge of the first encountered index pulse and continues until the next index pulse, at which time the interrupt is activated. The Data Request is activated immediately upon receiving the command, but writing will not start until after the first byte has been loaded into the DR. If the DR has not been loaded by the time the index pulse is encountered, the operation is terminated making the device Not Busy, the Lost Data status bit is set, and the interrupt is activated. If a byte is not present in the DR when needed, a byte of zeroes is substituted. This sequence continues from one index mark to the next index mark. Normally, whatever data pattern appears in the data register is written on the disk with a normal clock pattern. However, if the FDC detects a data pattern of F5 thru FE in the data register, this is interpreted as data address marks with missing clocks or CRC generation. The CRC generator is initialized when an F5 data byte is about to be transferred (in MFM). An F7 pattern will generate two CRC bytes. As a consequence, the patterns F5 thru FE must not appear in the gaps, data fiels, or ID fiels. Tracks may be formatted with sector lengths of 128, 256, 512 or 1024 bytes.
1101IJKLForce InterruptThe Forced Interrupt command is generally used to terminate a multiple sector read or write command or insure Type I status register. This command can be loaded into the command register at any time. If there is a current command under execution (busy status bit set), the command will be terminated and the busy status bit reset.

Flag Summary

BitsDescription
qrForms a 2 bit entity defining the Stepper motor Rate of 6ms(0), 12ms (1), 20ms(2) or 30ms(3) (3.5“ Drives are always 6ms)
VTrack Number Verify(1) Flag. For Step operations Sedoric Resets this bit
hHead Load Flag. For Step operations Sedoric Sets this bit
TTrack Update Flag. For Step operations Sedoric Sets this bit
aData Address Mark
CSide Compare Flag. For Sector Read Sedoric resets this bit
EAdd Delay of 15ms. For Sector Read Sedoric resets this bit
SSide Compare Flag. For Sector Read Sedoric Sets this bit
mMultiple Record Flag. For Sector Read Sedoric resets this bit
IJKLIf all these are zero, then Terminate with no irq Request.
INot Ready to Ready Transition
JReady to not Ready Transition
KIndex Pulse
LImmediate interrupt (Requires a Reset)
LocationR/WBitsDescription
$0311W0-7FDC Track Number

This 8-bit register holds the track number of the current Read/Write head position. It is incremented by one every time the head is stepped in (towards track 79) and decremeted by one when the head is stepped out (towards track 00). The contents of the register are compared with the recorded track number in the ID field during disk Read, Write and Verify operations. This Register should not be loaded when the device is busy.

LocationR/WBitsDescription
$0312W0-7FDC Sector Number

This 8-bit register holds the address of the desired sector position. The contents of the register are compared with the recorded sector number in the ID field during disk Read or Write operations. This register should not be loaded when the device is busy.

LocationR/WBitsDescription
$0313W0-7FDC Data

This 8-bit register is used as a holding register during Disk Read and Write operations. In Disk Read operations the assembled data byte is transferred in parallel to the Data Register from the Data Shift Register. In Disk Write operations information is transferred in parallel from the Data Register to the Data Shift Register.

When executing the Seek command the Data Register holds the address of the desired Track position.

LocationR/WBitsDescription
$0314W0FDC Interrupt Control

The FDC contains its own interrupt controller; this bit enables or disables connection of the FDC's interrupt line to the CPU's. Command completion can be detected in a number of ways.

$0314 Bit 0CPU I FlagDetecting end of Command
00The CPU must poll either the status register or bit 7 of $0314 for command completion
01The CPU must poll either the status register or bit 7 of $0314 for command completion
10The CPU must poll either the status register or bit 7 of $0314 for command completion
11The CPU will receive an interrupt at the end of the command
LocationR/WBitsDescription
$0314W1BASIC ROM Control

This switches in (1) or out(0) the internal BASIC ROM. Switching out the internal ROM will expose the top 16K RAM of ORIC memory. This usually holds the Disc operating system (Sedoric).

LocationR/WBitsDescription
$0314W2Data Seperator Clock Divisor

This selects the data seperator Clock divisor. This bit should always be set to 1.

LocationR/WBitsDescription
$0314W3FDC Density Flag

Selects Double(0) or Single(1) Density Disc. It is generally assumed that most disks are double density so this bit should be set to 0.

LocationR/WBitsDescription
$0314W4FDC Side Control

Selects the first Side (0) or the other Side (1). For 3.5”, the disc cannot be physically flipped. However with some older drives like the 5.25“, their is no way the FDC can detect which is the default side.

LocationR/WBitsDescription
$0314W5-6FDC Drive Number

Forms a 2 bit number ranging 0 to 3 which selects the Drive number. Drive 0 is the master drive.

LocationR/WBitsDescription
$0314W7RANDOS ROM Control

Selects the Internal RANDOS Disc Operating System(0) or switches it out(1). When enabled it will overlay $E000 to $FFFF of ORIC RAM, however the internal BASIC ROM will always take presedent.

LocationR/WBitsDescription
$0310R0-7FDC Status

The FDC Status Register returns the status of the last operation performed. Each Bit represents a flag of a disc aspect but not all bits are affected by all commands as shown below.

CommandBitFlagDescription
Restore, Seek, Step, Step-in and Step-outB0BusyCommand is in progress(1)
B1DRQIndicates index mark detected from drive(1)
B2Track 0Read/Write head is positioned to Track 0(1)
B3CRC ErrorCRC Error encountered in ID field(1)
B4Seek ErrorThe desired track was not verified(1)
B5Head LoadedThe head is loaded and engaged(1)
B6Write ProtectWrite Protect is activated(1)
B7Not ReadyThe drive is not ready(1)*
Read AddressB0BusyCommand is in progress(1)
B1DRQThe Data Register is full(1)
B2Lost DataThe computer did not respond to DRQ in one byte time(1)
B3CRC ErrorCRC Error encountered in ID field(1)
B4RNFThe desired track, sector, or side were not found(1)
B5--
B6--
B7Not ReadyThe drive is not ready(1)*
Read SectorB0BusyCommand is in progress(1)
B1DRQThe Data Register is full(1)
B2Lost DataThe computer did not respond to DRQ in one byte time(1)
B3CRC ErrorCRC Error encountered in ID field(1)
B4RNFThe desired track, sector, or side were not found(1)
B5Record TypeOn Read Record: it indicates the record-type code from data field address mark (1: Deleted Data Mark, 0: Data Mark)
B6--
B7Not ReadyThe drive is not ready(1)*
Read TrackB0BusyCommand is in progress(1)
B1DRQThe Data Register is full(1)
B2Lost DataThe computer did not respond to DRQ in one byte time(1)
B3--
B4--
B5--
B6--
B7Not ReadyThe drive is not ready(1)*
Write SectorB0BusyCommand is in progress(1)
B1DRQThe Data Register is empty(1)
B2Lost DataThe computer did not respond to DRQ in one byte time(1)
B3CRC ErrorCRC Error encountered in ID field(1)
B4RNFThe desired track, sector, or side were not found(1)
B5Write FaultIndicates a Write Fault(1)
B6Write ProtectWrite Protect is activated(1)
B7Not ReadyThe drive is not ready(1)*
Write TrackB0BusyCommand is in progress(1)
B1DRQThe Data Register is empty(1)
B2Lost DataThe computer did not respond to DRQ in one byte time(1)
B3--
B4--
B5Write FaultIndicates a Write Fault(1)
B6Write ProtectWrite Protect is activated(1)
B7Not ReadyThe drive is not ready(1)*

* the Microdisc connects the FDC's RDY line directly to +5v via a pull-up resistor. Therefore drives appear to be ready at all times.

LocationR/WBitsDescription
$0313R0-7FDC Data
LocationR/WBitsDescription
$0314R7FDC INTRQ

This reflects the FDC's INTRQ line which will be reset when the command has finished or when status is read. It is not affected by the value written to bit 0 of $0314.

LocationR/WBitsDescription
$0318R7FDC DRQ State

When a byte is ready to be read or written Bit 7 of $0318 is Reset.

oric/hardware/floppy_disk_controller_wd1793.txt · Last modified: 2016/12/08 16:50 by thomh