⭐ 欢迎来到虫虫下载站! | 📦 资源下载 📁 资源专辑 ℹ️ 关于我们
⭐ 虫虫下载站

📄 dirlist.c

📁 一款MP3 Player Firmware 的原代码,非常有参考价值
💻 C
📖 第 1 页 / 共 2 页
字号:
#include <8051.h>#include <string.h>#include "as31glue.h"#include "printf.h"#include "paulmon2.h"#include "dirlist.h"#include "malloc.h"#include "playlist.h"#include "display.h"#include "stricmp.h"// #define VERBOSE_DEBUGsimm_id /* dirlist_t * */ root; // The root dirent_structstatic xdata struct dirent_struct dl_fileinfo;static dirlist_t * dl_parent;static dirlist_t * data dl_struct;static filelist_t * data fl_struct; data simm_id temp_id;// Limit Directory Depth (See dirlist.h for max depth define)static xdata unsigned char subdir_depth;/* static*/ xdata unsigned long dirlist_time_count;/* static*/ xdata unsigned int mp3_file_count;/* static*/ xdata unsigned int m3u_file_count;/* static*/ xdata unsigned int total_file_count;/* static*/ xdata unsigned int directory_count;static simm_id m3u_list_start=0;static simm_id m3u_list_end=0;static xdata char pathname_buffer[320];#pragma CALLEE-SAVES test_file_extension;char test_file_extension(void);void dirlist_read_dir(dirlist_t *this_dir);void filelist_show(simm_id /* dirlist_t */ dir);// m3u stuffxdata char *this_dirname;#pragma SAVE#pragma NOGCSEvoid dirlist_add_dir(simm_id /* dirlist_t * */ directory) reentrant{  simm_id sub_directory;  // DO NOT add any non-static local variables here, as they  // will rapidly overflow the 8051's limited stack space!  if(++subdir_depth > MAX_SUBDIR_DEPTH) {        print("Maximum subdir depth reached\r\n");	subdir_depth--;	return;  }  dirlist_read_dir(addr5(directory));  //filelist_show(directory);  sub_directory = ((dirlist_t *)addr5(directory))->subdir_start;  while(sub_directory != 0) {      // playlist names are full pathname      full_pathname(sub_directory);      temp_id = simm_malloc(strlen_asm(pathname_buffer) + 1);      strcpy(addr7(temp_id), pathname_buffer);      print("\\[\\B \"");      print_str_n(pathname_buffer, 24);      print("\\]\r\n");      playlist_create(temp_id);      dirlist_add_dir(sub_directory);      sub_directory = ((dirlist_t *)addr5(sub_directory))->next;    }  subdir_depth--;  // on return from this function the next directory in the queue is processed}/* read a directory from the disk drive into a dirlist_struct *//* and populate all the dirlist_struct and filelist_struct's *//* that it points to.  The "this_dir" will be passed using *//* addr5, so this function must not contain any calls to *//* the addr5 function! */static xdata simm_id fl_struct_id_state;/* this bit is set by file_cache_work when it is waiting *//* for a FAT sector and can not continue to process the file *//* until that sector is transfered.  The bit is cleared by the *//* IDE driver every time a sector group is transfered.  This *//* ugly hack allows us to avoid calling file_cache_work when *//* it is useless to do so. */static bit at 0x18 fcw_is_waiting;static bit fl_struct_already_allocated;static bit caching_dir;static bit seek_needed;static bit this_dir_filelist_started;void dirlist_read_dir(dirlist_t *this_dir){  xdata char r;  xdata char dir_fd;  //xdata char *bu;  //data simm_id temp_dl;  xdata char *filename;#ifdef VERBOSE_DEBUG  r = SP;  print("Entered dirlist_read_dir, dir ");  print_str(Addr6(this_dir->long_name));  print("(depth=");  print_uint8(subdir_depth);  print("sp=");  print_uint8(r);  print(")\r\n");#endif  fl_struct_already_allocated = 0;  directory_count++;  dir_fd = file_open_by_1st_cluster(this_dir->cluster);  file_cache(dir_fd, 0, 0xFFFFFFFF);  // request entire directory cached  caching_dir = 1;  seek_needed = 1;#if 1  do {    r = file_cache_work(dir_fd);    if (r == 2) pm2_exit();    do_ide_loop(4);  } while (r == 0);  do_ide_loop(8);  file_seek(dir_fd, 0);#endif	/* a minor speedup... use a fast "bit" instead of checking */	/* this 32 bit value indirectly accessed in xdata (slow) */	if (this_dir->filelist_start == 0) {		this_dir_filelist_started = 0;	} else {		this_dir_filelist_started = 1;	}  while(1) {#if 0    /* this crazy idea is to be reading the directory and parsing */    /* it at the same time.  It does not work yet... :(  */    if (caching_dir && !fcw_is_waiting) {	r = file_cache_work(dir_fd);	if (r == 2) pm2_exit();	if (r) caching_dir = 0;    }    if (seek_needed) {	r = file_seek(dir_fd, 0);	if (r == 0) {		seek_needed = 0;	} else {		continue;	}    }#endif    if (fl_struct_already_allocated) {        temp_id = fl_struct_id_state;        fl_struct_already_allocated = 0;    } else {	temp_id = simm_malloc(sizeof(filelist_t));    }    fl_struct = addr7(temp_id); // common case: files rather than directories    r = dir_read_fast(dir_fd, fl_struct);    if (r == 1) {      // print("dir_read_fast returned 1 (xfer pending)\r\n");      do_ide_loop(4); // data wasn't in cache yet.      continue;    }    if (r) break;     // all other errors, stop reading this directory#ifdef VERBOSE_DEBUG    print("attrib=");    print_hex16(fl_struct->attrib);    print(":  ");    /* printf("a=%x, len=%d, ",         fl_struct->attrib, fl_struct->name_length); */    /* printf("ext=%c%c%c, ", (char)fl_struct->extension[0],	   (char)fl_struct->extension[1],	   (char)fl_struct->extension[2]); */    /* printf("clust=%lx, ", fl_struct->cluster); */    /* printf("size=%lx: ", fl_struct->size); */#endif    if (fl_struct->attrib == 0x17) {        print("Skipping RECYCLED directory\r\n");        continue;    }    if ((fl_struct->attrib & 0x0C) != 0) {        print("Skipping system/hidden file\r\n");        continue;    }    // allocate memory and read filename.  Initial length is rounded    // up to nearest entry boundary (13) - length is adjusted upon    // reading of actual entry.    fl_struct->long_name = simm_malloc(fl_struct->name_length);    filename = Addr6(fl_struct->long_name);    dir_read_fast_name(filename);#ifdef VERBOSE_DEBUG    print_str(filename);    print_crlf();#endif    if(fl_struct->attrib & 0x10) {        if (*filename != '.') {	  // abnormal case - copy data from fl_struct to dl_struct;#ifdef VERBOSE_DEBUG	  print("Processing directory: ");          print_str(filename);          print_crlf();#endif          fl_struct_id_state = temp_id;  // save id of allocated fl_struct          fl_struct_already_allocated = 1;          temp_id = simm_malloc(sizeof(dirlist_t));          dl_struct = addr6(temp_id);          // TODO: replace with a fast memcpy	  memcpy(dl_struct, fl_struct, 17); // copy first 6 items between structs	  if(this_dir->subdir_start == 0) {	    this_dir->subdir_start = temp_id;	    this_dir->subdir_end = temp_id;	    dl_struct = addr6(temp_id);	    dl_struct->prev = 0;	  } else {	    dl_struct = Addr6(this_dir->subdir_end);	    dl_struct->next = temp_id;	    dl_struct = addr6(temp_id);	    dl_struct->prev = this_dir->subdir_end;	    this_dir->subdir_end = temp_id;	  }	  dl_struct->next = 0;	  dl_struct->subdir_start = 0;	  dl_struct->subdir_end = 0;	  dl_struct->filelist_start = 0;	  dl_struct->filelist_end = 0;          dl_struct->parent_dir = simm_id_from_pointer(this_dir);	  dl_struct->open = 1;	  dl_struct->treedir_expand = 0;// directory not expanded	}    } else {	total_file_count++;        switch (test_file_extension()) {          case 1:  /* MP3 extension */	    //if(this_dir->filelist_start == 0) {	    if (!this_dir_filelist_started) {	      this_dir->filelist_start = temp_id;	      this_dir->filelist_end = temp_id;              fl_struct->prev = 0;	      this_dir_filelist_started = 1;            } else {              fl_struct = Addr7(this_dir->filelist_end);              fl_struct->next = temp_id;              fl_struct = addr7(temp_id);              fl_struct->prev = this_dir->filelist_end;              this_dir->filelist_end = temp_id;	    }	    fl_struct->next = 0;	    playlist_add_file(temp_id);   // TODO, move this someday            mp3_file_count++;            break;          case 2:  /* M3U extension */	    // add m3u file to list to process later	    if(m3u_list_start == 0) {	      m3u_list_start = temp_id;	      m3u_list_end = temp_id;	      fl_struct->prev=0;            } else {              fl_struct = Addr7(m3u_list_end);              fl_struct->next = temp_id;              fl_struct = addr7(temp_id);              fl_struct->prev = m3u_list_end;              m3u_list_end = temp_id;	    }	    fl_struct->next=0;	    print("Playlist ");            print_str(filename);            print(" queued\r\n");            m3u_file_count++;            break;	  default:	    // this really slows things down if there are a lot of	    // non-mp3 files on the hard drive	    //print("Unknown file extension, ignoring: ");            //print_str(filename);            //print_crlf();		;        }    }  }  file_close(dir_fd);   free_fat_memory();}void m3u_list_show() {   temp_id = m3u_list_start;   print("M3U files found:\r\n");   while (temp_id != 0) {     fl_struct = addr6(temp_id);     print_str(Addr7(fl_struct->long_name));     print("cluster=");     print_hex32(fl_struct->cluster);     print("size=");     print_hex32(fl_struct->size);     printf("ext=%c%c%c\r\n", (char) fl_struct->extension[0],	    (char) fl_struct->extension[1], (char) fl_struct->extension[2]);     temp_id = fl_struct->next;   }}// allow for leading /, dirs, and filename parts #define MAX_M3U_PATH_PARTS (MAX_SUBDIR_DEPTH+2)static volatile xdata char * data m3u_ptr;static unsigned long m3u_size;static xdata char * m3u_pathname[MAX_M3U_PATH_PARTS];static unsigned char num_path_parts;volatile static xdata at 0xFF08 unsigned int block_4000_mapping;volatile static xdata at 0xFF0A unsigned int block_5000_mapping;//volatile static xdata at 0xFF0C unsigned int block_6000_mapping;//volatile static xdata at 0xFF0E unsigned int block_7000_mapping;unsigned char parse_next_m3u_line(xdata char fd){  //print("parse next line");  //print_crlf();  if(m3u_ptr > (xdata char *)0x4FFF) {    block_4000_mapping = block_5000_mapping; // remap 0x5000 block to 0x4000    m3u_size-=4096;    if(m3u_size>4096) // load new 0x5000 block in if necessary      file_mem_map(fd, 5); // map next 4k of file to 'address block' 5    m3u_ptr-=4096; // change m3u_ptr to point to same position within 0x4000  }  num_path_parts = 0;  m3u_pathname[0] = m3u_ptr;  //printf("m3u_ptr=%d\r\n", m3u_ptr);  //print("m3u_size = ");  //print_hex32(m3u_size);  //print_crlf();  while (m3u_size>4096 || (m3u_ptr < (xdata char *)(0x4000 + m3u_size))) {    switch (*m3u_ptr) {      case '\\':      case '/':	//if(start_of_line) // ignore leading / if present	//  break;	// hmmm, are .m3u files specified relative to the directory	// in which they are in? if so, we need to take account of	// leading slashes to indicate start searching from root dir	// and store a ptr to the 'current' directory (where the .m3u	// file is stored as a baseline	// TODO: store a ptr to the base directory, then if leading /	//       go to root (in m3u_add_file)	*m3u_ptr = 0;	if(++num_path_parts<MAX_M3U_PATH_PARTS) {	  m3u_pathname[num_path_parts]=m3u_ptr+1;	} else {	  print("Too many parts in m3u path name");	  print_crlf();	  // return num_path_parts (not -1) so accesible data is returned,	  // even if of no use, but also so it still tries next line	  return num_path_parts;	}	break; // unused code      case 10:      case 13:	*m3u_ptr = 0;	m3u_ptr++;	if (*m3u_ptr == 10 || *m3u_ptr == 13) {	  *m3u_ptr = 0;	  m3u_ptr++;	}	return (num_path_parts + 1);      default:	break; // do nothing    }    m3u_ptr++;  }  *m3u_ptr = 0;  //print("end of file");  //print_crlf();  return 0;	// hit end of file...}void m3u_add_file() {

⌨️ 快捷键说明

复制代码 Ctrl + C
搜索代码 Ctrl + F
全屏模式 F11
切换主题 Ctrl + Shift + D
显示快捷键 ?
增大字号 Ctrl + =
减小字号 Ctrl + -