📄 cd.c
字号:
/*
** 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 + -