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

📄 lowl.c

📁 NUcleus plus 支持的文件系统。 是学习文件系统的很好参考资料。
💻 C
📖 第 1 页 / 共 5 页
字号:

    driveno= pdr->driveno;
    /* ======================== FAT12 ======================== */
    if (pdr->fasize == 3)       /* 3 nibble ? */
    {

        /* We do not read FAT to FAT cache yet. */
        if ( (fat_data == NULL) || ((fat_data[0] & (UINT8)0xF0) != (UINT8)0xF0) )
        {
            if (fat_data == NULL)
            {
                pdr->fat_swap_structure.data_array =
                                (UINT8 FAR *)NUF_Alloc(NUF_Drive_Fat_Size[driveno] << 9 );
#ifdef DEBUG
     DEBUG_PRINT("pc_faxx 12bit FAT fat_data == NULL %d  %s \r\n", __LINE__, __FILE__);
#endif
                if (pdr->fat_swap_structure.data_array == NULL )
                {
#ifdef DEBUG
     DEBUG_PRINT("pc_faxx 12bit FAT can't allocate FAT cache buffer %d  %s \r\n", __LINE__, __FILE__);
#endif
                    return(NUF_NO_MEMORY);
                }
            }
#ifdef DEBUG
            else 
     DEBUG_PRINT("pc_faxx 12bit FAT fat_data[0] != 0xF9 %d  %s \r\n", __LINE__, __FILE__);
#endif
            PC_DRIVE_IO_ENTER(driveno)
            /* Read FAT sectors */
            if ( !pc_bdevsw[driveno].io_proc(driveno, (UINT32)pdr->fatblock,
                                pdr->fat_swap_structure.data_array, (UINT16) pdr->secpfat, YES))
            {
                PC_DRIVE_IO_EXIT(driveno)
                pc_report_error(PCERR_FATREAD);
                NU_Deallocate_Memory((VOID *)pdr->fat_swap_structure.data_array);
                return(NUF_IO_ERROR);
            }
            PC_DRIVE_IO_EXIT(driveno)
        }

        wtry = (UINT16) (clno + (UINT16) (clno >> 1));    /* multiply by 1.5 */
           /* And use the product as index */
        wrdbuf[0] = fat_data[wtry];     /* Use a temp variable since in */
        wrdbuf[1] = fat_data[wtry+1];   /* small model we can't call with
                                           fat_data (it's a far pointer) */

        SWAP16((UINT16 *)&wvalue, (UINT16 *)wrdbuf);
        *pvalue = (UINT32) wvalue;   /* And use the product as index */

        if ( (UINT16)((clno << 1) + clno) == (wtry << 1) )  /* If whole number */
            *pvalue &= 0xfff;            /* Return it */
        else
            *pvalue =(UINT32) ((UINT16) (*pvalue >> 4) & 0xfff ); /* shift right 4 */
    }


    /* ======================== FAT16 ======================== */
    else if (pdr->fasize == 4)
    {
        /* 16 BIT fat. ret the value at 2 * clno */
        /* Some FAT data is cached */
        if (pdr->use_fatbuf)
        {
            ret_stat = pc_pfgword(pdr, (UINT16)clno, (UINT16 *) &wrdbuf[0]);
            if (ret_stat != NU_SUCCESS)
            {
#ifdef DEBUG
                DEBUG_PRINT("pc_pfgword returned error %d  %s \r\n", __LINE__, __FILE__);
#endif
                return(ret_stat);
            }
        }
        /* All FAT data is cached */
        else
        {
            ltry = (UINT32) clno;
            ltry <<= 1;
            wrdbuf[0] = fat_data[ltry];     /* Use a temp variable since in */
            wrdbuf[1] = fat_data[ltry+1];   /* intel small model we can't call
                                               with  fat_data (it's a far pointer) */
        }
        SWAP16(&wvalue, (UINT16 *)wrdbuf);
        *pvalue = wvalue;
    }


    /* ======================== FAT32 ======================== */
    else if (pdr->fasize == 8)
    {

        /* Some FAT data is cached */
        if (pdr->use_fatbuf)
        {
            /* Make sure we have access to the page. Don't Mark it for writing */
            ret_stat = pc_pfswap(&ppage, pdr, clno, NO);
            if (ret_stat != NU_SUCCESS)
            {
#ifdef DEBUG
                DEBUG_PRINT("pc_pfswap returned error %d  %s \r\n", __LINE__, __FILE__);
#endif
                return(ret_stat);
            }
            else
            {
                /* there are 128 entries per page */
                offset = (UINT32) (clno & 0x7f);
                *((UINT32 *)wrdbuf) = *((UINT32 *)ppage + offset);
            }
        }
        /* All FAT data is cached */
        else
        {
            /* 32-bit FAT */
            ltry = (UINT32) clno;
            ltry <<= 2;
            wrdbuf[0] = fat_data[ltry];     /* Use a temp variable since in */
            wrdbuf[1] = fat_data[ltry+1];   /* intel small model we can't call */
            wrdbuf[2] = fat_data[ltry+2];   /*   with  fat_data (it's a far pointer) */
            wrdbuf[3] = fat_data[ltry+3];
        }
        SWAP32(pvalue,(UINT32 *)&wrdbuf[0]);   /* And use the product as index */
    }
    else
    {
#ifdef DEBUG
        DEBUG_PRINT("pdr->fasize error %d  %s \r\n", __LINE__, __FILE__);
#endif
        return(NUF_INTERNAL);
    }
    return(NU_SUCCESS);
}


/************************************************************************
* FUNCTION                                                              
*                                                                       
*       pc_flushfat                                                     
*                                                                       
* DESCRIPTION                                                           
*                                                                       
*       Given a valid drive number. Write any fat blocks to disk that   
*       have been modified. Updates all copies of the fat.              
*                                                                       
* AUTHOR                                                                
*                                                                       
*       Takahiro Takahashi
*                                                                       
* INPUTS                                                                
*                                                                       
*       *pdr                                Drive management structure  
*                                                                       
* OUTPUTS                                                               
*                                                                       
*       NU_SUCCESS                          FAT flush success.          
*       NU_IO_ERROR                         Write failed.               
*       NU_INTERNAL                         FAT cache is NULL           
*                                                                       
*************************************************************************/
STATUS pc_flushfat(DDRIVE *pdr)
{
FATSWAP     *pfs;
UINT8 FAR   *pf;
UINT16      *pd;
UINT32      i;
UINT32      imax;
UINT16      j;
UINT32      baseblock;
INT         is_last;
STATUS      ret_stat;


    /* The FAT has no dirty block which heed to be write. */
    if (!pdr->fat_is_dirty)
        return(NU_SUCCESS);

    
	/* Whether we uses the FAT cache as buffer ? */
    if (pdr->use_fatbuf)
    {
        /* Flush FAT */
        ret_stat = pc_pfflush(pdr);
        if (ret_stat == NU_SUCCESS)
        {
            /* FAT flush successful compleate */
            pdr->fat_is_dirty = NO;
        }

        /* status retuern. */
        return(ret_stat);
    }

    /* else ... */
    PC_DRIVE_IO_ENTER(pdr->driveno)
    /* Move the number of FAT to local */
    imax = (UINT32) pdr->secpfat;

    for (j = 0; j < pdr->numfats; j++)
    {
        /* Work out start block number of FAT */
        baseblock = (UINT32) j;
        baseblock *= imax;
        baseblock += pdr->fatblock;

        /* Is this FAT last ? */
        if ( j == (UINT16) (pdr->numfats - 1) )
            is_last = YES;
        else
            is_last = NO;

        /* NOTE: data_array is the fat data. data_map is a 2 bytes map of dirty
           fat blocks                                                       */
        pf = pdr->fat_swap_structure.data_array;
        pd = pdr->fat_swap_structure.data_map;
        pfs = &pdr->fat_swap_structure;
        if (!pf)
        {
            PC_DRIVE_IO_EXIT(pdr->driveno)
            pc_report_error(PCERR_FAT_NULLP);

            return(NUF_INTERNAL);
        }

        /* Check each block in the fat */
        for (i = 0; i < imax; i++,pd++,baseblock++)
        {
            /* If the block is dirty */
            if ( (*pd) || ((i == 0) && (pfs->block_0_is_valid)) )
            {
                /* Write it */
                if ( !pc_bdevsw[pdr->driveno].io_proc(pdr->driveno, baseblock+pfs->base_block, pf, (UINT16) 1, NO) )
                {
                    PC_DRIVE_IO_EXIT(pdr->driveno)
                    pc_report_error(PCERR_FAT_FLUSH);

                    return(NUF_IO_ERROR);
                }
                if (is_last)
                    *pd = (UINT8) 0;
            }
            pf += 512;
        }
    }
    pdr->fat_is_dirty = NO;
    PC_DRIVE_IO_EXIT(pdr->driveno)

    return(NU_SUCCESS);
}


/************************************************************************
* FUNCTION                                                              
*                                                                       
*       pc_freechain                                                    
*                                                                       
* DESCRIPTION                                                           
*                                                                       
*       Trace the cluster chain starting at cluster and return all the  
*       clusters to the free state for re-use. The FAT is not flushed.  
*                                                                       
* AUTHOR                                                                
*                                                                       
*       Takahiro Takahashi
*                                                                       
* INPUTS                                                                
*                                                                       
*       *pdr                                Drive information           
*       cluster                             Free start cluser number    
*                                                                       
* OUTPUTS                                                               
*                                                                       
*       NU_SUCCESS                          If service is successful.   
*       NUF_IO_ERROR                        Driver IO error.            
*       NUF_INTERNAL                        Nucleus FILE internal error.
*                                                                       
*************************************************************************/
STATUS pc_freechain(DDRIVE *pdr, UINT32 cluster)
{
STATUS      ret_stat;
UINT32      nextcluster;


    ret_stat = pc_clnext(&nextcluster, pdr, cluster);
    while ( (cluster) && (ret_stat == NU_SUCCESS) )
    {
        ret_stat = pc_clrelease(pdr, cluster);
        if (ret_stat == NU_SUCCESS)
        {

⌨️ 快捷键说明

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