📄 dsa.c
字号:
play_sector_state = PLAY_SECTOR_INIT; } do { return_val = playSectors_step_by_step(begin, vstream, size, 0); if ((return_val == 2) || (return_val == 3)) { return (1); } if (return_val == 0) { /* failed */ 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); } else#endif { dsa_mode(MODE_ATTI_REL | MODE_CDROM | MODE_SPEED_NORMAL); } vcx_user_video_stream = vstream; reset_dsa_go(); begCDtime = begin; go_failed = 0; find_trials = 0; dsatime = adjCDtime(begCDtime, 0x16, -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, 0x16, -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); } find_trials++; previous_time = glbTimer; play_sector_state = PLAY_SECTOR_DSA_FIND; case PLAY_SECTOR_DSA_FIND:#ifdef ECHO MIC_service();#endif 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) || (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 0 /* this delays TDM turn on until track start */int playCDDA(int track_start_time, int begin, int end){ int retry = 3; extern RAMCODE RamCode; /* Kill TDM so when we restart, left/right will not swap */ mvd[tdmctl0] = 0x400; mvd[tdmrcvslots0] = 0; system_audio_partial_reset(0);#ifdef FRACTINT if (!FRACT_process_on) { FRACT_store = FRACTINT_START1; FRACT_process_on = 1; }#endif /* 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; XPORT_load_ucode(MPEG1_PS); /* Only MPEG1_PS has CDDA ucode */ dsa_mode(MODE_ATTI_REL | MODE_CDROM | MODE_SPEED_NORMAL); CDDA_play_time = adjCDtime(end, track_start_time, -1); CDDA_track_start_time = track_start_time; do { if (dsa_go(begin)) break; } while (--retry); #if TDM_ON_AT_TRACK_BEGIN if (retry) { retry = glbTimer+ONE_SECOND; /* use "retry" as timeout */ do { if (!receive_dsa_all(1)) return (0); /* force abort */ if (servo_track_changed) break; } while (retry>glbTimer); }#endif TDM_ON_AT_TRACK_BEGIN /* * Regardless of dsa_go result, just turn on XPORT and TDM. Otherwise, * if high-level doesn't retry, we'll be stuck. */ XPORT_restart_at(XPORT_OFFSET_PLAY_CDDA, 1); TDM_turn_on(); return(retry);}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; 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 dsa_gotime = begin; 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_ATTI_REL | MODE_CDROM | MODE_SPEED_DOUBLE); } else#endif /* ANTI_SHOCK */ { CPRINTF("1X SPEED", CDDA_play_time); dsa_mode(MODE_ATTI_REL | MODE_CDROM | 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; return(0); /* Really dead */ } } else { /* attempt to jump past errors.. * retry time adjustments: 5, 10, 20, 40 (seconds) */ adjdsa_time = logical2physical(375*ptrLshift[retry_cnt]); adjdsa_time = adjCDtime(dsa_gotime, adjdsa_time, 1); if (adjdsa_time > endCDtime) { /* give up..we're at end of track! */ end_of_play = 1; play_cdda_state = PLAY_CDDA_INIT; return(0); /* Really dead */ } dsa_gotime = adjdsa_time; reset_dsa_go(); retry_cnt++; } } else if (status==2) { #if TDM_ON_AT_TRACK_BEGIN retry_cnt = glbTimer + ONE_SECOND; /* use retry_cnt as timeout */ play_cdda_state = PLAY_CDDA_WAIT_BEGIN; CPRINTF("CDDA WAIT", SERVO_cdtime);#else play_cdda_state = PLAY_CDDA_TDM_ON;#endif TDM_ON_AT_TRACK_BEGIN } return(1);#if TDM_ON_AT_TRACK_BEGIN case PLAY_CDDA_WAIT_BEGIN: if (retry_cnt < glbTimer) { play_cdda_state = PLAY_CDDA_TDM_ON; } else { if (!receive_dsa_all(1)) return (0); /* force abort */ if (!servo_track_changed) return(1); play_cdda_state = PLAY_CDDA_TDM_ON; }#endif TDM_ON_AT_TRACK_BEGIN case PLAY_CDDA_TDM_ON: TDM_turn_on(); CPRINTF("TDM ON", retry_cnt);#ifdef ANTI_SHOCK if (match) { /* use "retry_cnt" as timeout */ retry_cnt = glbTimer+TWO_SECOND; ABV_xfer_flag = 0; /* "1" when CDDA data comes in */ play_cdda_state = PLAY_CDDA_MATCH; return(1); } else #endif { XPORT_active = 1; play_cdda_state = PLAY_CDDA_INIT; return(2); } break;#ifdef ANTI_SHOCK case PLAY_CDDA_MATCH: if (ABV_xfer_flag) { XPORT_active = 1; play_cdda_state = PLAY_CDDA_INIT; CPRINTF("ESP DATA MATCH", c2po); return(2); } else { /* timeout */ if (retry_cnt < glbTimer) { /* "fuzzy" play for CDDA */ if (c2po_timeout > glbTimer) { /* really scratched up.. * just go to next track. */ servo_track_changed = 1; } else { /* Kill TDM so when we restart, * left/right will not swap */ mvd[tdmctl0] = 0x400; mvd[tdmrcvslots0] = 0; TDM_force_stop(1); ABV_stop_filling(); XPORT_restart_at(XPORT_OFFSET_PLAY_CDDA, 1); TDM_turn_on(); ABV_start_filling(); XPORT_active = 1; CPRINTF("ESP FUZZY MATCH", c2po); play_cdda_state = PLAY_CDDA_INIT; return(3); /* fuzzy */ } } return(1); }#endif ANTI_SHOCK }}void fill_screen(int color){ DISP_Info *dip; int width; int height; dip = DISP_info + DISP_frame;#if defined(MP3) || defined(WMA_DEC) /* For MP3/WMA use I-frame for display, since MP3/WMA shares B&P */ if (STREAM_type) vcx_user_video_stream = 0xe1;#endif if ((vcx_user_video_stream == 0xe2) || (vcx_user_video_stream == 0x1e2)) { DISP_frame = E2; width = 704; height = DISP_scn_height * 2; } else { DISP_frame = I; width = 352; height = 288; /* Set as PAL source */ } vcx_VertSz = height; DISP_change_resolution(width, height); DISP_paint_screen(color, 0, DISP_frame); DISP_count = 0;}PRIVATE void init_dsa(void){#ifdef SERVO_7/* according to SERVO_7 SPEC. the three_disc changer will have to wait for a Carousel stop #1 command from the loader before sending any command, just in case of otherwise, we have a timeout here. */#ifdef THREE_CDS char retry; retry = 2; do { if (!receive_dsa_all(0)) break; /* if error then quit */ if ((dsa_word & 0xff00) == (SERVO_CAROUSEL_STOPPED << 8)) break; } while (--retry); #endif /*THREE_CDS */#endif /*SERVO_7 */ /* reset all state machine */ tran_state = D_IDLE; rec_state = R_IDLE; /* clear all flags */ CDinited = 0;}/************************************************************************ * Routines specific to Philips' DSA interface protocol (Games 6001) * ************************************************************************//* * Transmit "cmd" and "data" from our chip to servo. * * Inputs: * cmd: servo command * data: associated data */PRIVATE void trans_dsa(cmd, data)int cmd, data;{ char dsa_byte; int dsa_second; /* 1st byte of data sent */ unsigned int TDSATimeCount; /* To prevent transmission error so * * we can retrasmitt */ unsigned char mask; /* Mask for bit being trasmitted. */ int count = 0; /* Debug loop count */ int retry; unsigned int prevClock, elapsed; DEBUGASSIGN(dbgTransDsa, (cmd << 8) | data); if (rec_state != R_IDLE) { /* * If we are in the middle of receiving, make sure we finish. * Otherwise, if we are in R_W_ACK0, we may dead lock! */ if (!receive_dsa_all(1)) /* Any data, including tk/index/mm/ss */ return; /* Abort transmit, we have higher * * priority command waiting. */ } prevClock = glbTimer; while (1) {#ifdef ECHO MIC_service();#endif DEBUGINC(1, count); DEBUGASSIGN(dbgMaxTran, (count > dbgMaxTran) ? count : dbgMaxTran); /* glbTimer is updated in the interrupt handler */ elapsed = glbTimer - prevClock; if (elapsed > ONE_SECOND) { /* The usual elapsed time is ~.25 second */ DEBUGINC(1, dbgServoTran); tran_state = D_IDLE; /* Reset the transmit state */ return; } switch (tran_state) { case D_IDLE: /* Before actual synchronization */ TDSATimeCount = 0; SET_DSA_DATA; SET_DSA_ACK; SET_DSA_STROBE; tran_state = D_SYNC01; break; case D_SYNC01: /* Tx lower DATA; wait for Rv lower ACK */
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -