diff --git a/gba/include/fat.h b/gba/include/fat.h index f3b1f63..b0a9b0d 100644 --- a/gba/include/fat.h +++ b/gba/include/fat.h @@ -66,7 +66,7 @@ the disc. Otherwise it will try to mount the partition starting at startSector. cacheSize specifies the number of pages to allocate for the cache. This will not startup the disc, so you need to call interface->startup(); first. */ -extern bool fatMount (const char* name, const DISC_INTERFACE* interface, sec_t startSector, uint32_t cacheSize); +extern bool fatMount (const char* name, const DISC_INTERFACE* interface, sec_t startSector, uint32_t cacheSize, uint32_t SectorsPerPage); /* Unmount the partition specified by name. diff --git a/include/fat.h b/include/fat.h index 2ccf604..c449991 100644 --- a/include/fat.h +++ b/include/fat.h @@ -82,7 +82,7 @@ the disc. Otherwise it will try to mount the partition starting at startSector. cacheSize specifies the number of pages to allocate for the cache. This will not startup the disc, so you need to call interface->startup(); first. */ -extern bool fatMount (const char* name, const DISC_INTERFACE* interface, sec_t startSector, uint32_t cacheSize); +extern bool fatMount (const char* name, const DISC_INTERFACE* interface, sec_t startSector, uint32_t cacheSize, uint32_t SectorsPerPage); /* Unmount the partition specified by name. diff --git a/libogc/include/fat.h b/libogc/include/fat.h index 8457593..10f2af6 100644 --- a/libogc/include/fat.h +++ b/libogc/include/fat.h @@ -66,8 +66,7 @@ the disc. Otherwise it will try to mount the partition starting at startSector. cacheSize specifies the number of pages to allocate for the cache. This will not startup the disc, so you need to call interface->startup(); first. */ -extern bool fatMount (const char* name, const DISC_INTERFACE* interface, sec_t startSector, uint32_t cacheSize); - +extern bool fatMount (const char* name, const DISC_INTERFACE* interface, sec_t startSector, uint32_t cacheSize, uint32_t SectorsPerPage); /* Unmount the partition specified by name. If there are open files, it will attempt to synchronise them to disc. diff --git a/nds/include/fat.h b/nds/include/fat.h index 67c927d..5272b80 100644 --- a/nds/include/fat.h +++ b/nds/include/fat.h @@ -71,7 +71,7 @@ the disc. Otherwise it will try to mount the partition starting at startSector. cacheSize specifies the number of pages to allocate for the cache. This will not startup the disc, so you need to call interface->startup(); first. */ -extern bool fatMount (const char* name, const DISC_INTERFACE* interface, sec_t startSector, uint32_t cacheSize); +extern bool fatMount (const char* name, const DISC_INTERFACE* interface, sec_t startSector, uint32_t cacheSize, uint32_t SectorsPerPage); /* Unmount the partition specified by name. diff --git a/source/cache.c b/source/cache.c index 3d62bb8..0537b55 100644 --- a/source/cache.c +++ b/source/cache.c @@ -1,16 +1,16 @@ /* cache.c - The cache is not visible to the user. It should be flushed + The cache is not visible to the user. It should be flushed when any file is closed or changes are made to the filesystem. - - This cache implements a least-used-page replacement policy. This will - distribute sectors evenly over the pages, so if less than the maximum + + This cache implements a least-used-page replacement policy. This will + distribute sectors evenly over the pages, so if less than the maximum pages are used at once, they should all eventually remain in the cache. This also has the benefit of throwing out old sectors, so as not to keep too many stale pages around. Copyright (c) 2006 Michael "Chishm" Chisholm - + Redistribution and use in source and binary forms, with or without modification, are permitted provided that the following conditions are met: @@ -42,10 +42,11 @@ #include "mem_allocate.h" #include "bit_ops.h" +#include "file_allocation_table.h" #define CACHE_FREE UINT_MAX -CACHE* _FAT_cache_constructor (unsigned int numberOfPages, const DISC_INTERFACE* discInterface) { +CACHE* _FAT_cache_constructor (unsigned int numberOfPages, unsigned int sectorsPerPage, const DISC_INTERFACE* discInterface) { CACHE* cache; unsigned int i; CACHE_ENTRY* cacheEntries; @@ -53,7 +54,11 @@ CACHE* _FAT_cache_constructor (unsigned int numberOfPages, const DISC_INTERFACE* if (numberOfPages < 2) { numberOfPages = 2; } - + + if (sectorsPerPage < 8) { + sectorsPerPage = 8; + } + cache = (CACHE*) _FAT_mem_allocate (sizeof(CACHE)); if (cache == NULL) { return NULL; @@ -61,7 +66,8 @@ CACHE* _FAT_cache_constructor (unsigned int numberOfPages, const DISC_INTERFACE* cache->disc = discInterface; cache->numberOfPages = numberOfPages; - + cache->sectorsPerPage = sectorsPerPage; + cacheEntries = (CACHE_ENTRY*) _FAT_mem_allocate ( sizeof(CACHE_ENTRY) * numberOfPages); if (cacheEntries == NULL) { @@ -72,31 +78,33 @@ CACHE* _FAT_cache_constructor (unsigned int numberOfPages, const DISC_INTERFACE* for (i = 0; i < numberOfPages; i++) { cacheEntries[i].sector = CACHE_FREE; 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 ); } cache->cacheEntries = cacheEntries; - cache->pages = (uint8_t*) _FAT_mem_allocate ( CACHE_PAGE_SIZE * numberOfPages); - if (cache->pages == NULL) { - _FAT_mem_free (cache->cacheEntries); - _FAT_mem_free (cache); - return NULL; - } - return cache; } void _FAT_cache_destructor (CACHE* cache) { + unsigned int i; // Clear out cache before destroying it _FAT_cache_flush(cache); // Free memory in reverse allocation order - _FAT_mem_free (cache->pages); + for (i = 0; i < cache->numberOfPages; i++) { + _FAT_mem_free (cache->cacheEntries[i].cache); + } _FAT_mem_free (cache->cacheEntries); _FAT_mem_free (cache); +} - return; +static u32 accessCounter = 0; + +static u32 accessTime(){ + return accessCounter; } /* @@ -104,71 +112,147 @@ Retrieve a sector's page from the cache. If it is not found in the cache, load it into the cache and return the page it was loaded to. Return CACHE_FREE on error. */ -static unsigned int _FAT_cache_getSector (CACHE* cache, sec_t sector) { +static unsigned int _FAT_cache_getSector (CACHE* cache, sec_t sector, void* buffer) { unsigned int i; CACHE_ENTRY* cacheEntries = cache->cacheEntries; unsigned int numberOfPages = cache->numberOfPages; + unsigned int sectorsPerPage = cache->sectorsPerPage; - unsigned int leastUsed = 0; - unsigned int lowestCount = UINT_MAX; + unsigned int oldUsed = 0; + unsigned int oldAccess = cacheEntries[0].last_access; - for (i = 0; (i < numberOfPages) && (cacheEntries[i].sector != sector); i++) { - // While searching for the desired sector, also search for the leased used page - if ( (cacheEntries[i].sector == CACHE_FREE) || (cacheEntries[i].count < lowestCount) ) { - leastUsed = i; - lowestCount = cacheEntries[i].count; + for (i = 0; i < numberOfPages ; i++) { + if ( sector>=cacheEntries[i].sector && sector < cacheEntries[i].sector+cacheEntries[i].count) { + cacheEntries[i].last_access = accessTime(); + memcpy(buffer, cacheEntries[i].cache + ((sector - cacheEntries[i].sector)*BYTES_PER_READ), BYTES_PER_READ); + return true; + } + // While searching for the desired sector, also search for the least recently used page + if ( (cacheEntries[i].sector == CACHE_FREE) || (cacheEntries[i].last_access < oldAccess) ) { + oldUsed = i; + oldAccess = cacheEntries[i].last_access; } } - // If it found the sector in the cache, return it - if ((i < numberOfPages) && (cacheEntries[i].sector == sector)) { - // Increment usage counter - cacheEntries[i].count += 1; - return i; - } // If it didn't, replace the least used cache page with the desired sector - if ((cacheEntries[leastUsed].sector != CACHE_FREE) && (cacheEntries[leastUsed].dirty == true)) { + if ((cacheEntries[oldUsed].sector != CACHE_FREE) && (cacheEntries[oldUsed].dirty == true)) { // Write the page back to disc if it has been written to - if (!_FAT_disc_writeSectors (cache->disc, cacheEntries[leastUsed].sector, 1, cache->pages + CACHE_PAGE_SIZE * leastUsed)) { - return CACHE_FREE; + if (!_FAT_disc_writeSectors (cache->disc, cacheEntries[oldUsed].sector, cacheEntries[oldUsed].count, cacheEntries[oldUsed].cache)) { + return false; } - cacheEntries[leastUsed].dirty = false; + cacheEntries[oldUsed].dirty = false; } // Load the new sector into the cache - if (!_FAT_disc_readSectors (cache->disc, sector, 1, cache->pages + CACHE_PAGE_SIZE * leastUsed)) { - return CACHE_FREE; + if (!_FAT_disc_readSectors (cache->disc, sector, sectorsPerPage, cacheEntries[oldUsed].cache)) { + return false; } - cacheEntries[leastUsed].sector = sector; + cacheEntries[oldUsed].sector = sector; + cacheEntries[oldUsed].count = sectorsPerPage; // Increment the usage count, don't reset it - // This creates a paging policy of least used PAGE, not sector - cacheEntries[leastUsed].count += 1; - return leastUsed; + // This creates a paging policy of least recently used PAGE, not sector + cacheEntries[oldUsed].last_access = accessTime(); + memcpy(buffer, cacheEntries[oldUsed].cache, BYTES_PER_READ); + return true; +} + +bool _FAT_cache_getSectors (CACHE* cache, sec_t sector, sec_t numSectors, void* buffer) { + unsigned int i; + CACHE_ENTRY* cacheEntries = cache->cacheEntries; + unsigned int numberOfPages = cache->numberOfPages; + sec_t sec; + sec_t secs_to_read; + + unsigned int oldUsed = 0; + unsigned int oldAccess = cacheEntries[0].last_access; + accessCounter++; + + while(numSectors>0) + { + i=0; + while (i < numberOfPages ) { + if ( sector>=cacheEntries[i].sector && sector < cacheEntries[i].sector+cacheEntries[i].count) { + sec=sector-cacheEntries[i].sector; + secs_to_read=cacheEntries[i].count-sec; + if(secs_to_read>numSectors)secs_to_read=numSectors; + memcpy(buffer,cacheEntries[i].cache + (sec*BYTES_PER_READ), secs_to_read*BYTES_PER_READ); + cacheEntries[i].last_access = accessTime(); + numSectors=numSectors-secs_to_read; + if(numSectors==0) return true; + buffer+=secs_to_read*BYTES_PER_READ; + sector+=secs_to_read; + i=-1; // recheck all pages again + oldUsed = 0; + oldAccess = cacheEntries[0].last_access; + + } + else // While searching for the desired sector, also search for the least recently used page + if ( (cacheEntries[i].sector == CACHE_FREE) || (cacheEntries[i].last_access < oldAccess) ) { + oldUsed = i; + oldAccess = cacheEntries[i].last_access; + } + i++; + } + // If it didn't, replace the least recently used cache page with the desired sector + if ((cacheEntries[oldUsed].sector != CACHE_FREE) && (cacheEntries[oldUsed].dirty == true)) { + // Write the page back to disc if it has been written to + if (!_FAT_disc_writeSectors (cache->disc, cacheEntries[oldUsed].sector, cacheEntries[oldUsed].count, cacheEntries[oldUsed].cache)) { + return false; + } + cacheEntries[oldUsed].dirty = false; + } + + + cacheEntries[oldUsed].count = cache->sectorsPerPage; + if (!_FAT_disc_readSectors (cache->disc, sector, cacheEntries[oldUsed].count, cacheEntries[oldUsed].cache)) { + return false; + } + + cacheEntries[oldUsed].sector = sector; + // Increment the usage count, don't reset it + // This creates a paging policy of least used PAGE, not sector + cacheEntries[oldUsed].last_access = accessTime(); + + sec=0; + secs_to_read=cacheEntries[oldUsed].count-sec; + if(secs_to_read>numSectors)secs_to_read=numSectors; + memcpy(buffer,cacheEntries[oldUsed].cache + (sec*BYTES_PER_READ), secs_to_read*BYTES_PER_READ); + numSectors=numSectors-secs_to_read; + if(numSectors==0) return true; + buffer+=secs_to_read*BYTES_PER_READ; + + sector+=secs_to_read; + oldUsed = 0; + oldAccess = cacheEntries[0].last_access; + } + return false; } /* Reads some data from a cache page, determined by the sector number */ bool _FAT_cache_readPartialSector (CACHE* cache, void* buffer, sec_t sector, unsigned int offset, size_t size) { - unsigned int page; + void* sec; if (offset + size > BYTES_PER_READ) { return false; } - - page = _FAT_cache_getSector (cache, sector); - if (page == CACHE_FREE) { + sec = (void*) _FAT_mem_align ( BYTES_PER_READ ); + if(sec == NULL) return false; + if(! _FAT_cache_getSector(cache, sector, sec) ) { + _FAT_mem_free(sec); return false; } - memcpy (buffer, cache->pages + (CACHE_PAGE_SIZE * page) + offset, size); + memcpy(buffer, sec + offset, size); + _FAT_mem_free(sec); return true; } bool _FAT_cache_readLittleEndianValue (CACHE* cache, uint32_t *value, sec_t sector, unsigned int offset, int num_bytes) { uint8_t buf[4]; if (!_FAT_cache_readPartialSector(cache, buf, sector, offset, num_bytes)) return false; - + switch(num_bytes) { case 1: *value = buf[0]; break; case 2: *value = u8array_to_u16(buf,0); break; @@ -178,25 +262,38 @@ bool _FAT_cache_readLittleEndianValue (CACHE* cache, uint32_t *value, sec_t sect return true; } -/* +/* Writes some data to a cache page, making sure it is loaded into memory first. */ bool _FAT_cache_writePartialSector (CACHE* cache, const void* buffer, sec_t sector, unsigned int offset, size_t size) { - unsigned int page; + unsigned int i; + void* sec; + CACHE_ENTRY* cacheEntries = cache->cacheEntries; + unsigned int numberOfPages = cache->numberOfPages; if (offset + size > BYTES_PER_READ) { return false; } - page = _FAT_cache_getSector (cache, sector); - if (page == CACHE_FREE) { + //To be sure sector is in cache + sec = (void*) _FAT_mem_align ( BYTES_PER_READ ); + if(sec == NULL) return false; + if(! _FAT_cache_getSector(cache, sector, sec) ) { + _FAT_mem_free(sec); return false; } - - memcpy (cache->pages + (CACHE_PAGE_SIZE * page) + offset, buffer, size); - cache->cacheEntries[page].dirty = true; + _FAT_mem_free(sec); - return true; + //Find where sector is and write + for (i = 0; i < numberOfPages ; i++) { + if ( sector>=cacheEntries[i].sector && sector < cacheEntries[i].sector+cacheEntries[i].count) { + cacheEntries[i].last_access = accessTime(); + memcpy (cacheEntries[i].cache + ((sector-cacheEntries[i].sector)*BYTES_PER_READ) + offset, buffer, size); + cache->cacheEntries[i].dirty = true; + return true; + } + } + return false; } bool _FAT_cache_writeLittleEndianValue (CACHE* cache, const uint32_t value, sec_t sector, unsigned int offset, int size) { @@ -212,43 +309,54 @@ bool _FAT_cache_writeLittleEndianValue (CACHE* cache, const uint32_t value, sec_ return _FAT_cache_writePartialSector(cache, buf, sector, offset, size); } -/* +/* Writes some data to a cache page, zeroing out the page first */ bool _FAT_cache_eraseWritePartialSector (CACHE* cache, const void* buffer, sec_t sector, unsigned int offset, size_t size) { - unsigned int page; + unsigned int i; + void* sec; + CACHE_ENTRY* cacheEntries = cache->cacheEntries; + unsigned int numberOfPages = cache->numberOfPages; if (offset + size > BYTES_PER_READ) { return false; } - page = _FAT_cache_getSector (cache, sector); - if (page == CACHE_FREE) { + //To be sure sector is in cache + sec = (void*) _FAT_mem_align ( BYTES_PER_READ ); + if(sec == NULL) return false; + if(! _FAT_cache_getSector(cache, sector, sec) ) { + _FAT_mem_free(sec); return false; } - - memset (cache->pages + (CACHE_PAGE_SIZE * page), 0, CACHE_PAGE_SIZE); - memcpy (cache->pages + (CACHE_PAGE_SIZE * page) + offset, buffer, size); - cache->cacheEntries[page].dirty = true; + _FAT_mem_free(sec); - return true; + //Find where sector is and write + for (i = 0; i < numberOfPages ; i++) { + if ( sector>=cacheEntries[i].sector && sector < cacheEntries[i].sector+cacheEntries[i].count) { + cacheEntries[i].last_access = accessTime(); + memset (cacheEntries[i].cache + ((sector-cacheEntries[i].sector)*BYTES_PER_READ), 0, BYTES_PER_READ); + memcpy (cacheEntries[i].cache + ((sector-cacheEntries[i].sector)*BYTES_PER_READ) + offset, buffer, size); + cache->cacheEntries[i].dirty = true; + return true; + } + } + return false; } /* -Flushes all dirty pages to disc, clearing the dirty flag. -Also resets all pages' page count to 0. +Flushes all dirty pages to disc, clearing the dirty flag. */ bool _FAT_cache_flush (CACHE* cache) { unsigned int i; for (i = 0; i < cache->numberOfPages; i++) { if (cache->cacheEntries[i].dirty) { - if (!_FAT_disc_writeSectors (cache->disc, cache->cacheEntries[i].sector, 1, cache->pages + CACHE_PAGE_SIZE * i)) { + if (!_FAT_disc_writeSectors (cache->disc, cache->cacheEntries[i].sector, cache->cacheEntries[i].count, cache->cacheEntries[i].cache)) { return false; } } - cache->cacheEntries[i].count = 0; cache->cacheEntries[i].dirty = false; } @@ -257,10 +365,11 @@ bool _FAT_cache_flush (CACHE* cache) { void _FAT_cache_invalidate (CACHE* cache) { unsigned int i; + _FAT_cache_flush(cache); for (i = 0; i < cache->numberOfPages; i++) { cache->cacheEntries[i].sector = CACHE_FREE; + cache->cacheEntries[i].last_access = 0; cache->cacheEntries[i].count = 0; cache->cacheEntries[i].dirty = false; } } - diff --git a/source/cache.h b/source/cache.h index de4866a..bd9e10b 100644 --- a/source/cache.h +++ b/source/cache.h @@ -39,22 +39,24 @@ #include "common.h" #include "disc.h" -#define CACHE_PAGE_SIZE BYTES_PER_READ +#define PAGE_SECTORS 64 +#define CACHE_PAGE_SIZE (BYTES_PER_READ * PAGE_SECTORS) typedef struct { sec_t sector; unsigned int count; + unsigned int last_access; bool dirty; + uint8_t* cache; } CACHE_ENTRY; typedef struct { const DISC_INTERFACE* disc; unsigned int numberOfPages; + unsigned int sectorsPerPage; CACHE_ENTRY* cacheEntries; - uint8_t* pages; } CACHE; - /* Read data from a sector in the cache If the sector is not in the cache, it will be swapped in @@ -88,6 +90,11 @@ Precondition: offset + size <= BYTES_PER_READ */ bool _FAT_cache_eraseWritePartialSector (CACHE* cache, const void* buffer, sec_t sector, unsigned int offset, size_t size); +/* +Read several sectors from the cache +*/ +bool _FAT_cache_getSectors (CACHE* cache, sec_t sector, sec_t numSectors, void* buffer); + /* Read a full sector from the cache */ @@ -112,7 +119,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, const DISC_INTERFACE* discInterface); +CACHE* _FAT_cache_constructor (unsigned int numberOfPages, unsigned int sectorsPerPage, const DISC_INTERFACE* discInterface); void _FAT_cache_destructor (CACHE* cache); diff --git a/source/common.h b/source/common.h index 1800fbe..be4bd81 100644 --- a/source/common.h +++ b/source/common.h @@ -57,19 +57,23 @@ // Platform specific options #if defined (__wii__) - #define DEFAULT_CACHE_PAGES 8 + #define DEFAULT_CACHE_PAGES 4 + #define DEFAULT_SECTORS_PAGE 64 #define USE_LWP_LOCK #define USE_RTC_TIME #elif defined (__gamecube__) - #define DEFAULT_CACHE_PAGES 8 + #define DEFAULT_CACHE_PAGES 4 + #define DEFAULT_SECTORS_PAGE 64 #define USE_LWP_LOCK #define USE_RTC_TIME #elif defined (NDS) - #define DEFAULT_CACHE_PAGES 8 + #define DEFAULT_CACHE_PAGES 4 + #define DEFAULT_SECTORS_PAGE 8 #define USE_RTC_TIME #define LIMIT_SECTORS 128 #elif defined (GBA) #define DEFAULT_CACHE_PAGES 2 + #define DEFAULT_SECTORS_PAGE 8 #define LIMIT_SECTORS 128 #endif diff --git a/source/fatfile.c b/source/fatfile.c index fa5b0e7..cbceec8 100644 --- a/source/fatfile.c +++ b/source/fatfile.c @@ -36,6 +36,7 @@ #include #include #include +#include #include "cache.h" #include "file_allocation_table.h" @@ -244,6 +245,10 @@ int _FAT_open_r (struct _reent *r, void *fileStruct, const char *path, int flags _FAT_unlock(&partition->lock); + /*FILE *fp; + fp=__sfp(r); + fp->_file = (int) file; + setvbuf(fp,NULL,_IONBF,0);*/ return (int) file; } @@ -335,6 +340,33 @@ int _FAT_close_r (struct _reent *r, int fd) { return ret; } +sec_t _FAT_Num_Sectors_To_Cache(CACHE* cache, FILE_POSITION position,PARTITION* partition) { + uint32_t limit; + uint32_t ra_start, ra_end, ra_sectors; + + + limit = cache->sectorsPerPage; + + ra_start = position.cluster; + ra_sectors = - position.sector; + + while (true) { + ra_end = ra_start; + ra_start = _FAT_fat_nextCluster(partition, ra_end); + + if (ra_start != ra_end + 1) + break; + + ra_sectors += partition->sectorsPerCluster; + + if (ra_sectors >= limit) + break; + } + if (ra_sectors > limit) ra_sectors = limit; + + return ra_sectors; + +} ssize_t _FAT_read_r (struct _reent *r, int fd, char *ptr, size_t len) { FILE_STRUCT* file = (FILE_STRUCT*) fd; @@ -407,7 +439,7 @@ ssize_t _FAT_read_r (struct _reent *r, int fd, char *ptr, size_t len) { } if ((tempVar > 0) && flagNoError) { - if (! _FAT_disc_readSectors (partition->disc, _FAT_fat_clusterToSector (partition, position.cluster) + position.sector, + if (! _FAT_cache_getSectors (cache, _FAT_fat_clusterToSector (partition, position.cluster) + position.sector, tempVar, ptr)) { flagNoError = false; @@ -450,7 +482,7 @@ ssize_t _FAT_read_r (struct _reent *r, int fd, char *ptr, size_t len) { #endif (chunkSize + partition->bytesPerCluster <= remain)); - if (!_FAT_disc_readSectors (partition->disc, _FAT_fat_clusterToSector (partition, position.cluster), + if (!_FAT_cache_getSectors (cache, _FAT_fat_clusterToSector (partition, position.cluster), chunkSize / BYTES_PER_READ, ptr)) { flagNoError = false; @@ -476,7 +508,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 if ((tempVar > 0) && flagNoError) { - if (!_FAT_disc_readSectors (partition->disc, _FAT_fat_clusterToSector (partition, position.cluster), + if (!_FAT_cache_getSectors (cache, _FAT_fat_clusterToSector (partition, position.cluster), tempVar, ptr)) { flagNoError = false; diff --git a/source/libfat.c b/source/libfat.c index d2128b0..8bdc895 100644 --- a/source/libfat.c +++ b/source/libfat.c @@ -64,8 +64,7 @@ static const devoptab_t dotab_fat = { NULL /* Device data */ }; - -bool fatMount (const char* name, const DISC_INTERFACE* interface, sec_t startSector, uint32_t cacheSize) { +bool fatMount (const char* name, const DISC_INTERFACE* interface, sec_t startSector, uint32_t cacheSize, uint32_t SectorsPerPage) { PARTITION* partition; devoptab_t* devops; char* nameCopy; @@ -78,7 +77,7 @@ bool fatMount (const char* name, const DISC_INTERFACE* interface, sec_t startSec nameCopy = (char*)(devops+1); // Initialize the file system - partition = _FAT_partition_constructor (interface, cacheSize, startSector); + partition = _FAT_partition_constructor (interface, cacheSize, SectorsPerPage, startSector); if (!partition) { _FAT_mem_free (devops); return false; @@ -96,7 +95,7 @@ bool fatMount (const char* name, const DISC_INTERFACE* interface, sec_t startSec } bool fatMountSimple (const char* name, const DISC_INTERFACE* interface) { - return fatMount (name, interface, 0, DEFAULT_CACHE_PAGES); + return fatMount (name, interface, 0, DEFAULT_CACHE_PAGES, DEFAULT_SECTORS_PAGE); } void fatUnmount (const char* name) { @@ -132,7 +131,7 @@ bool fatInit (uint32_t cacheSize, bool setAsDefaultDevice) { i++) { disc = _FAT_disc_interfaces[i].getInterface(); - if (disc->startup() && fatMount (_FAT_disc_interfaces[i].name, disc, 0, cacheSize)) { + if (disc->startup() && fatMount (_FAT_disc_interfaces[i].name, disc, 0, cacheSize, DEFAULT_SECTORS_PAGE)) { // The first device to successfully mount is set as the default if (defaultDevice < 0) { defaultDevice = i; diff --git a/source/mem_allocate.h b/source/mem_allocate.h index 1c83196..3308807 100644 --- a/source/mem_allocate.h +++ b/source/mem_allocate.h @@ -37,6 +37,14 @@ static inline void* _FAT_mem_allocate (size_t size) { return malloc (size); } +static inline void* _FAT_mem_align (size_t size) { +#ifdef __wii__ + return memalign (32, size); +#else + return malloc (size); +#endif +} + static inline void _FAT_mem_free (void* mem) { free (mem); } diff --git a/source/partition.c b/source/partition.c index 7351da9..5f0fcc1 100644 --- a/source/partition.c +++ b/source/partition.c @@ -97,7 +97,7 @@ enum BPB { static const char FAT_SIG[3] = {'F', 'A', 'T'}; -PARTITION* _FAT_partition_constructor (const DISC_INTERFACE* disc, uint32_t cacheSize, sec_t startSector) { +PARTITION* _FAT_partition_constructor (const DISC_INTERFACE* disc, uint32_t cacheSize, uint32_t sectorsPerPage, sec_t startSector) { PARTITION* partition; int i; uint8_t sectorBuffer[BYTES_PER_READ] = {0}; @@ -220,7 +220,7 @@ PARTITION* _FAT_partition_constructor (const DISC_INTERFACE* disc, uint32_t cach } // Create a cache to use - partition->cache = _FAT_cache_constructor (cacheSize, partition->disc); + partition->cache = _FAT_cache_constructor (cacheSize, sectorsPerPage, partition->disc); // Set current directory to the root partition->cwdCluster = partition->rootDirCluster; diff --git a/source/partition.h b/source/partition.h index b0cfea7..c0e5c3e 100644 --- a/source/partition.h +++ b/source/partition.h @@ -72,7 +72,7 @@ typedef struct { /* Mount the supplied device and return a pointer to the struct necessary to use it */ -PARTITION* _FAT_partition_constructor (const DISC_INTERFACE* disc, uint32_t cacheSize, sec_t startSector); +PARTITION* _FAT_partition_constructor (const DISC_INTERFACE* disc, uint32_t cacheSize, uint32_t SectorsPerPage, sec_t startSector); /* Dismount the device and free all structures used.