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

📄 lowl.c

📁 NUcleus plus 支持的文件系统。 是学习文件系统的很好参考资料。
💻 C
📖 第 1 页 / 共 5 页
字号:
            cluster = nextcluster;
            ret_stat = pc_clnext(&nextcluster, pdr, nextcluster);
        }
    }

    return(ret_stat);
}


/************************************************************************
* FUNCTION                                                              
*                                                                       
*       pc_get_chain                                                    
*                                                                       
* DESCRIPTION                                                           
*                                                                       
*       Starting at start_cluster return the number of contiguous       
*       clusters allocated in the chain containing start_cluster or     
*       n_clusters, whichever is less.                                  
*                                                                       
* AUTHOR                                                                
*                                                                       
*       Takahiro Takahashi
*                                                                       
* INPUTS                                                                
*                                                                       
*       *pdr                                Drive information           
*       start cluster                       Start of the serch cluster  
*       *pnext_cluster                      Next cluster number         
*       n_clusters                          Number of the cluster that  
*                                            is needed.                 
*                                                                       
* OUTPUTS                                                               
*                                                                       
*       on an error. This function should always return at least one.   
*       (start_cluster). Unless an error occurs.                        
*                                                                       
*       NUF_IO_ERROR                        Driver IO error.            
*       NUF_INTERNAL                        Nucleus FILE internal error.
*                                                                       
*************************************************************************/
INT32 pc_get_chain(DDRIVE *pdr, UINT32 start_cluster, UINT32 *pnext_cluster,
                   UINT32 n_clusters)
{
STATUS      ret_stat;
UINT32      clno;
UINT32      n_contig;
UINT32      value;
INT16       nibs_per_entry;


    if (start_cluster < 2L)
        return(NUF_INTERNAL);
    if (start_cluster > pdr->maxfindex)
        return(NUF_INTERNAL);

    nibs_per_entry = pdr->fasize;

    clno = start_cluster;
    n_contig = 1L;
    *pnext_cluster = 0L;

    /* Get each FAT entry. If its value points to the next contiguous entry
       continue. Otherwise we have reached the end of the contiguous chain.
       At which point we return the number of contig's found and by reference
       the address of the FAT entry beginning the next chain segment.
    */
    while (1)
    {
        ret_stat = pc_faxx(pdr, clno, &value);
        if (ret_stat != NU_SUCCESS)
           return(ret_stat);

            /* check for a bad cluster and skip it if we see it */
        if ( (value == 0xff7 && nibs_per_entry == 3)
             || (value == 0xfff7 && nibs_per_entry == 4)
             || (value == 0x0ffffff7) )
        {
            clno += 1L;
        }
            /* check for end markers set next cluster to the last 
               cluster in the chain if we are at the end */
        else if ( (value > 0xff7 && nibs_per_entry == 3)
             || (value > 0xfff7 && nibs_per_entry == 4)
             || (value > 0x0ffffff7) )
        {
            value = clno;
            break;
        }
        else if (value == ++clno)
        {
            if (n_contig >= n_clusters)
               break;
            n_contig++;
        }
        else
            break;
   }
   *pnext_cluster = value;
   return(n_contig);
}


/************************************************************************
* FUNCTION                                                              
*                                                                       
*       pc_pfaxx                                                        
*                                                                       
* DESCRIPTION                                                           
*                                                                       
*       Given a DDRIVE,cluster number and value. Write the value in the 
*       fat at clusterno. Handle 32, 16 and 12 bit fats correctly.      
*                                                                       
* AUTHOR                                                                
*                                                                       
*       Takahiro Takahashi
*                                                                       
* INPUTS                                                                
*                                                                       
*       *pdr                                Drive information.          
*       clno                                Cluster number to get FAT   
*                                            entry value.               
*       pvalue                              FAT entry value.            
*                                                                       
* OUTPUTS                                                               
*                                                                       
*       If any error occured while FAT swapping return negative value   
*       else return NU_SUCCESS                                          
*                                                                       
*       NU_SUCCESS                          If service is successful.   
*       NUF_NO_MEMORY                       Can't allocate FAT cache    
*                                            buffer. (FAT12 only )      
*       NUF_IO_ERROR                        Driver IO error.            
*       NUF_INTERNAL                        Nucleus FILE internal error.
*                                                                       
*************************************************************************/
STATUS pc_pfaxx(DDRIVE *pdr, UINT32 clno, UINT32 value)
{
STATUS      ret_stat = NU_SUCCESS;
UINT16      wtry;
UINT32      ltry;
UINT8       wrdbuf[4];          /* Temp storage area */
UINT8 FAR   *fat_data = pdr->fat_swap_structure.data_array;
UINT32 FAR  *ppage;
UINT32      offset;
INT16       driveno;
UINT16      wvalue;


    pdr->fat_is_dirty = YES;
    driveno = pdr->driveno;
    /* ======================== FAT12 ======================== */
    if (pdr->fasize == 3)       /* 3 nibble ? */
    {
        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 read all FAT %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)
            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)
        }

        value &= 0x0fff;        /* 3 nibble clusters */
        wtry = (UINT16) (clno + (UINT16) (clno >> 1)); /* multiply by 1.5 */
        if ( (UINT16)((clno << 1) + clno) == (wtry << 1) )  /* If whole number */
        {
            fat_data[wtry] = (UINT8)((UINT8)value & 0xff); /* Low Byte to NIBBLE 1 & 2 */
            fat_data[wtry+1] &= 0xf0; /* clr low NIBBLE of next byte */
            /* Put the high nibble of value in the low nibble ofnext byte */
            fat_data[wtry+1] |= ( ((UINT8)(value >> 8)) & 0x0f );
        }
        else
        {
            fat_data[wtry+1]= (UINT8)((UINT8)(value >> 4) & 0xff); /* high to NIB 2 & 3*/
            fat_data[wtry] &= 0x0f; /* clr high NIBBLE of byte */
            /* Put the low nibble of value in the high nibble of byte */
            fat_data[wtry] |= ( ((UINT8)(value & 0xf) << 4) & 0xf0 );
        }
        /* Now mark the dirty flags block == index/512 */
        /* Note try >> 9 and try+1 >> 9 are usually the same */
        /* NOTE: data_map is a byte map of dirty fat blocks */
        pdr->fat_swap_structure.data_map[(wtry >> 9)]  = (UINT8) 1;
        pdr->fat_swap_structure.data_map[(wtry+1) >> 9] = (UINT8) 1;
    }


    /* ======================== FAT16 ======================== */
    else if (pdr->fasize == 4)
    {
        value &= 0xffff;        /* 4 nibble clusters */

        /* Use temp buffer since fat_data is far , can't call fr word with
          it directly in intel small model */
        wvalue = value;
        SWAP16((UINT16 *)&wrdbuf[0],&wvalue);

        if (!pdr->use_fatbuf)
        {
        /* Using the in-memory FAT Buffers */
           /* 16 BIT entries */
            /* Byte offset in fat ==s cluster number * 2 */
            ltry = (UINT32) clno;
            ltry <<= 1;

            fat_data[ltry] = wrdbuf[0];
            fat_data[ltry+1] = wrdbuf[1];
            /* Now mark the dirty flags block == index/512 */
            /* NOTE: data_map is a byte map of dirty fat blocks */
            pdr->fat_swap_structure.data_map[(ltry >> 9)]  = (UINT8) 1;
        }
        else
        {   /* fat swapping. Always 16 or 32 bit entries */

            /* Now put the values back into the FAT */
            ret_stat = pc_pfpword(pdr, (UINT16)clno, (UINT16 *) &wrdbuf[0]);
            if (ret_stat != NU_SUCCESS)
            {
                return(ret_stat);
            }
        }
    }


    /* ======================== FAT32 ======================== */
    else if (pdr->fasize == 8)
    {   /* 32 BIT entries */
        value &= 0x0fffffff;        /* 7 nibble clusters */

        SWAP32((UINT32 *)&wrdbuf[0],&value);

        if (!pdr->use_fatbuf)
        {
        /* Using the in-memory FAT Buffers */

            /* Byte offset in fat ==s cluster number * 4 */
            ltry = (UINT32) clno;
            ltry <<= 2;

            /* Use temp buffer since fat_data is far , can't call fr word with
               it directly in intel small model */
            fat_data[ltry] = wrdbuf[0];
            fat_data[ltry+1] = wrdbuf[1];
            fat_data[ltry+2] = wrdbuf[2];
            fat_data[ltry+3] = wrdbuf[3];
            /* Now mark the dirty flags block == index/512 */
            /* NOTE: data_map is a byte map of dirty fat blocks */
            pdr->fat_swap_structure.data_map[(ltry >> 9)]  = (UINT8) 1;
        }
        else 
        {   /* fat swapping. Always 16 or 32 bit entries */


            /* Make sure we have access to the page. Mark it for writing */
             ret_stat = pc_pfswap((UINT8 FAR **)&ppage, pdr, clno, YES);
            if (ret_stat != NU_SUCCESS)
            {
#ifdef DEBUG
                DEBUG_PRINT("pc_pfswap returned error %d  %s \r\n", __LINE__, __FILE__);
#endif
                return(ret_stat);
            }

⌨️ 快捷键说明

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