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