Index: apps/buffering.c =================================================================== --- apps/buffering.c (revision 25260) +++ apps/buffering.c (working copy) @@ -664,6 +664,10 @@ return true; } +#ifndef SIMULATOR + file_preloadfat(h->fd, MIN( h->filerem, buffer_len - h->widx ) ); +#endif + while (h->filerem > 0 && !stop) { /* max amount to copy */ Index: firmware/export/fat.h =================================================================== --- firmware/export/fat.h (revision 25260) +++ firmware/export/fat.h (working copy) @@ -127,5 +127,6 @@ 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 Index: firmware/include/file.h =================================================================== --- firmware/include/file.h (revision 25260) +++ firmware/include/file.h (working copy) @@ -81,5 +81,6 @@ 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 Index: firmware/common/file.c =================================================================== --- firmware/common/file.c (revision 25260) +++ firmware/common/file.c (working copy) @@ -815,3 +815,40 @@ return closed; /* return how many we did */ } #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; +} Index: firmware/drivers/fat.c =================================================================== --- firmware/drivers/fat.c (revision 25260) +++ firmware/drivers/fat.c (working copy) @@ -2546,3 +2546,31 @@ 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; +}