⭐ 欢迎来到虫虫下载站! | 📦 资源下载 📁 资源专辑 ℹ️ 关于我们
⭐ 虫虫下载站

📄 fl_drver.c

📁 移植Nuclues_RTC到coldfire5307在diab下编译通过
💻 C
📖 第 1 页 / 共 5 页
字号:
			fl_controller_init();
			return ReportError(ERR_IO_SECTOR);
		}
		
		if (!count)
			break;
		
			/* Add n transfered to the sector.
			If we wrapped the track reset the sector pointer.
			This wrap will occur almost every time. When we have a dma 
			wrap condition we truncated the sector count and will not
			wrap
		*/
		
		sec += n_todo;
		if (sec >= floppy[driveno].sectors_per_track)
		{
			sec = 0;
			if (head)
			{ 
				head = 0;
				cyl += 1;
			}
			else
				head = 1;
		}
		
		count -= n_todo;
		buffer += (n_todo<<9);
		
		/* Read the rest of the blocks or to the end of track. Whichever is less */
		/* Note: sec will usually be 0. unless a dma segment wrap occured. */
		utemp = (UCOUNT) (floppy[driveno].sectors_per_track - sec);
		if (count < utemp)
			n_todo = count;
		else
			n_todo = utemp;
    }
    return (YES);
}

/* floppy_format - Format a floppy disk.
* 
* Summary:
*
* BOOL floppy_format(driveno, drivesize, interleave, callback())
*
*
* Inputs:
*   UCOUNT driveno      - 0 or 1 = a: b:
*   COUNT drivesize     - 360,1200,1440,720
*   COUNT interleave    - interleave factor. (1 ==s no interleave gap)
*   void (*callback)()  - If non null this routine is called at each
*                         cylinder is formatted. The arguments are 
*                         cylinder number and highest cylinder. This
*                         may be used to print a progress summary.
*                         (see pcmkfs for a sample)
*
* Returns:
*   YES on success else NO.
*   
*   This routine formats every track on the drive. Before doing so it 
*   validates the interleave and returns if it is wrong. The interleave
*   must be either 1 or it must follow these two rules. 
*   It may not divide evenly into sectors/track and if sectors/track is an
*   even number interleave must be odd. If  sectors/track is an odd number
*   interleave must be even.
*
*   This routine is portable
*       
*/

BOOL floppy_format(UCOUNT driveno, COUNT drivesize, COUNT interleave, void (*callback)(COUNT, COUNT)) /*__fn__*/
{
	COMMAND_BLOCK b;
	COUNT parmindex;
	UTINY cylinder;
	UTINY sector;
	UTINY head;
	COUNT index;
	UTINY *sec_info;
	UCOUNT utemp;
	
    if (!interleave)
		return(NO);
	
    for (parmindex = 0; fl_devparms[parmindex].drive_size; parmindex++)
    {
		if ( (fl_devparms[parmindex].drive_size == drivesize) &&
			(floppy[driveno].drive_type == fl_devparms[parmindex].drive_type) )
		break;
    }
    if (!fl_devparms[parmindex].drive_size)
	{
		Stop_gTimer();
		fl_controller_init();
		return ReportError(ERR_INIT_DRNO);
//		return(fl_report_error(FLERR_UNK_DRIVE, NO));
	}
	
    if ((interleave > 1))
    {
		/* Interleave can not be an even multiple of sec/per track */
		if ( (((COUNT)(fl_devparms[parmindex].sectors_per_track)%interleave) == 0) ||
			/* Must be odd/even  or even/odd */
			((fl_devparms[parmindex].sectors_per_track & 0x01) == (interleave & 0x01) ) )
			return(fl_report_error(FLERR_INVALID_INTERLEAVE, NO));
    }
	
    /* load the floppy table from the device desc table. */
    fl_cp_parms(driveno, parmindex);
	
    fl_write_drr(floppy[driveno].data_rate);
    if (!fl_specify(driveno))
		return(fl_report_error(FLERR_SPECIFY, NO));
    fl_motor_on(driveno);
    if (!fl_recalibrate(driveno))
	{
		Stop_gTimer();
		fl_controller_init();
		return ReportError(ERR_RECAL);
//		return(fl_report_error(FLERR_RECAL, NO));
	}
	
    for (cylinder = 0; cylinder < fl_devparms[parmindex].cylinders_per_disk; cylinder++)
    {
		/* If a callback is provided print running status */
		if (callback)
			callback((COUNT)cylinder, (COUNT)(fl_devparms[parmindex].cylinders_per_disk-1));
		
		fl_motor_on(driveno);
		for (head = 0; head < 2; head++)
		{
			utemp = cylinder;
			if (floppy[driveno].double_step)
				utemp <<= 1;
			if (!fl_seek(driveno, utemp, head))
			{
				Stop_gTimer();
				fl_controller_init();
				return ReportError(ERR_SEEK);
//				return(fl_report_error(FLERR_SEEK, NO));
			}
			index = 0;
			/* build of the sector IDs. Include interleave calculation */
			for (sector = 1; sector <= fl_devparms[parmindex].sectors_per_track; sector++)
			{
				
#ifdef POLLED
				
				sec_info    = format_buffer+(index*4);
				
#else /* POLLED */
				
				sec_info    = dma_buffer+(index*4);
				
#endif /* POLLED */
				
				*sec_info++ = cylinder;
				*sec_info++ = head;
				*sec_info++ = sector;
				*sec_info   = 0x02;         /* N = 2 for 512 byte sectors */
				/* These three line do the interleave calulation */
				index += interleave;
				if (index >= (COUNT) fl_devparms[parmindex].sectors_per_track)
					index -= fl_devparms[parmindex].sectors_per_track;
			}
			b.n_to_send = 6;       
			b.n_to_get = 7;
			b.commands[0] = (UTINY) (MFMBIT|FL_FORMAT);
			b.commands[1] = (UTINY) ((head << 2)|driveno);
			b.commands[2] = (UTINY) 0x02;   /* bytes/sector */
			b.commands[3] = (UTINY) fl_devparms[parmindex].sectors_per_track;
			b.commands[4] = (UTINY) fl_devparms[parmindex].gpl_format;
			b.commands[5] = (UTINY) FORMAT_FILLER;
			
			/* Set up to write sec_per_track * 4 bytes */
#ifdef POLLED
			
			if (!fl_dma_init((UTINY *) format_buffer,(UCOUNT)((fl_devparms[parmindex].sectors_per_track)<<2), NO))
				return(fl_report_error(FLERR_DMA, NO));
			
#else /* POLLED */
			
			if (!fl_dma_init((UTINY *) dma_buffer,(UCOUNT)((fl_devparms[parmindex].sectors_per_track)<<2), NO))
				return(fl_report_error(FLERR_DMA, NO));
			
#endif /* POLLED */
			
			fl_motor_on(driveno);
			
			fl_int_enable(NO);
			if (!fl_command_phase(&b))
			{
				fl_int_enable(YES);
				goto fmterr;
			}
			/* Wait for the io to complete */
			if (!fl_waitdma(FLTMO_FMTTRACK))
				goto fmterr;
			if (!fl_results_phase(&b))
				goto fmterr;
			
			/* Check status register 0 for abnormal termination */
			if (b.results[0] & (BIT7|BIT6))
				goto fmterr;
		}
    }
    return(YES);
	
fmterr:
    return(fl_report_error(FLERR_FORMAT, NO));
}


/*  fl_controller_init - Initialize the floppy controller
* 
* summary
* BOOL fl_controller_init()
*
*
* Inputs:
*
* Returns:
*   YES on success else NO.
*   
* This routine zeroes out our data structures (floppy[0,1]). Then calls
* the host specific initialization code fl_establish() (sets up vectors/
* watchdogs). Then it attempts to reset the controller. If all is succesful
* it returns YES. 
*
* Called by floppy_open()
*
*/

static BOOL fl_controller_init()                                    /* __fn__ */
{
    selected_floppy = 0;
    pc_memfill(&floppy[0], sizeof(_FLOPPY), 0);
    pc_memfill(&floppy[1], sizeof(_FLOPPY), 0);

    /* Make sure the system timer is running */    
/*    mex_establish_timer(); */

    /* Event for signalling IO complete */
/*    if (!mex_floppy_event) */
/*        mex_floppy_event = NUF_FLOPPY_EVENT; */
/*        mex_floppy_event = mex_signal_alloc(); */
     /* make sure interrupt vector is installed */

    mex_establish_floppy_vector();

    floppy[0].drive_type = mex_floppy_type(0);
    floppy[1].drive_type = mex_floppy_type(1);
    floppy[0].media_type = (UTINY) DT_NONE;
    floppy[1].media_type = (UTINY) DT_NONE;

    Start_gTimer();         //Liuxuedong on 2002-3-28

    return (fl_reset_controller());
}

/* Issue a reset through the digital output register and wait for 
   an interrupt. */
static BOOL    fl_reset_controller()                                  /*__fn__*/
{
COMMAND_BLOCK b;

    fl_int_enable(NO);
    /* reset the floppy by toggling the reset line (BIT 3) */
    shadow_dig_out = 0;

    fl_write_dor(shadow_dig_out);
    /* Clear reset. Enable DMA and interrupts */
#ifdef POLLED

    shadow_dig_out |= (DORB_SRSTBAR);   /* Don't enable DMA or interrupts */

#else /* POLLED */

    shadow_dig_out |= (DORB_SRSTBAR|DORB_DMAEN);

#endif /* POLLED */

    fl_write_dor(shadow_dig_out);

    /* Wait up to 5 seconds for the interrupt to occur.*/
    if (!fl_waitint(FLTMO_RESET))
		return(fl_report_error(FLERR_RESET, NO));

    if (!fl_sense_interrupt(&b))
	return(fl_report_error(FLERR_RESET, NO));

	/*Enable the FIFO and set the FIFO threshold*/
	if(!fl_configure()) //by zhaowei
		return(NO);

    return(YES);
}

/* fl_claim - Claim the controller for IO to a drive
* 
* Summary:
*
* BOOL fl_claim(driveno)
*
*
* Inputs:
*   UCOUNT driveno      - 0 or 1 = a: b:
*
* Returns:
*   YES on success else NO.
*   
*   This routine is called by floppy_io each time it will do io to a drive.
*   if the drive is the current active drive it writes the data rate reg and 
*   returns. Otherwise the other drive will be accessed. If the medai type
*   has not been established this is done. The controller timing parameters
*   are specified and the data rate is set.
*       
*/

static BOOL fl_claim(UCOUNT driveno)                                  /*__fn__*/
{
    if (selected_floppy != (driveno+1))
    {
		selected_floppy = (UCOUNT) (driveno+1);
		if (floppy[driveno].media_type == DT_NONE)
		{
			if (!fl_establish_media(driveno))
				return(NO);
		}
		else if (!fl_specify(driveno))
			return(fl_report_error(FLERR_SPECIFY, NO));
		selected_floppy = (UCOUNT) (driveno+1);
    }
    fl_write_drr(floppy[driveno].data_rate);
    return(YES);
}

/* fl_establish_media - Vary the data rate and read until succesful
* 
* Summary:
*
* BOOL fl_establish_media(driveno)
*
*
* Inputs:
*   UCOUNT driveno      - 0 or 1 = a: b:
*
* Returns:
*   YES on success else NO.
*   
* For each possible media type for this drive type in the devparms table. 
* Set the data rate, recal ,seek and read sector ID information from the
* drive. If the read ID works return YES. If all possible media are exhausted
* return NO.
*
* NOTE: The floppy change line is cleared by the seek operations.
*/

static BOOL fl_establish_media(UCOUNT driveno)                        /*__fn__*/
{
COUNT i;
COMMAND_BLOCK b;
	
    /* Find the first drive description entry for the drive type */
    for (i = 0; fl_devparms[i].drive_type; i++)
    {
		if (fl_devparms[i].drive_type == floppy[driveno].drive_type)
			break;
    }
    /* Now scan through all drive descriptions for this drive type until
	we get get one we can read */
    while (fl_devparms[i].drive_type == floppy[driveno].drive_type)
    {
		/* Copy params from the drive table to the device */
		fl_cp_parms(driveno, i);
		/* Set the data rate */
		fl_write_drr(floppy[driveno].data_rate);
		if (fl_specify(driveno))
		{
			fl_motor_on(driveno);
			if (fl_recalibrate(driveno))
			{
				Recalibrate_Ok = YES ;//重校准OK,置YES  Liao Yibai 2002-11-26
				/* read sector markers. if we get a normal terminaton we're ok */
				fl_motor_on(driveno);
				/* See if we can read the sector ID field */
				if (fl_read_id(driveno, &b))
				{
					if ((b.results[0] & (BIT6|BIT7)) == 0)
					{
					/* Now we seek to cyl 2 and back to zero. This will 
						clear the change line if needed */
						fl_motor_on(driveno);
						if (!(fl_seek(driveno, 2, 0) && fl_seek(driveno, 0, 0)))
							break;
						else
							return(YES);
					}
				}
			}
			//重校准不OK,以此判断软盘驱动器接线是否正确  Liao Yibai 2002-11-26
			else
			{
				Recalibrate_Ok = NO ;
			}
		}
		i++;
    }
    floppy[driveno].media_type = DT_NONE;
    return (fl_report_error(FLERR_MEDIA, NO));
}

/*  fl_sense_interrupt - Issue a sense interrupt command
*  寻道命令和重校正命令都没有结果阶段.所以在使用这两条命令后,
*  必须用检测中断状态命令来结束操作并核查磁头的位置。
* Summary:
*
* BOOL fl_sense_interrupt(COMMAND_BLOCK *p)
*
*
* Inputs:
*   COMMAND_BLOCK *p - storage area. On return the results[0,1,2] will contain
*                      status registers 0,1,2
*
* Returns:
*   YES on success else NO.
*   
* This routine issues a sense interrupt command. It is called after

⌨️ 快捷键说明

复制代码 Ctrl + C
搜索代码 Ctrl + F
全屏模式 F11
切换主题 Ctrl + Shift + D
显示快捷键 ?
增大字号 Ctrl + =
减小字号 Ctrl + -