mirror of
https://github.com/reactos/reactos.git
synced 2024-12-27 09:34:43 +00:00
Continuing work in progress
svn path=/trunk/; revision=102
This commit is contained in:
parent
e96765787f
commit
fd5a21279e
2 changed files with 438 additions and 129 deletions
|
@ -7,15 +7,56 @@
|
|||
// Modification History:
|
||||
// 08/19/98 RJJ Created.
|
||||
//
|
||||
|
||||
// To do:
|
||||
// FIXME: get it working
|
||||
// FIXME: add support for DMA hardware
|
||||
// FIXME: should add support for floppy tape/zip devices
|
||||
|
||||
#include <ddk/ntddk.h>
|
||||
|
||||
#include "floppy.h"
|
||||
|
||||
#define VERSION "V0.0.1"
|
||||
|
||||
// --------------------------------------------------- File Statics
|
||||
|
||||
typedef struct _FLOPPY_CONTROLLER_PARAMETERS
|
||||
{
|
||||
int PortBase;
|
||||
int Vector;
|
||||
int IrqL;
|
||||
int SynchronizeIrqL;
|
||||
KINTERRUPT_MODE InterruptMode;
|
||||
KAFFINITY Affinity;
|
||||
} FLOPPY_CONTROLLER_PARAMETERS, *PFLOPPY_CONTROLLER_PARAMETERS;
|
||||
|
||||
#define FLOPPY_MAX_CONTROLLERS 2
|
||||
FLOPPY_CONTROLLER_PARAMETERS ControllerParameters[FLOPPY_MAX_CONTROLLERS] =
|
||||
{
|
||||
{0x03f0, 6, 6, 6, LevelSensitive, 0xffff},
|
||||
{0x0370, 6, 6, 6, LevelSensitive, 0xffff},
|
||||
};
|
||||
|
||||
FLOPPY_DEVICE_PARAMETERS DeviceTypes[] =
|
||||
{
|
||||
/* Unknown */
|
||||
{0, 500, 16, 16, 8000, 1000, 3000, 0, 20, 5, 80, 3000, 20, {3,1,2,0,2}, 0, 0, { 7, 4, 8, 2, 1, 5, 3,10}, 1500, 0, "unknown"},
|
||||
/* 5 1/4 360 KB PC*/
|
||||
{1, 300, 16, 16, 8000, 1000, 3000, 0, 20, 5, 40, 3000, 17, {3,1,2,0,2}, 0, 0, { 1, 0, 0, 0, 0, 0, 0, 0}, 1500, 1, "360K PC"},
|
||||
/* 5 1/4 HD AT*/
|
||||
{2, 500, 16, 16, 6000, 400, 3000, 14, 20, 6, 83, 3000, 17, {3,1,2,0,2}, 0, 0, { 2, 5, 6,23,10,20,11, 0}, 1500, 2, "1.2M"},
|
||||
/* 3 1/2 DD*/
|
||||
{3, 250, 16, 16, 3000, 1000, 3000, 0, 20, 5, 83, 3000, 20, {3,1,2,0,2}, 0, 0, { 4,22,21,30, 3, 0, 0, 0}, 1500, 4, "720k"},
|
||||
/* 3 1/2 HD*/
|
||||
{4, 500, 16, 16, 4000, 400, 3000, 10, 20, 5, 83, 3000, 20, {3,1,2,0,2}, 0, 0, { 7, 4,25,22,31,21,29,11}, 1500, 7, "1.44M"},
|
||||
/* 3 1/2 ED*/
|
||||
{5, 1000, 15, 8, 3000, 400, 3000, 10, 20, 5, 83, 3000, 40, {3,1,2,0,2}, 0, 0, { 7, 8, 4,25,28,22,31,21}, 1500, 8, "2.88M AMI BIOS"},
|
||||
/* 3 1/2 ED*/
|
||||
{6, 1000, 15, 8, 3000, 400, 3000, 10, 20, 5, 83, 3000, 40, {3,1,2,0,2}, 0, 0, { 7, 8, 4,25,28,22,31,21}, 1500, 8, "2.88M"}
|
||||
};
|
||||
|
||||
static BOOLEAN FloppyInitialized = FALSE;
|
||||
|
||||
// ------------------------------------------------------ Functions
|
||||
|
||||
// ModuleEntry
|
||||
|
@ -37,14 +78,14 @@
|
|||
// RETURNS:
|
||||
// NTSTATUS
|
||||
|
||||
NTSTATUS ModuleEntry(
|
||||
IN PDRIVER_OBJECT DriverObject,
|
||||
IN PUNICODE_STRING RegistryPath
|
||||
) {
|
||||
NTSTATUS
|
||||
DriverEntry(IN PDRIVER_OBJECT DriverObject,
|
||||
IN PUNICODE_STRING RegistryPath)
|
||||
{
|
||||
NTSTATUS RC;
|
||||
PFLOPPY_DEVICE_EXTENSION DeviceExtension;
|
||||
|
||||
// Export other driver entry points...
|
||||
// Export other driver entry points...
|
||||
DriverObject->DriverStartIo = FloppyStartIo;
|
||||
DriverObject->MajorFunction[IRP_MJ_CREATE] = FloppyDispatchOpenClose;
|
||||
DriverObject->MajorFunction[IRP_MJ_CLOSE] = FloppyDispatchOpenClose;
|
||||
|
@ -52,43 +93,82 @@ NTSTATUS ModuleEntry(
|
|||
DriverObject->MajorFunction[IRP_MJ_WRITE] = FloppyDispatchReadWrite;
|
||||
DriverObject->MajorFunction[IRP_MJ_DEVICE_CONTROL] = FloppyDispatchDeviceControl;
|
||||
|
||||
// FIXME: Try to detect floppy and abort if it fails
|
||||
// Try to detect controller and abort if it fails
|
||||
if (!FloppyCreateController(DriverObject,
|
||||
&ControllerParameters[0],
|
||||
0))
|
||||
{
|
||||
DPRINT("Could not find floppy controller");
|
||||
return STATUS_NO_SUCH_DEVICE;
|
||||
}
|
||||
|
||||
// Create a device object for the floppy
|
||||
RC = IoCreateDevice(DriverObject,
|
||||
sizeof(FLOPPY_DEVICE_EXTENSION),
|
||||
DeviceName,
|
||||
FILE_DEVICE_DISK,
|
||||
0,
|
||||
TRUE,
|
||||
&DeviceObject);
|
||||
if (!NT_SUCCESS(RC)) {
|
||||
DPRINT("Could not create device for floppy");
|
||||
return STATUS_NO_SUCH_DEVICE;
|
||||
}
|
||||
return STATUS_SUCCESS;
|
||||
}
|
||||
|
||||
// Fill out Device Extension
|
||||
DeviceExtension = (PFLOPPY_DEVICE_EXTENSION)
|
||||
DeviceObject->DeviceExtension;
|
||||
DeviceExtension->Number = 0;
|
||||
DeviceExtension->PortBase = FLOPPY_PORT_BASE;
|
||||
DeviceExtension->Vector = FLOPPY_IRQ_VECTOR;
|
||||
DeviceExtension->IrqL = FLOPPY_DIRQL;
|
||||
DeviceExtension->DMASupported = FALSE;
|
||||
DeviceExtension->FloppyState = FloppyStateIdle;
|
||||
static BOOLEAN
|
||||
FloppyCreateController(PDRIVER_OBJECT DriverObject,
|
||||
PFLOPPY_CONTROLLER_PARAMETERS ControllerParameters,
|
||||
int Index)
|
||||
{
|
||||
PFLOPPY_CONTROLLER_TYPE ControllerType;
|
||||
PCONTROLLER_OBJECT ControllerObject;
|
||||
PFLOPPY_CONTROLLER_EXTENSION ControllerExtension;
|
||||
|
||||
// Register an interrupt handler for this device
|
||||
RC = IoConnectInterrupt(&DeviceExtension->Interrupt,
|
||||
FloppyIsr, DeviceExtension, NULL,
|
||||
DeviceExtension->Vector, DeviceExtension->IrqL,
|
||||
DeviceExtension->IrqL, FLOPPY_IRQ_MODE,
|
||||
FALSE, FLOPPY_AFFINITY, FALSE);
|
||||
if (!NT_SUCCESS(RC)) {
|
||||
DPRINT("Could not Connect Interrupt %d\n", DeviceExtension->Vector);
|
||||
return STATUS_NO_SUCH_DEVICE;
|
||||
}
|
||||
/* Detect controller and determine type */
|
||||
if (!FloppyGetControllerVersion(ControllerParameters, &ControllerType))
|
||||
{
|
||||
return FALSE;
|
||||
}
|
||||
|
||||
// FIXME: register a DMA handler if needed for this controller
|
||||
// FIXME: Register port ranges and interrupts with HAL
|
||||
|
||||
/* Create controller object for FDC */
|
||||
ControllerObject = IoCreateController(sizeof(FLOPPY_CONTROLLER_EXTENSION));
|
||||
if (ControllerObject == NULL)
|
||||
{
|
||||
DPRINT("Could not create controller object for controller %d\n",
|
||||
Index);
|
||||
return FALSE;
|
||||
}
|
||||
|
||||
// FIXME: fill out controller data
|
||||
ControllerExtension = (PFLOPPY_CONTROLLER_EXTENSION)
|
||||
ControllerObject->ControllerExtension;
|
||||
ControllerExtension->Number = Index;
|
||||
ControllerExtension->PortBase = ControllerParameters->PortBase;
|
||||
ControllerExtension->Vector = ControllerParameters->Vector;
|
||||
ControllerExtension->FDCType = ControllerType;
|
||||
|
||||
/* Initialize the spin lock in the controller extension */
|
||||
KeInitializeSpinLock(&ControllerExtension->SpinLock);
|
||||
|
||||
/* Register an interrupt handler for this controller */
|
||||
RC = IoConnectInterrupt(&ControllerExtension->Interrupt,
|
||||
FloppyIsr,
|
||||
ControllerExtension,
|
||||
&ControllerExtension->SpinLock,
|
||||
ControllerExtension->Vector,
|
||||
ControllerParameters->IrqL,
|
||||
ControllerParameters->SynchronizeIrqL,
|
||||
ControllerParameters->InterruptMode,
|
||||
FALSE,
|
||||
ControllerParameters->Affinity,
|
||||
FALSE);
|
||||
if (!NT_SUCCESS(RC))
|
||||
{
|
||||
DPRINT("Could not Connect Interrupt %d\n", ControllerExtension->Vector);
|
||||
IoDeleteController(ControllerObject);
|
||||
return FALSE;
|
||||
}
|
||||
|
||||
// FIXME: setup DMA stuff for controller
|
||||
|
||||
// Check for each possible drive and create devices for them
|
||||
for (DriveIdx = 0; DriveIdx < FLOPPY_MAX_DRIVES; DriveIdx++)
|
||||
{
|
||||
// FIXME: try to identify the drive
|
||||
// FIXME: create a device if it's there
|
||||
}
|
||||
|
||||
return STATUS_SUCCESS;
|
||||
}
|
||||
|
@ -110,109 +190,255 @@ NTSTATUS ModuleEntry(
|
|||
// COMMENTS:
|
||||
// This routine (get_fdc_version) was originally written by David C. Niemi
|
||||
//
|
||||
static BOOLEAN FloppyGetControllerVersion(
|
||||
IN OUT PFLOPPY_DEVICE_EXTENSION DeviceExtension
|
||||
) {
|
||||
int Result;
|
||||
FLOPPY_CMD CommandToSend;
|
||||
FLOPPY_RESULT ResultReturned
|
||||
static BOOLEAN
|
||||
FloppyGetControllerVersion(IN PFLOPPY_CONTROLLER_PARAMETERS ControllerParameters,
|
||||
OUT PFLOPPY_CONTROLLER_TYPE ControllerType)
|
||||
{
|
||||
BYTE ResultReturned
|
||||
BYTE Result[FLOPPY_MAX_REPLIES];
|
||||
int ResultLength;
|
||||
|
||||
CommandToSend.CMd[0] = FLOPPY_CMD_FD_DUMPREGS;
|
||||
FloppyWriteCommand(DeviceExtension->PortBase, &CommandToSend, &ResultReturned);
|
||||
/* 82072 and better know DUMPREGS */
|
||||
if (!FloppyWriteCommandByte(ControllerParameters->PortBase,
|
||||
FLOPPY_CMD_DUMP_FDC))
|
||||
{
|
||||
return FALSE;
|
||||
}
|
||||
ResultLength = FloppyReadResultCode(PortBase, &Result));
|
||||
if (ResultLength < 0)
|
||||
{
|
||||
return FALSE;
|
||||
}
|
||||
|
||||
/* 82072 and better know DUMPREGS */
|
||||
if (FDCS->reset)
|
||||
return FDC_NONE;
|
||||
if ((r = result()) <= 0x00)
|
||||
return FDC_NONE; /* No FDC present ??? */
|
||||
if ((r==1) && (reply_buffer[0] == 0x80)){
|
||||
printk(KERN_INFO "FDC %d is an 8272A\n",fdc);
|
||||
return FDC_8272A; /* 8272a/765 don't know DUMPREGS */
|
||||
}
|
||||
if (r != 10) {
|
||||
printk("FDC %d init: DUMPREGS: unexpected return of %d bytes.\n",
|
||||
fdc, r);
|
||||
return FDC_UNKNOWN;
|
||||
}
|
||||
/* 8272a/765 don't know DUMPREGS */
|
||||
if ((ResultLength == 1) && (Result[0] == 0x80))
|
||||
{
|
||||
DPRINT("FDC %d is an 8272A\n", PortBase);
|
||||
*ControllerType = FDC_8272A;
|
||||
return TRUE;
|
||||
}
|
||||
if (r != 10)
|
||||
{
|
||||
DPRINT("FDC %d init: DUMP_FDC: unexpected return of %d bytes.\n",
|
||||
PortBase,
|
||||
ResultLength);
|
||||
return FALSE;
|
||||
}
|
||||
|
||||
if(!fdc_configure()) {
|
||||
printk(KERN_INFO "FDC %d is an 82072\n",fdc);
|
||||
return FDC_82072; /* 82072 doesn't know CONFIGURE */
|
||||
}
|
||||
if (!FloppyConfigure(PortBase, FALSE, 0x0a))
|
||||
{
|
||||
DPRINT("FDC %d is an 82072\n", PortBase);
|
||||
*ControllerType = FDC_82072;
|
||||
return TRUE;
|
||||
}
|
||||
FloppyWriteCommandByte(PortBase, FLOPPY_CMD_PPND_RW);
|
||||
if (FloppyNeedsMoreOutput(PortBase, Result) == FLOPPY_NEEDS_OUTPUT)
|
||||
{
|
||||
FloppyWriteCommandByte(PortBase, 0);
|
||||
}
|
||||
else
|
||||
{
|
||||
DPRINT("FDC %d is an 82072A\n", PortBase);
|
||||
*ControllerType = FDC_82072A;
|
||||
return TRUE;
|
||||
}
|
||||
|
||||
output_byte(FD_PERPENDICULAR);
|
||||
if(need_more_output() == MORE_OUTPUT) {
|
||||
output_byte(0);
|
||||
} else {
|
||||
printk(KERN_INFO "FDC %d is an 82072A\n", fdc);
|
||||
return FDC_82072A; /* 82072A as found on Sparcs. */
|
||||
}
|
||||
/* Pre-1991 82077, doesn't know LOCK/UNLOCK */
|
||||
FloppyWriteCommandByte(PortBase, FLOPPY_CMD_UNLK_FIFO);
|
||||
ResultLength = FloppyReadResultCode(PortBase, &Result));
|
||||
if ((ResultLength == 1) && (Result[0] == 0x80))
|
||||
{
|
||||
DPRINT("FDC %d is a pre-1991 82077\n", PortBase);
|
||||
*ControllerType = FDC_82077_ORIG;
|
||||
return TRUE;
|
||||
}
|
||||
if ((ResultLength != 1) || (Result[0] != 0x00))
|
||||
{
|
||||
DPRINT("FDC %d init: UNLOCK: unexpected return of %d bytes.\n",
|
||||
PortBase,
|
||||
ResultLength);
|
||||
return FALSE;
|
||||
}
|
||||
|
||||
output_byte(FD_UNLOCK);
|
||||
r = result();
|
||||
if ((r == 1) && (reply_buffer[0] == 0x80)){
|
||||
printk(KERN_INFO "FDC %d is a pre-1991 82077\n", fdc);
|
||||
return FDC_82077_ORIG; /* Pre-1991 82077, doesn't know
|
||||
* LOCK/UNLOCK */
|
||||
}
|
||||
if ((r != 1) || (reply_buffer[0] != 0x00)) {
|
||||
printk("FDC %d init: UNLOCK: unexpected return of %d bytes.\n",
|
||||
fdc, r);
|
||||
return FDC_UNKNOWN;
|
||||
}
|
||||
output_byte(FD_PARTID);
|
||||
r = result();
|
||||
if (r != 1) {
|
||||
printk("FDC %d init: PARTID: unexpected return of %d bytes.\n",
|
||||
fdc, r);
|
||||
return FDC_UNKNOWN;
|
||||
}
|
||||
if (reply_buffer[0] == 0x80) {
|
||||
printk(KERN_INFO "FDC %d is a post-1991 82077\n",fdc);
|
||||
return FDC_82077; /* Revised 82077AA passes all the tests */
|
||||
}
|
||||
switch (reply_buffer[0] >> 5) {
|
||||
case 0x0:
|
||||
/* Either a 82078-1 or a 82078SL running at 5Volt */
|
||||
printk(KERN_INFO "FDC %d is an 82078.\n",fdc);
|
||||
return FDC_82078;
|
||||
case 0x1:
|
||||
printk(KERN_INFO "FDC %d is a 44pin 82078\n",fdc);
|
||||
return FDC_82078;
|
||||
case 0x2:
|
||||
printk(KERN_INFO "FDC %d is a S82078B\n", fdc);
|
||||
return FDC_S82078B;
|
||||
case 0x3:
|
||||
printk(KERN_INFO "FDC %d is a National Semiconductor PC87306\n", fdc);
|
||||
return FDC_87306;
|
||||
default:
|
||||
printk(KERN_INFO "FDC %d init: 82078 variant with unknown PARTID=%d.\n",
|
||||
fdc, reply_buffer[0] >> 5);
|
||||
return FDC_82078_UNKN;
|
||||
}
|
||||
} /* get_fdc_version */
|
||||
/* Revised 82077AA passes all the tests */
|
||||
FloppyWriteCommandByte(PortBase, FLOPPY_CMD_PARTID);
|
||||
ResultLength = FloppyReadResultCode(PortBase, &Result));
|
||||
if (ResultLength != 1)
|
||||
{
|
||||
DPRINT("FDC %d init: PARTID: unexpected return of %d bytes.\n",
|
||||
PortBase,
|
||||
ResultLength);
|
||||
return FALSE;
|
||||
}
|
||||
if (Result[0] == 0x80)
|
||||
{
|
||||
DPRINT("FDC %d is a post-1991 82077\n", PortBase);
|
||||
*ControllerType = FDC_82077;
|
||||
return TRUE;
|
||||
}
|
||||
switch (Result[0] >> 5)
|
||||
{
|
||||
case 0x0:
|
||||
/* Either a 82078-1 or a 82078SL running at 5Volt */
|
||||
DPRINT("FDC %d is an 82078.\n", PortBase);
|
||||
*ControllerType = FDC_82078;
|
||||
return TRUE;
|
||||
|
||||
case 0x1:
|
||||
DPRINT("FDC %d is a 44pin 82078\n", PortBase);
|
||||
*ControllerType = FDC_82078;
|
||||
return TRUE;
|
||||
|
||||
static NTSTATUS FloppyStartIo(
|
||||
IN PDEVICE_OBJECT DeviceObject,
|
||||
IN PIRP Irp
|
||||
) {
|
||||
PIO_STACK_LOCATION IrpStack;
|
||||
PFLOPPY_DEVICE_EXTENSION DeviceExtension;
|
||||
|
||||
IrpStack = IoGetCurrentIrpStackLocation(Irp);
|
||||
DeviceExtension = (PFLOPPY_DEVICE_EXTENSION) DeviceObject->DeviceExtension;
|
||||
case 0x2:
|
||||
DPRINT("FDC %d is a S82078B\n", PortBase);
|
||||
*ControllerType = FDC_S82078B;
|
||||
return TRUE;
|
||||
|
||||
|
||||
case 0x3:
|
||||
DPRINT("FDC %d is a National Semiconductor PC87306\n", PortBase);
|
||||
*ControllerType = FDC_87306;
|
||||
return TRUE;
|
||||
|
||||
default:
|
||||
DPRINT("FDC %d init: 82078 variant with unknown PARTID=%d.\n",
|
||||
PortBase,
|
||||
Result[0] >> 5);
|
||||
*ControllerType = FDC_82078_UNKN;
|
||||
return TRUE;
|
||||
}
|
||||
}
|
||||
|
||||
FloppyDispatchOpenClose
|
||||
/* sends a command byte to the fdc */
|
||||
static BOOLEAN
|
||||
FloppyWriteCommandByte(WORD PortBase, BYTE Byte)
|
||||
{
|
||||
int Status;
|
||||
|
||||
FloppyDispatchReadWrite
|
||||
if ((Status = FloppyWaitUntilReady()) < 0)
|
||||
{
|
||||
return FALSE;
|
||||
}
|
||||
|
||||
FloppyDispatchDeviceControl
|
||||
if ((Status & (STATUS_READY|STATUS_DIR|STATUS_DMA)) == STATUS_READY)
|
||||
{
|
||||
FloppyWriteData(PortBase, Byte);
|
||||
return 0;
|
||||
}
|
||||
|
||||
FloppyIsr
|
||||
if (FloppyInitialized)
|
||||
{
|
||||
DPRINT("Unable to send byte %x to FDC. Fdc=%x Status=%x\n",
|
||||
Byte,
|
||||
PortBase,
|
||||
Status);
|
||||
}
|
||||
|
||||
return FALSE;
|
||||
}
|
||||
|
||||
/* gets the response from the fdc */
|
||||
static int
|
||||
FloppyReadResultCode(WORD PortBase, PBYTE Result)
|
||||
{
|
||||
int Replies;
|
||||
int Status;
|
||||
|
||||
for (Replies = 0; Replies < FLOPPY_MAX_REPLIES; Replies++)
|
||||
{
|
||||
if ((Status = FloppyWaitUntilReady(PortBase)) < 0)
|
||||
{
|
||||
break;
|
||||
}
|
||||
Status &= STATUS_DIR | STATUS_READY | STATUS_BUSY | STATUS_DMA;
|
||||
if ((Status & ~STATUS_BUSY) == STATUS_READY)
|
||||
{
|
||||
return Replies;
|
||||
}
|
||||
if (Status == (STATUS_DIR | STATUS_READY | STATUS_BUSY))
|
||||
{
|
||||
Result[Replies] = fd_inb(FD_DATA);
|
||||
}
|
||||
else
|
||||
{
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
if (FloppyInitialized)
|
||||
{
|
||||
DPRINT("get result error. Fdc=%d Last status=%x Read bytes=%d\n",
|
||||
PortBase,
|
||||
Status,
|
||||
Replies);
|
||||
}
|
||||
|
||||
return -1;
|
||||
}
|
||||
|
||||
/* waits until the fdc becomes ready */
|
||||
static int
|
||||
FloppyWaitUntilReady(WORD PortBase)
|
||||
{
|
||||
int Retries;
|
||||
int Status;
|
||||
|
||||
for (Retries = 0; Retries < FLOPPY_MAX_STAT_RETRIES; Retries++)
|
||||
{
|
||||
status = FloppyReadSTAT(PortBase);
|
||||
if (Status & STATUS_READY)
|
||||
{
|
||||
return Status;
|
||||
}
|
||||
}
|
||||
|
||||
if (FloppyInitialized)
|
||||
{
|
||||
DPRINT("Getstatus times out (%x) on fdc %d\n",
|
||||
Status,
|
||||
PortBase);
|
||||
}
|
||||
|
||||
return -1;
|
||||
}
|
||||
|
||||
|
||||
#define MORE_OUTPUT -2
|
||||
/* does the fdc need more output? */
|
||||
static int
|
||||
FloppyNeedsMoreOutput(WORD PortBase, PBYTE Result)
|
||||
{
|
||||
int Status;
|
||||
|
||||
if ((Status = FloppyWaitUntilReady(PortBase)) < 0)
|
||||
return -1;
|
||||
if ((Status & (STATUS_READY | STATUS_DIR | STATUS_DMA)) == STATUS_READY)
|
||||
{
|
||||
return FLOPPY_NEEDS_OUTPUT;
|
||||
}
|
||||
|
||||
return FloppyReadResultCode(PortBase, Result);
|
||||
}
|
||||
|
||||
static BOOLEAN
|
||||
FloppyConfigure(WORD PortBase, BOOLEAN DisableFIFO, BYTE FIFODepth)
|
||||
{
|
||||
BYTE Result[FLOPPY_MAX_REPLIES];
|
||||
|
||||
/* Turn on FIFO */
|
||||
FloppyWriteCommandByte(FLOPPY_CMD_CFG_FIFO);
|
||||
if (FloppyNeedsOutput(PortBase, Result) != FLOPPY_NEEDS_OUTPUT)
|
||||
{
|
||||
return FALSE;
|
||||
}
|
||||
FloppyWriteCommandByte(PortBase, 0);
|
||||
FloppyWriteCommandByte(PortBase,
|
||||
0x10 |
|
||||
(DisableFIFO ? 0x20 : 0x00) |
|
||||
(FIFODepth & 0x0f));
|
||||
/* pre-compensation from track 0 upwards */
|
||||
FloppyWriteCommandByte(PortBase, 0);
|
||||
|
||||
return TRUE;
|
||||
}
|
||||
|
||||
|
||||
|
|
|
@ -1,4 +1,10 @@
|
|||
|
||||
#define FLOPPY_MAX_STAT_RETRIES 10000
|
||||
|
||||
#define FLOPPY_NEEDS_OUTPUT -2
|
||||
//
|
||||
// Floppy register definitions
|
||||
//
|
||||
|
||||
#define FLOPPY_REG_DOR 0x0002
|
||||
#define FLOPPY_REG_MSTAT 0x0004
|
||||
|
@ -71,5 +77,82 @@
|
|||
#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_BYTE((A) + FLOPPY_REG_DOR, (V)))
|
||||
#define FloppyReadMSTAT(A) (READ_BYTE((A) + FLOPPY_REG_MSTAT))
|
||||
#define FloppyReadDATA(A) (READ_BYTE((A) + FLOPPY_REG_DATA))
|
||||
#define FloppyWriteDATA(A, V) (WRITE_BYTE((A) + FLOPPY_REG_DATA, (V)))
|
||||
#define FloppyReadDIR(A) (READ_BYTE((A) + FLOPPY_REG_DIR))
|
||||
#define FloppyWriteCCNTL(A, V) (WRITE_BYTE((A) + FLOPPY_REG_CCNTL, (V)))
|
||||
|
||||
//
|
||||
// Known Floppy controller types
|
||||
//
|
||||
typedef enum _FLOPPY_CONTROLLER_TYPE
|
||||
{
|
||||
FDC_NONE,
|
||||
FDC_UNKNOWN,
|
||||
FDC_8272A, /* Intel 8272a, NEC 765 */
|
||||
FDC_765ED, /* Non-Intel 1MB-compatible FDC, can't detect */
|
||||
FDC_82072, /* Intel 82072; 8272a + FIFO + DUMPREGS */
|
||||
FDC_82072A, /* 82072A (on Sparcs) */
|
||||
FDC_82077_ORIG, /* Original version of 82077AA, sans LOCK */
|
||||
FDC_82077, /* 82077AA-1 */
|
||||
FDC_82078_UNKN, /* Unknown 82078 variant */
|
||||
FDC_82078, /* 44pin 82078 or 64pin 82078SL */
|
||||
FDC_82078_1, /* 82078-1 (2Mbps fdc) */
|
||||
FDC_S82078B, /* S82078B (first seen on Adaptec AVA-2825 VLB SCSI/EIDE/Floppy controller) */
|
||||
FDC_87306 /* National Semiconductor PC 87306 */
|
||||
} FLOPPY_CONTROLLER_TYPE, *PFLOPPY_CONTROLLER_TYPE;
|
||||
|
||||
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;
|
||||
|
||||
#define FDP_DEBUG 0x02
|
||||
#define FDP_SILENT_DCL_CLEAR 0x04
|
||||
#define FDP_MSG 0x10
|
||||
#define FDP_BROKEN_DCL 0x20
|
||||
#define FDP_INVERTED_DCL 0x80
|
||||
|
||||
typedef struct _FLOPPY_DEVICE_PARAMETERS
|
||||
{
|
||||
char CMOSType;
|
||||
unsigned long MaxDTR; /* Step rate, usec */
|
||||
unsigned long HLT; /* Head load/settle time, msec */
|
||||
unsigned long HUT; /* Head unload time (remnant of 8" drives) */
|
||||
unsigned long SRT; /* Step rate, usec */
|
||||
unsigned long Spinup; /* time needed for spinup */
|
||||
unsigned long Spindown; /* timeout needed for spindown */
|
||||
unsigned char SpindownOffset; /* decides in which position the disk will stop */
|
||||
unsigned char SelectDelay; /* delay to wait after select */
|
||||
unsigned char RPS; /* rotations per second */
|
||||
unsigned char Tracks; /* maximum number of tracks */
|
||||
unsigned long Timeout; /* timeout for interrupt requests */
|
||||
unsigned char InterleaveSect; /* if there are more sectors, use interleave */
|
||||
FLOPPY_ERROR_THRESHOLDS MaxErrors;
|
||||
char Flags; /* various flags, including ftd_msg */
|
||||
BOOLEAN ReadTrack; /* use readtrack during probing? */
|
||||
short Autodetect[8]; /* autodetected formats */
|
||||
int CheckFreq; /* how often should the drive be checked for disk changes */
|
||||
int NativeFormat; /* native format of this drive */
|
||||
char *DriveName; /* name of the drive for reporting */
|
||||
} FLOPPY_DEVICE_PARAMETERS, *PFLOPPY_DEVICE_PARAMETERS;
|
||||
|
||||
|
||||
|
|
Loading…
Reference in a new issue