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