diff options
author | 2021-03-30 23:49:28 +0900 | |
---|---|---|
committer | 2021-03-31 01:49:28 +1100 | |
commit | 2caa566f22606682ee432c410d40376335e12b02 (patch) | |
tree | facee57b940e411583a0cd8a705df12b1ffb3d73 /src | |
parent | 03167581fc5925c601cf8487827fde94471c2343 (diff) |
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.
Diffstat (limited to 'src')
-rw-r--r-- | src/lib/util/cdrom.cpp | 72 | ||||
-rw-r--r-- | src/lib/util/cdrom.h | 1 | ||||
-rw-r--r-- | src/mame/drivers/fmtowns.cpp | 1 | ||||
-rw-r--r-- | src/mame/machine/megacdcd.cpp | 4 | ||||
-rw-r--r-- | src/mame/machine/pce_cd.cpp | 7 | ||||
-rw-r--r-- | src/mame/machine/psxcd.cpp | 3 |
6 files changed, 56 insertions, 32 deletions
diff --git a/src/lib/util/cdrom.cpp b/src/lib/util/cdrom.cpp index 12346a66868..cb899afa96b 100644 --- a/src/lib/util/cdrom.cpp +++ b/src/lib/util/cdrom.cpp @@ -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); diff --git a/src/lib/util/cdrom.h b/src/lib/util/cdrom.h index a5b6beda806..27d41da845e 100644 --- a/src/lib/util/cdrom.h +++ b/src/lib/util/cdrom.h @@ -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; diff --git a/src/mame/drivers/fmtowns.cpp b/src/mame/drivers/fmtowns.cpp index 696446c7d04..01e7fbaa195 100644 --- a/src/mame/drivers/fmtowns.cpp +++ b/src/mame/drivers/fmtowns.cpp @@ -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); diff --git a/src/mame/machine/megacdcd.cpp b/src/mame/machine/megacdcd.cpp index 59b40146773..a9a5f44da81 100644 --- a/src/mame/machine/megacdcd.cpp +++ b/src/mame/machine/megacdcd.cpp @@ -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 diff --git a/src/mame/machine/pce_cd.cpp b/src/mame/machine/pce_cd.cpp index fe389cd9bc2..30027256512 100644 --- a/src/mame/machine/pce_cd.cpp +++ b/src/mame/machine/pce_cd.cpp @@ -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); diff --git a/src/mame/machine/psxcd.cpp b/src/mame/machine/psxcd.cpp index ddbcf2e267b..6c9580c3bd0 100644 --- a/src/mame/machine/psxcd.cpp +++ b/src/mame/machine/psxcd.cpp @@ -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); } |