📄 dirlist.c
字号:
// TODO: search through directories to add this to the playlist // TODO: implement linear search just to 'get it going' // TODO: work out faster search algorithm (tree/hash table?) xdata unsigned char i, r; data simm_id temp_id2; xdata char *temp_string; i=0; r=0; // reqd. to avoid aslink warning // TODO: take account of .m3u file's base directory // assume leading / for now temp_id=root; // TODO: check for leading slash (m3u_pathname[0]=="") // once we start from .m3u file's base dir while(temp_id != 0) { dl_struct=addr7(temp_id); this_dirname = m3u_pathname[i]; if(i==num_path_parts) { //print("found correct directory"); //print_crlf(); //print("searching for file "); //print_str(m3u_pathname[i]); //print_crlf(); // traverse files list until match found temp_id2 = dl_struct->filelist_start; while(temp_id2!=0) { fl_struct=addr7(temp_id2); temp_string=Addr6(fl_struct->long_name); //print("comparing "); //print_str(temp_string); //print_crlf(); r = stricmp(temp_string, this_dirname); if(r == 0) { //print("[success!!]"); //print_crlf(); break; } temp_id2=fl_struct->next; } // if file found, add file to playlist if(r==0) { //print("found "); //print_str(this_dirname); //print_crlf(); //playlist_add_file(/*filelist_struct*/ temp_id2); return; } else { //print("cannot find "); //print_str(this_dirname); //print_crlf(); break; } } else { // ignore leading drive name (e.g. "G:") if(i==0 && this_dirname[1]==':') { //print("skipping "); //print_str(this_dirname); //print_crlf(); i++; continue; } else { //print("searching for '"); //print_str(this_dirname); //print("' directory "); //print_uint8(i); //print_crlf(); // traverse subdirs list until match found temp_id2 = dl_struct->subdir_start; while(temp_id2 != 0) { dl_struct=addr7(temp_id2); temp_string=Addr6(dl_struct->long_name); //print("comparing "); //print_str(temp_string); //print_crlf(); r = stricmp(temp_string, this_dirname); if(r == 0) { //print("[success!!]"); //print_crlf(); temp_id = temp_id2; break; } temp_id2=dl_struct->next; } if(r != 0) { // if directory not found, give up on this line //print("cannot find "); //print_str(this_dirname); //print("directory"); //print_crlf(); break; } } } // directory found, continue loop //print("match found!"); //print_crlf(); //i++; //continue; i++; //dl_struct=addr7(temp_id); //temp_id = dl_struct->next; } print("leaving m3u_add_file"); print_crlf();}void process_m3u() { xdata char r, fd; simm_id head_id; simm_id tail_id; simm_id file_id; file_id=m3u_list_start; head_id=0; tail_id=0;#if 0 // temporary hack to avoid my .m3u test file 1 and go straight to test file 2 fl_struct=addr7(file_id); file_id = fl_struct->next;#endif print("processing m3u files:\r\n"); while (file_id != 0) { fl_struct = addr7(file_id); print_str(Addr6(fl_struct->long_name)); print("cluster="); print_hex32(fl_struct->cluster); print("size="); print_hex32(fl_struct->size); print_crlf(); // load m3u file in fd = file_open_by_1st_cluster(fl_struct->cluster); file_cache(fd, 0, 0xFFFFFFFF); // request entire file cached do { do_ide_loop(4); r = file_cache_work(fd); if (r == 2) pm2_exit(); } while (r == 0); do_ide_loop(8); file_seek(fd, 0); m3u_size = fl_struct->size; // read first 4k of file into file_mem_map(fd, 4); // map first 4k in file to 'address block' 4 if(m3u_size>4096) { // load next 4k block into 0x5000 file_mem_map(fd, 5); } // we could make it a condition of processing a .m3u file that it starts // with #EXTM3U. I've not seen any without it and there's no other easy // way to check its definately a m3u format file (list of directories, // comment lines begin with #) m3u_ptr = (xdata char *)(0x4000); /*printf("m3u file: [%c,%c,%c]\r\n", (char) m3u_ptr[0], (char) m3u_ptr[1], (char) m3u_ptr[2]);*/ // create playlist //print("creating playlist\r\n"); // TODO: maybe remove .m3u extension from name playlist_create(fl_struct->long_name); //print("created playlist, loading m3u file in\r\n"); while(parse_next_m3u_line(fd)) { this_dirname = m3u_pathname[0]; //print(">"); //print_str(this_dirname); //print_crlf(); if(this_dirname[0]=='#') // ignore comment lines in file continue; //for(i=0; i<=num_path_parts; i++) { //print("[/]"); //print_str(m3u_pathname[i]); //} print_crlf(); m3u_add_file(); // TODO: pass directory in which .m3u file is located } // set up for next m3u file file_close(fd); // TODO: remove the dirlist entry from the list, and free that memory. fl_struct=Addr7(file_id); // playlist_add_file uses addr7 file_id = fl_struct->next; } print("leaving process_m3u\r\n");}void dirlist_init(){ // simm_id temp_id; //xdata struct dirstack_struct * this_dirstack_entr; unsigned int ticks; xdata char *root_name; // debug = 1; m3u_list_start=0; m3u_list_end=0; mp3_file_count=0; m3u_file_count=0; total_file_count=0; directory_count=0; dirlist_time_count=clock_tick(); temp_id = simm_malloc((unsigned int)(sizeof(char) * 2)); root_name = addr6(temp_id); *root_name = '/'; *(root_name + 1) = 0; //printf("root long name initialised to %s\r\n", root_name); subdir_depth = 0; root = simm_malloc((unsigned int)(sizeof(struct dirlist_struct))); dl_struct = Addr6(root); dl_struct->subdir_start = 0; dl_struct->subdir_end = 0; dl_struct->filelist_start = 0; dl_struct->filelist_end = 0; dl_struct->cluster = get_root_1st_cluster(); dl_struct->next=0; dl_struct->prev=0; dl_struct->parent_dir=0; dl_struct->long_name=temp_id; playlist_create(dl_struct->long_name); // *** reinserted these lines to fix my cock-up dirlist_add_dir(root); // *** ticks = (unsigned int)(clock_tick() - dirlist_time_count); printf("\r\n*** Found %u files (%u MP3 & %u M3U) in %u directories", total_file_count, mp3_file_count, m3u_file_count, directory_count); printf(" in %u.%u seconds ***\r\n\r\n", ticks / 10, ticks % 10); // debug = 0;}void filelist_show(simm_id /* dirlist_t */ dir){ temp_id = ((dirlist_t *)Addr6(dir))->filelist_start; while (temp_id != 0) { fl_struct = addr6(temp_id); printf("%s, %lx\r\n", Addr7(fl_struct->long_name), fl_struct->cluster); temp_id = fl_struct->next; }}/* allocate only one copy in xdata, instead of a separate copy *//* on the (limited) stack for each recursive call */static xdata unsigned char indent_count;void dirlist_show_helper(simm_id /* dirlist_t */ dir, unsigned char indent) reentrant{ simm_id subdir; // files dl_parent = addr6(dir); temp_id = dl_parent->filelist_start; while(temp_id != 0) { for(indent_count=0; indent_count<indent; indent_count++) print(" "); fl_struct = addr6(temp_id); print_str(Addr7(fl_struct->long_name)); print_hex32(fl_struct->cluster); print_crlf(); temp_id = fl_struct->next; } // directories subdir = ((dirlist_t *)addr6(dir))->subdir_start; while(subdir != 0) { for(indent_count=0; indent_count<indent; indent_count++) print(" "); dl_struct = addr6(subdir); print("(dir) "); print_str(Addr7(dl_struct->long_name)); print_crlf(); dirlist_show_helper(subdir, indent+1); subdir = ((dirlist_t *)addr6(subdir))->next; }}void dirlist_show(){ unsigned char x = 0; print("Dumping directory list...\r\n"); dirlist_show_helper(root,x);}xdata char * full_pathname(simm_id dir){ xdata simm_id dir_chain[MAX_SUBDIR_DEPTH]; unsigned char num=0; xdata char *p, *name; /* build a list of all the parent directories */ do { dir_chain[num++] = dir; dir = ((dirlist_t *)Addr7(dir))->parent_dir; } while (dir != 0 && num < MAX_SUBDIR_DEPTH); /* traverse the list and build the full pathname string */ /* TODO: should check for buffer overrun of pathname_buffer */ p = pathname_buffer; do { num--; if (dir_chain[num] == root) continue; *p++ = '/'; name = Addr7(((dirlist_t *)Addr6(dir_chain[num]))->long_name); while (*name) { *p++ = *name++; } } while (num != 0); *p = '\0'; return pathname_buffer;}#pragma RESTORE// checks the file extension in "fl_struct" (global pointer)// return values:// 0 = no match// 1 = MP3// 2 = M3U#pragma SAVE#pragma LESS_PEDANTICchar test_file_extension(void){ _asm mov dpl,_fl_struct mov dph,(_fl_struct+1) inc dptr inc dptr movx a, @dptr ;cjne a, #'M', test_ext_nope cjne a, #0x4D, test_ext_nope inc dptr movx a, @dptr ;cjne a, #'P', test_ext_m3u cjne a, #0x50, test_ext_m3u inc dptr movx a, @dptr ;cjne a, #'3', test_ext_nope cjne a, #0x33, test_ext_nope mov dpl, #1 rettest_ext_m3u: ;cjne a, #'3', test_ext_nope cjne a, #0x33, test_ext_nope inc dptr movx a, @dptr ;cjne a, #'U', test_ext_nope cjne a, #0x55, test_ext_nope mov dpl, #2 rettest_ext_nope: mov dpl, #0 ret _endasm;}#pragma RESTORE
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -