369 lines
16 KiB
HTML
369 lines
16 KiB
HTML
<!DOCTYPE HTML PUBLIC "-//W3C//DTD HTML 4.0 Transitional//EN">
|
|
<!-- saved from url=(0062)http://210.176.23.167/~stupid/MyPrograms/Boost!/DFA/FLOPPY.TXT -->
|
|
<HTML><HEAD>
|
|
<META content="text/html; charset=gb2312" http-equiv=Content-Type>
|
|
<META content="MSHTML 5.00.3502.5390" name=GENERATOR></HEAD>
|
|
<BODY><XMP>:765:FDC:NEC 765:8272:floppy controller
|
|
^NEC mPD765 - Floppy Disk Controller - 8272A
|
|
|
|
% FDC Digital Output Register at 3F2h (all systems)
|
|
|
|
|7|6|5|4|3|2|1|0| port 3F2h (write only)
|
|
| | | | | | ------- floppy drive select (0=A, 1=B, 2=floppy C, ...)
|
|
| | | | | -------- 1 = FDC enable, 0 = hold FDC at reset
|
|
| | | | --------- 1 = DMA & I/O interface enabled (reserved PS/2)
|
|
| | | ---------- 1 = turn floppy drive A motor on
|
|
| | ----------- 1 = turn floppy drive B motor on
|
|
| ------------ 1 = turn floppy drive C motor on; (reserved PS/2)
|
|
------------- 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)
|
|
|
|
|7|6|5|4|3|2|1|0| port 3F4h (read only)
|
|
| | | | | | | ----- floppy drive 0 in seek mode/busy
|
|
| | | | | | ------ floppy drive 1 in seek mode/busy
|
|
| | | | | ------- floppy drive 2 in seek mode/busy (reserved PS/2)
|
|
| | | | -------- floppy drive 3 in seek mode/busy (reserved PS/2)
|
|
| | | --------- FDC read or write command in progress
|
|
| | ---------- FDC is in non-DMA mode
|
|
| ----------- I/O direction; 1 = FDC to CPU; 0 = CPU to FDC
|
|
------------ data reg ready for I/O to/from CPU (request for master)
|
|
|
|
% FDC Command Status Register 0 at 3F5h (all systems)
|
|
|
|
|7|6|5|4|3|2|1|0| Command Status Register 0 at port 3F5h
|
|
| | | | | | ------- unit selected at interrupt (0=A, 1=B, 2=...)
|
|
| | | | | -------- head number at interrupt (head 0 or 1)
|
|
| | | | --------- not ready on read/write or SS access to head 1
|
|
| | | ---------- equipment check (see note)
|
|
| | ----------- set to 1 when FDD completes a seek command
|
|
-------------- last command status (see below)
|
|
|
|
% Bits
|
|
% 76 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)
|
|
|
|
|7|6|5|4|3|2|1|0| Command Status Register 1 at port 3F5h
|
|
| | | | | | | ----- FDC cannot find ID address mark (see reg 2)
|
|
| | | | | | ------ write protect detected during write
|
|
| | | | | ------- FDC cannot find sector ID
|
|
| | | | -------- unused (always zero)
|
|
| | | --------- over-run; FDC not serviced in reasonable time
|
|
| | ---------- data error (CRC) in ID field or data field
|
|
| ----------- unused (always zero)
|
|
------------ 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
|
|
|
|
% FDC Command Status Register 2 at 3F5h (all systems)
|
|
|
|
|7|6|5|4|3|2|1|0| Command Status Register 2 at port 3F5h
|
|
| | | | | | | ----- missing address mark in data field
|
|
| | | | | | ------ bad cylinder, ID not found and Cyl Id=FFh
|
|
| | | | | ------- scan command failed, sector not found in cylinder
|
|
| | | | -------- scan command equal condition satisfied
|
|
| | | --------- wrong cylinder detected
|
|
| | ---------- CRC error detected in sector data
|
|
| ----------- sector with deleted data address mark detected
|
|
------------ unused (always zero)
|
|
|
|
- bit 0 of Status Register 1 and bit 4 of Status Register 2 are
|
|
related and mimic each other
|
|
|
|
% FDC Command Status Register 3 at 3F5h (FDD status, all systems)
|
|
|
|
|7|6|5|4|3|2|1|0| Floppy Disk Drive Status at port 3F5h
|
|
| | | | | | ------- FDD unit selected status (0=A, 1=B, 2=...)
|
|
| | | | | -------- FDD side head select status (0=head 0, 1=head 1)
|
|
| | | | --------- FDD two sided status signal
|
|
| | | ---------- FDD track zero status signal
|
|
| | ----------- FDD ready status signal
|
|
| ------------ FDD write protect status signal
|
|
------------- FDD fault status signal
|
|
|
|
|
|
^FDC Programming Considerations
|
|
|
|
% Three phases of command execution:
|
|
|
|
1. 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
|
|
2. Execution phase; FDC executes instruction & generates INT 6
|
|
3. 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:
|
|
|
|
1. turn disk motor on and set delay time for drive spin up
|
|
2. perform seek operation; wait for disk interrupt
|
|
3. prepare DMA chip to move data to memory
|
|
4. send read command and wait for transfer complete interrupt
|
|
5. read status information
|
|
6. 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 D7 D6 D5 D4 D3 D2 D1 D0
|
|
% (Diagnostic)
|
|
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 D7 D6 D5 D4 D3 D2 D1 D0
|
|
% (Write Sector IDs)
|
|
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 D7 D6 D5 D4 D3 D2 D1 D0
|
|
% Status
|
|
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 & D7 D6 D5 D4 D3 D2 D1 D0
|
|
% Head Load
|
|
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 D7 D6 D5 D4 D3 D2 D1 D0
|
|
% Status
|
|
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
|
|
|
|
% mPD765 Version D7 D6 D5 D4 D3 D2 D1 D0
|
|
|
|
command byte 0: ? ? ? 1 0 0 0 0
|
|
result byte 0: status register 0
|
|
90h = mPD765B; 80h = mPD765A or mPD765A-2
|
|
|
|
% Invalid Command
|
|
|
|
result byte 0: status register 0 (value of 80h)
|
|
|
|
% Key to Abbreviations
|
|
HD = Head Number Selected SK = SKip Deleted-data address mark
|
|
MT = Multi-Track US0 = drive select bit 0
|
|
MF = MFM mode US1 = drive select bit 1
|
|
ND = Non-DMA mode
|
|
|
|
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 mPD765
|
|
- accessed through ports 3F0h-3F7h; NEC mPD765 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 ~BIOS Data Area~ ~INT TABLE~ ~INT 13~
|
|
</XMP></BODY></HTML>
|