📄 dsasl.c
字号:
/* 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 >= 3)||forceDSAabort) { /* derek */
CPRINTF("FAILED GETSECTOR1", dsatime);
DEBUGINC(1, dbgGetSector);
return(-1);
} else {
counter++;
dsatime = adjCDtime(dsatime,0x10,-1); // ojx zty
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 + GET_SECTOR_WAIT;
#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();
}
/* 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;
if (size) {
XPORT_active = 0;
play_sector_state = PLAY_SECTOR_INIT;
}
do {
if (SERVO_check_key_new()) {
return (-1);
}
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) //要保证每次读扇区都要能读到数据,不能因为有数据流就再跳
//&&(play_state != PLAY_STEP_STATE)&&(play_state != PLAY_SLOW_STATE))
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 = 0x25;
} else
#endif
{
dsa_mode(MODE_ATTI_REL | MODE_CDROM | MODE_SPEED_NORMAL);
/*zty*/
if(CDinfo.type == CD_VCD)
adjdsa_time = 0x20; //PBC
else if(STREAM_type == MP3_ID)
adjdsa_time = 0x15; //MP3,提前到20就有问题
else
adjdsa_time = 0x20; //CD GAME
}
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)
*/
if(go_failed == 0)
adjdsa_time = 0;
else
adjdsa_time =
logical2physical(375*ptrLshift[go_failed-1]);
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, 0x25, -1); //zty
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 >= 3) {
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 1
int 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;
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -