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

📄 lowl.c

📁 ertfs文件系统里面既有完整ucos程序
💻 C
📖 第 1 页 / 共 5 页
字号:
****************************************************************************/
/* Note: The caller locks the fat before calling this routine   */
CLUSTERTYPE pc_get_chain(DDRIVE *pdr, CLUSTERTYPE start_cluster, CLUSTERTYPE *pnext_cluster, CLUSTERTYPE n_clusters) /*__fn__*/
{
    CLUSTERTYPE clno;
    CLUSTERTYPE n_contig;
    CLUSTERTYPE value;
    BOOLEAN   nibs_3;
    BOOLEAN   nibs_4;
#if (FAT32)
    BOOLEAN   nibs_8;
#endif
    dword _Oxffffff7ul;



    if ( (start_cluster < 2) || (start_cluster > pdr->maxfindex))
        return (0);
    nibs_3 = nibs_4 = FALSE;
#if (FAT32)
    nibs_8 = FALSE;
#endif
    if (pdr->fasize == 3)
        nibs_3 = TRUE;
    else if (pdr->fasize == 4)
        nibs_4 = TRUE;
#if (FAT32)
    else if (pdr->fasize == 8)
        nibs_8 = TRUE;
#endif
    else
        return(0);


    clno = start_cluster;
    n_contig = 1;
    *pnext_cluster = 0;     
 
    /* 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(TRUE)
    {       
        if (!pc_faxx(pdr, clno, &value))
            return(0);
            /* check for a bad cluster and skip it if we see it   */
        _Oxffffff7ul =  0xffffff7ul;
        if ( ( value == 0xff7 && nibs_3)
            || (value == 0xfff7 && nibs_4)
#if (FAT32)
                 || (value == _Oxffffff7ul && nibs_8)
#endif
        )
        {
            clno = (CLUSTERTYPE)(clno + 1);
        }
            /* 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_3)
            || (value > 0xfff7 && nibs_4) 
#if (FAT32)
             || (value >= _Oxffffff7ul && nibs_8)
#endif               
             )
        {
            value = clno;
            break;
        }
        else if (value == ++clno)
        {
            if (n_contig >= n_clusters)
                break;
            n_contig++;
        }
        else
            break;
    }
    *pnext_cluster = value;
    return (n_contig);
}

RTFS_FILE(pfaxxtrm.c, pc_pfaxxterm)

#ifndef __PCDISK__  /* This allows us to build the lib with subroutines split */
#include <pcdisk.h>
#endif
#if RTFS_WRITE

/******************************************************************************
    PC_PFAXXTERM - Write a terminating value to the FAT at clno.
  
 Description
    Given a DDRIVE,cluster number and value. Write the value 0xffffffff or 
    0xffff in the fat at clusterno. Handle 32, 16 and 12 bit fats correctly.

 Returns
    FALSE if an io error occurred during fat swapping, else TRUE

*****************************************************************************/
 
/* Given a clno & fatval Put the value in the table at the index (clno)    */
/* Note: The caller locks the fat before calling this routine              */
BOOLEAN pc_pfaxxterm(DDRIVE   *pdr, CLUSTERTYPE  clno)             /*__fn__*/
{
#if (FAT32)
            if (pdr->fasize == 8)
                return(pc_pfaxx(pdr, clno, 0x0ffffffful));
            else
#endif
                return(pc_pfaxx(pdr, clno, 0xffff));
            
}
#endif

RTFS_FILE(pfaxx.c, pc_pfaxx)

#ifndef __PCDISK__  /* This allows us to build the lib with subroutines split */
#include <pcdisk.h>
#endif
#if (RTFS_WRITE)
 
/******************************************************************************
    PC_PFAXX - Write a value to the FAT at clno.
  
 Description
    Given a DDRIVE,cluster number and value. Write the value in the fat
    at clusterno. Handle 16 and 12 bit fats correctly.

 Returns
    No if an io error occurred during fat swapping, else TRUE.

*****************************************************************************/
 
/* Given a clno & fatval Put the value in the table at the index (clno)    */
/* Note: The caller locks the fat before calling this routine              */
BOOLEAN pc_pfaxx(DDRIVE *pdr, CLUSTERTYPE  clno, CLUSTERTYPE  value)            /*__fn__*/
{
    union align1 {
        byte    wrdbuf[4];          /* Temp storage area */
        word  fill[2];
    } u;
    CLUSTERTYPE nibble,index,offset, t;
    
    pdr->fat_is_dirty = TRUE;
    if (pdr->fasize == 3)       /* 3 nibble ? */
    {
        nibble = (CLUSTERTYPE)(clno * 3);
        index  = (CLUSTERTYPE)(nibble >> 2);
        offset = (CLUSTERTYPE)(clno & 0x03);
        /* Read the first word   */
        if (!pc_fword( pdr, index, (word *) &u.wrdbuf[0], FALSE ))
            return(FALSE);
/*
        |   W0      |   W1      |   W2  |
        A1 A0 B0 A2 B2 B1 C1 C0 D0 C2 D2 D1
        xx xx   xx
*/
        if (offset == 0) /* (A2 << 8) | A1 A2 */
        {
            /* Low nibble of b[1] is hi nibble of value   */
            u.wrdbuf[1] &= 0xf0;
            t = (CLUSTERTYPE)((value >> 8) & 0x0f);
            u.wrdbuf[1] |= (byte) t;
            /* b[0] is lo byte of value   */
            t = (CLUSTERTYPE)(value & 0x00ff);
            u.wrdbuf[0] = (byte) t;
            if (!pc_fword( pdr, index, (word *) &u.wrdbuf[0], TRUE ))
                return (FALSE);
        }
/*
        |   W0      |   W1      |   W2  |
        A1 A0 B0 A2 B2 B1 C1 C0 D0 C2 D2 D1
                xx  xx xx 
*/
    
        else if (offset == 1) /* (B1 B2 << 4) | B0 */
        {
            /* Hi nibble of b[1] is lo nibble of value   */
            u.wrdbuf[1] &= 0x0f;
            t = (CLUSTERTYPE)((value << 4) & 0x00f0);
            u.wrdbuf[1] |= (byte)t;
            if (!pc_fword( pdr, index, (word *) &u.wrdbuf[0], TRUE ))
                return (FALSE);
            /*  b[0] is hi byte of value   */
            if (!pc_fword( pdr, (word)(index+1), (word *) &u.wrdbuf[0], FALSE ))
                return(FALSE);
            t = (CLUSTERTYPE)((value >> 4) & 0x00ff);
            u.wrdbuf[0] = (byte) t;
            if (!pc_fword( pdr, (word)(index+1), (word *) &u.wrdbuf[0], TRUE ))
                return (FALSE);
        }
/*
        |   W0      |   W1  |   W2  |
        A1 A0 B0 A2 B2 B1 C1 C0 D0 C2 D2 D1
                            xx xx   xx 
*/
    
        else if (offset == 2) /*(C2 << 8) | C1 C2 */
        {
            /* b[1] = low byte of value   */
            t = (CLUSTERTYPE)(value & 0x00ff);
            u.wrdbuf[1] = (byte) t;
            if (!pc_fword( pdr, index, (word *) &u.wrdbuf[0], TRUE ))
                return (FALSE);
            /* lo nibble of b[0] == hi nibble of value   */
            if (!pc_fword( pdr, (word)(index+1), (word *) &u.wrdbuf[0], FALSE ))
                return(FALSE);
            u.wrdbuf[0] &= 0xf0;
            t = (CLUSTERTYPE)((value >> 8) & 0x0f);
            u.wrdbuf[0] |= (byte) t;
            if (!pc_fword( pdr, (word)(index+1), (word *) &u.wrdbuf[0], TRUE ))
                return (FALSE);
        }
/*
        |   W0      |   W1  |   W2  |
        A1 A0 B0 A2 B2 B1 C1 C0 D0 C2 D2 D1
                                xx  xx xx
*/
    
        else if (offset == 3) /* (D2 D1) << 4 | D0 */   
        {
            /* Hi nibble b[0] == low nible of value    */
            u.wrdbuf[0] &= 0x0f;
            t = (CLUSTERTYPE)((value << 4) & 0x00f0);
            u.wrdbuf[0] |= (byte) t;
            t = (CLUSTERTYPE)((value >> 4) & 0x00ff);
            u.wrdbuf[1] = (byte) t;
            if (!pc_fword( pdr, index, (word *) &u.wrdbuf[0], TRUE ))
                return (FALSE);
        }
    }
#if (FAT32) /* FAT32 only supported if FAT swapping is enabled */
    else if (pdr->fasize == 8)
    {
        fr_DWORD(&u.wrdbuf[0],value);          /*X*/
     /* Now put the values back into the FAT   */
        if (!pc_pfpdword( pdr, clno, (dword *) &u.wrdbuf[0] ))
        {
            return (FALSE);
        }
    }
#endif /* FAT32 */
    else        /* 16 BIT entries */
    {
        fr_WORD((byte *) &u.wrdbuf[0],(word)value);         /*X*/
        /* Now put the values back into the FAT   */
        if (!pc_fword( pdr, clno, (word *) &u.wrdbuf[0], TRUE ))
        {
            return (FALSE);
        }
    }
    return (TRUE);
}

#endif

RTFS_FILE(fatsw.c, pc_fatsw)

#ifndef __PCDISK__  /* This allows us to build the lib with subroutines split */
#include <pcdisk.h>
#endif

/***************************************************************************
    PC_FATSW - FAT Access code when fat buffering is enabled.
Summary

    Free all core associated with the drive's fat
        void pc_pfclose( DDRIVE *pdr);

    Flush the current page (if needed. And read in a new page such that
    "index" is contained therein. (Called by pc_pfpbyte() and pc_pfgbyte())
        BOOLEAN pc_pfswap( DDRIVE *pdr, word index);

    Put a byte (value) into the FAT at index. Return TRUE if everything worked. 
    Note: FAT page swaps will occur if they are needed. Called by pc_pfaxx().
        BOOLEAN pc_pfpbyte( DDRIVE *pdr, int index, word *pvalue);

    Get a byte from the FAT at index and put the value at *value. Return TRUE if
    everything worked.
    Note: FAT page swaps will occur if they are needed. Called by pc_faxx().
        BOOLEAN pc_pfgbyte( DDRIVE *pdr, int index, word *value);

    Flush any dirty blocks from the current FAT page. Called by pc_flushfat()
        BOOLEAN pc_pfflush( DDRIVE *pdr);

Description
    Provide a cacheing mechanism for the file allocation table. We have a 
    byte map table indicating the offset in our data cache for each block
    in the FAT. If the value at dat_map[block] is zero the block is not 
    cached. We also maintain a bitmap of each block in the FAT. If the 
    bit is set the corresponding block must be flushed.

Returns

Example
****************************************************************************/

    
/* Flush buffers and then swap in the page containing index                   */
/* Note: This routine must be called first with index == 0. see pc_dskinit    */
/* Note: The caller locks the fat before calling this routine                 */
PFBYTE pc_pfswap(DDRIVE *pdr, CLUSTERTYPE index, BOOLEAN for_write)         /*__fn__*/
{
    FATSWAP *pfs = &pdr->fat_swap_structure;
    BLOCKT newblock;
    CLUSTERTYPE block_offset_in_fat;
    CLUSTERTYPE i;
    PFBYTE pdata;
    byte uc;
    CLUSTERTYPE  byte_offset;           /*FAT32*/
    CLUSTERTYPE  bit_offset;            /*FAT32*/
    CLUSTERTYPE  data_block_to_use;     /*FAT32*/
#if (FAT32)
    dword *datamp;
    dword  block_tag;
    word fat_cache_index;
#endif
    dword ltemp;
    
    /* Convert the index (in words) to block values 
        divide by 256 since there are 256 FAT entries per block */
#if (FAT32)
    if (pdr->fasize == 8)
    {
        block_offset_in_fat = (dword)(index >> 7);
        fat_cache_index = (word)(block_offset_in_fat % pfs->n_blocks_total);
        block_tag = (dword)(block_offset_in_fat / pfs->n_blocks_total); 
        block_tag |= 0x80000000ul;
        datamp = (dword*) pfs->data_map;
    }
    else
#endif
    block_offset_in_fat = (word) (index >> 8);

    if (block_offset_in_fat >= pdr->secpfat) /* Check range */
        return (0);

    /* check if the block is already mapped. 
            Notice we use block_0_is_valid as a flag denoting whether
            the first block in the fat is buffered. We did this because
            we want to use:
                data_map[block_offset_in_fat] == 0;
            Where data_map[] indicates the offset into our cache memory
            (in blocks) of the the cached buffer.  
            To indicate that the disk block is not cached. Since offset 0
            is a valid number we chose to preload the first disk block in the
            fat to location 0 in our buffer cache. After this has occured we
            set block_0_is_valid. Yuk, but effective.. 
    */
#if (FAT32)
    if (pdr->fasize == 8)
    {
        ltemp = (dword) fat_cache_index;
#if (FAT_BUFFER_SIZE > 63) /* Ugly conditional until sure */
        pdata = pfs->data_array + (ltemp << 9); 
#else
        pdata = pfs->data_array + (word)(ltemp << 9);
#endif
        if (datamp[fat_cache_index] != block_tag)
        {
#if RTFS_WRITE
            if (!pc_pfflush(pdr))
                return(0);
#endif
            /* READ   */
            datamp[fat_cache_index] = block_tag;
            newblock = pdr->fatblock + block_offset_in_fat;
            if (!devio_read(pdr->driveno,newblock,pdata,1, FALSE))
            {
                datamp[fat_cache_index] = 0;
                return(0);
            }
        }
        block_offset_in_fat = fat_cache_index;
    }
    else
#endif /* FAT32 */
    if ( ((block_offset_in_fat == 0) && pfs->block_0_is_valid) || 
        (pfs->data_map[(int)block_offset_in_fat] != 0) )
    {
        /* Already in our cache. set up a pointer to it   */
        data_block_to_use = pfs->data_map[(int)block_offset_in_fat];
        ltemp = (dword) data_block_to_use;
#if (FAT_BUFFER_SIZE > 63) /* Ugly conditional until sure */
        pdata = pfs->data_array + (ltemp << 9);
#else
        pdata = pfs->data_array + (word) (ltemp << 9);
#endif

⌨️ 快捷键说明

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