+#define pffs_check_magic(data) (((data)&PFFS_INDEX_MAGIC_MASK)==PFFS_INDEX_MAGIC)
+#define pffs_fnlen(data) (((data)&PFFS_FNLEN_MASK)>>4)
+#define pffs_daddr_msb(data) (((data)&PFFS_LEN_MSB_MASK))
+#define pffs_sec_erase(pffs,sec) pffs->fe(pffs->base_addr|pffs->sec_addr[sec])
+
+u32 pffs_find_index(t_pffs *pffs,u8 sector) {
+
+ u16 data;
+
+ pffs->fr(pffs->base_addr+pffs->sec_addr[sector],&data,2);
+
+ if((data&0xf000)==PFFS_INDEX_MAGIC) {
+ pffs->index_sec=sector;
+ return PFFS_INDEX_FOUND;
+ }
+
+ return PFFS_NO_INDEX_FOUND;
+}
+
+int pffs_sec_empty(t_pffs *pffs,u8 sec) {
+
+ u32 addr;
+ u16 data;
+
+ addr=pffs->base_addr|pffs->sec_addr[sec];
+
+ while(addr<(pffs->base_addr|pffs->sec_addr[sec+1])) {
+ pffs->fr(addr,&data,2);
+ if(data!=0xffff)
+ return PFFS_SEC_NOT_EMPTY;
+ addr+=2;
+ }
+
+ return PFFS_SEC_EMPTY;
+}
+
+int pffs_find_data_tmp(t_pffs *pffs,u8 sector) {
+
+ u32 iaddr,daddr,dend,dstart;
+ u16 data[3];
+ u8 fnlen;
+
+ iaddr=pffs->base_addr|pffs->sec_addr[pffs->index_sec];
+ dstart=pffs->sec_addr[sector];
+ dend=pffs->sec_addr[sector+1];
+
+ while(iaddr<(pffs->base_addr|pffs->sec_addr[sector+1])) {
+ pffs->fr(iaddr,data,6);
+ if(pffs_check_magic(data[0]))
+ break;
+ daddr=pffs_daddr_msb(data[0])|data[1];
+ if((daddr+data[2]<dstart)|(daddr>=dend)) {
+ fnlen=pffs_fnlen(data[0]);
+ iaddr+=(6+fnlen+fnlen);
+ continue;
+ }
+ else
+ return PFFS_NO_DATA_TMP;
+ }
+
+ pffs->data_tmp_sec=sector;
+ if(pffs_sec_empty(pffs,sector)!=PFFS_SEC_EMPTY)
+ pffs->fe(pffs->base_addr|dstart);
+
+ return PFFS_DATA_TMP_FOUND;;
+}
+
+int pffs_orientate(t_pffs *pffs) {
+
+ u8 sec,sec0,sec1,found;
+
+ sec0=pffs->sec_num_index[0];
+ sec1=pffs->sec_num_index[1];
+
+ found=0;
+
+ /* check index sectors */
+ if(pffs_find_index(pffs,sec0)==PFFS_INDEX_FOUND)
+ found=1;
+ else if(pffs_find_index(pffs,sec1)==PFFS_INDEX_FOUND)
+ found=1;
+
+ /* chose temp data sector */
+ if(found) {
+ sec0=pffs->sec_num_data[0];
+ sec1=pffs->sec_num_data[1];
+ for(sec=sec1;sec>=sec0;sec--)
+ if(pffs_find_data_tmp(pffs,sec)==PFFS_DATA_TMP_FOUND)
+ break;
+
+ return PFFS_INDEX_FOUND;
+ }
+
+ /* initial run => no data + no index assumed => check whether erased! */
+ // erase index sectors
+ if(!pffs_sec_empty(pffs,sec0))
+ pffs_sec_erase(pffs,sec0);
+ if(!pffs_sec_empty(pffs,sec1))
+ pffs_sec_erase(pffs,sec1);
+ pffs->index_sec=sec0;
+ // erase data sectors
+ sec0=pffs->sec_num_data[0];
+ sec1=pffs->sec_num_data[1];
+ pffs->data_tmp_sec=sec1;
+ for(sec=sec0;sec<=sec1;sec++)
+ if(!pffs_sec_empty(pffs,sec))
+ pffs_sec_erase(pffs,sec);
+
+ return 0;
+}
+
+int pffs_get_data_sec(t_pffs_fd *fd) {
+
+ t_pffs *pffs;
+ u8 sec,sec0,sec1;
+
+ pffs->fd->pffs;
+ sec0=pffs->sec_num_data[0];
+ sec1=pffs->sec_num_data[1];
+
+ for(sec=sec0;sec<sec1;sec++) {
+ if((addr<pffs->sec_addr[sec+1])&(addr>=pffs->sec_addr[sec])) {
+ fd->data_sec=sec;
+ break;
+ }
+ }
+
+ return 0;
+}
+
+int pffs_rearrange(t_pffs *pffs) {
+
+
+
+ return 0;
+}
+
+int pffs_flash_register(t_pffs *pffs,u32 base_addr,u32 *sec_addr,
+ u8 sec_num_data_min,u8 sec_num_data_max,
+ u8 sec_num_index0,u8 sec_num_index1,