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

📄 cd.c

📁 这是一个VCD解码的学习资料,主要是CD SERVO 的一些源代码!以供大家参考!
💻 C
📖 第 1 页 / 共 2 页
字号:
** FUNCTION
** do_cd_speed_down()
**/
void	do_cd_speed_down()
{
  cd_func_setspeed(1);
}


/*
** FUNCTION
** do_cd_pause
**
** DESCRIPTION
** issue cdrom pausing and set-back some pausing functions.
**
** *NOTE*
** we might have to reconsider the logics here to prevent partially-lost sector.
** because we are parsing something eagerly, we might lost part of CD sector
** (since the header has been parsed)
**/
void	do_cd_pause(void)
{
  /*
  ** pause CD input..
  */
#ifdef MONE_SEEK
  printf("do_cd_pause\n");
  NowPrint("");
#endif
  regs0->cddsp_control = RF_CDDSP_PAUSE;
  ChkIsSkipTrk=0;//891031 terry 
//  timestamp_dsp=10000;
  /*
  ** handle CDDA case
  */
  if (cd_type==CDDA) 
  cd_func_pause(1);

  /*
  ** setup pause status
  */
  CDSetPause();
}


/*
** FUNCTION
** do_cd_pause_release
**
** DESCRIPTION
** issue cdrom pausing and set-back some pausing functions.
**/
void	do_cd_pause_release()
{
#ifdef MONE_SEEK
 printf("do_cd_pause release\n");
 NowPrint("");
#endif
 // do_cd_seek(CDDSP_GOBACK);
  do_cd_seek(0);//891031 terry
  CDSetPauseRelease();
}


/*
** CDROM parser
*/

/*
** FUNCTION
** process_cdrom_mapped
** 
** DESCRIPTION
** hacked cdrom server.
**/
static	int	process_cdrom_mapped(void)
{
  BYTE *p  = s_addr.ptr;
  int  len = s_len;
  int skip = s_skip;

  int	ip = dma_iptr;
  int  	il = dma_ilen;

  while (ip<il && len>0)
  {
    if (skip>0)
    {
      skip--;
      ip++;
      continue;
    }
    *p++ = dma_buf.b[ip++];
    len--;
  }

  if (len<=0)
  {
#ifdef	MONE_INTR
    epp_write("CD INTR1\n");
#endif
    AVD_SetMediaInterrupt();
  }
  
#ifdef MONE_S_LEN
  printf("s_len:%ld len4:%ld",s_len,len);
  NowPrint("");
#endif

  s_addr.ptr	= p;
  s_len		= len;
  s_skip	= skip;
  return 0;
}


/*
** FUNCTION
** do_cdrom
** 
** DESCRIPTION
** hacked cdrom server.
**/
static	int	process_cdrom(void)
{
  int	vx = s_addr.dma.x;
  int	vy = s_addr.dma.y;
  int  len = s_len;
  int skip = s_skip;

  int	ip = dma_iptr;
  int  	il = dma_ilen;
  int	op = dma_optr;

#ifdef	MONITOR
  fprintf(stderr, "do_cdrom: ip %d il %d tl %d\n", ip,il, len);
#endif

  while (ip<il && len>0)
  {
    if (skip>0)
    {
      skip--;
      ip++;
      continue;
    }
    dma_buf.b[OGT_OUT_BUF+op] = dma_buf.b[ip];
    len--;
    op++;
    ip++;
    if (op>=32)
    {
      DMA_save(VADDR_MODE_GLOBAL, vy, vx, OGT_OUT_BUF, 32);
      ADDR_adv_one(vx,vy,1024,32);
      DMA_wait();
      op=0;
    }
  }

  if (len<=0)
  {
#ifdef	MONE_INTR
    epp_write("CD INTR2\n");
#endif
    AVD_SetMediaInterrupt();
  }
#ifdef MONE_S_LEN
  printf("s_len:%ld len3:%ld",s_len,len);
  NowPrint("");
#endif
  dma_optr	= op;
  s_addr.dma.x	= vx;
  s_addr.dma.y	= vy;
  s_len		= len;
  s_skip	= skip;
  
  return 0;
}



#if	SUPPORT_MP3
/*
** FUNCTION
** process_cdrom_mp3
** 
** DESCRIPTION
** hacked cdrom server for MP3 task.
**/
static	int	process_cdrom_mp3(void)
{
  int	vx = abv_x;
  int	vy = abv_y;
  int  len = s_len;

  int	ip = dma_iptr;
  int  	il = dma_ilen;
  int	op = dma_optr;

  while (ip<il && len>0)
  {
    dma_buf.b[VIDEO_OUT_BUF+op] = dma_buf.b[ip];
    len--;
    op++;
    ip++;
    if (op>=32)
    {
      DMA_save(VADDR_MODE_GLOBAL, vy+MP3_BUF_BASE, vx, VIDEO_OUT_BUF, 32);
      if ((vx+=32)>=MP3_BUF_WIDTH)
      {
        vx = 0;
        if ((++vy)>=MP3_BUF_HEIGHT) vy = 0;
      }
      op=0;
      DMA_wait();
    }
  }
  
  if (len<=0) 
  {
  	#ifdef	MONE_INTR
    epp_write("CD INTR3\n");
#endif
  	//AVD_SetMediaInterrupt();
  	len=0;
  }

#ifdef MONE_S_LEN
  printf("s_len:%ld len2:%ld\n ",s_len,len);
  NowPrint("");
#endif

  dma_optr	= op;
  abv_x		= vx;
  abv_y		= vy;
  s_len		= len;
#ifdef SUP_MP3_FAST
//  if((e_msf-s_len)>=2048)
//  {  	
 // 	p_msf=addmsf(p_msf,1);  	
  
//#ifdef MONE_P_MSF
//	printf("p:%06x s:%06x l:%ld d:%d\n",p_msf,s_msf,s_len,e_msf-s_len);
//	NowPrint("");
//#endif 
//	e_msf=s_len;
 // }
#endif
  
  return 0;
}
#endif/*SUPPORT_MP3*/

/*
** FUNCTION
** do_cd_layer()
**
** DESCRIPTION
** process a CD header
**
** NOTE:
**
** 1. CD sector types:
**
**    mode 1 sector
**    |sssssssshhhhDDDDDDDDDDDDDDDDDDDDDD......EEEEEEEEEEE|
**    |--12---|-4-|-----2048--------|-4-|--8--|----276----|
**
**    mode 2 form 1 sector
**    |sssssssshhhhvvvvvvDDDDDDDDDDDDDDDDDDccccEEEEEEEEEEE|
**    |--12---|-4-|--8--|-----2048--------|-4-|----276----|
**
**    mode 2 form 2 sector
**    |sssssssshhhhvvvvvvDDDDDDDDDDDDDDDDDDDDDDDDDDDDDcccc|
**    |--12---|-4-|--8--|------------2324------------|-4--|
**
** 2. After processing..
**
**    |sssssssshhhhvvvvvvDDDDDDDDDDDDDDDDDDDDDDDDDDDDDcccc|
**    |<----(skipped)--->|                           |<-->| (cd_left)
**                       |------->(cd_len)<----------|
**                       |
**                       +-- we'll place fifo here (point to the payload)
**
**	ssss 	: sync words (if CDROM sectors)
** 	hhhh	: header (if CDROM sectors)
**	vvvv	: sub-header (if mode-2 sectors)
**	....	: blank (for mode-1 sector)
**	EEEE	: EDC (for mode-1 or mode-2 form-1 sector)
**	cccc	: CRC (if CDROM sectors)
**
** 	cd_len 	: length of the pay-load
**	cd_left : length of the padding-bytes
**
** 3. Like the packet/pack layer, these
**
** NOTE:
**				cd_len	cd_left
**	for mode-1		2048	
**	for mode-2 form-1	2324	20
**	for mode-2 form-2	2048	296
**		
**/
static	const	BYTE	sync_byte[12] 
  = {0x00, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0x00};


/*
** MSF_OVERFLOW_TIMES
** when received MSF is larger than we expected, the retry times.
**
** MSF_UNDERFLOW_TIMES
** when received MSF is smaller than we expected, the retry times.
**/
#define	MSF_OVERFLOW_TIMES	16
#define	MSF_UNDERFLOW_TIMES	16

int	do_cd_layer(void)
{
  int    offset;
  UINT32 status;

  polling();

  /* set initial guess */
  cd_len	= 2352 + 16;
  cd_left	= 0;

  status = regs0->cddsp_status;
  if (status & RF_CDDSP_CRC_ERROR_MASK)
  {
    regs0->cddsp_status = 0;

    if (cderr_handler(CDERR_CRC_ERROR))
    {
      return 0;
    }
  }

  /*
  ** Check CD sector type and determine length/padding
  */
  if (cd_type != CDDA)
  {
    t_cdxa	*cdxa;

    /*
    ** SYNC to CDXA header
    */
    offset  = 0;
    cdxa    = (t_cdxa *)&dma_buf.b[0];
    {
      int failed;
      failed  = (cdxa->sync_word[0] ^ 0x00ffffff);
      failed |= (cdxa->sync_word[1] ^ 0xffffffff);
      failed |= (cdxa->sync_word[2] ^ 0xffffff00);
      if (failed)
      {
        offset  = 32;
        cdxa    = (t_cdxa *)&dma_buf.b[32];
        failed  = (cdxa->sync_word[0] ^ 0x00ffffff);
        failed |= (cdxa->sync_word[1] ^ 0xffffffff);
        failed |= (cdxa->sync_word[2] ^ 0xffffff00);
        if (failed) return 0;
      }
    }

    /*
    ** Get sector MSF address from CD-XA header 
    */
    n_msf = MSF(
	bcd2bin(cdxa->mm_bcd),
	bcd2bin(cdxa->ss_bcd),
	bcd2bin(cdxa->ff_bcd)
    );

#ifdef	MONE_CDMSF
    psprintf(linebuf, "MSF %06x\n", n_msf);
    epp_write(linebuf);
#endif

    /*
    ** Check CD address sequence
    **
    ** If sector address is out of order, we have to adjust CD pickup
    ** location.
    **
    ** MSF(received) > MSF(expected)
    ** 1: reseek CD?
    ** 2: skip this frame and hope correct one will be coming soon?
    ** 3: giveup, since this frame might have been lost forever.
    **
    ** MSF(received) < MSF(expected),
    ** we have to speed-up CD layer parsing to catch up.
    **
    ** NOTE: this assume no sub-frame data in CDDSP buffer.
    **/
    s_msf &= 0x00ffffff;
    if (n_msf!=s_msf)
    {
      /*
      ** this sector is not-expected.
      */
      if ((play_state!=VCD_STATE_FASTFORWARD)&&(play_state!=VCD_STATE_FASTBACKWARD)) /*bondy 891013*/
      {
	      if (s_msf==CDMSF_FINDFIRST)
	      {
			s_msf = n_msf;
	      }
	      else if (s_msf<n_msf)
	      {
	        /*
	        ** s_msf < n_msf
	        ** we receive a LATE sector
	        */
			if (cderr_handler(CDERR_LATE_SECTOR))
	        {
	          return 0;
	        }
	      }
	      else 
	      {
	        /*
	        ** s_msf > n_msf
	        ** we receive a EARLY sector
	        */
	        if (cderr_handler(CDERR_EARLY_SECTOR))
	        {
		  	  cbv_y = WRAPr(cbv_y+1,CBV_H);
	          return 0;
	        }
	      }
	   }
    }

    /*
    ** check CD sector format
    */
    if (cdxa->mode==1)
    {
      /*
      ** mode 1
      */
      cd_len	= 2048;
      cd_left	= 288+16;
      dma_iptr	= offset+16;
    }
    else 
    {
      /*
      ** mode 2
      */
      UINT32	cd_submode = cdxa->subhead0.f.sub_mode;

      /*
      ** verify sub-header
      */
      if (cdxa->subhead0.w!=cdxa->subhead1.w) return 0;

      /*
      **
      */
      if (GetIntrMask() & INTR_AUTOPAUSE)
      {
        if (cd_submode&SUBMODE_TRIG)
          SetIntrFlag(GetIntrFlag() | INTR_AUTOPAUSE);
      }
      if (GetIntrMask() & INTR_EOF)
      {
        if (cd_submode&SUBMODE_EOF)
        {
	      //epp_write("EOF\n");
          SetIntrFlag(GetIntrFlag() | INTR_EOF);
          program_end = 1;
        }
      }

      dma_iptr   = offset+24;
      if (cd_submode & SUBMODE_FORM2) 
      {
        /*
        ** mode 2 form 2, 2324-byte payload.
        */
        cd_len  = 2324;
        cd_left = 4+16;
      }
      else
      {
        /*
        ** mode 2 form 1, 2048-byte payload.
        */
        cd_len  = 2048;
        cd_left = 280+16;
      }

    }
    /*
    ** This sector is accepted and now we update sector pointer s_msf to next one.
    */
#ifdef CDROM_OPEN_CRC_CHK  

#ifdef NES_GAME  /*summer 2001/5/4 09:57PM*/
  if(cd_crc_error)  
  {
  	cderr_clear_crcerr();
  	if(bDiscType&NES_DISC)
  	{  	
  		//ShowOsdMsg("CRC",0);
  		return 1;
  	}else if(cd_type_loaded==CDROM) 
      	{
      		if(IsAVDData())        		
      		{
      			//do_cd_seek(-6);
      		}else
      		{      		      		
	        	Mp3Seek(1,0);
	        }
    		return 1;
    	}  	
  }
  
#else  
      if(cd_type_loaded==CDROM)
      {      	
      	if(cd_crc_error)
      	{
      		cderr_clear_crcerr();
      		if(IsAVDData())        		
      		{
      			//do_cd_seek(-6);
      		}else
      		{      		      		
	        	Mp3Seek(1,0);
	        }
    		return 1;
    	}
      }
#endif          
#endif      
    if(n_msf==s_msf)
    {
  		cderr_clear_crcerr();
  		RetryFlyingDisk=0;  
  	}
  		
    s_msf = addmsf(n_msf, 1);
  }

  cderr_clear_seqerr();    
#ifdef PHILIPS_SERVO  
  cderr_clear_seekerr();
#endif  
  cd_sequencer_max=24;

  do_cd = do_cd_payload;
  return 1;
}


/*
** FUNCTION
** do_cd_payload()
**
** DESCRIPTION
** process cd_len stored in cddsp-buf
**/
int	do_cd_payload(void)
{
  int cl   = cd_len;
  int free = SRV_IN_BATCH - dma_iptr;

#ifdef MON_PARSE_CD
  fprintf(stderr, __FUNCTION__": cd_len %d (ip %d)\n", cd_len, dma_iptr);
  fflush(stderr);
#endif

  if (cl<free)
  {
    do_cd	= do_cd_layer;
    dma_ilen	= cl;
  }
  else
  {
    dma_ilen	= SRV_IN_BATCH;
  }

  cd_len = cl - free;
 
  switch (cd_type)
  {
    case CDROM_DMA:
      while (process_cdrom())
        ;
      break;

    case CDROM:
      while (process_cdrom_mapped())
        ;
      break;

#if	SUPPORT_MP3
    case CDROM_MP3:
      while (process_cdrom_mp3() &&s_len )
        ;
      break;
#endif/*SUPPORT_MP3*/

    default:
      while (do_system())
        ;
      break;
  }
  return 0;			/* please reload	*/
}


⌨️ 快捷键说明

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