Table des matières
8275A- NEC µPD765 - Floppy Disk Controller
8275A-µPD765 Registers
3F0h - FDC Diskette Status Register A (PS/2)
bit | 3F0h PS/2 Disk Status Register A (read-only) |
---|---|
0 | direction |
1 | write protect |
2 | index |
3 | head 1 select |
4 | track 0 |
5 | step |
6 | second drive installed |
7 | interrupt pending |
3F1h - FDC Diskette Status Register B (PS/2)
bit | 3F1h PS/2 Disk Status Register B (read-only) |
---|---|
0 | motor enable 0 |
1 | motor enable 1 |
2 | write enable |
3 | read data (toggles w/positive transition in -RD DATA) |
4 | write data (toggles w/positive transition in WR DATA) |
5 | drive select |
6-7 | reserved |
FDC Digital Output Register at 3F2h (all systems)
bit | port 3F2h (write only) |
---|---|
0-1 | floppy drive select (0=A, 1=B, 2=floppy C, …) |
2 | 1 = FDC enable, 0 = hold FDC at reset |
3 | 1 = DMA & I/O interface enabled (reserved PS/2) |
4 | 1 = turn floppy drive A motor on |
5 | 1 = turn floppy drive B motor on |
6 | 1 = turn floppy drive C motor on; (reserved PS/2) |
7 | 1 = turn floppy drive D motor on; (reserved PS/2) |
- used to control drive motors, drive selection, and feature enable
- PS/2 only uses bit 0 for floppy drive select; bit 1 is reserved
- PS/2 only uses bits 5 & 4 for motor enable; bits 7&6 are reserved
- all DOR bits are cleared during controller reset
FDC Main Status Register at 3F4h (all systems)
bit | port 3F4h (read only) |
---|---|
0 | floppy drive 0 in seek mode/busy |
1 | floppy drive 1 in seek mode/busy |
2 | floppy drive 2 in seek mode/busy (reserved PS/2) |
3 | floppy drive 3 in seek mode/busy (reserved PS/2) |
4 | FDC read or write command in progress |
5 | FDC is in non-DMA mode |
6 | I/O direction; 1 = FDC to CPU; 0 = CPU to FDC |
7 | data reg ready for I/O to/from CPU (request for master) |
FDC Command Status Register 0 at 3F5h (all systems)
bit | Command Status Register 0 at port 3F5h |
---|---|
0-1 | unit selected at interrupt (0=A, 1=B, 2=…) |
2 | head number at interrupt (head 0 or 1) |
3 | not ready on read/write or SS access to head 1 |
4 | equipment check (see note) |
5 | set to 1 when FDD completes a seek command |
6-7 | last command status (see below) |
Bits 7-6 | Last Command Status |
---|---|
00 | command terminated successfully |
01 | command execution started but terminated abnormally |
10 | invalid command issued |
11 | command terminated abnormally due to a change in state of the Ready Signal from the FDC (reserved on PS/2) |
- equipment check can occur if FDD signals a fault or track zero is not found after 77 steps on a recalibrate command
- PS/2 only uses bits 1-0 for drive (values are 01b and 10b)
FDC Command Status Register 1 at 3F5h (all systems)
bit | Command Status Register 1 at port 3F5h |
---|---|
0 | FDC cannot find ID address mark (see reg 2) |
1 | write protect detected during write |
2 | FDC cannot find sector ID |
3 | unused (always zero) |
4 | over-run; FDC not serviced in reasonable time |
5 | data error (CRC) in ID field or data field |
6 | unused (always zero) |
7 | end of cylinder; sector# greater than sectors/track |
- bit 0 of Status Register 1 and bit 4 of Status Register 2 are related and mimic each other
3F5h - FDC Command Status Register 2 (all systems)
bit | Command Status Register 2 at port 3F5h |
---|---|
0 | missing address mark in data field |
1 | bad cylinder, ID not found and Cyl Id=FFh |
2 | scan command failed, sector not found in cylinder |
3 | scan command equal condition satisfied |
4 | wrong cylinder detected |
5 | CRC error detected in sector data |
6 | sector with deleted data address mark detected |
7 | unused (always zero) |
- bit 0 of Status Register 1 and bit 4 of Status Register 2 are related and mimic each other
3F5h - FDC Command Status Register 3 (FDD status, all systems)
bit | Floppy Disk Drive Status at port 3F5h |
---|---|
0-1 | FDD unit selected status (0=A, 1=B, 2=…) |
2 | FDD side head select status (0=head 0, 1=head 1) |
3 | FDD two sided status signal |
4 | FDD track zero status signal |
5 | FDD ready status signal |
6 | FDD write protect status signal |
7 | FDD fault status signal |
3F7h - FDC Digital Input Register (PS/2)
bit | 3F7h PS/2 Digital Input Register (read only) |
---|---|
0 | high density select |
1-6 | reserved |
7 | diskette change |
3F7h - FDC Configuration Control Register (PS/2)
bit | 3F7h PS/2 Config. Control Register (write only) |
---|---|
0-1 | DRC1, DRC0 (see below) |
2-7 | reserved |
DRC1 | DRC0 | |
---|---|---|
0 | 0 | 500000 bit per second mode |
0 | 1 | reserved |
1 | 0 | 250000 bit per second mode |
1 | 1 | reserved |
- Digital Input Register is used to sense the state of the (-diskette change) and the (-high density select) signals
- Configuration Control Register is used to set the transfer rate
FDC Programming Considerations
Three phases of command execution:
- Command phase; commands are sent from the CPU to the FDC via port 3F5h; bit 6 of the Status Register at 3F4h must be zero
- Execution phase; FDC executes instruction & generates INT 6
- Result phase; status and other information is available to CPU; INT 6 sets bit 7 of BIOS Data Area location 40:3E which can be polled for completion status
Example of a read operation:
- turn disk motor on and set delay time for drive spin up
- perform seek operation; wait for disk interrupt
- prepare DMA chip to move data to memory
- send read command and wait for transfer complete interrupt
- read status information
- turn disk motor off
Floppy Diskette Controller Operations (15 commands)
Read Data | D7 | D6 | D5 | D4 | D3 | D2 | D1 | D0 |
---|---|---|---|---|---|---|---|---|
command byte 0: | MT | MF | SK | 0 | 0 | 1 | 1 | 0 |
command byte 1: | ? | ? | ? | ? | ? | HD | US1 | US0 |
command byte 2: | cylinder number | |||||||
command byte 3: | head number | |||||||
command byte 4: | sector number | |||||||
command byte 5: | bytes per sector | |||||||
command byte 6: | end of track (last sector in track) | |||||||
command byte 7: | gap 3 length | |||||||
command byte 8: | data length (if cmd byte 5==0) | |||||||
result byte 0: | status register 0 | |||||||
result byte 1: | status register 1 | |||||||
result byte 2: | status register 2 | |||||||
result byte 3: | cylinder number | |||||||
result byte 4: | head number | |||||||
result byte 5: | sector number | |||||||
result byte 6: | bytes per sector |
Read Deleted Data | D7 | D6 | D5 | D4 | D3 | D2 | D1 | D0 |
---|---|---|---|---|---|---|---|---|
command byte 0: | MT | MF | SK | 0 | 1 | 1 | 0 | 0 |
command byte 1: | ? | ? | ? | ? | ? | HD | US1 | US0 |
command byte 2: | cylinder number | |||||||
command byte 3: | head number | |||||||
command byte 4: | sector number | |||||||
command byte 5: | bytes per sector | |||||||
command byte 6: | end of track (last sector in track) | |||||||
command byte 7: | gap 3 length | |||||||
command byte 8: | data length (if cmd byte 5==0) | |||||||
result byte 0: | status register 0 | |||||||
result byte 1: | status register 1 | |||||||
result byte 2: | status register 2 | |||||||
result byte 3: | cylinder number | |||||||
result byte 4: | head number | |||||||
result byte 5: | sector number | |||||||
result byte 6: | bytes per sector |
Write Data | D7 | D6 | D5 | D4 | D3 | D2 | D1 | D0 |
---|---|---|---|---|---|---|---|---|
command byte 0: | MT | MF | 0 | 0 | 0 | 1 | 0 | 1 |
command byte 1: | ? | ? | ? | ? | ? | HD | US1 | US0 |
command byte 2: | cylinder number | |||||||
command byte 3: | head number | |||||||
command byte 4: | sector number | |||||||
command byte 5: | bytes per sector | |||||||
command byte 6: | end of track (last sector in track) | |||||||
command byte 7: | gap 3 length | |||||||
command byte 8: | data length (if cmd byte 5==0) | |||||||
result byte 0: | status register 0 | |||||||
result byte 1: | status register 1 | |||||||
result byte 2: | status register 2 | |||||||
result byte 3: | cylinder number | |||||||
result byte 4: | head number | |||||||
result byte 5: | sector number | |||||||
result byte 6: | bytes per sector |
Write Deleted Data | D7 | D6 | D5 | D4 | D3 | D2 | D1 | D0 |
---|---|---|---|---|---|---|---|---|
command byte 0: | MT | MF | 0 | 0 | 1 | 0 | 0 | 1 |
command byte 1: | ? | ? | ? | ? | ? | HD | US1 | US0 |
command byte 2: | cylinder number | |||||||
command byte 3: | head number | |||||||
command byte 4: | sector number | |||||||
command byte 5: | bytes per sector | |||||||
command byte 6: | end of track (last sector in track) | |||||||
command byte 7: | gap 3 length | |||||||
command byte 8: | data length (if cmd byte 5==0) | |||||||
result byte 0: | status register 0 | |||||||
result byte 1: | status register 1 | |||||||
result byte 2: | status register 2 | |||||||
result byte 3: | cylinder number | |||||||
result byte 4: | head number | |||||||
result byte 5: | sector number | |||||||
result byte 6: | bytes per sector |
Read a Track (Diagnostic) | D7 | D6 | D5 | D4 | D3 | D2 | D1 | D0 |
---|---|---|---|---|---|---|---|---|
command byte 0: | 0 | MF | SK | 0 | 0 | 0 | 1 | 0 |
command byte 1: | ? | ? | ? | ? | ? | HD | US1 | US0 |
command byte 2: | cylinder number | |||||||
command byte 3: | head number | |||||||
command byte 4: | sector number | |||||||
command byte 5: | bytes per sector | |||||||
command byte 6: | end of track (last sector in track) | |||||||
command byte 7: | gap 3 length | |||||||
command byte 8: | data length (if cmd byte 5==0) | |||||||
result byte 0: | status register 0 | |||||||
result byte 1: | status register 1 | |||||||
result byte 2: | status register 2 | |||||||
result byte 3: | cylinder number | |||||||
result byte 4: | head number | |||||||
result byte 5: | sector number | |||||||
result byte 6: | bytes per sector |
Read ID | D7 | D6 | D5 | D4 | D3 | D2 | D1 | D0 |
---|---|---|---|---|---|---|---|---|
command byte 0: | 0 | MF | 0 | 0 | 1 | 0 | 1 | 0 |
command byte 1: | ? | ? | ? | ? | ? | HD | US1 | US0 |
result byte 0: | status register 0 | |||||||
result byte 1: | status register 1 | |||||||
result byte 2: | status register 2 | |||||||
result byte 3: | cylinder number | |||||||
result byte 4: | head number | |||||||
result byte 5: | sector number | |||||||
result byte 6: | bytes per sector |
Format a Track (Write Sector IDs) | D7 | D6 | D5 | D4 | D3 | D2 | D1 | D0 |
---|---|---|---|---|---|---|---|---|
command byte 0: | 0 | MF | 0 | 0 | 1 | 1 | 0 | 1 |
command byte 1: | ? | ? | ? | ? | ? | HD | US1 | US0 |
command byte 2: | bytes per sector | |||||||
command byte 3: | sectors per track | |||||||
command byte 4: | gap 3 length | |||||||
command byte 5: | filler pattern to write in each byte | |||||||
result byte 0: | status register 0 | |||||||
result byte 1: | status register 1 | |||||||
result byte 2: | status register 2 | |||||||
result byte 3: | cylinder number | |||||||
result byte 4: | head number | |||||||
result byte 5: | sector number | |||||||
result byte 6: | bytes per sector |
Scan Equal | D7 | D6 | D5 | D4 | D3 | D2 | D1 | D0 |
---|---|---|---|---|---|---|---|---|
command byte 0: | MT | MF | SK | 1 | 0 | 0 | 0 | 1 |
command byte 1: | ? | ? | ? | ? | ? | HD | US1 | US0 |
command byte 2: | cylinder number | |||||||
command byte 3: | head number | |||||||
command byte 4: | sector number | |||||||
command byte 5: | bytes per sector | |||||||
command byte 6: | end of track (last sector in track) | |||||||
command byte 7: | gap 3 length | |||||||
command byte 8: | scan test (1=scan contiguous, 2=scan alternate) | |||||||
result byte 0: | status register 0 | |||||||
result byte 1: | status register 1 | |||||||
result byte 2: | status register 2 | |||||||
result byte 3: | cylinder number | |||||||
result byte 4: | head number | |||||||
result byte 5: | sector number | |||||||
result byte 6: | bytes per sector |
Scan Low or Equal | D7 | D6 | D5 | D4 | D3 | D2 | D1 | D0 |
---|---|---|---|---|---|---|---|---|
command byte 0: | MT | MF | SK | 1 | 1 | 0 | 0 | 1 |
command byte 1: | ? | ? | ? | ? | ? | HD | US1 | US0 |
command byte 2: | cylinder number | |||||||
command byte 3: | head number | |||||||
command byte 4: | sector number | |||||||
command byte 5: | bytes per sector | |||||||
command byte 6: | end of track (last sector in track) | |||||||
command byte 7: | gap 3 length | |||||||
command byte 8: | scan test (1=scan contiguous, 2=scan alternate) | |||||||
result byte 0: | status register 0 | |||||||
result byte 1: | status register 1 | |||||||
result byte 2: | status register 2 | |||||||
result byte 3: | cylinder number | |||||||
result byte 4: | head number | |||||||
result byte 5: | sector number | |||||||
result byte 6: | bytes per sector |
Scan High or Equal | D7 | D6 | D5 | D4 | D3 | D2 | D1 | D0 |
---|---|---|---|---|---|---|---|---|
command byte 0: | MT | MF | SK | 1 | 1 | 1 | 0 | 1 |
command byte 1: | ? | ? | ? | ? | ? | HD | US1 | US0 |
command byte 2: | cylinder number | |||||||
command byte 3: | head number | |||||||
command byte 4: | sector number | |||||||
command byte 5: | bytes per sector | |||||||
command byte 6: | end of track (last sector in track) | |||||||
command byte 7: | gap 3 length | |||||||
command byte 8: | scan test (1=scan contiguous, 2=scan alternate) | |||||||
result byte 0: | status register 0 | |||||||
result byte 1: | status register 1 | |||||||
result byte 2: | status register 2 | |||||||
result byte 3: | cylinder number | |||||||
result byte 4: | head number | |||||||
result byte 5: | sector number | |||||||
result byte 6: | bytes per sector |
Recalibrate | D7 | D6 | D5 | D4 | D3 | D2 | D1 | D0 |
---|---|---|---|---|---|---|---|---|
command byte 0: | 0 | 0 | 0 | 0 | 0 | 1 | 1 | 1 |
command byte 1: | ? | ? | ? | ? | ? | 0 | US1 | US0 |
returns nothing |
Sense Interrupt Status | D7 | D6 | D5 | D4 | D3 | D2 | D1 | D0 |
---|---|---|---|---|---|---|---|---|
command byte 0: | 0 | 0 | 0 | 0 | 1 | 0 | 0 | 0 |
result byte 0: | status register 0 | |||||||
result byte 1: | present cylinder number |
Specify Step & Head Load | D7 | D6 | D5 | D4 | D3 | D2 | D1 | D0 |
---|---|---|---|---|---|---|---|---|
command byte 0: | 0 | 0 | 0 | 0 | 0 | 0 | 1 | 1 |
command byte 1: | step rate time - head unload time | |||||||
command byte 2: | ——head load time—— ND | |||||||
returns nothing |
Sense Drive Status | D7 | D6 | D5 | D4 | D3 | D2 | D1 | D0 |
---|---|---|---|---|---|---|---|---|
command byte 0: | 0 | 0 | 0 | 0 | 0 | 1 | 0 | 0 |
command byte 1: | ? | ? | ? | ? | ? | HD | US1 | US0 |
result byte 0: | status register 3 |
Seek | D7 | D6 | D5 | D4 | D3 | D2 | D1 | D0 |
---|---|---|---|---|---|---|---|---|
command byte 0: | 0 | 0 | 0 | 0 | 1 | 1 | 1 | 1 |
command byte 1: | ? | ? | ? | ? | ? | HD | US1 | US0 |
command byte 2: | new cylinder number | |||||||
returns nothing |
µPD765 Version | D7 | D6 | D5 | D4 | D3 | D2 | D1 | D0 |
---|---|---|---|---|---|---|---|---|
command byte 0: | ? | ? | ? | 1 | 0 | 0 | 0 | 0 |
result byte 0: | status register 0 | |||||||
90h = µPD765B; 80h = µPD765A or µPD765A-2 |
Invalid Command | |
result byte 0: | status register 0 (value of 80h) |
Key to Abbreviations
HD | Head Number Selected |
---|---|
MT | Multi-Track |
MF | MFM mode |
ND | Non-DMA mode |
SK | SKip Deleted-data address mark |
US0 | drive select bit 0 |
US1 | drive select bit 1 |
- Head Load Time = 2 to 254ms in 2ms increments
- Head Unload Time = 16 to 240ms in 16ms increments
- Step Rate Time = 1 to 16ms in 1ms increments
- PS/2 systems use the 8272A diskette controller which is software and port compatible with the NEC µPD765
- accessed through ports 3F0h-3F7h;
NEC µPD765 is accessed through ports 3F2h, 3F4h and 3F5h;
the 8272A uses ports 3F0h, 3F1h, 3F2h, 3F4h, 3F5h and 3F7h - data, command and status registers are all accessed through port 3F5h a register stack with one address presented to the bus
- bit 7 of BIOS Data Area byte 40:3E can be polled to determine if a disk operation has completed; this bit is set by the interrupt handler when the operation has completed; it should be reset before continuing on with the next FDC operation
- see INT 13h