summaryrefslogtreecommitdiffstatshomepage
path: root/src
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
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')
-rw-r--r--src/lib/util/cdrom.c107
-rw-r--r--src/lib/util/cdrom.h8
-rw-r--r--src/mame/machine/megacdcd.c10
-rw-r--r--src/mess/machine/pce.c17
-rw-r--r--src/tools/chdman.c4
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 &params)
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 &params)
// 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;
}