diff options
-rw-r--r-- | src/lib/util/cdrom.c | 107 | ||||
-rw-r--r-- | src/lib/util/cdrom.h | 8 | ||||
-rw-r--r-- | src/mame/machine/megacdcd.c | 10 | ||||
-rw-r--r-- | src/mess/machine/pce.c | 17 | ||||
-rw-r--r-- | src/tools/chdman.c | 4 |
5 files changed, 114 insertions, 32 deletions
diff --git a/src/lib/util/cdrom.c b/src/lib/util/cdrom.c index 236d2132199..7d9e053b7d4 100644 --- a/src/lib/util/cdrom.c +++ b/src/lib/util/cdrom.c @@ -124,6 +124,29 @@ INLINE UINT32 physical_to_chd_lba(cdrom_file *file, UINT32 physlba, UINT32 &trac return physlba; } +/*------------------------------------------------- + logical_to_chd_lba - find the CHD LBA + and the track number +-------------------------------------------------*/ + +INLINE UINT32 logical_to_chd_lba(cdrom_file *file, UINT32 loglba, UINT32 &tracknum) +{ + UINT32 chdlba, physlba; + int track; + + /* loop until our current LBA is less than the start LBA of the next track */ + for (track = 0; track < file->cdtoc.numtrks; track++) + if (loglba < file->cdtoc.tracks[track + 1].logframeofs) + { + // 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; + tracknum = track; + return chdlba; + } + + return loglba; +} /*************************************************************************** @@ -134,7 +157,7 @@ cdrom_file *cdrom_open(const char *inputfile) { int i; cdrom_file *file; - UINT32 physofs; + UINT32 physofs, logofs; /* allocate memory for the CD-ROM file */ file = new cdrom_file(); @@ -168,21 +191,32 @@ cdrom_file *cdrom_open(const char *inputfile) /* calculate the starting frame for each track, keeping in mind that CHDMAN pads tracks out with extra frames to fit 4-frame size boundries */ - physofs = 0; + physofs = logofs = 0; for (i = 0; i < file->cdtoc.numtrks; i++) { file->cdtoc.tracks[i].physframeofs = physofs; file->cdtoc.tracks[i].chdframeofs = 0; + // pregap counts against this track + logofs += file->cdtoc.tracks[i].pregap; + file->cdtoc.tracks[i].logframeofs = logofs; + + // postgap counts against the next track + logofs += file->cdtoc.tracks[i].postgap; + physofs += file->cdtoc.tracks[i].frames; + logofs += file->cdtoc.tracks[i].frames; - LOG(("Track %02d is format %d subtype %d datasize %d subsize %d frames %d extraframes %d physofs %d chdofs %d\n", i+1, + LOG(("Track %02d is format %d subtype %d datasize %d subsize %d frames %d extraframes %d pregap %d postgap %d logofs %d physofs %d chdofs %d\n", i+1, file->cdtoc.tracks[i].trktype, file->cdtoc.tracks[i].subtype, file->cdtoc.tracks[i].datasize, file->cdtoc.tracks[i].subsize, file->cdtoc.tracks[i].frames, - file->cdtoc.tracks[i].extraframes, + file->cdtoc.tracks[i].extraframes, + file->cdtoc.tracks[i].pregap, + file->cdtoc.tracks[i].postgap, + file->cdtoc.tracks[i].logframeofs, file->cdtoc.tracks[i].physframeofs, file->cdtoc.tracks[i].chdframeofs)); } @@ -203,7 +237,7 @@ cdrom_file *cdrom_open(chd_file *chd) { int i; cdrom_file *file; - UINT32 physofs, chdofs; + UINT32 physofs, chdofs, logofs; chd_error err; /* punt if no CHD */ @@ -237,23 +271,34 @@ cdrom_file *cdrom_open(chd_file *chd) /* calculate the starting frame for each track, keeping in mind that CHDMAN pads tracks out with extra frames to fit 4-frame size boundries */ - physofs = chdofs = 0; + physofs = chdofs = logofs = 0; for (i = 0; i < file->cdtoc.numtrks; i++) { file->cdtoc.tracks[i].physframeofs = physofs; file->cdtoc.tracks[i].chdframeofs = chdofs; + // pregap counts against this track + logofs += file->cdtoc.tracks[i].pregap; + file->cdtoc.tracks[i].logframeofs = logofs; + + // postgap counts against the next track + logofs += file->cdtoc.tracks[i].postgap; + physofs += file->cdtoc.tracks[i].frames; chdofs += file->cdtoc.tracks[i].frames; chdofs += file->cdtoc.tracks[i].extraframes; + logofs += file->cdtoc.tracks[i].frames; - LOG(("Track %02d is format %d subtype %d datasize %d subsize %d frames %d extraframes %d physofs %d chdofs %d\n", i+1, + LOG(("Track %02d is format %d subtype %d datasize %d subsize %d frames %d extraframes %d pregap %d postgap %d logofs %d physofs %d chdofs %d\n", i+1, file->cdtoc.tracks[i].trktype, file->cdtoc.tracks[i].subtype, file->cdtoc.tracks[i].datasize, file->cdtoc.tracks[i].subsize, file->cdtoc.tracks[i].frames, - file->cdtoc.tracks[i].extraframes, + file->cdtoc.tracks[i].extraframes, + file->cdtoc.tracks[i].pregap, + file->cdtoc.tracks[i].postgap, + file->cdtoc.tracks[i].logframeofs, file->cdtoc.tracks[i].physframeofs, file->cdtoc.tracks[i].chdframeofs)); } @@ -328,14 +373,23 @@ chd_error read_partial_sector(cdrom_file *file, void *dest, UINT32 chdsector, UI from a CD-ROM -------------------------------------------------*/ -UINT32 cdrom_read_data(cdrom_file *file, UINT32 lbasector, void *buffer, UINT32 datatype) +UINT32 cdrom_read_data(cdrom_file *file, UINT32 lbasector, void *buffer, UINT32 datatype, bool phys) { if (file == NULL) return 0; // compute CHD sector and tracknumber UINT32 tracknum = 0; - UINT32 chdsector = physical_to_chd_lba(file, lbasector, tracknum); + UINT32 chdsector; + + if (phys) + { + chdsector = physical_to_chd_lba(file, lbasector, tracknum); + } + else + { + chdsector = logical_to_chd_lba(file, lbasector, tracknum); + } /* copy out the requested sector */ UINT32 tracktype = file->cdtoc.tracks[tracknum].trktype; @@ -390,14 +444,24 @@ UINT32 cdrom_read_data(cdrom_file *file, UINT32 lbasector, void *buffer, UINT32 a sector -------------------------------------------------*/ -UINT32 cdrom_read_subcode(cdrom_file *file, UINT32 lbasector, void *buffer) +UINT32 cdrom_read_subcode(cdrom_file *file, UINT32 lbasector, void *buffer, bool phys) { if (file == NULL) return ~0; // compute CHD sector and tracknumber UINT32 tracknum = 0; - UINT32 chdsector = physical_to_chd_lba(file, lbasector, tracknum); + UINT32 chdsector; + + if (phys) + { + chdsector = physical_to_chd_lba(file, lbasector, tracknum); + } + else + { + chdsector = logical_to_chd_lba(file, lbasector, tracknum); + } + if (file->cdtoc.tracks[tracknum].subsize == 0) return 1; @@ -425,7 +489,7 @@ UINT32 cdrom_get_track(cdrom_file *file, UINT32 frame) return ~0; /* convert to a CHD sector offset and get track information */ - physical_to_chd_lba(file, frame, track); + logical_to_chd_lba(file, frame, track); return track; } @@ -444,10 +508,25 @@ UINT32 cdrom_get_track_start(cdrom_file *file, UINT32 track) if (track == 0xaa) track = file->cdtoc.numtrks; - return file->cdtoc.tracks[track].physframeofs; + return file->cdtoc.tracks[track].logframeofs; } +/*------------------------------------------------- + cdrom_get_track_start_phys - get the + physical frame number that a track starts at +-------------------------------------------------*/ + +UINT32 cdrom_get_track_start_phys(cdrom_file *file, UINT32 track) +{ + if (file == NULL) + return ~0; + /* handle lead-out specially */ + if (track == 0xaa) + track = file->cdtoc.numtrks; + + return file->cdtoc.tracks[track].physframeofs; +} /*************************************************************************** TOC UTILITIES diff --git a/src/lib/util/cdrom.h b/src/lib/util/cdrom.h index 437501618b3..8737df50fdf 100644 --- a/src/lib/util/cdrom.h +++ b/src/lib/util/cdrom.h @@ -112,7 +112,8 @@ struct cdrom_track_info UINT32 padframes; /* number of frames of padding to add to the end of the track; needed for GDI */ /* fields used in MAME only */ - UINT32 physframeofs; /* frame number on the real CD this track starts at */ + UINT32 logframeofs; /* logical frame offset: offset including pre/postgaps */ + UINT32 physframeofs; /* physical frame offset: offset ignoring pre/postgaps */ UINT32 chdframeofs; /* frame number this track starts at on the CHD */ }; @@ -137,12 +138,13 @@ void cdrom_close(cdrom_file *file); cdrom_file *cdrom_open(const char *inputfile); /* core read access */ -UINT32 cdrom_read_data(cdrom_file *file, UINT32 lbasector, void *buffer, UINT32 datatype); -UINT32 cdrom_read_subcode(cdrom_file *file, UINT32 lbasector, void *buffer); +UINT32 cdrom_read_data(cdrom_file *file, UINT32 lbasector, void *buffer, UINT32 datatype, bool phys=false); +UINT32 cdrom_read_subcode(cdrom_file *file, UINT32 lbasector, void *buffer, bool phys=false); /* handy utilities */ UINT32 cdrom_get_track(cdrom_file *file, UINT32 frame); UINT32 cdrom_get_track_start(cdrom_file *file, UINT32 track); +UINT32 cdrom_get_track_start_phys(cdrom_file *file, UINT32 track); /* TOC utilities */ int cdrom_get_last_track(cdrom_file *file); diff --git a/src/mame/machine/megacdcd.c b/src/mame/machine/megacdcd.c index 155c1f0f5b2..bb8faed5992 100644 --- a/src/mame/machine/megacdcd.c +++ b/src/mame/machine/megacdcd.c @@ -236,9 +236,9 @@ void lc89510_temp_device::CDD_GetTrackPos(void) if(segacd.cd == NULL) // no cd is there, bail out return; CDD_STATUS |= SCD_STATUS; - elapsedlba = SCD_CURLBA - segacd.toc->tracks[ cdrom_get_track(segacd.cd, SCD_CURLBA) ].physframeofs; + elapsedlba = SCD_CURLBA - segacd.toc->tracks[ cdrom_get_track(segacd.cd, SCD_CURLBA) ].logframeofs; msf = lba_to_msf_alt (elapsedlba); - //popmessage("%08x %08x",SCD_CURLBA,segacd.toc->tracks[ cdrom_get_track(segacd.cd, SCD_CURLBA) + 1 ].physframeofs); + //popmessage("%08x %08x",SCD_CURLBA,segacd.toc->tracks[ cdrom_get_track(segacd.cd, SCD_CURLBA) + 1 ].logframeofs); CDD_MIN = to_bcd(((msf & 0x00ff0000)>>16),false); CDD_SEC = to_bcd(((msf & 0x0000ff00)>>8),false); CDD_FRAME = to_bcd(((msf & 0x000000ff)>>0),false); @@ -263,7 +263,7 @@ void lc89510_temp_device::CDD_Length(void) return; CDD_STATUS |= SCD_STATUS; - UINT32 startlba = (segacd.toc->tracks[cdrom_get_last_track(segacd.cd)].physframeofs); + UINT32 startlba = (segacd.toc->tracks[cdrom_get_last_track(segacd.cd)].logframeofs); UINT32 startmsf = lba_to_msf_alt( startlba ); CDD_MIN = to_bcd((startmsf&0x00ff0000)>>16,false); @@ -301,7 +301,7 @@ void lc89510_temp_device::CDD_GetTrackAdr(void) if (track < 1) track = 1; - UINT32 startlba = (segacd.toc->tracks[track-1].physframeofs); + UINT32 startlba = (segacd.toc->tracks[track-1].logframeofs); UINT32 startmsf = lba_to_msf_alt( startlba+150 ); CDD_MIN = to_bcd((startmsf&0x00ff0000)>>16,false); @@ -359,7 +359,7 @@ void lc89510_temp_device::CDD_Play(running_machine &machine) CLEAR_CDD_RESULT UINT32 msf = getmsf_from_regs(); SCD_CURLBA = msf_to_lba(msf)-150; - UINT32 end_msf = segacd.toc->tracks[ cdrom_get_track(segacd.cd, SCD_CURLBA) + 1 ].physframeofs; + UINT32 end_msf = segacd.toc->tracks[ cdrom_get_track(segacd.cd, SCD_CURLBA) + 1 ].logframeofs; SCD_CURTRK = cdrom_get_track(segacd.cd, SCD_CURLBA)+1; LC8951UpdateHeader(); SCD_STATUS = CDD_PLAYINGCDDA; diff --git a/src/mess/machine/pce.c b/src/mess/machine/pce.c index b298e539820..2c3382ba1af 100644 --- a/src/mess/machine/pce.c +++ b/src/mess/machine/pce.c @@ -600,12 +600,13 @@ static void pce_cd_nec_set_audio_start_position( running_machine &machine ) f = bcd_2_dec( pce_cd.command_buffer[4]); frame = f + 75 * (s + m * 60); - if(frame >= 525) // TODO: seven seconds gap? O_o - frame -= 525; + // PCE tries to be clever here and set (start of track + track pregap size) to skip the pregap + // (I guess it wants the TOC to have the real start sector for data tracks and the start of the pregap for audio?) + frame -= pce_cd.toc->tracks[cdrom_get_track(pce_cd.cd, frame)].pregap; break; } case 0x80: - frame = pce_cd.toc->tracks[ bcd_2_dec( pce_cd.command_buffer[2] ) - 1 ].physframeofs; + frame = pce_cd.toc->tracks[ bcd_2_dec( pce_cd.command_buffer[2] ) - 1 ].logframeofs; break; default: popmessage("CD-DA set start mode 0xc0, contact MESSdev"); @@ -635,7 +636,7 @@ static void pce_cd_nec_set_audio_start_position( running_machine &machine ) else { pce_cd.cdda_status = PCE_CD_CDDA_PLAYING; - pce_cd.end_frame = pce_cd.toc->tracks[ cdrom_get_track(pce_cd.cd, pce_cd.current_frame) + 1 ].physframeofs; //get the end of THIS track + pce_cd.end_frame = pce_cd.toc->tracks[ cdrom_get_track(pce_cd.cd, pce_cd.current_frame) + 1 ].logframeofs; //get the end of THIS track cdda_start_audio( machine.device( "cdda" ), pce_cd.current_frame, pce_cd.end_frame - pce_cd.current_frame ); pce_cd.end_mark = 0; pce_cd.cdda_play_mode = 3; @@ -680,7 +681,7 @@ static void pce_cd_nec_set_audio_stop_position( running_machine &machine ) break; } case 0x80: - frame = pce_cd.toc->tracks[ bcd_2_dec( pce_cd.command_buffer[2] ) - 1 ].physframeofs; + frame = pce_cd.toc->tracks[ bcd_2_dec( pce_cd.command_buffer[2] ) - 1 ].logframeofs; break; default: popmessage("CD-DA set end mode 0xc0, contact MESSdev"); @@ -822,7 +823,7 @@ static void pce_cd_nec_get_dir_info( running_machine &machine ) pce_cd.data_buffer_size = 2; break; case 0x01: /* Get total disk size in MSF format */ - frame = toc->tracks[toc->numtrks-1].physframeofs; + frame = toc->tracks[toc->numtrks-1].logframeofs; frame += toc->tracks[toc->numtrks-1].frames; msf = lba_to_msf( frame + 150 ); @@ -834,13 +835,13 @@ static void pce_cd_nec_get_dir_info( running_machine &machine ) case 0x02: /* Get track information */ if ( pce_cd.command_buffer[2] == 0xAA ) { - frame = toc->tracks[toc->numtrks-1].physframeofs; + frame = toc->tracks[toc->numtrks-1].logframeofs; frame += toc->tracks[toc->numtrks-1].frames; pce_cd.data_buffer[3] = 0x04; /* correct? */ } else { track = MAX( bcd_2_dec( pce_cd.command_buffer[2] ), 1 ); - frame = toc->tracks[track-1].physframeofs; + frame = toc->tracks[track-1].logframeofs; pce_cd.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/tools/chdman.c b/src/tools/chdman.c index 7790b248e6e..3210470d7a2 100644 --- a/src/tools/chdman.c +++ b/src/tools/chdman.c @@ -2366,7 +2366,7 @@ static void do_extract_cd(parameters_t ¶ms) progress(false, "Extracting, %.1f%% complete... \r", 100.0 * double(outputoffs) / double(total_bytes)); // read the data - cdrom_read_data(cdrom, cdrom_get_track_start(cdrom, tracknum) + frame, &buffer[bufferoffs], trackinfo.trktype); + cdrom_read_data(cdrom, cdrom_get_track_start_phys(cdrom, tracknum) + frame, &buffer[bufferoffs], trackinfo.trktype, true); // for CDRWin, audio tracks must be reversed if ((mode == MODE_CUEBIN) && (trackinfo.trktype == CD_TRACK_AUDIO)) @@ -2382,7 +2382,7 @@ static void do_extract_cd(parameters_t ¶ms) // read the subcode data if (trackinfo.subtype != CD_SUB_NONE && (mode == MODE_NORMAL)) { - cdrom_read_subcode(cdrom, cdrom_get_track_start(cdrom, tracknum) + frame, &buffer[bufferoffs]); + cdrom_read_subcode(cdrom, cdrom_get_track_start_phys(cdrom, tracknum) + frame, &buffer[bufferoffs], true); bufferoffs += trackinfo.subsize; } |