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

📄 svcd.c

📁 VCD原創程序 轉載請說明你出處
💻 C
字号:
/*
** FILE
** svcd.c
**
** DESCRIPTION
** check and return current CD infomation.
** manage low-level navigation structure.
**
*/

#include "config.h"
#include "global.h"
#include "func.h"
#include "dma.h"
#include "cdxa.h"
#include "util.h"
#include "stdlib.h"

#include "cdfs.h"
#include "epp.h"
#include "cd.h"

#include "svcd.h"
#include "memmap.h"
#include "osd.h"
#include "tx_code.h"
#include "timer.h"

#ifdef SUPPORT_EPP_DBG
//#define MONE_READ_SECT
//#define MONE_READ_SEG_MSF  
//#define MONE_CD_TYPE
#endif
/*
**
** iso9660_str  Tag (at PVD) for CDROM disc
**
** vcd_str  Tag (at INFO) for VCD
** cvd_str  Tag (at INFO) for CVD
** svcd_str Tag (at INFO) for SVCD
*/
static const char iso9660_str[5] = { 'C', 'D', '0', '0', '1' };
static const char vcd_str[8] = { 'V', 'I', 'D', 'E', 'O', '_', 'C', 'D' };
static const char tag_str[2] = { '2', '0' };
static const char cdi_str[4] = { 'C', 'D', '-', 'I' };
static const char cvd_str[8] = { 'H', 'Q', '-', 'V', 'C', 'D', ' ', ' ' };
static const char svcd_str[8] = { 'S', 'U', 'P', 'E', 'R', 'V', 'C', 'D' };
static const char oko_str[6] = { 'P', 'A', '-', 'V', 'C', 'D' };

//static const char oko1_str[8] = { 'P', 'A', '-', 'V', 'C', 'D', ' ', ' ' }; //Dr. OKO
static const char mpeg_str[4] = { 'M', 'P', 'E', 'G' };
static const char vcd30_str[7] = { 'S', '_', 'V', 'C', 'D', '3', '0' };


/*
** FUNCTION
** check_cdtype
** 
** DESCRIPTION
** this is the routine to check cd-type
*/
#define MSF_PVD             0x000210
#define MSF_INFO            0x000400
#define MSF_ENTRY           0x000401
#define MSF_ANCHOR          0x000531


#define SEGMENT_FIRST_FLAG  (1<<5)
#define IS_SEGMENT_FIRST(s) ((s)&SEGMENT_FIRST_FLAG)


#if 0
/*
** To count how many different characters between
** the two strings.
*/
int strdiff(const char *s1, const char *s2, int n)
{
    int     t = 0;

    for(; (n-- > 0) && (*s1 != 0) && (*s2 != 0); s1++, s2++)
        if(*s1 != *s2)
            t++;
    return t;
}
#endif

//Return 1 if we detect a VCD
int check_cd()
{
	int i;
	int found = 0;
	int tries = 0;
	t_sect_info *p = (t_sect_info *)(VCD_INFO_ADR);

	#ifdef MSF_INFO
	//printf("check_cd SessionNs[%d] found[%d]  try[%d]\n", SessionNs, found, tries);
	#endif

	//Clear buffer
	BYTE *temp = (BYTE *) (VCD_INFO_ADR);
	for (i = 0; i < 64; i++)
	{
		temp[i] = 0;
	}
	
	srv_kernel = srv_cd;
	timeout_playback = 0;
	
	//Check track 1 coding type
	if (
		((gettrkcna(1) & CNA_MASK_TYPE) != CNA_DATA)//First track not data, return 0
		||(SessionNs > 1)	 //multi-session disc	//jslin 20050707	single-session disc, SeccionNs = 1
		)
	{
		
		return 0;
	}

	cd_toggle_crc(1);
	while (!found && (tries < 4))
	{
		#ifdef MSF_INFO
		//printf("read info try[%d] \n", tries);
		#endif
		
		tries += 1;
		if (new_cdrom_read_msf((char *) VCD_INFO_ADR, MSF_INFO, 0, 2048) == 0)
		{
			if (tries > 2)
				cd_toggle_crc(0);
		}
		else
		{
			i = new_cdrom_read_msf((char *) VCD_ENTRIES_ADR, MSF_ENTRY, 0, 2048);
		}
		
#ifdef MONE_CD_TYPE
		HexDump((BYTE *) VCD_INFO_ADR, 64);
#endif
        
		//convert to little endian
#if (ENDIAN == LITTLE)
		p->version = endian_swap_16(p->version);
		p->album_no = endian_swap_16(p->album_no);
		p->album_seq = endian_swap_16(p->album_seq);
		p->psd_size = endian_swap_32(p->psd_size);
		p->maximum_list_id = endian_swap_16(p->maximum_list_id);
		p->maximum_segment_id = endian_swap_16(p->maximum_segment_id);
#endif
	
		//Search for VCD String
		if (strncmp(p->file_id, vcd_str, 8) == 0)
		{
			switch (p->version)
			{
				case 0x0200:
#ifdef SUPPORT_OLD_NES_DISC
					bDiscType = 0;
					bDiscType1 = 0;
						
					if (strncmp(p->album_id, "NES_DISC", 8) == 0)
						bDiscType = NES_DISC;
							
					if (strncmp(&(p->album_id[9]), "V1", 2) == 0)
						bDiscType1 |= NES_DISC_CHKSUM;
							
					if (strncmp(&(p->album_id[9]), "V2", 2) == 0)
						bDiscType |= (NES_DISC_CHKSUM | NES_DISC_HYBRID);
						
#endif
					cd_type_loaded = CDVCD20;
					found = 1;			
				break;
				
				case 0x0300:
					cd_type_loaded = CDVCD30;
					found = 1;
				break;
					
				case 0x0101:
					cd_type_loaded = CDVCD11;
					found = 1;
				break;
					
				default:
					cd_type_loaded = CDVCD11;
				break;
			}//end of switch
		}
		//Search for SVCD String
		else if ((strncmp(p->file_id, svcd_str, 8) == 0) ||
				(strncmp(p->file_id, cvd_str, 8) == 0) ||
				(strncmp(p->file_id, oko_str, 6) == 0))	
		{
			/* SVCD */
		#ifdef SUPPORT_SVCD
			cd_type_loaded = CDSVCD;
			found = 1;
		#else
		    found = -1;
		#endif
		}
	}//end of while

	psd_st.psd_list_id = 0xffff;
	
	//Recognized, but unsupported disc
	if (found == -1)
	{
	}
	else if (found)
	{
		switch (cd_type_loaded)
		{
			case CDSVCD:
			case CDVCD20:
			case CDCVD:
			
				if (p->psd_size == 0)
				{
					cd_type_loaded = CDVCD11;
				}
				else
				{
#ifdef START_UP_PBC_ON
					psd_st.psd_list_id = 0;
#endif
					psd_st.psd_item_no = 0;
					psd_st.psd_offset_multiplier = p->psd_offset_multiplier;
					psd_st.psd_first_segment_msf =
						MSF(bcd2bin(p->first_segment_mm_bcd),
							bcd2bin(p->first_segment_ss_bcd),
							bcd2bin(p->first_segment_ff_bcd));	
				}
			break;
		}
	}
#if 0 // mark by danny
	else
	{
		if((cd_trk_hi > cd_trk_lo) && (gettrkcna(2) & CNA_MASK_TYPE))
		{
			cd_type_loaded = CDVCD11;
			found = 1;
		}
	}
#endif	
	cd_toggle_crc(1);
	return found;
}


#if 0
int check_cdtype()
{

    BYTE ReadTitle_retry = 0;        
    int     i;

ReadTitle_RETRY:
 /*弄盒ぇ

⌨️ 快捷键说明

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