add read ahead cache by Rodries

This commit is contained in:
Dave Murphy 2009-05-17 22:16:35 +00:00
parent 527a26f299
commit 206ce78022
12 changed files with 250 additions and 92 deletions

View File

@ -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.

View File

@ -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.

View File

@ -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.

View File

@ -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.

View File

@ -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;
}
}

View File

@ -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);

View File

@ -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

View File

@ -36,6 +36,7 @@
#include <errno.h>
#include <ctype.h>
#include <unistd.h>
#include <stdio.h>
#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;

View File

@ -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;

View File

@ -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);
}

View File

@ -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;

View File

@ -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.