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:
|
// Modification History:
|
||||||
// 08/19/98 RJJ Created.
|
// 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 <ddk/ntddk.h>
|
||||||
|
|
||||||
#include "floppy.h"
|
#include "floppy.h"
|
||||||
|
|
||||||
#define VERSION "V0.0.1"
|
#define VERSION "V0.0.1"
|
||||||
|
|
||||||
// --------------------------------------------------- File Statics
|
// --------------------------------------------------- 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
|
// ------------------------------------------------------ Functions
|
||||||
|
|
||||||
// ModuleEntry
|
// ModuleEntry
|
||||||
|
@ -37,14 +78,14 @@
|
||||||
// RETURNS:
|
// RETURNS:
|
||||||
// NTSTATUS
|
// NTSTATUS
|
||||||
|
|
||||||
NTSTATUS ModuleEntry(
|
NTSTATUS
|
||||||
IN PDRIVER_OBJECT DriverObject,
|
DriverEntry(IN PDRIVER_OBJECT DriverObject,
|
||||||
IN PUNICODE_STRING RegistryPath
|
IN PUNICODE_STRING RegistryPath)
|
||||||
) {
|
{
|
||||||
NTSTATUS RC;
|
NTSTATUS RC;
|
||||||
PFLOPPY_DEVICE_EXTENSION DeviceExtension;
|
PFLOPPY_DEVICE_EXTENSION DeviceExtension;
|
||||||
|
|
||||||
// Export other driver entry points...
|
// Export other driver entry points...
|
||||||
DriverObject->DriverStartIo = FloppyStartIo;
|
DriverObject->DriverStartIo = FloppyStartIo;
|
||||||
DriverObject->MajorFunction[IRP_MJ_CREATE] = FloppyDispatchOpenClose;
|
DriverObject->MajorFunction[IRP_MJ_CREATE] = FloppyDispatchOpenClose;
|
||||||
DriverObject->MajorFunction[IRP_MJ_CLOSE] = FloppyDispatchOpenClose;
|
DriverObject->MajorFunction[IRP_MJ_CLOSE] = FloppyDispatchOpenClose;
|
||||||
|
@ -52,43 +93,82 @@ NTSTATUS ModuleEntry(
|
||||||
DriverObject->MajorFunction[IRP_MJ_WRITE] = FloppyDispatchReadWrite;
|
DriverObject->MajorFunction[IRP_MJ_WRITE] = FloppyDispatchReadWrite;
|
||||||
DriverObject->MajorFunction[IRP_MJ_DEVICE_CONTROL] = FloppyDispatchDeviceControl;
|
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
|
return STATUS_SUCCESS;
|
||||||
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;
|
|
||||||
}
|
|
||||||
|
|
||||||
// Fill out Device Extension
|
static BOOLEAN
|
||||||
DeviceExtension = (PFLOPPY_DEVICE_EXTENSION)
|
FloppyCreateController(PDRIVER_OBJECT DriverObject,
|
||||||
DeviceObject->DeviceExtension;
|
PFLOPPY_CONTROLLER_PARAMETERS ControllerParameters,
|
||||||
DeviceExtension->Number = 0;
|
int Index)
|
||||||
DeviceExtension->PortBase = FLOPPY_PORT_BASE;
|
{
|
||||||
DeviceExtension->Vector = FLOPPY_IRQ_VECTOR;
|
PFLOPPY_CONTROLLER_TYPE ControllerType;
|
||||||
DeviceExtension->IrqL = FLOPPY_DIRQL;
|
PCONTROLLER_OBJECT ControllerObject;
|
||||||
DeviceExtension->DMASupported = FALSE;
|
PFLOPPY_CONTROLLER_EXTENSION ControllerExtension;
|
||||||
DeviceExtension->FloppyState = FloppyStateIdle;
|
|
||||||
|
|
||||||
// Register an interrupt handler for this device
|
/* Detect controller and determine type */
|
||||||
RC = IoConnectInterrupt(&DeviceExtension->Interrupt,
|
if (!FloppyGetControllerVersion(ControllerParameters, &ControllerType))
|
||||||
FloppyIsr, DeviceExtension, NULL,
|
{
|
||||||
DeviceExtension->Vector, DeviceExtension->IrqL,
|
return FALSE;
|
||||||
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;
|
|
||||||
}
|
|
||||||
|
|
||||||
// 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;
|
return STATUS_SUCCESS;
|
||||||
}
|
}
|
||||||
|
@ -110,109 +190,255 @@ NTSTATUS ModuleEntry(
|
||||||
// COMMENTS:
|
// COMMENTS:
|
||||||
// This routine (get_fdc_version) was originally written by David C. Niemi
|
// This routine (get_fdc_version) was originally written by David C. Niemi
|
||||||
//
|
//
|
||||||
static BOOLEAN FloppyGetControllerVersion(
|
static BOOLEAN
|
||||||
IN OUT PFLOPPY_DEVICE_EXTENSION DeviceExtension
|
FloppyGetControllerVersion(IN PFLOPPY_CONTROLLER_PARAMETERS ControllerParameters,
|
||||||
) {
|
OUT PFLOPPY_CONTROLLER_TYPE ControllerType)
|
||||||
int Result;
|
{
|
||||||
FLOPPY_CMD CommandToSend;
|
BYTE ResultReturned
|
||||||
FLOPPY_RESULT ResultReturned
|
BYTE Result[FLOPPY_MAX_REPLIES];
|
||||||
|
int ResultLength;
|
||||||
|
|
||||||
CommandToSend.CMd[0] = FLOPPY_CMD_FD_DUMPREGS;
|
/* 82072 and better know DUMPREGS */
|
||||||
FloppyWriteCommand(DeviceExtension->PortBase, &CommandToSend, &ResultReturned);
|
if (!FloppyWriteCommandByte(ControllerParameters->PortBase,
|
||||||
|
FLOPPY_CMD_DUMP_FDC))
|
||||||
|
{
|
||||||
|
return FALSE;
|
||||||
|
}
|
||||||
|
ResultLength = FloppyReadResultCode(PortBase, &Result));
|
||||||
|
if (ResultLength < 0)
|
||||||
|
{
|
||||||
|
return FALSE;
|
||||||
|
}
|
||||||
|
|
||||||
/* 82072 and better know DUMPREGS */
|
/* 8272a/765 don't know DUMPREGS */
|
||||||
if (FDCS->reset)
|
if ((ResultLength == 1) && (Result[0] == 0x80))
|
||||||
return FDC_NONE;
|
{
|
||||||
if ((r = result()) <= 0x00)
|
DPRINT("FDC %d is an 8272A\n", PortBase);
|
||||||
return FDC_NONE; /* No FDC present ??? */
|
*ControllerType = FDC_8272A;
|
||||||
if ((r==1) && (reply_buffer[0] == 0x80)){
|
return TRUE;
|
||||||
printk(KERN_INFO "FDC %d is an 8272A\n",fdc);
|
}
|
||||||
return FDC_8272A; /* 8272a/765 don't know DUMPREGS */
|
if (r != 10)
|
||||||
}
|
{
|
||||||
if (r != 10) {
|
DPRINT("FDC %d init: DUMP_FDC: unexpected return of %d bytes.\n",
|
||||||
printk("FDC %d init: DUMPREGS: unexpected return of %d bytes.\n",
|
PortBase,
|
||||||
fdc, r);
|
ResultLength);
|
||||||
return FDC_UNKNOWN;
|
return FALSE;
|
||||||
}
|
}
|
||||||
|
|
||||||
if(!fdc_configure()) {
|
if (!FloppyConfigure(PortBase, FALSE, 0x0a))
|
||||||
printk(KERN_INFO "FDC %d is an 82072\n",fdc);
|
{
|
||||||
return FDC_82072; /* 82072 doesn't know CONFIGURE */
|
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);
|
/* Pre-1991 82077, doesn't know LOCK/UNLOCK */
|
||||||
if(need_more_output() == MORE_OUTPUT) {
|
FloppyWriteCommandByte(PortBase, FLOPPY_CMD_UNLK_FIFO);
|
||||||
output_byte(0);
|
ResultLength = FloppyReadResultCode(PortBase, &Result));
|
||||||
} else {
|
if ((ResultLength == 1) && (Result[0] == 0x80))
|
||||||
printk(KERN_INFO "FDC %d is an 82072A\n", fdc);
|
{
|
||||||
return FDC_82072A; /* 82072A as found on Sparcs. */
|
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);
|
/* Revised 82077AA passes all the tests */
|
||||||
r = result();
|
FloppyWriteCommandByte(PortBase, FLOPPY_CMD_PARTID);
|
||||||
if ((r == 1) && (reply_buffer[0] == 0x80)){
|
ResultLength = FloppyReadResultCode(PortBase, &Result));
|
||||||
printk(KERN_INFO "FDC %d is a pre-1991 82077\n", fdc);
|
if (ResultLength != 1)
|
||||||
return FDC_82077_ORIG; /* Pre-1991 82077, doesn't know
|
{
|
||||||
* LOCK/UNLOCK */
|
DPRINT("FDC %d init: PARTID: unexpected return of %d bytes.\n",
|
||||||
}
|
PortBase,
|
||||||
if ((r != 1) || (reply_buffer[0] != 0x00)) {
|
ResultLength);
|
||||||
printk("FDC %d init: UNLOCK: unexpected return of %d bytes.\n",
|
return FALSE;
|
||||||
fdc, r);
|
}
|
||||||
return FDC_UNKNOWN;
|
if (Result[0] == 0x80)
|
||||||
}
|
{
|
||||||
output_byte(FD_PARTID);
|
DPRINT("FDC %d is a post-1991 82077\n", PortBase);
|
||||||
r = result();
|
*ControllerType = FDC_82077;
|
||||||
if (r != 1) {
|
return TRUE;
|
||||||
printk("FDC %d init: PARTID: unexpected return of %d bytes.\n",
|
}
|
||||||
fdc, r);
|
switch (Result[0] >> 5)
|
||||||
return FDC_UNKNOWN;
|
{
|
||||||
}
|
case 0x0:
|
||||||
if (reply_buffer[0] == 0x80) {
|
/* Either a 82078-1 or a 82078SL running at 5Volt */
|
||||||
printk(KERN_INFO "FDC %d is a post-1991 82077\n",fdc);
|
DPRINT("FDC %d is an 82078.\n", PortBase);
|
||||||
return FDC_82077; /* Revised 82077AA passes all the tests */
|
*ControllerType = FDC_82078;
|
||||||
}
|
return TRUE;
|
||||||
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 */
|
|
||||||
|
|
||||||
|
case 0x1:
|
||||||
|
DPRINT("FDC %d is a 44pin 82078\n", PortBase);
|
||||||
|
*ControllerType = FDC_82078;
|
||||||
|
return TRUE;
|
||||||
|
|
||||||
static NTSTATUS FloppyStartIo(
|
case 0x2:
|
||||||
IN PDEVICE_OBJECT DeviceObject,
|
DPRINT("FDC %d is a S82078B\n", PortBase);
|
||||||
IN PIRP Irp
|
*ControllerType = FDC_S82078B;
|
||||||
) {
|
return TRUE;
|
||||||
PIO_STACK_LOCATION IrpStack;
|
|
||||||
PFLOPPY_DEVICE_EXTENSION DeviceExtension;
|
|
||||||
|
|
||||||
IrpStack = IoGetCurrentIrpStackLocation(Irp);
|
|
||||||
DeviceExtension = (PFLOPPY_DEVICE_EXTENSION) DeviceObject->DeviceExtension;
|
|
||||||
|
|
||||||
|
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_DOR 0x0002
|
||||||
#define FLOPPY_REG_MSTAT 0x0004
|
#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_WRITE (FLOPPY_CMD_WRT_DATA | FLOPPY_C0M_MFM | FLOPPY_C0M_MT)
|
||||||
#define FLOPPY_CMD_FORMAT (FLOPPY_CMD_FMT_TRK | FLOPPY_C0M_MFM)
|
#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