2 // Floppy register definitions
5 #define FLOPPY_REG_DOR 0x0002
6 #define FLOPPY_DOR_ENABLE 0x04
7 #define FLOPPY_DOR_DMA 0x08
8 #define FLOPPY_DOR_MOTOR0 0x10
9 #define FLOPPY_DOR_MOTOR1 0x20
10 #define FLOPPY_DRIVE0_ON ( FLOPPY_DOR_ENABLE | FLOPPY_DOR_DMA | FLOPPY_DOR_MOTOR0 )
11 #define FLOPPY_DRIVE1_ON ( FLOPPY_DOR_ENABLE | FLOPPY_DOR_DMA | FLOPPY_DOR_MOTOR1 | 1 )
12 #define FLOPPY_REG_MSTAT 0x0004
13 #define FLOPPY_MS_DRV0BUSY 0x01
14 #define FLOPPY_MS_DRV1BUSY 0x02
15 #define FLOPPY_MS_DRV2BUSY 0x04
16 #define FLOPPY_MS_DRV3BUSY 0x08
17 #define FLOPPY_MS_FDCBUSY 0x10
18 #define FLOPPY_MS_DMAMODE 0x20
19 #define FLOPPY_MS_DATADIR 0x40
20 #define FLOPPY_MS_RDYMASK 0xC0
21 #define FLOPPY_MS_DATARDYW 0x80
22 #define FLOPPY_MS_DATARDYR 0xC0
23 #define FLOPPY_REG_DATA 0x0005
24 #define FLOPPY_REG_DIR 0x0007 /* READ ONLY */
25 #define FLOPPY_DI_DSKCHNG 0x80
26 #define FLOPPY_REG_CCNTL 0x0007 /* WRITE ONLY */
27 #define FLOPPY_CCNTL_1MBIT 0x03
29 #define FLOPPY_CMD_RD_TRK 0x02
30 #define FLOPPY_CMD_SPEC_CHARS 0x03
31 #define FLOPPY_CSC_SRT_SHIFT 4
32 #define FLOPPY_CSC_HUT_MASK 0x0f
33 #define FLOPPY_CSC_HLT_SHIFT 1
34 #define FLOPPY_CSC_NON_DMA 0x01
35 #define FLOPPY_CMD_SNS_DRV 0x04
36 #define FLOPPY_CMD_WRT_DATA 0x05
37 #define FLOPPY_CMD_RD_DATA 0x06
38 #define FLOPPY_CMD_RECAL 0x07
39 #define FLOPPY_CMD_SNS_INTR 0x08
40 #define FLOPPY_ST0_SEEKGD 0x20
41 #define FLOPPY_ST0_GDMASK 0xd8
42 #define FLOPPY_CMD_WRT_DEL 0x09
43 #define FLOPPY_CMD_RD_ID 0x0a
44 #define FLOPPY_CMD_RD_DEL 0x0c
45 #define FLOPPY_CMD_FMT_TRK 0x0d
46 #define FLOPPY_CMD_DUMP_FDC 0x0e
47 #define FLOPPY_CMD_SEEK 0x0f
48 #define FLOPPY_CMD_VERSION 0x10
49 #define FLOPPY_CMD_SCN_EQ 0x11
50 #define FLOPPY_CMD_PPND_RW 0x12
51 #define FLOPPY_CMD_CFG_FIFO 0x13
52 #define FLOPPY_CMD_LCK_FIFO 0x14
53 #define FLOPPY_CMD_PARTID 0x18
54 #define FLOPPY_CMD_SCN_LE 0x19
55 #define FLOPPY_CMD_SCN_GE 0x1d
56 #define FLOPPY_CMD_CFG_PWR 0x27
57 #define FLOPPY_CMD_SAVE_FDC 0x2e
58 #define FLOPPY_CMD_FMT_ISO 0x33
59 #define FLOPPY_CMD_DMA_READ 0x46
60 #define FLOPPY_CMD_DMA_WRT 0x4a
61 #define FLOPPY_CMD_REST_FDC 0x4e
62 #define FLOPPY_CMD_DRV_SPEC 0x8e
63 #define FLOPPY_CMD_RSEEK_OUT 0x8f
64 #define FLOPPY_CMD_ULK_FIFO 0x94
65 #define FLOPPY_CMD_RSEEK_IN 0xcf
66 #define FLOPPY_CMD_FMT_WRT 0xef
68 // Command Code modifiers
69 #define FLOPPY_C0M_SK 0x20
70 #define FLOPPY_C0M_MFM 0x40
71 #define FLOPPY_C0M_MT 0x80
72 #define FLOPPY_C1M_DRVMASK 0x03
73 #define FLOPPY_C1M_HEAD1 0x04
75 // Status code values and masks
76 #define FLOPPY_ST0_INVALID 0x80
78 // useful command defines
79 #define FLOPPY_CMD_READ (FLOPPY_CMD_RD_DATA | FLOPPY_C0M_SK | FLOPPY_C0M_MFM | FLOPPY_C0M_MT)
80 #define FLOPPY_CMD_WRITE (FLOPPY_CMD_WRT_DATA | FLOPPY_C0M_MFM | FLOPPY_C0M_MT)
81 #define FLOPPY_CMD_FORMAT (FLOPPY_CMD_FMT_TRK | FLOPPY_C0M_MFM)
84 // HAL floppy register access commands
86 #define FloppyWriteDOR(A, V) (WRITE_PORT_UCHAR((PVOID)(A) + FLOPPY_REG_DOR, (V)))
87 #define FloppyReadMSTAT(A) (READ_PORT_UCHAR((PVOID)(A) + FLOPPY_REG_MSTAT))
88 #define FloppyReadDATA(A) (READ_PORT_UCHAR((PVOID)(A) + FLOPPY_REG_DATA))
89 #define FloppyWriteDATA(A, V) (WRITE_PORT_UCHAR((PVOID)(A) + FLOPPY_REG_DATA, (V)))
90 #define FloppyReadDIR(A) (READ_PORT_UCHAR((PVOID)(A) + FLOPPY_REG_DIR))
91 #define FloppyWriteCCNTL(A, V) (WRITE_PORT_UCHAR((PVOID)(A) + FLOPPY_REG_CCNTL, (V)))
93 typedef struct _FLOPPY_ERROR_THRESHOLDS
95 /* number of errors to be reached before aborting */
97 /* maximal number of errors permitted to read an entire track at once */
98 unsigned int ReadTrack;
99 /* maximal number of errors before a reset is tried */
101 /* maximal number of errors before a recalibrate is tried */
104 * Threshold for reporting FDC errors to the console.
105 * Setting this to zero may flood your screen when using
106 * ultra cheap floppies ;-)
108 unsigned int Reporting;
109 } FLOPPY_ERROR_THRESHOLDS;
111 typedef struct _FLOPPY_MEDIA_TYPE
116 DWORD SectorsPerTrack;
117 ULONG BytesPerSector;
120 extern const FLOPPY_MEDIA_TYPE MediaTypes[];
122 #define FDP_DEBUG 0x02
123 #define FDP_SILENT_DCL_CLEAR 0x04
125 #define FDP_BROKEN_DCL 0x20
126 #define FDP_INVERTED_DCL 0x80
128 // time to hold reset line low
129 #define FLOPPY_RESET_TIME 50000
130 #define FLOPPY_MOTOR_SPINUP_TIME -15000000
131 #define FLOPPY_MOTOR_SPINDOWN_TIME -50000000
132 #define FLOPPY_RECAL_TIMEOUT -30000000
134 typedef BOOLEAN (*FloppyIsrStateRoutine)( PCONTROLLER_OBJECT Controller );
135 typedef PIO_DPC_ROUTINE FloppyDpcStateRoutine;
137 typedef struct _FLOPPY_DEVICE_EXTENSION
139 PCONTROLLER_OBJECT Controller;
141 CHAR Cyl; // current cylinder
142 ULONG MediaType; // Media type index
143 } FLOPPY_DEVICE_EXTENSION, *PFLOPPY_DEVICE_EXTENSION;
145 typedef struct _FLOPPY_CONTROLLER_EXTENSION
147 PKINTERRUPT Interrupt;
152 KEVENT Event; // Event set by ISR/DPC to wake DeviceEntry
153 PDEVICE_OBJECT Device; // Pointer to the primary device on this controller
154 PIRP Irp; // Current IRP
155 CHAR St0; // Status registers
159 FloppyIsrStateRoutine IsrState; // pointer to state routine handler for ISR
160 FloppyDpcStateRoutine DpcState; // pointer to state routine handler for DPC
161 CHAR MotorOn; // drive select for drive with motor on
162 KDPC MotorSpinupDpc; // DPC for motor spin up time
163 KTIMER SpinupTimer; // Timer for motor spin up time
164 KDPC MotorSpindownDpc; // DPC for motor spin down
165 PADAPTER_OBJECT AdapterObject; // Adapter object for dma
166 PVOID MapRegisterBase;
167 DWORD TransferLength; // Length of the transfer
168 } FLOPPY_CONTROLLER_EXTENSION, *PFLOPPY_CONTROLLER_EXTENSION;
170 typedef struct _FLOPPY_CONTROLLER_PARAMETERS
175 KINTERRUPT_MODE InterruptMode;
176 } FLOPPY_CONTROLLER_PARAMETERS, *PFLOPPY_CONTROLLER_PARAMETERS;
178 #define FLOPPY_MAX_CONTROLLERS 1
181 FloppyDpcDetectMedia(PKDPC Dpc,
182 PDEVICE_OBJECT DeviceObject,
186 FloppyDpcFailIrp(PKDPC Dpc,
187 PDEVICE_OBJECT DeviceObject,
191 IO_ALLOCATION_ACTION STDCALL
192 FloppyExecuteReadWrite(PDEVICE_OBJECT DeviceObject,
194 PVOID MapRegisterbase,
197 IO_ALLOCATION_ACTION STDCALL
198 FloppyExecuteSpindown(PDEVICE_OBJECT DeviceObject,
200 PVOID MapRegisterbase,
204 FloppyMotorSpinupDpc(PKDPC Dpc,
210 FloppySeekDpc(PKDPC Dpc,
211 PDEVICE_OBJECT DeviceObject,
216 FloppyMotorSpindownDpc(PKDPC Dpc,
222 FloppyDpcDetect(PKDPC Dpc,
223 PDEVICE_OBJECT DeviceObject,
228 FloppyDpcReadWrite(PKDPC Dpc,
229 PDEVICE_OBJECT DeviceObject,
235 PDEVICE_OBJECT DeviceObject,
239 BOOLEAN FloppyIsrDetect( PCONTROLLER_OBJECT Controller );
241 BOOLEAN FloppyIsrReadWrite( PCONTROLLER_OBJECT Controller );
243 BOOLEAN FloppyIsrUnexpected( PCONTROLLER_OBJECT Controller );
245 BOOLEAN FloppyIsrDetectMedia( PCONTROLLER_OBJECT Controller );
247 BOOLEAN FloppyIsrRecal( PCONTROLLER_OBJECT Controller );
250 FloppyIsr(PKINTERRUPT Interrupt,
251 PVOID ServiceContext);
253 IO_ALLOCATION_ACTION STDCALL
254 FloppyAdapterControl(PDEVICE_OBJECT DeviceObject,
256 PVOID MapRegisterBase,