📄 fatlite.c
字号:
vol.firstFATSectorNo = vol.bootSectorNo + LE2(bootSector->bpb.reservedSectors); vol.secondFATSectorNo = vol.firstFATSectorNo + LE2(bootSector->bpb.sectorsPerFAT); vol.rootDirectorySectorNo = vol.firstFATSectorNo + bootSector->bpb.noOfFATS * LE2(bootSector->bpb.sectorsPerFAT); vol.sectorsInRootDirectory = (UNAL2(bootSector->bpb.rootDirectoryEntries) * DIRECTORY_ENTRY_SIZE - 1) / SECTOR_SIZE + 1; vol.firstDataSectorNo = vol.rootDirectorySectorNo + vol.sectorsInRootDirectory; noOfSectors = UNAL2(bootSector->bpb.totalSectorsInVolumeDOS3); if(noOfSectors == 0) noOfSectors = (SectorNo) LE4(bootSector->bpb.totalSectorsInVolume); vol.maxCluster = (unsigned) ((noOfSectors - vol.firstDataSectorNo) / vol.sectorsPerCluster) + 1; if(vol.maxCluster < 4085) {#ifdef FAT_12BIT vol.flags |= VOLUME_12BIT_FAT; /* 12-bit FAT */#else#ifdef DEBUG_PRINT DEBUG_PRINT("Debug: FAT_12BIT must be defined.\n");#endif return flFormatNotSupported;#endif } vol.bytesPerCluster = vol.sectorsPerCluster * SECTOR_SIZE; vol.allocationRover = 2; /* Set rover at first cluster */ vol.flags |= VOLUME_MOUNTED; /* That's it */ return flOK;}#if defined(DEFRAGMENT_VOLUME) || defined(SINGLE_BUFFER)/*----------------------------------------------------------------------*//* d e f r a g m e n t V o l u m e *//* *//* Performs a general defragmentation and recycling of non-writable *//* Flash areas, to achieve optimal write speed. *//* *//* NOTE: The required number of sectors (in irLength) may be changed *//* (from another execution thread) while defragmentation is active. In *//* particular, the defragmentation may be cut short after it began by *//* modifying the irLength field to 0. *//* *//* Parameters: *//* ioreq->irLength : Minimum number of sectors to make available *//* for writes. *//* *//* Returns: *//* ioreq->irLength : Actual number of sectors available for writes *//* FLStatus : 0 on success, otherwise failed *//*----------------------------------------------------------------------*/static FLStatus defragmentVolume(Volume vol, IOreq FAR2 *ioreq){ return vol.tl.defragment(vol.tl.rec,&ioreq->irLength);}#endif /* DEFRAGMENT_VOLUME */#ifdef FORMAT_VOLUME/*----------------------------------------------------------------------*//* f l F o r m a t V o l u m e *//* *//* Formats a volume, writing a new and empty file-system. All existing *//* data is destroyed. Optionally, a low-level FTL formatting is also *//* done. *//* Formatting leaves the volume in the dismounted state, so that a *//* flMountVolume call is necessary after it. *//* *//* Parameters: *//* irHandle : Drive number (0, 1, ...) *//* irFlags : NO_FTL_FORMAT: Do FAT formatting only *//* FTL_FORMAT: Do FTL & FAT formatting *//* FTL_FORMAT_IF_NEEDED: Do FTL formatting only *//* if current format is invalid *//* irData : Address of FormatParams structure to use *//* *//* Returns: *//* FLStatus : 0 on success, otherwise failed *//*----------------------------------------------------------------------*/static FLStatus formatVolume(Volume vol, IOreq FAR2 *ioreq){ FormatParams FAR1 *formatParams = (FormatParams FAR1 *) ioreq->irData; checkStatus(dismountVolume(&vol)); if(ioreq->irFlags == FTL_FORMAT) { checkStatus(flFormat(&vol - vols,formatParams)); } else { FLStatus status = flMount(&vol - vols,&vol.tl,&vol.flash); if((status == flUnknownMedia || status == flBadFormat) && ioreq->irFlags == FTL_FORMAT_IF_NEEDED) status = flFormat(&vol - vols,formatParams); if(status != flOK) return status; } checkStatus(flMount(&vol - vols,&vol.tl,&vol.flash)); checkStatus(flDosFormat(&vol.tl,formatParams)); return flOK;}#endif /* FORMAT_VOLUME */#ifdef ABS_READ_WRITE/*----------------------------------------------------------------------*//* a b s R e a d *//* *//* Reads absolute sectors by sector no. *//* *//* Parameters: *//* irHandle : Drive number (0, 1, ...) *//* irData : Address of user buffer to read into *//* irSectorNo : First sector no. to read (sector 0 is the *//* DOS boot sector). *//* irSectorCount : Number of consectutive sectors to read *//* *//* Returns: *//* FLStatus : 0 on success, otherwise failed *//* irSectorCount : Number of sectors actually read *//*----------------------------------------------------------------------*/static FLStatus absRead(Volume vol, IOreq FAR2 *ioreq){ char FAR1 *userBuffer = (char FAR1 *) ioreq->irData; SectorNo currSector = (vol.bootSectorNo + flFileSysSectorStart) + ioreq->irSectorNo; /* protect tffs at sector 0 */ unsigned sectorCount = ioreq->irSectorCount; for(ioreq->irSectorCount = 0; ioreq->irSectorCount < sectorCount; ioreq->irSectorCount++, currSector++, userBuffer += SECTOR_SIZE) { const void FAR0 *mappedSector = findSector(&vol,currSector); if(mappedSector) tffscpy(userBuffer,mappedSector,SECTOR_SIZE); else tffsset(userBuffer,0,SECTOR_SIZE); } return flOK;}/*----------------------------------------------------------------------*//* r e p l a c e F A T s e c t o r *//* *//* Monitors sector deletions in the FAT. *//* *//* When a FAT block is about to be written by an absolute write, this *//* routine will first scan whether any sectors are being logically *//* deleted by this FAT update, and if so, it will delete-sector them *//* before the actual FAT update takes place. *//* *//* Parameters: *//* vol : Pointer identifying drive *//* sectorNo : FAT Sector no. about to be written *//* newFATsector : Address of FAT sector about to be written *//* *//* Returns: *//* FLStatus : 0 on success, otherwise failed *//*----------------------------------------------------------------------*/FLStatus replaceFATsector(Volume vol, SectorNo sectorNo, const char FAR1 *newFATsector){ const char FAR0 *oldFATsector = (const char FAR0 *) findSector(&vol,sectorNo);#ifdef FAT_12BIT unsigned FAThalfBytes = vol.flags & VOLUME_12BIT_FAT ? 3 : 4; unsigned firstCluster = (FAThalfBytes == 3) ? (((unsigned) (sectorNo - vol.firstFATSectorNo) * (2 * SECTOR_SIZE) + 2) / 3) : ((unsigned) (sectorNo - vol.firstFATSectorNo) * (SECTOR_SIZE / 2)); SectorNo firstSector = ((SectorNo) firstCluster - 2) * vol.sectorsPerCluster + vol.firstDataSectorNo; unsigned int halfByteOffset = (firstCluster * FAThalfBytes) & (2 * SECTOR_SIZE - 1); if(oldFATsector == NULL) return flOK; /* Find if any clusters were logically deleted, and if so, delete them */ /* NOTE: We are skipping over 12-bit FAT entries which span more than */ /* one sector. Nobody's perfect anyway. */ for(; halfByteOffset < (2 * SECTOR_SIZE - 2); firstSector += vol.sectorsPerCluster, halfByteOffset += FAThalfBytes) { unsigned short oldFATentry, newFATentry;#ifdef TFFS_BIG_ENDIAN oldFATentry = LE2(*(LEushort FAR0 *)(oldFATsector + (halfByteOffset / 2))); newFATentry = LE2(*(LEushort FAR1 *)(newFATsector + (halfByteOffset / 2)));#else oldFATentry = UNAL2(*(Unaligned FAR0 *)(oldFATsector + (halfByteOffset / 2))); newFATentry = UNAL2(*(Unaligned FAR1 *)(newFATsector + (halfByteOffset / 2)));#endif if(halfByteOffset & 1) { oldFATentry >>= 4; newFATentry >>= 4; } else if(FAThalfBytes == 3) { oldFATentry &= 0xfff; newFATentry &= 0xfff; }#else /* FAT_12BIT */ unsigned firstCluster = ((unsigned) (sectorNo - vol.firstFATSectorNo) * (SECTOR_SIZE / 2)); SectorNo firstSector = ((SectorNo) firstCluster - 2) * vol.sectorsPerCluster + vol.firstDataSectorNo; unsigned int byteOffset; if(oldFATsector == NULL) return flOK; /* Find if any clusters were logically deleted, and if so, delete them */ for(byteOffset = 0; byteOffset < SECTOR_SIZE; firstSector += vol.sectorsPerCluster, byteOffset += 2) { unsigned short oldFATentry = LE2(*(LEushort FAR0 *)(oldFATsector + byteOffset)); unsigned short newFATentry = LE2(*(LEushort FAR1 *)(newFATsector + byteOffset));#endif if(oldFATentry != FAT_FREE && newFATentry == FAT_FREE) checkStatus(vol.tl.deleteSector(vol.tl.rec,firstSector,vol.sectorsPerCluster)); /* make sure sector is still there */ oldFATsector = (const char FAR0 *) findSector(&vol,sectorNo); } return flOK;}/*----------------------------------------------------------------------*//* d i s a b l e F A T m o n i t o r *//* *//* Turns off FAT monitor. *//* *//* Parameters: *//* vol : Pointer identifying drive *//* *//* Returns: *//* always flOK *//*----------------------------------------------------------------------*/static FLStatus disableFATmonitor(Volume vol){ vol.firstFATSectorNo = vol.secondFATSectorNo = 0; /* Disable FAT monitoring */ return flOK;}/*----------------------------------------------------------------------*//* a b s W r i t e *//* *//* Writes absolute sectors by sector no. *//* *//* Parameters: *//* irHandle : Drive number (0, 1, ...) *//* irData : Address of user buffer to write from *//* irSectorNo : First sector no. to write (sector 0 is the *//* DOS boot sector). *//* irSectorCount : Number of consectutive sectors to write *//* *//* Returns: *//* FLStatus : 0 on success, otherwise failed *//* irSectorCount : Number of sectors actually written *//*----------------------------------------------------------------------*/static FLStatus absWrite(Volume vol, IOreq FAR2 *ioreq){ char FAR1 *userBuffer = (char FAR1 *) ioreq->irData; SectorNo currSector = (vol.bootSectorNo + flFileSysSectorStart) + ioreq->irSectorNo; /* protect tffs at sector 0 */ unsigned sectorCount = ioreq->irSectorCount; if(currSector < vol.secondFATSectorNo && currSector + sectorCount > vol.firstFATSectorNo) { unsigned iSector; for(iSector = 0; iSector < sectorCount; iSector++, currSector++, userBuffer += SECTOR_SIZE) { if(currSector >= vol.firstFATSectorNo && currSector < vol.secondFATSectorNo) replaceFATsector(&vol,currSector,userBuffer); } userBuffer = (char FAR1 *) ioreq->irData; currSector = (vol.bootSectorNo + flFileSysSectorStart) + ioreq->irSectorNo; /* protect tffs at sector 0*/ } for(ioreq->irSectorCount = 0; ioreq->irSectorCount < sectorCount; ioreq->irSectorCount++, currSector++, userBuffer += SECTOR_SIZE) { checkStatus(vol.tl.writeSector(vol.tl.rec,currSector,userBuffer)); } return flOK;}
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -