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

📄 cd.c

📁 这是一个VCD解码的学习资料,主要是CD SERVO 的一些源代码!以供大家参考!
💻 C
📖 第 1 页 / 共 2 页
字号:
/*
** FILE
** cd.c
**
** DESCRIPTION
** cd/cdrom format processing
**
** HISTORY
** v.0.0.1	1999.4.27
**
** split from mpegsys.c 
**
**/

#include "config.h"
#include "global.h"
#include "memmap.h"
#include "dma.h"

#include "avd.h"
#include "sig.h"
#include "stc.h"

#include "epp.h"
#include "util.h"
#include "func.h"
#include "cdfunc.h"

#include "ringbuf.h"
#include "cddsp.h"
#include "cdxa.h"
#include "cdfs.h"
#include "cderr.h"
#include "drammap.h"  /*jhuang 891101*/ 

#include "cd.h"

//#define MONE_CDMSF
//#define MONE_SEEK
//#define MONE_INTR
//#define MONE_S_LEN
//#define MONE_P_MSF

int	do_cd_layer(void);
int	do_cd_payload(void);
void AdjustGoBack(int *goback);
void Mp3Seek(UINT16 f,UINT8 do_goto);

/*
** FUNCTION
** do_cd_reset
**
** DESCRIPTION
** reset all CD-layer information.
**/
void	do_cd_reset(int flag)
{
  if (flag & CD_RESET_HARDWARE) reset_cddsp();
  if (flag & CD_RESET_PARSER)
  {
    cd_seek_error       = 0;
    cd_seek_error_max   = 6;
    cbv_x               = cbv_y         = 0;
    do_cd               = do_cd_layer;
  }
  if (flag & CD_RESET_CACHE)
  {
    int i;
    for (i=0; i<MP3SECT_CACHE_LINES; i++) tag_msf[i] = -1;
  }
}


/*
** FUNCTION 
** do_cd_stop
**
** DESCRIPTION
** stop CD input
**/
void	do_cd_stop(void)
{
  regs0->cddsp_control	= RF_CDDSP_STOP;
#ifdef MONE_SEEK  
  NowPrint("cd stop\n");
#endif
}


/*
** FUNCTION
** do_cd_freerun
**
** DESCRIPTION
** let CD input incoming..
*/
void	do_cd_freerun(void)
{
  regs0->cddsp_control	= 0;
  regs0->cddsp_status	= 0;
#ifdef MONE_SEEK  
  NowPrint("cd free run\n");
#endif
}


/*
** FUNCTION
** do_cdrom_prep()
**
** DESCRIPTION
** we are now trying to read a cdrom sector into system by way of 
** dma.  it is a really bad idea to use this kind of dma in software
** , however the system architecture has been defined and we've got
** enough trouble about this. 
** in the proper manner, we'll call this routine by setting up 3
** global variables,
**
**	s_msf		HSF sector numbering.
**	s_skip		skip # of bytes first
**	s_len	 	read # of bytes
**	s_addr.dma.y
**	s_addr.dma.x	target address.
**
**	dma_buf[OGT..]	is used to store output buffer
** 	dma_optr	is used to track output buffer
**
**/
int	do_cdrom_prep(UINT32 cdrom_msf, int cdrom_len, int cdrom_skip, int vx, int vy)
{
  AVD_ResetMediaStatus();
  AVD_state_flags	= AVD_DATA;

  SetIntrMask(INTR_MASK_CDROM);
  SetIntrFlag(0);

  playback_cd_init(CDROM_DMA);

  vcd_state		= 0;

  s_msf			= cdrom_msf;
  s_skip		= cdrom_skip;
#ifdef MONE_S_LEN
  printf("s_len:%ld len1:%ld",s_len,cdrom_len);
  NowPrint("");
#endif
  s_len			= cdrom_len;
  s_addr.dma.x		= vx; 
  s_addr.dma.y		= vy;
  dma_optr		= 0;

  CDSetPlayOnlyGood();
  do_cd_seek(CDDSP_GOBACK);

  return 0;
}


/*
** FUNCTION
** do_cdrom_prep2
**
** DESCRIPTION
** Use LBC (memory-mapped-access) to write to DRAM. This function
** occationally failed for some unknown reason.  We believed it was
** problem of test-chip.
**/
int	do_cdrom_prep2(UINT32 cdrom_msf, int cdrom_len, int cdrom_skip, BYTE *p)
{
  AVD_ResetMediaStatus();
  AVD_state_flags	= AVD_DATA;

  SetIntrMask(INTR_MASK_CDROM);
  SetIntrFlag(0);

  playback_cd_init(CDROM);

  vcd_state		= 0;
#ifdef MONE_S_LEN
  printf("s_len:%ld len6:%ld",s_len,cdrom_len);
  NowPrint("");
#endif
  s_msf			= cdrom_msf;
  s_skip		= cdrom_skip;
  s_len			= cdrom_len;
  s_addr.ptr		= p;
  dma_optr		= 0;

  CDSetPlayOnlyGood();
  do_cd_seek(CDDSP_GOBACK);

  return 0;
}


/*
** FUNCTION
** do_cdrom_wait()
**
** DESCRIPTION
** call cdrom-polling routine.
**/
int	do_cdrom_wait(void)
{
  int	intr_mask = GetIntrMask();
  SetIntrMask(INTR_MASK_CDROM);
  SetIntrFlag(0);
  do {
    polling();

 
    if(((sys_cmd&0xffff)==(CMD_FUNC|CMD_FUNC_OPEN))) //kenny 891103 to solve mp3 open fail problem
    {
    //printf("**OPEN\n");    	
      return -1;
    }  

    srv_cd();
  } while (!IsAVDMediaInterrupt());
  SetIntrMask(intr_mask);

  #ifdef NES_GAME   /*summer 2001/5/4 09:57PM*/
  if(bDiscType&NES_DISC)  
  {
  	if(cd_seek_error==8)
  		return -1;
  }
  #endif
  
  if (IsAVDMediaError())
  {
    //epp_write_slow("CDROM ERROR\n");
    return -1;
  }
  return 0;
}


/*
** FUNCTION
** do_cdrom_cache_load
**
** DESCRIPTION
** load into sector cache.
**/
static	int	do_cdrom_cache_load(int i, UINT32 msf)
{
	BYTE j,k;
	  
  for(j=0;j<Offset_line;j++)
  	tag_msf[i+j]	= -1;
  
  do_cdrom_prep(msf, 2048*Offset_line, 0, 0, SECT_CACHE(i));
  if (do_cdrom_wait())
    return -1;
    
  for(j=0;j<Offset_line;j++)
  {
  	if(addmsf(msf,j)<s_msf)
  	{
  		//printf("sucess:%06x\n",addmsf(msf,j));
  		tag_msf[i+j]	= addmsf(msf,j);
  	}//else
  	{
  		//printf("fail:%06x\n",addmsf(msf,j));
  	}
  }
  return 0;
}


/*
** FUNCTION 
** do_dma_cpy
** 
** DESCRIPTION
** copy a region from DMA-position (vy:vx len) to (*dest)
**/
void	do_dma_cpy(BYTE *dest, int vx, int vy, int skip, int len)
{
  vy   += skip >> 10;		/* DMA Y-addr			*/
  vx   += skip &  0x03e0;	/* DMA X-addr(32-byte boundary)	*/
  skip &= 0x001f;		/* 32-byte fraction		*/
  if (vx>=1024) {vy++; vx-=1024;}

  DMA_push(0,32);

  while (len>0)
  { 
    int i,len_one;
    DMA_load(VADDR_MODE_GLOBAL, vy, vx, 0, 32);
    ADDR_adv(vx,vy,1024,2048,32);
    DMA_wait();
    len_one = 32-skip;
    if (len_one>len) len_one=len;
    for (i=0; i<len_one; i++)
      *dest++ = dma_buf.b[skip+i];
    skip = 0;
    len -= len_one;
  }

  DMA_pop(0,32);
}

/*
** FUNCTION
** do_cdrom_force_read
**
** DESCRIPTION
** load from a sector (and read from CD on cache-miss)
**/
int	do_cdrom_force_read(BYTE *dest, UINT32 msf, UINT32 skip, int len)
{
//	int Max_line;
  	int cache_line;

	/* reload cache */
	
	cache_line = last_cache_line+Offset_line;		
		
	if (cache_line>=CacheLineNs)
	  cache_line = 0;
	  
	last_cache_line = cache_line;
	if (do_cdrom_cache_load(cache_line, msf)<0) return -1;
 
	/* DMA copy to destination */ 
	do_dma_cpy(dest, 0, SECT_CACHE(cache_line), skip, len);
	return 0;
}
/*
** FUNCTION
** do_cdrom_read_one
**
** DESCRIPTION
** load from a sector (and read from CD on cache-miss)
**/
int	do_cdrom_read_one(BYTE *dest, UINT32 msf, UINT32 skip, int len)
{
  int cache_line;

  for (cache_line=0;cache_line<CacheLineNs;cache_line++)
  {
    if (msf==tag_msf[cache_line]) break;
  }

  if (cache_line==CacheLineNs)
  {
    /* reload cache */
    cache_line = last_cache_line+Offset_line;
    if (cache_line>=CacheLineNs)
      cache_line = 0;
    last_cache_line = cache_line;
    if (do_cdrom_cache_load(cache_line, msf)<0) return -1;
  }

  /* DMA copy to destination */ 
  do_dma_cpy(dest, 0, SECT_CACHE(cache_line), skip, len);
  return 0;
}



/*
** FUNCTION
** do_cdrom_read
**
** DESCRIPTION
** perform one CDROM read from (extent:pos).
**
** 	. extent	=> cdrom sector LBA (starting from 00:02:16)
**	. pos		=> cdrom-skip
**	. size		=> cdrom-len
**/
#define	BLOCK_SIZE	2048

int	do_cdrom_read(BYTE *dest, UINT32 extent, UINT32 pos, int size)
{
  UINT32 msf;
  int	 skip;
   
  /*
  ** adjust EXTENT to the first sector
  */
  extent += pos/BLOCK_SIZE;
  skip	  = pos%BLOCK_SIZE;

  /*
  ** translate to MSF
  */
  //msf	  = l2msf(extent);
  msf	  = extent;
  {//terry,2000/11/17 06:52PM
    UINT32 max,min;
        
    max=gettrkmsf_leadout();
    min=gettrkmsf(1)&0x00ffffff;
    //printf("====>Max:%ld Min:%ld Now:%ld\n",max,min,msf);    
    if( (msf>max)||(msf<min) )
    {
       //printf("Invalid MSF\n");
       return -1;
    }
  }     	
  /*
  ** sequencially read every sector.
  */
  do {
    int	len = BLOCK_SIZE - skip;
    if (len>size) len=size;
    if (do_cdrom_read_one(dest, msf, skip, len)<0) return -1;
    dest += len;
    size -= len;
    pos  += len;
    msf   = addmsf(msf, 1);
    skip  = 0;
  } while (size>0);
  return pos;
}


/*
** FUNCTION
** do_cdrom_read_msf
**
** DESCRIPTION
** perform CDROM read from (extent:pos).
**
** 	. extent	=> indicate cdrom sector
**	. pos		=> cdrom-skip
**	. size		=> cdrom-len
**/
int	do_cdrom_read_msf(BYTE *dest, UINT32 msf, UINT32 pos, int size)
{
  int inc;
  int skip;

  /*
  ** adjust MSF to the first sector
  */
  inc	= pos/BLOCK_SIZE;
  skip  = pos%BLOCK_SIZE;
  msf   = addmsf(msf, inc);

  /*
  ** sequencially read every sector.
  */
  do {
    int	len = BLOCK_SIZE - skip;
    if (len>size) len=size;
    do_cdrom_read_one(dest, msf, skip, len);
    dest += len;
    size -= len;
    pos  += len;
    msf   = addmsf(msf, 1);
    skip  = 0;
  } while (size>0);
  return pos;
}


int	do_cd_play(int trk)
{
  cd_func_playtrack(trk);
  regs0->cddsp_control  = 0;
  regs0->cddsp_status	= 0;
#ifdef MONE_SEEK  
  NowPrint("cd play\n");
#endif  
  return 0;
}


/*
** FUNCTION
** do_cd_seek
**
** DESCRIPTION
** perform CD seek function.
**
** NOTE
** Currently we flushed the old CD buffer during seeking.  Maybe we 
** should try to record last MSF (using CDDSP hardware MMSSFF) and
** restart there.
**/
int	do_cd_seek(int goback)
{
	
#ifndef PANASONIC_DSA	//terry,2001/2/20 07:01PM

    if(goback) //terry 891031
    switch(play_state)
    {
    	case VCD_STATE_POWER:
    	case VCD_STATE_STOP:
    	case VCD_STATE_OPEN:
    	return -1;
    
    	case VCD_STATE_NORMAL:
    	case VCD_STATE_PREVIEW:
    	case VCD_STATE_INTRO:
    	case VCD_STATE_9FRAMES:
    	
    		if( (goto_active==0)&&(!IsAVDData()) )
    		{
    			if( psd_state==(PSD_SEL_LIST|PSD_PLAY_SEG))
    			{
    				ChkIsSkipTrk=0;
    			}else
    			{
	    			ChkIsSkipTrk=1;
	    			//printf("G:%d S:%d\n",goto_active,ChkIsSkipTrk);
	    			return -1;
	    		}
    		}else if(goto_active==1)    		
    			ChkIsSkipTrk=2;
    		else
    			ChkIsSkipTrk=0;
    		break;
    	//case VCD_STATE_PLAYMP3:
    	//	ChkIsSkipTrk=2;
    	//	break;
    	default:
			ChkIsSkipTrk=0;
			break;   
   }  
#endif
  //printf("Goto:%d Skip:%d\n",goto_active,ChkIsSkipTrk);
    
  /*
  ** this will not function if you intended to
  ** seek an invalid MSF
  **/
  if (!IsValidMSF(s_msf)) return -1;

  /*
  ** adjust goback
  */
  AdjustGoBack(&goback);  

  /*
  ** handle CDDA case
  */
  if (cd_type==CDDA)
  {
    /* goback 0 frames (to avoid track-number changes too often)	*/
    goback = 0;
    /* just release CDDA input						*/
    regs0->cddsp_control	= 0;
#ifdef MONE_SEEK
    NowPrint("cdda seek\n");
#endif
  }
  else
  {
    /* stop CDDSP */
    if( (goto_active!=1)||IsAVDData() )
    {
    	regs0->cddsp_control  = RF_CDDSP_STOP | RF_CDDSP_RESET;
		regs0->cddsp_control	= RF_CDDSP_SEEK;
#ifdef MONE_SEEK
		printf("seek\n");
#endif
    }else if(!goback)
    {
#ifdef MONE_SEEK    	
    	printf("seek\n");
#endif
        regs0->cddsp_control	= RF_CDDSP_SEEK;
    }else
    	{                                 //jhuang 01-6-13 14:37
    	  if(play_state==VCD_STATE_SLOW || play_state==VCD_STATE_STEP)
    	  if(regs0->cddsp_control==RF_CDDSP_PAUSE) 
    	  regs0->cddsp_control	= RF_CDDSP_SEEK;
    	   
    	  cd_sequencer_max=50;    
        }
/* try CDDSP seeking	*/
#ifndef SUPPORT_COMBO
    regs0->cddsp_mm_bcd		= bin2bcd(msf_mm(s_msf));
    regs0->cddsp_ss_bcd		= bin2bcd(msf_ss(s_msf));
    regs0->cddsp_ff_bcd		= bin2bcd(msf_ff(s_msf));
#endif

#ifdef MONE_SEEK
    printf("data:%d mm:%d ss:%d ff:%d ,s_msf:%ld\n",IsAVDData(),bin2bcd(msf_mm(s_msf)),bin2bcd(msf_ss(s_msf)),bin2bcd(msf_ff(s_msf)),s_msf);
#endif
  }

  /* reset status */
  regs0->cddsp_status	= 0;

#ifdef SUPPORT_COMBO

	//#ifdef PANASONIC_SERVO
	 // cd_func_gotomsf(addmsf(s_msf, goback));
	//#else
	  cd_func_gotomsf(s_msf);	
	//#endif
#else
	cd_func_gotomsf(addmsf(s_msf, goback));
#endif
  
  
  return -1;
}



/*
** FUNCTION
** do_cd_speed_up()
**/
void	do_cd_speed_up()
{
  cd_func_setspeed(2);
}


/*

⌨️ 快捷键说明

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