📄 dos.c
字号:
//###########################################################
// File: dos.c
//
// Using fopen() and fread() is very slow because a lot
// of calculations have to be done.
// Using ReadFileRaw() is up to 7 times faster.
//
//
//#########################################################################
// Last change: 04.03.2004
//#########################################################################
// holger.klabunde@t-online.de
// http://home.t-online.de/home/holger.klabunde/homepage.htm
//#########################################################################
// Compiler: WIN-AVR 3.3
//#########################################################################
#include <stdlib.h>
#include <string.h>
#include <ctype.h>
#include "protos.h"
#include "dos.h"
#include "mydefs.h"
#include "serial.h"
/*
unsigned char DeleteFile(char *name)
{
// Look if file exists
// if not return success
// free clusters in cluster chain (make zero)
// remove dir entry (mark first character in direntry with 0xE5)
// return success
}
*/
//###########################################################
// reset DOS
void InitDOS(void)
//###########################################################
{
CurrentDirCluster=0; //root directory
CurrentSector=0;
CurrentCluster=2; //first possible free cluster
FileFirstCluster=0;
FileSize=0;
FileFlag=0;
lo=0; // no long filenames
}
//###########################################################
// write count bytes from buffer to file
// returns number of bytes written
//
// fwrite() does not write to CF until a sector is completely
// filled. you can force writing with fflush() when file should
// keep open, or close the file with fclose().
//###########################################################
unsigned int fwrite(unsigned char *buf, unsigned int count)
//###########################################################
{
unsigned char *p, secoffset;
unsigned long tmp;
unsigned int buffoffset, bytecount;
if(FileFlag==0) return 0; //don't write if file is closed
//written bytes are zero
p=buf;
bytecount=0;
do
{
tmp=FileSize; //next write position
tmp-= FileClusterCount; //calc byte position in cluster
if(tmp >= FileBytePerCluster)//is position in new cluster ?
{
CFWriteSector(FileCurrentSector,iob); //write last sector
FileCurrentCluster=AllocCluster(FileCurrentCluster); //alloc new cluster
if(FileCurrentCluster==DISK_FULL)
{
#ifdef F_DEBUG
puts("Disk full !\n");
#endif
return bytecount; //return number of bytes written before disk full
}
File1stClusterSector=GetFirstSectorOfCluster(FileCurrentCluster);//set new 1st sector of cluster
#ifdef F_DEBUG
printf("Cluster %lu Sector %lu\n",FileCurrentCluster,File1stClusterSector);
#endif
FileCurrentSector=File1stClusterSector; //set new current sector
// FileClusterCount++; //update cluster count
FileClusterCount+=FileBytePerCluster; //update cluster count
tmp-= FileBytePerCluster; //calc new byte position in cluster
}
secoffset=(unsigned char)(tmp / BYTE_PER_SEC); //calc offset from first sector in cluster
if(File1stClusterSector+secoffset != FileCurrentSector)
{
CFWriteSector(FileCurrentSector,iob); //write last sector used
FileCurrentSector=File1stClusterSector+secoffset;
#ifdef F_DEBUG
printf("Sector %lu\n",FileCurrentSector);
#endif
}
buffoffset=(unsigned int)(tmp % BYTE_PER_SEC); //calc offset in sector
iob[buffoffset]=*p++; //put byte in write buffer
FileSize++; //update Filesize
bytecount++; //one byte written to buffer
}while(bytecount<count);
return bytecount;
}
//###########################################################
// read count bytes into buffer
// returns number of bytes read
unsigned int fread(unsigned char *buf, unsigned int count)
//###########################################################
{
unsigned char *p, secoffset;
unsigned long tmp;
unsigned int buffoffset, bytecount;
if(FileFlag==0) return 0; //don't read if file is closed
//read bytes are zero
p=buf;
bytecount=0;
do
{
tmp=FilePosition;
if(tmp<FileSize) //end of file reached ?
{
// tmp-= FileClusterCount * FileBytePerCluster; //calc byte position in cluster
tmp-= FileClusterCount; //calc byte position in cluster
//maybe its faster to count cluster and sectorbytes
if(tmp >= FileBytePerCluster)//is position in current cluster ?
{
FileCurrentCluster=GetNextClusterNumber(FileCurrentCluster); //if not get next cluster
File1stClusterSector=GetFirstSectorOfCluster(FileCurrentCluster);//set new 1st sector of cluster
CFReadSector(File1stClusterSector,iob); //read new sector
#ifdef F_DEBUG
printf("Cluster %lu Sector %lu\n",FileCurrentCluster,File1stClusterSector);
#endif
FileCurrentSector=File1stClusterSector; //set new current sector
// FileClusterCount++; //update cluster count
FileClusterCount+=FileBytePerCluster; //update cluster count
tmp-= FileBytePerCluster; //calc new byte position in cluster
}
secoffset=(unsigned char)(tmp / BYTE_PER_SEC); //calc offset from first sector in cluster
if(File1stClusterSector+secoffset != FileCurrentSector)
{
FileCurrentSector=File1stClusterSector+secoffset;
CFReadSector(FileCurrentSector,iob); //read new sector
#ifdef F_DEBUG
printf("Sector %lu\n",FileCurrentSector);
#endif
}
buffoffset=(unsigned int)(tmp % BYTE_PER_SEC); //calc offset in sector
*p++=iob[buffoffset];
FilePosition++;
bytecount++; //one byte read into buffer
} //if(tmp<FileSize)
else return bytecount; //return bytes read til end of file
} while(bytecount<count);
return bytecount;
}
//###########################################################
//open a file for reading OR writing, NOT both !
unsigned char fopen(char *name, unsigned char flag)
//###########################################################
{
unsigned long tmp;
FileBytePerCluster=BYTE_PER_SEC * secPerCluster; //bytes per cluster
FileClusterCount=0;
if(flag==F_READ)
{
if(FindName(name)==FULL_MATCH) //file MUST exist for reading
{
FilePosition=0; //actual read position
FileCurrentCluster=FileFirstCluster;
FileFlag=flag; //needed for fclose
File1stClusterSector=GetFirstSectorOfCluster(FileFirstCluster);
FileCurrentSector=File1stClusterSector;
CFReadSector(FileCurrentSector,iob); //read first sector of file
#ifdef F_DEBUG
puts("File is open for reading\n");
#endif
return F_OK; //give back something above zero
}
#ifdef F_DEBUG
else puts("File not found\n");
#endif
}
if(flag==F_WRITE)
{
//if file exists, open it and spool to end of file to append data
if(FindName(name)==FULL_MATCH)
{
tmp=FileFirstCluster;
while(tmp<endofclusterchain) //go to end of cluster chain
{
tmp=GetNextClusterNumber(tmp);
if(tmp<endofclusterchain)
{
FileCurrentCluster=tmp;
FileClusterCount+=FileBytePerCluster;
}
}
tmp=FileSize-FileClusterCount;
File1stClusterSector=GetFirstSectorOfCluster(FileCurrentCluster);
FileCurrentSector=File1stClusterSector;
FileCurrentSector+= tmp / BYTE_PER_SEC;
CFReadSector(FileCurrentSector,iob); //read first sector of file
}
else //make a new file
{
MakeFileName(name,FileName,FileExt); //Split into name and extension
if(MakeNewFileEntry()) //file does not exist, make new file in currentdir
{
FileCurrentCluster=FileFirstCluster;
File1stClusterSector=GetFirstSectorOfCluster(FileFirstCluster);
FileCurrentSector=File1stClusterSector;
CFReadSector(FileCurrentSector,iob); //read first sector of file
}
else
{
#ifdef F_DEBUG
puts("fopen() failed !\nNo free DIR entry\n");
#endif
FileFlag=0; //needed for fclose
return F_ERROR; //new file could not be made
}
}
FileFlag=flag; //needed for fclose
return F_OK; //file is open for writing
}//if(flag==F_WRITE)
return F_ERROR; //something went wrong
}
//###########################################################
// close the file
// no error codes
void fclose(void)
//###########################################################
{
if(FileFlag==F_READ)
{
}
if(FileFlag==F_WRITE)
{
fflush(); //write last sector used to CF and update filesize, filetime
}
FileFlag=0; //a second fclose should do nothing
//reading and writing disabled
#ifdef F_DEBUG
puts("File is closed\n");
#endif
}
//###########################################################
// force writing last data written into sectorbuffer to be
// stored into CF without fclose(). direntry will also be
// updated.
void fflush(void)
//###########################################################
{
if(FileFlag==0) return; //don't write if file is closed
CFWriteSector(FileCurrentSector,iob); //write last sector used
//update file entry filesize and date/time
UpdateFileEntry();
}
//############################################################
// search for a filename or directoryname in current directory
unsigned char FindName(char *name)
//############################################################
{
unsigned char result;
if(CurrentDirCluster<2)
{
result=ScanRootDir(name);
}
else
{
result=ScanSubDir(CurrentDirCluster,name);
}
return result;
}
//###########################################################
// reads all clusters/sectors of the file.
// you have to check filesize from direntry to see how
// many bytes of last cluster are valid for the file.
// much faster than fread()
unsigned char ReadFileRaw(unsigned long startcluster)
//###########################################################
{
unsigned long tmp,tmpsector;
unsigned char i;
tmp=startcluster;
while(tmp < endofclusterchain)
{
tmpsector=GetFirstSectorOfCluster(tmp);
for(i=0; i<secPerCluster; i++)
{
CFReadSector(tmpsector,iob);
//Remove this if you like
DumpSector(iob); //Show sector on serial port
//**************************
//load your MP3-Chip here ;)
//**************************
tmpsector++;
}
tmp=GetNextClusterNumber(tmp);
}
return F_OK;
}
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -