📄 zfat.c
字号:
//Following while loops are shortened with EEPROM table longNameOffset. This reduces code size.
/*i=0;
while ((start<40)&&(i<5)) { fileName[start++]=longFile->Part1[i++]; }
i=0;
while ((start<40)&&(i<6)) { fileName[start++]=longFile->Part2[i++]; }
i=0;
while ((start<40)&&(i<2)) { fileName[start++]=longFile->Part3[i++]; }*/
//We only store text in fileName array if total length of text is less than 40 bytes
i=0;
while ((start<40)&&(i<13)) { fileName[start++] = sectorBuffer.data[longNameOffset[i++]]; }
longNameFound=1;
}
else {
//Found Short file entry, now determine its type
//------------------------------------------------------------------------------
for (i=0; i<8; i++) {
//Check for file name validity. There can be garbage in dir entry, that will cause system failure
//j<47 comes from # of eeprom invalidFileChars table
for (j=0; j<47; j++) if (invalidFileChars[j]== file->name[i]) goto CLEAR;
//This may look redundant but its done so that we don't have to write another loop to read fileName
if (longNameFound==0) fileName[i]=file->name[i]; // Reading file name if long name not found
}
/* Found a file. -----------------------------------*/
if ((file->attributes & 0x18 /*(ATTR_DIRECTORY | ATTR_VOLUME_ID)*/ ) == 0x00) {
for(i=0;i<3; i++) { //Collect the file extension
fileExtension[i]=file->extension[i];
}
extension = (*(dword *)fileExtension) & 0x00FFFFFF;
// if we wanted MP3 but extesion wasn't MP3 then goto CLEAR
if ((onlyMP3==1)&&(extension!=0x0033504D)) goto CLEAR; //extension = 03PM (little endian struct)
fileNum++; // File found, so increment fileNum
if (fileNum>currentFileNum) { // Making sure that this entry is not read before
currentFileNum=fileNum; // New entry, so increment current file number.
FileSize = file->fileSize;
currentCluster = file->highClust;
currentCluster = (currentCluster<<16) + file->startCluster;
dirReadOffset.cluster=cluster;
dirReadOffset.sectorPos=sectorPos;
dirReadOffset.fileNum=fileNum;
dirReadOffset.offset=readPos;
return 1;
}
goto CLEAR; //This file has already been encountered so clear the info
}
//-------------------------------------------------------------------------------
//Directory block
if ((file->attributes & 0x18) == ATTR_DIRECTORY) {
/* Found a directory. */
if ((onlyMP3==1) && (subDirLevel<8)) { //Enter sub dir only if looking for MP3
currentCluster=cluster; //pushDir will use value of currentCluster to push onto stack
cluster = file->highClust; //Get the sub-directory cluster address
cluster = (cluster<<16) + file->startCluster;
pushDir(); //push return cluster address on stack (gets value from currentCluster)
subDirLevel++;
readPos=0; //A new cluster has to be read, so set readPos=0
sectorPos=0;
//Fix dirString for LCD path display
i=0;
j=dirString[0];
while ((j<20)&&(fileName[i]!=0)) dirString[j++]=fileName[i++];
dirString[j++]='/';
dirString[0]=j;
}
goto CLEAR;
}
}
}
while (1);
}
dword findNextCluster(){
unsigned long FatOffset, sector;
unsigned int offset;
FatOffset = (currentCluster << 2); //Lshift by 2 will be 1 in FAT16, not supported here
sector = FirstFATSector + (FatOffset / Bytes_Per_Sector);
offset = FatOffset % Bytes_Per_Sector;
readPos=0; sectorPos=0;
while (readPos<offset) ATA_Read_Sectors_LBA(sector,1);
ATA_Read_Sectors_LBA(sector+sectorPos,2);//Have to read 1 word in FAT16, not supported here
return (*(unsigned long *) sectorBuffer.data) & 0x0FFFFFFF; //FAT32 address return
}
void GoToSectorOffset(dword LBASector,word offset) {
//Find the offset in the sector
readPos=0;
while (readPos<offset) ATA_Read_Sectors_LBA(LBASector,1); //go to offset
}
void pushDir() {
//pushes the directory return address on stack.
//Also stores global variables sectorPos and readPos
//Each record is 14 byte long.
//Dir return cluster address = 4 bytes
// ReadPos = 2 bytes
// SectorPos = 1 byte
// Total = 7 bytes
//Due to ZipAmp hardware, we can only store even bytes
//Thus, we rearrange the 7 byte data in 14 byte space, with every even byte having actual data.
byte offset, i;
offset = subDirLevel * 14; //this is storage byte offset, position to store this dir info
for (i=0; i<4; i++) //Arrange the cluster address data on even byte postion
sectorBuffer.data[offset + (i<<1)]=currentCluster>>(24-(i<<3)); //1 word
sectorBuffer.data[offset+8]=readPos>>8; //arrange readPos on even byte
sectorBuffer.data[offset+10]=readPos;
sectorBuffer.data[offset+12]=sectorPos;
offset=offset>>1; //divide by 2 to get word offset
if (offset>0) { //Go to offset if its not 0th position in sector
readPos=0;
ATA_Read_Sectors_LBA(dirStackLBA, offset ); //Load previous dir info in buffer
}
ATA_WriteSector(dirStackLBA); //Now write the buffer into file ZIPAMP.SYS pointed by dirStackLBA.
}
void popDir(){ //Pops directory info from stack, reverse process of pushDir.
byte offset,i;
offset=subDirLevel*14; //Offset we have to read now
readPos=0;
ATA_Read_Sectors_LBA(dirStackLBA, 128); //Load whole dir stack
//Arrange the data
for (i=0; i<7; i+=2) currentCluster=(currentCluster<<8) + sectorBuffer.data[offset+i];
readPos=sectorBuffer.data[offset+8];
readPos=(readPos<<8) + sectorBuffer.data[offset+10];
sectorPos=sectorBuffer.data[offset+12];
}
void saveConfig() {
//Saves player status on ZIPAMP.CFG file.
struct configuration *cfg;
byte i;
cfg = (struct configuration *) sectorBuffer.data;
cfg->Sign1=0xA5; //DataValid signature
cfg->SoundMode=soundMode; //PlayType
cfg->PlayMode=playMode; //Play mode
cfg->DriveSize=DriveSize; //Drive size
cfg->TotalFiles=totalFiles; //Total files
cfg->LastFile=currentFileNum-1; //Played file
cfg->Sign2=0x5A; //DataValid end sign
//Hardware lets us save only even bytes. So fix the array. Position i = position i*2
//13 comes from total size of struct configuration byte size+1 (12+1 bytes)
//Position 0 doesn't need to be fixed, its already in correct position.
for (i=13; i>0; i--) sectorBuffer.data[i*2]=sectorBuffer.data[i]; //Format data for saving, gap every odd byte
ATA_WriteSector(cfgFileLBA);
}
byte loadConfig() {
//Load player status from ZIPAMP.CFG file.
struct configuration *cfg;
byte i;
readPos=0;
ATA_Read_Sectors_LBA(cfgFileLBA,128);
for (i=1; i<=13; i++) sectorBuffer.data[i]=sectorBuffer.data[i*2]; //Format data for reading, ungap every odd byte
cfg = (struct configuration *) sectorBuffer.data;
if (cfg->DriveSize==DriveSize) { //If hard drive info matches
totalFiles=cfg->TotalFiles;
soundMode=cfg->SoundMode;
playMode=cfg->PlayMode;
currentFileNum=cfg->LastFile;
return 1; //Load was successful.
}
return 0; //Load failed.
}
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -