// // Floppy register definitions // #define FLOPPY_REG_DOR 0x0002 #define FLOPPY_DOR_ENABLE 0x04 #define FLOPPY_DOR_DMA 0x08 #define FLOPPY_DOR_MOTOR0 0x10 #define FLOPPY_DOR_MOTOR1 0x20 #define FLOPPY_DRIVE0_ON ( FLOPPY_DOR_ENABLE | FLOPPY_DOR_DMA | FLOPPY_DOR_MOTOR0 ) #define FLOPPY_DRIVE1_ON ( FLOPPY_DOR_ENABLE | FLOPPY_DOR_DMA | FLOPPY_DOR_MOTOR1 | 1 ) #define FLOPPY_REG_MSTAT 0x0004 #define FLOPPY_MS_DRV0BUSY 0x01 #define FLOPPY_MS_DRV1BUSY 0x02 #define FLOPPY_MS_DRV2BUSY 0x04 #define FLOPPY_MS_DRV3BUSY 0x08 #define FLOPPY_MS_FDCBUSY 0x10 #define FLOPPY_MS_DMAMODE 0x20 #define FLOPPY_MS_DATADIR 0x40 #define FLOPPY_MS_RDYMASK 0xC0 #define FLOPPY_MS_DATARDYW 0x80 #define FLOPPY_MS_DATARDYR 0xC0 #define FLOPPY_REG_DATA 0x0005 #define FLOPPY_REG_DIR 0x0007 /* READ ONLY */ #define FLOPPY_DI_DSKCHNG 0x80 #define FLOPPY_REG_CCNTL 0x0007 /* WRITE ONLY */ #define FLOPPY_CCNTL_1MBIT 0x03 #define FLOPPY_CMD_RD_TRK 0x02 #define FLOPPY_CMD_SPEC_CHARS 0x03 #define FLOPPY_CSC_SRT_SHIFT 4 #define FLOPPY_CSC_HUT_MASK 0x0f #define FLOPPY_CSC_HLT_SHIFT 1 #define FLOPPY_CSC_NON_DMA 0x01 #define FLOPPY_CMD_SNS_DRV 0x04 #define FLOPPY_CMD_WRT_DATA 0x05 #define FLOPPY_CMD_RD_DATA 0x06 #define FLOPPY_CMD_RECAL 0x07 #define FLOPPY_CMD_SNS_INTR 0x08 #define FLOPPY_ST0_SEEKGD 0x20 #define FLOPPY_ST0_GDMASK 0xd8 #define FLOPPY_CMD_WRT_DEL 0x09 #define FLOPPY_CMD_RD_ID 0x0a #define FLOPPY_CMD_RD_DEL 0x0c #define FLOPPY_CMD_FMT_TRK 0x0d #define FLOPPY_CMD_DUMP_FDC 0x0e #define FLOPPY_CMD_SEEK 0x0f #define FLOPPY_CMD_VERSION 0x10 #define FLOPPY_CMD_SCN_EQ 0x11 #define FLOPPY_CMD_PPND_RW 0x12 #define FLOPPY_CMD_CFG_FIFO 0x13 #define FLOPPY_CMD_LCK_FIFO 0x14 #define FLOPPY_CMD_PARTID 0x18 #define FLOPPY_CMD_SCN_LE 0x19 #define FLOPPY_CMD_SCN_GE 0x1d #define FLOPPY_CMD_CFG_PWR 0x27 #define FLOPPY_CMD_SAVE_FDC 0x2e #define FLOPPY_CMD_FMT_ISO 0x33 #define FLOPPY_CMD_DMA_READ 0x46 #define FLOPPY_CMD_DMA_WRT 0x4a #define FLOPPY_CMD_REST_FDC 0x4e #define FLOPPY_CMD_DRV_SPEC 0x8e #define FLOPPY_CMD_RSEEK_OUT 0x8f #define FLOPPY_CMD_ULK_FIFO 0x94 #define FLOPPY_CMD_RSEEK_IN 0xcf #define FLOPPY_CMD_FMT_WRT 0xef // Command Code modifiers #define FLOPPY_C0M_SK 0x20 #define FLOPPY_C0M_MFM 0x40 #define FLOPPY_C0M_MT 0x80 #define FLOPPY_C1M_DRVMASK 0x03 #define FLOPPY_C1M_HEAD1 0x04 // Status code values and masks #define FLOPPY_ST0_INVALID 0x80 // useful command defines #define FLOPPY_CMD_READ (FLOPPY_CMD_RD_DATA | FLOPPY_C0M_SK | FLOPPY_C0M_MFM | FLOPPY_C0M_MT) #define FLOPPY_CMD_WRITE (FLOPPY_CMD_WRT_DATA | FLOPPY_C0M_MFM | FLOPPY_C0M_MT) #define FLOPPY_CMD_FORMAT (FLOPPY_CMD_FMT_TRK | FLOPPY_C0M_MFM) // // HAL floppy register access commands // #define FloppyWriteDOR(A, V) (WRITE_PORT_UCHAR((PVOID)(A) + FLOPPY_REG_DOR, (V))) #define FloppyReadMSTAT(A) (READ_PORT_UCHAR((PVOID)(A) + FLOPPY_REG_MSTAT)) #define FloppyReadDATA(A) (READ_PORT_UCHAR((PVOID)(A) + FLOPPY_REG_DATA)) #define FloppyWriteDATA(A, V) (WRITE_PORT_UCHAR((PVOID)(A) + FLOPPY_REG_DATA, (V))) #define FloppyReadDIR(A) (READ_PORT_UCHAR((PVOID)(A) + FLOPPY_REG_DIR)) #define FloppyWriteCCNTL(A, V) (WRITE_PORT_UCHAR((PVOID)(A) + FLOPPY_REG_CCNTL, (V))) typedef struct _FLOPPY_ERROR_THRESHOLDS { /* number of errors to be reached before aborting */ unsigned int Abort; /* maximal number of errors permitted to read an entire track at once */ unsigned int ReadTrack; /* maximal number of errors before a reset is tried */ unsigned int Reset; /* maximal number of errors before a recalibrate is tried */ unsigned int Recal; /* * Threshold for reporting FDC errors to the console. * Setting this to zero may flood your screen when using * ultra cheap floppies ;-) */ unsigned int Reporting; } FLOPPY_ERROR_THRESHOLDS; typedef struct _FLOPPY_MEDIA_TYPE { BYTE SectorSizeCode; BYTE MaximumTrack; BYTE Heads; DWORD SectorsPerTrack; ULONG BytesPerSector; } FLOPPY_MEDIA_TYPE; extern const FLOPPY_MEDIA_TYPE MediaTypes[]; #define FDP_DEBUG 0x02 #define FDP_SILENT_DCL_CLEAR 0x04 #define FDP_MSG 0x10 #define FDP_BROKEN_DCL 0x20 #define FDP_INVERTED_DCL 0x80 // time to hold reset line low #define FLOPPY_RESET_TIME 50000 #define FLOPPY_MOTOR_SPINUP_TIME -15000000 #define FLOPPY_MOTOR_SPINDOWN_TIME -50000000 #define FLOPPY_RECAL_TIMEOUT -30000000 typedef BOOLEAN (*FloppyIsrStateRoutine)( PCONTROLLER_OBJECT Controller ); typedef PIO_DPC_ROUTINE FloppyDpcStateRoutine; typedef struct _FLOPPY_DEVICE_EXTENSION { PCONTROLLER_OBJECT Controller; CHAR DriveSelect; CHAR Cyl; // current cylinder ULONG MediaType; // Media type index } FLOPPY_DEVICE_EXTENSION, *PFLOPPY_DEVICE_EXTENSION; typedef struct _FLOPPY_CONTROLLER_EXTENSION { PKINTERRUPT Interrupt; KSPIN_LOCK SpinLock; ULONG Number; ULONG PortBase; ULONG Vector; KEVENT Event; // Event set by ISR/DPC to wake DeviceEntry PDEVICE_OBJECT Device; // Pointer to the primary device on this controller PIRP Irp; // Current IRP CHAR St0; // Status registers CHAR St1; CHAR St2; CHAR SectorSizeCode; FloppyIsrStateRoutine IsrState; // pointer to state routine handler for ISR FloppyDpcStateRoutine DpcState; // pointer to state routine handler for DPC CHAR MotorOn; // drive select for drive with motor on KDPC MotorSpinupDpc; // DPC for motor spin up time KTIMER SpinupTimer; // Timer for motor spin up time KDPC MotorSpindownDpc; // DPC for motor spin down PADAPTER_OBJECT AdapterObject; // Adapter object for dma PVOID MapRegisterBase; DWORD TransferLength; // Length of the transfer } FLOPPY_CONTROLLER_EXTENSION, *PFLOPPY_CONTROLLER_EXTENSION; typedef struct _FLOPPY_CONTROLLER_PARAMETERS { ULONG PortBase; ULONG Vector; ULONG DmaChannel; KINTERRUPT_MODE InterruptMode; } FLOPPY_CONTROLLER_PARAMETERS, *PFLOPPY_CONTROLLER_PARAMETERS; #define FLOPPY_MAX_CONTROLLERS 1 VOID STDCALL FloppyDpcDetectMedia(PKDPC Dpc, PDEVICE_OBJECT DeviceObject, PIRP Irp, PVOID Context); VOID STDCALL FloppyDpcFailIrp(PKDPC Dpc, PDEVICE_OBJECT DeviceObject, PIRP Irp, PVOID Context); IO_ALLOCATION_ACTION STDCALL FloppyExecuteReadWrite(PDEVICE_OBJECT DeviceObject, PIRP Irp, PVOID MapRegisterbase, PVOID Context); IO_ALLOCATION_ACTION STDCALL FloppyExecuteSpindown(PDEVICE_OBJECT DeviceObject, PIRP Irp, PVOID MapRegisterbase, PVOID Context); VOID STDCALL FloppyMotorSpinupDpc(PKDPC Dpc, PVOID Context, PVOID Arg1, PVOID Arg2); VOID STDCALL FloppySeekDpc(PKDPC Dpc, PDEVICE_OBJECT DeviceObject, PIRP Irp, PVOID Context); VOID STDCALL FloppyMotorSpindownDpc(PKDPC Dpc, PVOID Context, PVOID Arg1, PVOID Arg2); VOID STDCALL FloppyDpcDetect(PKDPC Dpc, PDEVICE_OBJECT DeviceObject, PIRP Irp, PVOID Context ); VOID STDCALL FloppyDpcReadWrite(PKDPC Dpc, PDEVICE_OBJECT DeviceObject, PIRP Irp, PVOID Context); VOID STDCALL FloppyDpc(PKDPC Dpc, PDEVICE_OBJECT DeviceObject, PIRP Irp, PVOID Context); BOOLEAN FloppyIsrDetect( PCONTROLLER_OBJECT Controller ); BOOLEAN FloppyIsrReadWrite( PCONTROLLER_OBJECT Controller ); BOOLEAN FloppyIsrUnexpected( PCONTROLLER_OBJECT Controller ); BOOLEAN FloppyIsrDetectMedia( PCONTROLLER_OBJECT Controller ); BOOLEAN FloppyIsrRecal( PCONTROLLER_OBJECT Controller ); BOOLEAN STDCALL FloppyIsr(PKINTERRUPT Interrupt, PVOID ServiceContext); IO_ALLOCATION_ACTION STDCALL FloppyAdapterControl(PDEVICE_OBJECT DeviceObject, PIRP Irp, PVOID MapRegisterBase, PVOID Context);