The FDC Floppy Disc Controller

If you want to ask questions about how the machine works, peculiar details, the differences between models, here it is !
How to program the oric hardware (VIA, FDC, ...) is also welcome.
User avatar
Twilighte
Game master
Posts: 819
Joined: Sat Jan 07, 2006 12:07 am
Location: Luton, UK
Contact:

The FDC Floppy Disc Controller

Post by Twilighte »

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

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.

The FDC in the Microdisc system is memory mapped in the conventional I/O area of page 3 in the range $0310 to $0313. Additionnal 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 write to
$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.

When Read from
$0310 holds the FDC Status
$0313 holds the FDC Data read from a disc
$0314 to $0317 holds the FDC INTRQ state(*2)
$0318 to $031B holds the FDC DRQ state(*2)
The remaining registers have no meaning when read from.

*2
All locations in range act as the same register.

And now each register in closer detail
$0310 (Write) - FDC 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.
0000hVqr Restore
0001hVqr Seek
001ThVqr Step
010ThVqr Step-In
011ThVqr Step-Out
100mSEC0 Read Sector
101mSECa Write Sector
11000E00 Read Address
11100E00 Read Track
11110E00 Write Track
1101IJKL Force Interrupt

Flag Summary
qr Forms 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)
V Track Number Verify(1) Flag
h Head Load Flag
T Track Update Flag
a Data Address Mark
C Side Compare Flag
E Delay 15ms
S Side Compare Flag
m Multiple Record Flag
IJKL If all these are zero, then Terminate with no irq Request.
I Not Ready to Ready Transition
J Ready to not Ready Transition
K Index Pulse
L Immediate interrupt (Requires a Reset)

$0311 (Write) - FDC 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.

$0312 (Write) - FDC 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.

$0313 (Write) - FDC 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.

$0314 (Write) - FDC Control (Bit 0) *1
Their are two FDC Modes available to detect when data is ready when reading data from the Disc.
When this bit is set to Zero, Bit 7 of $0318 will be Zero when data is ready to be read from $0313.
When this bit is set to One, a non-maskable Interrupt will trigger when data is ready to be read from $0313.
$0314 (Write) - FDC Control (Bit 1)
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).
$0314 (Write) - FDC Control (Bit 2)
This selects the data seperator Clock divisor.
This bit should always be set to 1.
$0314 (Write) - FDC Control (Bit 3)
Selects Double(1) or Single(0) Density Disc.
It is generally assumed that Most Disks are Single density so this bit should be set to 0.
$0314 (Write) - FDC Control (Bit 4)
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.
$0314 (Write) - FDC Control (Bits 5-6)
Forms a 2 bit number ranging 0 to 3 which selects the Drive number.
Drive 0 is the master drive.
$0314 (Write) - FDC Control (Bit 7)
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.

$0310 (Read) - FDC 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.

For Restore. Seek, Step, Step-in and Step-out
B0 Busy - When set command is in progress.
B1 DRQ - When set, indicates index mark detected from drive.
B2 Track 0 - When set, indicates Read/Write head is positioned to Track 0
B3 CRC Error - CRC encountered in ID field
B4 Seek Error - When set, the desired track was not verified.
B5 Head Loaded - When set, it indicates the head is loaded and engaged.
B6 Write Protect - When set, indicates Write Protect is activated.
B7 Not Ready - This bit when set indicates the drive is not ready.

For Read Address
B0 Busy - See Above
B1 DRQ - When set, it indicates the DR is full on a Read operation or the DR is empty on a Write operation.
B2 Lost Data - When set, it indicates the computer did not respond to DRQ in one byte time
B3 CRC Error - See Above
B4 RNF - When set, it indicates the desired track, sector, or side were not found.
B7 Not Ready - See Above

For Read Sector
B0 Busy - See Above
B1 DRQ - See Above
B2 Lost Data - See Above
B3 CRC Error - See Above
B4 RNF - See Above
B5 Record Type - On Read Record: it indicates the record-type code from data field address mark (1: Deleted Data Mark, 0: Data Mark).
B7 Not Ready - See Above

For Read Track
B0 Busy - See Above
B1 DRQ - See Above
B2 Lost Data - See Above
B7 Not Ready - See Above

For Write Sector
B0 Busy - See Above
B1 DRQ - See Above
B2 Lost Data - See Above
B3 CRC Error - See Above
B4 RNF - See Above
B5 Write Fault - Indicates a Write Fault.
B6 Write Protect - See Above
B7 Not Ready - See Above

For Write Track
B0 Busy - See Above
B1 DRQ - See Above
B2 Lost Data - See Above
B5 Write Fault - See Above
B6 Write Protect - See Above
B7 Not Ready - See Above

$0313 (Read) - FDC Data
$0314 (Read) - FDC INTRQ
$0318 (Read) - FDC DRQ (Bit 7)
Only Bit 7 is significant. Please refer to *1 above for further definition.

And Now a breakdown of the Commands.
Restore (Seek Track 0) (0000hVqr)
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 r1 r0 field are issued until the TR00 input is activated. At this time, the Track Register is loaded with zeroes and an interrupt is generated.

Seek (0001hVqr)
This 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.

Step (001ThVqr)
Upon receipt of this command, the FDC issues one stepping pulse to the disk drive. The stepping direction motor direction is the same as in the previous step command. An interrupt is generated at the end of the command.

Step-In (010ThVqr)
Upon 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.

Step-Out (011ThVqr)
Upon 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.

Read Sector (100mSEC0)
Upon 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. An 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).

Write Sector (101mSECa)
Upon 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.

Read Address (11000E00)
Upon 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.

Read Track (11100E00)
Upon 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 synchronization.

Write Track (formatting a track) (11110E00)
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.

Force Interrupt (1101IJKL)
The 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.


This is now reference material. If any corrections are mentioned when replying to this, they will be verified and updated above, so that we have a permanent up to date and accurate reference document.
Last edited by Twilighte on Sat Feb 04, 2006 7:57 pm, edited 1 time in total.
User avatar
Euphoric
Game master
Posts: 99
Joined: Mon Jan 09, 2006 11:33 am
Location: France

Post by Euphoric »

Hi Jon, just to be picky... :wink:
The disc drive may be one or two sides, some disc drives allow the second side to be read without having to flip the disc over (most 3.5" drives) but some do not (Most 3" drives).
Better say "Floppy disks might be either single or double sided, and disc drives might 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."
Their are usually 16 or 18 sectors per track and 256 bytes per sector because it makes it easier in the code.
Better say "Oric disk operating systems usually store 16 or 17 256-bytes sectors in each track (Stratsed allows to store 18 sectors, but it is not as reliable). Randos and BDDOS use 512-bytes sectors."
The FDC in the Microdisc system is memory mapped in the conventional I/O area of page 3 in the range $0310 to $0318.
Better say "The FDC in the Microdisc system is memory mapped in the conventional I/O area of page 3 in the range $0310 to $0313. Additionnal I/O registers and latches in the Microdisc electronics are mapped in the $0314-$031B address range."

and then, separate the definition of those Microdisc components...
$0314 to $0317 when write to is stored in a single Microdisc selection register.
$0314 to $0317 when read from latches the FDC INTRQ state
$0318 to $031B when read from latches the FDC DRQ state

For the FDC part, I think that giving the URL of WDC179x data sheet would be more readable...

Finally the description of the bits at $0314 could be improved, but I don't want to pick on your nerves
:wink:
User avatar
Twilighte
Game master
Posts: 819
Joined: Sat Jan 07, 2006 12:07 am
Location: Luton, UK
Contact:

Post by Twilighte »

I have amended the lines you mentioned. Please review and tell me if it now reads better. Though i'm not too hot on grammer myself, their were certain sentences that did not sound right so i took the liberty of changing them slightly.
BTW, the point of this document is to be an accurate definition of the FDC controller but providing a fairly easy-to-understand introduction in order to help people unfamiliar with the mechanics of a Disc Drive system. :)
Fabrice, you mentioned $314 could have had a better description, can you please expand :?:
User avatar
Euphoric
Game master
Posts: 99
Joined: Mon Jan 09, 2006 11:33 am
Location: France

Post by Euphoric »

Fabrice, you mentioned $314 could have had a better description, can you please expand ?
This is because you talk about the FDC when in fact it is the Microdisc controller. For me, the FDC is the WD 1793 chip. Actually, the topic should be titled "the Microdisc controller"... And by refering to the URL of the FDC, you would save repetition when describing the Jasmin controller (because it contains a compatible WD 1773 FDC)...

Anyway...
$0314 (Write) - FDC Control (Bit 0) *1
Their are two FDC Modes available to detect when data is ready when reading data from the Disc.
When this bit is set to Zero, Bit 7 of $0318 will be Zero when data is ready to be read from $0313.
When this bit is set to One, a non-maskable Interrupt will trigger when data is ready to be read from $0313.
I would say "bit 0 (write): enable FDC INTRQ to appear on read location $0314 and to drive cpu IRQ. When this bit is set to zero, the FDC will not interrupt the cpu, and bit 7 of $0314 will not reflect the interrupt condition of the FDC. When this bit is set to one, bit 7 of $0314 will reflect the interrupt status of the FDC and (if interrupts are enabled on the cpu), the FDC will interrupt the cpu. Reading $0314 permits to check the interrupt status of the FDC without resetting the interrupt condition."

NB: this bit has nothing to do with $0318 (the data request condition). And the interrupt is indeed an IRQ, i.e. a maskable interrupt.
$0314 (Write) - FDC Control (Bit 7)
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.
I would say "bit 7 (write): If internal Basic ROM has been disabled (bit 1 set to zero), this bit selects the internal Microdisc eprom (0) or switches it out (1). When enabled the eprom will overlay $E000 to $FFFF of ORIC RAM."

NB: the eprom contains a truncated/incomplete OricDOS v0.6

Cheers,

Fabrice
Post Reply