mirror of
https://github.com/holub/mame
synced 2025-04-22 16:31:49 +03:00
util/cdrom.cpp: Return index 1/start of track data instead of index 0/start of pregap data in generated TOC. (#7878)
* Add a pre-calculated field for data from current logofs to end of track. * Removed pregap adjustment from FM Towns code. * Added pregap adjustment so track ends when audio data ends in PSX CD player. * Fixed pce_cd load error.
This commit is contained in:
parent
03167581fc
commit
2caa566f22
@ -185,12 +185,6 @@ static inline uint32_t logical_to_chd_lba(cdrom_file *file, uint32_t loglba, uin
|
||||
{
|
||||
if (loglba < file->cdtoc.tracks[track + 1].logframeofs)
|
||||
{
|
||||
// is this a no-pregap-data track? compensate for the logical offset pointing to the "wrong" sector.
|
||||
if ((file->cdtoc.tracks[track].pgdatasize == 0) && (loglba > file->cdtoc.tracks[track].pregap))
|
||||
{
|
||||
loglba -= file->cdtoc.tracks[track].pregap;
|
||||
}
|
||||
|
||||
// convert to physical and proceed
|
||||
physlba = file->cdtoc.tracks[track].physframeofs + (loglba - file->cdtoc.tracks[track].logframeofs);
|
||||
chdlba = physlba - file->cdtoc.tracks[track].physframeofs + file->cdtoc.tracks[track].chdframeofs;
|
||||
@ -258,15 +252,21 @@ cdrom_file *cdrom_open(const char *inputfile)
|
||||
physofs = logofs = 0;
|
||||
for (i = 0; i < file->cdtoc.numtrks; i++)
|
||||
{
|
||||
file->cdtoc.tracks[i].physframeofs = physofs;
|
||||
file->cdtoc.tracks[i].chdframeofs = 0;
|
||||
file->cdtoc.tracks[i].logframeofs = logofs;
|
||||
file->cdtoc.tracks[i].logframeofs = 0;
|
||||
|
||||
// if the pregap sectors aren't in the track, add them to the track's logical length
|
||||
if (file->cdtoc.tracks[i].pgdatasize == 0)
|
||||
{
|
||||
logofs += file->cdtoc.tracks[i].pregap;
|
||||
}
|
||||
else
|
||||
{
|
||||
file->cdtoc.tracks[i].logframeofs = file->cdtoc.tracks[i].pregap;
|
||||
}
|
||||
|
||||
file->cdtoc.tracks[i].physframeofs = physofs;
|
||||
file->cdtoc.tracks[i].chdframeofs = 0;
|
||||
file->cdtoc.tracks[i].logframeofs += logofs;
|
||||
file->cdtoc.tracks[i].logframes = file->cdtoc.tracks[i].frames - file->cdtoc.tracks[i].pregap;
|
||||
|
||||
// postgap adds to the track length
|
||||
logofs += file->cdtoc.tracks[i].postgap;
|
||||
@ -274,7 +274,7 @@ cdrom_file *cdrom_open(const char *inputfile)
|
||||
physofs += file->cdtoc.tracks[i].frames;
|
||||
logofs += file->cdtoc.tracks[i].frames;
|
||||
|
||||
/* printf("Track %02d is format %d subtype %d datasize %d subsize %d frames %d extraframes %d pregap %d pgmode %d presize %d postgap %d logofs %d physofs %d chdofs %d\n", i+1,
|
||||
/* printf("Track %02d is format %d subtype %d datasize %d subsize %d frames %d extraframes %d pregap %d pgmode %d presize %d postgap %d logofs %d physofs %d chdofs %d logframes %d\n", i+1,
|
||||
file->cdtoc.tracks[i].trktype,
|
||||
file->cdtoc.tracks[i].subtype,
|
||||
file->cdtoc.tracks[i].datasize,
|
||||
@ -287,13 +287,15 @@ cdrom_file *cdrom_open(const char *inputfile)
|
||||
file->cdtoc.tracks[i].postgap,
|
||||
file->cdtoc.tracks[i].logframeofs,
|
||||
file->cdtoc.tracks[i].physframeofs,
|
||||
file->cdtoc.tracks[i].chdframeofs);*/
|
||||
file->cdtoc.tracks[i].chdframeofs,
|
||||
file->cdtoc.tracks[i].logframes);*/
|
||||
}
|
||||
|
||||
/* fill out dummy entries for the last track to help our search */
|
||||
file->cdtoc.tracks[i].physframeofs = physofs;
|
||||
file->cdtoc.tracks[i].logframeofs = logofs;
|
||||
file->cdtoc.tracks[i].chdframeofs = 0;
|
||||
file->cdtoc.tracks[i].logframes = 0;
|
||||
|
||||
return file;
|
||||
}
|
||||
@ -354,15 +356,29 @@ cdrom_file *cdrom_open(chd_file *chd)
|
||||
physofs = chdofs = logofs = 0;
|
||||
for (i = 0; i < file->cdtoc.numtrks; i++)
|
||||
{
|
||||
file->cdtoc.tracks[i].physframeofs = physofs;
|
||||
file->cdtoc.tracks[i].chdframeofs = chdofs;
|
||||
file->cdtoc.tracks[i].logframeofs = logofs;
|
||||
file->cdtoc.tracks[i].logframeofs = 0;
|
||||
|
||||
// if the pregap sectors aren't in the track, add them to the track's logical length
|
||||
if (file->cdtoc.tracks[i].pgdatasize == 0)
|
||||
{
|
||||
// Anything that isn't cue.
|
||||
// toc (cdrdao): Pregap data seems to be included at the end of previous track.
|
||||
// START/PREGAP is only issued in special cases, for instance alongside ZERO commands.
|
||||
// ZERO and SILENCE commands are supposed to generate additional data that's not included
|
||||
// in the image directly, so the total logofs value must be offset to point to index 1.
|
||||
logofs += file->cdtoc.tracks[i].pregap;
|
||||
}
|
||||
else
|
||||
{
|
||||
// cues: Pregap is the difference between index 0 and index 1 unless PREGAP is specified.
|
||||
// The data is assumed to be in the bin and not generated separately, so the pregap should
|
||||
// only be added to the current track's lba to offset it to index 1.
|
||||
file->cdtoc.tracks[i].logframeofs = file->cdtoc.tracks[i].pregap;
|
||||
}
|
||||
|
||||
file->cdtoc.tracks[i].physframeofs = physofs;
|
||||
file->cdtoc.tracks[i].chdframeofs = chdofs;
|
||||
file->cdtoc.tracks[i].logframeofs += logofs;
|
||||
file->cdtoc.tracks[i].logframes = file->cdtoc.tracks[i].frames - file->cdtoc.tracks[i].pregap;
|
||||
|
||||
// postgap counts against the next track
|
||||
logofs += file->cdtoc.tracks[i].postgap;
|
||||
@ -371,8 +387,8 @@ cdrom_file *cdrom_open(chd_file *chd)
|
||||
chdofs += file->cdtoc.tracks[i].frames;
|
||||
chdofs += file->cdtoc.tracks[i].extraframes;
|
||||
logofs += file->cdtoc.tracks[i].frames;
|
||||
/*
|
||||
printf("Track %02d is format %d subtype %d datasize %d subsize %d frames %d extraframes %d pregap %d pgmode %d presize %d postgap %d logofs %d physofs %d chdofs %d\n", i+1,
|
||||
|
||||
printf("Track %02d is format %d subtype %d datasize %d subsize %d frames %d extraframes %d pregap %d pgmode %d presize %d postgap %d logofs %d physofs %d chdofs %d logframes %d\n", i+1,
|
||||
file->cdtoc.tracks[i].trktype,
|
||||
file->cdtoc.tracks[i].subtype,
|
||||
file->cdtoc.tracks[i].datasize,
|
||||
@ -385,13 +401,15 @@ cdrom_file *cdrom_open(chd_file *chd)
|
||||
file->cdtoc.tracks[i].postgap,
|
||||
file->cdtoc.tracks[i].logframeofs,
|
||||
file->cdtoc.tracks[i].physframeofs,
|
||||
file->cdtoc.tracks[i].chdframeofs);*/
|
||||
file->cdtoc.tracks[i].chdframeofs,
|
||||
file->cdtoc.tracks[i].logframes);
|
||||
}
|
||||
|
||||
/* fill out dummy entries for the last track to help our search */
|
||||
file->cdtoc.tracks[i].physframeofs = physofs;
|
||||
file->cdtoc.tracks[i].logframeofs = logofs;
|
||||
file->cdtoc.tracks[i].chdframeofs = chdofs;
|
||||
file->cdtoc.tracks[i].logframes = 0;
|
||||
|
||||
return file;
|
||||
}
|
||||
@ -455,7 +473,7 @@ chd_error read_partial_sector(cdrom_file *file, void *dest, uint32_t lbasector,
|
||||
// if this is pregap info that isn't actually in the file, just return blank data
|
||||
if (!phys)
|
||||
{
|
||||
if ((file->cdtoc.tracks[tracknum].pgdatasize == 0) && (lbasector < (file->cdtoc.tracks[tracknum].logframeofs + file->cdtoc.tracks[tracknum].pregap)))
|
||||
if ((file->cdtoc.tracks[tracknum].pgdatasize == 0) && (lbasector < file->cdtoc.tracks[tracknum].logframeofs))
|
||||
{
|
||||
//printf("PG missing sector: LBA %d, trklog %d\n", lbasector, file->cdtoc.tracks[tracknum].logframeofs);
|
||||
memset(dest, 0, length);
|
||||
@ -466,7 +484,14 @@ chd_error read_partial_sector(cdrom_file *file, void *dest, uint32_t lbasector,
|
||||
// if a CHD, just read
|
||||
if (file->chd != nullptr)
|
||||
{
|
||||
if (!phys && file->cdtoc.tracks[tracknum].pgdatasize != 0) {
|
||||
// chdman (phys=true) relies on chdframeofs to point to index 0 instead of index 1 for extractcd.
|
||||
// Actually playing CDs requires it to point to index 1 instead of index 0, so adjust the offset when phys=false.
|
||||
chdsector += file->cdtoc.tracks[tracknum].pregap;
|
||||
}
|
||||
|
||||
result = file->chd->read_bytes(uint64_t(chdsector) * uint64_t(CD_FRAME_SIZE) + startoffs, dest, length);
|
||||
|
||||
/* swap CDDA in the case of LE GDROMs */
|
||||
if ((file->cdtoc.flags & CD_FLAG_GDROMLE) && (file->cdtoc.tracks[tracknum].trktype == CD_TRACK_AUDIO))
|
||||
needswap = true;
|
||||
@ -476,12 +501,15 @@ chd_error read_partial_sector(cdrom_file *file, void *dest, uint32_t lbasector,
|
||||
// else read from the appropriate file
|
||||
util::core_file &srcfile = *file->fhandle[tracknum];
|
||||
|
||||
uint64_t sourcefileoffset = file->track_info.track[tracknum].offset;
|
||||
int bytespersector = file->cdtoc.tracks[tracknum].datasize + file->cdtoc.tracks[tracknum].subsize;
|
||||
uint64_t sourcefileoffset = file->track_info.track[tracknum].offset;
|
||||
|
||||
if (file->cdtoc.tracks[tracknum].pgdatasize != 0)
|
||||
chdsector += file->cdtoc.tracks[tracknum].pregap;
|
||||
|
||||
sourcefileoffset += chdsector * bytespersector + startoffs;
|
||||
|
||||
// printf("Reading sector %d from track %d at offset %lld\n", chdsector, tracknum, sourcefileoffset);
|
||||
// printf("Reading sector %d from track %d at offset %lu\n", chdsector, tracknum, sourcefileoffset);
|
||||
|
||||
srcfile.seek(sourcefileoffset, SEEK_SET);
|
||||
srcfile.read(dest, length);
|
||||
|
@ -88,6 +88,7 @@ struct cdrom_track_info
|
||||
uint32_t logframeofs; /* logical frame of actual track data - offset by pregap size if pregap not physically present */
|
||||
uint32_t physframeofs; /* physical frame of actual track data in CHD data */
|
||||
uint32_t chdframeofs; /* frame number this track starts at on the CHD */
|
||||
uint32_t logframes; /* number of frames from logframeofs until end of track data */
|
||||
|
||||
/* fields used in multi-cue GDI */
|
||||
uint32_t multicuearea;
|
||||
|
@ -1837,7 +1837,6 @@ uint8_t towns_state::towns_cdrom_r(offs_t offset)
|
||||
{
|
||||
int track = (m_towns_cd.extra_status/2)-4;
|
||||
addr = cdrom_get_track_start(m_cdrom->get_cdrom_file(),track);
|
||||
addr += cdrom_get_toc(m_cdrom->get_cdrom_file())->tracks[track].pregap;
|
||||
addr = lba_to_msf(addr + 150);
|
||||
towns_cd_set_status(0x17,
|
||||
(addr & 0xff0000) >> 16,(addr & 0x00ff00) >> 8,addr & 0x0000ff);
|
||||
|
@ -455,7 +455,7 @@ void lc89510_temp_device::CDD_Play()
|
||||
SCD_CURLBA = msf_to_lba(msf)-150;
|
||||
if(segacd.cd == nullptr) // no CD is there, bail out
|
||||
return;
|
||||
uint32_t end_msf = segacd.toc->tracks[ cdrom_get_track(segacd.cd, SCD_CURLBA) + 1 ].logframeofs;
|
||||
uint32_t track_length = segacd.toc->tracks[ cdrom_get_track(segacd.cd, SCD_CURLBA) ].logframes;
|
||||
SCD_CURTRK = cdrom_get_track(segacd.cd, SCD_CURLBA)+1;
|
||||
LC8951UpdateHeader();
|
||||
SCD_STATUS = CDD_PLAYINGCDDA;
|
||||
@ -464,7 +464,7 @@ void lc89510_temp_device::CDD_Play()
|
||||
printf("%d Track played\n",SCD_CURTRK);
|
||||
CDD_MIN = to_bcd(SCD_CURTRK, false);
|
||||
if(!(CURRENT_TRACK_IS_DATA))
|
||||
m_cdda->start_audio(SCD_CURLBA, end_msf - SCD_CURLBA);
|
||||
m_cdda->start_audio(SCD_CURLBA, SCD_CURLBA + track_length);
|
||||
SET_CDC_READ
|
||||
|
||||
|
||||
|
@ -503,7 +503,7 @@ void pce_cd_device::nec_set_audio_start_position()
|
||||
else
|
||||
{
|
||||
//m_cdda_status = PCE_CD_CDDA_PLAYING;
|
||||
m_end_frame = m_toc->tracks[ cdrom_get_track(m_cd_file, m_current_frame) + 1 ].logframeofs; //get the end of THIS track
|
||||
m_end_frame = m_toc->tracks[ cdrom_get_track(m_cd_file, m_current_frame) ].logframeofs + m_toc->tracks[ cdrom_get_track(m_cd_file, m_current_frame) ].logframes; //get the end of THIS track
|
||||
m_cdda->start_audio(m_current_frame, m_end_frame - m_current_frame);
|
||||
m_end_mark = 0;
|
||||
m_cdda_play_mode = 3;
|
||||
@ -700,11 +700,6 @@ void pce_cd_device::nec_get_dir_info()
|
||||
{
|
||||
track = std::max(bcd_2_dec(m_command_buffer[2]), 1U);
|
||||
frame = toc->tracks[track-1].logframeofs;
|
||||
// PCE wants the start sector for data tracks to *not* include the pregap
|
||||
if (toc->tracks[track-1].trktype != CD_TRACK_AUDIO)
|
||||
{
|
||||
frame += toc->tracks[track-1].pregap;
|
||||
}
|
||||
m_data_buffer[3] = (toc->tracks[track-1].trktype == CD_TRACK_AUDIO) ? 0x00 : 0x04;
|
||||
}
|
||||
logerror("track = %d, frame = %d\n", track, frame);
|
||||
|
@ -1149,7 +1149,8 @@ void psxcd_device::start_play()
|
||||
|
||||
if (mode&mode_autopause)
|
||||
{
|
||||
autopause_sector = cdrom_get_track_start(m_cdrom_handle, track) + cdrom_get_toc(m_cdrom_handle)->tracks[track].frames;
|
||||
auto toc = cdrom_get_toc(m_cdrom_handle);
|
||||
autopause_sector = cdrom_get_track_start(m_cdrom_handle, track) + toc->tracks[track].logframes;
|
||||
// printf("pos=%d auto=%d\n",pos,autopause_sector);
|
||||
}
|
||||
|
||||
|
Loading…
Reference in New Issue
Block a user