Last modified on 21 September 2024, at 20:24

765 FDC

Revision as of 20:24, 21 September 2024 by Phi2x (Talk | contribs) (FDC Command Table (15 commands))

µPD765 - Floppy Disc Controller (used in DDI-1 and CPC 664/6128).

The ports used by Amstrad and compatible interfaces use:

  • Port &FA7E - Floppy Motor On/Off Flipflop
  • Port &FB7E - FDC 765 Main Status Register (read only)
  • Port &FB7F - FDC 765 Data Register (read/write)

The Vortex disc interface uses other ports. See its dedicated wiki page.


IC Models used in CPC

More than one manufacturer made 765 compatible ICs. These are the ones known to be used in the CPC by looking at pictures of CPC mainboards.

All should operate almost identically.

The following data seperators are used:

The CPC464, CPC472, 464 Plus and GX4000 are not equipped with a FDC chip.


Accessing the FDC 765

The Main Status Register (Port &FB7E) signalizes when the FDC is ready to send/receive the next byte through the Data Register.

The Data Register (Port &FB7F) is used to write Commands and Parameters, to read/write data bytes, and to receive result bytes. These three operations are called Command-, Execution-, and Result-Phase.


Command Phase

A command consists of a command byte (eventually including the MT, MF, SK bits), and up to 8 parameter bytes.


Execution Phase

During this phase, the actual data is transferred (if any). Usually that are the data bytes for the read/written sector(s), except for the Format Track Command, in that case 4 bytes for each sector are transferred.

During data transfers between the FDC and the processor, the FDC must be serviced every 26µs (for MFM mode with CPC timings) or the FDC terminates the FDC command.


Result Phase

Returns up to 7 result bytes (depending on the command) that are containing status information. The Recalibrate and Seek Track commands do not return result bytes directly, instead the program must wait until the Main Status Register signalizes that the command has been completed, and then it must (!) send a Sense Interrupt State command to 'terminate' the Seek/Recalibrate command.

During the result phase, all the result bytes must be read. The FDC will not accept a new command until all the result bytes are read.


FDC Command Table (15 commands)

Read Data (06h)
D7 D6 D5 D4 D3 D2 D1 D0
command byte 0 MT MF SK 0 0 1 1 0
command byte 1 x HD US
command byte 2 C: cylinder number
command byte 3 H: head number
command byte 4 R: sector number
command byte 5 N: bytes per sector
command byte 6 EOT: end of track (ie. last sector in track)
command byte 7 GPL: gap 3 length
command byte 8 DTL: data length (if command byte 5==0)
Execution Data-transfer from the FDD
result byte 0 ST0: status register 0
result byte 1 ST1: status register 1
result byte 2 ST2: status register 2
result byte 3 C: cylinder number
result byte 4 H: head number
result byte 5 R: sector number
result byte 6 N: bytes per sector
Read Deleted Data (0Ch)
D7 D6 D5 D4 D3 D2 D1 D0
command byte 0 MT MF SK 0 1 1 0 0
command byte 1 x HD US
command byte 2 C: cylinder number
command byte 3 H: head number
command byte 4 R: sector number
command byte 5 N: bytes per sector
command byte 6 EOT: end of track (ie. last sector in track)
command byte 7 GPL: gap 3 length
command byte 8 DTL: data length (if command byte 5==0)
Execution Data-transfer from the FDD
result byte 0 ST0: status register 0
result byte 1 ST1: status register 1
result byte 2 ST2: status register 2
result byte 3 C: cylinder number
result byte 4 H: head number
result byte 5 R: sector number
result byte 6 N: bytes per sector
Write Data (05h)
D7 D6 D5 D4 D3 D2 D1 D0
command byte 0 MT MF x 0 0 1 0 1
command byte 1 x HD US
command byte 2 C: cylinder number
command byte 3 H: head number
command byte 4 R: sector number
command byte 5 N: bytes per sector
command byte 6 EOT: end of track (ie. last sector in track)
command byte 7 GPL: gap 3 length
command byte 8 DTL: data length (if command byte 5==0)
Execution Data-transfer to the FDD
result byte 0 ST0: status register 0
result byte 1 ST1: status register 1
result byte 2 ST2: status register 2
result byte 3 C: cylinder number
result byte 4 H: head number
result byte 5 R: sector number
result byte 6 N: bytes per sector
Write Deleted Data (09h)
D7 D6 D5 D4 D3 D2 D1 D0
command byte 0 MT MF x 0 1 0 0 1
command byte 1 x HD US
command byte 2 C: cylinder number
command byte 3 H: head number
command byte 4 R: sector number
command byte 5 N: bytes per sector
command byte 6 EOT: end of track (ie. last sector in track)
command byte 7 GPL: gap 3 length
command byte 8 DTL: data length (if command byte 5==0)
Execution Data-transfer to the FDD
result byte 0 ST0: status register 0
result byte 1 ST1: status register 1
result byte 2 ST2: status register 2
result byte 3 C: cylinder number
result byte 4 H: head number
result byte 5 R: sector number
result byte 6 N: bytes per sector
Read Track (02h)
D7 D6 D5 D4 D3 D2 D1 D0
command byte 0 x MF SK 0 0 0 1 0
command byte 1 x HD US
command byte 2 C: cylinder number
command byte 3 H: head number
command byte 4 R: sector number
command byte 5 N: bytes per sector
command byte 6 EOT: end of track (ie. last sector in track)
command byte 7 GPL: gap 3 length
command byte 8 DTL: data length (if command byte 5==0)
Execution FDC reads all data fields from index hole to EOT
result byte 0 ST0: status register 0
result byte 1 ST1: status register 1
result byte 2 ST2: status register 2
result byte 3 C: cylinder number
result byte 4 H: head number
result byte 5 R: sector number
result byte 6 N: bytes per sector
Read ID (0Ah)
D7 D6 D5 D4 D3 D2 D1 D0
command byte 0 x MF x 0 1 0 1 0
command byte 1 x HD US
Execution The first correct ID information on the cylinder is stored in data register
result byte 0 ST0: status register 0
result byte 1 ST1: status register 1
result byte 2 ST2: status register 2
result byte 3 C: cylinder number
result byte 4 H: head number
result byte 5 R: sector number
result byte 6 N: bytes per sector
Format Track (0Dh)
D7 D6 D5 D4 D3 D2 D1 D0
command byte 0 x MF x 0 1 1 0 1
command byte 1 x HD US
command byte 2 N: bytes per sector
command byte 3 SC: sectors per track
command byte 4 GPL: gap 3 length
command byte 5 D: filler pattern to write in each byte
Execution FDC formats an entire track
result byte 0 ST0: status register 0
result byte 1 ST1: status register 1
result byte 2 ST2: status register 2
result byte 3 C: cylinder number
result byte 4 H: head number
result byte 5 R: sector number
result byte 6 N: bytes per sector
Scan Equal (11h)
D7 D6 D5 D4 D3 D2 D1 D0
command byte 0 MT MF SK 1 0 0 0 1
command byte 1 x HD US
command byte 2 C: cylinder number
command byte 3 H: head number
command byte 4 R: sector number
command byte 5 N: bytes per sector
command byte 6 EOT: end of track (ie. last sector in track)
command byte 7 GPL: gap 3 length
command byte 8 STP: scan test (1=scan contiguous, 2=scan alternate)
Execution Data compared between the FDD and main-system
result byte 0 ST0: status register 0
result byte 1 ST1: status register 1
result byte 2 ST2: status register 2
result byte 3 C: cylinder number
result byte 4 H: head number
result byte 5 R: sector number
result byte 6 N: bytes per sector
Scan Low or Equal (19h)
D7 D6 D5 D4 D3 D2 D1 D0
command byte 0 MT MF SK 1 1 0 0 1
command byte 1 x HD US
command byte 2 C: cylinder number
command byte 3 H: head number
command byte 4 R: sector number
command byte 5 N: bytes per sector
command byte 6 EOT: end of track (ie. last sector in track)
command byte 7 GPL: gap 3 length
command byte 8 STP: scan test (1=scan contiguous, 2=scan alternate)
Execution Data compared between the FDD and main-system
result byte 0 ST0: status register 0
result byte 1 ST1: status register 1
result byte 2 ST2: status register 2
result byte 3 C: cylinder number
result byte 4 H: head number
result byte 5 R: sector number
result byte 6 N: bytes per sector
Scan High or Equal (1Dh)
D7 D6 D5 D4 D3 D2 D1 D0
command byte 0 MT MF SK 1 1 1 0 1
command byte 1 x HD US
command byte 2 C: cylinder number
command byte 3 H: head number
command byte 4 R: sector number
command byte 5 N: bytes per sector
command byte 6 EOT: end of track (ie. last sector in track)
command byte 7 GPL: gap 3 length
command byte 8 STP: scan test (1=scan contiguous, 2=scan alternate)
Execution Data compared between the FDD and main-system
result byte 0 ST0: status register 0
result byte 1 ST1: status register 1
result byte 2 ST2: status register 2
result byte 3 C: cylinder number
result byte 4 H: head number
result byte 5 R: sector number
result byte 6 N: bytes per sector
Recalibrate (07h)
D7 D6 D5 D4 D3 D2 D1 D0
command byte 0 x 0 0 1 1 1
command byte 1 x US
Execution Head retracted to track 0
Seek (0Fh)
D7 D6 D5 D4 D3 D2 D1 D0
command byte 0 x 0 1 1 1 1
command byte 1 x HD US
command byte 2 NCN: new cylinder number
Execution Head is positioned over proper cylinder
Sense Interrupt Status (08h)
D7 D6 D5 D4 D3 D2 D1 D0
command byte 0 x 0 1 0 0 0
result byte 0 ST0: status register 0
result byte 1 PCN: present cylinder number
Sense Drive Status (04h)
D7 D6 D5 D4 D3 D2 D1 D0
command byte 0 x 0 0 1 0 0
command byte 1 x HD US
result byte 0 ST3: status register 3
Specify (03h)
D7 D6 D5 D4 D3 D2 D1 D0
command byte 0 x 0 0 0 1 1
command byte 1 SRT HUT
command byte 2 HLT ND
Invalid
D7 D6 D5 D4 D3 D2 D1 D0
command byte 0 x Invalid Codes
result byte 0 ST0: status register 0

Abbreviations used:

  • N = 2^(n+7) bytes. For example, N=2 means 512 bytes
  • MT = Multi-track (continue multi-sector function on other head)
  • MF = MFM mode (1 = Double Density)
  • SK = Skip deleted-data address mark (set if sectors with deleted DAM shall be skipped)
  • HD = Head number select
  • US = Unit select (drive select)
  • HLT = Head Load Time: 2 to 254ms in 2ms increments
  • HUT = Head Unload Time: 16 to 240ms in 16ms increments
  • SRT = Step Rate Time: 1 to 16ms in 1ms increments (F = 1ms, E = 2ms, etc.)
  • ND = Non-DMA mode

Notes:

  • Specify: All timings will be doubled on CPC because the FDC runs at 4MHz instead of 8MHz for the datasheet
  • Format Track: The processor must supply C, H, R, N to the FDC for each sector during execution phase
  • Recalibrate: Walks up to 77 tracks, 80-track drives may need a second recalibrate if failed
  • Seek / Recalibrate: All read/write commands will be disabled until successful sense interrupt


FDC Status Registers

The Main Status register can always be read through Port &FB7E. The other four Status Registers cannot be read directly, instead they are returned through the data register as result bytes in response to specific commands.

Main Status Register (Port &FB7E):

 b0..3  DB   FDD0..3 Busy (seek/recalib active, until succesful sense intstat)
 b4     CB   FDC Busy (still in command-, execution- or result-phase)
 b5     EXM  Execution Mode (still in execution-phase, non_DMA_only)
 b6     DIO  Data Input/Output (0=CPU->FDC, 1=FDC->CPU) (see b7)
 b7     RQM  Request For Master (1=ready for next byte) (see b6 for direction)

Status Register 0:

 b0,1   US   Unit Select (driveno during interrupt)
 b2     HD   Head Address (head during interrupt)
 b3     NR   Not Ready (drive not ready or non-existing 2nd head selected)
 b4     EC   Equipment Check (drive failure or recalibrate failed (retry))
 b5     SE   Seek End (Set if seek-command completed)
 b6,7   IC   Interrupt Code (0=OK, 1=aborted:readfail/OK if EN, 2=unknown cmd
             or senseint with no int occured, 3=aborted:disc removed etc.)

Status Register 1:

 b0     MA   Missing Address Mark (Sector_ID or DAM not found)
 b1     NW   Not Writeable (tried to write/format disc with wprot_tab=on)
 b2     ND   No Data (Sector_ID not found, CRC fail in ID_field)
 b3,6   0    Not used
 b4     OR   Over Run (CPU too slow in execution-phase (ca. 26us/Byte))
 b5     DE   Data Error (CRC-fail in ID- or Data-Field)
 b7     EN   End of Track (set past most read/write commands) (see IC)

Status Register 2:

 b0     MD   Missing Address Mark in Data Field (DAM not found)
 b1     BC   Bad Cylinder (read/programmed track-ID different and read-ID = FF)
 b2     SN   Scan Not Satisfied (no fitting sector found)
 b3     SH   Scan Equal Hit (equal)
 b4     WC   Wrong Cylinder (read/programmed track-ID different) (see b1)
 b5     DD   Data Error in Data Field (CRC-fail in data-field)
 b6     CM   Control Mark (read/scan command found sector with deleted DAM)
 b7     0    Not Used

Status Register 3:

 b0,1   US   Unit Select (pin 28,29 of FDC)
 b2     HD   Head Address (pin 27 of FDC)
 b3     TS   Two Side (0=yes, 1=no (!))
 b4     T0   Track 0 (on track 0 we are)
 b5     RY   Ready (drive ready signal)
 b6     WP   Write Protected (write protected)
 b7     FT   Fault (if supported: 1=Drive failure)


C, H, R, N values at result phase

If the processor terminates a read (or write) operation in the FDC, then the ID information in the Result phase is dependent upon the state of the MT bit and EOT byte:

MT HD Final Sector Transferred to Processor ID Information at Result Phase
C H R N
0 0 Less than EOT - - R + 1 -
0 0 Equal to EOT C + 1 - 0 -
0 1 Less than EOT - - R + 1 -
0 1 Equal to EOT C + 1 - 0 -
1 0 Less than EOT - - R + 1 -
1 0 Equal to EOT - LSB 0 -
1 1 Less than EOT - - R + 1 -
1 1 Equal to EOT C + 1 LSB 0 -
  • An empty cell means it is the same value as the one at the beginning of command execution
  • LSB (Least Significant Bit): The least significant bit of H is complemented


Motor On/Off Flipflop

Writing 00h to Port &FA7E turns all disk drive motors off, writing 01h turns all motors on. It is not possible to turn on/off the motor of a specific drive separately.

An exception are the Vortex F1-S, F1-D, M1-S and M1-D drives. (How are they different?)

The floppy disc rotates at a nominal speed of 300rpm, with some tolerance.


Unconnected Pins

At the end of a successful read or write command, the program should send a Terminal Count (TC) signal to the FDC. However, in the CPC the TC pin isn't connected to the I/O bus, making it impossible for the program to confirm a correct operation. For that reason, the FDC will assume that the command has failed, and it'll return both Bit 6 in Status Register 0 and Bit 7 in Status Register 1 set. The program should ignore this error message.

The CPC doesn't support floppy DMA transfers, and the FDC's Interrupt signal isn't used in the CPC.

The FDC controller inside the CPC or in the Amstrad DDI-1 expansion doesn't have the US1 pin connected. This means it can only select floppy drives 0 and 1, and not drives 2 and 3.

However, the FDC in the Vortex disc interface does have the US1 pin connected, so it can manage up to 4 floppy drives.


ABBA switch

The ABBA switch is a common hardware modification that allows users to swap between Drive A and Drive B.

On Amstrad CPC, some software and disk utilities were designed to run specifically from Drive A, creating a problem when the disk you needed was in Drive B.

The ABBA switch resolved this issue by allowing you to "swap" the designation of the two drives. When the switch is activated, Drive A becomes Drive B, and vice versa, effectively swapping their roles.


Ready / Disk Changed signal

This signal differs between floppy drives model:

  • For 3inch floppy drives (pin26), it is a "Ready" signal. The /RDY signal is active whenever a disk is installed and rotating in the drive.
  • For PC 3.5inch floppy drives (pin34), it is a "Disk Changed" signal. The /DSKCHG signal determines whether the same disk loaded during the previous disk access is still in the drive.

The easiest solution to this issue is to force the Ready signal on the cable. However, the CPC will hang if you type the CAT command with no disk inserted (inserting a disk will unblock it).

Alternatively, you can Modify PC floppy drives to create a Ready signal, or use Amiga floppy drives, which already have this signal.

Gotek drives with FlashFloppy or HxC firmware can also be configured to simulate the Ready signal.


Notes

Before accessing a disk you should issue a recalibrate command to the drive to move the head backwards until the track zero signal from the drive is sensed by the FDC. The FDC will also set its track counter for that drive to zero.

On an 80-track drive you may need to repeat that twice because some models of the FDC stop after 77 steps so if recalibrating from track 78 or above the controller might not reach track zero.

In order to format, read or write a sector on a specific track you must first seek that track using command 0Fh. That'll move the read/write head to the physical track number. If you don't do that then the FDC will attempt to read/write data from/to the current physical track, irrespective of the specified logical track ID.

The track, sector, and head IDs are logical IDs only. These logical IDs are defined when formatting the disk and aren't required to reflect the physical track, sector, or head numbers. However, when reading or writing a sector you must specify the same IDs that have been used during formatting.

Despite the name, a sector with a Deleted data Address Mark (DAM) is not deleted; the DAM-flag is just another ID bit. 'Deleted' sectors can be read/written just like normal data sectors and if that ID bit is specified correctly in the command.

Usually single sided 40-track 3" disk drives are used in CPCs. For practical purposes, 42 tracks could be used — the limit is specific to the drive and some support more tracks but 42 is a good maximum. The FDC controller can be used to control 80-tracks and/or double sided drives, though AMSDOS doesn't support such formats. AMSDOS supports a maximum of two disk drives only.


Floppy disk format specification

There are 3 standard formats in AMSDOS. They are all single-sided and double density (MFM), with the following characteristics:

DATA VENDOR or SYSTEM IBM
Sector size N=2 (512 bytes)
Number of sectors 9 8
Sector names &C1 to &C9 &41 to &49 &01 to &08
Sector interleave Yes No
Formatting byte &E5
Starting track 00
Ending track 39
Catalog position Track 0: sectors &C1 to &C4 Track 2: sectors &41 to &44 Track 1: sectors &01 to &04
Catalog size 2 KB
Catalog entries 64 max
Size per side 178 KB 169 KB 154 KB
Diskette size 356 KB 338 KB 308 KB

Note: To use 80-track drives and/or dual-head drives, you need to use another CPC DOS instead of AMSDOS. The most popular one is ParaDOS. It can handle up to 796KB instead of 178KB for AMSDOS.


DATA format

It is the most commonly used format on Amstrad CPC as it offers the most available space among the standard formats.


SYSTEM format

The SYSTEM format is a VENDOR format with the addition of information to boot the CP/M on:

  • Track 0: sectors &41, &42, &48, &49
  • Track 1: sectors &41, &46, &42, &47, &43, &48, &44, &49, &45

Type |CPM and you will find yourself under CP/M 2.2.

By the way, all the |CPM command does is load the 512 bytes of track 0 sector &41 into memory at address &100 and then execute it.


IBM format

Despite its name, the IBM format is not usable on PC as it uses the CP/M filesystem. PC floppies use the FAT12 filesystem instead.

Also, CP/M 2.2 supports the IBM format but CP/M Plus does not.


Catalog structure

It supports up to 64 entries of 32 bytes. A file larger than 16KB will require multiple entries in the catalog.

Byte offset Description Comment
0 User Number USER goes from 0 to 255. USER 229 (&E5) is for deleted files. RSX only gives access to USER 0 to 15.
1-8 Filename (excluding full stop) Always in CAPS and maximum 8 characters long.
9-11 Extension Always in CAPS and maximum 3 characters long. Read Only flag on byte9 bit7. Hidden flag on byte10 bit7. Archive flag on byte11 bit7.
12 Current Extent 0 is first extent. A file can have up to 4 entries (extent 0 to 3). So files cannot be larger than 64KB.
13 Reserved
14 Extent High Byte Not used.
15 Record Count (Number of 128 Byte Blocks) Goes up to 128 (&80).
16–31 Cluster ID where to find the file data 1 byte is used per 1KB bloc.

Note: Each file is usually stored with an AMSDOS Header but can also be headerless.

CAT'art

The catalog structure can be hacked by using ascii control characters (codes 0 to 31) to create decorated catalogs (CAT'art).

CAT never loads and executes a boot sector. It just displays the chars of the files using "TXT OUTPUT" (#bb5a) which will execute control codes as well.

There were already tools from the 80ies for modifying a directory in a way that will display colourful chars placed at any location on the screen by adding dummy file entries with 0KB sizes. Or you hardcode it directly by yourself, which allows much more chars and effects.

The trick is to disable text output at the end of a filename to prevent printing file sizes/line feeds and enable it again at the beginning of the next filename; and you also have to use one hidden char for sorting them in the correct order.

See here for more details: All about CAT'arts (FR)


FDC Track Format

FDC765 Track Format.png

The CRC is initialised to FFFF. It is updated byte by byte and uses the CCITT-CRC16 algorithm. It is written after the ID and data fields of each sector in big-endian format (high byte first and then low byte).


HD Floppy Disks on CPC

It is theoretically possible to use HD floppy disks (1.44MB) on CPC by using either a Gotek drive or Amiga HD floppy drives spinning at 150rpm. However, nobody has ever written a CPC DOS to make use of it.

On a real floppy drive, if you want to fit more sectors on the same track, you have 2 options: you can make the FDC run faster, or you can make the disk spin slower.

Normally, HD disks use a faster FDC (with an automatic switch between the slow and fast modes).

But, for example on Amiga systems with HD drives, they used floppy drives that spin slower for HD disks (150 rotations per minutes instead of 300) and this allow to use the same controller as before. By the time the floppy has done one complete rotation, you can write 18 sectors instead of just 9.

With a real PC HD floppy drive, this requires some mechanical modifications, and you may get into trouble if the spinning speed is not fast enough.

But with the Gotek, this is not a problem. You can have as many sectors as you want, and the Gotek will generate the index pulse (simulating the floppy completing a turn) after it has sent them all. So it is essentially emulating a floppy that turns very slowly. The FDC has no problems handling that, but you may need to be a bit more relaxed than usual with the timeouts, as it will be some time before the sector you need will pass in front of the drive head, and the index pulse will also be slower than usual.

On a Gotek drive, you can even simulate some fantasy floppy disks with up to 255 cylinders.


PC Floppy Drives

This chapter is relevant as many CPC users are using PC floppy drives on their CPC.

5.25inch PC diskette format

The IBM PC supports two standard diskette formats on a 5.25 inch drive:

  • The first is double sided, double density, 40 cylinders, which yields a capacity of 360KB per diskette. This is the original IBM PC format. The double density drive rotates at 300 RPM.
  • The second format was introduced with the PC-AT. It is double sided, quad density, 80 cylinders, with a total capacity of 1.2 MB. The high density drive rotates at 360 RPM, so only 15 sectors can be written on a track instead of 18.

3.5inch PC diskette format

The IBM PS/2 introduced two standard 3.5 inch diskette formats:

  • The first is a double sided, double density, 80 cylinders, format yielding a capacity of 720KB. The double density drive rotates at 300 RPM.
  • The other is double sided, quad density, 80 cylinders, with a total capacity of 1.44 MB. The high density drive rotates at 300 RPM.


Internal details of the chip

  • From a comment in the hackaday website: "Internally this is a microcoded part with a primative controller of NEC’s own design. Testing microcode embedded in a part can be troublesome. The uPD765 had a few extra gates associated with the DMA Request and DMA Ack pins. Presenting a certain illegal combination here places the part into a “test” mode and allows the sequencer microcode to be output on the normal Data pins. The sequencer microcode is responsible for high level commands such as Read Track, Recalibrate, Format Track, or Write Data. There is a similar test mode for the nano-code array which serializes data at the floppy disk head."


FDC Block Diagrams

FDC Intel 8272A block diagram.gif


WDC37C65 block diagram.png


Generic System Diagram

The Amstrad CPC and Amstrad Plus do not have a DMA controller associated with the FDC. The INT pin of the FDC is not connected either.

UPD765A System Diagram.png


PC to CPC floppy connector

Cpc6128floppytopcfloppy.gif


FDD Block Diagram

Floppy Disk Drive - Block Diagram.png


Datasheets


External links