📄 file_system.c
字号:
for( i = 0; i < 10; i++)
findinfo->direntry->sfn.reserved[i] = 0;
findinfo->direntry->sfn.time = findinfo->direntry->sfn.date = 0;
if(direntry_num==1)
{
findinfo->direntry->sfn.starting_cluster = 2;
}
else if(direntry_num==2)
{
pre_dir_entry=(dir_entry *)(Scratch);
start_cluster=pre_dir_entry->sfn.starting_cluster+pre_dir_entry->sfn.filesize/Sect_Cluster_Size()+1;//bytesper_cluster
findinfo->direntry->sfn.starting_cluster =start_cluster;
}
findinfo->direntry->sfn.filesize = 0;
// Fill in the filename
for( i = 0; i < 11; i++ )
findinfo->direntry->sfn.name[i] = ' ';
for( j = 0; j < 20; j++ ) {
if(!filename[j] || filename[j] == '.')
break;
if( j < 8 )
findinfo->direntry->sfn.name[j] = toupper(filename[j]);
}
if( filename[j] == '.' ) {
for( i = 0; i < 3; i++ ) {
if(!filename[j+i+1] || filename[j+i+1]=='.')
break;
findinfo->direntry->sfn.name[8+i] = toupper(filename[j+i+1]);
}
}
//for(i=0;i<11;i++) findinfo->direntry->sfn.name[i]=
//toupper(findinfo->direntry->sfn.name[i]);
// Don't forget to set the attrib:
findinfo->direntry->sfn.attrib = ATTRIB_ARCHIVE;
// Write the new data to MMC
Sect_Write(findinfo->block);
//update fat 10-25
memcpy(Scratch_temp,Scratch,512);
if(direntry_num==1)
{
Sect_Read(Sect_Fat1());
sect_start=(unsigned short *)Scratch;
*(sect_start+0)=LSB_to_MSB(0xff8f);
*(sect_start+1)=LSB_to_MSB(0xffff);
*(sect_start+2)=LSB_to_MSB(0xffff);
Sect_Write(Sect_Fat1());
}
else if(direntry_num==2)
{
Sect_Read(Sect_Fat1()+start_cluster/256);
sect_start=(unsigned short *)Scratch;
*(sect_start+start_cluster%256)=LSB_to_MSB(0xffff);
Sect_Write(Sect_Fat1()+start_cluster/256);
}
memcpy(Scratch,Scratch_temp,512);
return 1;
}
//-----------------------------------------------------------------------------
// m_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 m_fopen(M_FILE* f,char* filename,char* mode)
{
f->isopen = 0;
if( mode[0] == 'w' ) {
//m_fdelete(filename);
} // This is the most memory-efficient solution, not the most
// time-efficient solution.
m_fcreate(&findinfo, filename);
f->sector_direntry=findinfo.block;
f->offset_direntry=findinfo.offset;
f->cluster_start=f->sector_current=
(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;
}
int mm_fopen(M_FILE* f,char * filename,char * mode)
{
int i=0;
int j;
///////////////creat_file;
int dir_offset;
dir_entry * dir_entry_t;
unsigned short * fat_list;
int start_cluster;
int last_start_cluster;
int last_used_cluster;
dir_entry * last_dir_entry;
Sect_Read(0x100);
for(i=0;i<16;i++)//max file num is 16
{
dir_entry_t = (dir_entry*)(Scratch+i*0x20);
dir_offset=i*0x20;
if(dir_entry_t->sfn.name[0]==0)
break;
}
// Fill in the filename
for( i = 0; i < 11; i++ )
dir_entry_t->sfn.name[i] = ' ';
for( j = 0; j < 20; j++ ) {
if(!filename[j] || filename[j] == '.')
break;
if( j < 8 )
dir_entry_t->sfn.name[j] = toupper(filename[j]);
}
if( filename[j] == '.' ) {
for( i = 0; i < 3; i++ ) {
if(!filename[j+i+1] || filename[j+i+1]=='.')
break;
dir_entry_t->sfn.name[8+i] =toupper(filename[j+i+1]);
}
}
//
dir_entry_t->sfn.attrib=ATTRIB_ARCHIVE;
dir_entry_t->sfn.filesize=0;
dir_entry_t->sfn.date=0;
dir_entry_t->sfn.time=0;
//find a free fat block
fat_list=(unsigned short *)(get_vfile_add()+Sect_Fat1()*512);
if(dir_offset==0)
{
start_cluster=2;
*(fat_list+0)=0xff8f;
*(fat_list+1)=0xffff;
}
else
{
last_dir_entry=(dir_entry*)(Scratch+dir_offset-0x20);
last_start_cluster=last_dir_entry->sfn.starting_cluster;
last_used_cluster=(last_dir_entry->sfn.filesize/512+1);
start_cluster=last_start_cluster+last_used_cluster;
}
*(fat_list+start_cluster)=0xffff;
dir_entry_t->sfn.starting_cluster=start_cluster;
Sect_Write(0x100);
///////////open file
f->attrib=ATTRIB_ARCHIVE;
f->cluster_start=start_cluster;
f->offset_direntry=dir_offset;
f->pos=0;
f->sector_direntry=0x100;
f->sector_current=start_cluster;
f->size=0;
f->isopen=1;
//while(1);
return 0;
}
//-----------------------------------------------------------------------------
// m_feof
//-----------------------------------------------------------------------------
//
// Return Value : End of file value
// Parameters : f - pointer to file info structure
//
// This function printout size of file
//-----------------------------------------------------------------------------
int m_feof(M_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,ulong nr)
{
uint* fat_table=(uint *)Scratch;
uint sect,sect_prev=0;
ulong 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(ulong from)
{
uint* fat_table=(uint *)Scratch;
uint sect,sect_prev=0;
ulong 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 ulong fat_chain_alloc(ulong from,ulong nr)
{
uint* fat_table=(uint *)Scratch;
uint sect,sect_prev=0;
ulong index;
ulong 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;
}
//-----------------------------------------------------------------------------
// m_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
//-----------------------------------------------------------------------------
ulong m_fread(M_FILE* f,BYTE* buffer,ulong count)
{
ulong cnt,total_cnt=0;
if(!f->isopen || !count) return 0;
// If you use the Scratch buffer as m_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.
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -