📄 dsae.c
字号:
/* Set DSA_GO time to be 4d frames ealier than user specified */ dsatime = adjCDtime(begCDtime, 0x4, -1); /* Only change DSA mode if the current mode is not CDROM */ TDM_isCDDA = 0; /* Data is scrambled (as opposed to CDDA) */ XPORT_load_ucode((dest) ? DATA_PS : MP3_PS);#ifdef MP3CDG if (MP3CDG_started) dsa_mode(MODE_ATTI_REL | MODE_CDROM | MODE_SPEED_DOUBLE); else#endif dsa_mode(MODE_ATTI_REL | MODE_CDROM | MODE_SPEED_NORMAL); counter = 0; CPRINTF("GETSECTORS", dsatime); do { xfer_done = 0; if (counter >= 2) { DEBUGINC(1, dbgGetSector); CPRINTF("FAILED GETSECTOR2", dsatime); err_code = ERR_GETSECTOR; return(0); } counter++; if (!dsa_go(dsatime)) { /* DSA_GO command failed */ if ((counter >= 2)||forceDSAabort) { /* derek */ CPRINTF("FAILED GETSECTOR1", dsatime); DEBUGINC(1, dbgGetSector); return(-1); } else { counter++; continue; /* Time not specified, don't go */ } }#ifdef MP3CDG if (MP3CDG_started) VBV_start_filling(); else#endif { system_reset(); system_start(); } TDM_isCDDA = 0; XPORT_play20video(XPORT_OFFSET_GET_SECTOR, 2048); TDM_turn_on(); next_time = glbTimer + HALF_SECOND;#ifdef MP3CDG if(MP3CDG_started) next_time = glbTimer + TWO_SECOND;#endif timeout = 0; while (!TDM_found_begCDtime) { /* * There may not be any SYNC pattern (CDDA disk), so we'll * conclude that we are not getting the data if we have * been sitting here for .5 second */ if ((glbTimer > next_time) || (currCDtime > endCDtime)) { /* * Check one more time. In case CDI_get is cleared since * I checked it the last time. If we just turn off TDM, * then there is some chance that nobody will turn * TDM on again (because CDI_get is cleared) */ CPRINTF("GETSECTOR NO SYNC", dsatime); timeout = 1; break; } check_user_input(); MP3CDG_service();#ifdef SERVO SERVO_service(1); if (!servo_focus_on) { CPRINTF("GETSECTOR NO FOCUS", dsatime); return (-1); /* Focus is down, do not proceed */ }#endif } /* check if the data transfer is done */ if (!timeout) { /* Timeout to avoid hanging */#ifdef FLASH_UPDATE /* we may use getsectors() for "big" files */ tmp = (num>>6 - num>>9); /* ~(num/75) */ tmp = ONE_SECOND + tmp*ONE_SECOND; next_time = glbTimer + tmp;#else next_time = glbTimer + HALF_SECOND;#ifdef MP3CDG if (MP3CDG_started) next_time = glbTimer + TWO_SECOND;#endif#endif /* FLASH_UPDATE */ do { if (SERVO_check_key_new()) return (-2); MP3CDG_service(); } while (XPORT_active && (glbTimer < next_time)); xfer_done = 1; TDM_found_begCDtime = 0; } } while (!xfer_done); /* Victor: Because TDM will set end_of_play when CD_end is reached. We will need to reset end_of_play here. It should be safe because when we are getting PSD means we are not playing any playitem. */#ifdef MP3CDG if(MP3CDG_started) { begCDtime = beg1; endCDtime = end1; currCDtime = cur_time; stopCDtime = stop_time; end_of_play = end_status; } else#endif end_of_play = 0; return(1);}/* * Start playing from a given sector. There is no ending location! * Starting sector is specified in CD time format (i.e. MMSSFF where * each of MM/SS/FF is a BCD) * * This routine will always instruct the CD to go 10d frames earlier. * * Inputs: * begin: Starting CD sector time (in MMFFSS) * vstream: Video stream type (E0/E1/E2) * size: nonzero - Size of a CD sector (in bytes) * 0 - finish "step_by_step"..no init. * * Return: * 1: successful * 0: failure */int playSectors(begin, vstream, size)unsigned int begin, vstream;int size;{ int return_val; int start_time; extern int key0,is_ess_game; int ignore_key=0,key=0; if (size) { XPORT_active = 0; play_sector_state = PLAY_SECTOR_INIT; } start_time = 0; do { if(end_of_play) return 1; start_time++; if(start_time< 20) { start_time = 0; SERVO_focus_monitor(); if(servo_focus_drop) { SERVO_fcstry(); } } SERVO_service(1); if (SERVO_check_key_new()) { return (0); } /* if possible, find a better way to do this..*/ if((!(key0&0xff00))&&(key0>0)#ifdef GAMEBOY && !is_ess_game#endif ){ return (0); } return_val = playSectors_step_by_step(begin, vstream, size, 0); if ((return_val == 2) || (return_val == 3)) { return (1); } if (return_val == 0) { /* failed */ SERVO_focus_monitor(); if(servo_focus_drop) { SERVO_fcstry(); } return(fuzzyPlaySector(begin, size)); } if (XPORT_active) { /* when begCDtime == currCDtime */ return(1); } } while (1);}/***************************************************************************** Step by step playSectors. size: nonzero - Size of a CD sector (in bytes) 0 - finish "step_by_step"..no init. Returns 0 on failure. Returns 1 if don't know. Returns 2 if completed. Returns 3 if fuzzy. *****************************************************************************/int playSectors_step_by_step(begin, vstream, size, in_play)unsigned int begin, vstream;int size, in_play;{ static int dsatime; static int go_failed; static int find_trials; static unsigned int previous_time; int status, adjdsa_time; if (XPORT_active) return(1); switch (play_sector_state) { case PLAY_SECTOR_INIT: XPORT_active = 0; TDM_isCDDA = 0; end_of_still = 0; /* * This routine will go through actual loading of XPORT ucode * and CAM only if the current code doesn't match the bit * stream type. */ XPORT_load_ucode(vcx_bitstream_type);#if defined(ABNORMAL_VCD) || defined(ANTI_SHOCK) if (PLAY_set_2x_speed) { dsa_mode(MODE_ATTI_REL | MODE_CDROM | MODE_SPEED_DOUBLE); adjdsa_time = 0x10; } else#endif { dsa_mode(MODE_ATTI_REL | MODE_CDROM | MODE_SPEED_NORMAL); adjdsa_time = 0x3; } vcx_user_video_stream = vstream; reset_dsa_go(); begCDtime = begin; go_failed = 0; find_trials = 0; dsatime = adjCDtime(begCDtime, adjdsa_time, -1); play_sector_state = PLAY_SECTOR_DSA_GO; return(1); case PLAY_SECTOR_DSA_GO: status = dsa_go_step_by_step(dsatime); if (!status) { if (go_failed >= 4) { if (in_play) { /* keep trying to jump past errors for * MP3 and VCD under flow control or * anti-shock processing. */ go_failed = 0; find_trials = 0; } else { DEBUGINC(1, dbgPlaySector); play_sector_state = PLAY_SECTOR_INIT; return(0); /* Really dead */ } } else { /* attempt to jump past errors.. * retry time adjustments: 5, 10, 20, 40 (seconds) */ adjdsa_time = logical2physical(375*ptrLshift[go_failed]); adjdsa_time = adjCDtime(begCDtime, adjdsa_time, 1); if (adjdsa_time > endCDtime) { /* give up..we're at end of track! */ end_of_play = 1; play_sector_state = PLAY_SECTOR_INIT; return(0); /* Really dead */ } begCDtime = adjdsa_time; dsatime = adjCDtime(adjdsa_time, 0x10, -1); reset_dsa_go(); go_failed++; } } else if (status==2) { play_sector_state = PLAY_SECTOR_DSA_FIND_INIT; } return(1); case PLAY_SECTOR_DSA_FIND_INIT: XPORT_play20video(XPORT_OFFSET_PLAY_SECTOR, vstream); TDM_turn_on(); /* fuzzy_allowed */ if (find_trials >= 2) { DEBUGINC(1, dbgPlaySector); XPORT_play20video(XPORT_OFFSET_FUZZY_PLAY, vstream); TDM_turn_on(); XPORT_active = 1; vcx_pause = 0; play_sector_state = PLAY_SECTOR_INIT; return(3); }#ifdef ANTI_SHOCK if (ABV_set_good){ ABV_set_good = 0; ABV_wrptr = ABV_gdptr; }#endif ANTI_SHOCK find_trials++; previous_time = glbTimer; play_sector_state = PLAY_SECTOR_DSA_FIND; case PLAY_SECTOR_DSA_FIND: check_user_input(); if (XPORT_active == 0) { /* from MPEG4 VCD project */ if (currCDtime == 0) { (volatile)mvd[tdmdata]; } /* XPORT should be up within 1/4 second */ if ((glbTimer - previous_time > QUARTER_SECOND*5) || (currCDtime > begCDtime)) { goto go_again; } return (1); go_again: /* Kill TDM ..so XPORT_active won't be set. */ mvd[tdmctl0] = 0x400; mvd[tdmrcvslots0] = 0; XPORT_active = 0; go_failed = 0; play_sector_state = PLAY_SECTOR_DSA_GO; return(1); } /* Bingo! */ play_sector_state = PLAY_SECTOR_INIT; vcx_pause = 0; return(2); default: return(0); }}/* * This routine is used to do fuzzy search. * Input: * time: In CD sector format (i.e. MMSSFF where each of MM/SS/FF * is a BCD value) * size: nonzero - Size of a CD sector (in bytes) * 0 - finish "step_by_step"..no init. * * Return: * 1: successful * 0: failure */int fuzzyPlaySector(time, size)int time, size;{ int retry = 2; /* Only change DSA mode if the current mode is not CDROM */ TDM_isCDDA = 0; /* Data is scrambled (as opposed to CDDA) */ XPORT_load_ucode(vcx_bitstream_type);#if defined(ABNORMAL_VCD) || defined(ANTI_SHOCK) if (PLAY_set_2x_speed) dsa_mode(MODE_ATTI_REL | MODE_CDROM | MODE_SPEED_DOUBLE); else#endif dsa_mode(MODE_ATTI_REL | MODE_CDROM | MODE_SPEED_NORMAL); do { if (dsa_go(time)) break; } while (--retry); /* Regardless of dsa_go is OK or not. */ XPORT_play20video(XPORT_OFFSET_FUZZY_PLAY, 0xe0); TDM_turn_on(); if (retry) { /* start decoding */ vcx_pause = 0; return(1); } else { return(0); }}/* * Play CDDA data from "begin" time to "end" time where both "begin" and * "end" are in absolute CD time format. * * Return: * 1: successful * 0: failure */#define TDM_ON_AT_TRACK_BEGIN 1int playCDDA(int track_start_time, int begin, int end){ int return_val; XPORT_active = 0; play_cdda_state = PLAY_CDDA_INIT; do { if(forceDSAabort) return (-1); return_val = playCDDA_step_by_step(track_start_time, begin, end, 0); if ((return_val == 2)) { /* success */ return (1); } if ((return_val == 3)) { /* fuzzy */ return (2); } if (return_val == 0) { /* failed */ return(0); } } while (1);}int playCDDA_step_by_step(int track_start_time, int begin, int end, int match){ int status, adjdsa_time; static int retry_cnt; static int dsa_gotime; if (XPORT_active) return(1); switch (play_cdda_state) { case PLAY_CDDA_INIT: /* Kill TDM so when we restart, left/right will not swap */ mvd[tdmctl0] = 0x400; mvd[tdmrcvslots0] = 0; dsa_gotime = begin; if (!match) { system_audio_partial_reset(0);#ifdef ANTI_SHOCK XPORT_load_ucode(MP3_PS); /* MP3_PS has ESP ucode */#else XPORT_load_ucode(MPEG1_PS); /* MPEG1_PS has CDDA ucode */#endif CDDA_play_time = adjCDtime(end, track_start_time, -1); CDDA_track_start_time = track_start_time; /* Only change DSA mode if the current mode is not AUDIO */ TDM_isCDDA = 1; /* This is CDDA data (unscrambled PCM data) */ vcx_playvideo_only = 0;#ifdef ANTI_SHOCK#ifdef NO_CDDA_COMPRESS REC_compress_ratio = 1;#else /* default is G.721 */ REC_compress_ratio = 4; REC_4to1_coder_init(); REC_4to1_decoder_init();#endif /* NO_CDDA_COMPRESS */#endif /* ANTI_SHOCK */ }#ifdef ANTI_SHOCK if (PLAY_set_2x_speed) { CPRINTF("2X SPEED", CDDA_play_time); dsa_mode(MODE_AUDIO | MODE_SPEED_DOUBLE); } else#endif /* ANTI_SHOCK */ { CPRINTF("1X SPEED", CDDA_play_time); dsa_mode(MODE_AUDIO | MODE_SPEED_NORMAL); } play_cdda_state = PLAY_CDDA_XPORT_START; return(1); case PLAY_CDDA_XPORT_START:#ifdef ANTI_SHOCK if (match) { XPORT_load_cdda_match(); XPORT_restart_at(XPORT_OFFSET_MATCH_DATA, 1); } else#endif { XPORT_restart_at(XPORT_OFFSET_PLAY_CDDA, 1); } retry_cnt=0; /* initialize */ play_cdda_state = PLAY_CDDA_DSA_GO; dsa_go_state = DSA_GO_INIT; return(1); case PLAY_CDDA_DSA_GO: status = dsa_go_step_by_step(dsa_gotime); if (!status) { if (retry_cnt >= 4) { if (match) { /* keep trying to jump past errors for * CDDA anti-shock processing. */ retry_cnt = 0; } else { DEBUGINC(1, dbgPlaySector); play_cdda_state = PLAY_CDDA_INIT;
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -