summaryrefslogtreecommitdiffstatshomepage
path: root/src/lib
diff options
context:
space:
mode:
author R. Belmont <rb6502@users.noreply.github.com>2013-01-05 17:43:12 +0000
committer R. Belmont <rb6502@users.noreply.github.com>2013-01-05 17:43:12 +0000
commita6a1b82868177a94780dddf5d06d7ae2c17fbd10 (patch)
tree5323f64835b6f2cd0f1040d0a8fe83d33e713d5f /src/lib
parent585ecc7c2e26941929e1f56153e9745ce1ab4f11 (diff)
cdrom: Introduces concept of logical sector addresses so games see the disc with pregap/postgap sectors actually taking up sector numbers as in reality. Fixes PC-Engine CDs with hardcoded sector numbers. [R. Belmont, Angelo Salese]
Diffstat (limited to 'src/lib')
-rw-r--r--src/lib/util/cdrom.c107
-rw-r--r--src/lib/util/cdrom.h8
2 files changed, 98 insertions, 17 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);