📄 vcd_con.cpp
字号:
{
DBGPRINT(DBG_ON(DBG_ERROR), ("LoaderGetTOC() - FAILURE reading TOC data\n"));
return (-1);
}
/* how many entries in the toc? */
entries = (tocsize - 4) / FULL_DESC_SIZE;
/* fill in the rest of the toc record */
for (x=0; x<entries; x++)
{
int offset = x*FULL_DESC_SIZE + 4;
BYTE session = bLdrBuffer[offset];
BYTE control = bLdrBuffer[offset+1];
BYTE tno = bLdrBuffer[offset+2]; /* should always be zero */
BYTE point = bLdrBuffer[offset+3]; /* track 1-99 or special code. see Mt.Fuji spec table 369 */
BYTE min = bLdrBuffer[offset+4]; /* should always be zero if point == 1-99 or 0xA0-0xA2 */
BYTE sec = bLdrBuffer[offset+5]; /* should always be zero if point == 1-99 or 0xA0-0xA2 */
BYTE fra = bLdrBuffer[offset+6]; /* should always be zero if point == 1-99 or 0xA0-0xA2 */
BYTE zero = bLdrBuffer[offset+7]; /* should always be zero unless recordable media */
BYTE pmin = bLdrBuffer[offset+8]; /* MSF minutes if point == 1-99 */
BYTE psec = bLdrBuffer[offset+9]; /* MSF seconds if point == 1-99 */
BYTE pfra = bLdrBuffer[offset+10]; /* MSF frames if point == 1-99 */
UNUSED_PARAM(session);
UNUSED_PARAM(tno);
UNUSED_PARAM(min);
UNUSED_PARAM(sec);
UNUSED_PARAM(fra);
UNUSED_PARAM(zero);
DBGPRINT(DBG_ON(DBG_TRACE), ("%.2X, %.2X, %.2X, %.2X, %.2X\n", control, point, pmin, psec, pfra));
/* gather data and fill in the structure */
if (point == TOC_FST) // 0xA0
{
g_toc_info.first.cont = control;
g_toc_info.first.tno = point;
g_toc_info.first.tim[0] = BIN_TO_BCD(pmin);
g_toc_info.first.tim[1] = psec;
g_toc_info.first.tim[2] = pfra;
}
else if (point == TOC_LST) // 0xA1
{
g_toc_info.last.cont = control;
g_toc_info.last.tno = point;
g_toc_info.last.tim[0] = BIN_TO_BCD(pmin);
g_toc_info.last.tim[1] = BIN_TO_BCD(psec);
g_toc_info.last.tim[2] = BIN_TO_BCD(pfra);
last_track = pmin;
}
else if (point == TOC_OUT) /* 0xA2 retrieves the address of the lead-out area */
{
g_toc_info.out.cont = control;
g_toc_info.out.tno = point; /* the lead-out area doesn't have a track number */
g_toc_info.out.tim[0] = BIN_TO_BCD(pmin);
g_toc_info.out.tim[1] = BIN_TO_BCD(psec);
g_toc_info.out.tim[2] = BIN_TO_BCD(pfra);
}
else if ( (point > 0) && (point <= TRACK_MAX) ) /* individual track data */
{
g_toc_info.tno[point - 1].cont = control;
g_toc_info.tno[point - 1].tno = BIN_TO_BCD(point);
g_toc_info.tno[point - 1].tim[0] = BIN_TO_BCD(pmin);
g_toc_info.tno[point - 1].tim[1] = BIN_TO_BCD(psec);
g_toc_info.tno[point - 1].tim[2] = BIN_TO_BCD(pfra);
}
else
{
DbgPrint(("extra TOC info found for disc\n"));
DbgPrint(("point = 0x%.2X\n", point));
}
}
#if DBG_ON(DBG_VERBOSE)
int n;
printf("g_toc_info.first.tno = %.2X\n",g_toc_info.first.tno);
printf("g_toc_info.first.tim[0] = %.2X\n",g_toc_info.first.tim[0]);
printf("g_toc_info.first.tim[1] = %.2X\n",g_toc_info.first.tim[1]);
printf("g_toc_info.first.tim[2] = %.2X\n\n",g_toc_info.first.tim[2]);
printf("g_toc_info.last.tno = %.2X\n",g_toc_info.last.tno);
printf("g_toc_info.last.tim[0] = %.2X\n",g_toc_info.last.tim[0]);
printf("g_toc_info.last.tim[1] = %.2X\n",g_toc_info.last.tim[1]);
printf("g_toc_info.last.tim[2] = %.2X\n\n",g_toc_info.last.tim[2]);
printf("g_toc_info.out.tno = %.2X\n",g_toc_info.out.tno);
printf("g_toc_info.out.tim[0] = %.2X\n",g_toc_info.out.tim[0]);
printf("g_toc_info.out.tim[1] = %.2X\n",g_toc_info.out.tim[1]);
printf("g_toc_info.out.tim[2] = %.2X\n\n",g_toc_info.out.tim[2]);
for (n=0; n<last_track; n++)
{
printf("g_toc_info.tno[%i].tim[0] = %.2X\n", n, g_toc_info.tno[n].tim[0]);
printf("g_toc_info.tno[%i].tim[1] = %.2X\n", n, g_toc_info.tno[n].tim[1]);
printf("g_toc_info.tno[%i].tim[2] = %.2X\n\n", n, g_toc_info.tno[n].tim[2]);
}
#endif
return (0);
}
/*************************************************
Function Name: load_cd_toc
Purpose: Get the disc Table Of Contents
Theory: Gets the TOC from the drive and parses it.
Arguments: none
Returns: error code
*************************************************/
UBYTE load_cd_toc(void)
{
UBYTE error;
error = 0;
/* request the toc
* this will get the information from the loader and fill in the g_toc_info structure */
if (vcdReadToc() == -1)
{
error = 1;
}
else
{
UBYTE tno, i;
cd_max_tno = g_toc_info.last.tim[0];
cd_max_tno_cdda = cd_max_tno;
tno = com_bcdtobin(g_toc_info.last.tim[0]);
/* Max TNO */
for (i = tno; i > 1; --i)
{
if (g_toc_info.tno[i - 1].cont & TOC_CONTROL_FIELD_DATA_TRACK)
{
/* CD-DA Track ? */
break;
}
}
cd_max_tno_cdda = i; /* Max TNO */
g_max_time = g_toc_info.out.tim[0] << 16;
g_max_time |= g_toc_info.out.tim[1] << 8;
g_max_time |= g_toc_info.out.tim[2];
DBGPRINT(DBG_ON(DBG_TRACE), ("load_cd_toc(): g_max_time = %i\n", g_max_time));
if ((g_max_time == 0) || (cd_max_tno == 0))
{
DbgPrint(("load_cd_toc() -- g_max_time=%d, cd_max_tno=%d\n", g_max_time, cd_max_tno));
error = 1;
}
}
return (error);
}
/*************************************************
Function Name: load_vcd_info
Purpose: Get the disc info table
Theory: All VCD's have an info table.
One of the basic navigation structures
for the disc. This retrieves and parses it
Arguments: vcd_dir - directory with the vcd info
vcd_ext - file extension
Returns: error code
*************************************************/
UBYTE load_vcd_info(const char* vcd_dir, const char* vcd_ext)
{
LOADER_FILE_HANDLE InfoFile = 0;
UBYTE ubData[2048];
UBYTE status = 0;
char filename[50];
DBGPRINT(DBG_ON(DBG_TRACE), ("CALLED %s\n", __FUNCTION__));
snprintf(filename, 50, "/mnt/cdrom/%s/info.%s", vcd_dir, vcd_ext);
DBGPRINT(DBG_ON(DBG_TRACE), ("filename: %s\n", filename));
/*
* load and parse INFO.SVD
*/
if (LoaderFileOpen(tLoader, filename, &InfoFile) != LOADER_SUCCESS)
{
DBGPRINT(DBG_ON(DBG_ERROR), ("load_vcd_info_entry: info.svd Failed file open!\n"));
InfoFile = 0;
status = 0xff;
goto errout;
}
if (LoaderFileRead(tLoader, InfoFile, (PVOID)ubData, 2048, NULL) == LOADER_SUCCESS)
{
ULONG offset = 0;
// System ID string
memcpy(g_info_vcd.str, &ubData[offset], 8);
offset += 8;
// Version
g_info_vcd.ver = MAKE_WORD(&ubData[offset]);
offset += 2;
// Album ID String
memcpy(g_info_vcd.disc_id, &ubData[offset], 16);
offset += 16;
// Album Volumes
memcpy(g_info_vcd.album_vol, &ubData[offset], 2);
offset += 2;
// Album Sequence
memcpy(g_info_vcd.album_seq, &ubData[offset], 2);
offset += 2;
// Map Size
memcpy(g_info_vcd.map_size, &ubData[offset], 13);
offset += 13;
// Status
g_info_vcd.status = ubData[offset];
offset += 1;
// PSD size
g_info_vcd.psd_size = MAKE_DWORD(&ubData[offset]);
offset += 4;
// First segment address (MSF)
memcpy(g_info_vcd.fseg_addr, &ubData[offset], 3);
offset += 3;
// Offset multiplier
g_info_vcd.offset = ubData[offset];
offset += 1;
// Max List ID
g_info_vcd.max_list_id = MAKE_WORD(&ubData[offset]);
offset += 2;
// Max segment number
g_info_vcd.max_seg_num = MAKE_WORD(&ubData[offset]);
offset += 2;
// Segment Play Item Contents
memcpy(g_info_vcd.seg_play_item, &ubData[offset], 1980);
offset += 1980;
// Ext status
g_info_vcd.ext_status = ubData[offset];
offset += 1;
// Disc type
g_info_vcd.disc_type = ubData[offset];
offset += 1;
// reserved
memcpy(g_info_vcd.dummy, &ubData[offset], 10);
offset += 10;
}
else
{
DBGPRINT(DBG_ON(DBG_ERROR), ("load_vcd_info_entry: info.svd - Failed file read!\n"));
status = 0xff;
goto errout;
}
#if DBG_ON(DBG_TRACE)
printf("g_info_vcd.str[0] = %c\n", g_info_vcd.str[0]);
printf("g_info_vcd.str[1] = %c\n", g_info_vcd.str[1]);
printf("g_info_vcd.str[2] = %c\n", g_info_vcd.str[2]);
printf("g_info_vcd.str[3] = %c\n", g_info_vcd.str[3]);
printf("g_info_vcd.str[4] = %c\n", g_info_vcd.str[4]);
printf("g_info_vcd.str[5] = %c\n", g_info_vcd.str[5]);
printf("g_info_vcd.str[6] = %c\n", g_info_vcd.str[6]);
printf("g_info_vcd.str[7] = %c\n", g_info_vcd.str[7]);
printf("g_info_vcd.ver = 0x%X\n", g_info_vcd.ver);
printf("g_info_vcd.disc_id[0] = %c\n", g_info_vcd.disc_id[0]);
printf("g_info_vcd.disc_id[1] = %c\n", g_info_vcd.disc_id[1]);
printf("g_info_vcd.disc_id[2] = %c\n", g_info_vcd.disc_id[2]);
printf("g_info_vcd.disc_id[3] = %c\n", g_info_vcd.disc_id[3]);
printf("g_info_vcd.disc_id[4] = %c\n", g_info_vcd.disc_id[4]);
printf("g_info_vcd.disc_id[5] = %c\n", g_info_vcd.disc_id[5]);
printf("g_info_vcd.disc_id[6] = %c\n", g_info_vcd.disc_id[6]);
printf("g_info_vcd.disc_id[7] = %c\n", g_info_vcd.disc_id[7]);
printf("g_info_vcd.disc_id[8] = %c\n", g_info_vcd.disc_id[8]);
printf("g_info_vcd.disc_id[9] = %c\n", g_info_vcd.disc_id[9]);
printf("g_info_vcd.disc_id[10] = %c\n", g_info_vcd.disc_id[10]);
printf("g_info_vcd.disc_id[11] = %c\n", g_info_vcd.disc_id[11]);
printf("g_info_vcd.disc_id[12] = %c\n", g_info_vcd.disc_id[12]);
printf("g_info_vcd.disc_id[13] = %c\n", g_info_vcd.disc_id[13]);
printf("g_info_vcd.disc_id[14] = %c\n", g_info_vcd.disc_id[14]);
printf("g_info_vcd.disc_id[15] = %c\n", g_info_vcd.disc_id[15]);
printf("g_info_vcd.album_vol[0] = 0x%.2X\n", g_info_vcd.album_vol[0]);
printf("g_info_vcd.album_vol[1] = 0x%.2X\n", g_info_vcd.album_vol[1]);
printf("g_info_vcd.album_seq[0] = 0x%.2X\n", g_info_vcd.album_seq[0]);
printf("g_info_vcd.album_seq[1] = 0x%.2X\n", g_info_vcd.album_seq[1]);
printf("g_info_vcd.map_size[0] = %i\n", g_info_vcd.map_size[0]);
printf("g_info_vcd.map_size[1] = %i\n", g_info_vcd.map_size[1]);
printf("g_info_vcd.map_size[2] = %i\n", g_info_vcd.map_size[2]);
printf("g_info_vcd.map_size[3] = %i\n", g_info_vcd.map_size[3]);
printf("g_info_vcd.map_size[4] = %i\n", g_info_vcd.map_size[4]);
printf("g_info_vcd.map_size[5] = %i\n", g_info_vcd.map_size[5]);
printf("g_info_vcd.map_size[6] = %i\n", g_info_vcd.map_size[6]);
printf("g_info_vcd.map_size[7] = %i\n", g_info_vcd.map_size[7]);
printf("g_info_vcd.map_size[8] = %i\n", g_info_vcd.map_size[8]);
printf("g_info_vcd.map_size[9] = %i\n", g_info_vcd.map_size[9]);
printf("g_info_vcd.map_size[10] = %i\n", g_info_vcd.map_size[10]);
printf("g_info_vcd.map_size[11] = %i\n", g_info_vcd.map_size[11]);
printf("g_info_vcd.map_size[12] = %i\n", g_info_vcd.map_size[12]);
printf("g_info_vcd.status = %i\n", g_info_vcd.status);
printf("g_info_vcd.psd_size = %i\n", g_info_vcd.psd_size);
printf("g_info_vcd.fseg_addr[0] = %i\n", g_info_vcd.fseg_addr[0]);
printf("g_info_vcd.fseg_addr[1] = %i\n", g_info_vcd.fseg_addr[1]);
printf("g_info_vcd.fseg_addr[2] = %i\n", g_info_vcd.fseg_addr[2]);
printf("g_info_vcd.offset = %i\n", g_info_vcd.offset);
printf("g_info_vcd.max_list_id = %i\n", g_info_vcd.max_list_id);
printf("g_info_vcd.max_seg_num = %i\n", g_info_vcd.max_seg_num);
for (x=0; x<1980; x++)
{
if (g_info_vcd.seg_play_item[x] != 0)
{
printf("g_info_vcd.seg_play_item[%i] = 0x%x\n", x, g_info_vcd.seg_play_item[x]);
OS_TaskYield();
}
}
printf("g_info_vcd.ext_status = %i\n", g_info_vcd.ext_status);
printf("g_info_vcd.disc_type = %i\n", g_info_vcd.disc_type);
#endif
errout:
if (InfoFile != 0)
{
LoaderFileClose(tLoader, InfoFile);
}
return (status);
}
/*************************************************
Function Name: load_cd_entry
Purpose: Get the disc entry tables
Theory: All VCD's have an entry table.
One of the basic navigation structures
for the disc. This retrieves and parses it
Arguments: vcd_dir - directory with the vcd info
vcd_ext - file extension
Returns: error code
*************************************************/
UBYTE load_vcd_entry(const char* vcd_dir, const char* vcd_ext)
{
ULONG x = 0;
LOADER_FILE_HANDLE EntriesFile = 0;
UBYTE ubData[2048];
UBYTE status = 0;
char filename[50];
DBGPRINT(DBG_ON(DBG_TRACE), ("CALLED %s\n", __FUNCTION__));
snprintf(filename, 50, "/mnt/cdrom/%s/entries.%s", vcd_dir, vcd_ext);
/*
* load and parse ENTRIES.SVD
*/
if (LoaderFileOpen(tLoader, filename, &EntriesFile) != LOADER_SUCCESS)
{
DBGPRINT(DBG_ON(DBG_ERROR), ("load_vcd_info_entry: entries.svd Failed file open!\n"));
EntriesFile = 0;
status = 0xff;
goto errout;
}
if (LoaderFileRead(tLoader, EntriesFile, (PVOID)ubData, 2048, NULL) == LOADER_SUCCESS)
{
ULONG offset = 0;
// ID string
memcpy(g_entry_vcd.str, &ubData[offset], 8);
offset += 8;
// version
memcpy(g_entry_vcd.ver, &ubData[offset], 2);
offset += 2;
// number of list entries
g_entry_vcd.entries_used = MAKE_WORD(&ubData[offset]);
offset += 2;
DBGPRINT(DBG_ON(DBG_TRACE), ("There are %i entries used\n", g_entry_vcd.entries_used));
// loop and add entries
for (x=0; x<g_entry_vcd.entries_used; x++)
{
memcpy(&g_entry_vcd.entry[x], &ubData[offset], sizeof(ENTRY));
offset += sizeof(ENTRY);
DBGPRINT(DBG_ON(DBG_TRACE), ("ENTRY #%i, tno=0x%.2x, %.2i:%.2i:%.2i\n",
x+1, g_entry_vcd.entry[x].tno, g_entry_vcd.entry[x].sector[0], g_entry_vcd.entry[x].sector[1], g_entry_vcd.entry[x].sector[2]));
}
}
else
{
DBGPRINT(DBG_ON(DBG_ERROR), ("load_vcd_info_entry: entries.svd - Failed file read!\n"));
status = 0xff;
goto errout;
}
errout:
if (EntriesFile != 0)
{
LoaderFileClose(tLoader, EntriesFile);
}
return (status);
}
/*************************************************
Function Name: load_vcd_lot
Purpose: Get the disc Play Sequence Descriptor
and List Offset Table
Theory: VCD 2.0 discs can have a PSD and LOT
for segment play items. This routine
retrieves the LOT and parse it.
Arguments: none
Returns: error code
*************************************************/
UBYTE load_vcd_lot(const char* vcd_dir, const char* vcd_ext)
{
UBYTE error = 0;
LOADER_FILE_HANDLE LotFile = 0;
char filename[50];
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -