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

📄 vcd.c

📁 一个两碟控制的VCD的代码,两碟之间的转动及连续播放,已大量生产的CODE.
💻 C
📖 第 1 页 / 共 2 页
字号:
	    time = *((unsigned int *)&scratch_buf[index]) & x00ffffff;
	    if (time > CDtime) {
		entry_number = previous_number;
		break;
	    }
    }

/* If not found (!found), use entry_number..which has already been
 * incremented correctly. Don't use previous_number.
 * Yong, this will accomplish what you tried with the CUST3 ifdef.
 */
#if 0 
    /* We treat it as the last entry in the last track */
    if (!found) {
#ifdef CUST3
	entry_number = get_total_entry_number() - 1;
#else
	entry_number = previous_number;
#endif
    }
#endif /* PV */

    return (entry_number);
}

#ifdef ABSOLUTE_GOTO_TIME
/*------------------------------------------------------------------------
  Function:get_track_number
  Parameters:
      CDtime : BCD 0x00mmssff format.
  Description:
      Given a bcd time, return a track number that the CDtime is in
      that track.
  Return:
      0 : NO good.
------------------------------------------------------------------------*/
int get_track_number(int CDtime)
{
    int addr;
    int total_track_size;
    int track_number = 0;
    int found = 0;
    int track_begin_time;
    int track;
    int i;
    unsigned char *scratch_buf;

    /* check if the time is too big */
    if (CDtime >= (CDinfo.leadout & x00ffffff))
	return 0;

    total_track_size = (CDinfo.lasttrack - CDinfo.firsttrack) * 4;
    addr = TRACK_INFO_OFFSET + 4; /* skip the physical track 1 */

	    /* get track data */
    scratch_buf = (char *)((addr | x2000000)& x0fffffff);

	/* find the track */
    for (i = 0; i < total_track_size; i++) {
	    track_number++;
	    track_begin_time = *((unsigned int *)&scratch_buf[4*i]) &x00ffffff;

	    if (track_begin_time > CDtime) {
		track_number--;	     /* The previous track is the right one. */
		found = 1;
		break;
	    }
    }

    if (!found)
	track_number = CDinfo.lasttrack;

    return (track_number);
}

#endif

/*-----------------------------------------------------------
  Function: get_track_info
  Return Value:
    GOOD -> success
    BAD -> failure
-----------------------------------------------------------*/
int get_track_info(unsigned char track_num, unsigned int *start_mmssff,
		   unsigned int *end_mmssff, unsigned char *type)
{
#if 1
    int addr, last_track;
    unsigned char *scratch_buf;

#ifdef CUST4 /* CUST4 syscon gives us physical not logical track */
    last_track  = CDinfo.lasttrack - 1;
#else
    last_track  = CDinfo.lasttrack;
#endif /*CUST4*/

    if ((track_num < CDinfo.firsttrack) || 
	(track_num > last_track))
	return (BAD);

    /* get the track info data */
    addr = track_num * 4 + TRACK_INFO_OFFSET;
    scratch_buf = (char *)((addr | x2000000)& x0fffffff);

    *start_mmssff = (*((unsigned int *)&scratch_buf[0])) & x00ffffff;
    if (track_num < last_track) {
	*end_mmssff =  (*((unsigned int *)&scratch_buf[4])) & x00ffffff;
    }
    else { /* it is the last track, so the end_mmssff is the leave out time */
	*end_mmssff =  CDinfo.leadout & x00ffffff;
    }

    *end_mmssff = adjCDtime(*end_mmssff, 0x0100, 0);	/* minus 1 second */

    *type = (scratch_buf[0] & 0x40) >> 6;	/* check bit 6 for audio or data */
				        /* 0 -> CDDA. */
    return (GOOD);

#else	/* get track info from entries.vcd */

 /* get track info from entries.vcd */
    int addr;
    int last_entry;
    int i, j;
    int find_first = 0;
    unsigned char *scratch_buf; 

    /* check whether the seg_num is a good one */
    *start_mmssff = 0x2933;

track_num++;

    if (track_num < 2 || track_num > 99)
	return (BAD);


    addr = ENTRY_START_OFFSET; /* 0 base */

    last_entry = get_total_entry_number();

    for (i = 0; i < last_entry; i++) {
	if (!(mod_func(i, 64))) /* get next 64 long word bytes */ {
	    addr = ENTRY_START_OFFSET + i * 4; /* 4 bytes per entry */
    	    scratch_buf = (char *)((addr | x2000000)& x0fffffff);
	}

	j = mod_func(i, 64);	/* find the offset from scratch_buf */

	/* check we find the first entry whose track number == track_num */
	if ((scratch_buf[4*j] == track_num) && (!find_first)) {
	    *start_mmssff = (*((unsigned int *)&scratch_buf[4*j])) & x00ffffff;
	    find_first = 1;

	}

	/* check we find the first entry of the next track */
	if ((scratch_buf[4*j] != track_num) && (find_first)) {
	    *end_mmssff = (*((unsigned int *)&scratch_buf[4*j])) & x00ffffff;
	    break;

	}
    }
    
    return (GOOD);
#endif
}

/*-----------------------------------------------------------
  Function: reset_PSD
  NOTE: This function should be called when a new disk is
        put in CD drive.
-----------------------------------------------------------*/
void reset_PSD()
{
    PSD_start_addr = -1;
    PSD_end_addr = -1;
}

/*-----------------------------------------------------------
  Function: get_PSD
  Description: For a given PSD offset, it copys data from
     the PSD offset to buffer.

  Return Value:
     The number of bytes copied.
-----------------------------------------------------------*/
#if 1 /*def ECHO*/
#define SECTION_SIZE		512	/* bytes */
char * get_PSD(int offset, int size)
{
    int addr;
    int sector;
    int start_mmssff, search_mmssff;
    unsigned char  ss, ff, search_ff, search_ss;
    int tmp;
    int end_addr;

    addr = offset * 8;	/* Offset multiplier */
    end_addr = addr + size;
    if ((addr < PSD_start_addr || addr >= PSD_end_addr) ||
	(end_addr >= PSD_end_addr)) {
	int num_of_sectors, i;
	int start_section;	/* 512 bytes is one section. */
	int start_offset;
	int end_section;

	/* We get one sector for PSD if all data we need belong to one sector.
	   Otherwise, we need cross two secotrs.*/
	start_section = (addr % PSD_SECTOR_SIZE) / SECTION_SIZE;
	end_section = (end_addr % PSD_SECTOR_SIZE) / SECTION_SIZE;

	/* byte position from 0 to 511 is section 1.
	   byte position form 512 to 1023 is section 2.... */
	if (start_section == 3) {
	    /* the last section of the first sector
	       and the first section of the next one. */
	    num_of_sectors = 2;
	} else {
	    num_of_sectors = 1;
	}

	sector = addr / PSD_SECTOR_SIZE;
	start_offset = start_section * SECTION_SIZE;
	PSD_start_addr = sector * PSD_SECTOR_SIZE + 
	                 (start_section * SECTION_SIZE);
	PSD_end_addr = PSD_start_addr + PSD_SIZE;

	for (i = 0; i < num_of_sectors; i++) {
	    int offset;

	    sector += i;
	    tmp = (34 + sector) % 75; 
	    ff = hex2bcd[tmp]; /* 75 sector / second */
	    tmp = (34 + sector) / 75;
	    ss = hex2bcd[tmp + 0x04];
	
	    search_mmssff = (ss << 8) | ff;
	    getSectors(search_mmssff, 1, 2048);

	    if (num_of_sectors == 1) {
		put_scratch(PSD_START_OFFSET, (CDI_ptr + start_offset), 
			    SECTION_SIZE * 2);
	    } else {
		/* two sectors case */
		if (i == 0) {
		    put_scratch(PSD_START_OFFSET, (CDI_ptr + start_offset), 
				SECTION_SIZE);
		} else {
		    put_scratch((PSD_START_OFFSET + SECTION_SIZE), CDI_ptr, 
				SECTION_SIZE);
		}
	    }	
	}
    }

    addr -= PSD_start_addr;	/* adjust the addr */
    return (char *)((addr + PSD_START_OFFSET)|x2000000);
}

#else	/* ECHO */

char * get_PSD(int offset, int size)
{
    int addr;
    int sector;
    int start_mmssff, search_mmssff;
    unsigned char  ss, ff, search_ff, search_ss;
    int tmp;

    addr = offset * 8;	/* Offset multiplier */

    if ((addr < PSD_start_addr || addr >= PSD_end_addr) ||
	((addr + size) >= PSD_end_addr)) {
	/* get a new PSD data */
	int num_of_sectors, i;
	sector = addr / PSD_SECTOR_SIZE;
				/* use software mod/div  function. */
				/* since we do not want to inclue */
				/* div/mod library. */

	/* We need to decide whether we get a complete sector for PSD or
	   two half-secotr from 2 sectors for PSD. */
	if (((sector + 1) * PSD_SECTOR_SIZE) >= (addr + size)) {
	    num_of_sectors = 1;
	    PSD_start_addr = sector * PSD_SECTOR_SIZE;
	} else {
	    num_of_sectors = 2;
	    PSD_start_addr = sector * PSD_SECTOR_SIZE + (PSD_SECTOR_SIZE >> 1);
	}
	PSD_end_addr = PSD_start_addr + PSD_SECTOR_SIZE;

	for (i = 0; i < num_of_sectors; i++) {
	    sector += i;
	    tmp = (34 + sector) % 75; 
	    ff = hex2bcd[tmp]; /* 75 sector / second */
	    tmp = (34 + sector) / 75;
	    ss = hex2bcd[tmp + 0x04];
	
	    search_mmssff = (ss << 8) | ff;
	    getSectors(search_mmssff, 1, 2048);

	    if (num_of_sectors == 1)
		put_scratch(PSD_START_OFFSET, CDI_ptr, PSD_SECTOR_SIZE);
	    else if (i == 0)
		put_scratch(PSD_START_OFFSET, CDI_ptr+(PSD_SECTOR_SIZE >> 1), 
			    PSD_SECTOR_SIZE >> 1);
	    else
		put_scratch(PSD_START_OFFSET + (PSD_SECTOR_SIZE >> 1), 
			    CDI_ptr, PSD_SECTOR_SIZE >> 1);
	}
    }

    addr -= PSD_start_addr;	/* adjust the addr */
    return (char *)((addr + PSD_START_OFFSET));
}
#endif  /* ECHO */

#ifdef PRE_EMPHASIS
int is_track_pre_emphasis(int track_num)
{
    int		addr;
    char	control;
    unsigned char *scratch_buf; 

    /* get the track info data */
    addr = track_num * 4 + TRACK_INFO_OFFSET;
    scratch_buf = (char *)((addr | x2000000)& x0fffffff);

    control = scratch_buf[0] >> 4;

    /* see red book for info */   
    control &= 0xd;
    if ((control == 0x1) || (control == 0x9))
	return 1;

    return 0;
}
#endif /*PRE_EMPHASIS*/

#ifdef SCENE
/*-----------------------------------------------------------
  Function: get_list_offset
  Description: For a given list ID number, it gets the 
     the corresponding list ID offset.

  Return Value:
     The list ID offset.
-----------------------------------------------------------*/
unsigned short get_list_offset(unsigned int list_id_num)
{
    int odd_id = 0;
    unsigned int addr;
    unsigned short list_offset;
    unsigned char *scratch_buf; 

    if (list_id_num & 0x1) { /* Check for odd number */
	list_id_num &= 0xfffffffe;
	odd_id = 1;
    }     
    addr = (list_id_num << 1); /* (2 * list_id_num) bytes */
    addr += LOT_VCD_OFFSET;
    scratch_buf = (char *)((addr | x2000000)& x0fffffff);
    
    if (odd_id)
	list_offset = *((unsigned short *)(&scratch_buf[2]));
    else
	list_offset = *((unsigned short *)(scratch_buf));

    return(list_offset);
}
#endif /*SCENE*/


⌨️ 快捷键说明

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