📄 main.c
字号:
switch (play_state) { case S_START_NEW_FILE: case S_PLAYING_FILE: case S_FINISH_PLAYING_FILE: case S_FINISHED_FILE: case S_PAUSED: break; default: print("Illegal play_state\r\n"); play_state = S_START_NEW_FILE; break; } // And this separate state machine will be responsible for // disk access. The idea is to be able to do various things // with the disk drive independent of what the current state // of the playback might happen to be. switch (disk_state) { case S_DRIVE_INACTIVE: if (disk_activity_needed) { // TODO && sleep not pending ide_hard_reset(); disk_time_mark = clock_tick(); disk_state = S_WAIT_DRIVE_READY; } break; case S_WAIT_DRIVE_READY: if (ide_init()) { disk_latency = (clock_tick() - disk_time_mark); disk_state = S_CACHING_PRIORITY_1; caching_priority = 1; } else { // TODO, timeout, go back to and try again } break; case S_CACHING: if (highest_priority == NULL) { ide_sleep(); free_fat_memory(); disk_state = S_WAIT_SHUTDOWN; break; } r = file_cache_work(highest_priority->file_desc); if (r == 1) { // finished caching this file highest_priority->priority = 0; highest_priority = highest_priority->next; break; } if (r == 2) { // ran out of memory highest_priority = NULL; } break; case S_WAIT_SHUTDOWN: // TODO, check if drive is actually in sleep mode // and remain in this state until it really is disk_state = S_DRIVE_INACTIVE; break; default: print("Illegal disk_state\r\n"); play_state = S_DRIVE_INACTIVE; break; }#endif //NEW_STATE_MACHINE //dram_test(); } pm2_exit();}#if 0static data unsigned int test_ref=0xFFFF;static xdata at 0x8000 unsigned int test2;static xdata at 0xFF00 unsigned int test3;volatile xdata unsigned int *test4=(xdata unsigned int *)0x0000;void dram_test(void){ data unsigned int temp; EA = 0; if ((temp = test2) != test_ref) { printf("test2: %x (%x, %x) vs %x.... ", temp, test2, test2, test_ref); test2 = test_ref; printf("%x, %x, %x\r\n", test2, test2, test2); EA = 1; return; } if ((temp = test3) != test_ref) { printf("test3: %x (%x, %x) vs %x.... ", temp, test3, test3, test_ref); test3 = test_ref; printf("%x, %x, %x\r\n", test3, test3, test3); EA = 1; return; } /* if (test_ref == 0xFFFF) { test4++; if ((unsigned int)test4 > 0x0FFF) test4=(xdata unsigned int *)0x0000; *test4 = test_ref; printf("t_ok: %d\r\n", (unsigned int)test4); } if ((temp = *test4) != test_ref) { printf("test4: %x (%x, %x) vs %x.... ", temp, *test4, *test4, test_ref); *test4 = test_ref; printf("%x, %x, %x, ptr=%x\r\n", *test4, *test4, *test4, (unsigned int)test4); return; } (*test4)++; */ test_ref++; test2++; test3++; EA = 1;}#endif/* still not quite sure how this is going to work, but the idea is to *//* hold a list of the files that are open, in some sort of order of *//* priority that we'll try to read them when the drive is spinning */struct play_queue_struct { char file_desc; unsigned char priority; simm_id filelist_id; struct play_queue_struct *next_priority;};#define PLAY_QUEUE_SIZE 12struct play_queue_struct *highest_priority;struct play_queue_struct play_queue[PLAY_QUEUE_SIZE];unsigned int get_move_count(char direction) { // Modified to call rev_rand if we want to go backwards. pl_prev & pl_l_prev should pass -1 to// get the last random number to allow moving backwards. pl_next & pl_l_next should pass +1 to// get the next random number in the sequence.// -ZSB 29-Aug-2001 11:26 PM update_rand_needed = 1; // Every time the random changes, we'll set the update. // An update won't actually happen unless the user has changed something else // (IE timer 3 was already running) or until the 10th time, when we'll fall // into the if below & set timer 3 here. -ZSB 31-Aug-2001 2:08 PM if (direction == 1) return rand16(); else return rev_rand16();}#pragma SAVE// #pragma NOGCSEvoid pl_l_next() // Move to next playlist skipping empty lists{ unsigned int count; xdata struct playlist_list_struct * pl_l_struct; if (play_mode == MODE_ALLRAND || play_mode == MODE_PLSTRAND) { count = get_move_count(1); if (count > directory_count) { // Don't allow a jump of more than there are playlists count = count % directory_count; if (count == 0) count = 1; } } else { count = 1; } //printf("pl_l_next, count=%d\r\n", count); do { pl_l_struct = addr6(current_playlist); if(pl_l_struct->next != 0) { current_playlist = pl_l_struct->next; playlist_index++; //print("."); } else { current_playlist = first_playlist; playlist_index = 0; //print("*"); } pl_l_struct = addr6(current_playlist); current_file = pl_l_struct->playlist_start; track_index = 0; if (current_file == 0) { count++; playlist_index--; //print("%"); } } while (--count); //print_str( (xdata char *)addr7(((filelist_t *)addr7(((playlist_t *)addr7(current_file))->fl_rec))->long_name));; //print_crlf(); if(resume) { save_resume_info(); }}void pl_l_prev() // Move to prev playlist skipping empty lists{ xdata struct playlist_list_struct * pl_l_struct; unsigned int count; if (play_mode == MODE_ALLRAND || play_mode == MODE_PLSTRAND) { count = get_move_count(-1); if (count > directory_count) { // Don't allow a jump of more than there are playlists count = count % directory_count; if (count == 0) count = 1; } } else { count = 1; } //printf("pl_l_prev, count=%d\r\n", count); do { pl_l_struct = addr6(current_playlist); if(pl_l_struct->prev != 0) { current_playlist = pl_l_struct->prev; playlist_index--; } else { current_playlist = last_playlist; } pl_l_struct = addr6(current_playlist); current_file = pl_l_struct->playlist_start; if (current_file == 0) { count++; playlist_index++; } } while (--count); if(resume) { save_resume_info(); }}void pl_next(){ unsigned int count; xdata struct playlist_struct * pl_struct; //simm_id name, flp, next, prev; //unsigned long clust, size; if (play_mode == MODE_ALLRAND || play_mode == MODE_DIRRAND) { count = get_move_count(1); if (count > mp3_file_count) { // Don't allow a jump of more than there are files count = count % mp3_file_count; if (count == 0) count = 1; } } else { count = 1; } //printf("pl_next, count=%d\r\n", count); do { // executes once for MODE_DIRONLY and MODE_SEQUENTIAL pl_struct = addr7(current_file); if (pl_struct->next == 0) { if (play_mode == MODE_DIRONLY || play_mode == MODE_DIRRAND) { current_file = ((playlist_list_t *)addr6(current_playlist))->playlist_start; track_index=0; } else { //print_crlf(); pl_l_next(); //printf("Count Remaining = %d\r\n", count); } } else { current_file = pl_struct->next; track_index++; } //print(" "); //print_hex32(current_file); //flp = ((playlist_t *)addr7(current_file))->fl_rec; //print_hex32(flp); //next = ((playlist_t *)addr7(current_file))->next; //print_hex32(next); //prev = ((playlist_t *)addr7(current_file))->prev; //print_hex32(prev); //name = ((filelist_t *)addr7(flp))->long_name; //print_hex32(name); //clust = ((filelist_t *)addr7(flp))->cluster; //print_hex32(clust); //size = ((filelist_t *)addr7(flp))->size; //print_hex32(size); //print_str((xdata char *)addr7(name)); //print_crlf(); } while (--count); //print_str( (xdata char *)addr7(((filelist_t *)addr7(((playlist_t *)addr7(current_file))->fl_rec))->long_name));; //print_crlf(); if(resume) { save_resume_info(); }}void pl_prev(){ xdata struct playlist_struct * pl_struct; unsigned int count; if (play_mode == MODE_ALLRAND || play_mode == MODE_DIRRAND) { count = get_move_count(-1); if(count > mp3_file_count) { // Don't allow a jump of more than there are songs count = count % mp3_file_count; if (count == 0) count = 1; } } else{ count = 1; } //printf("pl_prev, count=%d\r\n", count); do { // executes once for MODE_DIRONLY and MODE_SEQUENTIAL pl_struct = addr7(current_file); if (pl_struct->prev == 0) { if (play_mode == MODE_DIRONLY || play_mode == MODE_DIRRAND) { current_file = ((playlist_list_t *)addr6(current_playlist))->playlist_end; // TODO, track_index ???? } else { pl_l_prev(); } } else { current_file = pl_struct->prev; track_index--; } } while (--count); // TODO, resume stuff ??}#pragma RESTOREchar is_state_normal(unsigned char state){ if (state == S_PLAYING || state == S_PLAYING_AND_CACHING || state == S_FINISH_PLAYING) { return 1; } return 0;}#define BLOCK_SIZE 4096/* return 0 if there is more to play, or non-zero if we have played *//* everything or nothing more can play for some reason */char play_blocks(char mp3_fd){ unsigned int block; static unsigned long played_bytes; static unsigned char eof_count; if (mp3_fd == -1) { played_bytes = 0; eof_count = 0; return 1; } if (current_file_size == 0xFFFFFFFF) { print("WARNING: play_blocks called without known file size\r\n"); return 1; } while (play_queue_avail()) { block = file_read_block(mp3_fd); printfd("FRB, r=%x, played=%lx, size=%lx\r\n", block, played_bytes, current_file_size); if (block == 0) { return 0; // not in cache yet } if (block == 0xFFFF) { if (++eof_count > 240) { played_bytes = 0; // end of file (physical on disk) return 1; } else { return 0; // maybe more will be read soon? } } if (current_file_size - played_bytes > BLOCK_SIZE) { play_block(block, BLOCK_SIZE); played_bytes += BLOCK_SIZE; } else { play_block(block, current_file_size - played_bytes); played_bytes = current_file_size; return 1; } } eof_count = 0; return 0;}void process_resume(){ unsigned int count,i; count = ((int)param_value[PARAM_PLST_INDEX_HI] << 8) + param_value[PARAM_PLST_INDEX_LO]; //printf("playlist: %d \r\n",count); //Use sequential mode so that the indices count forward right. play_mode = MODE_SEQNTIAL; resume=0; if(count > 0) { for(i=1;i<=count;i++) { pl_l_next(); } } count = ((int)param_value[PARAM_TRACK_INDEX_HI] << 8) + param_value[PARAM_TRACK_INDEX_LO]; //printf("track: %d \r\n",count); if(count > 0) { for(i=1;i<=count;i++) { pl_next(); } } resume=1;}void save_resume_info(){ unsigned char hi,lo; //printf("playlist_index: %d track_index: %d\r\n",playlist_index,track_index); hi=(playlist_index & 0xFF00)>>8; lo=(playlist_index & 0x00FF); // FIXME: I'm leaving these flash writes outside of the timer // until the resume functionality is a little more settled. // Ideally, this should go to disk or something anyways... // -ZSB 11-Aug-2001 11:30 PM ibuf[0]=lo; write_flash_param(PARAM_PLST_INDEX_LO, ibuf); ibuf[0]=hi; write_flash_param(PARAM_PLST_INDEX_HI, ibuf); hi=(track_index & 0xFF00)>>8; lo=(track_index & 0x00FF); ibuf[0]=lo; write_flash_param(PARAM_TRACK_INDEX_LO, ibuf); ibuf[0]=hi; write_flash_param(PARAM_TRACK_INDEX_HI, ibuf);}
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -