📄 gdtservo.c
字号:
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) * sz: Size of a CD sector (in bytes) * * Return: * 1: successful * 0: failure */#define PLAY_SECTOR_INIT 0#define PLAY_SECTOR_DSA_GO 1#define PLAY_SECTOR_DSA_FIND_INIT 2#define PLAY_SECTOR_DSA_FIND 3int playSectors(begin, vstream, size)unsigned int begin, vstream;int size;{ int return_val; XPORT_active = 0; play_sector_state = PLAY_SECTOR_INIT; do { return_val = playSectors_step_by_step(begin, vstream, size, 1); 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. 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, fuzzy_allowed)unsigned int begin, vstream;int size, fuzzy_allowed;{ static int dsatime; static int go_failed; static int find_trials; static unsigned int previous_time; int status; if (XPORT_active) return (1);/* showingLogo = SHOWING_NOLOGO;*/ 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); 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, 0x11, -1); /*0x00000004*/ play_sector_state = PLAY_SECTOR_DSA_GO; return (1); case PLAY_SECTOR_DSA_GO: status = dsa_go_step_by_step(dsatime);#if 1 if(status == 2) play_sector_state = PLAY_SECTOR_DSA_FIND_INIT; else if(status == 0) { play_sector_state = PLAY_SECTOR_INIT; return(0); /* Really dead */ } else return(1);#else if (!status) { /*if (forceDSAabort) return(0);*/ /* derek */ if ((go_failed >= 2) || forceDSAabort) { DEBUGINC(1, dbgPlaySector); play_sector_state = PLAY_SECTOR_INIT; return(0); /* Really dead */ } go_failed++; return(1); } else if (status != 2) return(1); play_sector_state = PLAY_SECTOR_DSA_FIND_INIT; /* Fall through to the next state */#endif case PLAY_SECTOR_DSA_FIND_INIT: XPORT_play20video(XPORT_OFFSET_PLAY_SECTOR, vstream); TDM_turn_on(); if (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; 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 1 if (XPORT_active == 0) { XPORT_active = 1; /*temp changed by fyh */ if (((glbTimer - previous_time) >= TWO_SECOND) || (currCDtime > begCDtime)) { go_failed = 0; play_sector_state = PLAY_SECTOR_DSA_GO; } return (1); }#endif /* Bingo! */ /* OUTOSD(10, "BINGO", "BINGO", 0);*/ 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: Size of a CD sector * * Return: * 1: successful * 0: failure */int fuzzyPlaySector(time, size)int time, size;{ int retry = 2; /* showingLogo = SHOWING_NOLOGO;*/ /* 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); 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; int diff_time; 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 { SERVO_service(); if ((run_time & x00ffffff) >= track_start_time) 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. */#if 0 save_ramcode = RamCode; VP_load_ucode(rcddamono);#endif XPORT_restart_at(XPORT_OFFSET_PLAY_CDDA, 1); TDM_turn_on(); cdda_glbTimer = glbTimer; /* * if the begin time is not close to the begin track, we want to stop it * when we reach the end of track and ignore the 2 seconds ignore time. * This is to fix the problem that FF does not stop at the end of track. */ diff_time = adjCDtime(begin, track_start_time, -1); if (diff_time > 0x0500) cdda_glbTimer = glbTimer - TWO_SECOND;#ifdef LATER#ifndef CDDA_PANEL /* * If we are not using the CDDA panel, then we'll need to show the logo * if it is not being displayed. */ if (showingLogo != SHOWING_CDDALOGO) { showLogo(TBLOFF_CDDASCN, TBLSZ_CDDASCN); /* We allow multiple logo in digest */ if (!vcx_digest) showingLogo = SHOWING_CDDALOGO; else showingLogo = SHOWING_NOLOGO; }#endif#endif return (retry);}void fill_screen(int color){ DISP_Info *dip; int width; int height; dip = DISP_info + DISP_frame;#ifdef MP3 /* For MP3 use B-frame area, since MP3 shares "top" part of * display memory in Dram. */ if (STREAM_type) vcx_user_video_stream = 0xe1;#endif if ((vcx_user_video_stream == 0xe2) || (vcx_user_video_stream == 0x1e2)) { DISP_frame = 0xE2; width = 704; height = DISP_scn_height * 2; } else { DISP_frame = B; width = 352; height = 240; /* Set as NTSC source */ } vcx_VertSz = height; DISP_change_resolution(width, height); DISP_paint_screen(color, 0, DISP_frame); DISP_count = 0;}void init_dsa(void){ /* clear all flags */ CDinited = 0;}/************************************************************************ * Routines specific to Philips' DSA interface protocol (Games 6001) * ************************************************************************//* receive information from CD *//* return dsa_word */void receive_dsa(void){ char r_tmp; int CDDA_intro_time; int tmp; int update_time; /* * Talk with uP while receiving from DSA. Otherwise, uP may be left out * for long period of time, and it may think E3204 is dead. */ microEngine();#ifdef ECHO MIC_service();#endif if (servo_info != last_servo_info) { last_servo_info = servo_info; updateLCDtime(); /* in play.c */ OSD_update_info(); /* in fsosd.c */ }}/************************************************** DSA operation function***************************************************//* * Set CD-module's modes. * * NOTE: SERVO has a bug, if it receives 2 trans_dsa(DSA_mode, mode) in * a "short" period of time, the mode is actually not changed * even though it will report the mode has been changed. * * Therefore, we can't use the standard way to retry dsa_mode. * At track boundary, we'll get SERVO_TRACK, SERVO_INDEX, SERVO_MIN, * and receive_dsa_all only retries 3 time, so we many not get * a chance to see SERVO_MODE_STATUS if we just retry like other * cases. * * When going into DOUBLE speed, the servo usually takes around * 1 second to respond! When going into NORMAL speed, the response * time is a lot shorter. * * Input: * mode: set CD's mode * * Return: * 0: fail * 1: successful */int dsa_mode(mode)int mode;{ DISP_naicigam(); return (1);}/* * This function simulates real dsa_release function by set the CDDA_play_time * to a big number, so the end_of_play will not be set until a track change. * * Return: * 1: successful */int dsa_release(unsigned int track_start, unsigned int track_end){ CDDA_play_time = adjCDtime(track_end, track_start,-1); return (1);}/* * Close the tray. Servo answers with TRAY MOVING (which we ignore) * and TRAY CLOSED command. */int dsa_close(int power_down){ forceDSAabort = 0; return(SERVO_close());}/* * Opens the tray. If the CD-module is in PLAY mode, it first performs * a STOP procedure before the tray opens. When the moving of the tray * starts, the CD-module send the TRAY MOVING command (we ignore). Then * we we'll get TRAY OPENED. This command clears the internal 'pause mode * indicator. */int dsa_open(void){ return(SERVO_open());}/* * Stops playing the disk and brakes. This command also clears the * internal 'pause mode indicator' */int dsa_stop(void){ DISP_naicigam(); SERVO_stop();}/* * Pause. This is for CDDA. */int dsa_pause(void){ target_min = bcd2hex[SERVO_Qarray_current[SERVO_QPMIN]]; target_sec = bcd2hex[SERVO_Qarray_current[SERVO_QPSEC]]; target_frame = bcd2hex[SERVO_Qarray_current[SERVO_QPFRAME]]; return (1);}/* * Pause release. This is for CDDA. */int dsa_pauserelease(void){ int return_val; extern int cd_pause; if (!cd_pause) return; SERVO_mode = Mode_Seek; SERVO_state = Seek_Initial; while (1) { microEngine(); GDT_SERVO_process(); return_val = SERVO_STATUS; if (SERVO_check_key_new()) return 0; if (return_val == SERVO_RET_clvok) break; if ((return_val == SERVO_RET_int)|| (return_val == SERVO_RET_fng)|| (return_val == SERVO_RET_clvng)) { return (0); } } return (1);}
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -