mirror of
https://github.com/rvtr/GodMode9i.git
synced 2025-11-02 00:11:07 -04:00
Update fat.c
This commit is contained in:
parent
c96b8e1855
commit
4cabc9d09f
@ -75,12 +75,9 @@ License:
|
||||
|
||||
#define __PACKED __attribute__ ((__packed__))
|
||||
|
||||
// Boot Sector - must be packed
|
||||
typedef struct
|
||||
{
|
||||
u8 jmpBoot[3];
|
||||
u8 OEMName[8];
|
||||
// BIOS Parameter Block
|
||||
// BIOS Parameter Block
|
||||
typedef struct {
|
||||
|
||||
u16 bytesPerSector;
|
||||
u8 sectorsPerCluster;
|
||||
u16 reservedSectors;
|
||||
@ -93,6 +90,14 @@ typedef struct
|
||||
u16 numHeads;
|
||||
u32 numHiddenSectors;
|
||||
u32 numSectors;
|
||||
} __PACKED BIOS_BPB;
|
||||
|
||||
// Boot Sector - must be packed
|
||||
typedef struct
|
||||
{
|
||||
u8 jmpBoot[3];
|
||||
u8 OEMName[8];
|
||||
BIOS_BPB bpb;
|
||||
union // Different types of extended BIOS Parameter Block for FAT16 and FAT32
|
||||
{
|
||||
struct
|
||||
@ -106,7 +111,7 @@ typedef struct
|
||||
u8 fileSysType[8];
|
||||
// Bootcode
|
||||
u8 bootCode[448];
|
||||
} fat16;
|
||||
} __PACKED fat16;
|
||||
struct
|
||||
{
|
||||
// FAT32 extended block
|
||||
@ -126,13 +131,15 @@ typedef struct
|
||||
u8 fileSysType[8];
|
||||
// Bootcode
|
||||
u8 bootCode[420];
|
||||
} fat32;
|
||||
} extBlock;
|
||||
} __PACKED fat32;
|
||||
} __PACKED extBlock;
|
||||
|
||||
__PACKED u16 bootSig;
|
||||
|
||||
} __PACKED BOOT_SEC;
|
||||
|
||||
_Static_assert(sizeof(BOOT_SEC) == 512);
|
||||
|
||||
// Directory entry - must be packed
|
||||
typedef struct
|
||||
{
|
||||
@ -251,8 +258,7 @@ u32 FAT_NextCluster(u32 cluster)
|
||||
// read the nextCluster value
|
||||
nextCluster = ((u16*)globalBuffer)[offset];
|
||||
|
||||
if (nextCluster >= 0xFFF7)
|
||||
{
|
||||
if (nextCluster >= 0xFFF7) {
|
||||
nextCluster = CLUSTER_EOF;
|
||||
}
|
||||
break;
|
||||
@ -265,8 +271,7 @@ u32 FAT_NextCluster(u32 cluster)
|
||||
// read the nextCluster value
|
||||
nextCluster = (((u32*)globalBuffer)[offset]) & 0x0FFFFFFF;
|
||||
|
||||
if (nextCluster >= 0x0FFFFFF7)
|
||||
{
|
||||
if (nextCluster >= 0x0FFFFFF7) {
|
||||
nextCluster = CLUSTER_EOF;
|
||||
}
|
||||
break;
|
||||
@ -304,8 +309,7 @@ bool FAT_InitFiles (bool initCard)
|
||||
int bootSector;
|
||||
BOOT_SEC* bootSec;
|
||||
|
||||
if (initCard && !CARD_StartUp())
|
||||
{
|
||||
if (initCard && !CARD_StartUp()) {
|
||||
return (false);
|
||||
}
|
||||
|
||||
@ -314,17 +318,10 @@ bool FAT_InitFiles (bool initCard)
|
||||
{
|
||||
return false;
|
||||
}
|
||||
// Check if there is a FAT string, which indicates this is a boot sector
|
||||
if ((globalBuffer[0x36] == 'F') && (globalBuffer[0x37] == 'A') && (globalBuffer[0x38] == 'T'))
|
||||
{
|
||||
if (((globalBuffer[0x36] == 'F') && (globalBuffer[0x37] == 'A') && (globalBuffer[0x38] == 'T')) // Check if there is a FAT string, which indicates this is a boot sector
|
||||
|| ((globalBuffer[0x52] == 'F') && (globalBuffer[0x53] == 'A') && (globalBuffer[0x54] == 'T'))) { // Check for FAT32
|
||||
bootSector = 0;
|
||||
}
|
||||
// Check for FAT32
|
||||
else if ((globalBuffer[0x52] == 'F') && (globalBuffer[0x53] == 'A') && (globalBuffer[0x54] == 'T'))
|
||||
{
|
||||
bootSector = 0;
|
||||
}
|
||||
else // This is an MBR
|
||||
} else // This is an MBR
|
||||
{
|
||||
// Find first valid partition from MBR
|
||||
// First check for an active partition
|
||||
@ -334,7 +331,7 @@ bool FAT_InitFiles (bool initCard)
|
||||
for (i=0x1BE; (i < 0x1FE) && (globalBuffer[i+0x04] == 0x00); i+= 0x10);
|
||||
|
||||
// Go to first valid partition
|
||||
if ( i != 0x1FE) // Make sure it found a partition
|
||||
if (i != 0x1FE) // Make sure it found a partition
|
||||
{
|
||||
bootSector = globalBuffer[0x8 + i] + (globalBuffer[0x9 + i] << 8) + (globalBuffer[0xA + i] << 16) + ((globalBuffer[0xB + i] << 24) & 0x0F);
|
||||
} else {
|
||||
@ -347,55 +344,41 @@ bool FAT_InitFiles (bool initCard)
|
||||
CARD_ReadSector (bootSector, bootSec);
|
||||
|
||||
// Store required information about the file system
|
||||
if (bootSec->sectorsPerFAT != 0)
|
||||
{
|
||||
discSecPerFAT = bootSec->sectorsPerFAT;
|
||||
}
|
||||
else
|
||||
{
|
||||
if (bootSec->bpb.sectorsPerFAT != 0) {
|
||||
discSecPerFAT = bootSec->bpb.sectorsPerFAT;
|
||||
} else {
|
||||
discSecPerFAT = bootSec->extBlock.fat32.sectorsPerFAT32;
|
||||
}
|
||||
|
||||
if (bootSec->numSectorsSmall != 0)
|
||||
{
|
||||
discNumSec = bootSec->numSectorsSmall;
|
||||
}
|
||||
else
|
||||
{
|
||||
discNumSec = bootSec->numSectors;
|
||||
if (bootSec->bpb.numSectorsSmall != 0) {
|
||||
discNumSec = bootSec->bpb.numSectorsSmall;
|
||||
} else {
|
||||
discNumSec = bootSec->bpb.numSectors;
|
||||
}
|
||||
|
||||
discBytePerSec = BYTES_PER_SECTOR; // Sector size is redefined to be 512 bytes
|
||||
discSecPerClus = bootSec->sectorsPerCluster * bootSec->bytesPerSector / BYTES_PER_SECTOR;
|
||||
discSecPerClus = bootSec->bpb.sectorsPerCluster * bootSec->bpb.bytesPerSector / BYTES_PER_SECTOR;
|
||||
discBytePerClus = discBytePerSec * discSecPerClus;
|
||||
discFAT = bootSector + bootSec->reservedSectors;
|
||||
discFAT = bootSector + bootSec->bpb.reservedSectors;
|
||||
|
||||
discRootDir = discFAT + (bootSec->numFATs * discSecPerFAT);
|
||||
discData = discRootDir + ((bootSec->rootEntries * sizeof(DIR_ENT)) / BYTES_PER_SECTOR);
|
||||
discRootDir = discFAT + (bootSec->bpb.numFATs * discSecPerFAT);
|
||||
discData = discRootDir + ((bootSec->bpb.rootEntries * sizeof(DIR_ENT)) / BYTES_PER_SECTOR);
|
||||
|
||||
if ((discNumSec - discData) / bootSec->sectorsPerCluster < 4085)
|
||||
{
|
||||
if ((discNumSec - discData) / bootSec->bpb.sectorsPerCluster < 4085) {
|
||||
discFileSystem = FS_FAT12;
|
||||
}
|
||||
else if ((discNumSec - discData) / bootSec->sectorsPerCluster < 65525)
|
||||
{
|
||||
} else if ((discNumSec - discData) / bootSec->bpb.sectorsPerCluster < 65525) {
|
||||
discFileSystem = FS_FAT16;
|
||||
}
|
||||
else
|
||||
{
|
||||
} else {
|
||||
discFileSystem = FS_FAT32;
|
||||
}
|
||||
|
||||
if (discFileSystem != FS_FAT32)
|
||||
{
|
||||
if (discFileSystem != FS_FAT32) {
|
||||
discRootDirClus = FAT16_ROOT_DIR_CLUSTER;
|
||||
}
|
||||
else // Set up for the FAT32 way
|
||||
} else // Set up for the FAT32 way
|
||||
{
|
||||
discRootDirClus = bootSec->extBlock.fat32.rootClus;
|
||||
// Check if FAT mirroring is enabled
|
||||
if (!(bootSec->extBlock.fat32.extFlags & 0x80))
|
||||
{
|
||||
if (!(bootSec->extBlock.fat32.extFlags & 0x80)) {
|
||||
// Use the active FAT
|
||||
discFAT = discFAT + ( discSecPerFAT * (bootSec->extBlock.fat32.extFlags & 0x0F));
|
||||
}
|
||||
@ -425,8 +408,7 @@ u32 getBootFileCluster (const char* bootName)
|
||||
|
||||
|
||||
// Check if fat has been initialised
|
||||
if (discBytePerSec == 0)
|
||||
{
|
||||
if (discBytePerSec == 0) {
|
||||
return (CLUSTER_FREE);
|
||||
}
|
||||
|
||||
@ -443,52 +425,42 @@ u32 getBootFileCluster (const char* bootName)
|
||||
wrkDirOffset = -1; // Start at entry zero, Compensating for increment
|
||||
while (!found && !notFound) {
|
||||
wrkDirOffset++;
|
||||
if (wrkDirOffset == BYTES_PER_SECTOR / sizeof (DIR_ENT))
|
||||
{
|
||||
if (wrkDirOffset == BYTES_PER_SECTOR / sizeof (DIR_ENT)) {
|
||||
wrkDirOffset = 0;
|
||||
wrkDirSector++;
|
||||
if ((wrkDirSector == discSecPerClus) && (wrkDirCluster != FAT16_ROOT_DIR_CLUSTER))
|
||||
{
|
||||
if ((wrkDirSector == discSecPerClus) && (wrkDirCluster != FAT16_ROOT_DIR_CLUSTER)) {
|
||||
wrkDirSector = 0;
|
||||
wrkDirCluster = FAT_NextCluster(wrkDirCluster);
|
||||
if (wrkDirCluster == CLUSTER_EOF)
|
||||
{
|
||||
if (wrkDirCluster == CLUSTER_EOF) {
|
||||
notFound = true;
|
||||
}
|
||||
firstSector = FAT_ClustToSect(wrkDirCluster);
|
||||
}
|
||||
else if ((wrkDirCluster == FAT16_ROOT_DIR_CLUSTER) && (wrkDirSector == (discData - discRootDir)))
|
||||
{
|
||||
} else if ((wrkDirCluster == FAT16_ROOT_DIR_CLUSTER) && (wrkDirSector == (discData - discRootDir))) {
|
||||
notFound = true; // Got to end of root dir
|
||||
}
|
||||
CARD_ReadSector (firstSector + wrkDirSector, globalBuffer);
|
||||
}
|
||||
dir = ((DIR_ENT*) globalBuffer)[wrkDirOffset];
|
||||
found = true;
|
||||
if ((dir.attrib & ATTRIB_DIR) || (dir.attrib & ATTRIB_VOL))
|
||||
{
|
||||
if ((dir.attrib & ATTRIB_DIR) || (dir.attrib & ATTRIB_VOL)) {
|
||||
found = false;
|
||||
}
|
||||
if(namelen<8 && dir.name[namelen]!=0x20) found = false;
|
||||
for (nameOffset = 0; nameOffset < namelen && found; nameOffset++)
|
||||
{
|
||||
if (namelen<8 && dir.name[namelen]!=0x20) found = false;
|
||||
for (nameOffset = 0; nameOffset < namelen && found; nameOffset++) {
|
||||
if (ucase(dir.name[nameOffset]) != bootName[nameOffset])
|
||||
found = false;
|
||||
}
|
||||
for (nameOffset = 0; nameOffset < 3 && found; nameOffset++)
|
||||
{
|
||||
for (nameOffset = 0; nameOffset < 3 && found; nameOffset++) {
|
||||
if (ucase(dir.ext[nameOffset]) != bootName[nameOffset+namelen+1])
|
||||
found = false;
|
||||
}
|
||||
if (dir.name[0] == FILE_LAST)
|
||||
{
|
||||
if (dir.name[0] == FILE_LAST) {
|
||||
notFound = true;
|
||||
}
|
||||
}
|
||||
|
||||
// If no file is found, return CLUSTER_FREE
|
||||
if (notFound)
|
||||
{
|
||||
if (notFound) {
|
||||
return CLUSTER_FREE;
|
||||
}
|
||||
|
||||
@ -513,8 +485,7 @@ u32 fileRead (char* buffer, u32 cluster, u32 startOffset, u32 length)
|
||||
}
|
||||
|
||||
// Follow cluster list until desired one is found
|
||||
for (chunks = startOffset / discBytePerClus; chunks > 0; chunks--)
|
||||
{
|
||||
for (chunks = startOffset / discBytePerClus; chunks > 0; chunks--) {
|
||||
cluster = FAT_NextCluster (cluster);
|
||||
}
|
||||
|
||||
@ -524,33 +495,30 @@ u32 fileRead (char* buffer, u32 cluster, u32 startOffset, u32 length)
|
||||
curByte = startOffset % BYTES_PER_SECTOR;
|
||||
|
||||
// Load sector buffer for new position in file
|
||||
CARD_ReadSector( curSect + FAT_ClustToSect(cluster), globalBuffer);
|
||||
CARD_ReadSector(curSect + FAT_ClustToSect(cluster), globalBuffer);
|
||||
curSect++;
|
||||
|
||||
// Number of bytes needed to read to align with a sector
|
||||
beginBytes = (BYTES_PER_SECTOR < length + curByte ? (BYTES_PER_SECTOR - curByte) : length);
|
||||
|
||||
// Read first part from buffer, to align with sector boundary
|
||||
for (dataPos = 0 ; dataPos < beginBytes; dataPos++)
|
||||
{
|
||||
for (dataPos = 0 ; dataPos < beginBytes; dataPos++) {
|
||||
buffer[dataPos] = globalBuffer[curByte++];
|
||||
}
|
||||
|
||||
// Read in all the 512 byte chunks of the file directly, saving time
|
||||
for ( chunks = ((int)length - beginBytes) / BYTES_PER_SECTOR; chunks > 0;)
|
||||
{
|
||||
for (chunks = ((int)length - beginBytes) / BYTES_PER_SECTOR; chunks > 0;) {
|
||||
int sectorsToRead;
|
||||
|
||||
// Move to the next cluster if necessary
|
||||
if (curSect >= discSecPerClus)
|
||||
{
|
||||
if (curSect >= discSecPerClus) {
|
||||
curSect = 0;
|
||||
cluster = FAT_NextCluster (cluster);
|
||||
}
|
||||
|
||||
// Calculate how many sectors to read (read a maximum of discSecPerClus at a time)
|
||||
sectorsToRead = discSecPerClus - curSect;
|
||||
if(chunks < sectorsToRead)
|
||||
if (chunks < sectorsToRead)
|
||||
sectorsToRead = chunks;
|
||||
|
||||
// Read the sectors
|
||||
@ -561,21 +529,18 @@ u32 fileRead (char* buffer, u32 cluster, u32 startOffset, u32 length)
|
||||
}
|
||||
|
||||
// Take care of any bytes left over before end of read
|
||||
if (dataPos < length)
|
||||
{
|
||||
if (dataPos < length) {
|
||||
|
||||
// Update the read buffer
|
||||
curByte = 0;
|
||||
if (curSect >= discSecPerClus)
|
||||
{
|
||||
if (curSect >= discSecPerClus) {
|
||||
curSect = 0;
|
||||
cluster = FAT_NextCluster (cluster);
|
||||
}
|
||||
CARD_ReadSector( curSect + FAT_ClustToSect( cluster), globalBuffer);
|
||||
CARD_ReadSector(curSect + FAT_ClustToSect(cluster), globalBuffer);
|
||||
|
||||
// Read in last partial chunk
|
||||
for (; dataPos < length; dataPos++)
|
||||
{
|
||||
for (; dataPos < length; dataPos++) {
|
||||
buffer[dataPos] = globalBuffer[curByte];
|
||||
curByte++;
|
||||
}
|
||||
|
||||
Loading…
Reference in New Issue
Block a user