From 4bd870360af595a3f90b9ccc5a09d1414fd654e9 Mon Sep 17 00:00:00 2001 From: Björn Stenberg Date: Tue, 7 May 2002 16:01:53 +0000 Subject: Added open/close/read. read() only works on whole sectors right now. git-svn-id: svn://svn.rockbox.org/rockbox/trunk@498 a1c6a512-1295-4272-9138-f99709370657 --- firmware/common/dir.c | 1 + firmware/common/dir.h | 1 + firmware/common/file.c | 170 +++++++++++++++++++++++++++++++++++++++++++++ firmware/common/file.h | 7 +- firmware/test/fat/Makefile | 5 +- firmware/test/fat/main.c | 97 +++++++++++++------------- 6 files changed, 230 insertions(+), 51 deletions(-) create mode 100644 firmware/common/file.c (limited to 'firmware') diff --git a/firmware/common/dir.c b/firmware/common/dir.c index b0927c09c6..acc412c570 100644 --- a/firmware/common/dir.c +++ b/firmware/common/dir.c @@ -94,6 +94,7 @@ struct dirent* readdir(DIR* dir) strncpy(theent.d_name, entry.name, sizeof( theent.d_name ) ); theent.attribute = entry.attr; theent.size = entry.filesize; + theent.startcluster = entry.firstcluster; return &theent; } diff --git a/firmware/common/dir.h b/firmware/common/dir.h index e03d50901c..274c0b1ea4 100644 --- a/firmware/common/dir.h +++ b/firmware/common/dir.h @@ -32,6 +32,7 @@ struct dirent { unsigned char d_name[256]; int attribute; int size; + int startcluster; }; #endif diff --git a/firmware/common/file.c b/firmware/common/file.c new file mode 100644 index 0000000000..86e1099918 --- /dev/null +++ b/firmware/common/file.c @@ -0,0 +1,170 @@ +/*************************************************************************** + * __________ __ ___. + * Open \______ \ ____ ____ | | _\_ |__ _______ ___ + * Source | _// _ \_/ ___\| |/ /| __ \ / _ \ \/ / + * Jukebox | | ( <_> ) \___| < | \_\ ( <_> > < < + * Firmware |____|_ /\____/ \___ >__|_ \|___ /\____/__/\_ \ + * \/ \/ \/ \/ \/ + * $Id$ + * + * Copyright (C) 2002 by Björn Stenberg + * + * All files in this archive are subject to the GNU General Public License. + * See the file COPYING in the source tree root for full license agreement. + * + * This software is distributed on an "AS IS" basis, WITHOUT WARRANTY OF ANY + * KIND, either express or implied. + * + ****************************************************************************/ +#include +#include "file.h" +#include "fat.h" +#include "types.h" +#include "dir.h" +#include "debug.h" + +#define MAX_OPEN_FILES 4 + +struct filedesc { + unsigned char sector[SECTOR_SIZE]; + int offset; + struct fat_file fatfile; + bool busy; +}; + +static struct filedesc openfiles[MAX_OPEN_FILES]; + +int open(char* pathname, int flags) +{ + DIR* dir; + struct dirent* entry; + int fd; + char* name; + int namelen; + + if ( pathname[0] != '/' ) { + DEBUGF("'%s' is not an absolute path.\n",pathname); + DEBUGF("Only absolute pathnames supported at the moment\n"); + return -1; + } + + /* find a free file descriptor */ + for ( fd=0; fdd_name, namelen) ) { + fat_open(entry->startcluster, &(openfiles[fd].fatfile)); + break; + } + else { + DEBUGF("entry: %s\n",entry->d_name); + } + } + closedir(dir); + if ( !entry ) { + DEBUGF("Couldn't find %s in %s\n",name,pathname); + /* fixme: we need to use proper error codes */ + return -1; + } + + openfiles[fd].offset = 0; + openfiles[fd].busy = TRUE; + return fd; +} + +int close(int fd) +{ + openfiles[fd].busy = FALSE; + return 0; +} + +int read(int fd, void* buf, int count) +{ + int sectors; + int nread=0; + + /* are we in the middle of a cached sector? */ + if ( openfiles[fd].offset ) { + if ( count > (SECTOR_SIZE - openfiles[fd].offset) ) { + memcpy( buf, openfiles[fd].sector, + SECTOR_SIZE - openfiles[fd].offset ); + openfiles[fd].offset = 0; + nread = SECTOR_SIZE - openfiles[fd].offset; + count -= nread; + } + else { + memcpy( buf, openfiles[fd].sector, count ); + openfiles[fd].offset += count; + nread = count; + count = 0; + } + } + + /* read whole sectors right into the supplied buffer */ + sectors = count / SECTOR_SIZE; + if ( sectors ) { + if ( fat_read(&(openfiles[fd].fatfile), sectors, buf+nread ) < 0 ) { + DEBUGF("Failed reading %d sectors\n",sectors); + return -1; + } + nread += sectors * SECTOR_SIZE; + count -= sectors * SECTOR_SIZE; + openfiles[fd].offset = 0; + } + + /* trailing odd bytes? */ + if ( count ) { + /* do we already have the sector cached? */ + if ( count < (SECTOR_SIZE - openfiles[fd].offset) ) { + memcpy( buf + nread, openfiles[fd].sector, count ); + openfiles[fd].offset += count; + nread += count; + count = 0; + } + else { + /* cache one sector and copy the trailing bytes */ + if ( fat_read(&(openfiles[fd].fatfile), 1, + &(openfiles[fd].sector)) < 0 ) { + DEBUGF("Failed reading odd sector\n"); + return -1; + } + memcpy( buf + nread, openfiles[fd].sector, count ); + openfiles[fd].offset = nread; + nread += count; + } + } + + return nread; +} + +/* + * local variables: + * eval: (load-file "../rockbox-mode.el") + * end: + */ diff --git a/firmware/common/file.h b/firmware/common/file.h index 58fb22d881..9d0d6f0501 100644 --- a/firmware/common/file.h +++ b/firmware/common/file.h @@ -33,14 +33,15 @@ #ifndef SIMULATOR extern int open(char* pathname, int flags); extern int close(int fd); - extern int read(int fd, void* buf, int count); -extern int write(int fd, void* buf, int count); - extern int lseek(int fd, int offset, int whence); +#ifdef DISK_WRITE +extern int write(int fd, void* buf, int count); extern int remove(char* pathname); extern int rename(char* oldname, char* newname); +#endif + #else #ifdef WIN32 #include diff --git a/firmware/test/fat/Makefile b/firmware/test/fat/Makefile index 48bddb9630..bd6869e8e9 100644 --- a/firmware/test/fat/Makefile +++ b/firmware/test/fat/Makefile @@ -5,7 +5,7 @@ CFLAGS = -g -Wall -DTEST_FAT -I$(DRIVERS) -I$(FIRMWARE)/common -I$(FIRMWARE) -I. TARGET = fat -$(TARGET): fat.o ata-sim.o main.o disk.o debug.o dir.o +$(TARGET): fat.o ata-sim.o main.o disk.o debug.o dir.o file.o gcc -g -o fat $+ -lfl fat.o: $(DRIVERS)/fat.c $(DRIVERS)/fat.h $(DRIVERS)/ata.h @@ -17,6 +17,9 @@ disk.o: $(FIRMWARE)/common/disk.c dir.o: $(FIRMWARE)/common/dir.c $(CC) $(CFLAGS) -c $< -o $@ +file.o: $(FIRMWARE)/common/file.c + $(CC) $(CFLAGS) -c $< -o $@ + debug.o: $(FIRMWARE)/debug.c $(CC) $(CFLAGS) -c $< -o $@ diff --git a/firmware/test/fat/main.c b/firmware/test/fat/main.c index 13c30b2ed5..0cf06bdac3 100644 --- a/firmware/test/fat/main.c +++ b/firmware/test/fat/main.c @@ -6,6 +6,7 @@ #include "debug.h" #include "disk.h" #include "dir.h" +#include "file.h" void dbg_dump_sector(int sec); void dbg_dump_buffer(unsigned char *buf); @@ -17,7 +18,7 @@ void dbg_dump_sector(int sec) unsigned char buf[512]; ata_read_sectors(sec,1,buf); - printf("---< Sector %d >-----------------------------------------\n", sec); + DEBUGF("---< Sector %d >-----------------------------------------\n", sec); dbg_dump_buffer(buf); } @@ -33,7 +34,7 @@ void dbg_dump_buffer(unsigned char *buf) { c = buf[i*16+j]; - printf("%02x ", c); + DEBUGF("%02x ", c); if(c < 32 || c > 127) { ascii[j] = '.'; @@ -45,39 +46,39 @@ void dbg_dump_buffer(unsigned char *buf) } ascii[j] = 0; - printf("%s\n", ascii); + DEBUGF("%s\n", ascii); } } void dbg_print_bpb(struct bpb *bpb) { - printf("bpb_oemname = \"%s\"\n", bpb->bs_oemname); - printf("bpb_bytspersec = %d\n", bpb->bpb_bytspersec); - printf("bpb_secperclus = %d\n", bpb->bpb_secperclus); - printf("bpb_rsvdseccnt = %d\n", bpb->bpb_rsvdseccnt); - printf("bpb_numfats = %d\n", bpb->bpb_numfats); - printf("bpb_rootentcnt = %d\n", bpb->bpb_rootentcnt); - printf("bpb_totsec16 = %d\n", bpb->bpb_totsec16); - printf("bpb_media = %02x\n", bpb->bpb_media); - printf("bpb_fatsz16 = %d\n", bpb->bpb_fatsz16); - printf("bpb_secpertrk = %d\n", bpb->bpb_secpertrk); - printf("bpb_numheads = %d\n", bpb->bpb_numheads); - printf("bpb_hiddsec = %u\n", bpb->bpb_hiddsec); - printf("bpb_totsec32 = %u\n", bpb->bpb_totsec32); - - printf("bs_drvnum = %d\n", bpb->bs_drvnum); - printf("bs_bootsig = %02x\n", bpb->bs_bootsig); + DEBUGF("bpb_oemname = \"%s\"\n", bpb->bs_oemname); + DEBUGF("bpb_bytspersec = %d\n", bpb->bpb_bytspersec); + DEBUGF("bpb_secperclus = %d\n", bpb->bpb_secperclus); + DEBUGF("bpb_rsvdseccnt = %d\n", bpb->bpb_rsvdseccnt); + DEBUGF("bpb_numfats = %d\n", bpb->bpb_numfats); + DEBUGF("bpb_rootentcnt = %d\n", bpb->bpb_rootentcnt); + DEBUGF("bpb_totsec16 = %d\n", bpb->bpb_totsec16); + DEBUGF("bpb_media = %02x\n", bpb->bpb_media); + DEBUGF("bpb_fatsz16 = %d\n", bpb->bpb_fatsz16); + DEBUGF("bpb_secpertrk = %d\n", bpb->bpb_secpertrk); + DEBUGF("bpb_numheads = %d\n", bpb->bpb_numheads); + DEBUGF("bpb_hiddsec = %u\n", bpb->bpb_hiddsec); + DEBUGF("bpb_totsec32 = %u\n", bpb->bpb_totsec32); + + DEBUGF("bs_drvnum = %d\n", bpb->bs_drvnum); + DEBUGF("bs_bootsig = %02x\n", bpb->bs_bootsig); if(bpb->bs_bootsig == 0x29) { - printf("bs_volid = %xl\n", bpb->bs_volid); - printf("bs_vollab = \"%s\"\n", bpb->bs_vollab); - printf("bs_filsystype = \"%s\"\n", bpb->bs_filsystype); + DEBUGF("bs_volid = %xl\n", bpb->bs_volid); + DEBUGF("bs_vollab = \"%s\"\n", bpb->bs_vollab); + DEBUGF("bs_filsystype = \"%s\"\n", bpb->bs_filsystype); } - printf("bpb_fatsz32 = %u\n", bpb->bpb_fatsz32); - printf("last_word = %04x\n", bpb->last_word); + DEBUGF("bpb_fatsz32 = %u\n", bpb->bpb_fatsz32); + DEBUGF("last_word = %04x\n", bpb->last_word); - printf("fat_type = FAT32\n"); + DEBUGF("fat_type = FAT32\n"); } void dbg_dir(char* currdir) @@ -88,38 +89,40 @@ void dbg_dir(char* currdir) dir = opendir(currdir); if (dir) { - for ( entry = readdir(dir); - entry; - entry = readdir(dir) ) - { - printf("%s (%08x)\n", entry->d_name, entry->size); + while ( (entry = readdir(dir)) ) { + DEBUGF("%15s (%d bytes)\n", entry->d_name, entry->size); } } else { - fprintf(stderr, "Could not open dir %s\n", currdir); + DEBUGF( "Could not open dir %s\n", currdir); } closedir(dir); } -void dbg_type(int cluster) +void dbg_type(char* name) { unsigned char buf[SECTOR_SIZE*5]; - struct fat_file ent; - int i; + int i,fd,rc; - fat_open(cluster,&ent); + fd = open(name,O_RDONLY); + if (fd<0) + return; + DEBUGF("Got file descriptor %d\n",fd); - for (i=0;i<5;i++) - if(fat_read(&ent, 1, buf) >= 0) + for (i=0;i<5;i++) { + rc = read(fd, buf, SECTOR_SIZE/3); + if( rc >= 0 ) { buf[SECTOR_SIZE]=0; - printf("%s\n", buf); + DEBUGF("%d: %d\n", i, rc); } else { - fprintf(stderr, "Could not read file on cluster %d\n", cluster); + DEBUGF("Failed reading file\n"); } + } + close(fd); } char current_directory[256] = "\\"; @@ -127,7 +130,7 @@ int last_secnum = 0; void dbg_prompt(void) { - printf("C:%s> ", current_directory); + DEBUGF("C:%s> ", current_directory); } void dbg_console(void) @@ -173,19 +176,17 @@ void dbg_console(void) { last_secnum++; } - printf("secnum: %d\n", last_secnum); + DEBUGF("secnum: %d\n", last_secnum); dbg_dump_sector(last_secnum); continue; } if(!strcasecmp(s, "type")) { - int cluster = 0; - if((s = strtok(NULL, " \n"))) - { - cluster = atoi(s); - } - dbg_type(cluster); + s = strtok(NULL, " \n"); + if (!s) + continue; + dbg_type(s); continue; } @@ -196,6 +197,8 @@ void dbg_console(void) } } } + else + quit = 1; } } -- cgit v1.2.3