📄 dsa.c
字号:
trans_dsa(DSA_STOP, 0); force_quit = !receive_dsa_all(0); if (((dsa_word & 0xff00) == (SERVO_STOPPED << 8)) || force_quit) return(1); } while (--retry); /* Shall never get here! */ DEBUGASSIGN(dbgDSAstop, dsa_word); return(0);}/* * Pause. This is for CDDA. */int dsa_pause(void){ int retry = 2; int force_quit; /* 1: force abort; 0: receive OK */ do { trans_dsa(DSA_PAUSE, 0); force_quit = !receive_dsa_all(0); if (((dsa_word & 0xff00) == (SERVO_FOUND << 8)) || force_quit) { /* * end_of_play will be set. We need to clear them. * * inA2B will be cleared. It is OK. If dsa_pauserelease * is called, I'll set it again. */ end_of_play = 0; /* In case set by FOUND */ return(1); } } while (--retry); /* Shall never get here! */ DEBUGASSIGN(dbgDSApause, dsa_word); return(0);}/* * Pause release. This is for CDDA. */int dsa_pauserelease(void){ int retry = 2; int force_quit; /* 1: force abort; 0: receive OK */ do { trans_dsa(DSA_PAUSERELEASE, 0); force_quit = !receive_dsa_all(0); if (((dsa_word & 0xff00) == (SERVO_FOUND << 8)) || force_quit) { /* Redundant, but to be on the safe side */ end_of_play = 0; return(1); } } while (--retry); /* Shall never get here! */ DEBUGASSIGN(dbgDSApauserelease, dsa_word); return(0);}/* * 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 */int dsa_ltoc(pTk, szTk)unsigned int * pTk;int szTk;{ int track_rd_num; /* # of track info have been read */ unsigned char data, cmd; int i; int t64r, t65r, t66r; /* Keep track whether we have received * * 64h, 65h, 66h (A0, A1, A2) */ int ltoc_done; /* LTOC is done */ unsigned char track; /* Current track number */ 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 tk64_data; /* Track #64 data */ CDinited = 0; /* Avoid partially initialized CD info */#ifdef SERVO_7#ifndef THREE_CDS /* send a dsa_close here just in case the tray is opened *//* if(cd_opened) dsa_close(0);*/#endif /* not three_CDS */#endif /* SERVO_7 */ltoc_retry: if (retry_cnt >= 2) { 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; /* clear CD data base */ for (i = 0; i < szTk; i++) pTk[i] = xff000000; t64r = t65r = t66r = 0; track_rd_num = num_of_track = 0; /* send commend */ trans_dsa(DSA_LTOC, 0); /* process received data until it is done */ loopcnt = ltoc_done = 0; while (!ltoc_done) { loopcnt++;#ifdef ECHO MIC_service();#endif #ifdef LTOC_TV_CHANGE DISP_TV_service();#endif DEBUGASSIGN(dbgMaxLtocCnt, (loopcnt > dbgMaxLtocCnt) ? loopcnt : dbgMaxLtocCnt); if (loopcnt > 2000) { /* * Servo is going crazy! This rarely happens; however, I have * seen this happened! */ goto ltoc_retry; } /* Higher priority command received. Go handle it */ if (!receive_dsa_all(0)) break; data = dsa_word & 0xff; cmd = (dsa_word >> 8) & 0xff; switch (cmd) { case SERVO_LTOC_TRACK: track = data; if (data < 0x64) { /* Ordinary track */ if (track > szTk) { err_code = ERR_EXCEEDTK; goto ltoc_err_return; } if (pTk[track - 1] == xff000000) track_rd_num++; /* Haven't seen this track yet */ } else if ((data > 0x66) && (data != 0xb0)) { CPRINTF("ERROR TRACK", track); goto ltoc_retry; } break; case SERVO_LTOC_CTL_ADR: /* Control & address */#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 (track == 1) tk1_ctl_adr = data;#endif if (track < 0x64) pTk[track - 1] = (((unsigned int) data) << 24); break; case SERVO_LTOC_SMIN: if (track < 0x64) /* Track's starting minute */ pTk[track - 1] |= (((unsigned int) hex2bcd[data]) << 16); else if (track == 0x64) { /* 1st track number */ t64r = 1; CDinfo.firsttrack = (int) ((unsigned int) data); if (t65r) { if (CDinfo.type == CD_CDI) num_of_track = -1; else num_of_track = CDinfo.lasttrack - CDinfo.firsttrack + 1; } } else if (track == 0x65) { /* Last track number */ t65r = 1; CDinfo.lasttrack = (int) ((unsigned int) data) - 1; if (t64r) { if (CDinfo.type == CD_CDI) num_of_track = -1; else num_of_track = CDinfo.lasttrack - CDinfo.firsttrack + 1; } } else if (track == 0x66) { /* Lead out minute */ t66r = 1; CDinfo.leadout = ((unsigned int) hex2bcd[data]) << 16; } break; case SERVO_LTOC_SSEC: if (track < 0x64) /* Track's starting second */ pTk[track - 1] |= (((unsigned int) hex2bcd[data]) << 8); else if (track == 0x64) { /* CD's type */ tk64_data = data; if (data == 0xa) { /* CDI */ CDinfo.type = CD_CDI; if (t65r) num_of_track = -1; } } else if (track == 0x66) /* Lead out second */ CDinfo.leadout |= ((unsigned int) hex2bcd[data]) << 8; break; case SERVO_LTOC_SFRM: if (track < 0x64) /* Track's starting frame */ pTk[track - 1] |= ((unsigned int) hex2bcd[data]); else if (track == 0x66) /* Lead out frame */ CDinfo.leadout |= ((unsigned int) hex2bcd[data]); /* Have we got all the info yet? */ if (t64r && t65r && t66r && (track_rd_num > num_of_track)) ltoc_done = 1; break; case SERVO_ERROR: if (data == SERVOERR_NODISC) { CDinfo.type = CD_NODISC; cd_stop = 1; err_code = ERR_TRAYEMPTY; goto ltoc_err_return; } else { CPRINTF("CD ERROR", data); goto ltoc_retry; } break; default: /* unknown command */ break; } } /* end of while(ltoc_done) */ /* set tk1_ctl_adr after getting all toc info */ tk1_ctl_adr = pTk[CDinfo.firsttrack-1] >> 24; /* Disc type is determined here..CDI not supported */ if ((tk1_ctl_adr & 0xcf) == 0x01) CDinfo.type = CD_CDDA; else if (tk64_data != 0 && (tk1_ctl_adr == 0x41 || tk1_ctl_adr == 0x61)) CDinfo.type = CD_VCD; /* Note: Photo-CD will also pass as VCD */ else {#ifdef DATA_CD if (!tk64_data) CDinfo.type = CD_DATA; else#endif CDinfo.type = CD_UNKNOWN; } dsa_mode(MODE_ATTI_REL | MODE_CDROM | MODE_SPEED_NORMAL); CDinited = 1; /* * Some loaders have problem after LTOC if it is not followed by * STOP. */#ifdef JIANGHAI (void) dsa_stop();#endif DISP_cigam(CDinfo.type != CD_CDDA); return(1);ltoc_err_return: (void) dsa_stop(); return(0);}/* * Goto time. This command forces the CD-module to jump to the requested * absolute time location. * * Input: * time: CD sector time in MMSSFF format where each of MM/SS/FF * is a BCD number. * * Return: * 1: successful * 0: otherwise */int dsa_go(unsigned int time){ int return_val; int r_tmp; dsa_go_state = 0; do { return_val = dsa_go_step_by_step(time); if (return_val == 2) return (1); if (return_val == 0) return (0); } while (1);}void reset_dsa_go(){ dsa_go_state = DSA_GO_INIT;}static int receive_trials;static unsigned prevClock;/**************************************************************************** Step by step go time. Returns 0 if failed, 1 if don't know, 2 if succeed. ****************************************************************************/PRIVATE int dsa_go_step_by_step(unsigned int time){ int i, tmp; static int array[3]; static int retry; switch (dsa_go_state) { case DSA_GO_INIT: if (time > CDinfo.leadout) time = CDinfo.leadout; if (time < 0x200) time = 0x200; for (i = 0; i < 3; i++) { array[i] = (int) bcd2hex[time & 0xff]; time >>= 8; } DEBUGASSIGN(go_time, ((array[2] << 16)|(array[1] << 8)|array[0])); dsa_go_state = DSA_GO_MINUTE; retry = 0; case DSA_GO_MINUTE: trans_dsa(DSA_GO_MIN, array[2]); dsa_go_state = DSA_GO_SECOND; return(1); case DSA_GO_SECOND: trans_dsa(DSA_GO_SEC, array[1]); dsa_go_state = DSA_GO_FRAME; return(1); case DSA_GO_FRAME: trans_dsa(DSA_GO_FRM, array[0]); receive_trials = 0; dsa_go_state = DSA_GO_RECEIVE_INIT; case DSA_GO_RECEIVE_INIT: receive_trials++; dsa_flag = 1; prevClock = glbTimer; dsa_go_state = DSA_GO_RECEIVE; case DSA_GO_RECEIVE: if (dsa_flag == 1) { unsigned elapsed; elapsed = glbTimer - prevClock; if (elapsed > TEN_SECOND) { /* Abnormal situation. */ DEBUGINC(1, dbgServoRcv); dsa_word = SERVO_ERROR << 8; rec_state = R_IDLE; goto dsa_retry; /* Try it again */ } else { receive_dsa(); /* * If there is higher priority command waiting, then * quit (and 'FOUND'); otherwise, we'll have to * loop 'til the end. */ if (forceDSAabort) return(2); else return(1); } } if (!dsa_word) { /* DSA may have returned MM, SS, FF etc */ if (receive_trials > 3) { dsa_go_state = DSA_GO_INIT; return(0); /* We're dead! */ } else { dsa_go_state = DSA_GO_RECEIVE_INIT; return(1); /* Try again */ } } dsa_go_state = DSA_GO_ALMOST_DONE; case DSA_GO_ALMOST_DONE: dsa_go_state = DSA_GO_INIT; /* If disc is inserted upside down, we'll get an error! */ tmp = (dsa_word >> 8) & 0xff; if (tmp == SERVO_FOUND) { /* Bingo! */ return(2); } else if (tmp == SERVO_ERROR) { err_code = ERR_DISCERR; return(0); } else { dsa_retry: retry++; if (retry >= 2) { DEBUGASSIGN(dbgDSAgo, dsa_word); return(0); /* really dead */ } dsa_go_state = DSA_GO_MINUTE; return(1); /* try again */ } default: return(0); }}#ifdef THREE_CDSint dsa_get_disc_status(unsigned char *status){ int tmp; int retry = 2; int force_quit; /* 1: force abort; 0: receive OK */#ifdef SERVO_6003 *status = disc_6003_status << 4; return(1);#else do { trans_dsa(DSA_GET_DISC_STATUS, 0); do { force_quit = !receive_dsa_all(0); tmp = (dsa_word >> 8) & 0xff; if ((tmp == SERVO_DISC_STATUS) || force_quit) { *status = dsa_word & 0xff; return(1); } else break; } while (1); } while (--retry); /* Retry if we get unexpected result */ /* Shall never get here! */ return(0); #endif}int dsa_rotate_disk(int direction){ int tmp; int rotation; int retry = 2; int force_quit; /* 1: force abort; 0: receive OK */#ifdef SERVO_7 /* we have to send a dsa_stop here before rotate. */ dsa_stop();#endif /*SERVO_7 */#ifndef SERVO_6003 rotation = (direction) ? DSA_ROTATE_ANTI_CLOCKWISE: DSA_ROTATE_CLOCKWISE; do { trans_dsa(rotation, 0); do { force_quit = !receive_dsa_all(0); tmp = (dsa_word >> 8) & 0xff; if ((tmp == SERVO_CAROUSEL_STOPPED) || force_quit) { return(1); } else if (tmp == SERVO_CAROUSEL_MOVING) /* Intermediate */ continue; else break; } while (1); } while (--retry); /* Retry if we get unexpected result */#else if (direction == 0) { while (CD_UP_IS_LOW) { /* Philips 6003 program */ ROTATE_CLOCK_MOVE; } while (CD_UP_IS_HIGH) { ROTATE_CLOCK_MOVE; } ROTATE_STOP; if (disc_6003_status == 1) { disc_6003_status = 3; } else { disc_6003_status--; } } else { while (CD_UP_IS_LOW) { ROTATE_CLOCK_ANTI_MOVE; } while (CD_UP_IS_HIGH) { ROTATE_CLOCK_ANTI_MOVE; } ROTATE_STOP; if (disc_6003_status == 3) { disc_6003_status = 1; } else { disc_6003_status++; } } return(1);#endif /* Shall never get here! */ return(0); }#endif#ifdef PHILIPS2Xint barfoo;void testtest(){ extern void DSA_2x(), DSA_1x(); int xfer_mode = 5; if (barfoo == 1) { system_reset(); system_start(); XPORT_restart_at(XPORT_OFFSET_FUZZY_PLAY, 0); XFER_start(xfer_mode); vcx_playvideo_only = 1; VBV_alarm = 4096; DSA_2x(); } else if (barfoo == 2) { system_reset(); system_start(); XPORT_restart_at(XPORT_OFFSET_FUZZY_PLAY, 0); XFER_start(xfer_mode); vcx_playvideo_only = 0; VBV_alarm = 1024; DSA_1x(); } barfoo = 0;}/* * Run CD at 2X speed. */void DSA_2x(){ int tmp; tmp = currDSAmode & ~MODE_SPEED_NORMAL; tmp |= MODE_SPEED_DOUBLE; dsa_mode(tmp);}/* * Reset CD back to 1X speed. */void DSA_1x(){ int tmp; tmp = currDSAmode & ~MODE_SPEED_DOUBLE; tmp |= MODE_SPEED_NORMAL; dsa_mode(tmp);}#endif
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -