⭐ 欢迎来到虫虫下载站! | 📦 资源下载 📁 资源专辑 ℹ️ 关于我们
⭐ 虫虫下载站

📄 tdm.c

📁 一个两碟控制的VCD的代码,两碟之间的转动及连续播放,已大量生产的CODE.
💻 C
📖 第 1 页 / 共 2 页
字号:
	 *	 * This is an escape clause.	 */	/*	 * CDDA's copy_cdda is at the same location as STOP_STATE,	 * but we'll not get TDM interrupt for CDDA. However, we do	 * have to check XPORT_active since we may have stopped, then	 * we get an extra TDM interrupt.	 */	stopit = XPORT_active;    }    if (!TDM_expectBreak) {	/*	 * If disk is seriously scratched, currCDtime after a jump is	 * not reliable. We shouldn't turn off CD accidentally by	 * that value! We'll let the next sector to make the judgement.	 */	if ((currCDtime >= endCDtime) || (currCDtime > second_endCDtime)) {	    stopit = 1;	}    }  quit_tdm:    if (stopit) {	TDM_stop(TDM_off);    }#endif    TDM_expectBreak = 0;	/* Next currCDtime should be sequential	*/    /* Return if there is nothing left in the FIFO */    if (!argcnt || !XPORT_active) return;#ifdef XPORT11    /*     * For 1.1 players, if the current sector is INFO.VCD, then the     * transport microcode will send us:     *	1) 2B of VCD version number     *	2) 4B of PSD size     *	3) 2B of maximum segment number     *	4) 2B for the first 2 segment play item bytes     */    if (currCDtime == 0x000400) {	if (argcnt == 5) {	    /* If number of item is not right, don't even process it! */	    unsigned int szPsd;	    unsigned short szSeg;	    unsigned short dataPSD;	    unsigned char seg1;	    vcdVersion = *pfifo++;	    vcdVersion += 0x3030;	/* From BCD to character */	    szPsd = ((unsigned int) (*pfifo++)) << 16;	    szPsd |= ((unsigned int) (*pfifo++));	    szSeg = *pfifo++;	    dataPSD = *pfifo++;	    seg1 = dataPSD >> 8;	    if ((vcdVersion == 0x3131) || (szPsd == 0)) {		/* If PSD size is 0, then then is 1.1 disc */		vcdVersion = 0x3131;		if (vcx_digest || skipTk1) TDM_send_skip = 1;	    }	    foundVCDversion = 1;	/* Found a new VCD version	*/	    tmp = 0x1e1;	    if (szSeg) {		/* 		 * If there are segments, we'll look at bits [4:2] by		 * masking other bits off. If the first segment play item		 * contents byte is 0x8 or 0x18, then we have high		 * resolution still (E2). Otherwise, assume low resolution		 * still (E1)		 */		if ((seg1 == (unsigned char) 0x8) ||		    (seg1 == (unsigned char) 0x18))		  tmp = 0x1e2;	    }	    /* Reload PID to reflect E1/E2 requirement */	    XPORT_loadstill(tmp);	#if (P1O || P2O || P3O || P4O)	    keepStillType = tmp & 0xff;#endif	}	return;    }     /* If we get here, then we have file number! */    filenumber = *pfifo++;    argcnt--;#endif    subheader = *pfifo++;    argcnt--;    /*      * If there is no packid, then we don't look at subheader info.     * In addition, if there is only 1 entry left, then it is CD     * time of the next sector. Don't read it!!     */    if (argcnt < 2) {#ifdef XPORT11	/*	 * When using XPORT11, we need to look at the filenumber here	 * because sometimes we are not getting 1Ex/1C0 yet we still	 * need to find the track number.	 */	if ((filenumber & 0xff00) == 0x200) {	    /* Mode byte has to be 2; otherwise, we ignore filenumber */	    TDM_tracknumber = filenumber & 0xff;	    if (TDM_most_recent_video & 0xf) {		/* 		 * We were playing still pictures. If we believe that		 * we have finished all the data, then skip to the next		 * track.		 */		if (skipTk1) {		    register unsigned int codeinfo = subheader & 0xff;		    if ((codeinfo != 0)		&&	/* Empty	*/			(codeinfo != 0xf)	&& 	/* E0		*/			(codeinfo != 0x1f)	&& 	/* E1/padding	*/			(codeinfo != 0x3f)	&&	/* E2		*/			(codeinfo != 0x7f)) {		/* Audio	*/			TDM_send_skip = !TDM_skip_sent;		    }		}	    }	}#endif	return;    }    tmp = subheader & 0x4eff;    if ((tmp != 0x420f) && (tmp != 0x447f)) {	/*	 * If subheader looks suspecious, then clear trigger bit and EOF.	 * This prevents false autopause.	 *	 * 620F is the usual submode/coding_info for video	 * 647f is the usual submode/coding_info for audio	 */	subheader &= (~(CDSUBMODE_T | CDSUBMODE_EOF));    }    packid = *pfifo++;  error_recovery:    argcnt --;    if ((packid & 0xff00) == 0) {	/* This is NOT pack ID!! To be on the safe side, just return */	return;    }#if (XPORT11 || XPORT20)    tmp = packid & 0xfff0;    if ((tmp == 0x1c0) || (tmp == 0x1e0)) {#ifdef DSC_ENABLE_C2PO        if (C2PO_interrupt) {	    /*	     * If we have found a C2PO error since the last TDM interrupt,	     * then make a note if the data is audio so we can flush	     * ABV later.	     */	    C2PO_audio_error = (tmp == 0x1c0);	    if (tmp == 0x1e0) C2PO_video_error++;        }#endif	/* 	 * We only process subheader if packid checked OK (i.e. subheader	 * must be right)	 */#ifdef WATCHDOG	if (XPORT_start) {	    /* 	     * When we just start, there is a short period of time that	     * data starts to come in, but no huffman has completed.	     * If timer hit, the current longjmp algorithm will yank	     * us out. This is dangeous because we will miss the first	     * still picture. So I fake VBV_huffman_xfer_count to prevent	     * this long jump.	     */	    VBV_ABV_xport_xfer_count = VBV_ABV_huffman_xfer_count = 1;		    XPORT_start = 0;	}#endif#ifdef PLAY20	/*	 * If XPORT sees 000001b7, it'll do a CAM look up. Here, we check	 * the last matched CAM entry, if it is XPORT_PID_B7, then we know	 * that a 1b7 is found!	 */	if ((mvd[xport_read_cam_channel] & 0x1f) == XPORT_PID_B7)	  end_of_sequence = currCDtime;	if (subheader & CDSUBMODE_EOR) {	  if ((tmp == 0x1e0) && ((packid & 0xf) != 0)) {	      end_of_still = 2;	  }	}	/*	 * After seeing trigger bit, we always get one more video	 * sector before stopping so hopefully all the data we need	 * has been flushed out of various FIFO's.	 */#ifndef CUST3	if ((tmp == 0x1e0) && TDM_trigger) {#ifndef DVD_VCD	    TDM_stop(1);		/* Stop taking in data. Save	*					 * currCDtime+1 in stopCDtime	*/#endif	    TDM_stop_time = glbTimer;	    TDM_trigger = 3;		/* Inform decoder that all the	*					 * data is in.			*/	}#endif	/*	 * Usually when CDSUBMODE_T appears, it appears in consecutive CD	 * sectors.  Therefore, we need to set another flag such that once	 * we set the "trigger" bit, we'll not set it again within these 	 * consecutive sectors. In other words, we'll only stop once for 	 * a consecutive bunch of CDSUBMODE_T.	 */	if (set_trigger && PBC_on #ifdef CUST4 	/* CUST4 has some modes that shouldn't have auto-pause enabled */	   && !PLAY_no_autopause#endif	   ) {	    if (subheader & CDSUBMODE_T) {		TDM_trigger = 4;	/* Will be cleared when handled	*/		set_trigger = 0;	/* Don't set trigger again til	*					 * we are done with the		*					 * consecutive CDSUBMODE_T's	*/		trigger_time = glbTimer + FIVE_SECOND;	    }	} else if (glbTimer > trigger_time)	  set_trigger = 1;	/* Ignore other triggers for 5 seconds	*/	/*	 * Save the last VBV_wrptr before trigger bit so we know when	 * to stop decoding.	 */	if ((tmp == 0x1e0) && !TDM_trigger)	  VBV_trigger = VBV_wrptr;#endif#if (P1O || P2O || P3O || P4O)	TDM_tracknumber = filenumber & 0xff;	/* Assign file number	*/	/* 	 * Record the last video type, so we can compare it with	 * keepStillType.	 */	if (tmp == 0x1e0) TDM_most_recent_video = packid & 0xff;	if (vcx_digest) {	    if (TDM_most_recent_video & 0xf) {		/*		 * No still picture inside digest.		 */		TDM_send_skip = !TDM_skip_sent;	    }	}	if (subheader & CDSUBMODE_EOR) {	    if ((TDM_most_recent_video == keepStillType) && !vcx_digest) {		/*		 * For 3208/3210, vcx_user_video_stream is set to		 * E2 during digest. However, we don't want to pause		 * and see 'SELECT' inside INTRO screen.		 */	        if ((tmp == 0x1e0) && ((packid & 0xf) != 0)) {		    end_of_still = 2;		}		osdSelect = pbcON;	/* Show "select" + pause */	    } else /* For E0, this means end of track in some disc  */	      end_of_track++;	} else if (subheader & CDSUBMODE_EOF) end_of_track++;#endif    }#endif /* XPORT11 || XPORT20 */    /*     * argcnt can only be 1 (no PTS) or 3 (with PTS). No other value     * is expected.     */    if (argcnt == 3)      TDM_getPTS(pfifo, packid);}/* * Get Stream ID, PTS from the RISC fifo. * * Stream ID is always present (otherwise, this routine shouldn't be * called.) * * PTS is optionsl, so there are 3 possibilities: *	1) Neither PTS nor DTS:	 *		<junk:0xf> *	2) PTS only: *		<junk:PTS[4]> <PTS[3]:PTS[2]> <PTS[1]:PTS[0]> *	3) PTS + DTS, but XPORT sends in PTS only: *		<junk:PTS[4]> <PTS[3]:PTS[2]> <PTS[1]:PTS[0]> * Only case 2 and 3 will call this routine. * * Input: *	pfifo:  Pointer to the FIFO array *	packid:	Pack ID * * Return: *	None. */PRIVATE void TDM_getPTS(pfifo, packid)unsigned short *pfifo;unsigned short packid;{    unsigned short d1, d2, d3;    unsigned int pts;    static unsigned last_pts = 0;    /* PTS or PTS portion of PTS/DTS */    d1 = *pfifo++;    d2 = *pfifo++ & 0xfffe;    d3 = *pfifo++;	    /* Drop 1 least significant bits so our clock is 45000 Hz */    pts  = (d1 & 0xe) << 28;    pts |= (d2 << 13);    pts |= (d3 >> 2);		/* Drop 1 bit !! */    if (pts != last_pts) {    	last_pts = pts;	/* We only care about e0 and c0. */	if (packid == 0x1e0) {	    PTS_vid = pts;	} else if (packid == 0x1c0) {	    PTS_aud = pts;	} else	    return;	/* When the type of PTS change we take notice */	if (packid != PTS_last) {	    PTS_xsit++;	    PTS_last = packid;	}    }}#ifdef CUST4/* get_a_byte() and put_a_dword() needs to be in cachable region to  * generate fast enough clock. */void get_a_byte(unsigned int *dataptr) {    int	i;    volatile unsigned int* ptr = (int *) 0x1c060000; /* ROM address */#ifdef CUST4_NEW_BOARD     volatile unsigned int* ptr1 = (int *) 0x14000000; /* For CS1 enable */    for (i = 0; i < BYTE_SIZE; i++)     {	(void) *ptr1;	*dataptr <<= 1;	asm("nop");	*dataptr |= READ_HOST_DATA; /* read a bit..MSB first */	(void) *ptr;		(void) *ptr;		(void) *ptr;	    }#else /* Old Board */    for (i = 0; i < BYTE_SIZE; i++)     {        LOWER_XMT_CLK;	*dataptr <<= 1;	(void) *ptr;	/* 360nsec per read from ROM */	(void) *ptr;		(void) *ptr;		RAISE_XMT_CLK;	*dataptr |= READ_HOST_DATA; /* read a bit..MSB first */	(void) *ptr;		(void) *ptr;		(void) *ptr;	    }#endif /* CUST4_NEW_BOARD */}void put_a_dword(unsigned data){    int	i,j;    volatile unsigned int* ptr = (int *) 0x1c060000; #ifdef CUST4_NEW_BOARD     volatile unsigned int* ptr1 = (int *) 0x14000000; /* For CS1 enable */    for (i = 0; i < COMMAND_SIZE; i++)     {	if (data & 0x80000000) { /* need to send MSB first */	   WRITE_HI_TO_HOST;	} else {	   WRITE_LOW_TO_HOST;	}	(void) *ptr1;	data <<= 1;	(void) *ptr;	(void) *ptr;		(void) *ptr;	    }#else /* Old Board */    for (i = 0; i < COMMAND_SIZE; i++)     {        LOWER_XMT_CLK;	if (data & 0x80000000) { /* need to send MSB first */	   WRITE_HI_TO_HOST;	} else {	   WRITE_LOW_TO_HOST;	}	(void) *ptr;	/* 360nsec per read from ROM */	(void) *ptr;	RAISE_XMT_CLK;	data <<= 1;	(void) *ptr;	(void) *ptr;		(void) *ptr;	    }#endif /* CUST4_NEW_BOARD */}#endif /*CUST4*/

⌨️ 快捷键说明

复制代码 Ctrl + C
搜索代码 Ctrl + F
全屏模式 F11
切换主题 Ctrl + Shift + D
显示快捷键 ?
增大字号 Ctrl + =
减小字号 Ctrl + -