720c828d3f67b2472cc2c91bf16392beee7f6f8b
[reactos.git] / reactos / drivers / storage / floppy / hardware.h
1 /*
2 * ReactOS Floppy Driver
3 * Copyright (C) 2004, Vizzini (vizzini@plasmic.com)
4 *
5 * This program is free software; you can redistribute it and/or modify
6 * it under the terms of the GNU General Public License as published by
7 * the Free Software Foundation; either version 2 of the License, or
8 * (at your option) any later version.
9 *
10 * This program is distributed in the hope that it will be useful,
11 * but WITHOUT ANY WARRANTY; without even the implied warranty of
12 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
13 * GNU General Public License for more details.
14 *
15 * You should have received a copy of the GNU General Public License along
16 * with this program; if not, write to the Free Software Foundation, Inc.,
17 * 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA.
18 *
19 * PROJECT: ReactOS Floppy Driver
20 * FILE: hardware.h
21 * PURPOSE: Header for FDC control routines
22 * PROGRAMMER: Vizzini (vizzini@plasmic.com)
23 * REVISIONS:
24 * 15-Feb-2004 vizzini - Created
25 *
26 * NOTES:
27 * - Baesd on http://www.nondot.org/sabre/os/files/Disk/FLOPPY.TXT
28 * - Some information taken from Intel 82077AA data sheet (order #290166-007)
29 * - Some definitions are PS/2-Specific; others include the original NEC PD765
30 * - Other information gathered from the comments in the NT 3.5 floppy driver
31 *
32 * TODO:
33 * - Convert these numbers to 100% absolute values; eliminate bit positions
34 * in favor of shifts or bitfields
35 */
36
37 #define FLOPPY_DEFAULT_IRQ 0x6
38 #define FDC_PORT_BYTES 0x8
39
40 /* Register offsets from base address (usually 0x3f8) */
41 #define STATUS_REGISTER_A 0x0 /* Read; PS/2 Only */
42 #define STATUS_REGISTER_B 0x1 /* Read; PS/2 Only */
43 #define DIGITAL_OUTPUT_REGISTER 0x2 /* Read/Write */
44 #define TAPE_DRIVE_REGISTER 0x3 /* Read/Write */
45 #define MAIN_STATUS_REGISTER 0x4 /* Read */
46 #define DATA_RATE_SELECT_REGISTER 0x4 /* Write */
47 #define FIFO 0x5 /* Read/Write */
48 #define RESERVED_REGISTER 0x6 /* Reserved */
49 #define DIGITAL_INPUT_REGISTER 0x7 /* Read; PS/2 Only */
50 #define CONFIGURATION_CONTROL_REGISTER 0x7 /* Write; PS/2 Only */
51
52 /* STATUS_REGISTER_A */
53 #define DSRA_DIRECTION 0x1
54 #define DSRA_WRITE_PROTECT 0x2
55 #define DSRA_INDEX 0x4
56 #define DSRA_HEAD_1_SELECT 0x8
57 #define DSRA_TRACK_0 0x10
58 #define DSRA_STEP 0x20
59 #define DSRA_SECOND_DRIVE_INSTALLED 0x40
60 #define DSRA_INTERRUPT_PENDING 0x80
61
62 /* STATUS_REGISTER_B */
63 #define DSRB_MOTOR_ENABLE_0 0x1
64 #define DSRB_MOTOR_ENABLE_1 0x2
65 #define DSRB_WRITE_ENABLE 0x4
66 #define DSRB_READ_DATA 0x8
67 #define DSRB_WRTITE_DATA 0x10
68 #define DSRB_DRIVE_SELECT 0x20
69
70 /* DIGITAL_OUTPUT_REGISTER */
71 #define DOR_FLOPPY_DRIVE_SELECT 0x3 /* Covers 2 bits, defined below */
72 #define DOR_FDC_ENABLE 0x4 /* from the website */
73 #define DOR_RESET 0x4 /* from the Intel guide; 0 = resetting, 1 = enabled */
74 #define DOR_DMA_IO_INTERFACE_ENABLE 0x8 /* Reserved on PS/2 */
75 #define DOR_FLOPPY_MOTOR_ON_A 0x10
76 #define DOR_FLOPPY_MOTOR_ON_B 0x20
77 #define DOR_FLOPPY_MOTOR_ON_C 0x40 /* Reserved on PS/2 */
78 #define DOR_FLOPPY_MOTOR_ON_D 0x80 /* Reserved on PS/2 */
79
80 /* DOR_FLOPPY_DRIVE_SELECT */
81 #define DOR_FLOPPY_DRIVE_SELECT_A 0x0
82 #define DOR_FLOPPY_DRIVE_SELECT_B 0x1
83 #define DOR_FLOPPY_DRIVE_SELECT_C 0x2 /* Reserved on PS/2 */
84 #define DOR_FLOPPY_DRIVE_SELECT_D 0x3 /* Reserved on PS/2 */
85
86 /* MAIN_STATUS_REGISTER */
87 #define MSR_FLOPPY_BUSY_0 0x1
88 #define MSR_FLOPPY_BUSY_1 0x2
89 #define MSR_FLOPPY_BUSY_2 0x4 /* Reserved on PS/2 */
90 #define MSR_FLOPPY_BUSY_3 0x8 /* Reserved on PS/2 */
91 #define MSR_READ_WRITE_IN_PROGRESS 0x10
92 #define MSR_NON_DMA_MODE 0x20
93 #define MSR_IO_DIRECTION 0x40 /* Determines meaning of Command Status Registers */
94 #define MSR_DATA_REG_READY_FOR_IO 0x80
95
96 /* DATA_RATE_SELECT_REGISTER */
97 #define DRSR_DSEL 0x3 /* covers two bits as defined below */
98 #define DRSR_PRECOMP 0x1c /* covers three bits as defined below */
99 #define DRSR_MBZ 0x20
100 #define DRSR_POWER_DOWN 0x40
101 #define DRSR_SW_RESET 0x80
102
103 /* DRSR_DSEL */
104 #define DRSR_DSEL_500KBPS 0x0
105 #define DRSR_DSEL_300KBPS 0x1
106 #define DRSR_DSEL_250KBPS 0x2
107 #define DRSR_DSEL_1MBPS 0x3
108
109 /* STATUS_REGISTER_0 */
110 #define SR0_UNIT_SELECTED_AT_INTERRUPT 0x3 /* Covers two bits as defined below */
111 #define SR0_HEAD_NUMBER_AT_INTERRUPT 0x4 /* Values defined below */
112 #define SR0_NOT_READY_ON_READ_WRITE 0x8 /* Unused in PS/2 */
113 #define SR0_SS_ACCESS_TO_HEAD_1 0x8 /* Unused in PS/2 */
114 #define SR0_EQUIPMENT_CHECK 0x10
115 #define SR0_SEEK_COMPLETE 0x20
116 #define SR0_LAST_COMMAND_STATUS 0xC0 /* Covers two bits as defined below */
117
118 /* SR0_UNIT_SELECTED_AT_INTERRUPT */
119 #define SR0_UNIT_SELECTED_A 0x0
120 #define SR0_UNIT_SELECTED_B 0x1
121 #define SR0_UNIT_SELECTED_C 0x2
122 #define SR0_UNIT_SELECTED_D 0x3
123 #define SR0_PS2_UNIT_SELECTED_A 0x1 /* PS/2 uses only two drives: A = 01b B = 10b */
124 #define SR0_PST_UNIT_SELECTED_B 0x2
125
126 /* SR0_HEAD_NUMBER_AT_INTERRUPT */
127 #define SR0_HEAD_0 0x0
128 #define SR0_HEAD_1 0x1
129
130 /* SR0_LAST_COMMAND_STATUS */
131 #define SR0_LCS_SUCCESS 0x0
132 #define SR0_LCS_TERMINATED_ABNORMALLY 0x40
133 #define SR0_LCS_INVALID_COMMAND_ISSUED 0x80
134 #define SR0_LCS_READY_SIGNAL_CHANGED 0xc0 /* Reserved on PS/2; a/k/a abnormal termination due to polling */
135
136 /* STATUS_REGISTER_1 */
137 #define SR1_CANNOT_FIND_ID_ADDRESS 0x1 /* Mimics SR2_WRONG_CYLINDER_DETECTED */
138 #define SR1_WRITE_PROTECT_DETECTED 0x2
139 #define SR1_CANNOT_FIND_SECTOR_ID 0x4
140 #define SR1_OVERRUN 0x10
141 #define SR1_CRC_ERROR 0x20
142 #define SR1_END_OF_CYLINDER 0x80
143
144 /* STATUS_REGISTER_2 */
145 #define SR2_MISSING_ADDRESS_MARK 0x1
146 #define SR2_BAD_CYLINDER 0x2
147 #define SR2_SCAN_COMMAND_FAILED 0x4
148 #define SR2_SCAN_COMMAND_EQUAL 0x8
149 #define SR2_WRONG_CYLINDER_DETECTED 0x10 /* Mimics SR1_CANNOT_FIND_ID_ADDRESS */
150 #define SR2_CRC_ERROR_IN_SECTOR_DATA 0x20
151 #define SR2_SECTOR_WITH_DELETED_DATA 0x40
152
153 /* STATUS_REGISTER_3 */
154 #define SR3_UNIT_SELECTED 0x3 /* Covers two bits; defined below */
155 #define SR3_SIDE_HEAD_SELECT_STATUS 0x4 /* Values defined below */
156 #define SR3_TWO_SIDED_STATUS_SIGNAL 0x8
157 #define SR3_TRACK_ZERO_STATUS_SIGNAL 0x10
158 #define SR3_READY_STATUS_SIGNAL 0x20
159 #define SR3_WRITE_PROTECT_STATUS_SIGNAL 0x40
160 #define SR3_FAULT_STATUS_SIGNAL 0x80
161
162 /* SR3_UNIT_SELECTED */
163 #define SR3_UNIT_SELECTED_A 0x0
164 #define SR3_UNIT_SELECTED_B 0x1
165 #define SR3_UNIT_SELECTED_C 0x2
166 #define SR3_UNIT_SELECTED_D 0x3
167
168 /* SR3_SIDE_HEAD_SELECT_STATUS */
169 #define SR3_SHSS_HEAD_0 0x0
170 #define SR3_SHSS_HEAD_1 0x1
171
172 /* DIGITAL_INPUT_REGISTER */
173 #define DIR_HIGH_DENSITY_SELECT 0x1
174 #define DIR_DISKETTE_CHANGE 0x80
175
176 /* CONFIGURATION_CONTROL_REGISTER */
177 #define CCR_DRC 0x3 /* Covers two bits, defined below */
178 #define CCR_DRC_0 0x1
179 #define CCR_DRC_1 0x2
180
181 /* CCR_DRC */
182 #define CCR_DRC_500000 0x0
183 #define CCR_DRC_250000 0x2
184
185 /* Commands */
186 #define COMMAND_READ_TRACK 0x2
187 #define COMMAND_SPECIFY 0x3
188 #define COMMAND_SENSE_DRIVE_STATUS 0x4
189 #define COMMAND_WRITE_DATA 0x5
190 #define COMMAND_READ_DATA 0x6
191 #define COMMAND_RECALIBRATE 0x7
192 #define COMMAND_SENSE_INTERRUPT_STATUS 0x8
193 #define COMMAND_WRITE_DELETED_DATA 0x9
194 #define COMMAND_READ_ID 0xA
195 #define COMMAND_READ_DELETED_DATA 0xC
196 #define COMMAND_FORMAT_TRACK 0xD
197 #define COMMAND_SEEK 0xF
198 #define COMMAND_VERSION 0x10
199 #define COMMAND_SCAN_EQUAL 0x11
200 #define COMMAND_CONFIGURE 0x13
201 #define COMMAND_SCAN_LOW_OR_EQUAL 0x19
202 #define COMMAND_SCAN_HIGH_OR_EQUAL 0x1D
203
204 /* COMMAND_READ_DATA constants */
205 #define READ_DATA_DS0 0x1
206 #define READ_DATA_DS1 0x2
207 #define READ_DATA_HDS 0x4
208 #define READ_DATA_SK 0x20
209 #define READ_DATA_MFM 0x40
210 #define READ_DATA_MT 0x80
211
212 /* COMMAND_READ_ID constants */
213 #define READ_ID_MFM 0x40
214
215 /* COMMAND_SPECIFY constants */
216 #define SPECIFY_HLT_1M 0x10 /* 16ms; based on intel data sheet */
217 #define SPECIFY_HLT_500K 0x8 /* 16ms; based on intel data sheet */
218 #define SPECIFY_HLT_300K 0x6 /* 16ms; based on intel data sheet */
219 #define SPECIFY_HLT_250K 0x4 /* 16ms; based on intel data sheet */
220 #define SPECIFY_HUT_1M 0x0 /* Need to figure out these eight values; 0 is max */
221 #define SPECIFY_HUT_500K 0x0
222 #define SPECIFY_HUT_300K 0x0
223 #define SPECIFY_HUT_250K 0x0
224 #define SPECIFY_SRT_1M 0x0
225 #define SPECIFY_SRT_500K 0x0
226 #define SPECIFY_SRT_300K 0x0
227 #define SPECIFY_SRT_250K 0x0
228
229 /* Command byte 1 constants */
230 #define COMMAND_UNIT_SELECT 0x3 /* Covers two bits; defined below */
231 #define COMMAND_UNIT_SELECT_0 0x1
232 #define COMMAND_UNIT_SELECT_1 0x2
233 #define COMMAND_HEAD_NUMBER 0x4
234 #define COMMAND_HEAD_NUMBER_SHIFT 0x2
235
236 /* COMMAND_VERSION */
237 #define VERSION_ENHANCED 0x90
238
239 /* COMMAND_UNIT_SELECT */
240 #define CUS_UNIT_0 0x0
241 #define CUS_UNIT_1 0x1
242
243 /* COMMAND_CONFIGURE constants */
244 #define CONFIGURE_FIFOTHR 0xf
245 #define CONFIGURE_POLL 0x10
246 #define CONFIGURE_EFIFO 0x20
247 #define CONFIGURE_EIS 0x40
248 #define CONFIGURE_PRETRK 0xff
249
250 /* Command Head Number Constants */
251 #define COMMAND_HEAD_0 0x0
252 #define COMMAND_HEAD_1 0x1
253
254 /* Bytes per sector constants */
255 #define HW_128_BYTES_PER_SECTOR 0x0
256 #define HW_256_BYTES_PER_SECTOR 0x1
257 #define HW_512_BYTES_PER_SECTOR 0x2
258 #define HW_1024_BYTES_PER_SECTOR 0x3
259
260 /*
261 * FUNCTIONS
262 */
263 NTSTATUS NTAPI
264 HwTurnOnMotor(PDRIVE_INFO DriveInfo);
265
266 NTSTATUS NTAPI
267 HwSenseDriveStatus(PDRIVE_INFO DriveInfo);
268
269 NTSTATUS NTAPI
270 HwReadWriteData(PCONTROLLER_INFO ControllerInfo,
271 BOOLEAN Read,
272 UCHAR Unit,
273 UCHAR Cylinder,
274 UCHAR Head,
275 UCHAR Sector,
276 UCHAR BytesPerSector,
277 UCHAR EndOfTrack,
278 UCHAR Gap3Length,
279 UCHAR DataLength);
280
281 NTSTATUS NTAPI
282 HwRecalibrate(PDRIVE_INFO DriveInfo);
283
284 NTSTATUS NTAPI
285 HwSenseInterruptStatus(PCONTROLLER_INFO ControllerInfo);
286
287 NTSTATUS NTAPI
288 HwReadId(PDRIVE_INFO DriveInfo, UCHAR Head);
289
290 NTSTATUS NTAPI
291 HwFormatTrack(PCONTROLLER_INFO ControllerInfo,
292 UCHAR Unit,
293 UCHAR Head,
294 UCHAR BytesPerSector,
295 UCHAR SectorsPerTrack,
296 UCHAR Gap3Length,
297 UCHAR FillerPattern);
298
299 NTSTATUS NTAPI
300 HwSeek(PDRIVE_INFO DriveInfo, UCHAR Cylinder);
301
302 NTSTATUS NTAPI
303 HwReadWriteResult(PCONTROLLER_INFO ControllerInfo);
304
305 NTSTATUS NTAPI
306 HwGetVersion(PCONTROLLER_INFO ControllerInfo);
307
308 NTSTATUS NTAPI
309 HwConfigure(PCONTROLLER_INFO ControllerInfo,
310 BOOLEAN EIS,
311 BOOLEAN EFIFO,
312 BOOLEAN POLL,
313 UCHAR FIFOTHR,
314 UCHAR PRETRK) ;
315
316 NTSTATUS NTAPI
317 HwRecalibrateResult(PCONTROLLER_INFO ControllerInfo);
318
319 NTSTATUS NTAPI
320 HwDiskChanged(PDRIVE_INFO DriveInfo,
321 PBOOLEAN DiskChanged);
322
323 NTSTATUS NTAPI
324 HwSenseDriveStatusResult(PCONTROLLER_INFO ControllerInfo,
325 PUCHAR Status);
326
327 NTSTATUS NTAPI
328 HwSpecify(PCONTROLLER_INFO ControllerInfo,
329 UCHAR HeadLoadTime,
330 UCHAR HeadUnloadTime,
331 UCHAR StepRateTime,
332 BOOLEAN NonDma);
333
334 NTSTATUS NTAPI
335 HwReadIdResult(PCONTROLLER_INFO ControllerInfo,
336 PUCHAR CurCylinder,
337 PUCHAR CurHead);
338
339 NTSTATUS NTAPI
340 HwSetDataRate(PCONTROLLER_INFO ControllerInfo, UCHAR DataRate);
341
342 NTSTATUS NTAPI
343 HwReset(PCONTROLLER_INFO Controller);
344
345 NTSTATUS NTAPI
346 HwPowerOff(PCONTROLLER_INFO ControllerInfo);
347
348 VOID NTAPI
349 HwDumpRegisters(PCONTROLLER_INFO ControllerInfo);
350
351 NTSTATUS NTAPI
352 HwTurnOffMotor(PCONTROLLER_INFO ControllerInfo);
353