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

📄 fileio.c

📁 SD卡驱动
💻 C
📖 第 1 页 / 共 5 页
字号:
 * PreCondition:    FILEopen in the read mode has been executed
 *
 * Input:           fo			- File to be read
 *					pDest		- Destination buffer for read bytes
 *					count		- Number of bytes to be read
 *					pBytesRead	- Number of bytes read
 *                  
 * Output:			CE_GOOD				- my_fread successful
 *					CE_EOF				- End of file reached
 *					
 *
 * Side Effects:    None
 *
 * Overview:        Reads data from a file into destination buffer
 *
 * Note:            None
 *****************************************************************************/

CETYPE __fread( MYFILE *fo, BYTE *pDest, WORD count, WORD *pBytesRead )
{
	DISK 	*dsk;					// Disk structure
	DWORD 	seek, sec_sel;
	WORD 	pos; 		//position within sector
	CETYPE	error = CE_GOOD;
	
	dsk 	= (DISK *)fo->dsk;
	pos 	= fo->pos;
	seek 	= fo->seek;
	
	*pBytesRead = 0;

	if( fo->Flags.write )
		return CE_WRITEONLY;

	// if it not my buffer, then get it from the disk.
	if( gBufferOwner != fo &&
		pos != MEDIA_SECTOR_SIZE )
	{
		gBufferOwner = fo;
		sec_sel = Cluster2Sector(dsk,fo->ccls);
		sec_sel += (WORD)fo->sec;		// add the sector number to it

		if( !SECTORread( sec_sel, dsk->buffer) )
			return CE_BAD_SECTOR_READ;
	}

	//loop reading (count) bytes
	while( count )
	{
		if( seek == fo->size )
		{	error = CE_EOF;
			break; 	}

		// In my_fopen, pos is init to 0 and the sect is loaded
        if( pos == MEDIA_SECTOR_SIZE )
        {
            // reset position
            pos = 0;

            // point to the next sector
            fo->sec++;

            // get a new cluster if necessary
            if( fo->sec == dsk->SecPerClus )
            {
                fo->sec = 0;
                if( (error = FILEget_next_cluster( fo, 1)) != CE_GOOD )
					break;
            }

            sec_sel = Cluster2Sector(dsk,fo->ccls);
			sec_sel += (WORD)fo->sec;		// add the sector number to it

	        gBufferOwner = fo;
            if( !SECTORread( sec_sel, dsk->buffer) )
			{	error = CE_BAD_SECTOR_READ;
				break; }
        }

        // copy one byte at a time
        *pDest = RAMread( dsk->buffer, pos++ );
		pDest++;
        seek++;
		(*pBytesRead)++;
        count--;
	}

	// save off the positon
	fo->pos = pos;

	// save off the seek
	fo->seek = seek;

    return(error);
} // my_fread

/******************************************************************************
 * Function:        BYTE FILEget_next_cluster(FILEOBJ fo, WORD n)
 *
 * PreCondition:    Disk mounted, fo contains valid file data
 *
 * Input:           fo		- File structure
 *					n		- number of links in the FAT cluster chain to jump
 *							  through; n == 1 - next cluster in the chain
 *                  
 * Output:			CE_GOOD				- Operation successful
 *					CE_BAD_SECTOR_READ	- A bad read occured of a sector 
 *					CE_INVALID_CLUSTER	- Invalid cluster value > maxcls 
 *					CE_FAT_EOF			- Fat attempt to read beyond EOF
 *					
 *
 * Side Effects:    None
 *
 * Overview:        Steps through a chain of clusters
 *
 * Note:            None
 *****************************************************************************/

BYTE FILEget_next_cluster(FILEOBJ fo, WORD n)
{
    WORD         c, c2;
    BYTE          error = CE_GOOD;
    DISK *      disk;
   
    disk = fo->dsk;     
        
    // loop n times
    do {    
        // get the next cluster link from FAT
        c2 = fo->ccls;
        
        if ( (c = FATread( disk, c2)) == FAIL)
            error = CE_BAD_SECTOR_READ;
        else
        {    
            // check if cluster value is valid
            if ( c >= disk->maxcls)
            {
                error = CE_INVALID_CLUSTER;
            }
            
            // compare against max value of a cluster in FAT
            c2 = LAST_CLUSTER;
            
            // return if eof
            if ( c >= c2)    // check against eof
            {
                error = CE_FAT_EOF;
            }
        }
        
        // update the MYFILE structure
        fo->ccls = c;

    } while (--n > 0 && error == CE_GOOD);// loop end
        

    return(error);
} // get next cluster


/******************************************************************************
 * Function:        BYTE Write_File_Entry( FILEOBJ fo, WORD * curEntry)
 *
 * PreCondition:    Disk mounted, fo contains valid file data
 *
 * Input:           fo			- File structure
 *					curEntry	- Write destination
 *                  
 * Output:			TRUE	- Operation successful
 *					FALSE	- Operation failed 
 *
 * Side Effects:    None
 *
 * Overview:        Write the buffer into the current entry
 *
 * Note:            None
 *****************************************************************************/

BYTE Write_File_Entry( FILEOBJ fo, WORD * curEntry)
{
    DISK	*dsk;
    BYTE	status;
	BYTE	offset2;
    DWORD	sector;
	WORD	ccls;
    
    dsk = fo->dsk;
    
    // get the cluster of this entry
    ccls = fo->dirccls;
      
    offset2  = (*curEntry >> 4);
      
    // if its not the root, it works cluster based  
    if(ccls != 0)
        offset2 = offset2 % (dsk->SecPerClus);
        
	sector = Cluster2Sector(dsk,ccls);
              
	// Now write it    	
	if ( !SECTORwrite( sector + offset2, dsk->buffer)) 
	    status = FALSE;
	else
	    status = TRUE;                      
    
    return(status);
} // Write_File_Entry 

/******************************************************************************
 * Function:        WORD FATwrite( DISK *dsk, WORD cls, WORD v)
 *
 * PreCondition:    Disk mounted, fo contains valid file data
 *
 * Input:           dsk		- Disk structure
 *					cls		- Current cluster
 *					v		- New value
 *                  
 * Output:			c		- Cluster value
 *					FAIL	- Operation failed 
 *
 * Side Effects:    None
 *
 * Overview:        Write a cluster link in all FAT copies
 *
 * Note:            None
 *****************************************************************************/

WORD FATwrite( DISK *dsk, WORD cls, WORD v)
{
    BYTE  i;
    WORD p, c;
    DWORD l, li;

    if ( dsk->type != FAT16)
		return FAIL;

	gBufferOwner = NULL;

    // get address of current cluster in fat
    p = cls * 2; // always even
    // cluster = 0xabcd
    // packed as:     0   |   1    |   2   |  3    |
    // word p       0   1 |  2   3 | 4   5 | 6   7 |..
    //              cd  ab|  cd  ab| cd  ab| cd  ab|

    // load the fat sector containing the cluster
    l = dsk->fat + (p >> 9 );
    p &= 0x1ff;
    if( !SECTORread( l, dsk->buffer) )
        return FAIL;

    // get the next cluster value
    RAMwrite( dsk->buffer, p, v);       // lsb
    RAMwrite( dsk->buffer, p+1, (v>>8));// msb

    // update all FAT copies
    for ( i = 0, li = l; i < dsk->fatcopy; i++, li += dsk->fatsize)
        if ( !SECTORwrite( l, dsk->buffer) )
            return FAIL;

    // Normalize it so 0xFFFF is an error
    if(c >= LAST_CLUSTER_FAT16)
        c = LAST_CLUSTER;

    return c;

} // FATwrite

/******************************************************************************
 * Function:        BYTE FAT_erase_cluster_chain (WORD cluster, DISK * dsk)
 *
 * PreCondition:    Disk mounted, should be called from FILEerase
 *
 * Input:           cluster	- The cluster number
 *					dsk		- The disk structure
 *                  
 * Output:			TRUE		- Operation successful
 *					FALSE		- Operation failed 
 *					
 *
 * Side Effects:    None
 *
 * Overview:        Erase the cluster chain
 *
 * Note:            None
 *****************************************************************************/

BYTE FAT_erase_cluster_chain (WORD cluster, DISK * dsk)
{ 
    WORD     c,c2;
    enum    _status {Good, Fail, Exit}status;
    
    status = Good;
    
    // Make sure there is actually a cluster assigned
    if(cluster == 0 || cluster == 1)
    {
        status = Exit;
    }
    else
    {
        while(status == Good)
        {
            // Get the FAT entry
            if((c = FATread( dsk, cluster)) == FAIL)
                status = Fail;
            else
            {    
                if(c == 0 || c == 1)
				{
					 status = Exit;			
				}
				else
				{
					// compare against max value of a cluster in FATxx
	                c2 = LAST_CLUSTER;
	                
	                // look for the last cluster in the chain
	                if ( c >= c2)    
	                    status = Exit;
	                
	                // Now erase this FAT entry
	                if(FATwrite(dsk, cluster, CLUSTER_EMPTY) == FAIL)
	                    status = Fail;
	                
	                // now update what the current cluster is 
	                cluster = c;
				}
            }
        }// while status
    }// cluster == 0
    
    if(status == Exit)
        return(TRUE);
    else    
        return(FALSE);
} // Erase cluster


/******************************************************************************
 * Function:        DIRENTRY Cache_File_Entry( FILEOBJ fo, WORD * curEntry, BYTE ForceRead)
 *
 * PreCondition:    Disk mounted
 *
 * Input:           fo			- File information
 *					curEntry	- Location of the sector
 *					ForceRead	- Forces loading of a new sector of the root
 *                  
 * Output:			DIRENTRY	- Sector loaded
 *
 * Side Effects:    None
 *
 * Overview:        Get the sector loaded as pointed to by curEntry
 *
 * Note:            Should not be called by user
 *****************************************************************************/

DIRENTRY Cache_File_Entry( FILEOBJ fo, WORD * curEntry, BYTE ForceRead)
{
    DIRENTRY dir;
    DISK *dsk;
    DWORD sector;
    WORD cluster;
    WORD ccls;
    BYTE offset2;
    BYTE numofclus;

    dsk = fo->dsk;
    
    // get the base sector of this directory
    cluster = fo->dirclus;
    ccls = fo->dirccls;

	// figure out the offset from the base sector
	offset2  = (*curEntry >> 4);
	offset2 = offset2; // emulator issue
          
	// if its the root its not cluster based
	if(cluster != 0)  
	    offset2  = offset2 % (dsk->SecPerClus);   // figure out the offset
             
    // check if a new sector of the root must be loaded
    if (ForceRead || (*curEntry & 0xf) == 0)    // only 16 entries per sector
    {
        // see if we have to load a new cluster
        if((offset2 == 0 && (*curEntry) > DIRENTRIES_PER_SECTOR) || ForceRead)
        {
			if(cluster == 0)
			{
			    ccls = 0;
			}
			else
			{
    			if(ForceRead)
    				numofclus = ((WORD)(*curEntry) / (WORD)(((WORD)DIRENTRIES_PER_SECTOR) * (WORD)dsk->SecPerClus));
    			else
    				numofclus = 1;
    
    			// move to the correct cluster
    			while(numofclus)
    			{
    				ccls = FATread(dsk, ccls);  
    				
    				if(ccls >= LAST_CLUSTER)
    				    break;
    				else          
    				    numofclus--;
    			}
    		}	
        }       
        
        // see if that we have a valid cluster number
        if(ccls < LAST_CLUSTER)
        {           
            fo->dirccls = ccls; // write it back
            
            sector = Cluster2Sector(dsk,ccls);
            
            // see if we are root and about to go pass our boundaries
            if(ccls == 0 && (sector + offset2) >= dsk->data)
            {
                dir = ((DIRENTRY)NULL);   // reached the end of the root!
            }
            else
            {
                gBufferOwner = NULL;

                if ( SECTORread( sector + offset2, dsk->buffer) != TRUE) 
                    dir = ((DIRENTRY)NULL);
        		else
        		{
        		    // now figure out the pointer if its a forced read
        		    if(ForceRead)
        		        dir = (DIRENTRY)((DIRENTRY)dsk->buffer) + ((*curEntry)%DIRENTRIES_PER_SECTOR);
                    else
                        dir = (DIRENTRY)dsk->buffer;                        
                }       
            }
        }
        else
             dir = ((DIRENTRY)NULL);   
    }
    else
        dir = (DIRENTRY)((DIRENTRY)dsk->buffer) + ((*curEntry)%DIRENTRIES_PER_SECTOR);

    return(dir);
} // Cache_File_Entry 


/******************************************************************************
 * Function:        CETYPE __fwrite( MYFILE* fo, void * src, WORD count, WORD* pBytesWritten )
 *
 * PreCondition:    File opened in WRITE mode
 *
 * Input:           fo			- Pointer to file structure
 *					src			- Pointer to source buffer
 *					count		- Number of bytes to transfer
 *					pBytesWritten	- The number of bytes that have been written
 *                  
 * Output:			CE_GOOD			- Write successful
 *					CE_WRITE_ERROR	- Write failed
 *					Default			- Number of bytes that could not be written
 *
 * Side Effects:    None
 *
 * Overview:        Write file
 *
 * Note:            None
 *****************************************************************************/

⌨️ 快捷键说明

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