📄 f34x_msd_file_system.src
字号:
;
; //-----------------------------------------------------------------------------
; // 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 + -