📄 dsak.c
字号:
#ifndef SERVOPRIVATE void trans_dsa(cmd, data)int cmd, data;{ return;}#endif/* receive information from CD */void receive_dsa(void){ int CDDA_intro_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. */#ifdef SONY3D process_eject();#endif check_user_input(); if (OSD_update_time) { OSD_update_time=0; /* use servo time to check end of play */ if (TDM_isCDDA) { /* only do it when we received second */ int passtime; passtime = ((servo_info & 0xffff) << 8); if (second_endCDtime != xMAX_CDTIME) /* intro mode */ { CDDA_intro_time = adjCDtime(second_endCDtime, CDDA_track_start_time, -1); } else { CDDA_intro_time = xMAX_CDTIME; } /* victor: because of the ATTI_REL mode and some wrongly * * encoded CD might have incorrect track info, there is * * a possibility that CDDA_play_time hasn't been reached * * before a new track occurs(ABEX), we add a check on the * * new track here. */ if ((passtime >= CDDA_play_time) || (passtime >= CDDA_intro_time) || (servo_track_changed)) {#ifdef ANTI_SHOCK /* Set RISC stat bit to stop XPORT data(CDDA) */ mvd[xport_input_mode] = XPORT_input_mode | 0x4; XPORT_active = 0; XPORT_data_end = 1;#else end_of_play = 1;#endif ANTI_SHOCK servo_track_changed= 0; /* reset it, very important */ } } OSD_update_info(); /* OSD info needs to update */ } return;}/* * Receive data from servo. Since receive_dsa filters out disk's timing * information (and set dsa_word to 0), we'll retry up to 3 times to * get non-timing information. * * Input * quit_on_any: * Return with anything (including tk/index/mm/ss). Setting of this * flag will also force something to be returned (i.e. even if * forceDSAabort is set, we'll not abort and return). * * Return: * 1: If successful or exhaust 3 retries. * 0: If force to quit due to forceDSAabort * * Side effect: * Global variable dsa_word has the non-timing info received from * servo. * */#ifndef SERVOint receive_dsa_all(quit_on_any)int quit_on_any;{ return(1);}#endif/************************************************** 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(int mode){ DISP_naicigam(); if ((currDSAmode&0x7)^(mode&0x7)) {#if (defined(ANTI_SHOCK) || defined(ABNORMAL_VCD)) SERVO_set_speed((mode & MODE_SPEED_DOUBLE) ? SET_CD_2X : SET_CD_1X);#endif } currDSAmode = mode; 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){ int Timer;#ifdef SONY3D if(((!VCD_30) && (play_state==ENTRY_STATE)) || power_down) { TRAY_CLOSE; while(SERVO_CLOSE_HIGH) { microEngine(); if (int_eject) { TRAY_STOP ; cd_opened = 0 ; return(1); } } TRAY_STOP; if (SERVO_UP_HIGH) { TRAY_CLOSE; while (SERVO_UP_HIGH); TRAY_STOP; process_up_down(); } cd_opened = 0; } else { TRAY_CLOSE; TrayStatus = TRAY_CLOSING; } return(1);#else forceDSAabort = 0; return(SERVO_close());#endif}/* * 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){ int Timer;#ifdef SONY3D if((!VCD_30) && (play_state==ENTRY_STATE)) { if (SERVO_DOWN_HIGH) { TRAY_CLOSE; while(SERVO_DOWN_HIGH); TRAY_STOP; process_up_down(); } TRAY_OPEN; while(SERVO_OPEN_HIGH) { microEngine(); if (int_eject) break; } TRAY_STOP; cd_opened = 1 ; } else { TRAY_OPEN; TrayStatus = TRAY_OPENING; } return(1);#else return(SERVO_open());#endif}/* * Stops playing the disk and brakes. This command also clears the * internal 'pause mode indicator' */int dsa_stop(void){ forceDSAabort = 0; DISP_naicigam(); cd_stop = 1; SERVO_stop(1); return 0;}/* * Pause. This is for CDDA. */int dsa_pause(void){ if (kickfg) { SERVO_target_msf = SERVO_cdtime; SERVO_mode = SERVO_PAUSE; } Do_mute(); return(1);}/* * Pause release. This is for CDDA. */int dsa_pauserelease(void){ int found; if ((SERVO_mode == SERVO_PAUSE) && kickfg) { SERVO_mode = SERVO_PLAY; found = SERVO_search(); if (!found && !servo_focus_on) SERVO_stop(1); } Undo_mute(); /* We need this for MP3 and WMA in case when we pause after all * the file's data is already in..we'll restart at "paused" location * saved in "previous_sector". */ end_of_play = 0; return(1);}/* * Read the table of content. CD-module passes all track info. Information * depends on track number: * 0 <= track number <= 63 * track number * control & address * start time (min) * start time (sec) * start time (frm) * * This routine initialize track information as well as lead out time. * * Input: * pTk: Pointer to the track information buffer * szTk: Size (number of entries) of track information buffer * * Return: * 0: failed * 1: OK */extern int SERVO_access_toc(void);extern unsigned char cdrw_disc;extern void Servo_goto_leadin(void);int dsa_ltoc(pTk, szTk)unsigned int * pTk;int szTk;{ int track_rd_num; /* # of track info have been read */ unsigned char data; int i; int pt_A0, pt_A1, pt_A2; /* Keep track whether we have received * * 64h, 65h, 66h (A0, A1, A2) */ int ltoc_done; /* LTOC is done */ int retry_cnt = 0; /* This routine's retry count */ int loopcnt; /* Number of replies from servo. */ int tk1_ctl_adr; /* Track #1 Control/Address */ int pt_A0_PSEC; /* Track #64 data */ int timeout; int multi_session; int first_session_cdda=0; /*set if the first session has CDDA track*/#ifdef MULTI_SESSION int pt_B0, pt_C0; /* 6Eh, 78h (B0, C0) */ int return_val=0; int last_session_msf_1=0; int first_session_retry_cnt=0;#endif /* No digital-out during ltoc */ CDinited = 0; /* Avoid partially initialized CD info */ /* Make sure FOCUS is on before reading LTOC */ retry_cnt = 0; if(!focus_adj){ SERVO9223_init(); SERVO_close(); SERVO_sledin(); }SERVO_ltoc_retry: /* Interrupted by user */ if (SERVO_check_key_new()) goto ltoc_err_return; /* Focus off, sled into inner position to read TOC, and focus again */ if (retry_cnt >= 1){ SERVO_all_servo_off(); SERVO_sledin(); } servo_task = SERVO_focus; SERVO_schedule(); if (!servo_focus_on) { CDinfo.type = CD_NODISC; err_code = ERR_TRAYEMPTY; goto ltoc_err_return; } if (retry_cnt >= 2) { CDinfo.type = CD_UNKNOWN; err_code = ERR_LTOC; goto ltoc_err_return; /* Retried twice and still fails */ } retry_cnt ++; /* initialize some CDinfo */ CDinfo.type = 255; CDinfo.firsttrack = 0; CDinfo.lasttrack = 0; for (i = 0; i < szTk; i++) pTk[i] = xff000000; pt_A0 = pt_A1 = pt_A2 = 0; track_rd_num = num_of_track = 0; multi_session = 0; num_of_session = 1;#ifdef MULTI_SESSION pt_B0 = pt_C0 = 0; last_session_msf = 0;#endif MULTI_SESSION /* process received data until it is done */ loopcnt = ltoc_done = 0; SERVO_new_Qcode = 0;#if defined(CD_TEXT) && !defined(ANTI_SHOCK) CD_text_init(1);#endif while (!ltoc_done) {#ifdef ECHO MIC_service();#endif VCX_service();#ifdef LTOC_TV_CHANGE DISP_TV_service();#endif loopcnt++; if (loopcnt > 2000) { /* * Servo is going crazy! This rarely happens; however, I have * seen this happened! */ goto SERVO_ltoc_retry; } /* Higher priority command received. Go handle it */ if ((loopcnt % 8) == 0) if(SERVO_check_key_new()) goto ltoc_err_return; timeout = glbTimer + FOUR_SECOND; do { SERVO_service(1); if (!servo_focus_on || (glbTimer > timeout)) goto SERVO_ltoc_retry; /* Focus is down or time out, * * do not proceed */ if (SERVO_new_Qcode) { SERVO_new_Qcode = 0; break; } if(SERVO_check_key_new()) goto ltoc_err_return; #ifdef LTOC_TV_CHANGE DISP_TV_service();#endif } while(1); switch (SERVO_Qarray_new[SERVO_QTRACK]) { case 0x00: switch (SERVO_Qarray_new[SERVO_QPOINT]) { case 0xA0: CDinfo.firsttrack = bcd2hex[SERVO_Qarray_new[SERVO_QPMIN]]; pt_A0_PSEC = SERVO_Qarray_new[SERVO_QPSEC]; if(pt_A0_PSEC == 0xa) CDinfo.type = CD_CDI; pt_A0 = 1; break; case 0xA1: /*make sure we have read first track info before set pt_A1*/ if(!pt_A0) break; CDinfo.lasttrack = bcd2hex[SERVO_Qarray_new[SERVO_QPMIN]] - 1; if (CDinfo.type == CD_CDI) num_of_track = -1; else num_of_track = CDinfo.lasttrack - CDinfo.firsttrack + 1; pt_A1 = 1; break; case 0xA2: CDinfo.leadout = SERVO_Qarray_new[SERVO_QPMIN]<<16 ; CDinfo.leadout |= SERVO_Qarray_new[SERVO_QPSEC]<<8; CDinfo.leadout |= SERVO_Qarray_new[SERVO_QPFRAME]; pt_A2 = 1; break; #ifdef MULTI_SESSION case 0xB0: if (pt_B0) break; first_session_retry_cnt++; if (!((SERVO_Qarray_new[SERVO_QRMIN]==0xff) && (SERVO_Qarray_new[SERVO_QRSEC]==0xff) && (SERVO_Qarray_new[SERVO_QRFRAME]==0xff))){ multi_session=1; last_session_msf_1=last_session_msf; last_session_msf = SERVO_Qarray_new[SERVO_QRMIN]<<16 ; last_session_msf|= SERVO_Qarray_new[SERVO_QRSEC]<<8; last_session_msf|= SERVO_Qarray_new[SERVO_QRFRAME]; } pt_B0 = 1; break; case 0xC0: pt_C0 = 1; break;#endif /*MULTI_SESSION*/ default: if ((SERVO_Qarray_new[SERVO_QPOINT] < 0xa0) && (SERVO_Qarray_new[SERVO_QPOINT] > 0x00)) { int trk_index; trk_index = bcd2hex[SERVO_Qarray_new[SERVO_QPOINT]] - 1; /*allow toc overriding*/ i = (SERVO_Qarray_new[SERVO_QCTRADD] << 24) | (SERVO_Qarray_new[SERVO_QPMIN] << 16)| (SERVO_Qarray_new[SERVO_QPSEC] << 8)| SERVO_Qarray_new[SERVO_QPFRAME]; if(pTk[trk_index] != i){ if (pTk[trk_index] == xff000000) track_rd_num++; pTk[trk_index] = i; if ((num_of_session==1) && ((SERVO_Qarray_new[SERVO_QCTRADD] & 0x4f) == 0x01))/*CDDA*/ first_session_cdda = 1;#if 0 /* for single session DATA discs (MP3...) which have * only one track, depending on the order of Q-code, * we may not have a chance to set tk1_ctl_adr. * tk1_ctl_adr can be more reliably set after all the * TOC info has been acquired. */ if (SERVO_Qarray_new[SERVO_QPOINT] == CDinfo.firsttrack) tk1_ctl_adr = SERVO_Qarray_new[SERVO_QCTRADD];#endif } } break; } /*One Point of a qcode*/
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -