📄 cd.c
字号:
#include "config.h"
#include "global.h"
#include "memmap.h"
#include "dma.h"
#include "avd.h"
#include "sig.h"
#include "stc.h"
#include "util.h"
#include "func.h"
#include "cdfunc.h"
#include "ringbuf.h"
#include "cddsp.h"
#include "cdxa.h"
#include "cdfs.h"
#include "cd.h"
#include "fs9660.h"
extern void reset_cddsp(void); // in cddsp.c
int do_cd_layer(void);
int do_cd_payload(void);
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 = 3; // 6 // jhuang playability 2002/12/4
#ifdef SUPPORT_CD_MOVE
cbv_x = 736;
cbv_y = 0;
#else
cbv_x = cbv_y = 0;
#endif
#ifdef SUPPORT_ESP
espw_x = 0;
espw_y = 0;
espr_x = 0;
espr_y = 0;
#endif
do_cd = do_cd_layer;
}
if (flag & CD_RESET_CACHE) {
}
}
void do_cd_stop(void)
{
regs0->cddsp_control = RF_CDDSP_STOP;
}
void do_cd_freerun(void)
{
regs0->cddsp_control = 0;
regs0->cddsp_status = 0;
}
int do_cdrom_prep(UINT32 cdrom_msf, int cdrom_len, int cdrom_skip, int vx, int vy)
{
cdrom_msf = cdrom_len = cdrom_skip = vx = vy = 0;
return 0;
}
int do_cdrom_prep2(UINT32 cdrom_msf, int cdrom_len, int cdrom_skip, BYTE * p)
{
if (*p)
cdrom_msf = cdrom_len = cdrom_skip = 0;
return 0;
}
int do_cdrom_wait(void)
{
return 0;
}
int do_cdrom_read_one(BYTE * dest, UINT32 msf, UINT32 skip, int len)
{
if (*dest) {
msf = skip = len = 0;
}
return 0;
}
int do_cdrom_read(BYTE * dest, UINT32 extent, UINT32 pos, int size)
{
if (*dest) {
extent = pos = size = 0;
}
return 0;
}
int do_cdrom_read_msf(BYTE * dest, UINT32 msf, UINT32 pos, int size)
{
if (*dest) {
msf = pos = size = 0;
}
return 0;
}
int do_cd_play(int trk)
{
cd_func_playtrack(trk);
regs0->cddsp_control = 0;
regs0->cddsp_status = 0;
return 0;
}
int do_cd_seek(int goback)
{
goback = 0;
return -1;
}
void do_cd_speed_up()
{
}
void do_cd_speed_down()
{
}
void do_cd_pause(void)
{
}
void do_cd_pause_release()
{
}
/*
** 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
**
**/
int do_cd_layer(void)
{
int offset;
UINT32 status;
polling();
/* set initial guess */
cd_len = 2352 + 16;
cd_left = 0;
// NO skip data
cddsp_flag = 0;
status = regs0->cddsp_status;
if (status & RF_CDDSP_CRC_ERROR_MASK) {
regs0->cddsp_status = 0;
}
/*
** Check CD sector type and determine length/padding
*/
if (cd_type != CDDA) {
t_cdxa *cdxa;
int failed;
/*
** SYNC to CDXA header
*/
offset = 0;
cdxa = (t_cdxa *) & dma_buf.b[0];
#if (ENDIAN==LITTLE)
failed = (cdxa->sync_word[0] ^ 0xffffff00);
failed |= (cdxa->sync_word[1] ^ 0xffffffff);
failed |= (cdxa->sync_word[2] ^ 0x00ffffff);
#else
failed = (cdxa->sync_word[0] ^ 0x00ffffff);
failed |= (cdxa->sync_word[1] ^ 0xffffffff);
failed |= (cdxa->sync_word[2] ^ 0xffffff00);
#endif
if (failed) {
offset = 32;
cdxa = (t_cdxa *) & dma_buf.b[32];
#if (ENDIAN==LITTLE)
failed = (cdxa->sync_word[0] ^ 0xffffff00);
failed |= (cdxa->sync_word[1] ^ 0xffffffff);
failed |= (cdxa->sync_word[2] ^ 0x00ffffff);
#else
failed = (cdxa->sync_word[0] ^ 0x00ffffff);
failed |= (cdxa->sync_word[1] ^ 0xffffffff);
failed |= (cdxa->sync_word[2] ^ 0xffffff00);
#endif
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));
/*
** 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) {
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;
}
}
if (n_msf == s_msf) {
cderr_clear_crcerr();
}
/*
** This sector is accepted and now we update sector pointer s_msf to next one.
*/
if (skip_track_goto_ok == 1) { // update s_msf and clear flag
skip_track_goto_ok = 0;
s_msf = MSF(bcd2bin(regs0->cddsp_mm_bcd),
bcd2bin(regs0->cddsp_ss_bcd),
bcd2bin(regs0->cddsp_ff_bcd));
}
else
s_msf = addmsf(n_msf, 1);
}
cderr_clearES_seqerr(); // jhuang playability 2002/12/4
#ifdef PHILIPS_SERVO
cderr_clear_seekerr();
#endif
cd_sequencer_max = 12; //24; // jhuang playability 2002/12/4
do_cd = do_cd_payload;
if (dma_iptr > 32)
cddsp_flag = 0x1;
return 1;
}
int do_cd_payload(void)
{
int cl = cd_len;
int free = SRV_IN_BATCH - dma_iptr;
if (cl < free) {
do_cd = do_cd_layer;
dma_ilen = cl;
// check need skip load data
if (cddsp_flag == 0x1)
cddsp_flag = 0x2;
}
else {
dma_ilen = SRV_IN_BATCH;
}
cd_len = cl - free;
switch (cd_type) {
default:
while (do_system());
break;
}
return 0; /* please reload */
}
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -