📄 fl_drver.c
字号:
/*************************************************************************/
/*声明: 本文件由张士玉修改,如果要修改,请先与他联系!
/* */
/* VERSION RELEASE DATE: 12-08-93 */
/* */
/* RTX/PLUS/386 PC WITH */
/* NUCLEUS BIOS */
/* FILE SYSTEM 1.5 */
/* */
/* */
/* HISTORY */
/* */
/* DATE REMARKS */
/* */
/* 12-08-93 Initial version of the Nucleus Single */
/* Board File System. This version was */
/* originally only for the Nucleus PLUS */
/* Single Board version. */
/* */
/* 12-22-93 The File System is updated to run with */
/* either Nucleus RTX Single Board (ver 1.1)*/
/* or Nucleus Plus Single Board (ver 1.1b). */
/* */
/* 08-20-97 The File System is updated to run */
/* without using DMA. The compile line */
/* option POLLED will turn off DMA support */
/* and use polled mode to talk to the */
/* floppy controller (release 1.5). */
/* */
/* 10-06-97 Changed FLTMO_SEEK to support low level */
/* formatting of 360k floppy. */
/* */
/*************************************************************************/
/* Contains NUCLEUS Specific Code */
/*
* EBS - RTFS (Real Time File Manager)
*
* Copyright Peter Van Oudenaren , 1993
* All rights reserved.
* This code may not be redistributed in source or linkable object form
* without the consent of its author.
*/
/* fl_drver.c - Generic floppy disk driver routines.
Routines in this file are generic routines to control an NEC765 class
floppy disk controller in AT mode. The routines should be independent
of executive environment and of the system hosting the 765 controller.
Public routines:
These routines are pointed to by the RTFS bdevsw table.
floppy_ioctl - IO control function. Does nothing
floppy_raw_open - Raw open routine. Does nothing
floppy_open - Drive open routine. Initializes the controller and
establishes interrupt vector if open count is zero.
Increments the open count.
floppy_close - Decreases the open count. If the open count goes
to zero it releases interrupts.
floppy_io - Performs reads/writes on the drives
This routine is public but is not in the device table. You may call it
directly.
fl_format -
The rest of the routines are internal to the driver.
fl_claim - Claims the controller for a drive. Establishes
the media type if need be and sets the data rate
so the disk may be read/written.
fl_establish_media - Determines the media type of the floppy disk in
the drive by varying the data rate and attempting to
read the sector ID off of the disk. Also seeks the
head to clear the disk changed line.
fl_sense_interrupt - Requests sense (staust registers) from the floppy
after reset,recal and seek
fl_read_id - Reads sector IDs from a floppy. Used by establish
media
fl_seek - Seeks the head.
fl_recalibrate - Seeks the head to track 0 and resets chips internal
head position counter
fl_specify - Specify head load/unload times and seek step rate
fl_controller_init - Clears internal floppy tables, establishes interrupts
and resets the 765 chip.
fl_reset_controller - Called by fl_controller_init. Issues a reset to
the chip.
fl_motor_on - Turns the floppy motor on and starts a daemon to
shut it off.
fl_motor_off - The daemon calls this to shut off the floppy motor
fl_command_phase - Sends command phase values to the chip. Called by
higher level routines like fl_read_id, fl_io etc.
fl_results_phase - Reads results phase values from the chip. Called by
higher level routines like fl_read_id, fl_io etc.
fl_ready - Determines what data transfer state the floppy
controller's state machine is in. TO, FROM or
none.
fl_change_line - Called by floppy_io to check the drive's change
line to see if the floppy disk has been removed.
If the drive has been removed we call establish
media to clear it. We should probaly add a call
back mechanism here to alert the user to replace the
disk and possibly to give the file system a
chance to recover.
fl_cp_parms - Copy parameters from the parameter table to the
_floppy structure.
fl_dma_chk - Takes an address and returns the number of blocks
that may be transferd to that address before a
dma segment wrap occurs.
fl_dma_init - Sets up the dma controller for a to or from memory
transfer from/to the floppy controller
fl_int_enable - Mask floppy disk interupts oin/off
fl_read_data - Reads a byte from the 765 data register
fl_read_drr - Reads a byte from the 765 data rate register
fl_read_msr - Reads a byte from the 765 master status register
fl_write_data - Writes a byte to the 765 data register
fl_write_dor - Writes a byte to the 765 digital output register
fl_write_drr - Writes a byte to the 765 data rate register
fl_report_error - Converts floppy errors to strings and prints them
fl_waitdma - Waits for dma to complete and checks status
fl_waitint - Waits for a floppy disk interrupt. Or tiomes out
fl_isr - Floppy disk interrupt service routine
*/
//Daniel Start
#ifndef POLLED
#define POLLED 1
#endif
//Daniel End
#ifdef PLUS
#include "nucleus.h"
#else
#include "nu_defs.h"
#include "nu_extr.h"
#include <dos.h>
#endif
#include "pcdisk.h"
#include "miniexec.h"
//add by Lxd on 02-2-8
#define Start_gTimer() asm(" nop ")
#define Stop_gTimer() asm(" nop ")
//add by zlp 02-01-14, mo
#define delay_25us() asm(" nop ")
#define delay_1us() asm(" nop ")
//end add by zlp
//系统自检加入,放驱动器重校准命令执行的结果 Liao Yibai 2002-11-26
int Recalibrate_Ok;
/*
//Daniel Start, 定时器2
#define TMR2 0x10000120
#define TRR2 0x10000124
#define TCR2 0x10000128
#define TCN2 0x1000012c
#define TER2 0x10000131
//Daniel End
*/
/* Handy bit definitions */
#define BIT7 (UTINY) 0x80
#define BIT6 (UTINY) 0x40
#define BIT5 (UTINY) 0x20
#define BIT4 (UTINY) 0x10
#define BIT3 (UTINY) 0x08
#define BIT2 (UTINY) 0x04
#define BIT1 (UTINY) 0x02
#define BIT0 (UTINY) 0x01
/* Timing parameters */
#if 0
NUCLEUS - These values are expressed below in ticks.
#define FL_SPINUP 1000 /* Milliseconds to delay on spin up */
#define MOTOR_TIMEOUT 3000 /* Milliseconds until we shut the motor off */
/* Timeout values in millisecond for various operations */
/* These are in ticks under smx */
#define FLTMO_IO 6000 /* 6 sec Read or write */
#define FLTMO_FMTTRACK 6000 /* 6 sec Format a track */
#define FLTMO_READID 3000 /* 3 sec Read ID during establish media */
#define FLTMO_SEEK 1000 /* 1 sek Seek to a track */
#define FLTMO_RECAL 3000 /* 3 sec Recalibrate (seek to 0) */
#define FLTMO_RESET 6000 /* 6 sec Wait for interrupt after reset */
#else
#define FL_SPINUP 18 /* Milliseconds to delay on spin up */
//#define MOTOR_TIMEOUT 54 /* Milliseconds until we shut the motor off */
#define MOTOR_TIMEOUT 260 //需要调整,以获得最佳效果
/* Timeout values in millisecond for various operations */
/* These are in ticks under smx */
#ifdef POLLED
#define FLTMO_IO 2 /* 20 ms Read or write */
#define FLTMO_FMTTRACK 2 /* 20 ms Format a track */
#define FLTMO_READID 2 /* 20 ms Read ID during establish media */
//#define FLTMO_SEEK 2 /* 20 ms Seek to a track */
#define FLTMO_SEEK 24//36 /* 36 is used for 360k disks */
//#define FLTMO_RECAL 2 /* 20 ms Recalibrate (seek to 0) */
#define FLTMO_RECAL 24 /* 240 ms Recalibrate (seek to 0) */
#define FLTMO_RESET 2 /* 20 ms Wait for interrupt after reset */
#else /* POLLED */
#define FLTMO_IO 108 /* 6 sec Read or write */
#define FLTMO_FMTTRACK 108 /* 6 sec Format a track */
#define FLTMO_READID 54 /* 3 sec Read ID during establish media */
#define FLTMO_SEEK 36 /* was 18 for 1 sec Seek to a track */
/* Changed to 36 for 360k disks */
#define FLTMO_RECAL 54 /* 3 sec Recalibrate (seek to 0) */
#define FLTMO_RESET 108 /* 6 sec Wait for interrupt after reset */
#endif /* POLLED */
#endif
/* Digital output register bits */
#define DORB_DSEL BIT0
#define DORB_SRSTBAR BIT2
#define DORB_DMAEN BIT3
#define DORB_MOEN1 BIT4
#define DORB_MOEN2 BIT5
#define DORB_MODESEL BIT7
/* Commands to the controller */
#define FL_CONFIGURE 0x13 /* Control some operation modes */
#define FL_SPECIFY 0x3 /* Specify drive timing */
#define FL_SENSE_STATUS 0x4 /* Read status register 3 */
#define FL_WRITE 0x5 /* Write block(s) */
#define FL_READ 0x6 /* Read block(s) */
#define FL_RECALIBRATE 0x7 /* Recalibrate */
#define FL_SENSE_INTERRUPT 0x8 /* Sense interrupt status */
#define FL_READID 0xa /* Read sector id under head */
#define FL_FORMAT 0xd /* Format track */
#define FL_SEEK 0xf /* Seek to a cylinder */
/* Qualifier bits to read/write commands */
#define MFMBIT BIT6
#define MTBIT BIT7
/* Arguments to specify command */
//#define SP_1 (UTINY) 0xaf /* step rate 6 milsec, head uload 240 */
#define SP_1 (UTINY) 0xDF /*步进速率:3ms, 磁头卸载时间:240,Daniel */
#ifdef POLLED
#define SP_2 (UTINY) 0x3 /* head load = 1ms(应该是2ms//Daniel), dma disabled */
#else /* POLLED */
#define SP_2 (UTINY) 0x2 /* head load = 1ms, dma enabled */
#endif /* POLLED */
/* Filler byte for use during format */
#define FORMAT_FILLER 0xf6
/* Error values */
#define FLERR_ABN_TERM 1
#define FLERR_CHIP_HUNG 2
#define FLERR_DMA 3
#define FLERR_FORMAT 4
#define FLERR_INVALID_INTERLEAVE 5
#define FLERR_IO_SECTOR 6
#define FLERR_IO_TMO 7
#define FLERR_MEDIA 8
#define FLERR_RECAL 9
#define FLERR_RESET 10
#define FLERR_SEEK 11
#define FLERR_SPECIFY 12
#define FLERR_UNK_DRIVE 13
#define FLERR_EXEC_EST 14
/* Drive types as stored in the AT cmos eeprom. We use the same constants for
established media type in the drive. */
#define DT_NONE 0
#define DT_360 1
#define DT_12 2
#define DT_720 3
#define DT_144 4
#define DT_288 5
/* Data rate register values */
#define DR_250 0x02
#define DR_300 0x01
#define DR_500 0x00
#define DR_1000 0x03
/* Values returned from fl_ready. - If it returns 0 the controller is not
ready to accept or send data */
#define FL_FRHOST 1 /* Controller expecting data from host */
#define FL_TOHOST 2 /* Controller has data for host */
/* Gap values. nemonics make the drive description table easier to read */
/* GPF is gpl_format */
#define GPF_50 0x50
#define GPF_54 0x54
#define GPF_6C 0x6C
/* GPL is gpl_read */
#define GPL_2A 0x2A
#define GPL_1B 0x1B
typedef struct _fl_devparms {
COUNT drive_size; /* 360,720,1200,1440,2880 */
UTINY drive_type; /* DT_360 et al. Drive type from AT cmos */
UTINY media_type; /* DT_360 et al. Media installed in drive */
UTINY specify_1; /* StepRate:Head Unload */
UTINY specify_2; /* HeadLoad:NonDma */
UTINY data_rate; /* DR_250 et al */
UTINY sectors_per_track;
UTINY cylinders_per_disk;
UTINY gpl_read; /* Gap durong read write */
UTINY gpl_format; /* Gap during format */
} _FL_DEVPARMS;
/****************************************************************
//1440, 4, 4, 0xAF, 0x03, 0, 18, 80, 0x1B, 0x6C
specify_1 :步进速率:磁头卸载时间
磁头卸载时间:0x0F 磁头卸载时间(HUT)规定了从读/写命令执行阶段
结束到磁头处于卸载状态的时间,该定时器是可编程的
编程值从16-240ms,增量是16ms(即01=16ms,02=32ms
…0F=240ms)
步进速率: 0x0A 步进速率时间(SRT)规定了相邻步进脉冲之间的时间
间隔,该定时器可有1一16ms的编程范围.增量是1ms(F=
1ms,E=2ms.D=3ms等), 这里:6ms
specify_2 : 磁头加载时间:DMA
磁头加载时间: 0x01 磁头加载时间(HCT)规定了启动磁头加载信号和开
始该/写操作之间的时间间隔,该定时器可有2-254ms
的编程范围,增量是2ms(01=2ms,02=4ms.03=6ms,
…FE=254ms)。步进速率应该比驱动器所需要的最短时
间长1ms
DMA: 0x01 非DMA方式
****************************************************************/
typedef struct command_block
{
UTINY data_rate_reg; /* Written to data rate register each time */
COUNT n_to_send; /* Number of bytes to send in the command phase */
COUNT n_to_get; /* Number of bytes expected in the results phase */
COUNT n_gotten; /* Number gotten in the results phase */
UTINY commands[10]; /* Sent during command phase */
UTINY results[10]; /* Returned during results phase */
} COMMAND_BLOCK;
/* Each drive has one of these structures that we update one we know what the media type is */
typedef struct _floppy
{
UTINY drive_type; /* DT_360 et al. Drive type from AT cmos */
UTINY media_type; /* DT_NONE if not established */
UTINY specify_1; /* StepRate:Head Unload */
UTINY specify_2; /* HeadLoad:NonDma */
UTINY data_rate; /* DR_250 et al */
UTINY sectors_per_track;
UTINY sectors_per_cyl;
UTINY cylinders_per_disk;
UTINY gpl_read; /* Gap durong read write */
BOOL double_step;
} _FLOPPY;
/* Handle of io event channel */
/* COUNT mex_floppy_event; */
/* Shadow of the digital output register. We write to this each time we
write to the dig. output reg. */
UTINY shadow_dig_out = 0;
#ifndef POLLED
/* We need a 512 byte buffer occasionaly */
/* UTINY dma_buffer[512]; */ /* <- Already allocated in FMT.ASM */
IMPORT UTINY dma_buffer[65535];
#define DMA_BUF_SIZE 128 /* <- Size in blocks of the dma_buffer */
#else /* NOT POLLED */
UTINY format_buffer[512]; /* Work buffer needed by the format function */
#endif /* NOT POLLED */
#ifdef POLLED
/* These are filled in by fl_dma_init and are used by fl_waitdma when in
polled mode so that it can transfer the data to the floppy controller. */
UTINY *polled_buffer; /* Pointer to the user supplied data buffer */
UCOUNT polled_length; /* Number of bytes to transfer */
BOOL polled_reading; /* Flag to determine if this is a Read or Write */
#endif /* POLLED */
/* Current selected floppy for use by fl_claim.
Note: We use the following confusing convention:
0 = None selected
1 = Drive one selected
2 = Drive two selected
This is confusing because usually driveno == 0, 1 for the first two drives */
UCOUNT selected_floppy = 0;
_FLOPPY floppy[2];
/* Table of device paramters, The first field specifies the drive itself
the second specifies the media installed, the rest are operating
parameters. Note: the order of the table is important. When trynig to
determine media type we find the drive type and then try each media
type for that drive type in ascending order until one works. */
const _FL_DEVPARMS fl_devparms[] = {
{360, DT_360, DT_360, SP_1, SP_2, DR_250, 9, 40, GPL_2A, GPF_50},
{1200, DT_12 , DT_12 , SP_1, SP_2, DR_500, 15, 80, GPL_1B, GPF_54},
{360, DT_12 , DT_360, SP_1, SP_2, DR_300, 9, 40, GPL_2A, GPF_50},
{720, DT_720, DT_720, SP_1, SP_2, DR_250, 9, 80, GPL_2A, GPF_50},
{1440, DT_144, DT_144, SP_1, SP_2, DR_500, 18, 80, GPL_1B, GPF_6C},
{720, DT_144, DT_720, SP_1, SP_2, DR_250, 9, 80, GPL_2A, GPF_50},
{0, 0, 0, 0, 0, 0, 0, 0, 0, 0}
};
//1440, 4, 4, 0xAF, 0x03, 0, 18, 80, 0x1B, 0x6C
#ifndef POLLED
#ifdef PLUS
void real_lisr_fl_isr();
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -