CDL Modules
Files
fdc8271

Files

file  fdc8271.cdl
 CDL implementation of 8271 FDC.
 

Detailed Description

Modules

module fdc8271::fdc8271 ( clock  clk,
input bit  reset_n,
input bit  chip_select_n,
input bit  read_n,
input bit  write_n,
input bit  address[2],
input bit  data_in[8],
output bit  data_out[8],
output bit  irq_n,
output bit  data_req,
input bit  data_ack_n,
output bit  select[2],
input bit  ready[2],
output bit  fault_reset,
output bit  write_enable,
output bit  seek_step,
output bit  direction,
output bit  load_head,
output bit  low_current,
input bit  track_0_n,
input bit  write_protect_n,
input bit  index_n,
output t_bbc_floppy_op  bbc_floppy_op,
input t_bbc_floppy_response  bbc_floppy_response 
)

Diskettes had a standard format, with up to 80 (or so) tracks, each with a fixed layout

Each track would 'start' at the index marker, with a sync gap; the track then contained 'N' sectors each with an ID, a sync gap, data and another sync gap.

At the end there would be a final gap - but not a sync gap. A sync gap is 8hff's followed by six 8h00's. The final gap is all 8hff.

What this means is that effectively a track is 1's until the first sector Each sector is 48 0's, then a sector ID (which starts with a 1) followed by 1's with about 48 0's separating the ID from the sector data. The sector data starts with a single marker byte (starting with a 1) followed by the data and a CRC, followed by 1's.

The 48 0's may not always be 48, and the 1's may vary too - these are effectively start/stop regions, which can be encroached on by variations in disk speed.

Bytes on the disk are stored with a high clock pulse every 4us, and a low or high data pulse in the middle (i.e. after 2us).

Each bit on the disk is normally 4us, and a track is notionally 8*5,208 bits, so 166,656us (basically 1/6th of a second). This is because the disk spins at 360rpm, 6rps. At 4us/bit, a byte is read a 32us/byte - this is the NMI response time.

Note that the index markers have gapped clocks, to identify them properly - but the data is guaranteed to have ones, so the disk will not have just zeros for the index markers.

A simple implementation of a disk system might just support the sector data with a fixed number of sectors. However, for more flexibility (and perhaps ease of hardware implementation here) an alternative approach can be taken. This is to have a sector descriptor memory, as well as a disk data memory.

The sector descriptor memory is indexed by track and sector number. Supporting up to 16 sectors per track means that a sector descriptor memory is addressed by {track[7;0], sector[4;0]} - an 11-bit address. The sector descriptor memory is indexed by physical sector - i.e. the position on the track. The sector descriptor memory contains the sector's logical sector number.

The sector descriptor (64 bits) must contain:

bit indicating it is valid (so that a max number of sectors <16 can be used) start address in disk data memory of sector data (excluding the bottom 7 bits must be zero, since sectors are always a multiple of 128 bytes)

id address mark for sector (8 bits) (8hFE, clock pattern 8hc7) track number (7 bits) head number (1 bit) sector number (4 bits) sector length (2 bits, 0=>128, 1=>256, 2=>512, 3=>1024) disk data address mark (8 bits) (8hFB valid, 8hf8 deleted data) (in the sector data itself on the disk) bit indicating ID has bad CRC bit indicating data has bad CRC

A disk descriptor then needs a base address of sector descriptor data, a base address of disk data memory, a number of tracks. For emulation purposes, the disk descriptor also includes details on how realistic the timing should be. It should also have a 'valid' bit (0 if disk not loaded), and a 'write protect' bit

The NMI code is: 7 (NMI brk) 3 0xd00 PHA 4 0xd01 LDA &FE28 ;; FDC Status/Command 2 0xd04 AND #&1F 2 0xd06 CMP #&03 2 0xd08 BNE LBCBA ... error handling 4 0xd0a LDA &FE2B ;; FDC Data 4 0xd0d STA &FFFF ;; Replaced with destination address 6 0xd10 INC 0xD0E 3 0xd13 BNE 0xd18

  • 0xd15 INC 0xD0F 4 0xd18 PLA 6 0xd19 RTI

Total of 47 cycles, or 23.5us per byte for data transfers

On a real drive, each track has 5208 bytes.
  index mark
  post-index gap, 32 bytes (26 0xff, 6 0x00 sync)
  Numsectors * { id field, 7 bytes; post-id field gap 17 bytes (11 0xff, 6 0x00 sync); data field (n bytes); post-data field gap 33 bytes (27 0xff, 6 0x00 sync) }
  trailing gap (40 0xff, 6 0x00 sync)

id field is:
  id address mark
  track address (00-74, officially in 8271)
  head address (0 or 1)
  sector address (01-26)
  sector length (0=>128, 1=>256, 2=>512)
  2 bytes CRC

data field is:
  data address mark
  N bytes data
  2 byte CRC

Command

command

Parameter

parameter

Write action

action

Status read

status

Result read

result

Seek track

track

Seek sector id

track

sector

Load head

track

Find index

track

Read id

track

Read data

track

sector

Parameters
[in]clk
[in]reset_n8271 has an active high reset, but...
[in]chip_select_nActive low chip select
[in]read_nIndicates a read transaction if asserted and chip selected
[in]write_nIndicates a write transaction if asserted and chip selected
[in]addressAddress of register being accessed
[in]data_inData in (from CPU)
[out]data_outRead data out (to CPU)
[out]irq_nWas INT on the 8271, but that means something else now; active low interrupt
[out]data_req
[in]data_ack_n
[out]selectdrive select
[in]readydrive ready
[out]fault_reset
[out]write_enableHigh if the drive should write data
[out]seek_stepHigh if the drive should step
[out]directionDirection of step
[out]load_headEnable drive head
[out]low_currentAsserted for track>=43
[in]track_0_nAsserted low if the selected drive is on track 0
[in]write_protect_nAsserted low if the selected drive is write-protected
[in]index_nAsserted low if the selected drive photodiode indicates start of track
[out]bbc_floppy_opModel drive operation, including write data
[in]bbc_floppy_responseParallel data read, specific to the model