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

📄 fl_drver.c

📁 移植Nuclues_RTC到coldfire5307在diab下编译通过
💻 C
📖 第 1 页 / 共 5 页
字号:
UTINY c;
int old_level;    /* old interrupt level */

#ifdef PLUS
    old_level = NU_Control_Interrupts(NU_DISABLE_INTERRUPTS);    
#else    
    old_level = NU_Control_Interrupts(NU_DISABLE_INTERRUPTS);    
#endif
    /* Toggle bit six in the PIC */
    c = (UTINY) fl_inp(0x21);
    if (on)
	c &= ~BIT6;
    else
	c |= BIT6;
    fl_outp(0x21, c);
#ifdef PLUS
    NU_Control_Interrupts(old_level);
#else
    old_level = NU_Control_Interrupts(NU_DISABLE_INTERRUPTS);    
    enable();
#endif
}

#ifndef POLLED

#ifdef  PLUS
/*  real_lisr_fl_isr -  this function is invoked by the LISR in file FL_ASM.ASM
*                       and is responsible for scheduling an HISR.
* Inputs
*   None
* Outputs
*   HISR Activated
*
*   This function, when called, simply schedules an HISR which is responsible
*   for calling real_fl_isr which in-turn sets an event.
*
*/
/* void    far real_lisr_fl_isr() */
void  real_lisr_fl_isr()
{
    /*  Activate the HISR to handle IDE interrupts.  */
    NU_Activate_HISR(&FL_HISR_Control);
}

/*  fl_init_HISR -  Provides Nucleus PLUS initialization for interrupt service
*                   routines used by the Floppy driver.
* Inputs
*   global definitions of FL_HISR_Control and FL_HISR_Stack
* Outputs
*   HISR created to handle Floppy interrupts
* Returns
*   Nothing
*
*   This routine is called to create the HISR (fl_real_isr) used by
*   the Floppy driver for processing floppy interrupts.
*/
VOID    fl_init_HISR()
{
    /*  Create the HISR for the ide_interrupt.  The parameters are the
	control structure (defined globally above, the ASCII string that
	represent the HISR's name, the function that will be activated from
	the HISR, a priority of 2 (the lowest), a pointer to the memory to
	be used for the HISR's stack, and the size of the stack (see definition
	of FL_HISR_Stack above).  */
    NU_Create_HISR(&FL_HISR_Control, "FL_HISR", real_fl_isr,
		   2, FL_HISR_Stack, 500);
}
#endif

/*  NUCLEUS fl_isr() is the pc specific vectored interupt routine
    that calls this routine */
void real_fl_isr()                              /*__fn__*/
{
/*    mex_signal_send(NUF_FLOPPY_EVENT); */
    /* Signal interupt complete */
#ifdef  PLUS
//	NU_Set_Events(&NUFP_RTX_To_PLUS_Events[NUF_FLOPPY_EVENT],
	NU_Set_Events(&NUFP_Events[NUF_FLOPPY_EVENT],
		      (UNSIGNED) ~0, NU_OR);
#else
	/* PC SPECIFIC Send and end of interrupt to the PIC */    
	NU_Set_Events(NUF_FLOPPY_EVENT, NU_EVENT_OR, (unsigned int) ~0);
#endif  /*  PLUS  */
}

#endif /* NOT POLLED */

/*
* Name:
*    fl_waitint() - Wait for a floppy interrupt. If one doesn't come. Fail.
*
* Summary:
*   fl_waitint(COUNT millis)
*
* Inputs:
*   millis - Number of miliseconds to wait for the interrupt to occur.
*
*  
* Returns:
*   YES if the interrupt occured, NO if it timed out
* 
* Description:
*   This function is called when the driver is waiting for an interrupt from the
*   controller. On entry the controller interrupt is masked off. This routine must
*   turn the interrupt on and then wait for the the interrupt service routine to
*   occur. 
*
* Porting considerations:
*
* In the reference port we enter a loop and wait for either the floppy interrupt
* to occur or for the tick count to occur. In a real time kernel you would 
* probably wait on a event channel with a timeout that will be signaled by
* the floppy interrupt service routine or time out
*
*/

static BOOL fl_waitint(COUNT millis)                                     /*__fn__*/
{
    BOOL ret_val;

#ifndef POLLED

#ifdef PLUS
    unsigned long current_events;
#else
    unsigned int current_events;
#endif

#endif /* NOT POLLED */

    /* Enable ints at the controller */
    fl_int_enable(YES);

    /* Wait for an interrupt or timeout */

#if (LOCK_METHOD == 2)
    /* Release the file system */
    fs_release();
#endif
/*    ret_val = mex_signal_test(NUF_FLOPPY_EVENT,millis); */
#ifdef  PLUS

#ifdef POLLED

    NU_Sleep(millis);    /*MAT Wait for command to finish */

#else /* POLLED */

//    if (NU_Retrieve_Events(&NUFP_RTX_To_PLUS_Events[NUF_FLOPPY_EVENT],
    if (NU_Retrieve_Events(&NUFP_Events[NUF_FLOPPY_EVENT],
			   (UNSIGNED) ~0, NU_OR_CONSUME, &current_events,
			   millis) != NU_SUCCESS)

#endif /* POLLED */

#else /* PLUS */

#ifdef POLLED

    NU_Sleep(millis);    /*MAT Wait for command to finish */

#else /* POLLED */

    if (NU_Wait_For_Events(NUF_FLOPPY_EVENT, NU_EVENT_OR_CONSUME,
			   (unsigned int) ~0, &current_events, millis)
			   != NU_SUCCESS)

#endif /* POLLED */

#endif  /* PLUS  */

#ifndef POLLED
	    ret_val = NO;
    else

#endif /* NOT POLLED */

	    ret_val = YES;   /* For Polled mode, always return YES */
#if (LOCK_METHOD == 2)
    /* reclaim */
    fs_reclaim();
#endif
    return( (BOOL) ret_val);
}

/*
* Name:
*    fl_report_error()                Report and clear an error
*
* Summary:
*    BOOL fl_report_error(COUNT error, BOOL return_me)
*
* Inputs:
*   error       - Error number
*   return_me   - This is returned
* Returns:
*   return_me
* 
* Description:
*   This routine reports and clears errors. The table of error strings and
*   the printing of the errors is optional. Clearing the error consists of
*   reseting the controller and clearing the known media type. When IO is 
*   is resumed the media type will be re-established. 
*  
* Porting considerations:
*
*/

TEXT * fl_errors[] = {
/* 0 */ "",
/* FLERR_ABN_TERM */            "Abnormal Termination Error",
/* FLERR_CHIP_HUNG */           "Floppy controller not responding",
/* FLERR_DMA */                 "Dma Error",
/* FLERR_FORMAT */              "Error during format",
/* FLERR_INVALID_INTERLEAVE */  "Invalid Interleave For Media Type",
/* FLERR_IO_SECTOR */           "Sector Not Found",
/* FLERR_IO_TMO */              "Time out",
/* FLERR_MEDIA */               "Can't determine Media",
/* FLERR_RECAL */               "Error During Recal",
/* FLERR_RESET */               "Error resetting drive",
/* FLERR_SEEK */                "Error during seek",
/* FLERR_SPECIFY */             "Error during specify",
/* FLERR_UNK_DRIVE */           "Unknown Drive type"
};

static BOOL fl_report_error(COUNT error, BOOL return_me)      /*__fn__*/
{
    switch(error)
    {
    case FLERR_ABN_TERM:
    case FLERR_CHIP_HUNG:
    case FLERR_DMA:
    case FLERR_FORMAT:
    case FLERR_IO_SECTOR:
    case FLERR_IO_TMO:
    case FLERR_MEDIA:
    case FLERR_RECAL:
    case FLERR_SEEK:
    case FLERR_SPECIFY:
//		floppy[0].media_type = (UTINY) DT_NONE;
//		floppy[1].media_type = (UTINY) DT_NONE;
//		fl_reset_controller();
		Stop_gTimer();
		fl_controller_init();
		/* printf("%s\n",fl_errors[error]); */
#ifdef DEBUG  //Daniel
		puts((const char *)fl_errors[error]);
#endif  //Daniel
		break;
    case FLERR_RESET:
    case FLERR_INVALID_INTERLEAVE:
    case FLERR_UNK_DRIVE:
    case FLERR_EXEC_EST:
		/* printf("%s\n",fl_errors[error]); */
#ifdef DEBUG  //Daniel
		puts((const char *)fl_errors[error]);
#endif  //Daniel
		break;
    default:
		/* printf("Unknown Floppy Error\n"); */
#ifdef DEBUG  //Daniel
		puts("Unknown Floppy Error\n");
#endif  //Daniel
		break;
    }
    return(return_me);
}


/*
* Name:
*    fl_waitdma() - Wait for a dma transfer to complete
*
* Summary:
*   fl_waitdma(COUNT millis)
*
* Inputs:
*   millis - Fail if more than milli milliseconds elapses
*
*  
* Returns:
*   YES if the dma transfer was sucessful.
* 
* Description:
*   This function is called when the driver is waiting for a dma transfer to
*   complete. The transfer was set up by fl_dma_setup().
*
*   This routine calls pc_wait_int(millis) for the floppy to interrupt 
*   and then verifies that the dma channel has reach terminal count.
*   need to do is wait for the floppy interrupt. We seperated the two 
*
*   Note: In a system using programmed transfer the transfer loop 
*   would go inside here. The addresses and could would come from 
*   fl_dma_init().
*
*/

/* DMA registers */
#define STATUS_REGISTER     0x08
#define MASK_REGISTER       0x0a
#define MODE_REGISTER       0x0b
#define FLIPFLOP_REGISTER   0x0c
#define BANK_REGISTER       0x81

/* Channel 2 register bank */
#define ADDRESS_REGISTER    0x04
#define COUNT_REGISTER       0x05

static BOOL fl_waitdma(COUNT millis)                                     /*__fn__*/
{

#ifdef POLLED
UTINY main_status_register;
COUNT i ;
COUNT ready;
int timeout = 0xFFFE;//32000;

#else /* POLLED */

UTINY status;

#endif /* POLLED */

#ifdef POLLED

    ready = 0;    /* Initializing "ready" */

	ready = fl_ready();
    if (polled_reading)
    {
        for (i = 0; i < polled_length; i++)
        {
	        if (ready != FL_TOHOST)
	        {
	            return(NO);
	        }
   	        polled_buffer[i] = fl_read_data();
   	        delay_1us();	//wait the msr.bit7 to be ready, Lxd on 2002-2-8
	        ready = fl_ready();
/*		    while (YES)
			{
				if (!timeout--)
				{ 
					ready = 0;
					return NO;//break; 如果不返回,写磁盘时将磁盘抽走会死机!
				}
				main_status_register = fl_read_msr();
				if (main_status_register & BIT7)
					break;
				delay_25us();
			}

			if (main_status_register & BIT6)
				ready = FL_TOHOST; 
			else
				ready = FL_FRHOST;
*/
        }
    }
    else
    {
        for (i = 0; i < polled_length; i++)
        {
	        if (ready != FL_FRHOST)
	        {
	            return(NO);
	        }
	        fl_write_data(polled_buffer[i]);
   	        delay_1us();	//wait the msr.bit7 to be ready, Lxd on 2002-2-8
	        ready = fl_ready();
/*		    while (YES)
			{
				if (!timeout--)
				{ 
					ready = 0;
					return NO;//break; 如果不返回,写磁盘时将磁盘抽走会死机!
				}
				main_status_register = fl_read_msr();
				if (main_status_register & BIT7)
					break;
				delay_25us();
			}

			if (main_status_register & BIT6)
				ready = FL_TOHOST; 
			else
				ready = FL_FRHOST;
*/
        }
    }

    fl_waitint(millis);

    return(YES);

#else /* POLLED */

    if (fl_waitint(millis))
    {
	    /*      Check terminal count flag  */
	    status = (UTINY) fl_inp(STATUS_REGISTER);
    	if (status & BIT2)
	        return(YES);
    	else 
	        return(NO);
    }
    return(NO);

#endif /* POLLED */

}

/*
* Name:
*    fl_dma_init() - Initialize a dma transfer
*
* Summary:
*    BOOL fl_dma_init(UTINY *in_address, UCOUNT length, BOOL reading)
*
* Inputs:
*   in_address - Address to transfer data to/from
*   length     - Length in bytes to transfer
*   reading    - If yes, floppy to memory, else mem to floppy
* Returns:
*   YES if the setup was successful. NO on a boundary wrap.
* 
* Description:
*   This function is called to set up a dma transfer.

⌨️ 快捷键说明

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