X-Git-Url: https://hackdaworld.org/gitweb/?p=my-code%2Farm.git;a=blobdiff_plain;f=betty%2Fpffs.c;h=1257d184f32c1332fb7b4f01aefeea1f87c10a1a;hp=995e1082c56b3450078e95468f68661c8725e400;hb=bbf7d44cf935538f5a353665f160e5cd3ed59da8;hpb=94909b5b893d5c60bc44bbafec8de1b3c86d9595 diff --git a/betty/pffs.c b/betty/pffs.c index 995e108..1257d18 100644 --- a/betty/pffs.c +++ b/betty/pffs.c @@ -11,15 +11,102 @@ * functions */ -int pffs_flash_register(t_pffs *pffs,u32 base_addr,u8 sec_num,u32 *sec_addr, - u8 dmin,u8 dmax,u8 index1,u8 index2, +u32 pffs_get_ptr(t_pffs *pffs,u8 sector) { + + u16 data[3]; + u32 iaddr; + u32 daddr; + u8 fnlen; + u8 found; + + iaddr=0; + daddr=0; + found=0; + + while(1) { + pffs->fr(pffs->base_addr+pffs->sec_addr[sector]+iaddr,data,6); + if(!((data[0]&0xff00)==PFFS_INDEX_MAGIC)) + break; + found=1; + fnlen=(data[0]&0x00f0)>>4; + iaddr+=(6+fnlen+fnlen); + daddr=((data[0]&0x000f)<<16)|data[1]; + } + + pffs->data_ptr=daddr; + + if(found) { + pffs->index_ptr[0]=pffs->sec_addr[sector]; + pffs->index_ptr[1]=pffs->sec_addr[sector]+iaddr; + return 0; + } + else + return -1; +} + +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])) { + data=*((u16 *)(addr)); + if(data!=0xffff) + return 0; + addr+=2; + } + + return 1; +} + +#define pffs_sec_erase(pffs,sec) pffs->fe(pffs->base_addr|pffs->sec_addr[sec]) + +int pffs_orientate(t_pffs *pffs) { + + u8 sec,sec0,sec1; + + /* check index sectors */ + sec0=pffs->sec_num_index[0]; + sec1=pffs->sec_num_index[1]; + if(!(pffs_get_ptr(pffs,sec0)&pffs_get_ptr(pffs,sec1))) + return 0; + + /* 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); + // erase data sectors + sec0=pffs->sec_num_data[0]; + sec1=pffs->sec_num_data[1]; + for(sec=sec0;sec<=sec1;sec++) + if(!pffs_sec_empty(pffs,sec)) + pffs_sec_erase(pffs,sec); + + 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, int (*fw)(u32 addr,u16 *buf,int len), int (*fr)(u32 addr,u16 *buf,int len), int (*fe)(u32 addr)) { + /* assign physical flash specs */ pffs->base_addr=base_addr; - pffs->sec_num=sec_num; pffs->sec_addr=sec_addr; + + /* specified index and data sectors */ + pffs->sec_num_data[0]=sec_num_data_min; + pffs->sec_num_data[1]=sec_num_data_max; + pffs->sec_num_index[0]=sec_num_index0; + pffs->sec_num_index[1]=sec_num_index1; + + /* flash acccess function pointers */ pffs->fw=fw; pffs->fr=fr; pffs->fe=fe; @@ -31,9 +118,87 @@ int pffs_flash_register(t_pffs *pffs,u32 base_addr,u8 sec_num,u32 *sec_addr, int pffs_init(t_pffs *pffs) { + /* check whether a flash is registered */ if(!(pffs->state&PFFS_REGISTERED)) return -1; + /* orientate */ + pffs_orientate(pffs); + + return 0; +} + +#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)&)) + +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]; + + pffs->index_ptr[2]=pffs->base_addr|pffs->index_ptr[0]; + + while(pffs->index_ptr[2]index_ptr[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(fd->file,(char *)(data+3),fnl+fnl)) { + *daddr=((data[0]&0x000f)<<16)|data[1]; + *len=data[2]; + pffs->index_ptr[2]=*iaddr; + return PFFS_FILE_EXISTS; + } + pffs->fr(iaddr,data,3); + } + + return PFFS_FILE_NOT_FOUND; +} + +int pffs_open_read(t_pffs *pffs,t_pffs_fd *fd) { + + u32 iaddr; + u32 daddr; + u16 data[PFFS_MAX_FILENAME+PFFS_HEADER_SIZE]; + + iaddr=pffs->base_addr|pffs->index_ptr[0]; + + return 0x23; +} + +int pffs_open(t_pffs *pffs,t_pffs_fd *fd,char *file,u8 mode) { + + /* the pffs struct */ + fd->pffs=pffs; + + /* filename */ + fd->fn_size=strlen(file); + if(fd->fn_size>30) + return PFFS_FILENAME_TOO_LONG; + strncpy(fd->file,file,fd->fn_size); + if(fd->fn_size&1) + fd->file[fd->fn_size++]='\0'; + + /* mode */ + fd->mode=mode; + + /* action */ + switch(mode) { + case PFFS_READ: + pffs_open_read(pffs,fd); + break; + case PFFS_WRITE: + break; + case PFFS_RDWR: + default: + return PFFS_MODE_UNSUPPORTED; + } + return 0; }