QD6580 DOS Driver 3.7 analysis

Instalation:

   A:Install [/Option1] [/Option2]

 Option1 :
     S       For slow hard disk, its data transfer rate from 3.8 to 4.4MB/s or higher.
     N1      For normal-1 hard disk, its data transfer rate from 4.4 to 5.0MB/s or higher.
     N2      For normal-2 hard disk, its data transfer rate from 5.0 to 6.3MB/s or higher.
     F       For fast hard disk, its data transfer rate is higher than 6.3MB/s.
     T1      For secondary channel timing setting when the secondary channel connects one hard disk
     T2      For secondary channel timing setting when the secondary channel connects two hard disks
     U       For uninstall the software driver(s).
     H       For help information.

 Option2 :
     M       For hard disk that supports multiple sectors READ/WRITE.
     O       Forcing driver supports only single sector READ/WRITE.
     NI      Use motherboard BIOS HDD interrupt service routine INT 13H.

How does install program use command line parameters? It will change byte on address 42dh, for the first option upper nibble, for second lower nibble:
00 = no option
1x = S
2x = N1
3x = N2
4x = F
5x = T1
6x = T2
x1 = M
x2 = O
x3 = NI
x4 = undocumented, using 32-bit outsd and insd instructions

INITIALIZATION of the driver

Test if DOS version is 3.0 or higher
Test if QD6580 is present
Test if hda is present
If ok, IDENTIFY DRIVE (EC) command is issued. Based on read parameters and for older drives on name are determined three values - ActiveTime, RecoveryTime and multiple sectror R/W capability.
For multiple sectror R/W capability, SET MULTIPLE MODE (C6) command is issued.
The same for hdb
First programming of QD6580:
Initial setting: base+0 = 0, base+2 = 0, base+3 = 4Fh
- VL bus clock is determined by measuring how long it takes to transfer some amount of bytes - 4 values are finally recognized:
20 ns = 50 MHz
25 ns = 40 MHz
30 ns = 33 MHz
40 ns = 25 MHz
Port base+2 is programmed depending on speed to 0 for faster bus than 33 MHz and 0Ah for 33MHz or slower.
Port base+3 is programmed depending on bit 1 port base+3 - 0x5F for 0 (disk and ATAPI), 0xDF for 1 (disk peripherals only).
If not "NI", int13 is redirected into this driver
Test for advanced PIO modes for both drives:
Test for IORDY support
Test for PIO3 and PIO4
setting of PIO3 by "SET FEATURES" command, subcommand 3, set PIO mode.
determining active and recovery time:
PIO3 with IORDY: ActiveTime = 86 ns, RecoveryTime = CYCLE time - 102 ns
PIO4 with IORDY: ActiveTime = 70 ns, RecoveryTime = CYCLE time - 61 ns
without IORDY: ActiveTime = 110 ns, RecoveryTime = CYCLE time - 120 ns
CYCLE time is read by IDENTIFY DRIVE command.
Preset timing check:
Memory location 42dh (CmdLine) is checked.
1x = S = Slow = 3.8 to 4.4MB/s - active = 175 ns, recovery = 335ns
2x = N1 = Normal-1 = 4.4 to 5.0MB/s - active = 145 ns, recovery = 295 ns
3x = N2 = Normal-2 = 5.0 to 6.3MB/s - active = 110 ns, recovery = 265 ns
4x = F = Fast = more than 6.3MB/s - active = 110 ns, recovery = 195 ns
Test for hdb
For hdb present, IDENTIFY DRIVE is performed and for cylinder register = 0xEB14, i.e. ATAPI present,  port base+3 is set to 5Fh.
Setting base+0 and base+2 registers:
For bit 0 port base+3 = 0 (Both Primary and Secondary IDE ports enable)
base+0 register is programmed according to higher (worse) values active and recovery time for hda and hdb.
Active and recovery time are divided by VL-bus clock period, added 1 and than values modified.
For active time, the result is limited from 2 to 17 and then subtracted from 17, so that the range is 0 to 15 (0Fh). This is lower nibble
For recovery time, the result is limited from 2 to 15 and then subtracted from 15, so that the range is 0 to 13 (0Dh). This is upper nibble.
For bit 0 port base+3 = 1 (Only Primary IDE port enable)
base+0 register is programmed using calculation above for hda
base+2 register is programmed using calculation above for hdb
Secondary channel timing setting
If required by T1 or T2 options, secondary channel (on addresses 0x170-0x177) is programmed.
This driver has no other support for secondary channel than correct programming QD6580 chip. Temporarily it installs IRQ15 = INT77 handler.
If bit 0 port base+3 is 1, nothing is done.
Active time is fixed 115 ns and recovery time is read from "IDENTIFY COMMAND" less 115 ns.
base+2 register is programmed using calculation above.

That's it!

Here is zipped little bit commented disassembled listing of this driver.