diff options
Diffstat (limited to 'src/lib/util/cdrom.c')
-rw-r--r-- | src/lib/util/cdrom.c | 107 |
1 files changed, 93 insertions, 14 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 |