/* * ReactOS Floppy Driver * Copyright (C) 2004, Vizzini (vizzini@plasmic.com) * * This program is free software; you can redistribute it and/or modify * it under the terms of the GNU General Public License as published by * the Free Software Foundation; either version 2 of the License, or * (at your option) any later version. * * This program is distributed in the hope that it will be useful, * but WITHOUT ANY WARRANTY; without even the implied warranty of * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the * GNU General Public License for more details. * * You should have received a copy of the GNU General Public License along * with this program; if not, write to the Free Software Foundation, Inc., * 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA. * * PROJECT: ReactOS Floppy Driver * FILE: hardware.h * PURPOSE: Header for FDC control routines * PROGRAMMER: Vizzini (vizzini@plasmic.com) * REVISIONS: * 15-Feb-2004 vizzini - Created * * NOTES: * - Baesd on http://www.nondot.org/sabre/os/files/Disk/FLOPPY.TXT * - Some information taken from Intel 82077AA data sheet (order #290166-007) * - Some definitions are PS/2-Specific; others include the original NEC PD765 * - Other information gathered from the comments in the NT 3.5 floppy driver * * TODO: * - Convert these numbers to 100% absolute values; eliminate bit positions * in favor of shifts or bitfields */ #pragma once #define FLOPPY_DEFAULT_IRQ 0x6 #define FDC_PORT_BYTES 0x8 /* Register offsets from base address (usually 0x3f8) */ #define STATUS_REGISTER_A 0x0 /* Read; PS/2 Only */ #define STATUS_REGISTER_B 0x1 /* Read; PS/2 Only */ #define DIGITAL_OUTPUT_REGISTER 0x2 /* Read/Write */ #define TAPE_DRIVE_REGISTER 0x3 /* Read/Write */ #define MAIN_STATUS_REGISTER 0x4 /* Read */ #define DATA_RATE_SELECT_REGISTER 0x4 /* Write */ #define FIFO 0x5 /* Read/Write */ #define RESERVED_REGISTER 0x6 /* Reserved */ #define DIGITAL_INPUT_REGISTER 0x7 /* Read; PS/2 Only */ #define CONFIGURATION_CONTROL_REGISTER 0x7 /* Write; PS/2 Only */ /* STATUS_REGISTER_A */ #define DSRA_DIRECTION 0x1 #define DSRA_WRITE_PROTECT 0x2 #define DSRA_INDEX 0x4 #define DSRA_HEAD_1_SELECT 0x8 #define DSRA_TRACK_0 0x10 #define DSRA_STEP 0x20 #define DSRA_SECOND_DRIVE_INSTALLED 0x40 #define DSRA_INTERRUPT_PENDING 0x80 /* STATUS_REGISTER_B */ #define DSRB_MOTOR_ENABLE_0 0x1 #define DSRB_MOTOR_ENABLE_1 0x2 #define DSRB_WRITE_ENABLE 0x4 #define DSRB_READ_DATA 0x8 #define DSRB_WRITE_DATA 0x10 #define DSRB_DRIVE_SELECT 0x20 /* DIGITAL_OUTPUT_REGISTER */ #define DOR_FLOPPY_DRIVE_SELECT 0x3 /* Covers 2 bits, defined below */ #define DOR_FDC_ENABLE 0x4 /* from the website */ #define DOR_RESET 0x4 /* from the Intel guide; 0 = resetting, 1 = enabled */ #define DOR_DMA_IO_INTERFACE_ENABLE 0x8 /* Reserved on PS/2 */ #define DOR_FLOPPY_MOTOR_ON_A 0x10 #define DOR_FLOPPY_MOTOR_ON_B 0x20 #define DOR_FLOPPY_MOTOR_ON_C 0x40 /* Reserved on PS/2 */ #define DOR_FLOPPY_MOTOR_ON_D 0x80 /* Reserved on PS/2 */ /* DOR_FLOPPY_DRIVE_SELECT */ #define DOR_FLOPPY_DRIVE_SELECT_A 0x0 #define DOR_FLOPPY_DRIVE_SELECT_B 0x1 #define DOR_FLOPPY_DRIVE_SELECT_C 0x2 /* Reserved on PS/2 */ #define DOR_FLOPPY_DRIVE_SELECT_D 0x3 /* Reserved on PS/2 */ /* MAIN_STATUS_REGISTER */ #define MSR_FLOPPY_BUSY_0 0x1 #define MSR_FLOPPY_BUSY_1 0x2 #define MSR_FLOPPY_BUSY_2 0x4 /* Reserved on PS/2 */ #define MSR_FLOPPY_BUSY_3 0x8 /* Reserved on PS/2 */ #define MSR_READ_WRITE_IN_PROGRESS 0x10 #define MSR_NON_DMA_MODE 0x20 #define MSR_IO_DIRECTION 0x40 /* Determines meaning of Command Status Registers */ #define MSR_DATA_REG_READY_FOR_IO 0x80 /* DATA_RATE_SELECT_REGISTER */ #define DRSR_DSEL 0x3 /* covers two bits as defined below */ #define DRSR_PRECOMP 0x1c /* covers three bits as defined below */ #define DRSR_MBZ 0x20 #define DRSR_POWER_DOWN 0x40 #define DRSR_SW_RESET 0x80 /* DRSR_DSEL */ #define DRSR_DSEL_500KBPS 0x0 #define DRSR_DSEL_300KBPS 0x1 #define DRSR_DSEL_250KBPS 0x2 #define DRSR_DSEL_1MBPS 0x3 /* STATUS_REGISTER_0 */ #define SR0_UNIT_SELECTED_AT_INTERRUPT 0x3 /* Covers two bits as defined below */ #define SR0_HEAD_NUMBER_AT_INTERRUPT 0x4 /* Values defined below */ #define SR0_NOT_READY_ON_READ_WRITE 0x8 /* Unused in PS/2 */ #define SR0_SS_ACCESS_TO_HEAD_1 0x8 /* Unused in PS/2 */ #define SR0_EQUIPMENT_CHECK 0x10 #define SR0_SEEK_COMPLETE 0x20 #define SR0_LAST_COMMAND_STATUS 0xC0 /* Covers two bits as defined below */ /* SR0_UNIT_SELECTED_AT_INTERRUPT */ #define SR0_UNIT_SELECTED_A 0x0 #define SR0_UNIT_SELECTED_B 0x1 #define SR0_UNIT_SELECTED_C 0x2 #define SR0_UNIT_SELECTED_D 0x3 #define SR0_PS2_UNIT_SELECTED_A 0x1 /* PS/2 uses only two drives: A = 01b B = 10b */ #define SR0_PST_UNIT_SELECTED_B 0x2 /* SR0_HEAD_NUMBER_AT_INTERRUPT */ #define SR0_HEAD_0 0x0 #define SR0_HEAD_1 0x1 /* SR0_LAST_COMMAND_STATUS */ #define SR0_LCS_SUCCESS 0x0 #define SR0_LCS_TERMINATED_ABNORMALLY 0x40 #define SR0_LCS_INVALID_COMMAND_ISSUED 0x80 #define SR0_LCS_READY_SIGNAL_CHANGED 0xc0 /* Reserved on PS/2; a/k/a abnormal termination due to polling */ /* STATUS_REGISTER_1 */ #define SR1_CANNOT_FIND_ID_ADDRESS 0x1 /* Mimics SR2_WRONG_CYLINDER_DETECTED */ #define SR1_WRITE_PROTECT_DETECTED 0x2 #define SR1_CANNOT_FIND_SECTOR_ID 0x4 #define SR1_OVERRUN 0x10 #define SR1_CRC_ERROR 0x20 #define SR1_END_OF_CYLINDER 0x80 /* STATUS_REGISTER_2 */ #define SR2_MISSING_ADDRESS_MARK 0x1 #define SR2_BAD_CYLINDER 0x2 #define SR2_SCAN_COMMAND_FAILED 0x4 #define SR2_SCAN_COMMAND_EQUAL 0x8 #define SR2_WRONG_CYLINDER_DETECTED 0x10 /* Mimics SR1_CANNOT_FIND_ID_ADDRESS */ #define SR2_CRC_ERROR_IN_SECTOR_DATA 0x20 #define SR2_SECTOR_WITH_DELETED_DATA 0x40 /* STATUS_REGISTER_3 */ #define SR3_UNIT_SELECTED 0x3 /* Covers two bits; defined below */ #define SR3_SIDE_HEAD_SELECT_STATUS 0x4 /* Values defined below */ #define SR3_TWO_SIDED_STATUS_SIGNAL 0x8 #define SR3_TRACK_ZERO_STATUS_SIGNAL 0x10 #define SR3_READY_STATUS_SIGNAL 0x20 #define SR3_WRITE_PROTECT_STATUS_SIGNAL 0x40 #define SR3_FAULT_STATUS_SIGNAL 0x80 /* SR3_UNIT_SELECTED */ #define SR3_UNIT_SELECTED_A 0x0 #define SR3_UNIT_SELECTED_B 0x1 #define SR3_UNIT_SELECTED_C 0x2 #define SR3_UNIT_SELECTED_D 0x3 /* SR3_SIDE_HEAD_SELECT_STATUS */ #define SR3_SHSS_HEAD_0 0x0 #define SR3_SHSS_HEAD_1 0x1 /* DIGITAL_INPUT_REGISTER */ #define DIR_HIGH_DENSITY_SELECT 0x1 #define DIR_DISKETTE_CHANGE 0x80 /* CONFIGURATION_CONTROL_REGISTER */ #define CCR_DRC 0x3 /* Covers two bits, defined below */ #define CCR_DRC_0 0x1 #define CCR_DRC_1 0x2 /* CCR_DRC */ #define CCR_DRC_500000 0x0 #define CCR_DRC_250000 0x2 /* Commands */ #define COMMAND_READ_TRACK 0x2 #define COMMAND_SPECIFY 0x3 #define COMMAND_SENSE_DRIVE_STATUS 0x4 #define COMMAND_WRITE_DATA 0x5 #define COMMAND_READ_DATA 0x6 #define COMMAND_RECALIBRATE 0x7 #define COMMAND_SENSE_INTERRUPT_STATUS 0x8 #define COMMAND_WRITE_DELETED_DATA 0x9 #define COMMAND_READ_ID 0xA #define COMMAND_READ_DELETED_DATA 0xC #define COMMAND_FORMAT_TRACK 0xD #define COMMAND_SEEK 0xF #define COMMAND_VERSION 0x10 #define COMMAND_SCAN_EQUAL 0x11 #define COMMAND_CONFIGURE 0x13 #define COMMAND_SCAN_LOW_OR_EQUAL 0x19 #define COMMAND_SCAN_HIGH_OR_EQUAL 0x1D /* COMMAND_READ_DATA constants */ #define READ_DATA_DS0 0x1 #define READ_DATA_DS1 0x2 #define READ_DATA_HDS 0x4 #define READ_DATA_SK 0x20 #define READ_DATA_MFM 0x40 #define READ_DATA_MT 0x80 /* COMMAND_READ_ID constants */ #define READ_ID_MFM 0x40 /* COMMAND_SPECIFY constants */ #define SPECIFY_HLT_1M 0x10 /* 16ms; based on intel data sheet */ #define SPECIFY_HLT_500K 0x8 /* 16ms; based on intel data sheet */ #define SPECIFY_HLT_300K 0x6 /* 16ms; based on intel data sheet */ #define SPECIFY_HLT_250K 0x4 /* 16ms; based on intel data sheet */ #define SPECIFY_HUT_1M 0x0 /* Need to figure out these eight values; 0 is max */ #define SPECIFY_HUT_500K 0x0 #define SPECIFY_HUT_300K 0x0 #define SPECIFY_HUT_250K 0x0 #define SPECIFY_SRT_1M 0x0 #define SPECIFY_SRT_500K 0x0 #define SPECIFY_SRT_300K 0x0 #define SPECIFY_SRT_250K 0x0 /* Command byte 1 constants */ #define COMMAND_UNIT_SELECT 0x3 /* Covers two bits; defined below */ #define COMMAND_UNIT_SELECT_0 0x1 #define COMMAND_UNIT_SELECT_1 0x2 #define COMMAND_HEAD_NUMBER 0x4 #define COMMAND_HEAD_NUMBER_SHIFT 0x2 /* COMMAND_VERSION */ #define VERSION_ENHANCED 0x90 /* COMMAND_UNIT_SELECT */ #define CUS_UNIT_0 0x0 #define CUS_UNIT_1 0x1 /* COMMAND_CONFIGURE constants */ #define CONFIGURE_FIFOTHR 0xf #define CONFIGURE_POLL 0x10 #define CONFIGURE_EFIFO 0x20 #define CONFIGURE_EIS 0x40 #define CONFIGURE_PRETRK 0xff /* Command Head Number Constants */ #define COMMAND_HEAD_0 0x0 #define COMMAND_HEAD_1 0x1 /* Bytes per sector constants */ #define HW_128_BYTES_PER_SECTOR 0x0 #define HW_256_BYTES_PER_SECTOR 0x1 #define HW_512_BYTES_PER_SECTOR 0x2 #define HW_1024_BYTES_PER_SECTOR 0x3 /* * FUNCTIONS */ NTSTATUS NTAPI HwTurnOnMotor(PDRIVE_INFO DriveInfo); NTSTATUS NTAPI HwSenseDriveStatus(PDRIVE_INFO DriveInfo); NTSTATUS NTAPI HwReadWriteData(PCONTROLLER_INFO ControllerInfo, BOOLEAN Read, UCHAR Unit, UCHAR Cylinder, UCHAR Head, UCHAR Sector, UCHAR BytesPerSector, UCHAR EndOfTrack, UCHAR Gap3Length, UCHAR DataLength); NTSTATUS NTAPI HwRecalibrate(PDRIVE_INFO DriveInfo); NTSTATUS NTAPI HwSenseInterruptStatus(PCONTROLLER_INFO ControllerInfo); NTSTATUS NTAPI HwReadId(PDRIVE_INFO DriveInfo, UCHAR Head); NTSTATUS NTAPI HwFormatTrack(PCONTROLLER_INFO ControllerInfo, UCHAR Unit, UCHAR Head, UCHAR BytesPerSector, UCHAR SectorsPerTrack, UCHAR Gap3Length, UCHAR FillerPattern); NTSTATUS NTAPI HwSeek(PDRIVE_INFO DriveInfo, UCHAR Cylinder); NTSTATUS NTAPI HwReadWriteResult(PCONTROLLER_INFO ControllerInfo); NTSTATUS NTAPI HwGetVersion(PCONTROLLER_INFO ControllerInfo); NTSTATUS NTAPI HwConfigure(PCONTROLLER_INFO ControllerInfo, BOOLEAN EIS, BOOLEAN EFIFO, BOOLEAN POLL, UCHAR FIFOTHR, UCHAR PRETRK) ; NTSTATUS NTAPI HwRecalibrateResult(PCONTROLLER_INFO ControllerInfo); NTSTATUS NTAPI HwDiskChanged(PDRIVE_INFO DriveInfo, PBOOLEAN DiskChanged); NTSTATUS NTAPI HwSenseDriveStatusResult(PCONTROLLER_INFO ControllerInfo, PUCHAR Status); NTSTATUS NTAPI HwSpecify(PCONTROLLER_INFO ControllerInfo, UCHAR HeadLoadTime, UCHAR HeadUnloadTime, UCHAR StepRateTime, BOOLEAN NonDma); NTSTATUS NTAPI HwReadIdResult(PCONTROLLER_INFO ControllerInfo, PUCHAR CurCylinder, PUCHAR CurHead); NTSTATUS NTAPI HwSetDataRate(PCONTROLLER_INFO ControllerInfo, UCHAR DataRate); NTSTATUS NTAPI HwReset(PCONTROLLER_INFO Controller); NTSTATUS NTAPI HwPowerOff(PCONTROLLER_INFO ControllerInfo); VOID NTAPI HwDumpRegisters(PCONTROLLER_INFO ControllerInfo); NTSTATUS NTAPI HwTurnOffMotor(PCONTROLLER_INFO ControllerInfo);