diff --git a/apps/buffering.c b/apps/buffering.c index 6160869..0952ca1 100644 --- a/apps/buffering.c +++ b/apps/buffering.c @@ -607,6 +607,8 @@ static bool buffer_handle(int handle_id) return true; } + file_preloadfat(h->fd, MIN( h->filerem, buffer_len - h->widx ) ); + while (h->filerem > 0) { /* max amount to copy */ diff --git a/firmware/common/file.c b/firmware/common/file.c index 7c01f03..636622b 100644 --- a/firmware/common/file.c +++ b/firmware/common/file.c @@ -793,3 +793,40 @@ int release_files(int volume) } #endif /* #ifdef HAVE_HOTSWAP */ +int file_preloadfat(int fd, size_t count) +{ + long sectors; + struct filedesc* file = &openfiles[fd]; + int rc=0; + + if (fd < 0 || fd > MAX_OPEN_FILES-1) { + errno = EINVAL; + return -1; + } + if ( !file->busy ) { + errno = EBADF; + return -1; + } + + LDEBUGF( "file_preloadfat(%d,%ld)\n", + fd,count); + + /* attempt to read past EOF? */ + if ((long)count > file->size - file->fileoffset) + count = file->size - file->fileoffset; + + /* any head bytes? */ + if ( file->cacheoffset != -1 ) { + int offs = file->cacheoffset; + int headbytes = MIN((long)count, SECTOR_SIZE - offs); + count -= headbytes; + } + + /* read/write whole sectors right into/from the supplied buffer */ + sectors = count / SECTOR_SIZE; + if ( sectors ) { + rc = fat_preload(&(file->fatfile), sectors); + } + + return rc; +} diff --git a/firmware/drivers/fat.c b/firmware/drivers/fat.c index 2ff4c61..3b2068d 100644 --- a/firmware/drivers/fat.c +++ b/firmware/drivers/fat.c @@ -2520,3 +2520,31 @@ bool fat_ismounted(int volume) return (volumevolume]; +#else + struct bpb* fat_bpb = &fat_bpbs[0]; +#endif + long cluster = file->lastcluster; + long i; + long clustercount = sectorcount / (long)fat_bpb->bpb_secperclus + + ( (sectorcount % (long)fat_bpb->bpb_secperclus > 0 ) ? 1 : 0 ); + + LDEBUGF( "fat_preload(file:%lx,count:0x%lx)\n", + file->firstcluster,sectorcount); + LDEBUGF( "fat_preload: sec=%lx numsec=%ld eof=%d\n", + sector,numsec, eof?1:0); + + if ( file->eof ) + return 0; + + for ( i=0; cluster && i < clustercount; i++ ) { + cluster = get_next_cluster(IF_MV2(fat_bpb,) cluster); + } + + DEBUGF("Cluster numbers preloaded: %ld\n", i); + return i; +} diff --git a/firmware/export/fat.h b/firmware/export/fat.h index c99a1a7..9cd0b42 100644 --- a/firmware/export/fat.h +++ b/firmware/export/fat.h @@ -123,5 +123,6 @@ extern int fat_opendir(IF_MV2(int volume,) extern int fat_getnext(struct fat_dir *ent, struct fat_direntry *entry); extern unsigned int fat_get_cluster_size(IF_MV_NONVOID(int volume)); /* public for debug info screen */ extern bool fat_ismounted(int volume); +extern long fat_preload(struct fat_file *ent, long sectorcount); #endif diff --git a/firmware/include/file.h b/firmware/include/file.h index 3e07fd0..49d5a04 100644 --- a/firmware/include/file.h +++ b/firmware/include/file.h @@ -81,5 +81,6 @@ extern int rename(const char* path, const char* newname); extern int ftruncate(int fd, off_t length); extern off_t filesize(int fd); extern int release_files(int volume); +extern int file_preloadfat(int fd, size_t count); #endif