+int pffs_find_file(t_pffs *pffs,char *file,u32 *iaddr,u32 *daddr,u16 *len) {
+
+ u8 fnl;
+ u16 data[PFFS_MAX_FILENAME_SIZE+PFFS_HEADER_SIZE];
+
+ *iaddr=pffs->base_addr|pffs->sec_addr[pffs->index_sec];
+
+ while(*iaddr<pffs->sec_addr[pffs->index_sec+1]) {
+ pffs->fr(*iaddr,data,3);
+
+ if(!pffs_check_magic(data[0]))
+ break;
+
+ fnl=pffs_fnlen(data[0]);
+ pffs->fr(*iaddr+6,data+3,fnl+fnl);
+
+ if(!strncmp(file,(char *)(data+3),fnl+fnl)) {
+ *daddr=pffs->base_addr|((data[0]&0x000f)<<16)|data[1];
+ *len=data[2];
+ return PFFS_FILE_FOUND;
+ }
+
+ *iaddr+=(6+fnl+fnl);
+ }
+
+ return PFFS_FILE_NOT_FOUND;
+}
+
+int pffs_open_read(t_pffs_fd *fd) {
+
+ int ret;
+
+ ret=pffs_find_file(fd->pffs,fd->file,
+ &(fd->iaddr),&(fd->daddr),&(fd->len));
+
+ if(ret==PFFS_FILE_FOUND) {
+ fd->dptr=fd->daddr;
+ fd->mode=PFFS_READ;
+ }
+
+ return ret;
+}
+
+int pffs_write_index_init(t_pffs_fd *fd) {
+
+ t_pffs *pffs;
+ u16 data[PFFS_HEADER_SIZE+PFFS_MAX_FILENAME_SIZE];
+
+ pffs=fd->pffs;
+ fns=fd->fn-size;
+
+ if(fd->iaddr+6+fns+fns>=pffs->sec_addr[pffs->index_sec+1])
+ return PFFS_NO_INDEX_SPACE_LEFT;
+
+ data[0]=0x7f00|(fns<<4)|((fd->daddr>>16)&0xf);
+ data[1]=fd->daddr&0xffff;
+ pffs->fw(fd->iaddr,data,4);
+ pffs->fw(fd->iaddr+6,fd->file,fns+fns);
+
+ return PFFS_INDEX_WROTE_INIT;
+}
+
+int pffs_write_finish(t_pffs_fd *fd) {
+
+ fd->pffs->fw(fd->iaddr+4,&(fd->len),2);
+
+ return 0;
+}
+
+int pffs_open_write(t_pffs_fd *fd) {
+
+ int ret;
+
+ ret=pffs_find_file(fd->pffs,fd->file,
+ &(fd->iaddr),&(fd->daddr),&(fd->len));
+
+ switch(ret) {
+ case PFFS_FILE_NOT_FOUND:
+ ret=pffs_write_index_init();
+ if(ret!=PFFS_INDEX_WROTE_INIT)
+ break;
+ fd->dptr=fd->daddr;
+ fd->len=0;
+ fd->mode=PFFS_WRITE;
+ break;
+ case PFFS_FILE_FOUND:
+ default:
+ break;
+ }
+
+ return ret;
+}
+
+int pffs_open(t_pffs *pffs,t_pffs_fd *fd,char *file,u8 mode) {
+
+ int ret;
+
+ /* the pffs struct */
+ fd->pffs=pffs;
+
+ /* filename */
+ fd->fn_size=strlen(file);
+ if(fd->fn_size&1)
+ fd->file[fd->fn_size++]='\0';
+ fd->fn_size>>1;
+ if(fd->fn_size>PFFS_MAX_FILENAME_SIZE)
+ return PFFS_FILENAME_TOO_LONG;
+ strncpy(fd->file,file,fd->fn_size+fd->fn_size);
+
+ /* clear fd mode */
+ fd->mode=0;
+
+ /* action */
+ switch(mode) {
+ case PFFS_READ:
+ ret=pffs_open_read(fd);
+ break;
+ case PFFS_WRITE:
+ ret=pffs_open_write(fd);
+ break;
+ case PFFS_RDWR:
+ default:
+ return PFFS_MODE_UNSUPPORTED;
+ }
+
+ return ret;
+}
+
+int pffs_read(t_pffs_fd *fd,u8 *buf,int len) {
+
+ int missing;
+ int sec_end;
+
+ /* check whether valid */
+ if(!(fd->mode&PFFS_READ))
+ return PFFS_EINVAL;
+
+ /* check len */
+ if(len&1)
+ return PFFS_INVALID_LEN;
+
+ /* check how much we read */
+ missing=fd->len-(fd->dptr-fd->daddr);
+ if(len>missing)
+ len=missing;
+
+ if((fd->dptr+len)>=pffs->sec_addr[pffs->sec_num_data[1]+1])
+ sec_end=pffs->sec_addr[pffs->sec_num_data[1]+1]-fd->dptr;
+
+
+ /* read */
+ fd->pffs->fr(fd->dptr,(u16 *)buf,len);
+ fd->dptr+=len;;
+
+ return len;
+}
+
+int pffs_write(t_pffs_fd *fd,u8 buf,int len) {
+
+ /* check whether valid */
+ if(!(fd->mode&PFFS_WRITE))
+ return PFFS_EINVAL;
+
+ /* check len */
+ if(len&1)
+ return PFFS_INVALID_LEN;
+
+ missing=PFFS_MAX_FILE_SIZE-fd->len;
+ if(len>missing)
+ len=missing;
+
+ /* check for */
+ if(fd->dptr+len>=pffs->)
+}
+