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

📄 f34x_msd_file_system.src

📁 USB读写SD卡例程
💻 SRC
📖 第 1 页 / 共 5 页
字号:
; 
; //-----------------------------------------------------------------------------
; // fopen
; //-----------------------------------------------------------------------------
; //
; // Return Value : TRUE if file is open
; // Parameters   : f - pointer to file structure info
; //  			  filename - pointer to file name
; //				  mode - pointer to opened file mode (read, write etc.)
; //
; // This function opens file
; //-----------------------------------------------------------------------------
; 
; int fopen(FILE* f,char* filename,char* mode) 
; {
; 	f->isopen = 0;
; 
; 	if( mode[0] == 'w' ) { 
;     fdelete(filename); 
;   } // This is the most memory-efficient solution, not the most 
;     // time-efficient solution.
; 
;   findfirst(&findinfo, 0);
;   while(!file_name_match(filename,findinfo.direntry->sfn.name)) {
;     if(!findnext(&findinfo)) {
;       if(mode[0] == 'r') {
;         return 0; // File not found.
;       }
;       if( mode[0] == 'w' || mode[0] == 'a' ) {
;         if(!fcreate(&findinfo, filename)) {
;           return 0; // File cannot be created.
;         } else {
;           break;
;         }
;       }
;     }
;   }
; 
;   f->sector_direntry=findinfo.block;
;   f->offset_direntry=findinfo.offset;
;   f->cluster_start=f->sector_current=
;   ntohs(findinfo.direntry->sfn.starting_cluster);//*MBR.sectors_per_cluster;
;   f->attrib=findinfo.direntry->sfn.attrib;
;   f->size=ntohl(findinfo.direntry->sfn.filesize);
; 
;   if(mode[0]=='a') f->pos=f->size; else f->pos=0;
; //	Print_File(f);
;   return 	f->isopen=1;
; }
; 
; //-----------------------------------------------------------------------------
; // feof
; //-----------------------------------------------------------------------------
; //
; // Return Value : End of file value
; // Parameters   : f - pointer to file info structure
; //
; // This function printout size of file
; //-----------------------------------------------------------------------------
; 
; int feof(FILE* f) 
; {
;   if(!f->isopen) return 1;
;   return f->pos >= f->size;
; }
; 
; //-----------------------------------------------------------------------------
; // fat_chain
; //-----------------------------------------------------------------------------
; //
; // Return Value : global number of sector 
; // Parameters   : from - starting number of sector
; //				  nr - relative number of sector
; //
; // Find the 'nr'-th sector in the fat chain starting at 'from'
; //-----------------------------------------------------------------------------
; 
; static unsigned long fat_chain(unsigned long from,unsigned nr) 
; {
;   unsigned* xdata fat_table=Scratch;
;   unsigned xdata sect,sect_prev=0;
;   unsigned xdata cluster = nr/MBR.sectors_per_cluster;
; 
;   while(cluster) {
;     sect = Sect_Fat1() + from/(Sect_Block_Size()/2);
;     if(sect!=sect_prev) {
;       Sect_Read(sect_prev=sect);
;     }
; 
;     from=ntohs(fat_table[from%(Sect_Block_Size()/2)]);
; 
;     if(!(from>=2 && from<=0xFFEF)) {
;       return 0xFFFFFFFF;
;     }
; 
;     cluster--;
;   }
;   from *= MBR.sectors_per_cluster;
;   from += nr%MBR.sectors_per_cluster;
;   return from;
; }
; 
; //-----------------------------------------------------------------------------
; // fat_chain_free
; //-----------------------------------------------------------------------------
; //
; // Return Value :  
; // Parameters   : from - starting number of sector
; //
; // Function frees an entire fat chain, starting at 'from' until the end of the chain
; //-----------------------------------------------------------------------------
; 
; static void fat_chain_free(unsigned from) 
; {
;   unsigned* xdata fat_table=Scratch;
;   unsigned xdata sect,sect_prev=0;
;   unsigned xdata index;
; 
;   if(from<2) return;
; 
;   sect = Sect_Fat1() + from/(Sect_Block_Size()/2);
; 
;   while(1) {
;     if(sect!=sect_prev) {
;       Sect_Read(sect_prev=sect);
;     }
; 
;     index = from%(Sect_Block_Size()/2);
; 	
;     from=ntohs(fat_table[index]);
; 		
;     fat_table[index]=0x0000; // Free it
; 
;     if(!(from>=2 && from<=0xFFEF)) {
;       Sect_Write_Multi_Fat(sect_prev);
;       break;
;     }
; 
;     sect = Sect_Fat1() + from/(Sect_Block_Size()/2);
;     if(sect!=sect_prev) {
;       Sect_Write_Multi_Fat(sect_prev);
;     }
;   }
; }
; 
; 
; //-----------------------------------------------------------------------------
; // fat_chain_alloc
; //-----------------------------------------------------------------------------
; //
; // Return Value : numer of allocated sector 
; // Parameters   : from - starting number of sector
; //				  nr - relative number of sector
; //
; // Allocate 'nr' of extra FAT blocks at the end of the chain that starts at 'from'
; //-----------------------------------------------------------------------------
; 
; static unsigned fat_chain_alloc(unsigned from,unsigned nr) 
; {
;   unsigned* xdata fat_table=Scratch;
;   unsigned xdata sect,sect_prev=0;
;   unsigned xdata index;
;   unsigned xdata alloced=0xFFFF;
; 
; 	// Find free FAT entries, allocate them, and link them together.
;   for(sect=Sect_Fat1();nr && sect<Sect_Fat2();sect++) {
;     Sect_Read(sect);
; 		// (Skip first two FAT entries when looking for free blocks)
;     for(index=((sect==Sect_Fat1())?2:0);index<Sect_Block_Size()/2;index++) {
;       if(fat_table[index]==0x0000) { 		// It's free
;         fat_table[index]=ntohs(alloced);// Allocate it (refer to previously 
;                                         //   alloc'ed FAT entry).
;         alloced = 						// Remember which FAT entry was alloc'ed
;           (sect-Sect_Fat1()) * (Sect_Block_Size()/2) + index;
;         if(!--nr) break;
;       }
;     }
;     if(alloced!=0xFFFF) Sect_Write_Multi_Fat(sect);	// Write all FAT copies
;   }
; 
;   // When we get here, 'alloced' contains the first FAT block in the alloc'ed chain
;   // Find the end of the current FAT chain.
;   // Make the end of the current FAT chain refer to the newly allocated FAT chain
;   while(from>=2 && from<=0xFFEF && alloced!=0xFFFF) {
;     sect = Sect_Fat1() + from/(Sect_Block_Size()/2);
;     if(sect!=sect_prev) {
;       Sect_Read(sect_prev=sect);
;     }
;     index = from%(Sect_Block_Size()/2);
;     from=ntohs(fat_table[index]);
; 
;     if(from>=0xFFF8) {
;       fat_table[index]=ntohs(alloced);
;       Sect_Write_Multi_Fat(sect);
;     }
;   }
; 
;   return alloced;
; }
; 
; //-----------------------------------------------------------------------------
; // fread
; //-----------------------------------------------------------------------------
; //
; // Return Value : amount of read bytes 
; // Parameters   : f - pointer to file structure
; //				  buffer - pinter to buffer
; //				  count - number of bytes to read
; //
; // This function reads the file
; //-----------------------------------------------------------------------------
; 
; unsigned fread(FILE* f,BYTE* buffer,unsigned count) 
; {
;   unsigned xdata cnt,total_cnt=0;
;   if(!f->isopen || !count) return 0;
; 
;   // If you use the Scratch buffer as fread buffer, then
;   // we cannot possibly support transfers consisting of
;   // multiple Sect_Read() operations. The second Sect_Read
;   // would overwrite the stored bytes from the first one.
;   if(buffer>=Scratch && buffer<Scratch+Sect_Block_Size())
;     count=min(count,Sect_Block_Size()-f->pos%Sect_Block_Size());
; 
;   while(count && !feof(f)) {
;     f->sector_current = fat_chain(f->cluster_start,f->pos/Sect_Block_Size());
; 
;     Sect_Read(Sect_File_Data() + f->sector_current);
; 
;     cnt=min(Sect_Block_Size()-f->pos%Sect_Block_Size(),count);
;     cnt=min(cnt,f->size-f->pos);
; 
;     memmove(buffer,Scratch+f->pos%Sect_Block_Size(),cnt); // MUST be overlap-safe 
;                                                           // copy operation!
;     total_cnt+=cnt;
;     f->pos+=cnt;
;     count-=cnt;
;     buffer+=cnt;
;   }
; 
;   return total_cnt;
; }
; 
; //-----------------------------------------------------------------------------
; // fwrite
; //-----------------------------------------------------------------------------
; //
; // Return Value : amount of written bytes 
; // Parameters   : f - pointer to file structure
; //				  buffer - pinter to buffer
; //				  count - number of bytes to write
; //
; // This function writes the file
; //-----------------------------------------------------------------------------
; 
; unsigned fwrite(FILE* f,BYTE* buffer,unsigned count) 
; {
;   xdata unsigned cnt,total_cnt=0,xtra,alloced;
;   xdata dir_entry* entry;
;   if(!f->isopen || !count) return 0;
; 
; 
;   // First, extend the file so it can hold all the data:
;   if(f->pos+count>f->size) {
;     // If the new EOF ends up in the next FAT block, an extra block must be allocated.
;     // The number of blocks needed to store X bytes = 1+(X-1)/512 if X!=0, or =0 if X==0.
;     // We will need to store 'pos+count' bytes after the write operation
;     // This means we need 1+(pos+count-1)/512 blocks after the write operation
;     // We currently have 'size' bytes in the file, or 1+(size-1)/512 blocks (or 0 if size==0).
;     // So, we need to allocate (1+(pos+count-1)/512) - (1+(size-1)/512) extra blocks
;     xtra=(1+((f->pos+count-1)/Sect_Block_Size())/MBR.sectors_per_cluster); 
;     if ( f->size )
;       xtra -= ( 1 +(( f->size - 1 ) / Sect_Block_Size() ) / MBR.sectors_per_cluster );
; 		
; 
;     if(xtra) {
;       if(0xFFFF==(alloced=fat_chain_alloc(f->sector_current/MBR.sectors_per_cluster,xtra))) 
;         return 0;
;     }
; 
; 		// Modify the direntry for this file:
;     Sect_Read(f->sector_direntry);
;     entry = (dir_entry*)(Scratch+f->offset_direntry);
;     if((entry->sfn.filesize==0) && (entry->sfn.starting_cluster<2 || 
;                                 entry->sfn.starting_cluster>=0xFFF0)) {
;       entry->sfn.starting_cluster=ntohs(f->cluster_start=alloced);
;     } 
;     entry->sfn.filesize=ntohl(f->size=f->pos+count);
;     f->attrib=(entry->sfn.attrib|=ATTRIB_ARCHIVE);
;     Sect_Write(f->sector_direntry);
;   }
; 
;   // Now we are sure the fwrite() operation can be performed
;   // in the existing file data blocks. Either because the file 
;   // was big enough to start with, or because we have just
;   // allocated extra blocks for the new data.
;   while(count && !feof(f)) {
;     f->sector_current = fat_chain(f->cluster_start,f->pos/Sect_Block_Size());
; 		
; 
;     Sect_Read(Sect_File_Data() + f->sector_current);
;   //	Print_File(f);
;   //	print_scratch();
; 
;     cnt=min(Sect_Block_Size()-f->pos%Sect_Block_Size(),count);
;     cnt=min(cnt,f->size-f->pos);
; 
;     memmove(Scratch+f->pos%Sect_Block_Size(),buffer,cnt);
; 
;   //	print_scratch();
;     Sect_Write(Sect_File_Data() + f->sector_current);
; 
;     total_cnt+=cnt;
;     f->pos+=cnt;
;     count-=cnt;
;     buffer+=cnt;
;   }
; 
;   return total_cnt;
; }
; 
; //-----------------------------------------------------------------------------
; // fclose
; //-----------------------------------------------------------------------------
; //
; // Return Value : 
; // Parameters   : f - pointer to file structure
; 
; //
; // This function closes the file
; //-----------------------------------------------------------------------------
; 
; void fclose(FILE* f) 
; {
;   f->isopen=0;
; }
; 
; //-----------------------------------------------------------------------------
; // fdelete
; //-----------------------------------------------------------------------------
; //
; // Return Value :TRUE if everything is ok
; // Parameters   : name - pointer to filename
; //
; //
; // This function deletes the file
; //-----------------------------------------------------------------------------
; 
; int fdelete(char* name) 
; {
;   findfirst(&findinfo,0);
;   while(!file_name_match(name,findinfo.direntry->sfn.name)) {
;     if(!findnext(&findinfo)) {
;       return 0;
;     }
;   }
; 
;   // Do not delete subdirectories or labels:
;   if(findinfo.direntry->sfn.attrib & (ATTRIB_SUBDIR|ATTRIB_LABEL)) return 0;
; 
;   // Mark the direntry as "deleted" before freeing the fat chain.
;   // At this point, the findinfo is still valid in the 'Scratch' buffer.
;   // fat_chain_free() would overwrite the Scratch buffer.
;   findinfo.direntry->sfn.name[0]=0xE5; // Mark as "deleted"
;   Sect_Write(findinfo.block);
;   fat_chain_free(ntohs(findinfo.direntry->sfn.starting_cluster));
; 
;   return 1;
; }
; 
; //-------------------directory functions---------------------
; //--------- findfirst, findnext directory functions ---------
; 
; static BYTE findvalid(find_info* findinfo) 
; {
;   xdata char n0 = findinfo->direntry->sfn.name[0];
;   if(findinfo->findempty) {
;     return (n0==(char)0xE5) || (n0=='\0');
;   }
;   return (n0!=(char)0xE5) && (n0>' ') && (findinfo->direntry->sfn.attrib!=0x0F);
; }
; 
; 
; BYTE findfirst(find_info* findinfo,BYTE empty) 
; {
;   Sect_Read(findinfo->block = Current_Dir_Block);
; 
;   findinfo->findempty=empty;
; 
;   findinfo->direntry=(dir_entry*)(Scratch+(findinfo->offset=0));
;   if(findvalid(findinfo))
;     return 1;
;   return findnext(findinfo);
; }
; 
; 
; BYTE findnext(find_info* findinfo) 
; {
;   xdata BYTE bRoot = (Current_Dir_Block == Sect_Root_Dir());
;   
; 
;   do {
;     if((findinfo->offset+=sizeof(dir_entry))>=Sect_Block_Size()) {
;       xdata unsigned long dir_next_cluster_block = 
;                      Get_First_Block_Directory_Cluster(findinfo->block);
;       if(bRoot &&  (findinfo->block>=Sect_Root_Dir_Last()))
;       {
;       //	printf("NOT FOUND\r\n");
;         return 0;
;       }
; 	  else if((!bRoot) && (dir_next_cluster_block != 0xffffffff) && 
; 	  		(findinfo->block>=(dir_next_cluster_block + MBR.sectors_per_cluster-1)))
; 	  {
; 	  	// read next cluster occupied by directory	
; 	  	xdata unsigned long next_next_block = Get_First_Block_Of_Next_Cluster(
; 										Get_Cluster_From_Sector(dir_next_cluster_block));
; 			
; 		if(next_next_block == (0xFFFFFFFF))
; 		{
; 			if(!findinfo->findempty)
; 				return 0;
; 			else
; 			{
; 				xdata new_cluster = 
;                   fat_chain_alloc(Get_Cluster_From_Sector(dir_next_cluster_block),1);
; 				if(new_cluster == 0xFFFF)
; 					return 0;
; 				next_next_block = Get_First_Sector(new_cluster);
; 				Clear_Cluster(new_cluster);
; 			}	
; 		}
; 
; 		dir_next_cluster_block = next_next_block;
; 		findinfo->offset=0;
; 		Sect_Read(findinfo->block = dir_next_cluster_block);
; 	  }
;       else {
;         findinfo->offset=0;
;         Sect_Read(++findinfo->block);
; 
;       }
;     }
; 		
; 		
;     findinfo->direntry=(dir_entry*)(Scratch+findinfo->offset);
;   } while(!findvalid(findinfo));
; 
;   return 1;
; }
; 
; #else
; 
; //---------------------------------------------------------
; /* Copy of functions for devices different then F340*/
; //---------------------------------------------------------
; 
; static BYTE fcreate(find_info* findinfo,char* filename) 

	RSEG  ?PR?_fcreate?F34X_MSD_FILE_SYSTEM
_fcreate:
	USING	0
			; SOURCE LINE # 1054
	MOV  	DPTR,#findinfo?144
	MOV  	A,R3
	LCALL	L?0165
; {
			; SOURCE LINE # 1055
;   BYTE i,j;
;   // Find the first empty directory entry
;   if(!findfirst(findinfo,1)) return 0;
			; SOURCE LINE # 1058
	MOV  	R5,#01H
	LCALL	_findfirst
	MOV  	A,R7
	JNZ  	?C0017
	MOV  	R7,A
	RET  	
?C0017:
; 
;   // Fill in the direntry
;   for( i = 0; i < 10; i++) 
			; SOURCE LINE # 1061
	CLR  	A
	MOV  	DPTR,#i?146
	MOVX 	@DPTR,A
?C0019:
	LCALL	L?0223
	SUBB 	A,#0AH
	JNC  	?C0020
;     findinfo->direntry->sfn.reserved[i] = 0;
			; SOURCE LINE # 1062
	MOV  	DPTR,#findinfo?144
	LCALL	L?0154
	LCALL	L?0174
	MOV  	A,R1
	ADD  	A,#0CH
	MOV  	R1,A
	CLR  	A
	ADDC 	A,R2
	MOV  	R2,A
	MOV  	R6,#00H
	MOV  	A,R1
	ADD  	A,R7
	MOV  	R1,A
	MOV  	A,R6
	ADDC 	A,R2
	MOV  	R2,A
	CLR  	A
	LCALL	?C?CSTPTR
	LCALL	L?0214
	SJMP 	?C0019
?C0020:
;   findinfo->direntry->sfn.time.i = findinfo->direntry->sfn.date.i = 0;
			; SOURCE LINE # 1063
	MOV  	DPTR,#findinfo?144
	LCALL	L?0154
	LCALL	L?0174
	MOV  	DPTR,#018H
	LCALL	L?0200
	MOV  	DPTR,#findinfo?144
	LCALL	L?0154
	LCALL	L?0175
	MOV  	DPTR,#016H
	LCALL	L?0201
;   findinfo->direntry->sfn.starting_cluster = findinfo->direntry->sfn.filesize = 0;
			; SOURCE LINE # 1064
	MOV  	DPTR,#findinfo?144
	LCALL	L?0154
	LCALL	L?0175
	MOV  	DPTR,#01CH
	LCALL	?C?LSTKOPTR
	DB   	00H
	DB   	00H
	DB   	00H
	DB   	00H
	MOV  	DPTR,#findinfo?144
	LCALL	L?0154
	LCALL	L?0175
	MOV  	DPTR,#01AH
	LCALL	L?0200
; 
;   // Fill in the filename
;   for( i = 0; i < 11; i++ ) 
			; SOURCE LINE # 1067
	CLR  	A
	MOV  	DPTR,#i?146
	MOVX 	@DPTR,A

⌨️ 快捷键说明

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