*Added support for starting .wbfs game files from fat32/ntfs partitions on a sector size > 512 (tested with 4096)

*modified libcustomfat and ntfs fragment fetch function to support >512 bytes per sector
*Added new ehcmodule (thanks rodries)
*Added real support of using both ports simultaniously without shutting down the other (thanks rodries for the ehcmodule works on this). There is no longer the limitation that the settings have to be on SD card for this. (ONLY HERMES CIOS)
*Moved a few settings to Feature Settings and added a new Hard Drive Settings
*Changed Wiinnertag path to only point to the path and not to the file. You must correct the path manually in custom path settings or reset you configs for this change or Winnertag won't work!!
*Removed a few compile warnings for devkitPPC R23
This commit is contained in:
dimok321 2011-06-22 17:57:37 +00:00
parent d657e03e5f
commit f6c9003574
11 changed files with 267 additions and 5756 deletions

View File

@ -46,7 +46,7 @@
#define CACHE_FREE UINT_MAX
CACHE* _FAT_cache_constructor (unsigned int numberOfPages, unsigned int sectorsPerPage, const DISC_INTERFACE* discInterface, sec_t endOfPartition) {
CACHE* _FAT_cache_constructor (unsigned int numberOfPages, unsigned int sectorsPerPage, const DISC_INTERFACE* discInterface, sec_t endOfPartition, unsigned int bytesPerSector) {
CACHE* cache;
unsigned int i;
CACHE_ENTRY* cacheEntries;
@ -68,6 +68,7 @@ CACHE* _FAT_cache_constructor (unsigned int numberOfPages, unsigned int sectorsP
cache->endOfPartition = endOfPartition;
cache->numberOfPages = numberOfPages;
cache->sectorsPerPage = sectorsPerPage;
cache->bytesPerSector = bytesPerSector;
cacheEntries = (CACHE_ENTRY*) _FAT_mem_allocate ( sizeof(CACHE_ENTRY) * numberOfPages);
@ -81,7 +82,7 @@ CACHE* _FAT_cache_constructor (unsigned int numberOfPages, unsigned int sectorsP
cacheEntries[i].count = 0;
cacheEntries[i].last_access = 0;
cacheEntries[i].dirty = false;
cacheEntries[i].cache = (uint8_t*) _FAT_mem_align ( sectorsPerPage * BYTES_PER_READ );
cacheEntries[i].cache = (uint8_t*) _FAT_mem_align ( sectorsPerPage * bytesPerSector );
}
cache->cacheEntries = cacheEntries;
@ -168,9 +169,9 @@ bool _FAT_cache_readSectors(CACHE *cache,sec_t sector,sec_t numSectors,void *buf
secs_to_read = entry->count - sec;
if(secs_to_read>numSectors) secs_to_read = numSectors;
memcpy(dest,entry->cache + (sec*BYTES_PER_READ),(secs_to_read*BYTES_PER_READ));
memcpy(dest,entry->cache + (sec*cache->bytesPerSector),(secs_to_read*cache->bytesPerSector));
dest += (secs_to_read*BYTES_PER_READ);
dest += (secs_to_read*cache->bytesPerSector);
sector += secs_to_read;
numSectors -= secs_to_read;
}
@ -186,13 +187,13 @@ bool _FAT_cache_readPartialSector (CACHE* cache, void* buffer, sec_t sector, uns
sec_t sec;
CACHE_ENTRY *entry;
if (offset + size > BYTES_PER_READ) return false;
if (offset + size > cache->bytesPerSector) return false;
entry = _FAT_cache_getPage(cache,sector);
if(entry==NULL) return false;
sec = sector - entry->sector;
memcpy(buffer,entry->cache + ((sec*BYTES_PER_READ) + offset),size);
memcpy(buffer,entry->cache + ((sec*cache->bytesPerSector) + offset),size);
return true;
}
@ -218,13 +219,13 @@ bool _FAT_cache_writePartialSector (CACHE* cache, const void* buffer, sec_t sect
sec_t sec;
CACHE_ENTRY *entry;
if (offset + size > BYTES_PER_READ) return false;
if (offset + size > cache->bytesPerSector) return false;
entry = _FAT_cache_getPage(cache,sector);
if(entry==NULL) return false;
sec = sector - entry->sector;
memcpy(entry->cache + ((sec*BYTES_PER_READ) + offset),buffer,size);
memcpy(entry->cache + ((sec*cache->bytesPerSector) + offset),buffer,size);
entry->dirty = true;
return true;
@ -251,14 +252,14 @@ bool _FAT_cache_eraseWritePartialSector (CACHE* cache, const void* buffer, sec_t
sec_t sec;
CACHE_ENTRY *entry;
if (offset + size > BYTES_PER_READ) return false;
if (offset + size > cache->bytesPerSector) return false;
entry = _FAT_cache_getPage(cache,sector);
if(entry==NULL) return false;
sec = sector - entry->sector;
memset(entry->cache + (sec*BYTES_PER_READ),0,BYTES_PER_READ);
memcpy(entry->cache + ((sec*BYTES_PER_READ) + offset),buffer,size);
memset(entry->cache + (sec*cache->bytesPerSector),0,cache->bytesPerSector);
memcpy(entry->cache + ((sec*cache->bytesPerSector) + offset),buffer,size);
entry->dirty = true;
return true;
@ -281,9 +282,9 @@ bool _FAT_cache_writeSectors (CACHE* cache, sec_t sector, sec_t numSectors, cons
secs_to_write = entry->count - sec;
if(secs_to_write>numSectors) secs_to_write = numSectors;
memcpy(entry->cache + (sec*BYTES_PER_READ),src,(secs_to_write*BYTES_PER_READ));
memcpy(entry->cache + (sec*cache->bytesPerSector),src,(secs_to_write*cache->bytesPerSector));
src += (secs_to_write*BYTES_PER_READ);
src += (secs_to_write*cache->bytesPerSector);
sector += secs_to_write;
numSectors -= secs_to_write;

View File

@ -39,9 +39,6 @@
#include "common.h"
#include "disc.h"
#define PAGE_SECTORS 64
#define CACHE_PAGE_SIZE (BYTES_PER_READ * PAGE_SECTORS)
typedef struct {
sec_t sector;
unsigned int count;
@ -55,6 +52,7 @@ typedef struct {
sec_t endOfPartition;
unsigned int numberOfPages;
unsigned int sectorsPerPage;
unsigned int bytesPerSector;
CACHE_ENTRY* cacheEntries;
} CACHE;
@ -100,14 +98,14 @@ bool _FAT_cache_readSectors (CACHE* cache, sec_t sector, sec_t numSectors, void*
Read a full sector from the cache
*/
static inline bool _FAT_cache_readSector (CACHE* cache, void* buffer, sec_t sector) {
return _FAT_cache_readPartialSector (cache, buffer, sector, 0, BYTES_PER_READ);
return _FAT_cache_readPartialSector (cache, buffer, sector, 0, cache->bytesPerSector);
}
/*
Write a full sector to the cache
*/
static inline bool _FAT_cache_writeSector (CACHE* cache, const void* buffer, sec_t sector) {
return _FAT_cache_writePartialSector (cache, buffer, sector, 0, BYTES_PER_READ);
return _FAT_cache_writePartialSector (cache, buffer, sector, 0, cache->bytesPerSector);
}
bool _FAT_cache_writeSectors (CACHE* cache, sec_t sector, sec_t numSectors, const void* buffer);
@ -122,7 +120,7 @@ Clear out the contents of the cache without writing any dirty sectors first
*/
void _FAT_cache_invalidate (CACHE* cache);
CACHE* _FAT_cache_constructor (unsigned int numberOfPages, unsigned int sectorsPerPage, const DISC_INTERFACE* discInterface, sec_t endOfPartition);
CACHE* _FAT_cache_constructor (unsigned int numberOfPages, unsigned int sectorsPerPage, const DISC_INTERFACE* discInterface, sec_t endOfPartition, unsigned int bytesPerSector);
void _FAT_cache_destructor (CACHE* cache);

View File

@ -29,7 +29,6 @@
#ifndef _COMMON_H
#define _COMMON_H
#define BYTES_PER_READ 512
#include <fat.h>
#include <stddef.h>
#include <stdint.h>

View File

@ -251,7 +251,7 @@ static bool _FAT_directory_incrementDirEntryPosition (PARTITION* partition, DIR_
// Increment offset, wrapping at the end of a sector
++ position.offset;
if (position.offset == BYTES_PER_READ / DIR_ENTRY_DATA_SIZE) {
if (position.offset == partition->bytesPerSector / DIR_ENTRY_DATA_SIZE) {
position.offset = 0;
// Increment sector when wrapping
++ position.sector;
@ -1113,8 +1113,8 @@ void _FAT_directory_entryStat (PARTITION* partition, DIR_ENTRY* entry, struct st
u8array_to_u16 (entry->entryData, DIR_ENTRY_cDate)
);
st->st_spare3 = 0;
st->st_blksize = BYTES_PER_READ; // Prefered file I/O block size
st->st_blocks = (st->st_size + BYTES_PER_READ - 1) / BYTES_PER_READ; // File size in blocks
st->st_blksize = partition->bytesPerSector; // Prefered file I/O block size
st->st_blocks = (st->st_size + partition->bytesPerSector - 1) / partition->bytesPerSector; // File size in blocks
st->st_spare4[0] = 0;
st->st_spare4[1] = 0;
}

View File

@ -54,6 +54,7 @@ static const DISC_INTERFACE* get_io_usbstorage (void) {
static const DISC_INTERFACE* get_io_gcsda (void) {
return &__io_gcsda;
}
static const DISC_INTERFACE* get_io_gcsdb (void) {
return &__io_gcsdb;
}
@ -87,7 +88,12 @@ const INTERFACE_ID _FAT_disc_interfaces[] = {
#elif defined (NDS)
#include <nds/arm9/dldi.h>
static const DISC_INTERFACE* get_io_dsisd (void) {
return &__io_dsisd;
}
const INTERFACE_ID _FAT_disc_interfaces[] = {
{"sd", get_io_dsisd},
{"fat", dldiGetInternal},
{NULL, NULL}
};

View File

@ -216,8 +216,8 @@ int _FAT_open_r (struct _reent *r, void *fileStruct, const char *path, int flags
// Set append pointer to the end of the file
file->appendPosition.cluster = _FAT_fat_lastCluster (partition, file->startCluster);
file->appendPosition.sector = (file->filesize % partition->bytesPerCluster) / BYTES_PER_READ;
file->appendPosition.byte = file->filesize % BYTES_PER_READ;
file->appendPosition.sector = (file->filesize % partition->bytesPerCluster) / partition->bytesPerSector;
file->appendPosition.byte = file->filesize % partition->bytesPerSector;
// Check if the end of the file is on the end of a cluster
if ( (file->filesize > 0) && ((file->filesize % partition->bytesPerCluster)==0) ){
@ -381,12 +381,12 @@ ssize_t _FAT_read_r (struct _reent *r, int fd, char *ptr, size_t len) {
cache = file->partition->cache;
// Align to sector
tempVar = BYTES_PER_READ - position.byte;
tempVar = partition->bytesPerSector - position.byte;
if (tempVar > remain) {
tempVar = remain;
}
if ((tempVar < BYTES_PER_READ) && flagNoError)
if ((tempVar < partition->bytesPerSector) && flagNoError)
{
_FAT_cache_readPartialSector ( cache, ptr, _FAT_fat_clusterToSector (partition, position.cluster) + position.sector,
position.byte, tempVar);
@ -395,7 +395,7 @@ ssize_t _FAT_read_r (struct _reent *r, int fd, char *ptr, size_t len) {
ptr += tempVar;
position.byte += tempVar;
if (position.byte >= BYTES_PER_READ) {
if (position.byte >= partition->bytesPerSector) {
position.byte = 0;
position.sector++;
}
@ -403,10 +403,10 @@ ssize_t _FAT_read_r (struct _reent *r, int fd, char *ptr, size_t len) {
// align to cluster
// tempVar is number of sectors to read
if (remain > (partition->sectorsPerCluster - position.sector) * BYTES_PER_READ) {
if (remain > (partition->sectorsPerCluster - position.sector) * partition->bytesPerSector) {
tempVar = partition->sectorsPerCluster - position.sector;
} else {
tempVar = remain / BYTES_PER_READ;
tempVar = remain / partition->bytesPerSector;
}
if ((tempVar > 0) && flagNoError) {
@ -416,8 +416,8 @@ ssize_t _FAT_read_r (struct _reent *r, int fd, char *ptr, size_t len) {
flagNoError = false;
r->_errno = EIO;
} else {
ptr += tempVar * BYTES_PER_READ;
remain -= tempVar * BYTES_PER_READ;
ptr += tempVar * partition->bytesPerSector;
remain -= tempVar * partition->bytesPerSector;
position.sector += tempVar;
}
}
@ -449,12 +449,12 @@ ssize_t _FAT_read_r (struct _reent *r, int fd, char *ptr, size_t len) {
chunkSize += partition->bytesPerCluster;
} while ((nextChunkStart == chunkEnd + 1) &&
#ifdef LIMIT_SECTORS
(chunkSize + partition->bytesPerCluster <= LIMIT_SECTORS * BYTES_PER_READ) &&
(chunkSize + partition->bytesPerCluster <= LIMIT_SECTORS * partition->bytesPerSector) &&
#endif
(chunkSize + partition->bytesPerCluster <= remain));
if (!_FAT_cache_readSectors (cache, _FAT_fat_clusterToSector (partition, position.cluster),
chunkSize / BYTES_PER_READ, ptr))
chunkSize / partition->bytesPerSector, ptr))
{
flagNoError = false;
r->_errno = EIO;
@ -477,7 +477,7 @@ ssize_t _FAT_read_r (struct _reent *r, int fd, char *ptr, size_t len) {
}
// Read remaining sectors
tempVar = remain / BYTES_PER_READ; // Number of sectors left
tempVar = remain / partition->bytesPerSector; // Number of sectors left
if ((tempVar > 0) && flagNoError) {
if (!_FAT_cache_readSectors (cache, _FAT_fat_clusterToSector (partition, position.cluster),
tempVar, ptr))
@ -485,8 +485,8 @@ ssize_t _FAT_read_r (struct _reent *r, int fd, char *ptr, size_t len) {
flagNoError = false;
r->_errno = EIO;
} else {
ptr += tempVar * BYTES_PER_READ;
remain -= tempVar * BYTES_PER_READ;
ptr += tempVar * partition->bytesPerSector;
remain -= tempVar * partition->bytesPerSector;
position.sector += tempVar;
}
}
@ -555,13 +555,14 @@ static bool _FAT_file_extend_r (struct _reent *r, FILE_STRUCT* file) {
PARTITION* partition = file->partition;
CACHE* cache = file->partition->cache;
FILE_POSITION position;
uint8_t zeroBuffer [BYTES_PER_READ] = {0};
uint8_t zeroBuffer [partition->bytesPerSector];
memset(zeroBuffer, 0, partition->bytesPerSector);
uint32_t remain;
uint32_t tempNextCluster;
unsigned int sector;
position.byte = file->filesize % BYTES_PER_READ;
position.sector = (file->filesize % partition->bytesPerCluster) / BYTES_PER_READ;
position.byte = file->filesize % partition->bytesPerSector;
position.sector = (file->filesize % partition->bytesPerCluster) / partition->bytesPerSector;
// It is assumed that there is always a startCluster
// This will be true when _FAT_file_extend_r is called from _FAT_write_r
position.cluster = _FAT_fat_lastCluster (partition, file->startCluster);
@ -580,7 +581,7 @@ static bool _FAT_file_extend_r (struct _reent *r, FILE_STRUCT* file) {
position.sector = 0;
}
if (remain + position.byte < BYTES_PER_READ) {
if (remain + position.byte < partition->bytesPerSector) {
// Only need to clear to the end of the sector
_FAT_cache_writePartialSector (cache, zeroBuffer,
_FAT_fat_clusterToSector (partition, position.cluster) + position.sector, position.byte, remain);
@ -589,13 +590,13 @@ static bool _FAT_file_extend_r (struct _reent *r, FILE_STRUCT* file) {
if (position.byte > 0) {
_FAT_cache_writePartialSector (cache, zeroBuffer,
_FAT_fat_clusterToSector (partition, position.cluster) + position.sector, position.byte,
BYTES_PER_READ - position.byte);
remain -= (BYTES_PER_READ - position.byte);
partition->bytesPerSector - position.byte);
remain -= (partition->bytesPerSector - position.byte);
position.byte = 0;
position.sector ++;
}
while (remain >= BYTES_PER_READ) {
while (remain >= partition->bytesPerSector) {
if (position.sector >= partition->sectorsPerCluster) {
position.sector = 0;
// Ran out of clusters so get a new one
@ -611,7 +612,7 @@ static bool _FAT_file_extend_r (struct _reent *r, FILE_STRUCT* file) {
sector = _FAT_fat_clusterToSector (partition, position.cluster) + position.sector;
_FAT_cache_writeSectors (cache, sector, 1, zeroBuffer);
remain -= BYTES_PER_READ;
remain -= partition->bytesPerSector;
position.sector ++;
}
@ -712,12 +713,12 @@ ssize_t _FAT_write_r (struct _reent *r, int fd, const char *ptr, size_t len) {
_FAT_check_position_for_next_cluster(r, &position, partition, remain, &flagNoError);
// Align to sector
tempVar = BYTES_PER_READ - position.byte;
tempVar = partition->bytesPerSector - position.byte;
if (tempVar > remain) {
tempVar = remain;
}
if ((tempVar < BYTES_PER_READ) && flagNoError) {
if ((tempVar < partition->bytesPerSector) && flagNoError) {
// Write partial sector to disk
_FAT_cache_writePartialSector (cache, ptr,
_FAT_fat_clusterToSector (partition, position.cluster) + position.sector, position.byte, tempVar);
@ -728,7 +729,7 @@ ssize_t _FAT_write_r (struct _reent *r, int fd, const char *ptr, size_t len) {
// Move onto next sector
if (position.byte >= BYTES_PER_READ) {
if (position.byte >= partition->bytesPerSector) {
position.byte = 0;
position.sector ++;
}
@ -736,10 +737,10 @@ ssize_t _FAT_write_r (struct _reent *r, int fd, const char *ptr, size_t len) {
// Align to cluster
// tempVar is number of sectors to write
if (remain > (partition->sectorsPerCluster - position.sector) * BYTES_PER_READ) {
if (remain > (partition->sectorsPerCluster - position.sector) * partition->bytesPerSector) {
tempVar = partition->sectorsPerCluster - position.sector;
} else {
tempVar = remain / BYTES_PER_READ;
tempVar = remain / partition->bytesPerSector;
}
if ((tempVar > 0 && tempVar < partition->sectorsPerCluster) && flagNoError) {
@ -749,8 +750,8 @@ ssize_t _FAT_write_r (struct _reent *r, int fd, const char *ptr, size_t len) {
flagNoError = false;
r->_errno = EIO;
} else {
ptr += tempVar * BYTES_PER_READ;
remain -= tempVar * BYTES_PER_READ;
ptr += tempVar * partition->bytesPerSector;
remain -= tempVar * partition->bytesPerSector;
position.sector += tempVar;
}
}
@ -769,7 +770,7 @@ ssize_t _FAT_write_r (struct _reent *r, int fd, const char *ptr, size_t len) {
// group consecutive clusters
while (flagNoError &&
#ifdef LIMIT_SECTORS
(chunkSize + partition->bytesPerCluster <= LIMIT_SECTORS * BYTES_PER_READ) &&
(chunkSize + partition->bytesPerCluster <= LIMIT_SECTORS * partition->bytesPerSector) &&
#endif
(chunkSize + partition->bytesPerCluster < remain))
{
@ -786,7 +787,7 @@ ssize_t _FAT_write_r (struct _reent *r, int fd, const char *ptr, size_t len) {
}
if ( !_FAT_cache_writeSectors (cache,
_FAT_fat_clusterToSector(partition, position.cluster), chunkSize / BYTES_PER_READ, ptr))
_FAT_fat_clusterToSector(partition, position.cluster), chunkSize / partition->bytesPerSector, ptr))
{
flagNoError = false;
r->_errno = EIO;
@ -810,15 +811,15 @@ ssize_t _FAT_write_r (struct _reent *r, int fd, const char *ptr, size_t len) {
_FAT_check_position_for_next_cluster(r, &position, partition, remain, &flagNoError);
// Write remaining sectors
tempVar = remain / BYTES_PER_READ; // Number of sectors left
tempVar = remain / partition->bytesPerSector; // Number of sectors left
if ((tempVar > 0) && flagNoError) {
if (!_FAT_cache_writeSectors (cache, _FAT_fat_clusterToSector (partition, position.cluster), tempVar, ptr))
{
flagNoError = false;
r->_errno = EIO;
} else {
ptr += tempVar * BYTES_PER_READ;
remain -= tempVar * BYTES_PER_READ;
ptr += tempVar * partition->bytesPerSector;
remain -= tempVar * partition->bytesPerSector;
position.sector += tempVar;
}
}
@ -927,8 +928,8 @@ off_t _FAT_seek_r (struct _reent *r, int fd, off_t pos, int dir) {
}
// Calculate the sector and byte of the current position,
// and store them
file->rwPosition.sector = (position % partition->bytesPerCluster) / BYTES_PER_READ;
file->rwPosition.byte = position % BYTES_PER_READ;
file->rwPosition.sector = (position % partition->bytesPerCluster) / partition->bytesPerSector;
file->rwPosition.byte = position % partition->bytesPerSector;
nextCluster = _FAT_fat_nextCluster (partition, cluster);
while ((clusCount > 0) && (nextCluster != CLUSTER_FREE) && (nextCluster != CLUSTER_EOF)) {
@ -1087,13 +1088,13 @@ int _FAT_ftruncate_r (struct _reent *r, int fd, off_t len) {
lastCluster = _FAT_fat_trimChain (partition, file->startCluster, chainLength);
if (file->append) {
file->appendPosition.byte = newSize % BYTES_PER_READ;
file->appendPosition.byte = newSize % partition->bytesPerSector;
// Does the end of the file fall on the edge of a cluster?
if (newSize % partition->bytesPerCluster == 0) {
// Set a flag to allocate a new cluster
file->appendPosition.sector = partition->sectorsPerCluster;
} else {
file->appendPosition.sector = (newSize % partition->bytesPerCluster) / BYTES_PER_READ;
file->appendPosition.sector = (newSize % partition->bytesPerCluster) / partition->bytesPerSector;
}
file->appendPosition.cluster = lastCluster;
}

View File

@ -32,7 +32,7 @@ int _FAT_get_fragments (const char *path, _fat_frag_append_t append_fragment, vo
partition = file.partition;
_FAT_lock(&partition->lock);
size = file.filesize / BYTES_PER_READ;
size = file.filesize / partition->bytesPerSector;
cluster = file.startCluster;
offset = 0;

View File

@ -30,6 +30,7 @@
#include "file_allocation_table.h"
#include "partition.h"
#include "mem_allocate.h"
#include <string.h>
/*
@ -54,15 +55,15 @@ uint32_t _FAT_fat_nextCluster(PARTITION* partition, uint32_t cluster)
case FS_FAT12:
{
u32 nextCluster_h;
sector = partition->fat.fatStart + (((cluster * 3) / 2) / BYTES_PER_READ);
offset = ((cluster * 3) / 2) % BYTES_PER_READ;
sector = partition->fat.fatStart + (((cluster * 3) / 2) / partition->bytesPerSector);
offset = ((cluster * 3) / 2) % partition->bytesPerSector;
_FAT_cache_readLittleEndianValue (partition->cache, &nextCluster, sector, offset, sizeof(u8));
offset++;
if (offset >= BYTES_PER_READ) {
if (offset >= partition->bytesPerSector) {
offset = 0;
sector++;
}
@ -85,8 +86,8 @@ uint32_t _FAT_fat_nextCluster(PARTITION* partition, uint32_t cluster)
break;
}
case FS_FAT16:
sector = partition->fat.fatStart + ((cluster << 1) / BYTES_PER_READ);
offset = (cluster % (BYTES_PER_READ >> 1)) << 1;
sector = partition->fat.fatStart + ((cluster << 1) / partition->bytesPerSector);
offset = (cluster % (partition->bytesPerSector >> 1)) << 1;
_FAT_cache_readLittleEndianValue (partition->cache, &nextCluster, sector, offset, sizeof(u16));
@ -96,8 +97,8 @@ uint32_t _FAT_fat_nextCluster(PARTITION* partition, uint32_t cluster)
break;
case FS_FAT32:
sector = partition->fat.fatStart + ((cluster << 2) / BYTES_PER_READ);
offset = (cluster % (BYTES_PER_READ >> 2)) << 2;
sector = partition->fat.fatStart + ((cluster << 2) / partition->bytesPerSector);
offset = (cluster % (partition->bytesPerSector >> 2)) << 2;
_FAT_cache_readLittleEndianValue (partition->cache, &nextCluster, sector, offset, sizeof(u32));
@ -135,8 +136,8 @@ static bool _FAT_fat_writeFatEntry (PARTITION* partition, uint32_t cluster, uint
break;
case FS_FAT12:
sector = partition->fat.fatStart + (((cluster * 3) / 2) / BYTES_PER_READ);
offset = ((cluster * 3) / 2) % BYTES_PER_READ;
sector = partition->fat.fatStart + (((cluster * 3) / 2) / partition->bytesPerSector);
offset = ((cluster * 3) / 2) % partition->bytesPerSector;
if (cluster & 0x01) {
@ -147,7 +148,7 @@ static bool _FAT_fat_writeFatEntry (PARTITION* partition, uint32_t cluster, uint
_FAT_cache_writeLittleEndianValue (partition->cache, value & 0xFF, sector, offset, sizeof(u8));
offset++;
if (offset >= BYTES_PER_READ) {
if (offset >= partition->bytesPerSector) {
offset = 0;
sector++;
}
@ -159,7 +160,7 @@ static bool _FAT_fat_writeFatEntry (PARTITION* partition, uint32_t cluster, uint
_FAT_cache_writeLittleEndianValue (partition->cache, value, sector, offset, sizeof(u8));
offset++;
if (offset >= BYTES_PER_READ) {
if (offset >= partition->bytesPerSector) {
offset = 0;
sector++;
}
@ -174,16 +175,16 @@ static bool _FAT_fat_writeFatEntry (PARTITION* partition, uint32_t cluster, uint
break;
case FS_FAT16:
sector = partition->fat.fatStart + ((cluster << 1) / BYTES_PER_READ);
offset = (cluster % (BYTES_PER_READ >> 1)) << 1;
sector = partition->fat.fatStart + ((cluster << 1) / partition->bytesPerSector);
offset = (cluster % (partition->bytesPerSector >> 1)) << 1;
_FAT_cache_writeLittleEndianValue (partition->cache, value, sector, offset, sizeof(u16));
break;
case FS_FAT32:
sector = partition->fat.fatStart + ((cluster << 2) / BYTES_PER_READ);
offset = (cluster % (BYTES_PER_READ >> 2)) << 2;
sector = partition->fat.fatStart + ((cluster << 2) / partition->bytesPerSector);
offset = (cluster % (partition->bytesPerSector >> 2)) << 2;
_FAT_cache_writeLittleEndianValue (partition->cache, value, sector, offset, sizeof(u32));
@ -269,7 +270,7 @@ If an error occurs, return CLUSTER_ERROR
uint32_t _FAT_fat_linkFreeClusterCleared (PARTITION* partition, uint32_t cluster) {
uint32_t newCluster;
uint32_t i;
uint8_t emptySector[BYTES_PER_READ];
uint8_t *emptySector;
// Link the cluster
newCluster = _FAT_fat_linkFreeCluster(partition, cluster);
@ -278,14 +279,18 @@ uint32_t _FAT_fat_linkFreeClusterCleared (PARTITION* partition, uint32_t cluster
return CLUSTER_ERROR;
}
emptySector = (uint8_t*) _FAT_mem_allocate(partition->bytesPerSector);
// Clear all the sectors within the cluster
memset (emptySector, 0, BYTES_PER_READ);
memset (emptySector, 0, partition->bytesPerSector);
for (i = 0; i < partition->sectorsPerCluster; i++) {
_FAT_cache_writeSectors (partition->cache,
_FAT_fat_clusterToSector (partition, newCluster) + i,
1, emptySector);
}
_FAT_mem_free(emptySector);
return newCluster;
}

View File

@ -40,11 +40,6 @@
sec_t _FAT_startSector;
/*
This device name, as known by devkitPro toolchains
*/
const char* DEVICE_NAME = "fat";
/*
Data offsets
*/
@ -110,17 +105,20 @@ static const char FAT_SIG[3] = {'F', 'A', 'T'};
static const char FS_INFO_SIG1[4] = {'R', 'R', 'a', 'A'};
static const char FS_INFO_SIG2[4] = {'r', 'r', 'A', 'a'};
sec_t FindFirstValidPartition(const DISC_INTERFACE* disc)
{
uint8_t part_table[16*4];
uint8_t *ptr;
int i;
uint8_t sectorBuffer[BYTES_PER_READ] = {0};
uint8_t *sectorBuffer = (uint8_t*) _FAT_mem_allocate(MAX_SECTOR_SIZE);
if(!sectorBuffer) {
return 0;
}
// Read first sector of disc
if (!_FAT_disc_readSectors (disc, 0, 1, sectorBuffer)) {
_FAT_mem_free(sectorBuffer);
return 0;
}
@ -132,6 +130,7 @@ sec_t FindFirstValidPartition(const DISC_INTERFACE* disc)
if (!memcmp(sectorBuffer + BPB_FAT16_fileSysType, FAT_SIG, sizeof(FAT_SIG)) ||
!memcmp(sectorBuffer + BPB_FAT32_fileSysType, FAT_SIG, sizeof(FAT_SIG))) {
_FAT_mem_free(sectorBuffer);
return part_lba;
}
@ -144,43 +143,61 @@ sec_t FindFirstValidPartition(const DISC_INTERFACE* disc)
for(n=0;n<8;n++) // max 8 logic partitions
{
if(!_FAT_disc_readSectors (disc, part_lba+next_lba2, 1, sectorBuffer)) return 0;
if(!_FAT_disc_readSectors (disc, part_lba+next_lba2, 1, sectorBuffer)) {
_FAT_mem_free(sectorBuffer);
return 0;
}
part_lba2 = part_lba + next_lba2 + u8array_to_u32(sectorBuffer, 0x1C6) ;
next_lba2 = u8array_to_u32(sectorBuffer, 0x1D6);
if(!_FAT_disc_readSectors (disc, part_lba2, 1, sectorBuffer)) return 0;
if(!_FAT_disc_readSectors (disc, part_lba2, 1, sectorBuffer)) {
_FAT_mem_free(sectorBuffer);
return 0;
}
if (!memcmp(sectorBuffer + BPB_FAT16_fileSysType, FAT_SIG, sizeof(FAT_SIG)) ||
!memcmp(sectorBuffer + BPB_FAT32_fileSysType, FAT_SIG, sizeof(FAT_SIG)))
{
!memcmp(sectorBuffer + BPB_FAT32_fileSysType, FAT_SIG, sizeof(FAT_SIG))) {
_FAT_mem_free(sectorBuffer);
return part_lba2;
}
if(next_lba2==0) break;
}
} else {
if(!_FAT_disc_readSectors (disc, part_lba, 1, sectorBuffer)) return 0;
if(!_FAT_disc_readSectors (disc, part_lba, 1, sectorBuffer)) {
_FAT_mem_free(sectorBuffer);
return 0;
}
if (!memcmp(sectorBuffer + BPB_FAT16_fileSysType, FAT_SIG, sizeof(FAT_SIG)) ||
!memcmp(sectorBuffer + BPB_FAT32_fileSysType, FAT_SIG, sizeof(FAT_SIG))) {
_FAT_mem_free(sectorBuffer);
return part_lba;
}
}
}
_FAT_mem_free(sectorBuffer);
return 0;
}
PARTITION* _FAT_partition_constructor (const DISC_INTERFACE* disc, uint32_t cacheSize, uint32_t sectorsPerPage, sec_t startSector) {
PARTITION* partition;
uint8_t sectorBuffer[BYTES_PER_READ] = {0};
uint8_t *sectorBuffer = (uint8_t*) _FAT_mem_allocate(MAX_SECTOR_SIZE);
if(!sectorBuffer) {
return NULL;
}
// Read first sector of disc
if (!_FAT_disc_readSectors (disc, startSector, 1, sectorBuffer)) {
_FAT_mem_free(sectorBuffer);
return NULL;
}
// Make sure it is a valid MBR or boot sector
if ( (sectorBuffer[BPB_bootSig_55] != 0x55) || (sectorBuffer[BPB_bootSig_AA] != 0xAA)) {
_FAT_mem_free(sectorBuffer);
return NULL;
}
@ -195,27 +212,29 @@ PARTITION* _FAT_partition_constructor (const DISC_INTERFACE* disc, uint32_t cach
} else {
startSector = FindFirstValidPartition(disc);
if (!_FAT_disc_readSectors (disc, startSector, 1, sectorBuffer)) {
_FAT_mem_free(sectorBuffer);
return NULL;
}
}
_FAT_startSector = startSector;
// Now verify that this is indeed a FAT partition
if (memcmp(sectorBuffer + BPB_FAT16_fileSysType, FAT_SIG, sizeof(FAT_SIG)) &&
memcmp(sectorBuffer + BPB_FAT32_fileSysType, FAT_SIG, sizeof(FAT_SIG)))
{
memcmp(sectorBuffer + BPB_FAT32_fileSysType, FAT_SIG, sizeof(FAT_SIG))) {
_FAT_mem_free(sectorBuffer);
return NULL;
}
partition = (PARTITION*) _FAT_mem_allocate (sizeof(PARTITION));
if (partition == NULL) {
_FAT_mem_free(sectorBuffer);
return NULL;
}
// Init the partition lock
_FAT_lock_init(&partition->lock);
_FAT_startSector = startSector;
if (!memcmp(sectorBuffer + BPB_FAT16_fileSysType, FAT_SIG, sizeof(FAT_SIG)))
strncpy(partition->label, (char*)(sectorBuffer + BPB_FAT16_volumeLabel), 11);
else
@ -236,8 +255,19 @@ PARTITION* _FAT_partition_constructor (const DISC_INTERFACE* disc, uint32_t cach
partition->numberOfSectors = u8array_to_u32( sectorBuffer, BPB_numSectors);
}
partition->bytesPerSector = BYTES_PER_READ; // Sector size is redefined to be 512 bytes
partition->sectorsPerCluster = sectorBuffer[BPB_sectorsPerCluster] * u8array_to_u16(sectorBuffer, BPB_bytesPerSector) / BYTES_PER_READ;
if(disc->features & FEATURE_WII_USB)
partition->bytesPerSector = u8array_to_u16(sectorBuffer, BPB_bytesPerSector);
else
partition->bytesPerSector = MIN_SECTOR_SIZE;
if(partition->bytesPerSector < MIN_SECTOR_SIZE || partition->bytesPerSector > MAX_SECTOR_SIZE) {
// Unsupported sector size
_FAT_mem_free(sectorBuffer);
_FAT_mem_free(partition);
return NULL;
}
partition->sectorsPerCluster = sectorBuffer[BPB_sectorsPerCluster] * u8array_to_u16(sectorBuffer, BPB_bytesPerSector) / partition->bytesPerSector;
partition->bytesPerCluster = partition->bytesPerSector * partition->sectorsPerCluster;
partition->fat.fatStart = startSector + u8array_to_u16(sectorBuffer, BPB_reservedSectors);
@ -278,7 +308,7 @@ PARTITION* _FAT_partition_constructor (const DISC_INTERFACE* disc, uint32_t cach
}
// Create a cache to use
partition->cache = _FAT_cache_constructor (cacheSize, sectorsPerPage, partition->disc, startSector+partition->numberOfSectors);
partition->cache = _FAT_cache_constructor (cacheSize, sectorsPerPage, partition->disc, startSector+partition->numberOfSectors, partition->bytesPerSector);
// Set current directory to the root
partition->cwdCluster = partition->rootDirCluster;
@ -292,6 +322,8 @@ PARTITION* _FAT_partition_constructor (const DISC_INTERFACE* disc, uint32_t cach
_FAT_partition_readFSinfo(partition);
_FAT_mem_free(sectorBuffer);
return partition;
}
@ -338,8 +370,11 @@ void _FAT_partition_createFSinfo(PARTITION * partition)
if(partition->readOnly || partition->filesysType != FS_FAT32)
return;
uint8_t sectorBuffer[BYTES_PER_READ];
memset(sectorBuffer, 0, sizeof(sectorBuffer));
uint8_t *sectorBuffer = (uint8_t*) _FAT_mem_allocate(partition->bytesPerSector);
if(!sectorBuffer) {
return;
}
memset(sectorBuffer, 0, partition->bytesPerSector);
int i;
for(i = 0; i < 4; ++i)
@ -356,6 +391,8 @@ void _FAT_partition_createFSinfo(PARTITION * partition)
sectorBuffer[FSIB_bootSig_AA] = 0xAA;
_FAT_disc_writeSectors (partition->disc, partition->fsInfoSector, 1, sectorBuffer);
_FAT_mem_free(sectorBuffer);
}
void _FAT_partition_readFSinfo(PARTITION * partition)
@ -363,24 +400,29 @@ void _FAT_partition_readFSinfo(PARTITION * partition)
if(partition->filesysType != FS_FAT32)
return;
uint8_t sectorBuffer[BYTES_PER_READ] = {0};
uint8_t *sectorBuffer = (uint8_t*) _FAT_mem_allocate(partition->bytesPerSector);
if(!sectorBuffer) {
return;
}
memset(sectorBuffer, 0, partition->bytesPerSector);
// Read first sector of disc
if (!_FAT_disc_readSectors (partition->disc, partition->fsInfoSector, 1, sectorBuffer)) {
_FAT_mem_free(sectorBuffer);
return;
}
if(memcmp(sectorBuffer+FSIB_SIG1, FS_INFO_SIG1, 4) != 0 ||
memcmp(sectorBuffer+FSIB_SIG2, FS_INFO_SIG2, 4) != 0 ||
u8array_to_u32(sectorBuffer, FSIB_numberOfFreeCluster) == 0)
{
u8array_to_u32(sectorBuffer, FSIB_numberOfFreeCluster) == 0) {
//sector does not yet exist, create one!
_FAT_partition_createFSinfo(partition);
_FAT_mem_free(sectorBuffer);
return;
}
partition->fat.numberFreeCluster = u8array_to_u32(sectorBuffer, FSIB_numberOfFreeCluster);
partition->fat.numberLastAllocCluster = u8array_to_u32(sectorBuffer, FSIB_numberLastAllocCluster);
_FAT_mem_free(sectorBuffer);
}
void _FAT_partition_writeFSinfo(PARTITION * partition)
@ -388,21 +430,26 @@ void _FAT_partition_writeFSinfo(PARTITION * partition)
if(partition->filesysType != FS_FAT32)
return;
uint8_t sectorBuffer[BYTES_PER_READ] = {0};
uint8_t *sectorBuffer = (uint8_t*) _FAT_mem_allocate(partition->bytesPerSector);
if(!sectorBuffer) {
return;
}
memset(sectorBuffer, 0, partition->bytesPerSector);
// Read first sector of disc
if (!_FAT_disc_readSectors (partition->disc, partition->fsInfoSector, 1, sectorBuffer)) {
_FAT_mem_free(sectorBuffer);
return;
}
if(memcmp(sectorBuffer+FSIB_SIG1, FS_INFO_SIG1, 4) || memcmp(sectorBuffer+FSIB_SIG2, FS_INFO_SIG2, 4))
if(memcmp(sectorBuffer+FSIB_SIG1, FS_INFO_SIG1, 4) || memcmp(sectorBuffer+FSIB_SIG2, FS_INFO_SIG2, 4)) {
_FAT_mem_free(sectorBuffer);
return;
}
u32_to_u8array(sectorBuffer, FSIB_numberOfFreeCluster, partition->fat.numberFreeCluster);
u32_to_u8array(sectorBuffer, FSIB_numberLastAllocCluster, partition->fat.numberLastAllocCluster);
// Read first sector of disc
if (!_FAT_disc_writeSectors (partition->disc, partition->fsInfoSector, 1, sectorBuffer)) {
return;
}
_FAT_disc_writeSectors (partition->disc, partition->fsInfoSector, 1, sectorBuffer);
_FAT_mem_free(sectorBuffer);
}

View File

@ -34,8 +34,8 @@
#include "cache.h"
#include "lock.h"
// Device name
extern const char* DEVICE_NAME;
#define MIN_SECTOR_SIZE 512
#define MAX_SECTOR_SIZE 4096
// Filesystem type
typedef enum {FS_UNKNOWN, FS_FAT12, FS_FAT16, FS_FAT32} FS_TYPE;

File diff suppressed because it is too large Load Diff