summaryrefslogtreecommitdiffstatshomepage
path: root/src
diff options
context:
space:
mode:
Diffstat (limited to 'src')
-rw-r--r--src/devices/bus/isa/mcd.cpp22
-rw-r--r--src/devices/bus/nscsi/cd.cpp24
-rw-r--r--src/devices/imagedev/chd_cd.cpp12
-rw-r--r--src/devices/machine/akiko.cpp52
-rw-r--r--src/devices/machine/spg290_cdservo.cpp50
-rw-r--r--src/devices/machine/stvcd.cpp74
-rw-r--r--src/devices/machine/stvcd.h2
-rw-r--r--src/devices/machine/t10mmc.cpp54
-rw-r--r--src/devices/sound/cdda.cpp10
-rw-r--r--src/lib/util/cdrom.cpp2587
-rw-r--r--src/lib/util/cdrom.h412
-rw-r--r--src/lib/util/chd.cpp2
-rw-r--r--src/lib/util/chdcd.cpp1848
-rw-r--r--src/lib/util/chdcd.h40
-rw-r--r--src/lib/util/chdcodec.cpp80
-rw-r--r--src/mame/drivers/fmtowns.cpp32
-rw-r--r--src/mame/drivers/jaguar.cpp8
-rw-r--r--src/mame/drivers/konamim2.cpp2
-rw-r--r--src/mame/drivers/ksys573.cpp4
-rw-r--r--src/mame/machine/cdicdic.cpp18
-rw-r--r--src/mame/machine/gdrom.cpp14
-rw-r--r--src/mame/machine/megacdcd.cpp44
-rw-r--r--src/mame/machine/megacdcd.h2
-rw-r--r--src/mame/machine/naomigd.cpp16
-rw-r--r--src/mame/machine/pce_cd.cpp41
-rw-r--r--src/mame/machine/pce_cd.h2
-rw-r--r--src/mame/machine/psxcd.cpp36
-rw-r--r--src/mame/machine/psxcd.h4
-rw-r--r--src/tools/chdman.cpp150
29 files changed, 2680 insertions, 2962 deletions
diff --git a/src/devices/bus/isa/mcd.cpp b/src/devices/bus/isa/mcd.cpp
index 7929970342e..9bb8b82a5da 100644
--- a/src/devices/bus/isa/mcd.cpp
+++ b/src/devices/bus/isa/mcd.cpp
@@ -78,10 +78,10 @@ void mcd_isa_device::device_reset()
bool mcd_isa_device::read_sector(bool first)
{
- uint32_t lba = msf_to_lba(m_readmsf);
+ uint32_t lba = cdrom_file::msf_to_lba(m_readmsf);
if(m_drvmode == DRV_MODE_CDDA)
{
- if(cdrom_get_track_type(m_cdrom_handle, cdrom_get_track(m_cdrom_handle, lba)) == CD_TRACK_AUDIO)
+ if(m_cdrom_handle->get_track_type(m_cdrom_handle->get_track(lba)) == cdrom_file::CD_TRACK_AUDIO)
{
m_cdda->stop_audio();
m_cdda->set_cdrom(m_cdrom_handle);
@@ -100,14 +100,14 @@ bool mcd_isa_device::read_sector(bool first)
return false;
}
m_cdda->stop_audio();
- cdrom_read_data(m_cdrom_handle, lba - 150, m_buf, m_mode & 0x40 ? CD_TRACK_MODE1_RAW : CD_TRACK_MODE1);
+ m_cdrom_handle->read_data(lba - 150, m_buf, m_mode & 0x40 ? cdrom_file::CD_TRACK_MODE1_RAW : cdrom_file::CD_TRACK_MODE1);
if(m_mode & 0x40)
{
//correct the header
m_buf[12] = dec_2_bcd((m_readmsf >> 16) & 0xff);
m_buf[13] = dec_2_bcd((m_readmsf >> 8) & 0xff);
}
- m_readmsf = lba_to_msf_alt(lba + 1);
+ m_readmsf = cdrom_file::lba_to_msf_alt(lba + 1);
m_buf_count = m_dmalen + 1;
m_buf_idx = 0;
m_data = true;
@@ -272,9 +272,9 @@ void mcd_isa_device::cmd_w(uint8_t data)
case CMD_GET_INFO:
if(m_cdrom_handle)
{
- uint32_t first = lba_to_msf(150), last = lba_to_msf(cdrom_get_track_start(m_cdrom_handle, 0xaa));
+ uint32_t first = cdrom_file::lba_to_msf(150), last = cdrom_file::lba_to_msf(m_cdrom_handle->get_track_start(0xaa));
m_cmdbuf[1] = 1;
- m_cmdbuf[2] = dec_2_bcd(cdrom_get_last_track(m_cdrom_handle));
+ m_cmdbuf[2] = dec_2_bcd(m_cdrom_handle->get_last_track());
m_cmdbuf[3] = (last >> 16) & 0xff;
m_cmdbuf[4] = (last >> 8) & 0xff;
m_cmdbuf[5] = last & 0xff;
@@ -294,11 +294,11 @@ void mcd_isa_device::cmd_w(uint8_t data)
case CMD_GET_Q:
if(m_cdrom_handle)
{
- int tracks = cdrom_get_last_track(m_cdrom_handle);
- uint32_t start = cdrom_get_track_start(m_cdrom_handle, m_curtoctrk);
- uint32_t len = lba_to_msf(cdrom_get_track_start(m_cdrom_handle, m_curtoctrk < (tracks - 1) ? m_curtoctrk + 1 : 0xaa) - start);
- start = lba_to_msf(start);
- m_cmdbuf[1] = (cdrom_get_adr_control(m_cdrom_handle, m_curtoctrk) << 4) & 0xf0;
+ int tracks = m_cdrom_handle->get_last_track();
+ uint32_t start = m_cdrom_handle->get_track_start(m_curtoctrk);
+ uint32_t len = cdrom_file::lba_to_msf(m_cdrom_handle->get_track_start(m_curtoctrk < (tracks - 1) ? m_curtoctrk + 1 : 0xaa) - start);
+ start = cdrom_file::lba_to_msf(start);
+ m_cmdbuf[1] = (m_cdrom_handle->get_adr_control(m_curtoctrk) << 4) & 0xf0;
m_cmdbuf[2] = 0; // track num except when reading toc
m_cmdbuf[3] = dec_2_bcd(m_curtoctrk + 1); // index
m_cmdbuf[4] = (len >> 16) & 0xff;
diff --git a/src/devices/bus/nscsi/cd.cpp b/src/devices/bus/nscsi/cd.cpp
index 49944b7abb8..e45c9feabc6 100644
--- a/src/devices/bus/nscsi/cd.cpp
+++ b/src/devices/bus/nscsi/cd.cpp
@@ -123,7 +123,7 @@ uint8_t nscsi_cdrom_device::scsi_get_data(int id, int pos)
const int extra_pos = (lba * bytes_per_block) % bytes_per_sector;
if(sector != cur_sector) {
cur_sector = sector;
- if(!cdrom_read_data(cdrom, sector, sector_buffer, CD_TRACK_MODE1)) {
+ if(!cdrom->read_data(sector, sector_buffer, cdrom_file::CD_TRACK_MODE1)) {
LOG("CD READ ERROR sector %d!\n", sector);
std::fill_n(sector_buffer, sizeof(sector_buffer), 0);
}
@@ -319,7 +319,7 @@ void nscsi_cdrom_device::scsi_command()
LOG("command READ CAPACITY\n");
// get the last used block on the disc
- const u32 temp = cdrom_get_track_start(cdrom, 0xaa) * (bytes_per_sector / bytes_per_block) - 1;
+ const u32 temp = cdrom->get_track_start(0xaa) * (bytes_per_sector / bytes_per_block) - 1;
scsi_cmdbuf[0] = (temp>>24) & 0xff;
scsi_cmdbuf[1] = (temp>>16) & 0xff;
@@ -365,7 +365,7 @@ void nscsi_cdrom_device::scsi_command()
scsi_cmdbuf[pos++] = 0x80; // WP, cache
// get the last used block on the disc
- const u32 temp = cdrom_get_track_start(cdrom, 0xaa) * (bytes_per_sector / bytes_per_block) - 1;
+ const u32 temp = cdrom->get_track_start(0xaa) * (bytes_per_sector / bytes_per_block) - 1;
scsi_cmdbuf[pos++] = 0x08; // Block descriptor length
scsi_cmdbuf[pos++] = 0x00; // density code
@@ -469,12 +469,12 @@ void nscsi_cdrom_device::scsi_command()
scsi_cmdbuf[3] = 1; // first track
scsi_cmdbuf[4] = 1; // number of sessions (TODO: session support for CHDv6)
scsi_cmdbuf[5] = 1; // first track in last session
- scsi_cmdbuf[6] = cdrom_get_last_track(cdrom); // last track in last session
+ scsi_cmdbuf[6] = cdrom->get_last_track(); // last track in last session
scsi_cmdbuf[8] = 0; // CD-ROM, not XA
// lead in start time in MSF
{
- u32 tstart = cdrom_get_track_start(cdrom, 0);
+ u32 tstart = cdrom->get_track_start(0);
tstart = to_msf(tstart + 150);
scsi_cmdbuf[16] = (tstart >> 24) & 0xff;
@@ -483,7 +483,7 @@ void nscsi_cdrom_device::scsi_command()
scsi_cmdbuf[19] = (tstart & 0xff);
// lead-out start time in MSF
- tstart = cdrom_get_track_start(cdrom, 0xaa);
+ tstart = cdrom->get_track_start(0xaa);
tstart = to_msf(tstart + 150);
scsi_cmdbuf[20] = (tstart >> 24) & 0xff;
@@ -542,7 +542,7 @@ void nscsi_cdrom_device::scsi_command()
switch (format) {
case 0: {
int start_track = scsi_cmdbuf[6];
- int end_track = cdrom_get_last_track(cdrom);
+ int end_track = cdrom->get_last_track();
int tracks;
if(start_track == 0)
@@ -561,7 +561,7 @@ void nscsi_cdrom_device::scsi_command()
scsi_cmdbuf[pos++] = (len>>8) & 0xff;
scsi_cmdbuf[pos++] = (len & 0xff);
scsi_cmdbuf[pos++] = 1;
- scsi_cmdbuf[pos++] = cdrom_get_last_track(cdrom);
+ scsi_cmdbuf[pos++] = cdrom->get_last_track();
if (start_track == 0)
start_track = 1;
@@ -575,11 +575,11 @@ void nscsi_cdrom_device::scsi_command()
}
scsi_cmdbuf[pos++] = 0;
- scsi_cmdbuf[pos++] = cdrom_get_adr_control(cdrom, cdrom_track);
+ scsi_cmdbuf[pos++] = cdrom->get_adr_control(cdrom_track);
scsi_cmdbuf[pos++] = track;
scsi_cmdbuf[pos++] = 0;
- u32 tstart = cdrom_get_track_start(cdrom, cdrom_track);
+ u32 tstart = cdrom->get_track_start(cdrom_track);
if(msf)
tstart = to_msf(tstart+150);
@@ -601,11 +601,11 @@ void nscsi_cdrom_device::scsi_command()
scsi_cmdbuf[pos++] = 1;
scsi_cmdbuf[pos++] = 0;
- scsi_cmdbuf[pos++] = cdrom_get_adr_control(cdrom, 0);
+ scsi_cmdbuf[pos++] = cdrom->get_adr_control(0);
scsi_cmdbuf[pos++] = 1;
scsi_cmdbuf[pos++] = 0;
- u32 tstart = cdrom_get_track_start(cdrom, 0);
+ u32 tstart = cdrom->get_track_start(0);
if (msf)
tstart = to_msf(tstart+150);
diff --git a/src/devices/imagedev/chd_cd.cpp b/src/devices/imagedev/chd_cd.cpp
index 753a7b88212..cf87d17b5ef 100644
--- a/src/devices/imagedev/chd_cd.cpp
+++ b/src/devices/imagedev/chd_cd.cpp
@@ -65,7 +65,7 @@ void cdrom_image_device::device_start()
chd_file *chd = machine().rom_load().get_disk_handle(owner()->tag() );
if( chd != nullptr )
{
- m_cdrom_handle = cdrom_open( chd );
+ m_cdrom_handle = new cdrom_file( chd );
}
else
{
@@ -76,7 +76,7 @@ void cdrom_image_device::device_start()
void cdrom_image_device::device_stop()
{
if (m_cdrom_handle)
- cdrom_close(m_cdrom_handle);
+ delete m_cdrom_handle;
if( m_self_chd.opened() )
m_self_chd.close();
}
@@ -87,7 +87,7 @@ image_init_result cdrom_image_device::call_load()
chd_file *chd = nullptr;
if (m_cdrom_handle)
- cdrom_close(m_cdrom_handle);
+ delete m_cdrom_handle;
if (!loaded_through_softlist()) {
if (is_filetype("chd") && is_loaded()) {
@@ -105,9 +105,9 @@ image_init_result cdrom_image_device::call_load()
/* open the CHD file */
if (chd) {
- m_cdrom_handle = cdrom_open(chd);
+ m_cdrom_handle = new cdrom_file(chd);
} else {
- m_cdrom_handle = cdrom_open(filename());
+ m_cdrom_handle = new cdrom_file(filename());
}
if (!m_cdrom_handle)
goto error;
@@ -125,7 +125,7 @@ error:
void cdrom_image_device::call_unload()
{
assert(m_cdrom_handle);
- cdrom_close(m_cdrom_handle);
+ delete m_cdrom_handle;
m_cdrom_handle = nullptr;
if( m_self_chd.opened() )
m_self_chd.close();
diff --git a/src/devices/machine/akiko.cpp b/src/devices/machine/akiko.cpp
index 1e5aee6db16..98f9f040d20 100644
--- a/src/devices/machine/akiko.cpp
+++ b/src/devices/machine/akiko.cpp
@@ -161,21 +161,21 @@ void akiko_device::device_reset()
else
{
// Arcade case
- m_cdrom = cdrom_open(machine().rom_load().get_disk_handle(":cdrom"));
+ m_cdrom = new cdrom_file(machine().rom_load().get_disk_handle(":cdrom"));
}
/* create the TOC table */
- if ( m_cdrom != nullptr && cdrom_get_last_track(m_cdrom) )
+ if ( m_cdrom != nullptr && m_cdrom->get_last_track() )
{
uint8_t *p;
- int i, addrctrl = cdrom_get_adr_control( m_cdrom, 0 );
+ int i, addrctrl = m_cdrom->get_adr_control( 0 );
uint32_t discend;
- discend = cdrom_get_track_start(m_cdrom,cdrom_get_last_track(m_cdrom)-1);
- discend += cdrom_get_toc(m_cdrom)->tracks[cdrom_get_last_track(m_cdrom)-1].frames;
- discend = lba_to_msf(discend);
+ discend = m_cdrom->get_track_start(m_cdrom->get_last_track()-1);
+ discend += m_cdrom->get_toc().tracks[m_cdrom->get_last_track()-1].frames;
+ discend = cdrom_file::lba_to_msf(discend);
- m_cdrom_numtracks = cdrom_get_last_track(m_cdrom)+3;
+ m_cdrom_numtracks = m_cdrom->get_last_track()+3;
m_cdrom_toc = std::make_unique<uint8_t[]>(13*m_cdrom_numtracks);
memset( m_cdrom_toc.get(), 0, 13*m_cdrom_numtracks);
@@ -187,7 +187,7 @@ void akiko_device::device_reset()
p += 13;
p[1] = 0x01;
p[3] = 0xa1; /* last track */
- p[8] = cdrom_get_last_track(m_cdrom);
+ p[8] = m_cdrom->get_last_track();
p += 13;
p[1] = 0x01;
p[3] = 0xa2; /* disc end */
@@ -196,12 +196,12 @@ void akiko_device::device_reset()
p[10] = discend & 0xff;
p += 13;
- for( i = 0; i < cdrom_get_last_track(m_cdrom); i++ )
+ for( i = 0; i < m_cdrom->get_last_track(); i++ )
{
- uint32_t trackpos = cdrom_get_track_start(m_cdrom,i);
+ uint32_t trackpos = m_cdrom->get_track_start(i);
- trackpos = lba_to_msf(trackpos);
- addrctrl = cdrom_get_adr_control( m_cdrom, i );
+ trackpos = cdrom_file::lba_to_msf(trackpos);
+ addrctrl = m_cdrom->get_adr_control( i );
p[1] = ((addrctrl & 0x0f) << 4) | ((addrctrl & 0xf0) >> 4);
p[3] = dec_2_bcd( i+1 );
@@ -225,8 +225,8 @@ void akiko_device::device_stop()
{
if( m_cdrom )
{
- cdrom_close(m_cdrom);
- m_cdrom = (cdrom_file *)nullptr;
+ delete m_cdrom;
+ m_cdrom = nullptr;
}
}
}
@@ -469,11 +469,11 @@ TIMER_CALLBACK_MEMBER(akiko_device::dma_proc)
if ( m_cdrom_readreqmask & ( 1 << index ) )
{
- uint32_t track = cdrom_get_track( m_cdrom, m_cdrom_lba_cur );
- uint32_t datasize;// = cdrom_get_toc(m_cdrom)->tracks[track].datasize;
- uint32_t subsize = cdrom_get_toc( m_cdrom )->tracks[track].subsize;
+ uint32_t track = m_cdrom->get_track( m_cdrom_lba_cur );
+ uint32_t datasize;// = m_cdrom->get_toc().tracks[track].datasize;
+ uint32_t subsize = m_cdrom->get_toc().tracks[track].subsize;
- uint32_t curmsf = lba_to_msf( m_cdrom_lba_cur );
+ uint32_t curmsf = cdrom_file::lba_to_msf( m_cdrom_lba_cur );
memset( buf, 0, 16 );
buf[3] = m_cdrom_lba_cur - m_cdrom_lba_start;
@@ -485,7 +485,7 @@ TIMER_CALLBACK_MEMBER(akiko_device::dma_proc)
buf[15] = 0x01; /* mode1 */
datasize = 2048;
- if ( !cdrom_read_data( m_cdrom, m_cdrom_lba_cur, &buf[16], CD_TRACK_MODE1 ) )
+ if ( !m_cdrom->read_data( m_cdrom_lba_cur, &buf[16], cdrom_file::CD_TRACK_MODE1 ) )
{
LOGWARN( "AKIKO: Read error trying to read sector %08x!\n", m_cdrom_lba_cur );
return;
@@ -493,7 +493,7 @@ TIMER_CALLBACK_MEMBER(akiko_device::dma_proc)
if ( subsize )
{
- if ( !cdrom_read_subcode( m_cdrom, m_cdrom_lba_cur, &buf[16+datasize] ) )
+ if ( !m_cdrom->read_subcode( m_cdrom_lba_cur, &buf[16+datasize] ) )
{
LOGWARN( "AKIKO: Read error trying to read subcode for sector %08x!\n", m_cdrom_lba_cur );
return;
@@ -695,9 +695,9 @@ void akiko_device::update_cdrom()
LOGCD("AKIKO CD: Seek - start lba: %08x - end lba: %08x\n", startpos, endpos );
m_cdrom_track_index = 0;
- for( i = 0; i < cdrom_get_last_track(m_cdrom); i++ )
+ for( i = 0; i < m_cdrom->get_last_track(); i++ )
{
- if ( startpos <= cdrom_get_track_start( m_cdrom, i ) )
+ if ( startpos <= m_cdrom->get_track_start( i ) )
{
/* reset to 0 */
m_cdrom_track_index = i + 2;
@@ -733,16 +733,16 @@ void akiko_device::update_cdrom()
uint32_t track;
int addrctrl;
- track = cdrom_get_track(m_cdrom, lba);
- addrctrl = cdrom_get_adr_control(m_cdrom, track);
+ track = m_cdrom->get_track(lba);
+ addrctrl = m_cdrom->get_adr_control(track);
resp[2] = 0x00;
resp[3] = ((addrctrl & 0x0f) << 4) | ((addrctrl & 0xf0) >> 4);
resp[4] = dec_2_bcd(track+1);
resp[5] = 0; /* index */
- disk_pos = lba_to_msf(lba);
- track_pos = lba_to_msf(lba - cdrom_get_track_start(m_cdrom, track));
+ disk_pos = cdrom_file::lba_to_msf(lba);
+ track_pos = cdrom_file::lba_to_msf(lba - m_cdrom->get_track_start(track));
/* track position */
resp[6] = (track_pos >> 16) & 0xff;
diff --git a/src/devices/machine/spg290_cdservo.cpp b/src/devices/machine/spg290_cdservo.cpp
index aa0ed1856d4..3370724ece2 100644
--- a/src/devices/machine/spg290_cdservo.cpp
+++ b/src/devices/machine/spg290_cdservo.cpp
@@ -109,7 +109,7 @@ void spg290_cdservo_device::device_timer(emu_timer &timer, device_timer_id id, i
if (BIT(m_control0, 15)) // CDDA
{
- cdrom_read_data(m_cdrom->get_cdrom_file(), m_cur_sector - 150 - SPG290_LEADIN_LEN, cdbuf, CD_TRACK_AUDIO);
+ m_cdrom->get_cdrom_file()->read_data(m_cur_sector - 150 - SPG290_LEADIN_LEN, cdbuf, cdrom_file::CD_TRACK_AUDIO);
for (int i=0; i<2352; i++)
{
@@ -120,13 +120,13 @@ void spg290_cdservo_device::device_timer(emu_timer &timer, device_timer_id id, i
}
else
{
- cdrom_read_data(m_cdrom->get_cdrom_file(), m_cur_sector - 150 - SPG290_LEADIN_LEN, cdbuf, CD_TRACK_MODE1_RAW);
+ m_cdrom->get_cdrom_file()->read_data(m_cur_sector - 150 - SPG290_LEADIN_LEN, cdbuf, cdrom_file::CD_TRACK_MODE1_RAW);
// FIXME: this is required for load iso images
- if (cdrom_get_track_type(m_cdrom->get_cdrom_file(), m_qsub[m_cur_sector * 12 + 1] - 1) == CD_TRACK_MODE1)
+ if (m_cdrom->get_cdrom_file()->get_track_type(m_qsub[m_cur_sector * 12 + 1] - 1) == cdrom_file::CD_TRACK_MODE1)
{
int lba = (bcd_2_dec(cdbuf[12]) * 60 + bcd_2_dec(cdbuf[13])) * 75 + bcd_2_dec(cdbuf[14]);
- uint32_t msf = lba_to_msf(lba + 150);
+ uint32_t msf = cdrom_file::lba_to_msf(lba + 150);
cdbuf[12] = (msf >> 16) & 0xff;
cdbuf[13] = (msf >> 8) & 0xff;
cdbuf[14] = (msf >> 0) & 0xff;
@@ -357,9 +357,9 @@ void spg290_cdservo_device::add_qsub(int sector, uint8_t addrctrl, uint8_t track
void spg290_cdservo_device::generate_qsub(cdrom_file *cdrom)
{
- const cdrom_toc *toc = cdrom_get_toc(cdrom);
- int numtracks = cdrom_get_last_track(cdrom);
- uint32_t total_sectors = cdrom_get_track_start(cdrom, numtracks - 1) + toc->tracks[numtracks - 1].frames + 150;
+ const cdrom_file::toc &toc = cdrom->get_toc();
+ int numtracks = cdrom->get_last_track();
+ uint32_t total_sectors = cdrom->get_track_start(numtracks - 1) + toc.tracks[numtracks - 1].frames + 150;
m_tot_sectors = SPG290_LEADIN_LEN + total_sectors + SPG290_LEADOUT_LEN;
m_qsub = std::make_unique<uint8_t[]>(m_tot_sectors * 12);
@@ -369,54 +369,54 @@ void spg290_cdservo_device::generate_qsub(cdrom_file *cdrom)
// 7500 sectors lead-in
for (int s=0; s < SPG290_LEADIN_LEN; s += numtracks + 3)
{
- if (lba < SPG290_LEADIN_LEN) add_qsub(lba++, 0x14, 0, 0xa0, lba_to_msf(s + 0), 1 << 16); // first track number
- if (lba < SPG290_LEADIN_LEN) add_qsub(lba++, 0x14, 0, 0xa1, lba_to_msf(s + 1), numtracks << 16); // last track number
- if (lba < SPG290_LEADIN_LEN) add_qsub(lba++, 0x14, 0, 0xa2, lba_to_msf(s + 2), lba_to_msf(total_sectors)); // start time of lead-out
+ if (lba < SPG290_LEADIN_LEN) add_qsub(lba++, 0x14, 0, 0xa0, cdrom_file::lba_to_msf(s + 0), 1 << 16); // first track number
+ if (lba < SPG290_LEADIN_LEN) add_qsub(lba++, 0x14, 0, 0xa1, cdrom_file::lba_to_msf(s + 1), numtracks << 16); // last track number
+ if (lba < SPG290_LEADIN_LEN) add_qsub(lba++, 0x14, 0, 0xa2, cdrom_file::lba_to_msf(s + 2), cdrom_file::lba_to_msf(total_sectors)); // start time of lead-out
for(int track = 0; track < numtracks; track++)
{
- uint32_t track_start = cdrom_get_track_start(cdrom, track) + 150;
+ uint32_t track_start = cdrom->get_track_start(track) + 150;
if (lba < SPG290_LEADIN_LEN)
- add_qsub(lba++, cdrom_get_adr_control(cdrom, track), 0, dec_2_bcd(track + 1), lba_to_msf(s + 3 + track), lba_to_msf(track_start));
+ add_qsub(lba++, cdrom->get_adr_control(track), 0, dec_2_bcd(track + 1), cdrom_file::lba_to_msf(s + 3 + track), cdrom_file::lba_to_msf(track_start));
}
}
// data tracks
for(int track = 0; track < numtracks; track++)
{
- uint32_t control = cdrom_get_adr_control(cdrom, track);
- uint32_t track_start = cdrom_get_track_start(cdrom, track);
+ uint32_t control = cdrom->get_adr_control(track);
+ uint32_t track_start = cdrom->get_track_start(track);
// pregap
- uint32_t pregap = toc->tracks[track].pregap;
+ uint32_t pregap = toc.tracks[track].pregap;
// first track should have a 150 frames pregap
- if (track == 0 && toc->tracks[0].pregap == 0)
+ if (track == 0 && toc.tracks[0].pregap == 0)
pregap = 150;
- else if (track != 0 && toc->tracks[0].pregap == 0)
+ else if (track != 0 && toc.tracks[0].pregap == 0)
track_start += 150;
for(int s = 0; s < pregap; s++)
- add_qsub(lba++, control, dec_2_bcd(track + 1), 0, lba_to_msf(s), lba_to_msf(track_start + s));
+ add_qsub(lba++, control, dec_2_bcd(track + 1), 0, cdrom_file::lba_to_msf(s), cdrom_file::lba_to_msf(track_start + s));
track_start += pregap;
- for(int s = 0; s < toc->tracks[track].frames; s++)
+ for(int s = 0; s < toc.tracks[track].frames; s++)
{
// TODO: if present use subcode from CHD
- add_qsub(lba++, control, dec_2_bcd(track + 1), 1, lba_to_msf(s), lba_to_msf(track_start + s));
+ add_qsub(lba++, control, dec_2_bcd(track + 1), 1, cdrom_file::lba_to_msf(s), cdrom_file::lba_to_msf(track_start + s));
}
- track_start += toc->tracks[track].frames;
+ track_start += toc.tracks[track].frames;
// postgap
- for(int s = 0; s < toc->tracks[track].postgap; s++)
- add_qsub(lba++, control, dec_2_bcd(track + 1), 2, lba_to_msf(s), lba_to_msf(track_start + s));
+ for(int s = 0; s < toc.tracks[track].postgap; s++)
+ add_qsub(lba++, control, dec_2_bcd(track + 1), 2, cdrom_file::lba_to_msf(s), cdrom_file::lba_to_msf(track_start + s));
- track_start += toc->tracks[track].postgap;
+ track_start += toc.tracks[track].postgap;
}
// 6750 sectors lead-out
for(int s = 0; s < SPG290_LEADOUT_LEN; s++)
- add_qsub(lba++, 0x14, 0xaa, 1, lba_to_msf(s), lba_to_msf(total_sectors + s));
+ add_qsub(lba++, 0x14, 0xaa, 1, cdrom_file::lba_to_msf(s), cdrom_file::lba_to_msf(total_sectors + s));
}
diff --git a/src/devices/machine/stvcd.cpp b/src/devices/machine/stvcd.cpp
index 9e62335f448..2c8c42f3a0b 100644
--- a/src/devices/machine/stvcd.cpp
+++ b/src/devices/machine/stvcd.cpp
@@ -478,12 +478,12 @@ int stvcd_device::get_track_index(uint32_t fad)
uint32_t rel_fad;
uint8_t track;
- if(cdrom_get_track_type(cdrom, cdrom_get_track(cdrom, fad)) != CD_TRACK_AUDIO)
+ if(cdrom->get_track_type(cdrom->get_track(fad)) != cdrom_file::CD_TRACK_AUDIO)
return 1;
- track = cdrom_get_track( cdrom, fad );
+ track = cdrom->get_track( fad );
- rel_fad = fad - cdrom_get_track_start( cdrom, track );
+ rel_fad = fad - cdrom->get_track_start( track );
if(rel_fad < 150)
return 0;
@@ -493,7 +493,7 @@ int stvcd_device::get_track_index(uint32_t fad)
int stvcd_device::sega_cdrom_get_adr_control(cdrom_file *file, int track)
{
- return bitswap<8>(cdrom_get_adr_control(file, cur_track),3,2,1,0,7,6,5,4);
+ return bitswap<8>(file->get_adr_control(cur_track),3,2,1,0,7,6,5,4);
}
void stvcd_device::cr_standard_return(uint16_t cur_status)
@@ -501,7 +501,7 @@ void stvcd_device::cr_standard_return(uint16_t cur_status)
if ((cd_stat & 0x0f00) == CD_STAT_SEEK)
{
/* During seek state, values returned are from the target position */
- uint8_t seek_track = cdrom_get_track(cdrom, cd_fad_seek-150);
+ uint8_t seek_track = cdrom->get_track(cd_fad_seek-150);
cr1 = cur_status | (playtype << 7) | 0x00 | (cdda_repeat_count & 0xf);
cr2 = (seek_track == 0xff) ? 0xffff : ((sega_cdrom_get_adr_control(cdrom, seek_track)<<8) | seek_track);
@@ -511,7 +511,7 @@ void stvcd_device::cr_standard_return(uint16_t cur_status)
else
{
cr1 = cur_status | (playtype << 7) | 0x00 | (cdda_repeat_count & 0xf); //options << 4 | repeat & 0xf
- cr2 = (cur_track == 0xff) ? 0xffff : ((sega_cdrom_get_adr_control(cdrom, cur_track)<<8) | (cdrom_get_track(cdrom, cd_curfad-150)+1));
+ cr2 = (cur_track == 0xff) ? 0xffff : ((sega_cdrom_get_adr_control(cdrom, cur_track)<<8) | (cdrom->get_track(cd_curfad-150)+1));
cr3 = (get_track_index(cd_curfad)<<8) | (cd_curfad>>16); //index & 0xff00
cr4 = cd_curfad;
}
@@ -761,7 +761,7 @@ void stvcd_device::cmd_play_disc()
cd_curfad = start_pos & 0xfffff;
logerror("fad mode\n");
- cur_track = cdrom_get_track(cdrom, cd_curfad-150);
+ cur_track = cdrom->get_track(cd_curfad-150);
}
else
{
@@ -769,7 +769,7 @@ void stvcd_device::cmd_play_disc()
if(((start_pos)>>8) != 0)
{
cur_track = (start_pos)>>8;
- cd_fad_seek = cdrom_get_track_start(cdrom, cur_track-1);
+ cd_fad_seek = cdrom->get_track_start(cur_track-1);
cd_stat = CD_STAT_SEEK;
m_cdda->pause_audio(0);
}
@@ -795,7 +795,7 @@ void stvcd_device::cmd_play_disc()
uint8_t end_track;
end_track = (end_pos)>>8;
- fadstoplay = cdrom_get_track_start(cdrom, end_track) - cd_fad_seek;
+ fadstoplay = cdrom->get_track_start(end_track) - cd_fad_seek;
}
}
else // play until the end of the disc
@@ -811,9 +811,9 @@ void stvcd_device::cmd_play_disc()
else
{
if(end_pos == 0)
- fadstoplay = (cdrom_get_track_start(cdrom, 0xaa)) - cd_curfad;
+ fadstoplay = (cdrom->get_track_start(0xaa)) - cd_curfad;
else
- fadstoplay = (cdrom_get_track_start(cdrom, (end_pos & 0xff00) >> 8)) - cd_curfad;
+ fadstoplay = (cdrom->get_track_start((end_pos & 0xff00) >> 8)) - cd_curfad;
}
logerror("track mode %08x %08x\n",cd_curfad,fadstoplay);
}
@@ -828,8 +828,8 @@ void stvcd_device::cmd_play_disc()
// be countless possible combinations ...
if(fadstoplay == 0)
{
- cd_curfad = cdrom_get_track_start(cdrom, cur_track-1);
- fadstoplay = cdrom_get_track_start(cdrom, cur_track) - cd_curfad;
+ cd_curfad = cdrom->get_track_start(cur_track-1);
+ fadstoplay = cdrom->get_track_start(cur_track) - cd_curfad;
}
logerror("track resume %08x %08x\n",cd_curfad,fadstoplay);
}
@@ -845,7 +845,7 @@ void stvcd_device::cmd_play_disc()
playtype = 0;
// cdda
- if(cdrom_get_track_type(cdrom, cdrom_get_track(cdrom, cd_curfad)) == CD_TRACK_AUDIO)
+ if(cdrom->get_track_type(cdrom->get_track(cd_curfad)) == cdrom_file::CD_TRACK_AUDIO)
{
m_cdda->pause_audio(0);
//m_cdda->start_audio(cd_curfad, fadstoplay);
@@ -892,7 +892,7 @@ void stvcd_device::cmd_seek_disc()
{
cd_stat = CD_STAT_PAUSE;
cur_track = cr2>>8;
- cd_curfad = cdrom_get_track_start(cdrom, cur_track-1);
+ cd_curfad = cdrom->get_track_start(cur_track-1);
m_cdda->pause_audio(1);
// (index is cr2 low byte)
}
@@ -952,13 +952,13 @@ void stvcd_device::cmd_get_subcode_q_rw_channel()
xxxx xxxx [11] CRCC
*/
- msf_abs = lba_to_msf_alt( cd_curfad - 150 );
- track = cdrom_get_track( cdrom, cd_curfad );
- msf_rel = lba_to_msf_alt( cd_curfad - 150 - cdrom_get_track_start( cdrom, track ) );
+ msf_abs = cdrom_file::lba_to_msf_alt( cd_curfad - 150 );
+ track = cdrom->get_track( cd_curfad );
+ msf_rel = cdrom_file::lba_to_msf_alt( cd_curfad - 150 - cdrom->get_track_start( track ) );
xfertype = XFERTYPE_SUBQ;
xfercount = 0;
- subqbuf[0] = 0x01 | ((cdrom_get_track_type(cdrom, cdrom_get_track(cdrom, track+1)) == CD_TRACK_AUDIO) ? 0x00 : 0x40);
+ subqbuf[0] = 0x01 | ((cdrom->get_track_type(cdrom->get_track(track+1)) == cdrom_file::CD_TRACK_AUDIO) ? 0x00 : 0x40);
subqbuf[1] = dec_2_bcd(track+1);
subqbuf[2] = dec_2_bcd(get_track_index(cd_curfad));
subqbuf[3] = dec_2_bcd((msf_rel >> 16) & 0xff);
@@ -2006,7 +2006,7 @@ TIMER_DEVICE_CALLBACK_MEMBER( stvcd_device::stv_sector_cb )
cd_playdata();
- if(cdrom_get_track_type(cdrom, cdrom_get_track(cdrom, cd_curfad)) == CD_TRACK_AUDIO)
+ if(cdrom->get_track_type(cdrom->get_track(cd_curfad)) == cdrom_file::CD_TRACK_AUDIO)
m_sector_timer->adjust(attotime::from_hz(75)); // 75 sectors / second = 150kBytes/second (cdda track ignores cd_speed setting)
else
m_sector_timer->adjust(attotime::from_hz(75*cd_speed)); // 75 / 150 sectors / second = 150 / 300kBytes/second
@@ -2069,7 +2069,7 @@ void stvcd_device::device_reset()
for (i = 0; i < MAX_BLOCKS; i++)
{
blocks[i].size = -1;
- memset(&blocks[i].data, 0, CD_MAX_SECTOR_DATA);
+ memset(&blocks[i].data, 0, cdrom_file::MAX_SECTOR_DATA);
}
// open device
@@ -2384,7 +2384,7 @@ void stvcd_device::cd_readTOC(void)
if (cdrom)
{
- ntrks = cdrom_get_last_track(cdrom);
+ ntrks = cdrom->get_last_track();
}
else
{
@@ -2409,7 +2409,7 @@ void stvcd_device::cd_readTOC(void)
{
//tocbuf[tocptr] = sega_cdrom_get_adr_control(cdrom, i);
//HACK: ddsom does not enter ingame with the line above!
- tocbuf[tocptr] = cdrom_get_adr_control(cdrom, i)<<4 | 0x01;
+ tocbuf[tocptr] = cdrom->get_adr_control(i)<<4 | 0x01;
}
else
{
@@ -2418,7 +2418,7 @@ void stvcd_device::cd_readTOC(void)
if (cdrom)
{
- fad = cdrom_get_track_start(cdrom, i) + 150;
+ fad = cdrom->get_track_start(i) + 150;
tocbuf[tocptr+1] = (fad>>16)&0xff;
tocbuf[tocptr+2] = (fad>>8)&0xff;
@@ -2459,7 +2459,7 @@ void stvcd_device::cd_readTOC(void)
tocbuf[tocptr+7] = 0;
// get total disc length (start of lead-out)
- fad = cdrom_get_track_start(cdrom, 0xaa) + 150;
+ fad = cdrom->get_track_start(0xaa) + 150;
tocbuf[tocptr+8] = tocbuf[0];
tocbuf[tocptr+9] = (fad>>16)&0xff;
@@ -2493,7 +2493,7 @@ stvcd_device::partitionT *stvcd_device::cd_filterdata(filterT *flt, int trktype,
}
}
- if ((trktype != CD_TRACK_AUDIO) && (curblock.data[15] == 2))
+ if ((trktype != cdrom_file::CD_TRACK_AUDIO) && (curblock.data[15] == 2))
{
if (flt->mode & 1) // file number
{
@@ -2630,27 +2630,27 @@ stvcd_device::partitionT *stvcd_device::cd_read_filtered_sector(int32_t fad, uin
if ((cddevice != nullptr) && (!buffull))
{
// find out the track's type
- trktype = cdrom_get_track_type(cdrom, cdrom_get_track(cdrom, fad-150));
+ trktype = cdrom->get_track_type(cdrom->get_track(fad-150));
// now get a raw 2352 byte sector - if it's mode 1, get mode1_raw
- if ((trktype == CD_TRACK_MODE1) || (trktype == CD_TRACK_MODE1_RAW))
+ if ((trktype == cdrom_file::CD_TRACK_MODE1) || (trktype == cdrom_file::CD_TRACK_MODE1_RAW))
{
- cdrom_read_data(cdrom, fad-150, curblock.data, CD_TRACK_MODE1_RAW);
+ cdrom->read_data(fad-150, curblock.data, cdrom_file::CD_TRACK_MODE1_RAW);
}
- else if (trktype != CD_TRACK_AUDIO) // if not audio it must be mode 2 so get mode2_raw
+ else if (trktype != cdrom_file::CD_TRACK_AUDIO) // if not audio it must be mode 2 so get mode2_raw
{
- cdrom_read_data(cdrom, fad-150, curblock.data, CD_TRACK_MODE2_RAW);
+ cdrom->read_data(fad-150, curblock.data, cdrom_file::CD_TRACK_MODE2_RAW);
}
else
{
- cdrom_read_data(cdrom, fad-150, curblock.data, CD_TRACK_AUDIO);
+ cdrom->read_data(fad-150, curblock.data, cdrom_file::CD_TRACK_AUDIO);
}
curblock.size = sectlenin;
curblock.FAD = fad;
// if track is Mode 2, get the subheader values
- if ((trktype != CD_TRACK_AUDIO) && (curblock.data[15] == 2))
+ if ((trktype != cdrom_file::CD_TRACK_AUDIO) && (curblock.data[15] == 2))
{
curblock.chan = curblock.data[17];
curblock.fnum = curblock.data[16];
@@ -2714,7 +2714,7 @@ void stvcd_device::cd_playdata()
{
uint8_t p_ok;
- if(cdrom_get_track_type(cdrom, cdrom_get_track(cdrom, cd_curfad)) != CD_TRACK_AUDIO)
+ if(cdrom->get_track_type(cdrom->get_track(cd_curfad)) != cdrom_file::CD_TRACK_AUDIO)
{
cd_read_filtered_sector(cd_curfad,&p_ok);
m_cdda->stop_audio(); //stop any pending CD-DA
@@ -2752,8 +2752,8 @@ void stvcd_device::cd_playdata()
if(cdda_repeat_count < 0xe)
cdda_repeat_count++;
- cd_curfad = cdrom_get_track_start(cdrom, cur_track-1) + 150;
- fadstoplay = cdrom_get_track_start(cdrom, cur_track) - cd_curfad;
+ cd_curfad = cdrom->get_track_start(cur_track-1) + 150;
+ fadstoplay = cdrom->get_track_start(cur_track) - cd_curfad;
}
}
}
@@ -2767,7 +2767,7 @@ void stvcd_device::cd_readblock(uint32_t fad, uint8_t *dat)
{
if (cdrom)
{
- cdrom_read_data(cdrom, fad-150, dat, CD_TRACK_MODE1);
+ cdrom->read_data(fad-150, dat, cdrom_file::CD_TRACK_MODE1);
}
}
diff --git a/src/devices/machine/stvcd.h b/src/devices/machine/stvcd.h
index 2cef9608be8..78ad1392c24 100644
--- a/src/devices/machine/stvcd.h
+++ b/src/devices/machine/stvcd.h
@@ -82,7 +82,7 @@ private:
{
int32_t size; // size of block
int32_t FAD; // FAD on disc
- uint8_t data[CD_MAX_SECTOR_DATA];
+ uint8_t data[cdrom_file::MAX_SECTOR_DATA];
uint8_t chan; // channel
uint8_t fnum; // file number
uint8_t subm; // subchannel mode
diff --git a/src/devices/machine/t10mmc.cpp b/src/devices/machine/t10mmc.cpp
index 3d22129e3f4..2fbab77d8b6 100644
--- a/src/devices/machine/t10mmc.cpp
+++ b/src/devices/machine/t10mmc.cpp
@@ -72,7 +72,7 @@ t10mmc::toc_format_t t10mmc::toc_format()
int t10mmc::toc_tracks()
{
int start_track = command[6];
- int end_track = cdrom_get_last_track(m_cdrom);
+ int end_track = m_cdrom->get_last_track();
if (start_track == 0)
{
@@ -229,8 +229,8 @@ void t10mmc::ExecCommand()
// A request for LBA 0 will return something different depending on the type of media being played.
// For data and mixed media, LBA 0 is assigned to MSF 00:02:00 (= LBA 150).
// For audio media, LBA 0 is assigned to the actual starting address of track 1.
- if (cdrom_get_track_type(m_cdrom, 0) == CD_TRACK_AUDIO)
- m_lba = cdrom_get_track_start(m_cdrom, 0);
+ if (m_cdrom->get_track_type(0) == cdrom_file::CD_TRACK_AUDIO)
+ m_lba = m_cdrom->get_track_start(0);
else
m_lba = 150;
}
@@ -241,9 +241,9 @@ void t10mmc::ExecCommand()
//m_device->logerror("T10MMC: PLAY AUDIO(10) at LBA %x for %x blocks\n", m_lba, m_blocks);
- trk = cdrom_get_track(m_cdrom, m_lba);
+ trk = m_cdrom->get_track(m_lba);
- if (cdrom_get_track_type(m_cdrom, trk) == CD_TRACK_AUDIO)
+ if (m_cdrom->get_track_type(trk) == cdrom_file::CD_TRACK_AUDIO)
{
m_cdda->start_audio(m_lba, m_blocks);
m_audio_sense = SCSI_SENSE_ASC_ASCQ_AUDIO_PLAY_OPERATION_IN_PROGRESS;
@@ -265,8 +265,8 @@ void t10mmc::ExecCommand()
if (m_lba == 0)
{
- if (cdrom_get_track_type(m_cdrom, 0) == CD_TRACK_AUDIO)
- m_lba = cdrom_get_track_start(m_cdrom, 0);
+ if (m_cdrom->get_track_type(0) == cdrom_file::CD_TRACK_AUDIO)
+ m_lba = m_cdrom->get_track_start(0);
else
m_lba = 150;
}
@@ -278,9 +278,9 @@ void t10mmc::ExecCommand()
//m_device->logerror("T10MMC: PLAY AUDIO MSF at LBA %x for %x blocks (MSF %i:%i:%i - %i:%i:%i)\n",
//m_lba, m_blocks, command[3], command[4], command[5], command[6], command[7], command[8]);
- trk = cdrom_get_track(m_cdrom, m_lba);
+ trk = m_cdrom->get_track(m_lba);
- if (cdrom_get_track_type(m_cdrom, trk) == CD_TRACK_AUDIO)
+ if (m_cdrom->get_track_type(trk) == cdrom_file::CD_TRACK_AUDIO)
{
m_cdda->start_audio(m_lba, m_blocks);
m_audio_sense = SCSI_SENSE_ASC_ASCQ_AUDIO_PLAY_OPERATION_IN_PROGRESS;
@@ -308,7 +308,7 @@ void t10mmc::ExecCommand()
// be careful: tracks here are zero-based, but the SCSI command
// uses the real CD track number which is 1-based!
//m_device->logerror("T10MMC: PLAY AUDIO T/I: strk %d idx %d etrk %d idx %d frames %d\n", command[4], command[5], command[7], command[8], m_blocks);
- int end_track = cdrom_get_last_track(m_cdrom);
+ int end_track = m_cdrom->get_last_track();
if (end_track > command[7])
end_track = command[7];
@@ -319,11 +319,11 @@ void t10mmc::ExecCommand()
if (m_sotc)
end_track = command[4];
- m_lba = cdrom_get_track_start(m_cdrom, command[4] - 1);
- m_blocks = cdrom_get_track_start(m_cdrom, end_track) - m_lba;
- trk = cdrom_get_track(m_cdrom, m_lba);
+ m_lba = m_cdrom->get_track_start(command[4] - 1);
+ m_blocks = m_cdrom->get_track_start(end_track) - m_lba;
+ trk = m_cdrom->get_track(m_lba);
- if (cdrom_get_track_type(m_cdrom, trk) == CD_TRACK_AUDIO)
+ if (m_cdrom->get_track_type(trk) == cdrom_file::CD_TRACK_AUDIO)
{
m_cdda->start_audio(m_lba, m_blocks);
m_audio_sense = SCSI_SENSE_ASC_ASCQ_AUDIO_PLAY_OPERATION_IN_PROGRESS;
@@ -382,8 +382,8 @@ void t10mmc::ExecCommand()
if (m_lba == 0)
{
- if (cdrom_get_track_type(m_cdrom, 0) == CD_TRACK_AUDIO)
- m_lba = cdrom_get_track_start(m_cdrom, 0);
+ if (m_cdrom->get_track_type(0) == cdrom_file::CD_TRACK_AUDIO)
+ m_lba = m_cdrom->get_track_start(0);
else
m_lba = 150;
}
@@ -394,9 +394,9 @@ void t10mmc::ExecCommand()
//m_device->logerror("T10MMC: PLAY AUDIO(12) at LBA %x for %x blocks\n", m_lba, m_blocks);
- trk = cdrom_get_track(m_cdrom, m_lba);
+ trk = m_cdrom->get_track(m_lba);
- if (cdrom_get_track_type(m_cdrom, trk) == CD_TRACK_AUDIO)
+ if (m_cdrom->get_track_type(trk) == cdrom_file::CD_TRACK_AUDIO)
{
m_cdda->start_audio(m_lba, m_blocks);
m_audio_sense = SCSI_SENSE_ASC_ASCQ_AUDIO_PLAY_OPERATION_IN_PROGRESS;
@@ -476,7 +476,7 @@ void t10mmc::ReadData( uint8_t *data, int dataLength )
case T10SBC_CMD_READ_CAPACITY:
m_device->logerror("T10MMC: READ CAPACITY\n");
- temp = cdrom_get_track_start(m_cdrom, 0xaa);
+ temp = m_cdrom->get_track_start(0xaa);
temp--; // return the last used block on the disc
data[0] = (temp>>24) & 0xff;
@@ -496,7 +496,7 @@ void t10mmc::ReadData( uint8_t *data, int dataLength )
{
while (dataLength > 0)
{
- if (!cdrom_read_data(m_cdrom, m_lba, tmp_buffer, CD_TRACK_MODE1))
+ if (!m_cdrom->read_data(m_lba, tmp_buffer, cdrom_file::CD_TRACK_MODE1))
{
m_device->logerror("T10MMC: CD read error!\n");
}
@@ -571,7 +571,7 @@ void t10mmc::ReadData( uint8_t *data, int dataLength )
data[3] = 12; // data length
data[4] = 0x01; // sub-channel format code
data[5] = 0x10 | (audio_active ? 0 : 4);
- data[6] = cdrom_get_track(m_cdrom, m_last_lba) + 1; // track
+ data[6] = m_cdrom->get_track(m_last_lba) + 1; // track
data[7] = 0; // index
uint32_t frame = m_last_lba;
@@ -586,7 +586,7 @@ void t10mmc::ReadData( uint8_t *data, int dataLength )
data[10] = (frame>>8)&0xff;
data[11] = frame&0xff;
- frame = m_last_lba - cdrom_get_track_start(m_cdrom, data[6] - 1);
+ frame = m_last_lba - m_cdrom->get_track_start(data[6] - 1);
if (msf)
{
@@ -634,7 +634,7 @@ void t10mmc::ReadData( uint8_t *data, int dataLength )
data[dptr++] = (len>>8) & 0xff;
data[dptr++] = (len & 0xff);
data[dptr++] = 1;
- data[dptr++] = cdrom_get_last_track(m_cdrom);
+ data[dptr++] = m_cdrom->get_last_track();
int first_track = command[6];
if (first_track == 0)
@@ -658,11 +658,11 @@ void t10mmc::ReadData( uint8_t *data, int dataLength )
}
data[dptr++] = 0;
- data[dptr++] = cdrom_get_adr_control(m_cdrom, cdrom_track);
+ data[dptr++] = m_cdrom->get_adr_control(cdrom_track);
data[dptr++] = track;
data[dptr++] = 0;
- uint32_t tstart = cdrom_get_track_start(m_cdrom, cdrom_track);
+ uint32_t tstart = m_cdrom->get_track_start(cdrom_track);
if (msf)
{
@@ -688,11 +688,11 @@ void t10mmc::ReadData( uint8_t *data, int dataLength )
data[dptr++] = 1;
data[dptr++] = 0;
- data[dptr++] = cdrom_get_adr_control(m_cdrom, 0);
+ data[dptr++] = m_cdrom->get_adr_control(0);
data[dptr++] = 1;
data[dptr++] = 0;
- uint32_t tstart = cdrom_get_track_start(m_cdrom, 0);
+ uint32_t tstart = m_cdrom->get_track_start(0);
if (msf)
{
diff --git a/src/devices/sound/cdda.cpp b/src/devices/sound/cdda.cpp
index 7cb2afbd28a..38a4c4736cc 100644
--- a/src/devices/sound/cdda.cpp
+++ b/src/devices/sound/cdda.cpp
@@ -29,7 +29,7 @@ void cdda_device::sound_stream_update(sound_stream &stream, std::vector<read_str
void cdda_device::device_start()
{
/* allocate an audio cache */
- m_audio_cache = std::make_unique<uint8_t[]>(CD_MAX_SECTOR_DATA * MAX_SECTORS );
+ m_audio_cache = std::make_unique<uint8_t[]>(cdrom_file::MAX_SECTOR_DATA * MAX_SECTORS );
m_stream = stream_alloc(0, 2, clock());
@@ -47,7 +47,7 @@ void cdda_device::device_start()
save_item( NAME(m_audio_ended_normally) );
save_item( NAME(m_audio_lba) );
save_item( NAME(m_audio_length) );
- save_pointer( NAME(m_audio_cache), CD_MAX_SECTOR_DATA * MAX_SECTORS );
+ save_pointer( NAME(m_audio_cache), cdrom_file::MAX_SECTOR_DATA * MAX_SECTORS );
save_item( NAME(m_audio_samples) );
save_item( NAME(m_audio_bptr) );
}
@@ -114,7 +114,7 @@ void cdda_device::pause_audio(int pause)
uint32_t cdda_device::get_audio_lba()
{
m_stream->update();
- return m_audio_lba - ((m_audio_samples + (CD_MAX_SECTOR_DATA / 4) - 1) / (CD_MAX_SECTOR_DATA / 4));
+ return m_audio_lba - ((m_audio_samples + (cdrom_file::MAX_SECTOR_DATA / 4) - 1) / (cdrom_file::MAX_SECTOR_DATA / 4));
}
@@ -207,12 +207,12 @@ void cdda_device::get_audio_data(write_stream_view &bufL, write_stream_view &buf
for (i = 0; i < sectors; i++)
{
- cdrom_read_data(m_disc, m_audio_lba, &m_audio_cache[CD_MAX_SECTOR_DATA*i], CD_TRACK_AUDIO);
+ m_disc->read_data(m_audio_lba, &m_audio_cache[cdrom_file::MAX_SECTOR_DATA*i], cdrom_file::CD_TRACK_AUDIO);
m_audio_lba++;
}
- m_audio_samples = (CD_MAX_SECTOR_DATA*sectors)/4;
+ m_audio_samples = (cdrom_file::MAX_SECTOR_DATA*sectors)/4;
m_audio_length -= sectors;
/* reset feedout ptr */
diff --git a/src/lib/util/cdrom.cpp b/src/lib/util/cdrom.cpp
index a935cd50612..4cbd621115c 100644
--- a/src/lib/util/cdrom.cpp
+++ b/src/lib/util/cdrom.cpp
@@ -1,5 +1,5 @@
// license:BSD-3-Clause
-// copyright-holders:Aaron Giles
+// copyright-holders:Aaron Giles,R. Belmont
/***************************************************************************
cdrom.c
@@ -18,8 +18,7 @@
#include "cdrom.h"
-#include "chdcd.h"
-#include "corefile.h"
+#include "corestr.h"
#include <cassert>
#include <cstdlib>
@@ -70,58 +69,6 @@ void CLIB_DECL logerror(const char *text, ...) ATTR_PRINTF(1,2);
/***************************************************************************
- CONSTANTS
-***************************************************************************/
-
-/** @brief offset within sector. */
-const int SYNC_OFFSET = 0x000;
-/** @brief 12 bytes. */
-const int SYNC_NUM_BYTES = 12;
-
-/** @brief offset within sector. */
-const int MODE_OFFSET = 0x00f;
-
-/** @brief offset within sector. */
-const int ECC_P_OFFSET = 0x81c;
-/** @brief 2 lots of 86. */
-const int ECC_P_NUM_BYTES = 86;
-/** @brief 24 bytes each. */
-const int ECC_P_COMP = 24;
-
-/** @brief The ECC q offset. */
-const int ECC_Q_OFFSET = ECC_P_OFFSET + 2 * ECC_P_NUM_BYTES;
-/** @brief 2 lots of 52. */
-const int ECC_Q_NUM_BYTES = 52;
-/** @brief 43 bytes each. */
-const int ECC_Q_COMP = 43;
-
-
-
-/***************************************************************************
- TYPE DEFINITIONS
-***************************************************************************/
-
-/**
- * @struct cdrom_file
- *
- * @brief A cdrom file.
- */
-
-struct cdrom_file
-{
- /** @brief The chd. */
- chd_file * chd; /* CHD file */
- /** @brief The cdtoc. */
- cdrom_toc cdtoc; /* TOC for the CD */
- /** @brief Information describing the track. */
- chdcd_track_input_info track_info; /* track info */
- /** @brief The fhandle[ CD maximum tracks]. */
- util::core_file::ptr fhandle[CD_MAX_TRACKS];/* file handle */
-};
-
-
-
-/***************************************************************************
INLINE FUNCTIONS
***************************************************************************/
@@ -131,27 +78,26 @@ struct cdrom_file
-------------------------------------------------*/
/**
- * @fn static inline uint32_t physical_to_chd_lba(cdrom_file *file, uint32_t physlba, uint32_t &tracknum)
+ * @fn static inline uint32_t physical_to_chd_lba(uint32_t physlba, uint32_t &tracknum)
*
* @brief Physical to chd lba.
*
- * @param [in,out] file If non-null, the file.
* @param physlba The physlba.
* @param [in,out] tracknum The tracknum.
*
* @return An uint32_t.
*/
-static inline uint32_t physical_to_chd_lba(cdrom_file *file, uint32_t physlba, uint32_t &tracknum)
+uint32_t cdrom_file::physical_to_chd_lba(uint32_t physlba, uint32_t &tracknum) const
{
uint32_t chdlba;
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 (physlba < file->cdtoc.tracks[track + 1].physframeofs)
+ for (track = 0; track < cdtoc.numtrks; track++)
+ if (physlba < cdtoc.tracks[track + 1].physframeofs)
{
- chdlba = physlba - file->cdtoc.tracks[track].physframeofs + file->cdtoc.tracks[track].chdframeofs;
+ chdlba = physlba - cdtoc.tracks[track].physframeofs + cdtoc.tracks[track].chdframeofs;
tracknum = track;
return chdlba;
}
@@ -165,30 +111,29 @@ static inline uint32_t physical_to_chd_lba(cdrom_file *file, uint32_t physlba, u
-------------------------------------------------*/
/**
- * @fn static inline uint32_t logical_to_chd_lba(cdrom_file *file, uint32_t loglba, uint32_t &tracknum)
+ * @fn uint32_t logical_to_chd_lba(uint32_t loglba, uint32_t &tracknum)
*
* @brief Logical to chd lba.
*
- * @param [in,out] file If non-null, the file.
* @param loglba The loglba.
* @param [in,out] tracknum The tracknum.
*
* @return An uint32_t.
*/
-static inline uint32_t logical_to_chd_lba(cdrom_file *file, uint32_t loglba, uint32_t &tracknum)
+uint32_t cdrom_file::logical_to_chd_lba(uint32_t loglba, uint32_t &tracknum) const
{
uint32_t 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++)
+ for (track = 0; track < cdtoc.numtrks; track++)
{
- if (loglba < file->cdtoc.tracks[track + 1].logframeofs)
+ if (loglba < 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;
+ physlba = cdtoc.tracks[track].physframeofs + (loglba - cdtoc.tracks[track].logframeofs);
+ chdlba = physlba - cdtoc.tracks[track].physframeofs + cdtoc.tracks[track].chdframeofs;
tracknum = track;
return chdlba;
}
@@ -203,48 +148,38 @@ static inline uint32_t logical_to_chd_lba(cdrom_file *file, uint32_t loglba, uin
***************************************************************************/
/**
- * @fn cdrom_file *cdrom_open(const char *inputfile)
+ * @fn constructor
*
- * @brief Queries if a given cdrom open.
+ * @brief Open a cdrom for a file.
*
* @param inputfile The inputfile.
- *
- * @return null if it fails, else a cdrom_file*.
*/
-cdrom_file *cdrom_open(const char *inputfile)
+cdrom_file::cdrom_file(const char *inputfile)
{
int i;
- cdrom_file *file;
uint32_t physofs, logofs;
- // allocate memory for the CD-ROM file
- file = new (std::nothrow) cdrom_file();
- if (file == nullptr)
- return nullptr;
-
// set up the CD-ROM module and get the disc info
- std::error_condition err = chdcd_parse_toc(inputfile, file->cdtoc, file->track_info);
+ std::error_condition err = parse_toc(inputfile, cdtoc, cdtrack_info);
if (err)
{
fprintf(stderr, "Error reading input file: %s\n", err.message().c_str());
- delete file;
- return nullptr;
+ throw nullptr;
}
// fill in the data
- file->chd = nullptr;
+ chd = nullptr;
- LOG(("CD has %d tracks\n", file->cdtoc.numtrks));
+ LOG(("CD has %d tracks\n", cdtoc.numtrks));
- for (i = 0; i < file->cdtoc.numtrks; i++)
+ for (i = 0; i < cdtoc.numtrks; i++)
{
- std::error_condition const filerr = util::core_file::open(file->track_info.track[i].fname, OPEN_FLAG_READ, file->fhandle[i]);
+ std::error_condition const filerr = util::core_file::open(cdtrack_info.track[i].fname, OPEN_FLAG_READ, fhandle[i]);
if (filerr)
{
- fprintf(stderr, "Unable to open file: %s\n", file->track_info.track[i].fname.c_str());
- cdrom_close(file);
- return nullptr;
+ fprintf(stderr, "Unable to open file: %s\n", cdtrack_info.track[i].fname.c_str());
+ throw nullptr;
}
}
@@ -252,58 +187,56 @@ cdrom_file *cdrom_open(const char *inputfile)
pads tracks out with extra frames to fit 4-frame size boundries
*/
physofs = logofs = 0;
- for (i = 0; i < file->cdtoc.numtrks; i++)
+ for (i = 0; i < cdtoc.numtrks; i++)
{
- file->cdtoc.tracks[i].logframeofs = 0;
+ cdtoc.tracks[i].logframeofs = 0;
- if (file->cdtoc.tracks[i].pgdatasize == 0)
+ if (cdtoc.tracks[i].pgdatasize == 0)
{
- logofs += file->cdtoc.tracks[i].pregap;
+ logofs += cdtoc.tracks[i].pregap;
}
else
{
- file->cdtoc.tracks[i].logframeofs = file->cdtoc.tracks[i].pregap;
+ cdtoc.tracks[i].logframeofs = 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;
+ cdtoc.tracks[i].physframeofs = physofs;
+ cdtoc.tracks[i].chdframeofs = 0;
+ cdtoc.tracks[i].logframeofs += logofs;
+ cdtoc.tracks[i].logframes = cdtoc.tracks[i].frames - cdtoc.tracks[i].pregap;
// postgap adds to the track length
- logofs += file->cdtoc.tracks[i].postgap;
+ logofs += cdtoc.tracks[i].postgap;
- physofs += file->cdtoc.tracks[i].frames;
- logofs += file->cdtoc.tracks[i].frames;
+ physofs += cdtoc.tracks[i].frames;
+ logofs += 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 logframes %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].pregap,
- file->cdtoc.tracks[i].pgtype,
- file->cdtoc.tracks[i].pgdatasize,
- file->cdtoc.tracks[i].postgap,
- file->cdtoc.tracks[i].logframeofs,
- file->cdtoc.tracks[i].physframeofs,
- file->cdtoc.tracks[i].chdframeofs,
- file->cdtoc.tracks[i].logframes);*/
+ cdtoc.tracks[i].trktype,
+ cdtoc.tracks[i].subtype,
+ cdtoc.tracks[i].datasize,
+ cdtoc.tracks[i].subsize,
+ cdtoc.tracks[i].frames,
+ cdtoc.tracks[i].extraframes,
+ cdtoc.tracks[i].pregap,
+ cdtoc.tracks[i].pgtype,
+ cdtoc.tracks[i].pgdatasize,
+ cdtoc.tracks[i].postgap,
+ cdtoc.tracks[i].logframeofs,
+ cdtoc.tracks[i].physframeofs,
+ cdtoc.tracks[i].chdframeofs,
+ 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;
+ cdtoc.tracks[i].physframeofs = physofs;
+ cdtoc.tracks[i].logframeofs = logofs;
+ cdtoc.tracks[i].chdframeofs = 0;
+ cdtoc.tracks[i].logframes = 0;
}
/*-------------------------------------------------
- cdrom_open - "open" a CD-ROM file from an
+ constructor - "open" a CD-ROM file from an
already-opened CHD file
-------------------------------------------------*/
@@ -317,128 +250,100 @@ cdrom_file *cdrom_open(const char *inputfile)
* @return null if it fails, else a cdrom_file*.
*/
-cdrom_file *cdrom_open(chd_file *chd)
+cdrom_file::cdrom_file(chd_file *_chd)
{
- // punt if no CHD
- if (!chd)
- return nullptr;
+ chd = _chd;
/* validate the CHD information */
- if (chd->hunk_bytes() % CD_FRAME_SIZE != 0)
- return nullptr;
- if (chd->unit_bytes() != CD_FRAME_SIZE)
- return nullptr;
-
- /* allocate memory for the CD-ROM file */
- cdrom_file *file = new (std::nothrow) cdrom_file();
- if (!file)
- return nullptr;
-
- /* fill in the data */
- file->chd = chd;
+ if (chd->hunk_bytes() % FRAME_SIZE != 0)
+ throw nullptr;
+ if (chd->unit_bytes() != FRAME_SIZE)
+ throw nullptr;
/* read the CD-ROM metadata */
- std::error_condition err = cdrom_parse_metadata(chd, &file->cdtoc);
+ std::error_condition err = parse_metadata(chd, cdtoc);
if (err)
- {
- delete file;
- return nullptr;
- }
+ throw nullptr;
- LOG(("CD has %d tracks\n", file->cdtoc.numtrks));
+ LOG(("CD has %d tracks\n", cdtoc.numtrks));
/* calculate the starting frame for each track, keeping in mind that CHDMAN
pads tracks out with extra frames to fit 4-frame size boundries
*/
uint32_t physofs = 0, chdofs = 0, logofs = 0;
int i;
- for (i = 0; i < file->cdtoc.numtrks; i++)
+ for (i = 0; i < cdtoc.numtrks; i++)
{
- file->cdtoc.tracks[i].logframeofs = 0;
+ cdtoc.tracks[i].logframeofs = 0;
- if (file->cdtoc.tracks[i].pgdatasize == 0)
+ if (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;
+ logofs += 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;
+ cdtoc.tracks[i].logframeofs = 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;
+ cdtoc.tracks[i].physframeofs = physofs;
+ cdtoc.tracks[i].chdframeofs = chdofs;
+ cdtoc.tracks[i].logframeofs += logofs;
+ cdtoc.tracks[i].logframes = cdtoc.tracks[i].frames - cdtoc.tracks[i].pregap;
// postgap counts against the next track
- logofs += file->cdtoc.tracks[i].postgap;
+ logofs += 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;
+ physofs += cdtoc.tracks[i].frames;
+ chdofs += cdtoc.tracks[i].frames;
+ chdofs += cdtoc.tracks[i].extraframes;
+ logofs += 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 logframes %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].pregap,
- file->cdtoc.tracks[i].pgtype,
- file->cdtoc.tracks[i].pgdatasize,
- file->cdtoc.tracks[i].postgap,
- file->cdtoc.tracks[i].logframeofs,
- file->cdtoc.tracks[i].physframeofs,
- file->cdtoc.tracks[i].chdframeofs,
- file->cdtoc.tracks[i].logframes);*/
+ cdtoc.tracks[i].trktype,
+ cdtoc.tracks[i].subtype,
+ cdtoc.tracks[i].datasize,
+ cdtoc.tracks[i].subsize,
+ cdtoc.tracks[i].frames,
+ cdtoc.tracks[i].extraframes,
+ cdtoc.tracks[i].pregap,
+ cdtoc.tracks[i].pgtype,
+ cdtoc.tracks[i].pgdatasize,
+ cdtoc.tracks[i].postgap,
+ cdtoc.tracks[i].logframeofs,
+ cdtoc.tracks[i].physframeofs,
+ cdtoc.tracks[i].chdframeofs,
+ 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;
+ cdtoc.tracks[i].physframeofs = physofs;
+ cdtoc.tracks[i].logframeofs = logofs;
+ cdtoc.tracks[i].chdframeofs = chdofs;
+ cdtoc.tracks[i].logframes = 0;
}
/*-------------------------------------------------
- cdrom_close - "close" a CD-ROM file
+ destructor - "close" a CD-ROM file
-------------------------------------------------*/
-/**
- * @fn void cdrom_close(cdrom_file *file)
- *
- * @brief Cdrom close.
- *
- * @param [in,out] file If non-null, the file.
- */
-
-void cdrom_close(cdrom_file *file)
+cdrom_file::~cdrom_file()
{
- if (file == nullptr)
- return;
-
- if (file->chd == nullptr)
+ if (chd == nullptr)
{
- for (int i = 0; i < file->cdtoc.numtrks; i++)
+ for (int i = 0; i < cdtoc.numtrks; i++)
{
- file->fhandle[i].reset();
+ fhandle[i].reset();
}
}
-
- delete file;
}
@@ -448,11 +353,10 @@ void cdrom_close(cdrom_file *file)
***************************************************************************/
/**
- * @fn std::error_condition read_partial_sector(cdrom_file *file, void *dest, uint32_t lbasector, uint32_t chdsector, uint32_t tracknum, uint32_t startoffs, uint32_t length)
+ * @fn std::error_condition read_partial_sector(void *dest, uint32_t lbasector, uint32_t chdsector, uint32_t tracknum, uint32_t startoffs, uint32_t length)
*
* @brief Reads partial sector.
*
- * @param [in,out] file If non-null, the file.
* @param [in,out] dest If non-null, destination for the.
* @param lbasector The lbasector.
* @param chdsector The chdsector.
@@ -463,7 +367,7 @@ void cdrom_close(cdrom_file *file)
* @return The partial sector.
*/
-std::error_condition read_partial_sector(cdrom_file *file, void *dest, uint32_t lbasector, uint32_t chdsector, uint32_t tracknum, uint32_t startoffs, uint32_t length, bool phys=false)
+std::error_condition cdrom_file::read_partial_sector(void *dest, uint32_t lbasector, uint32_t chdsector, uint32_t tracknum, uint32_t startoffs, uint32_t length, bool phys)
{
std::error_condition result;
bool needswap = false;
@@ -471,40 +375,40 @@ std::error_condition read_partial_sector(cdrom_file *file, void *dest, uint32_t
// 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))
+ if ((cdtoc.tracks[tracknum].pgdatasize == 0) && (lbasector < cdtoc.tracks[tracknum].logframeofs))
{
- //printf("PG missing sector: LBA %d, trklog %d\n", lbasector, file->cdtoc.tracks[tracknum].logframeofs);
+ //printf("PG missing sector: LBA %d, trklog %d\n", lbasector, cdtoc.tracks[tracknum].logframeofs);
memset(dest, 0, length);
return result;
}
}
// if a CHD, just read
- if (file->chd != nullptr)
+ if (chd != nullptr)
{
- if (!phys && file->cdtoc.tracks[tracknum].pgdatasize != 0)
+ if (!phys && 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;
+ chdsector += cdtoc.tracks[tracknum].pregap;
}
- result = file->chd->read_bytes(uint64_t(chdsector) * uint64_t(CD_FRAME_SIZE) + startoffs, dest, length);
+ result = chd->read_bytes(uint64_t(chdsector) * uint64_t(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))
+ if ((cdtoc.flags & CD_FLAG_GDROMLE) && (cdtoc.tracks[tracknum].trktype == CD_TRACK_AUDIO))
needswap = true;
}
else
{
// else read from the appropriate file
- util::core_file &srcfile = *file->fhandle[tracknum];
+ util::core_file &srcfile = *fhandle[tracknum];
- int bytespersector = file->cdtoc.tracks[tracknum].datasize + file->cdtoc.tracks[tracknum].subsize;
- uint64_t sourcefileoffset = file->track_info.track[tracknum].offset;
+ int bytespersector = cdtoc.tracks[tracknum].datasize + cdtoc.tracks[tracknum].subsize;
+ uint64_t sourcefileoffset = cdtrack_info.track[tracknum].offset;
- if (file->cdtoc.tracks[tracknum].pgdatasize != 0)
- chdsector += file->cdtoc.tracks[tracknum].pregap;
+ if (cdtoc.tracks[tracknum].pgdatasize != 0)
+ chdsector += cdtoc.tracks[tracknum].pregap;
sourcefileoffset += chdsector * bytespersector + startoffs;
@@ -516,7 +420,7 @@ std::error_condition read_partial_sector(cdrom_file *file, void *dest, uint32_t
result = srcfile.read(dest, length, actual);
// FIXME: if (actual < length) report error
- needswap = file->track_info.track[tracknum].swap;
+ needswap = cdtrack_info.track[tracknum].swap;
}
if (needswap)
@@ -539,11 +443,10 @@ std::error_condition read_partial_sector(cdrom_file *file, void *dest, uint32_t
-------------------------------------------------*/
/**
- * @fn uint32_t cdrom_read_data(cdrom_file *file, uint32_t lbasector, void *buffer, uint32_t datatype, bool phys)
+ * @fn bool read_data(uint32_t lbasector, void *buffer, uint32_t datatype, bool phys)
*
* @brief Cdrom read data.
*
- * @param [in,out] file If non-null, the file.
* @param lbasector The lbasector.
* @param [in,out] buffer If non-null, the buffer.
* @param datatype The datatype.
@@ -552,37 +455,34 @@ std::error_condition read_partial_sector(cdrom_file *file, void *dest, uint32_t
* @return An uint32_t.
*/
-uint32_t cdrom_read_data(cdrom_file *file, uint32_t lbasector, void *buffer, uint32_t datatype, bool phys)
+bool cdrom_file::read_data(uint32_t lbasector, void *buffer, uint32_t datatype, bool phys)
{
- if (file == nullptr)
- return 0;
-
// compute CHD sector and tracknumber
uint32_t tracknum = 0;
uint32_t chdsector;
if (phys)
{
- chdsector = physical_to_chd_lba(file, lbasector, tracknum);
+ chdsector = physical_to_chd_lba(lbasector, tracknum);
}
else
{
- chdsector = logical_to_chd_lba(file, lbasector, tracknum);
+ chdsector = logical_to_chd_lba(lbasector, tracknum);
}
// copy out the requested sector
- uint32_t tracktype = file->cdtoc.tracks[tracknum].trktype;
+ uint32_t tracktype = cdtoc.tracks[tracknum].trktype;
if ((datatype == tracktype) || (datatype == CD_TRACK_RAW_DONTCARE))
{
- return !read_partial_sector(file, buffer, lbasector, chdsector, tracknum, 0, file->cdtoc.tracks[tracknum].datasize, phys);
+ return !read_partial_sector(buffer, lbasector, chdsector, tracknum, 0, cdtoc.tracks[tracknum].datasize, phys);
}
else
{
// return 2048 bytes of mode 1 data from a 2352 byte mode 1 raw sector
if ((datatype == CD_TRACK_MODE1) && (tracktype == CD_TRACK_MODE1_RAW))
{
- return !read_partial_sector(file, buffer, lbasector, chdsector, tracknum, 16, 2048, phys);
+ return !read_partial_sector(buffer, lbasector, chdsector, tracknum, 16, 2048, phys);
}
// return 2352 byte mode 1 raw sector from 2048 bytes of mode 1 data
@@ -598,25 +498,25 @@ uint32_t cdrom_read_data(cdrom_file *file, uint32_t lbasector, void *buffer, uin
bufptr[14] = msf&0xff;
bufptr[15] = 1; // mode 1
LOG(("CDROM: promotion of mode1/form1 sector to mode1 raw is not complete!\n"));
- return !read_partial_sector(file, bufptr+16, lbasector, chdsector, tracknum, 0, 2048, phys);
+ return !read_partial_sector(bufptr+16, lbasector, chdsector, tracknum, 0, 2048, phys);
}
// return 2048 bytes of mode 1 data from a mode2 form1 or raw sector
if ((datatype == CD_TRACK_MODE1) && ((tracktype == CD_TRACK_MODE2_FORM1)||(tracktype == CD_TRACK_MODE2_RAW)))
{
- return !read_partial_sector(file, buffer, lbasector, chdsector, tracknum, 24, 2048, phys);
+ return !read_partial_sector(buffer, lbasector, chdsector, tracknum, 24, 2048, phys);
}
// return 2048 bytes of mode 1 data from a mode2 form2 or XA sector
if ((datatype == CD_TRACK_MODE1) && (tracktype == CD_TRACK_MODE2_FORM_MIX))
{
- return !read_partial_sector(file, buffer, lbasector, chdsector, tracknum, 8, 2048, phys);
+ return !read_partial_sector(buffer, lbasector, chdsector, tracknum, 8, 2048, phys);
}
// return mode 2 2336 byte data from a 2352 byte mode 1 or 2 raw sector (skip the header)
if ((datatype == CD_TRACK_MODE2) && ((tracktype == CD_TRACK_MODE1_RAW) || (tracktype == CD_TRACK_MODE2_RAW)))
{
- return !read_partial_sector(file, buffer, lbasector, chdsector, tracknum, 16, 2336, phys);
+ return !read_partial_sector(buffer, lbasector, chdsector, tracknum, 16, 2336, phys);
}
LOG(("CDROM: Conversion from type %d to type %d not supported!\n", tracktype, datatype));
@@ -626,46 +526,42 @@ uint32_t cdrom_read_data(cdrom_file *file, uint32_t lbasector, void *buffer, uin
/*-------------------------------------------------
- cdrom_read_subcode - read subcode data for
+ read_subcode - read subcode data for
a sector
-------------------------------------------------*/
/**
- * @fn uint32_t cdrom_read_subcode(cdrom_file *file, uint32_t lbasector, void *buffer, bool phys)
+ * @fn bool read_subcode(uint32_t lbasector, void *buffer, bool phys)
*
* @brief Cdrom read subcode.
*
- * @param [in,out] file If non-null, the file.
* @param lbasector The lbasector.
* @param [in,out] buffer If non-null, the buffer.
* @param phys true to physical.
*
- * @return An uint32_t.
+ * @return false on failure.
*/
-uint32_t cdrom_read_subcode(cdrom_file *file, uint32_t lbasector, void *buffer, bool phys)
+bool cdrom_file::read_subcode(uint32_t lbasector, void *buffer, bool phys)
{
- if (file == nullptr)
- return ~0;
-
// compute CHD sector and tracknumber
uint32_t tracknum = 0;
uint32_t chdsector;
if (phys)
{
- chdsector = physical_to_chd_lba(file, lbasector, tracknum);
+ chdsector = physical_to_chd_lba(lbasector, tracknum);
}
else
{
- chdsector = logical_to_chd_lba(file, lbasector, tracknum);
+ chdsector = logical_to_chd_lba(lbasector, tracknum);
}
- if (file->cdtoc.tracks[tracknum].subsize == 0)
- return 0;
+ if (cdtoc.tracks[tracknum].subsize == 0)
+ return false;
// read the data
- std::error_condition err = read_partial_sector(file, buffer, lbasector, chdsector, tracknum, file->cdtoc.tracks[tracknum].datasize, file->cdtoc.tracks[tracknum].subsize);
+ std::error_condition err = read_partial_sector(buffer, lbasector, chdsector, tracknum, cdtoc.tracks[tracknum].datasize, cdtoc.tracks[tracknum].subsize);
return !err;
}
@@ -676,220 +572,43 @@ uint32_t cdrom_read_subcode(cdrom_file *file, uint32_t lbasector, void *buffer,
***************************************************************************/
/*-------------------------------------------------
- cdrom_get_track - get the track number
+ get_track - get the track number
for a physical frame number
-------------------------------------------------*/
/**
- * @fn uint32_t cdrom_get_track(cdrom_file *file, uint32_t frame)
+ * @fn uint32_t get_track(uint32_t frame)
*
* @brief Cdrom get track.
*
- * @param [in,out] file If non-null, the file.
* @param frame The frame.
*
* @return An uint32_t.
*/
-uint32_t cdrom_get_track(cdrom_file *file, uint32_t frame)
+uint32_t cdrom_file::get_track(uint32_t frame) const
{
uint32_t track = 0;
- if (file == nullptr)
- return ~0;
-
/* convert to a CHD sector offset and get track information */
- logical_to_chd_lba(file, frame, track);
+ logical_to_chd_lba(frame, track);
return track;
}
-/*-------------------------------------------------
- cdrom_get_track_start - get the frame number
- that a track starts at
--------------------------------------------------*/
-
-/**
- * @fn uint32_t cdrom_get_track_start(cdrom_file *file, uint32_t track)
- *
- * @brief Cdrom get track start.
- *
- * @param [in,out] file If non-null, the file.
- * @param track The track.
- *
- * @return An uint32_t.
- */
-
-uint32_t cdrom_get_track_start(cdrom_file *file, uint32_t track)
-{
- if (file == nullptr)
- return ~0;
-
- /* handle lead-out specially */
- if (track == 0xaa)
- track = file->cdtoc.numtrks;
-
- return file->cdtoc.tracks[track].logframeofs;
-}
-
-/*-------------------------------------------------
- cdrom_get_track_start_phys - get the
- physical frame number that a track starts at
--------------------------------------------------*/
-
-/**
- * @fn uint32_t cdrom_get_track_start_phys(cdrom_file *file, uint32_t track)
- *
- * @brief Cdrom get track start physical.
- *
- * @param [in,out] file If non-null, the file.
- * @param track The track.
- *
- * @return An uint32_t.
- */
-
-uint32_t cdrom_get_track_start_phys(cdrom_file *file, uint32_t track)
-{
- if (file == nullptr)
- return ~0;
-
- /* handle lead-out specially */
- if (track == 0xaa)
- track = file->cdtoc.numtrks;
-
- return file->cdtoc.tracks[track].physframeofs;
-}
-
-/*-------------------------------------------------
- cdrom_get_chd - get a handle to a CHD
- from a cdrom
--------------------------------------------------*/
-
-chd_file *cdrom_get_chd(cdrom_file *file)
-{
- return file->chd;
-}
-
-/***************************************************************************
- TOC UTILITIES
-***************************************************************************/
-
-/*-------------------------------------------------
- cdrom_get_last_track - returns the last track
- number
--------------------------------------------------*/
-
-/**
- * @fn int cdrom_get_last_track(cdrom_file *file)
- *
- * @brief Cdrom get last track.
- *
- * @param [in,out] file If non-null, the file.
- *
- * @return An int.
- */
-
-int cdrom_get_last_track(cdrom_file *file)
-{
- if (file == nullptr)
- return -1;
-
- return file->cdtoc.numtrks;
-}
-
-
-/*-------------------------------------------------
- cdrom_get_adr_control - get the ADR | CONTROL
- for a track
--------------------------------------------------*/
-
-/**
- * @fn int cdrom_get_adr_control(cdrom_file *file, int track)
- *
- * @brief Cdrom get address control.
- *
- * @param [in,out] file If non-null, the file.
- * @param track The track.
- *
- * @return An int.
- */
-
-int cdrom_get_adr_control(cdrom_file *file, int track)
-{
- if (file == nullptr)
- return -1;
-
- if (track == 0xaa || file->cdtoc.tracks[track].trktype == CD_TRACK_AUDIO)
- {
- return 0x10; // audio track, subchannel is position
- }
-
- return 0x14; // data track, subchannel is position
-}
-
-
-/*-------------------------------------------------
- cdrom_get_track_type - return the track type
--------------------------------------------------*/
-
-/**
- * @fn int cdrom_get_track_type(cdrom_file *file, int track)
- *
- * @brief Cdrom get track type.
- *
- * @param [in,out] file If non-null, the file.
- * @param track The track.
- *
- * @return An int.
- */
-
-int cdrom_get_track_type(cdrom_file *file, int track)
-{
- if (file == nullptr)
- return -1;
-
- return file->cdtoc.tracks[track].trktype;
-}
-
-
-/*-------------------------------------------------
- cdrom_get_toc - return the TOC data for a
- CD-ROM
--------------------------------------------------*/
-
-/**
- * @fn const cdrom_toc *cdrom_get_toc(cdrom_file *file)
- *
- * @brief Cdrom get TOC.
- *
- * @param [in,out] file If non-null, the file.
- *
- * @return null if it fails, else a cdrom_toc*.
- */
-
-const cdrom_toc *cdrom_get_toc(cdrom_file *file)
-{
- if (file == nullptr)
- return nullptr;
-
- return &file->cdtoc;
-}
-
-
-
/***************************************************************************
EXTRA UTILITIES
***************************************************************************/
/*-------------------------------------------------
- cdrom_get_info_from_type_string
+ get_info_from_type_string
take a string and convert it into track type
and track data size
-------------------------------------------------*/
/**
- * @fn static void cdrom_get_info_from_type_string(const char *typestring, uint32_t *trktype, uint32_t *datasize)
+ * @fn static void get_info_from_type_string(const char *typestring, uint32_t *trktype, uint32_t *datasize)
*
* @brief Cdrom get information from type string.
*
@@ -898,7 +617,7 @@ const cdrom_toc *cdrom_get_toc(cdrom_file *file)
* @param [in,out] datasize If non-null, the datasize.
*/
-static void cdrom_get_info_from_type_string(const char *typestring, uint32_t *trktype, uint32_t *datasize)
+void cdrom_file::get_info_from_type_string(const char *typestring, uint32_t *trktype, uint32_t *datasize)
{
if (!strcmp(typestring, "MODE1"))
{
@@ -983,61 +702,61 @@ static void cdrom_get_info_from_type_string(const char *typestring, uint32_t *tr
}
/*-------------------------------------------------
- cdrom_convert_type_string_to_track_info -
+ convert_type_string_to_track_info -
take a string and convert it into track type
and track data size
-------------------------------------------------*/
/**
- * @fn void cdrom_convert_type_string_to_track_info(const char *typestring, cdrom_track_info *info)
+ * @fn void convert_type_string_to_track_info(const char *typestring, track_info *info)
*
- * @brief Cdrom convert type string to track information.
+ * @brief Convert type string to track information.
*
* @param typestring The typestring.
* @param [in,out] info If non-null, the information.
*/
-void cdrom_convert_type_string_to_track_info(const char *typestring, cdrom_track_info *info)
+void cdrom_file::convert_type_string_to_track_info(const char *typestring, track_info *info)
{
- cdrom_get_info_from_type_string(typestring, &info->trktype, &info->datasize);
+ get_info_from_type_string(typestring, &info->trktype, &info->datasize);
}
/*-------------------------------------------------
- cdrom_convert_type_string_to_pregap_info -
+ convert_type_string_to_pregap_info -
take a string and convert it into pregap type
and pregap data size
-------------------------------------------------*/
/**
- * @fn void cdrom_convert_type_string_to_pregap_info(const char *typestring, cdrom_track_info *info)
+ * @fn void convert_type_string_to_pregap_info(const char *typestring, track_info *info)
*
- * @brief Cdrom convert type string to pregap information.
+ * @brief Convert type string to pregap information.
*
* @param typestring The typestring.
* @param [in,out] info If non-null, the information.
*/
-void cdrom_convert_type_string_to_pregap_info(const char *typestring, cdrom_track_info *info)
+void cdrom_file::convert_type_string_to_pregap_info(const char *typestring, track_info *info)
{
- cdrom_get_info_from_type_string(typestring, &info->pgtype, &info->pgdatasize);
+ get_info_from_type_string(typestring, &info->pgtype, &info->pgdatasize);
}
/*-------------------------------------------------
- cdrom_convert_subtype_string_to_track_info -
+ convert_subtype_string_to_track_info -
take a string and convert it into track subtype
and track subcode data size
-------------------------------------------------*/
/**
- * @fn void cdrom_convert_subtype_string_to_track_info(const char *typestring, cdrom_track_info *info)
+ * @fn void convert_subtype_string_to_track_info(const char *typestring, track_info *info)
*
- * @brief Cdrom convert subtype string to track information.
+ * @brief Convert subtype string to track information.
*
* @param typestring The typestring.
* @param [in,out] info If non-null, the information.
*/
-void cdrom_convert_subtype_string_to_track_info(const char *typestring, cdrom_track_info *info)
+void cdrom_file::convert_subtype_string_to_track_info(const char *typestring, track_info *info)
{
if (!strcmp(typestring, "RW"))
{
@@ -1052,21 +771,21 @@ void cdrom_convert_subtype_string_to_track_info(const char *typestring, cdrom_tr
}
/*-------------------------------------------------
- cdrom_convert_subtype_string_to_pregap_info -
+ convert_subtype_string_to_pregap_info -
take a string and convert it into track subtype
and track subcode data size
-------------------------------------------------*/
/**
- * @fn void cdrom_convert_subtype_string_to_pregap_info(const char *typestring, cdrom_track_info *info)
+ * @fn void convert_subtype_string_to_pregap_info(const char *typestring, track_info *info)
*
- * @brief Cdrom convert subtype string to pregap information.
+ * @brief Convert subtype string to pregap information.
*
* @param typestring The typestring.
* @param [in,out] info If non-null, the information.
*/
-void cdrom_convert_subtype_string_to_pregap_info(const char *typestring, cdrom_track_info *info)
+void cdrom_file::convert_subtype_string_to_pregap_info(const char *typestring, track_info *info)
{
if (!strcmp(typestring, "RW"))
{
@@ -1081,21 +800,21 @@ void cdrom_convert_subtype_string_to_pregap_info(const char *typestring, cdrom_t
}
/*-------------------------------------------------
- cdrom_get_type_string - get the string
+ get_type_string - get the string
associated with the given type
-------------------------------------------------*/
/**
- * @fn const char *cdrom_get_type_string(uint32_t trktype)
+ * @fn const char *get_type_string(uint32_t trktype)
*
- * @brief Cdrom get type string.
+ * @brief Get type string.
*
* @param trktype The trktype.
*
* @return null if it fails, else a char*.
*/
-const char *cdrom_get_type_string(uint32_t trktype)
+const char *cdrom_file::get_type_string(uint32_t trktype)
{
switch (trktype)
{
@@ -1113,21 +832,21 @@ const char *cdrom_get_type_string(uint32_t trktype)
/*-------------------------------------------------
- cdrom_get_subtype_string - get the string
+ get_subtype_string - get the string
associated with the given subcode type
-------------------------------------------------*/
/**
- * @fn const char *cdrom_get_subtype_string(uint32_t subtype)
+ * @fn const char *get_subtype_string(uint32_t subtype)
*
- * @brief Cdrom get subtype string.
+ * @brief Get subtype string.
*
* @param subtype The subtype.
*
* @return null if it fails, else a char*.
*/
-const char *cdrom_get_subtype_string(uint32_t subtype)
+const char *cdrom_file::get_subtype_string(uint32_t subtype)
{
switch (subtype)
{
@@ -1144,14 +863,14 @@ const char *cdrom_get_subtype_string(uint32_t subtype)
***************************************************************************/
/*-------------------------------------------------
- cdrom_parse_metadata - parse metadata into the
+ parse_metadata - parse metadata into the
TOC structure
-------------------------------------------------*/
/**
- * @fn std::error_condition cdrom_parse_metadata(chd_file *chd, cdrom_toc *toc)
+ * @fn std::error_condition cdrom_parse_metadata(chd_file *chd, toc *toc)
*
- * @brief Cdrom parse metadata.
+ * @brief Parse metadata.
*
* @param [in,out] chd If non-null, the chd.
* @param [in,out] toc If non-null, the TOC.
@@ -1159,24 +878,24 @@ const char *cdrom_get_subtype_string(uint32_t subtype)
* @return A std::error_condition.
*/
-std::error_condition cdrom_parse_metadata(chd_file *chd, cdrom_toc *toc)
+std::error_condition cdrom_file::parse_metadata(chd_file *chd, toc &toc)
{
std::string metadata;
std::error_condition err;
- toc->flags = 0;
+ toc.flags = 0;
/* start with no tracks */
- for (toc->numtrks = 0; toc->numtrks < CD_MAX_TRACKS; toc->numtrks++)
+ for (toc.numtrks = 0; toc.numtrks < MAX_TRACKS; toc.numtrks++)
{
int tracknum = -1, frames = 0, pregap, postgap, padframes;
char type[16], subtype[16], pgtype[16], pgsub[16];
- cdrom_track_info *track;
+ track_info *track;
pregap = postgap = padframes = 0;
/* fetch the metadata for this track */
- err = chd->read_metadata(CDROM_TRACK_METADATA_TAG, toc->numtrks, metadata);
+ err = chd->read_metadata(CDROM_TRACK_METADATA_TAG, toc.numtrks, metadata);
if (!err)
{
/* parse the metadata */
@@ -1184,13 +903,13 @@ std::error_condition cdrom_parse_metadata(chd_file *chd, cdrom_toc *toc)
pgtype[0] = pgsub[0] = 0;
if (sscanf(metadata.c_str(), CDROM_TRACK_METADATA_FORMAT, &tracknum, type, subtype, &frames) != 4)
return chd_file::error::INVALID_DATA;
- if (tracknum == 0 || tracknum > CD_MAX_TRACKS)
+ if (tracknum == 0 || tracknum > MAX_TRACKS)
return chd_file::error::INVALID_DATA;
- track = &toc->tracks[tracknum - 1];
+ track = &toc.tracks[tracknum - 1];
}
else
{
- err = chd->read_metadata(CDROM_TRACK_METADATA2_TAG, toc->numtrks, metadata);
+ err = chd->read_metadata(CDROM_TRACK_METADATA2_TAG, toc.numtrks, metadata);
if (!err)
{
/* parse the metadata */
@@ -1198,18 +917,18 @@ std::error_condition cdrom_parse_metadata(chd_file *chd, cdrom_toc *toc)
pregap = postgap = 0;
if (sscanf(metadata.c_str(), CDROM_TRACK_METADATA2_FORMAT, &tracknum, type, subtype, &frames, &pregap, pgtype, pgsub, &postgap) != 8)
return chd_file::error::INVALID_DATA;
- if (tracknum == 0 || tracknum > CD_MAX_TRACKS)
+ if (tracknum == 0 || tracknum > MAX_TRACKS)
return chd_file::error::INVALID_DATA;
- track = &toc->tracks[tracknum - 1];
+ track = &toc.tracks[tracknum - 1];
}
else
{
- err = chd->read_metadata(GDROM_OLD_METADATA_TAG, toc->numtrks, metadata);
+ err = chd->read_metadata(GDROM_OLD_METADATA_TAG, toc.numtrks, metadata);
if (!err)
/* legacy GDROM track was detected */
- toc->flags |= CD_FLAG_GDROMLE;
+ toc.flags |= CD_FLAG_GDROMLE;
else
- err = chd->read_metadata(GDROM_TRACK_METADATA_TAG, toc->numtrks, metadata);
+ err = chd->read_metadata(GDROM_TRACK_METADATA_TAG, toc.numtrks, metadata);
if (!err)
{
@@ -1218,10 +937,10 @@ std::error_condition cdrom_parse_metadata(chd_file *chd, cdrom_toc *toc)
pregap = postgap = 0;
if (sscanf(metadata.c_str(), GDROM_TRACK_METADATA_FORMAT, &tracknum, type, subtype, &frames, &padframes, &pregap, pgtype, pgsub, &postgap) != 9)
return chd_file::error::INVALID_DATA;
- if (tracknum == 0 || tracknum > CD_MAX_TRACKS)
+ if (tracknum == 0 || tracknum > MAX_TRACKS)
return chd_file::error::INVALID_DATA;
- track = &toc->tracks[tracknum - 1];
- toc->flags |= CD_FLAG_GDROM;
+ track = &toc.tracks[tracknum - 1];
+ toc.flags |= CD_FLAG_GDROM;
}
else
{
@@ -1233,20 +952,20 @@ std::error_condition cdrom_parse_metadata(chd_file *chd, cdrom_toc *toc)
/* extract the track type and determine the data size */
track->trktype = CD_TRACK_MODE1;
track->datasize = 0;
- cdrom_convert_type_string_to_track_info(type, track);
+ convert_type_string_to_track_info(type, track);
if (track->datasize == 0)
return chd_file::error::INVALID_DATA;
/* extract the subtype and determine the subcode data size */
track->subtype = CD_SUB_NONE;
track->subsize = 0;
- cdrom_convert_subtype_string_to_track_info(subtype, track);
+ convert_subtype_string_to_track_info(subtype, track);
/* set the frames and extra frames data */
track->frames = frames;
track->padframes = padframes;
- int padded = (frames + CD_TRACK_PADDING - 1) / CD_TRACK_PADDING;
- track->extraframes = padded * CD_TRACK_PADDING - frames;
+ int padded = (frames + TRACK_PADDING - 1) / TRACK_PADDING;
+ track->extraframes = padded * TRACK_PADDING - frames;
/* set the pregap info */
track->pregap = pregap;
@@ -1258,10 +977,10 @@ std::error_condition cdrom_parse_metadata(chd_file *chd, cdrom_toc *toc)
{
if (pgtype[0] == 'V')
{
- cdrom_convert_type_string_to_pregap_info(&pgtype[1], track);
+ convert_type_string_to_pregap_info(&pgtype[1], track);
}
- cdrom_convert_subtype_string_to_pregap_info(pgsub, track);
+ convert_subtype_string_to_pregap_info(pgsub, track);
}
/* set the postgap info */
@@ -1269,10 +988,10 @@ std::error_condition cdrom_parse_metadata(chd_file *chd, cdrom_toc *toc)
}
/* if we got any tracks this way, we're done */
- if (toc->numtrks > 0)
+ if (toc.numtrks > 0)
return std::error_condition();
- printf("toc->numtrks = %u?!\n", toc->numtrks);
+ printf("toc.numtrks = %u?!\n", toc.numtrks);
/* look for old-style metadata */
std::vector<uint8_t> oldmetadata;
@@ -1282,37 +1001,37 @@ std::error_condition cdrom_parse_metadata(chd_file *chd, cdrom_toc *toc)
/* reconstruct the TOC from it */
auto *mrp = reinterpret_cast<uint32_t *>(&oldmetadata[0]);
- toc->numtrks = *mrp++;
+ toc.numtrks = *mrp++;
- for (int i = 0; i < CD_MAX_TRACKS; i++)
+ for (int i = 0; i < MAX_TRACKS; i++)
{
- toc->tracks[i].trktype = *mrp++;
- toc->tracks[i].subtype = *mrp++;
- toc->tracks[i].datasize = *mrp++;
- toc->tracks[i].subsize = *mrp++;
- toc->tracks[i].frames = *mrp++;
- toc->tracks[i].extraframes = *mrp++;
- toc->tracks[i].pregap = 0;
- toc->tracks[i].postgap = 0;
- toc->tracks[i].pgtype = 0;
- toc->tracks[i].pgsub = 0;
- toc->tracks[i].pgdatasize = 0;
- toc->tracks[i].pgsubsize = 0;
+ toc.tracks[i].trktype = *mrp++;
+ toc.tracks[i].subtype = *mrp++;
+ toc.tracks[i].datasize = *mrp++;
+ toc.tracks[i].subsize = *mrp++;
+ toc.tracks[i].frames = *mrp++;
+ toc.tracks[i].extraframes = *mrp++;
+ toc.tracks[i].pregap = 0;
+ toc.tracks[i].postgap = 0;
+ toc.tracks[i].pgtype = 0;
+ toc.tracks[i].pgsub = 0;
+ toc.tracks[i].pgdatasize = 0;
+ toc.tracks[i].pgsubsize = 0;
}
/* TODO: I don't know why sometimes the data is one endian and sometimes another */
- if (toc->numtrks > CD_MAX_TRACKS)
+ if (toc.numtrks > MAX_TRACKS)
{
- toc->numtrks = swapendian_int32(toc->numtrks);
- for (int i = 0; i < CD_MAX_TRACKS; i++)
+ toc.numtrks = swapendian_int32(toc.numtrks);
+ for (int i = 0; i < MAX_TRACKS; i++)
{
- toc->tracks[i].trktype = swapendian_int32(toc->tracks[i].trktype);
- toc->tracks[i].subtype = swapendian_int32(toc->tracks[i].subtype);
- toc->tracks[i].datasize = swapendian_int32(toc->tracks[i].datasize);
- toc->tracks[i].subsize = swapendian_int32(toc->tracks[i].subsize);
- toc->tracks[i].frames = swapendian_int32(toc->tracks[i].frames);
- toc->tracks[i].padframes = swapendian_int32(toc->tracks[i].padframes);
- toc->tracks[i].extraframes = swapendian_int32(toc->tracks[i].extraframes);
+ toc.tracks[i].trktype = swapendian_int32(toc.tracks[i].trktype);
+ toc.tracks[i].subtype = swapendian_int32(toc.tracks[i].subtype);
+ toc.tracks[i].datasize = swapendian_int32(toc.tracks[i].datasize);
+ toc.tracks[i].subsize = swapendian_int32(toc.tracks[i].subsize);
+ toc.tracks[i].frames = swapendian_int32(toc.tracks[i].frames);
+ toc.tracks[i].padframes = swapendian_int32(toc.tracks[i].padframes);
+ toc.tracks[i].extraframes = swapendian_int32(toc.tracks[i].extraframes);
}
}
@@ -1321,13 +1040,13 @@ std::error_condition cdrom_parse_metadata(chd_file *chd, cdrom_toc *toc)
/*-------------------------------------------------
- cdrom_write_metadata - write metadata
+ write_metadata - write metadata
-------------------------------------------------*/
/**
- * @fn std::error_condition cdrom_write_metadata(chd_file *chd, const cdrom_toc *toc)
+ * @fn std::error_condition write_metadata(chd_file *chd, const toc *toc)
*
- * @brief Cdrom write metadata.
+ * @brief Write metadata.
*
* @param [in,out] chd If non-null, the chd.
* @param toc The TOC.
@@ -1335,40 +1054,40 @@ std::error_condition cdrom_parse_metadata(chd_file *chd, cdrom_toc *toc)
* @return A std::error_condition.
*/
-std::error_condition cdrom_write_metadata(chd_file *chd, const cdrom_toc *toc)
+std::error_condition cdrom_file::write_metadata(chd_file *chd, const toc &toc)
{
std::error_condition err;
/* write the metadata */
- for (int i = 0; i < toc->numtrks; i++)
+ for (int i = 0; i < toc.numtrks; i++)
{
std::string metadata;
- if (!(toc->flags & CD_FLAG_GDROM))
+ if (!(toc.flags & CD_FLAG_GDROM))
{
char submode[32];
- if (toc->tracks[i].pgdatasize > 0)
+ if (toc.tracks[i].pgdatasize > 0)
{
- strcpy(&submode[1], cdrom_get_type_string(toc->tracks[i].pgtype));
+ strcpy(&submode[1], get_type_string(toc.tracks[i].pgtype));
submode[0] = 'V'; // indicate valid submode
}
else
{
- strcpy(submode, cdrom_get_type_string(toc->tracks[i].pgtype));
+ strcpy(submode, get_type_string(toc.tracks[i].pgtype));
}
- metadata = util::string_format(CDROM_TRACK_METADATA2_FORMAT, i + 1, cdrom_get_type_string(toc->tracks[i].trktype),
- cdrom_get_subtype_string(toc->tracks[i].subtype), toc->tracks[i].frames, toc->tracks[i].pregap,
- submode, cdrom_get_subtype_string(toc->tracks[i].pgsub),
- toc->tracks[i].postgap);
+ metadata = util::string_format(CDROM_TRACK_METADATA2_FORMAT, i + 1, get_type_string(toc.tracks[i].trktype),
+ get_subtype_string(toc.tracks[i].subtype), toc.tracks[i].frames, toc.tracks[i].pregap,
+ submode, get_subtype_string(toc.tracks[i].pgsub),
+ toc.tracks[i].postgap);
err = chd->write_metadata(CDROM_TRACK_METADATA2_TAG, i, metadata);
}
else
{
- metadata = util::string_format(GDROM_TRACK_METADATA_FORMAT, i + 1, cdrom_get_type_string(toc->tracks[i].trktype),
- cdrom_get_subtype_string(toc->tracks[i].subtype), toc->tracks[i].frames, toc->tracks[i].padframes,
- toc->tracks[i].pregap, cdrom_get_type_string(toc->tracks[i].pgtype),
- cdrom_get_subtype_string(toc->tracks[i].pgsub), toc->tracks[i].postgap);
+ metadata = util::string_format(GDROM_TRACK_METADATA_FORMAT, i + 1, get_type_string(toc.tracks[i].trktype),
+ get_subtype_string(toc.tracks[i].subtype), toc.tracks[i].frames, toc.tracks[i].padframes,
+ toc.tracks[i].pregap, get_type_string(toc.tracks[i].pgtype),
+ get_subtype_string(toc.tracks[i].pgsub), toc.tracks[i].postgap);
err = chd->write_metadata(GDROM_TRACK_METADATA_TAG, i, metadata);
}
@@ -1384,7 +1103,7 @@ std::error_condition cdrom_write_metadata(chd_file *chd, const cdrom_toc *toc)
* -------------------------------------------------.
*/
-static const uint8_t ecclow[256] =
+const uint8_t cdrom_file::ecclow[256] =
{
0x00, 0x02, 0x04, 0x06, 0x08, 0x0a, 0x0c, 0x0e, 0x10, 0x12, 0x14, 0x16, 0x18, 0x1a, 0x1c, 0x1e,
0x20, 0x22, 0x24, 0x26, 0x28, 0x2a, 0x2c, 0x2e, 0x30, 0x32, 0x34, 0x36, 0x38, 0x3a, 0x3c, 0x3e,
@@ -1405,7 +1124,7 @@ static const uint8_t ecclow[256] =
};
/** @brief The ecchigh[ 256]. */
-static const uint8_t ecchigh[256] =
+const uint8_t cdrom_file::ecchigh[256] =
{
0x00, 0xf4, 0xf5, 0x01, 0xf7, 0x03, 0x02, 0xf6, 0xf3, 0x07, 0x06, 0xf2, 0x04, 0xf0, 0xf1, 0x05,
0xfb, 0x0f, 0x0e, 0xfa, 0x0c, 0xf8, 0xf9, 0x0d, 0x08, 0xfc, 0xfd, 0x09, 0xff, 0x0b, 0x0a, 0xfe,
@@ -1432,7 +1151,7 @@ static const uint8_t ecchigh[256] =
* -------------------------------------------------.
*/
-static const uint16_t poffsets[ECC_P_NUM_BYTES][ECC_P_COMP] =
+const uint16_t cdrom_file::poffsets[cdrom_file::ECC_P_NUM_BYTES][cdrom_file::ECC_P_COMP] =
{
{ 0x000,0x056,0x0ac,0x102,0x158,0x1ae,0x204,0x25a,0x2b0,0x306,0x35c,0x3b2,0x408,0x45e,0x4b4,0x50a,0x560,0x5b6,0x60c,0x662,0x6b8,0x70e,0x764,0x7ba },
{ 0x001,0x057,0x0ad,0x103,0x159,0x1af,0x205,0x25b,0x2b1,0x307,0x35d,0x3b3,0x409,0x45f,0x4b5,0x50b,0x561,0x5b7,0x60d,0x663,0x6b9,0x70f,0x765,0x7bb },
@@ -1529,7 +1248,7 @@ static const uint16_t poffsets[ECC_P_NUM_BYTES][ECC_P_COMP] =
* -------------------------------------------------.
*/
-static const uint16_t qoffsets[ECC_Q_NUM_BYTES][ECC_Q_COMP] =
+const uint16_t cdrom_file::qoffsets[ECC_Q_NUM_BYTES][ECC_Q_COMP] =
{
{ 0x000,0x058,0x0b0,0x108,0x160,0x1b8,0x210,0x268,0x2c0,0x318,0x370,0x3c8,0x420,0x478,0x4d0,0x528,0x580,0x5d8,0x630,0x688,0x6e0,0x738,0x790,0x7e8,0x840,0x898,0x034,0x08c,0x0e4,0x13c,0x194,0x1ec,0x244,0x29c,0x2f4,0x34c,0x3a4,0x3fc,0x454,0x4ac,0x504,0x55c,0x5b4 },
{ 0x001,0x059,0x0b1,0x109,0x161,0x1b9,0x211,0x269,0x2c1,0x319,0x371,0x3c9,0x421,0x479,0x4d1,0x529,0x581,0x5d9,0x631,0x689,0x6e1,0x739,0x791,0x7e9,0x841,0x899,0x035,0x08d,0x0e5,0x13d,0x195,0x1ed,0x245,0x29d,0x2f5,0x34d,0x3a5,0x3fd,0x455,0x4ad,0x505,0x55d,0x5b5 },
@@ -1592,7 +1311,7 @@ static const uint16_t qoffsets[ECC_Q_NUM_BYTES][ECC_Q_COMP] =
// particular to a mode
//-------------------------------------------------
-inline uint8_t ecc_source_byte(const uint8_t *sector, uint32_t offset)
+uint8_t cdrom_file::ecc_source_byte(const uint8_t *sector, uint32_t offset)
{
// in mode 2 always treat these as 0 bytes
return (sector[MODE_OFFSET] == 2 && offset < 4) ? 0x00 : sector[SYNC_OFFSET + SYNC_NUM_BYTES + offset];
@@ -1612,7 +1331,7 @@ inline uint8_t ecc_source_byte(const uint8_t *sector, uint32_t offset)
* @param [in,out] val2 The second value.
*/
-void ecc_compute_bytes(const uint8_t *sector, const uint16_t *row, int rowlen, uint8_t &val1, uint8_t &val2)
+void cdrom_file::ecc_compute_bytes(const uint8_t *sector, const uint16_t *row, int rowlen, uint8_t &val1, uint8_t &val2)
{
val1 = val2 = 0;
for (int component = 0; component < rowlen; component++)
@@ -1637,7 +1356,7 @@ void ecc_compute_bytes(const uint8_t *sector, const uint16_t *row, int rowlen, u
* @return true if it succeeds, false if it fails.
*/
-bool ecc_verify(const uint8_t *sector)
+bool cdrom_file::ecc_verify(const uint8_t *sector)
{
// first verify P bytes
for (int byte = 0; byte < ECC_P_NUM_BYTES; byte++)
@@ -1670,7 +1389,7 @@ bool ecc_verify(const uint8_t *sector)
* @param [in,out] sector If non-null, the sector.
*/
-void ecc_generate(uint8_t *sector)
+void cdrom_file::ecc_generate(uint8_t *sector)
{
// first verify P bytes
for (int byte = 0; byte < ECC_P_NUM_BYTES; byte++)
@@ -1691,8 +1410,1822 @@ void ecc_generate(uint8_t *sector)
* @param [in,out] sector If non-null, the sector.
*/
-void ecc_clear(uint8_t *sector)
+void cdrom_file::ecc_clear(uint8_t *sector)
{
memset(&sector[ECC_P_OFFSET], 0, 2 * ECC_P_NUM_BYTES);
memset(&sector[ECC_Q_OFFSET], 0, 2 * ECC_Q_NUM_BYTES);
}
+
+/***************************************************************************
+
+ TOC parser
+ Handles CDRDAO .toc, CDRWIN .cue, Nero .nrg, and Sega GDROM .gdi
+
+***************************************************************************/
+
+/***************************************************************************
+ CONSTANTS & DEFINES
+***************************************************************************/
+
+/**
+ * @def TOKENIZE();
+ *
+ * @brief A macro that defines tokenize.
+ *
+ * @param linebuffer The linebuffer.
+ * @param i Zero-based index of the.
+ * @param sizeof(linebuffer) The sizeof(linebuffer)
+ * @param token The token.
+ * @param sizeof(token) The sizeof(token)
+ */
+
+#define TOKENIZE i = tokenize( linebuffer, i, sizeof(linebuffer), token, sizeof(token) );
+
+
+/***************************************************************************
+ IMPLEMENTATION
+***************************************************************************/
+
+/**
+ * @fn std::string get_file_path(std::string &path)
+ *
+ * @brief Gets file path.
+ *
+ * @param [in,out] path Full pathname of the file.
+ *
+ * @return The file path.
+ */
+
+std::string cdrom_file::get_file_path(std::string &path)
+{
+ int pos = path.find_last_of('\\');
+ if (pos!=-1) {
+ path = path.substr(0,pos+1);
+ } else {
+ pos = path.find_last_of('/');
+ path = path.substr(0,pos+1);
+ }
+ return path;
+}
+/*-------------------------------------------------
+ get_file_size - get the size of a file
+-------------------------------------------------*/
+
+/**
+ * @fn static uint64_t get_file_size(const char *filename)
+ *
+ * @brief Gets file size.
+ *
+ * @param filename Filename of the file.
+ *
+ * @return The file size.
+ */
+
+uint64_t cdrom_file::get_file_size(const char *filename)
+{
+ osd_file::ptr file;
+ std::uint64_t filesize = 0;
+
+ osd_file::open(filename, OPEN_FLAG_READ, file, filesize);
+
+ return filesize;
+}
+
+
+/*-------------------------------------------------
+ tokenize - get a token from the line buffer
+-------------------------------------------------*/
+
+/**
+ * @fn static int tokenize( const char *linebuffer, int i, int linebuffersize, char *token, int tokensize )
+ *
+ * @brief Tokenizes.
+ *
+ * @param linebuffer The linebuffer.
+ * @param i Zero-based index of the.
+ * @param linebuffersize The linebuffersize.
+ * @param [in,out] token If non-null, the token.
+ * @param tokensize The tokensize.
+ *
+ * @return An int.
+ */
+
+int cdrom_file::tokenize( const char *linebuffer, int i, int linebuffersize, char *token, int tokensize )
+{
+ int j = 0;
+ int singlequote = 0;
+ int doublequote = 0;
+
+ while ((i < linebuffersize) && isspace((uint8_t)linebuffer[i]))
+ {
+ i++;
+ }
+
+ while ((i < linebuffersize) && (j < tokensize))
+ {
+ if (!singlequote && linebuffer[i] == '"' )
+ {
+ doublequote = !doublequote;
+ }
+ else if (!doublequote && linebuffer[i] == '\'')
+ {
+ singlequote = !singlequote;
+ }
+ else if (!singlequote && !doublequote && isspace((uint8_t)linebuffer[i]))
+ {
+ break;
+ }
+ else
+ {
+ token[j] = linebuffer[i];
+ j++;
+ }
+
+ i++;
+ }
+
+ token[j] = '\0';
+
+ return i;
+}
+
+
+/*-------------------------------------------------
+ msf_to_frames - convert m:s:f into a number of frames
+-------------------------------------------------*/
+
+/**
+ * @fn static int msf_to_frames( char *token )
+ *
+ * @brief Msf to frames.
+ *
+ * @param [in,out] token If non-null, the token.
+ *
+ * @return An int.
+ */
+
+int cdrom_file::msf_to_frames( char *token )
+{
+ int m = 0;
+ int s = 0;
+ int f = 0;
+
+ if( sscanf( token, "%d:%d:%d", &m, &s, &f ) == 1 )
+ {
+ f = m;
+ }
+ else
+ {
+ /* convert to just frames */
+ s += (m * 60);
+ f += (s * 75);
+ }
+
+ return f;
+}
+
+/*-------------------------------------------------
+ parse_wav_sample - takes a .WAV file, verifies
+ that the file is 16 bits, and returns the
+ length in bytes of the data and the offset in
+ bytes to where the data starts in the file.
+-------------------------------------------------*/
+
+/**
+ * @fn static uint32_t parse_wav_sample(const char *filename, uint32_t *dataoffs)
+ *
+ * @brief Parse WAV sample.
+ *
+ * @param filename Filename of the file.
+ * @param [in,out] dataoffs If non-null, the dataoffs.
+ *
+ * @return An uint32_t.
+ */
+
+uint32_t cdrom_file::parse_wav_sample(const char *filename, uint32_t *dataoffs)
+{
+ unsigned long offset = 0;
+ uint32_t length, rate, filesize;
+ uint16_t bits, temp16;
+ char buf[32];
+ osd_file::ptr file;
+ uint64_t fsize = 0;
+ std::uint32_t actual;
+
+ std::error_condition const filerr = osd_file::open(filename, OPEN_FLAG_READ, file, fsize);
+ if (filerr)
+ {
+ printf("ERROR: could not open (%s)\n", filename);
+ return 0;
+ }
+
+ /* read the core header and make sure it's a WAVE file */
+ file->read(buf, 0, 4, actual);
+ offset += actual;
+ if (offset < 4)
+ {
+ printf("ERROR: unexpected RIFF offset %lu (%s)\n", offset, filename);
+ return 0;
+ }
+ if (memcmp(&buf[0], "RIFF", 4) != 0)
+ {
+ printf("ERROR: could not find RIFF header (%s)\n", filename);
+ return 0;
+ }
+
+ /* get the total size */
+ file->read(&filesize, offset, 4, actual);
+ offset += actual;
+ if (offset < 8)
+ {
+ printf("ERROR: unexpected size offset %lu (%s)\n", offset, filename);
+ return 0;
+ }
+ filesize = little_endianize_int32(filesize);
+
+ /* read the RIFF file type and make sure it's a WAVE file */
+ file->read(buf, offset, 4, actual);
+ offset += actual;
+ if (offset < 12)
+ {
+ printf("ERROR: unexpected WAVE offset %lu (%s)\n", offset, filename);
+ return 0;
+ }
+ if (memcmp(&buf[0], "WAVE", 4) != 0)
+ {
+ printf("ERROR: could not find WAVE header (%s)\n", filename);
+ return 0;
+ }
+
+ /* seek until we find a format tag */
+ while (true)
+ {
+ file->read(buf, offset, 4, actual);
+ offset += actual;
+ file->read(&length, offset, 4, actual);
+ offset += actual;
+ length = little_endianize_int32(length);
+ if (memcmp(&buf[0], "fmt ", 4) == 0)
+ break;
+
+ /* seek to the next block */
+ offset += length;
+ if (offset >= filesize)
+ {
+ printf("ERROR: could not find fmt tag (%s)\n", filename);
+ return 0;
+ }
+ }
+
+ /* read the format -- make sure it is PCM */
+ file->read(&temp16, offset, 2, actual);
+ offset += actual;
+ temp16 = little_endianize_int16(temp16);
+ if (temp16 != 1)
+ {
+ printf("ERROR: unsupported format %u - only PCM is supported (%s)\n", temp16, filename);
+ return 0;
+ }
+
+ /* number of channels -- only stereo is supported */
+ file->read(&temp16, offset, 2, actual);
+ offset += actual;
+ temp16 = little_endianize_int16(temp16);
+ if (temp16 != 2)
+ {
+ printf("ERROR: unsupported number of channels %u - only stereo is supported (%s)\n", temp16, filename);
+ return 0;
+ }
+
+ /* sample rate */
+ file->read(&rate, offset, 4, actual);
+ offset += actual;
+ rate = little_endianize_int32(rate);
+ if (rate != 44100)
+ {
+ printf("ERROR: unsupported samplerate %u - only 44100 is supported (%s)\n", rate, filename);
+ return 0;
+ }
+
+ /* bytes/second and block alignment are ignored */
+ file->read(buf, offset, 6, actual);
+ offset += actual;
+
+ /* bits/sample */
+ file->read(&bits, offset, 2, actual);
+ offset += actual;
+ bits = little_endianize_int16(bits);
+ if (bits != 16)
+ {
+ printf("ERROR: unsupported bits/sample %u - only 16 is supported (%s)\n", bits, filename);
+ return 0;
+ }
+
+ /* seek past any extra data */
+ offset += length - 16;
+
+ /* seek until we find a data tag */
+ while (true)
+ {
+ file->read(buf, offset, 4, actual);
+ offset += actual;
+ file->read(&length, offset, 4, actual);
+ offset += actual;
+ length = little_endianize_int32(length);
+ if (memcmp(&buf[0], "data", 4) == 0)
+ break;
+
+ /* seek to the next block */
+ offset += length;
+ if (offset >= filesize)
+ {
+ printf("ERROR: could not find data tag (%s)\n", filename);
+ return 0;
+ }
+ }
+
+ /* if there was a 0 length data block, we're done */
+ if (length == 0)
+ {
+ printf("ERROR: empty data block (%s)\n", filename);
+ return 0;
+ }
+
+ *dataoffs = offset;
+
+ return length;
+}
+
+/**
+ * @fn uint16_t read_uint16(FILE *infile)
+ *
+ * @brief Reads uint 16.
+ *
+ * @param [in,out] infile If non-null, the infile.
+ *
+ * @return The uint 16.
+ */
+
+uint16_t cdrom_file::read_uint16(FILE *infile)
+{
+ uint16_t res = 0;
+ unsigned char buffer[2];
+
+ fread(buffer, 2, 1, infile);
+
+ res = buffer[1] | buffer[0]<<8;
+
+ return res;
+}
+
+/**
+ * @fn uint32_t read_uint32(FILE *infile)
+ *
+ * @brief Reads uint 32.
+ *
+ * @param [in,out] infile If non-null, the infile.
+ *
+ * @return The uint 32.
+ */
+
+uint32_t cdrom_file::read_uint32(FILE *infile)
+{
+ uint32_t res = 0;
+ unsigned char buffer[4];
+
+ fread(buffer, 4, 1, infile);
+
+ res = buffer[3] | buffer[2]<<8 | buffer[1]<<16 | buffer[0]<<24;
+
+ return res;
+}
+
+/**
+ * @fn uint64_t read_uint64(FILE *infile)
+ *
+ * @brief Reads uint 64.
+ *
+ * @param [in,out] infile If non-null, the infile.
+ *
+ * @return The uint 64.
+ */
+
+uint64_t cdrom_file::read_uint64(FILE *infile)
+{
+ uint64_t res0(0), res1(0);
+ uint64_t res;
+ unsigned char buffer[8];
+
+ fread(buffer, 8, 1, infile);
+
+ res0 = buffer[3] | buffer[2]<<8 | buffer[1]<<16 | buffer[0]<<24;
+ res1 = buffer[7] | buffer[6]<<8 | buffer[5]<<16 | buffer[4]<<24;
+
+ res = res0<<32 | res1;
+
+ return res;
+}
+
+/*-------------------------------------------------
+ parse_nero - parse a Nero .NRG file
+-------------------------------------------------*/
+
+/**
+ * @fn std::error_condition parse_nero(const char *tocfname, toc &outtoc, track_input_info &outinfo)
+ *
+ * @brief Chdcd parse nero.
+ *
+ * @param tocfname The tocfname.
+ * @param [in,out] outtoc The outtoc.
+ * @param [in,out] outinfo The outinfo.
+ *
+ * @return A std::error_condition.
+ */
+
+std::error_condition cdrom_file::parse_nero(const char *tocfname, toc &outtoc, track_input_info &outinfo)
+{
+ unsigned char buffer[12];
+ uint32_t chain_offs, chunk_size;
+ int done = 0;
+
+ std::string path = std::string(tocfname);
+
+ FILE *infile = fopen(tocfname, "rb");
+ if (!infile)
+ {
+ return std::error_condition(errno, std::generic_category());
+ }
+
+ path = get_file_path(path);
+
+ /* clear structures */
+ memset(&outtoc, 0, sizeof(outtoc));
+ outinfo.reset();
+
+ // seek to 12 bytes before the end
+ fseek(infile, -12, SEEK_END);
+ fread(buffer, 12, 1, infile);
+
+ if (memcmp(buffer, "NER5", 4))
+ {
+ printf("ERROR: Not a Nero 5.5 or later image!\n");
+ fclose(infile);
+ return chd_file::error::UNSUPPORTED_FORMAT;
+ }
+
+ chain_offs = buffer[11] | (buffer[10]<<8) | (buffer[9]<<16) | (buffer[8]<<24);
+
+ if ((buffer[7] != 0) || (buffer[6] != 0) || (buffer[5] != 0) || (buffer[4] != 0))
+ {
+ printf("ERROR: File size is > 4GB, this version of CHDMAN cannot handle it.");
+ fclose(infile);
+ return chd_file::error::UNSUPPORTED_FORMAT;
+ }
+
+// printf("NER5 detected, chain offset: %x\n", chain_offs);
+
+ while (!done)
+ {
+ uint32_t offset;
+ uint8_t start, end;
+ int track;
+
+ fseek(infile, chain_offs, SEEK_SET);
+ fread(buffer, 8, 1, infile);
+
+ chunk_size = (buffer[7] | buffer[6]<<8 | buffer[5]<<16 | buffer[4]<<24);
+
+// printf("Chunk type: %c%c%c%c, size %x\n", buffer[0], buffer[1], buffer[2], buffer[3], chunk_size);
+
+ // we want the DAOX chunk, which has the TOC information
+ if (!memcmp(buffer, "DAOX", 4))
+ {
+ // skip second chunk size and UPC code
+ fseek(infile, 20, SEEK_CUR);
+
+ fread(&start, 1, 1, infile);
+ fread(&end, 1, 1, infile);
+
+// printf("Start track %d End track: %d\n", start, end);
+
+ outtoc.numtrks = (end-start) + 1;
+
+ offset = 0;
+ for (track = start; track <= end; track++)
+ {
+ uint32_t size, mode;
+ uint64_t index0, index1, track_end;
+
+ fseek(infile, 12, SEEK_CUR); // skip ISRC code
+ size = read_uint16(infile);
+ mode = read_uint16(infile);
+ fseek(infile, 2, SEEK_CUR);
+ index0 = read_uint64(infile);
+ index1 = read_uint64(infile);
+ track_end = read_uint64(infile);
+
+// printf("Track %d: sector size %d mode %x index0 %llx index1 %llx track_end %llx (pregap %d sectors, length %d sectors)\n", track, size, mode, index0, index1, track_end, (uint32_t)(index1-index0)/size, (uint32_t)(track_end-index1)/size);
+ outinfo.track[track-1].fname.assign(tocfname);
+ outinfo.track[track-1].offset = offset + (uint32_t)(index1-index0);
+ outinfo.track[track-1].idx0offs = 0;
+ outinfo.track[track-1].idx1offs = 0;
+
+ switch (mode)
+ {
+ case 0x0000: // 2048 byte data
+ outtoc.tracks[track-1].trktype = CD_TRACK_MODE1;
+ outinfo.track[track-1].swap = false;
+ break;
+
+ case 0x0300: // Mode 2 Form 1
+ printf("ERROR: Mode 2 Form 1 tracks not supported\n");
+ fclose(infile);
+ return chd_file::error::UNSUPPORTED_FORMAT;
+
+ case 0x0500: // raw data
+ printf("ERROR: Raw data tracks not supported\n");
+ fclose(infile);
+ return chd_file::error::UNSUPPORTED_FORMAT;
+
+ case 0x0600: // 2352 byte mode 2 raw
+ outtoc.tracks[track-1].trktype = CD_TRACK_MODE2_RAW;
+ outinfo.track[track-1].swap = false;
+ break;
+
+ case 0x0700: // 2352 byte audio
+ outtoc.tracks[track-1].trktype = CD_TRACK_AUDIO;
+ outinfo.track[track-1].swap = true;
+ break;
+
+ case 0x0f00: // raw data with sub-channel
+ printf("ERROR: Raw data tracks with sub-channel not supported\n");
+ fclose(infile);
+ return chd_file::error::UNSUPPORTED_FORMAT;
+
+ case 0x1000: // audio with sub-channel
+ printf("ERROR: Audio tracks with sub-channel not supported\n");
+ fclose(infile);
+ return chd_file::error::UNSUPPORTED_FORMAT;
+
+ case 0x1100: // raw Mode 2 Form 1 with sub-channel
+ printf("ERROR: Raw Mode 2 Form 1 tracks with sub-channel not supported\n");
+ fclose(infile);
+ return chd_file::error::UNSUPPORTED_FORMAT;
+
+ default:
+ printf("ERROR: Unknown track type %x, contact MAMEDEV!\n", mode);
+ fclose(infile);
+ return chd_file::error::UNSUPPORTED_FORMAT;
+ }
+
+ outtoc.tracks[track-1].datasize = size;
+
+ outtoc.tracks[track-1].subtype = CD_SUB_NONE;
+ outtoc.tracks[track-1].subsize = 0;
+
+ outtoc.tracks[track-1].pregap = (uint32_t)(index1-index0)/size;
+ outtoc.tracks[track-1].frames = (uint32_t)(track_end-index1)/size;
+ outtoc.tracks[track-1].postgap = 0;
+ outtoc.tracks[track-1].pgtype = 0;
+ outtoc.tracks[track-1].pgsub = CD_SUB_NONE;
+ outtoc.tracks[track-1].pgdatasize = 0;
+ outtoc.tracks[track-1].pgsubsize = 0;
+ outtoc.tracks[track-1].padframes = 0;
+
+ offset += (uint32_t)track_end-index1;
+ }
+ }
+
+ if (!memcmp(buffer, "END!", 4))
+ {
+ done = 1;
+ }
+ else
+ {
+ chain_offs += chunk_size + 8;
+ }
+ }
+
+ fclose(infile);
+
+ return std::error_condition();
+}
+
+/*-------------------------------------------------
+ parse_iso - parse a .ISO file
+-------------------------------------------------*/
+
+/**
+ * @fn std::error_condition parse_iso(const char *tocfname, toc &outtoc, track_input_info &outinfo)
+ *
+ * @brief Parse ISO.
+ *
+ * @param tocfname The tocfname.
+ * @param [in,out] outtoc The outtoc.
+ * @param [in,out] outinfo The outinfo.
+ *
+ * @return A std::error_condition.
+ */
+
+std::error_condition cdrom_file::parse_iso(const char *tocfname, toc &outtoc, track_input_info &outinfo)
+{
+ std::string path = std::string(tocfname);
+
+ FILE *infile = fopen(tocfname, "rb");
+ if (!infile)
+ {
+ return std::error_condition(errno, std::generic_category());
+ }
+
+ path = get_file_path(path);
+
+ /* clear structures */
+ memset(&outtoc, 0, sizeof(outtoc));
+ outinfo.reset();
+
+ uint64_t size = get_file_size(tocfname);
+ fclose(infile);
+
+
+ outtoc.numtrks = 1;
+
+ outinfo.track[0].fname = tocfname;
+ outinfo.track[0].offset = 0;
+ outinfo.track[0].idx0offs = 0;
+ outinfo.track[0].idx1offs = 0;
+
+ if ((size % 2048)==0 ) {
+ outtoc.tracks[0].trktype = CD_TRACK_MODE1;
+ outtoc.tracks[0].frames = size / 2048;
+ outtoc.tracks[0].datasize = 2048;
+ outinfo.track[0].swap = false;
+ } else if ((size % 2336)==0 ) {
+ // 2352 byte mode 2
+ outtoc.tracks[0].trktype = CD_TRACK_MODE2;
+ outtoc.tracks[0].frames = size / 2336;
+ outtoc.tracks[0].datasize = 2336;
+ outinfo.track[0].swap = false;
+ } else if ((size % 2352)==0 ) {
+ // 2352 byte mode 2 raw
+ outtoc.tracks[0].trktype = CD_TRACK_MODE2_RAW;
+ outtoc.tracks[0].frames = size / 2352;
+ outtoc.tracks[0].datasize = 2352;
+ outinfo.track[0].swap = false;
+ } else {
+ printf("ERROR: Unrecognized track type\n");
+ return chd_file::error::UNSUPPORTED_FORMAT;
+ }
+
+ outtoc.tracks[0].subtype = CD_SUB_NONE;
+ outtoc.tracks[0].subsize = 0;
+
+ outtoc.tracks[0].pregap = 0;
+
+ outtoc.tracks[0].postgap = 0;
+ outtoc.tracks[0].pgtype = 0;
+ outtoc.tracks[0].pgsub = CD_SUB_NONE;
+ outtoc.tracks[0].pgdatasize = 0;
+ outtoc.tracks[0].pgsubsize = 0;
+ outtoc.tracks[0].padframes = 0;
+
+
+ return std::error_condition();
+}
+
+/*-------------------------------------------------
+ parse_gdi - parse a Sega GD-ROM rip
+-------------------------------------------------*/
+
+/**
+ * @fn static std::error_condition parse_gdi(const char *tocfname, toc &outtoc, track_input_info &outinfo)
+ *
+ * @brief Chdcd parse GDI.
+ *
+ * @param tocfname The tocfname.
+ * @param [in,out] outtoc The outtoc.
+ * @param [in,out] outinfo The outinfo.
+ *
+ * @return A std::error_condition.
+ */
+
+std::error_condition cdrom_file::parse_gdi(const char *tocfname, toc &outtoc, track_input_info &outinfo)
+{
+ int i, numtracks;
+
+ std::string path = std::string(tocfname);
+
+ FILE *infile = fopen(tocfname, "rt");
+ if (!infile)
+ {
+ return std::error_condition(errno, std::generic_category());
+ }
+
+ path = get_file_path(path);
+
+ /* clear structures */
+ memset(&outtoc, 0, sizeof(outtoc));
+ outinfo.reset();
+
+ outtoc.flags = CD_FLAG_GDROM;
+
+ char linebuffer[512];
+ fgets(linebuffer,511,infile);
+ numtracks=atoi(linebuffer);
+
+ for(i=0;i<numtracks;++i)
+ {
+ char *tok;
+ int trknum;
+ int trksize,trktype;
+ int sz;
+
+ fgets(linebuffer,511,infile);
+
+ tok=strtok(linebuffer," ");
+
+ trknum=atoi(tok)-1;
+
+ outinfo.track[trknum].swap=false;
+ outinfo.track[trknum].offset=0;
+
+ outtoc.tracks[trknum].datasize = 0;
+ outtoc.tracks[trknum].subtype = CD_SUB_NONE;
+ outtoc.tracks[trknum].subsize = 0;
+ outtoc.tracks[trknum].pgsub = CD_SUB_NONE;
+
+ tok=strtok(nullptr," ");
+ outtoc.tracks[trknum].physframeofs=atoi(tok);
+
+ tok=strtok(nullptr," ");
+ trktype=atoi(tok);
+
+ tok=strtok(nullptr," ");
+ trksize=atoi(tok);
+
+ if(trktype==4 && trksize==2352)
+ {
+ outtoc.tracks[trknum].trktype=CD_TRACK_MODE1_RAW;
+ outtoc.tracks[trknum].datasize=2352;
+ }
+ if(trktype==4 && trksize==2048)
+ {
+ outtoc.tracks[trknum].trktype=CD_TRACK_MODE1;
+ outtoc.tracks[trknum].datasize=2048;
+ }
+ if(trktype==0)
+ {
+ outtoc.tracks[trknum].trktype=CD_TRACK_AUDIO;
+ outtoc.tracks[trknum].datasize=2352;
+ outinfo.track[trknum].swap = true;
+ }
+
+ std::string name;
+
+ tok=strtok(nullptr," ");
+ name = tok;
+ if (tok[0]=='"') {
+ do {
+ tok=strtok(nullptr," ");
+ if (tok!=nullptr) {
+ name += " ";
+ name += tok;
+ }
+ } while(tok!=nullptr && (strrchr(tok,'"')-tok !=(strlen(tok)-1)));
+ strdelchr(name,'"');
+ }
+ outinfo.track[trknum].fname.assign(path).append(name);
+
+ sz = get_file_size(outinfo.track[trknum].fname.c_str());
+
+ outtoc.tracks[trknum].frames = sz/trksize;
+ outtoc.tracks[trknum].padframes = 0;
+
+ if (trknum != 0)
+ {
+ int dif=outtoc.tracks[trknum].physframeofs-(outtoc.tracks[trknum-1].frames+outtoc.tracks[trknum-1].physframeofs);
+ outtoc.tracks[trknum-1].frames += dif;
+ outtoc.tracks[trknum-1].padframes = dif;
+ }
+ }
+
+ #if 0
+ for(i=0; i < numtracks; i++)
+ {
+ printf("%s %d %d %d (true %d)\n", outinfo.track[i].fname.c_str(), outtoc.tracks[i].frames, outtoc.tracks[i].padframes, outtoc.tracks[i].physframeofs, outtoc.tracks[i].frames - outtoc.tracks[i].padframes);
+ }
+ #endif
+
+ /* close the input TOC */
+ fclose(infile);
+
+ /* store the number of tracks found */
+ outtoc.numtrks = numtracks;
+
+ return std::error_condition();
+}
+
+/*-------------------------------------------------
+ parse_cue - parse a CDRWin format CUE file
+-------------------------------------------------*/
+
+/**
+ * @fn std::error_condition parse_cue(const char *tocfname, toc &outtoc, track_input_info &outinfo)
+ *
+ * @brief Chdcd parse cue.
+ *
+ * @param tocfname The tocfname.
+ * @param [in,out] outtoc The outtoc.
+ * @param [in,out] outinfo The outinfo.
+ *
+ * @return A std::error_condition.
+ */
+
+std::error_condition cdrom_file::parse_cue(const char *tocfname, toc &outtoc, track_input_info &outinfo)
+{
+ int i, trknum;
+ static char token[512];
+ std::string lastfname;
+ uint32_t wavlen, wavoffs;
+ std::string path = std::string(tocfname);
+
+ FILE *infile = fopen(tocfname, "rt");
+ if (!infile)
+ {
+ return std::error_condition(errno, std::generic_category());
+ }
+
+ path = get_file_path(path);
+
+ /* clear structures */
+ memset(&outtoc, 0, sizeof(outtoc));
+ outinfo.reset();
+
+ trknum = -1;
+ wavoffs = wavlen = 0;
+
+ char linebuffer[512];
+ while (!feof(infile))
+ {
+ /* get the next line */
+ fgets(linebuffer, 511, infile);
+
+ /* if EOF didn't hit, keep going */
+ if (!feof(infile))
+ {
+ i = 0;
+
+ TOKENIZE
+
+ if (!strcmp(token, "FILE"))
+ {
+ /* found the data file for a track */
+ TOKENIZE
+
+ /* keep the filename */
+ lastfname.assign(path).append(token);
+
+ /* get the file type */
+ TOKENIZE
+
+ if (!strcmp(token, "BINARY"))
+ {
+ outinfo.track[trknum+1].swap = false;
+ }
+ else if (!strcmp(token, "MOTOROLA"))
+ {
+ outinfo.track[trknum+1].swap = true;
+ }
+ else if (!strcmp(token, "WAVE"))
+ {
+ wavlen = parse_wav_sample(lastfname.c_str(), &wavoffs);
+ if (!wavlen)
+ {
+ fclose(infile);
+ printf("ERROR: couldn't read [%s] or not a valid .WAV\n", lastfname.c_str());
+ return chd_file::error::INVALID_DATA;
+ }
+ }
+ else
+ {
+ fclose(infile);
+ printf("ERROR: Unhandled track type %s\n", token);
+ return chd_file::error::UNSUPPORTED_FORMAT;
+ }
+ }
+ else if (!strcmp(token, "TRACK"))
+ {
+ /* get the track number */
+ TOKENIZE
+ trknum = strtoul(token, nullptr, 10) - 1;
+
+ /* next token on the line is the track type */
+ TOKENIZE
+
+ if (wavlen != 0)
+ {
+ outtoc.tracks[trknum].trktype = CD_TRACK_AUDIO;
+ outtoc.tracks[trknum].frames = wavlen/2352;
+ outinfo.track[trknum].offset = wavoffs;
+ wavoffs = wavlen = 0;
+ }
+ else
+ {
+ outtoc.tracks[trknum].trktype = CD_TRACK_MODE1;
+ outtoc.tracks[trknum].datasize = 0;
+ outinfo.track[trknum].offset = 0;
+ }
+ outtoc.tracks[trknum].subtype = CD_SUB_NONE;
+ outtoc.tracks[trknum].subsize = 0;
+ outtoc.tracks[trknum].pgsub = CD_SUB_NONE;
+ outtoc.tracks[trknum].pregap = 0;
+ outtoc.tracks[trknum].padframes = 0;
+ outinfo.track[trknum].idx0offs = -1;
+ outinfo.track[trknum].idx1offs = 0;
+
+ outinfo.track[trknum].fname.assign(lastfname); // default filename to the last one
+
+// printf("trk %d: fname %s offset %d\n", trknum, outinfo.track[trknum].fname.c_str(), outinfo.track[trknum].offset);
+
+ convert_type_string_to_track_info(token, &outtoc.tracks[trknum]);
+ if (outtoc.tracks[trknum].datasize == 0)
+ {
+ fclose(infile);
+ printf("ERROR: Unknown track type [%s]. Contact MAMEDEV.\n", token);
+ return chd_file::error::UNSUPPORTED_FORMAT;
+ }
+
+ /* next (optional) token on the line is the subcode type */
+ TOKENIZE
+
+ convert_subtype_string_to_track_info(token, &outtoc.tracks[trknum]);
+ }
+ else if (!strcmp(token, "INDEX")) /* only in bin/cue files */
+ {
+ int idx, frames;
+
+ /* get index number */
+ TOKENIZE
+ idx = strtoul(token, nullptr, 10);
+
+ /* get index */
+ TOKENIZE
+ frames = msf_to_frames( token );
+
+ if (idx == 0)
+ {
+ outinfo.track[trknum].idx0offs = frames;
+ }
+ else if (idx == 1)
+ {
+ outinfo.track[trknum].idx1offs = frames;
+ if ((outtoc.tracks[trknum].pregap == 0) && (outinfo.track[trknum].idx0offs != -1))
+ {
+ outtoc.tracks[trknum].pregap = frames - outinfo.track[trknum].idx0offs;
+ outtoc.tracks[trknum].pgtype = outtoc.tracks[trknum].trktype;
+ switch (outtoc.tracks[trknum].pgtype)
+ {
+ case CD_TRACK_MODE1:
+ case CD_TRACK_MODE2_FORM1:
+ outtoc.tracks[trknum].pgdatasize = 2048;
+ break;
+
+ case CD_TRACK_MODE1_RAW:
+ case CD_TRACK_MODE2_RAW:
+ case CD_TRACK_AUDIO:
+ outtoc.tracks[trknum].pgdatasize = 2352;
+ break;
+
+ case CD_TRACK_MODE2:
+ case CD_TRACK_MODE2_FORM_MIX:
+ outtoc.tracks[trknum].pgdatasize = 2336;
+ break;
+
+ case CD_TRACK_MODE2_FORM2:
+ outtoc.tracks[trknum].pgdatasize = 2324;
+ break;
+ }
+ }
+ else // pregap sectors not in file, but we're always using idx0ofs for track length calc now
+ {
+ outinfo.track[trknum].idx0offs = frames;
+ }
+ }
+ }
+ else if (!strcmp(token, "PREGAP"))
+ {
+ int frames;
+
+ /* get index */
+ TOKENIZE
+ frames = msf_to_frames( token );
+
+ outtoc.tracks[trknum].pregap = frames;
+ }
+ else if (!strcmp(token, "POSTGAP"))
+ {
+ int frames;
+
+ /* get index */
+ TOKENIZE
+ frames = msf_to_frames( token );
+
+ outtoc.tracks[trknum].postgap = frames;
+ }
+ }
+ }
+
+ /* close the input CUE */
+ fclose(infile);
+
+ /* store the number of tracks found */
+ outtoc.numtrks = trknum + 1;
+
+ /* now go over the files again and set the lengths */
+ for (trknum = 0; trknum < outtoc.numtrks; trknum++)
+ {
+ uint64_t tlen = 0;
+
+ // this is true for cue/bin and cue/iso, and we need it for cue/wav since .WAV is little-endian
+ if (outtoc.tracks[trknum].trktype == CD_TRACK_AUDIO)
+ {
+ outinfo.track[trknum].swap = true;
+ }
+
+ // don't do this for .WAV tracks, we already have their length and offset filled out
+ if (outinfo.track[trknum].offset == 0)
+ {
+ // is this the last track?
+ if (trknum == (outtoc.numtrks-1))
+ {
+ /* if we have the same filename as the last track, do it that way */
+ if (trknum != 0 && (outinfo.track[trknum].fname.compare(outinfo.track[trknum-1].fname)==0))
+ {
+ tlen = get_file_size(outinfo.track[trknum].fname.c_str());
+ if (tlen == 0)
+ {
+ printf("ERROR: couldn't find bin file [%s]\n", outinfo.track[trknum-1].fname.c_str());
+ return std::errc::no_such_file_or_directory;
+ }
+ outinfo.track[trknum].offset = outinfo.track[trknum-1].offset + outtoc.tracks[trknum-1].frames * (outtoc.tracks[trknum-1].datasize + outtoc.tracks[trknum-1].subsize);
+ outtoc.tracks[trknum].frames = (tlen - outinfo.track[trknum].offset) / (outtoc.tracks[trknum].datasize + outtoc.tracks[trknum].subsize);
+ }
+ else /* data files are different */
+ {
+ tlen = get_file_size(outinfo.track[trknum].fname.c_str());
+ if (tlen == 0)
+ {
+ printf("ERROR: couldn't find bin file [%s]\n", outinfo.track[trknum-1].fname.c_str());
+ return std::errc::no_such_file_or_directory;
+ }
+ tlen /= (outtoc.tracks[trknum].datasize + outtoc.tracks[trknum].subsize);
+ outtoc.tracks[trknum].frames = tlen;
+ outinfo.track[trknum].offset = 0;
+ }
+ }
+ else
+ {
+ /* if we have the same filename as the next track, do it that way */
+ if (outinfo.track[trknum].fname.compare(outinfo.track[trknum+1].fname)==0)
+ {
+ outtoc.tracks[trknum].frames = outinfo.track[trknum+1].idx0offs - outinfo.track[trknum].idx0offs;
+
+ if (trknum == 0) // track 0 offset is 0
+ {
+ outinfo.track[trknum].offset = 0;
+ }
+ else
+ {
+ outinfo.track[trknum].offset = outinfo.track[trknum-1].offset + outtoc.tracks[trknum-1].frames * (outtoc.tracks[trknum-1].datasize + outtoc.tracks[trknum-1].subsize);
+ }
+
+ if (!outtoc.tracks[trknum].frames)
+ {
+ printf("ERROR: unable to determine size of track %d, missing INDEX 01 markers?\n", trknum+1);
+ return chd_file::error::INVALID_DATA;
+ }
+ }
+ else /* data files are different */
+ {
+ tlen = get_file_size(outinfo.track[trknum].fname.c_str());
+ if (tlen == 0)
+ {
+ printf("ERROR: couldn't find bin file [%s]\n", outinfo.track[trknum].fname.c_str());
+ return std::errc::no_such_file_or_directory;
+ }
+ tlen /= (outtoc.tracks[trknum].datasize + outtoc.tracks[trknum].subsize);
+ outtoc.tracks[trknum].frames = tlen;
+ outinfo.track[trknum].offset = 0;
+ }
+ }
+ }
+ //printf("trk %d: %d frames @ offset %d\n", trknum+1, outtoc.tracks[trknum].frames, outinfo.track[trknum].offset);
+ }
+
+ return std::error_condition();
+}
+
+/*---------------------------------------------------------------------------------------
+ is_gdicue - determine if CUE contains Redump multi-CUE format for Dreamcast GDI
+----------------------------------------------------------------------------------------*/
+
+/**
+ * Dreamcast GDI has two images on one disc, SINGLE-DENSITY and HIGH-DENSITY.
+ *
+ * Redump stores both images in a single .cue with a REM comment separating the images.
+ * This multi-cue format replaces the old flawed .gdi format.
+ *
+ * http://forum.redump.org/topic/19969/done-sega-dreamcast-multicue-gdi/
+ *
+ * This function looks for strings "REM SINGLE-DENSITY AREA" & "REM HIGH-DENSITY AREA"
+ * indicating the Redump multi-cue format and therefore a Dreamcast GDI disc.
+ */
+
+bool cdrom_file::is_gdicue(const char *tocfname)
+{
+ bool has_rem_singledensity = false;
+ bool has_rem_highdensity = false;
+ std::string path = std::string(tocfname);
+
+ FILE *infile = fopen(tocfname, "rt");
+ if (!infile)
+ {
+ return false;
+ }
+
+ path = get_file_path(path);
+
+ char linebuffer[512];
+ while (!feof(infile))
+ {
+ fgets(linebuffer, 511, infile);
+
+ /* if EOF didn't hit, keep going */
+ if (!feof(infile))
+ {
+ has_rem_singledensity = has_rem_singledensity || !strncmp(linebuffer, "REM SINGLE-DENSITY AREA", 23);
+ has_rem_highdensity = has_rem_highdensity || !strncmp(linebuffer, "REM HIGH-DENSITY AREA", 21);
+ }
+ }
+
+ fclose(infile);
+
+ return has_rem_singledensity && has_rem_highdensity;
+}
+
+/*-----------------------------------------------------------------
+ parse_gdicue - parse a Redump multi-CUE for Dreamcast GDI
+------------------------------------------------------------------*/
+
+/**
+ * @fn std::error_condition parse_gdicue(const char *tocfname, toc &outtoc, track_input_info &outinfo)
+ *
+ * @brief Chdcd parse cue.
+ *
+ * @param tocfname The tocfname.
+ * @param [in,out] outtoc The outtoc.
+ * @param [in,out] outinfo The outinfo.
+ *
+ * @return A std::error_condition.
+ *
+ * Dreamcast discs have two images on a single disc. The first image is SINGLE-DENSITY and the second image
+ * is HIGH-DENSITY. The SINGLE-DENSITY area starts 0 LBA and HIGH-DENSITY area starts 45000 LBA.
+ *
+ * There are three Dreamcast disc patterns.
+ *
+ * Pattern I - (SD) DATA + AUDIO, (HD) DATA
+ * Pattern II - (SD) DATA + AUDIO, (HD) DATA + ... + AUDIO
+ * Pattern III - (SD) DATA + AUDIO, (HD) DATA + ... + DATA
+ *
+ * TOSEC layout is preferred and this code adjusts the TOC and INFO generated by a Redump .cue to match the
+ * layout from a TOSEC .gdi.
+ */
+
+std::error_condition cdrom_file::parse_gdicue(const char *tocfname, toc &outtoc, track_input_info &outinfo)
+{
+ int i, trknum;
+ static char token[512];
+ std::string lastfname;
+ uint32_t wavlen, wavoffs;
+ std::string path = std::string(tocfname);
+ enum gdi_area current_area = SINGLE_DENSITY;
+ enum gdi_pattern disc_pattern = TYPE_UNKNOWN;
+
+ FILE *infile = fopen(tocfname, "rt");
+ if (!infile)
+ {
+ return std::error_condition(errno, std::generic_category());
+ }
+
+ path = get_file_path(path);
+
+ /* clear structures */
+ memset(&outtoc, 0, sizeof(outtoc));
+ outinfo.reset();
+
+ trknum = -1;
+ wavoffs = wavlen = 0;
+
+ outtoc.flags = CD_FLAG_GDROM;
+
+ char linebuffer[512];
+ while (!feof(infile))
+ {
+ /* get the next line */
+ fgets(linebuffer, 511, infile);
+
+ /* if EOF didn't hit, keep going */
+ if (!feof(infile))
+ {
+ /* single-density area starts LBA = 0 */
+ if (!strncmp(linebuffer, "REM SINGLE-DENSITY AREA", 23))
+ {
+ current_area = SINGLE_DENSITY;
+ continue;
+ }
+
+ /* high-density area starts LBA = 45000 */
+ if (!strncmp(linebuffer, "REM HIGH-DENSITY AREA", 21))
+ {
+ current_area = HIGH_DENSITY;
+ continue;
+ }
+
+ i = 0;
+
+ TOKENIZE
+
+ if (!strcmp(token, "FILE"))
+ {
+ /* found the data file for a track */
+ TOKENIZE
+
+ /* keep the filename */
+ lastfname.assign(path).append(token);
+
+ /* get the file type */
+ TOKENIZE
+
+ if (!strcmp(token, "BINARY"))
+ {
+ outinfo.track[trknum+1].swap = false;
+ }
+ else if (!strcmp(token, "MOTOROLA"))
+ {
+ outinfo.track[trknum+1].swap = true;
+ }
+ else if (!strcmp(token, "WAVE"))
+ {
+ wavlen = parse_wav_sample(lastfname.c_str(), &wavoffs);
+ if (!wavlen)
+ {
+ fclose(infile);
+ printf("ERROR: couldn't read [%s] or not a valid .WAV\n", lastfname.c_str());
+ return chd_file::error::INVALID_DATA;
+ }
+ }
+ else
+ {
+ fclose(infile);
+ printf("ERROR: Unhandled track type %s\n", token);
+ return chd_file::error::UNSUPPORTED_FORMAT;
+ }
+ }
+ else if (!strcmp(token, "TRACK"))
+ {
+ /* get the track number */
+ TOKENIZE
+ trknum = strtoul(token, nullptr, 10) - 1;
+
+ /* next token on the line is the track type */
+ TOKENIZE
+
+ if (wavlen != 0)
+ {
+ outtoc.tracks[trknum].trktype = CD_TRACK_AUDIO;
+ outtoc.tracks[trknum].frames = wavlen/2352;
+ outinfo.track[trknum].offset = wavoffs;
+ wavoffs = wavlen = 0;
+ }
+ else
+ {
+ outtoc.tracks[trknum].trktype = CD_TRACK_MODE1;
+ outtoc.tracks[trknum].datasize = 0;
+ outinfo.track[trknum].offset = 0;
+ }
+ outtoc.tracks[trknum].subtype = CD_SUB_NONE;
+ outtoc.tracks[trknum].subsize = 0;
+ outtoc.tracks[trknum].pgsub = CD_SUB_NONE;
+ outtoc.tracks[trknum].pregap = 0;
+ outtoc.tracks[trknum].padframes = 0;
+ outtoc.tracks[trknum].multicuearea = current_area;
+ outinfo.track[trknum].idx0offs = -1;
+ outinfo.track[trknum].idx1offs = 0;
+
+ outinfo.track[trknum].fname.assign(lastfname); // default filename to the last one
+
+#if 0
+ printf("trk %d: fname %s offset %d area %d\n", trknum, outinfo.track[trknum].fname.c_str(), outinfo.track[trknum].offset, outtoc.tracks[trknum].multicuearea);
+#endif
+
+ convert_type_string_to_track_info(token, &outtoc.tracks[trknum]);
+ if (outtoc.tracks[trknum].datasize == 0)
+ {
+ fclose(infile);
+ printf("ERROR: Unknown track type [%s]. Contact MAMEDEV.\n", token);
+ return chd_file::error::UNSUPPORTED_FORMAT;
+ }
+
+ /* next (optional) token on the line is the subcode type */
+ TOKENIZE
+
+ convert_subtype_string_to_track_info(token, &outtoc.tracks[trknum]);
+ }
+ else if (!strcmp(token, "INDEX")) /* only in bin/cue files */
+ {
+ int idx, frames;
+
+ /* get index number */
+ TOKENIZE
+ idx = strtoul(token, nullptr, 10);
+
+ /* get index */
+ TOKENIZE
+ frames = msf_to_frames( token );
+
+ if (idx == 0)
+ {
+ outinfo.track[trknum].idx0offs = frames;
+ }
+ else if (idx == 1)
+ {
+ outinfo.track[trknum].idx1offs = frames;
+ if ((outtoc.tracks[trknum].pregap == 0) && (outinfo.track[trknum].idx0offs != -1))
+ {
+ outtoc.tracks[trknum].pregap = frames - outinfo.track[trknum].idx0offs;
+ outtoc.tracks[trknum].pgtype = outtoc.tracks[trknum].trktype;
+ switch (outtoc.tracks[trknum].pgtype)
+ {
+ case CD_TRACK_MODE1:
+ case CD_TRACK_MODE2_FORM1:
+ outtoc.tracks[trknum].pgdatasize = 2048;
+ break;
+
+ case CD_TRACK_MODE1_RAW:
+ case CD_TRACK_MODE2_RAW:
+ case CD_TRACK_AUDIO:
+ outtoc.tracks[trknum].pgdatasize = 2352;
+ break;
+
+ case CD_TRACK_MODE2:
+ case CD_TRACK_MODE2_FORM_MIX:
+ outtoc.tracks[trknum].pgdatasize = 2336;
+ break;
+
+ case CD_TRACK_MODE2_FORM2:
+ outtoc.tracks[trknum].pgdatasize = 2324;
+ break;
+ }
+ }
+ else // pregap sectors not in file, but we're always using idx0ofs for track length calc now
+ {
+ outinfo.track[trknum].idx0offs = frames;
+ }
+ }
+ }
+ else if (!strcmp(token, "PREGAP"))
+ {
+ int frames;
+
+ /* get index */
+ TOKENIZE
+ frames = msf_to_frames( token );
+
+ outtoc.tracks[trknum].pregap = frames;
+ }
+ else if (!strcmp(token, "POSTGAP"))
+ {
+ int frames;
+
+ /* get index */
+ TOKENIZE
+ frames = msf_to_frames( token );
+
+ outtoc.tracks[trknum].postgap = frames;
+ }
+ }
+ }
+
+ /* close the input CUE */
+ fclose(infile);
+
+ /* store the number of tracks found */
+ outtoc.numtrks = trknum + 1;
+
+ /* now go over the files again and set the lengths */
+ for (trknum = 0; trknum < outtoc.numtrks; trknum++)
+ {
+ uint64_t tlen = 0;
+
+ // this is true for cue/bin and cue/iso, and we need it for cue/wav since .WAV is little-endian
+ if (outtoc.tracks[trknum].trktype == CD_TRACK_AUDIO)
+ {
+ outinfo.track[trknum].swap = true;
+ }
+
+ // don't do this for .WAV tracks, we already have their length and offset filled out
+ if (outinfo.track[trknum].offset == 0)
+ {
+ // is this the last track?
+ if (trknum == (outtoc.numtrks-1))
+ {
+ /* if we have the same filename as the last track, do it that way */
+ if (trknum != 0 && (outinfo.track[trknum].fname.compare(outinfo.track[trknum-1].fname)==0))
+ {
+ tlen = get_file_size(outinfo.track[trknum].fname.c_str());
+ if (tlen == 0)
+ {
+ printf("ERROR: couldn't find bin file [%s]\n", outinfo.track[trknum-1].fname.c_str());
+ return std::errc::no_such_file_or_directory;
+ }
+ outinfo.track[trknum].offset = outinfo.track[trknum-1].offset + outtoc.tracks[trknum-1].frames * (outtoc.tracks[trknum-1].datasize + outtoc.tracks[trknum-1].subsize);
+ outtoc.tracks[trknum].frames = (tlen - outinfo.track[trknum].offset) / (outtoc.tracks[trknum].datasize + outtoc.tracks[trknum].subsize);
+ }
+ else /* data files are different */
+ {
+ tlen = get_file_size(outinfo.track[trknum].fname.c_str());
+ if (tlen == 0)
+ {
+ printf("ERROR: couldn't find bin file [%s]\n", outinfo.track[trknum-1].fname.c_str());
+ return std::errc::no_such_file_or_directory;
+ }
+ tlen /= (outtoc.tracks[trknum].datasize + outtoc.tracks[trknum].subsize);
+ outtoc.tracks[trknum].frames = tlen;
+ outinfo.track[trknum].offset = 0;
+ }
+ }
+ else
+ {
+ /* if we have the same filename as the next track, do it that way */
+ if (outinfo.track[trknum].fname.compare(outinfo.track[trknum+1].fname)==0)
+ {
+ outtoc.tracks[trknum].frames = outinfo.track[trknum+1].idx0offs - outinfo.track[trknum].idx0offs;
+
+ if (trknum == 0) // track 0 offset is 0
+ {
+ outinfo.track[trknum].offset = 0;
+ }
+ else
+ {
+ outinfo.track[trknum].offset = outinfo.track[trknum-1].offset + outtoc.tracks[trknum-1].frames * (outtoc.tracks[trknum-1].datasize + outtoc.tracks[trknum-1].subsize);
+ }
+
+ if (!outtoc.tracks[trknum].frames)
+ {
+ printf("ERROR: unable to determine size of track %d, missing INDEX 01 markers?\n", trknum+1);
+ return chd_file::error::INVALID_DATA;
+ }
+ }
+ else /* data files are different */
+ {
+ tlen = get_file_size(outinfo.track[trknum].fname.c_str());
+ if (tlen == 0)
+ {
+ printf("ERROR: couldn't find bin file [%s]\n", outinfo.track[trknum].fname.c_str());
+ return std::errc::no_such_file_or_directory;
+ }
+ tlen /= (outtoc.tracks[trknum].datasize + outtoc.tracks[trknum].subsize);
+ outtoc.tracks[trknum].frames = tlen;
+ outinfo.track[trknum].offset = 0;
+ }
+ }
+ }
+ }
+
+ /*
+ * Dreamcast patterns are identified by track types and number of tracks
+ */
+ if (outtoc.numtrks > 4 && outtoc.tracks[outtoc.numtrks-1].pgtype == CD_TRACK_MODE1_RAW)
+ {
+ if (outtoc.tracks[outtoc.numtrks-2].pgtype == CD_TRACK_AUDIO)
+ disc_pattern = TYPE_III_SPLIT;
+ else
+ disc_pattern = TYPE_III;
+ }
+ else if (outtoc.numtrks > 3)
+ {
+ if (outtoc.tracks[outtoc.numtrks-1].pgtype == CD_TRACK_AUDIO)
+ disc_pattern = TYPE_II;
+ else
+ disc_pattern = TYPE_III;
+ }
+ else if (outtoc.numtrks == 3)
+ {
+ disc_pattern = TYPE_I;
+ }
+
+ /*
+ * Strip pregaps from Redump tracks and adjust the LBA offset to match TOSEC layout
+ */
+ for (trknum = 1; trknum < outtoc.numtrks; trknum++)
+ {
+ uint32_t prev_pregap = outtoc.tracks[trknum-1].pregap;
+ uint32_t prev_offset = prev_pregap * (outtoc.tracks[trknum-1].datasize + outtoc.tracks[trknum-1].subsize);
+ uint32_t this_pregap = outtoc.tracks[trknum].pregap;
+ uint32_t this_offset = this_pregap * (outtoc.tracks[trknum].datasize + outtoc.tracks[trknum].subsize);
+
+ if (outtoc.tracks[trknum-1].pgtype != CD_TRACK_AUDIO)
+ {
+ // pad previous DATA track to match TOSEC layout
+ outtoc.tracks[trknum-1].frames += this_pregap;
+ outtoc.tracks[trknum-1].padframes += this_pregap;
+ }
+
+ if (outtoc.tracks[trknum-1].pgtype == CD_TRACK_AUDIO && outtoc.tracks[trknum].pgtype == CD_TRACK_AUDIO)
+ {
+ // shift previous AUDIO track to match TOSEC layout
+ outinfo.track[trknum-1].offset += prev_offset;
+ outtoc.tracks[trknum-1].splitframes += prev_pregap;
+ }
+
+ if (outtoc.tracks[trknum-1].pgtype == CD_TRACK_AUDIO && outtoc.tracks[trknum].pgtype != CD_TRACK_AUDIO)
+ {
+ // shrink previous AUDIO track to match TOSEC layout
+ outtoc.tracks[trknum-1].frames -= prev_pregap;
+ outinfo.track[trknum-1].offset += prev_offset;
+ }
+
+ if (outtoc.tracks[trknum].pgtype == CD_TRACK_AUDIO && trknum == outtoc.numtrks-1)
+ {
+ // shrink final AUDIO track to match TOSEC layout
+ outtoc.tracks[trknum].frames -= this_pregap;
+ outinfo.track[trknum].offset += this_offset;
+ }
+ }
+
+ /*
+ * Special handling for TYPE_III_SPLIT, pregap in last track contains 75 frames audio and 150 frames data
+ */
+ if (disc_pattern == TYPE_III_SPLIT)
+ {
+ assert(outtoc.tracks[outtoc.numtrks-1].pregap == 225);
+
+ // grow the AUDIO track into DATA track by 75 frames as per Pattern III
+ outtoc.tracks[outtoc.numtrks-2].frames += 225;
+ outtoc.tracks[outtoc.numtrks-2].padframes += 150;
+ outinfo.track[outtoc.numtrks-2].offset = 150 * (outtoc.tracks[outtoc.numtrks-2].datasize+outtoc.tracks[outtoc.numtrks-2].subsize);
+ outtoc.tracks[outtoc.numtrks-2].splitframes = 75;
+
+ // skip the pregap when reading the DATA track
+ outtoc.tracks[outtoc.numtrks-1].frames -= 225;
+ outinfo.track[outtoc.numtrks-1].offset += 225 * (outtoc.tracks[outtoc.numtrks-1].datasize+outtoc.tracks[outtoc.numtrks-1].subsize);
+ }
+
+ /*
+ * TOC now matches TOSEC layout, set LBA for every track with HIGH-DENSITY area @ LBA 45000
+ */
+ for (trknum = 1; trknum < outtoc.numtrks; trknum++)
+ {
+ if (outtoc.tracks[trknum].multicuearea == HIGH_DENSITY && outtoc.tracks[trknum-1].multicuearea == SINGLE_DENSITY)
+ {
+ outtoc.tracks[trknum].physframeofs = 45000;
+ int dif=outtoc.tracks[trknum].physframeofs-(outtoc.tracks[trknum-1].frames+outtoc.tracks[trknum-1].physframeofs);
+ outtoc.tracks[trknum-1].frames += dif;
+ outtoc.tracks[trknum-1].padframes = dif;
+ }
+ else
+ {
+ outtoc.tracks[trknum].physframeofs = outtoc.tracks[trknum-1].physframeofs + outtoc.tracks[trknum-1].frames;
+ }
+
+ // no longer need the pregap info, zeroed out to match TOSEC layout
+ outtoc.tracks[trknum].pregap = 0;
+ outtoc.tracks[trknum].pgtype = 0;
+ }
+
+#if 0
+ for (trknum = 0; trknum < outtoc.numtrks; trknum++)
+ {
+ printf("trk %d: %d frames @ offset %d, pad=%d, split=%d, area=%d, phys=%d, pregap=%d, pgtype=%d, idx0=%d, idx1=%d, (true %d)\n",
+ trknum+1,
+ outtoc.tracks[trknum].frames,
+ outinfo.track[trknum].offset,
+ outtoc.tracks[trknum].padframes,
+ outtoc.tracks[trknum].splitframes,
+ outtoc.tracks[trknum].multicuearea,
+ outtoc.tracks[trknum].physframeofs,
+ outtoc.tracks[trknum].pregap,
+ outtoc.tracks[trknum].pgtype,
+ outinfo.track[trknum].idx0offs,
+ outinfo.track[trknum].idx1offs,
+ outtoc.tracks[trknum].frames - outtoc.tracks[trknum].padframes);
+ }
+#endif
+
+ return std::error_condition();
+}
+
+/*-------------------------------------------------
+ parse_toc - parse a CDRDAO format TOC file
+-------------------------------------------------*/
+
+/**
+ * @fn std::error_condition parse_toc(const char *tocfname, toc &outtoc, track_input_info &outinfo)
+ *
+ * @brief Chdcd parse TOC.
+ *
+ * @param tocfname The tocfname.
+ * @param [in,out] outtoc The outtoc.
+ * @param [in,out] outinfo The outinfo.
+ *
+ * @return A std::error_condition.
+ */
+
+std::error_condition cdrom_file::parse_toc(const char *tocfname, toc &outtoc, track_input_info &outinfo)
+{
+ int i, trknum;
+ static char token[512];
+ char tocftemp[512];
+
+ strcpy(tocftemp, tocfname);
+ for (i = 0; i < strlen(tocfname); i++)
+ {
+ tocftemp[i] = tolower(tocftemp[i]);
+ }
+
+ if (strstr(tocftemp,".gdi"))
+ {
+ return parse_gdi(tocfname, outtoc, outinfo);
+ }
+
+ if (strstr(tocftemp,".cue"))
+ {
+ if (is_gdicue(tocfname))
+ return parse_gdicue(tocfname, outtoc, outinfo);
+ else
+ return parse_cue(tocfname, outtoc, outinfo);
+ }
+
+ if (strstr(tocftemp,".nrg"))
+ {
+ return parse_nero(tocfname, outtoc, outinfo);
+ }
+
+ if (strstr(tocftemp,".iso") || strstr(tocftemp,".cdr") || strstr(tocftemp,".toast"))
+ {
+ return parse_iso(tocfname, outtoc, outinfo);
+ }
+
+ std::string path = std::string(tocfname);
+
+ FILE *infile = fopen(tocfname, "rt");
+ if (!infile)
+ {
+ return std::error_condition(errno, std::generic_category());
+ }
+
+ path = get_file_path(path);
+
+ /* clear structures */
+ memset(&outtoc, 0, sizeof(outtoc));
+ outinfo.reset();
+
+ trknum = -1;
+
+ char linebuffer[512];
+ while (!feof(infile))
+ {
+ /* get the next line */
+ fgets(linebuffer, 511, infile);
+
+ /* if EOF didn't hit, keep going */
+ if (!feof(infile))
+ {
+ i = 0;
+
+ TOKENIZE
+
+ if ((!strcmp(token, "DATAFILE")) || (!strcmp(token, "AUDIOFILE")) || (!strcmp(token, "FILE")))
+ {
+ int f;
+
+ /* found the data file for a track */
+ TOKENIZE
+
+ /* keep the filename */
+ outinfo.track[trknum].fname.assign(path).append(token);
+
+ /* get either the offset or the length */
+ TOKENIZE
+
+ if (!strcmp(token, "SWAP"))
+ {
+ TOKENIZE
+
+ outinfo.track[trknum].swap = true;
+ }
+ else
+ {
+ outinfo.track[trknum].swap = false;
+ }
+
+ if (token[0] == '#')
+ {
+ /* it's a decimal offset, use it */
+ f = strtoul(&token[1], nullptr, 10);
+ }
+ else if (isdigit((uint8_t)token[0]))
+ {
+ /* convert the time to an offset */
+ f = msf_to_frames( token );
+
+ f *= (outtoc.tracks[trknum].datasize + outtoc.tracks[trknum].subsize);
+ }
+ else
+ {
+ f = 0;
+ }
+
+ outinfo.track[trknum].offset = f;
+
+ TOKENIZE
+
+ if (isdigit((uint8_t)token[0]))
+ {
+ // this could be the length or an offset from the previous field.
+ f = msf_to_frames( token );
+
+ TOKENIZE
+
+ if (isdigit((uint8_t)token[0]))
+ {
+ // it was an offset.
+ f *= (outtoc.tracks[trknum].datasize + outtoc.tracks[trknum].subsize);
+
+ outinfo.track[trknum].offset += f;
+
+ // this is the length.
+ f = msf_to_frames( token );
+ }
+ }
+ else if( trknum == 0 && outinfo.track[trknum].offset != 0 )
+ {
+ /* the 1st track might have a length with no offset */
+ f = outinfo.track[trknum].offset / (outtoc.tracks[trknum].datasize + outtoc.tracks[trknum].subsize);
+ outinfo.track[trknum].offset = 0;
+ }
+ else
+ {
+ /* guesstimate the track length? */
+ f = 0;
+ }
+
+ outtoc.tracks[trknum].frames = f;
+ }
+ else if (!strcmp(token, "TRACK"))
+ {
+ trknum++;
+
+ /* next token on the line is the track type */
+ TOKENIZE
+
+ outtoc.tracks[trknum].trktype = CD_TRACK_MODE1;
+ outtoc.tracks[trknum].datasize = 0;
+ outtoc.tracks[trknum].subtype = CD_SUB_NONE;
+ outtoc.tracks[trknum].subsize = 0;
+ outtoc.tracks[trknum].pgsub = CD_SUB_NONE;
+ outtoc.tracks[trknum].padframes = 0;
+
+ convert_type_string_to_track_info(token, &outtoc.tracks[trknum]);
+ if (outtoc.tracks[trknum].datasize == 0)
+ {
+ fclose(infile);
+ printf("ERROR: Unknown track type [%s]. Contact MAMEDEV.\n", token);
+ return chd_file::error::UNSUPPORTED_FORMAT;
+ }
+
+ /* next (optional) token on the line is the subcode type */
+ TOKENIZE
+
+ convert_subtype_string_to_track_info(token, &outtoc.tracks[trknum]);
+ }
+ else if (!strcmp(token, "START"))
+ {
+ int frames;
+
+ /* get index */
+ TOKENIZE
+ frames = msf_to_frames( token );
+
+ outtoc.tracks[trknum].pregap = frames;
+ }
+ }
+ }
+
+ /* close the input TOC */
+ fclose(infile);
+
+ /* store the number of tracks found */
+ outtoc.numtrks = trknum + 1;
+
+ return std::error_condition();
+}
diff --git a/src/lib/util/cdrom.h b/src/lib/util/cdrom.h
index 1847a1db83a..ee26472d2e7 100644
--- a/src/lib/util/cdrom.h
+++ b/src/lib/util/cdrom.h
@@ -1,5 +1,5 @@
// license:BSD-3-Clause
-// copyright-holders:Aaron Giles
+// copyright-holders:Aaron Giles,R. Belmont
/***************************************************************************
cdrom.h
@@ -13,175 +13,253 @@
#pragma once
#include "chd.h"
-
+#include "corefile.h"
#include "osdcore.h"
-
-
-/***************************************************************************
- CONSTANTS
-***************************************************************************/
-
-// tracks are padded to a multiple of this many frames
-const uint32_t CD_TRACK_PADDING = 4;
-
-#define CD_MAX_TRACKS (99) /* AFAIK the theoretical limit */
-#define CD_MAX_SECTOR_DATA (2352)
-#define CD_MAX_SUBCODE_DATA (96)
-
-#define CD_FRAME_SIZE (CD_MAX_SECTOR_DATA + CD_MAX_SUBCODE_DATA)
-#define CD_FRAMES_PER_HUNK (8)
-
-#define CD_METADATA_WORDS (1+(CD_MAX_TRACKS * 6))
-
-enum
-{
- CD_TRACK_MODE1 = 0, /* mode 1 2048 bytes/sector */
- CD_TRACK_MODE1_RAW, /* mode 1 2352 bytes/sector */
- CD_TRACK_MODE2, /* mode 2 2336 bytes/sector */
- CD_TRACK_MODE2_FORM1, /* mode 2 2048 bytes/sector */
- CD_TRACK_MODE2_FORM2, /* mode 2 2324 bytes/sector */
- CD_TRACK_MODE2_FORM_MIX, /* mode 2 2336 bytes/sector */
- CD_TRACK_MODE2_RAW, /* mode 2 2352 bytes / sector */
- CD_TRACK_AUDIO, /* redbook audio track 2352 bytes/sector (588 samples) */
-
- CD_TRACK_RAW_DONTCARE /* special flag for cdrom_read_data: just return me whatever is there */
-};
-
-enum
-{
- CD_SUB_NORMAL = 0, /* "cooked" 96 bytes per sector */
- CD_SUB_RAW, /* raw uninterleaved 96 bytes per sector */
- CD_SUB_NONE /* no subcode data stored */
-};
-
-#define CD_FLAG_GDROM 0x00000001 // disc is a GD-ROM, all tracks should be stored with GD-ROM metadata
-#define CD_FLAG_GDROMLE 0x00000002 // legacy GD-ROM, with little-endian CDDA data
-
-/***************************************************************************
- TYPE DEFINITIONS
-***************************************************************************/
-
-struct cdrom_file;
-
-struct cdrom_track_info
-{
- /* fields used by CHDMAN and in MAME */
- uint32_t trktype; /* track type */
- uint32_t subtype; /* subcode data type */
- uint32_t datasize; /* size of data in each sector of this track */
- uint32_t subsize; /* size of subchannel data in each sector of this track */
- uint32_t frames; /* number of frames in this track */
- uint32_t extraframes; /* number of "spillage" frames in this track */
- uint32_t pregap; /* number of pregap frames */
- uint32_t postgap; /* number of postgap frames */
- uint32_t pgtype; /* type of sectors in pregap */
- uint32_t pgsub; /* type of subchannel data in pregap */
- uint32_t pgdatasize; /* size of data in each sector of the pregap */
- uint32_t pgsubsize; /* size of subchannel data in each sector of the pregap */
-
- /* fields used in CHDMAN only */
- uint32_t padframes; /* number of frames of padding to add to the end of the track; needed for GDI */
- uint32_t splitframes; /* number of frames to read from the next file; needed for Redump split-bin GDI */
-
- /* fields used in MAME/MESS only */
- 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;
-};
-
-
-struct cdrom_toc
-{
- uint32_t numtrks; /* number of tracks */
- uint32_t flags; /* see FLAG_ above */
- cdrom_track_info tracks[CD_MAX_TRACKS];
-};
-
-
-
-/***************************************************************************
- FUNCTION PROTOTYPES
-***************************************************************************/
-
-/* base functionality */
-cdrom_file *cdrom_open(chd_file *chd);
-void cdrom_close(cdrom_file *file);
-
-cdrom_file *cdrom_open(const char *inputfile);
-
-/* core read access */
-uint32_t cdrom_read_data(cdrom_file *file, uint32_t lbasector, void *buffer, uint32_t datatype, bool phys=false);
-uint32_t cdrom_read_subcode(cdrom_file *file, uint32_t lbasector, void *buffer, bool phys=false);
-
-/* handy utilities */
-uint32_t cdrom_get_track(cdrom_file *file, uint32_t frame);
-uint32_t cdrom_get_track_start(cdrom_file *file, uint32_t track);
-uint32_t cdrom_get_track_start_phys(cdrom_file *file, uint32_t track);
-chd_file *cdrom_get_chd(cdrom_file *file);
-
-/* TOC utilities */
-int cdrom_get_last_track(cdrom_file *file);
-int cdrom_get_adr_control(cdrom_file *file, int track);
-int cdrom_get_track_type(cdrom_file *file, int track);
-const cdrom_toc *cdrom_get_toc(cdrom_file *file);
-
-/* extra utilities */
-void cdrom_convert_type_string_to_track_info(const char *typestring, cdrom_track_info *info);
-void cdrom_convert_type_string_to_pregap_info(const char *typestring, cdrom_track_info *info);
-void cdrom_convert_subtype_string_to_track_info(const char *typestring, cdrom_track_info *info);
-void cdrom_convert_subtype_string_to_pregap_info(const char *typestring, cdrom_track_info *info);
-const char *cdrom_get_type_string(uint32_t trktype);
-const char *cdrom_get_subtype_string(uint32_t subtype);
-std::error_condition cdrom_parse_metadata(chd_file *chd, cdrom_toc *toc);
-std::error_condition cdrom_write_metadata(chd_file *chd, const cdrom_toc *toc);
-
-// ECC utilities
-bool ecc_verify(const uint8_t *sector);
-void ecc_generate(uint8_t *sector);
-void ecc_clear(uint8_t *sector);
-
-
-
-/***************************************************************************
- INLINE FUNCTIONS
-***************************************************************************/
-
-static inline uint32_t msf_to_lba(uint32_t msf)
-{
- return ( ((msf&0x00ff0000)>>16) * 60 * 75) + (((msf&0x0000ff00)>>8) * 75) + ((msf&0x000000ff)>>0);
-}
-
-static inline uint32_t lba_to_msf(uint32_t lba)
-{
- uint8_t m, s, f;
-
- m = lba / (60 * 75);
- lba -= m * (60 * 75);
- s = lba / 75;
- f = lba % 75;
-
- return ((m / 10) << 20) | ((m % 10) << 16) |
+class cdrom_file {
+public:
+ // tracks are padded to a multiple of this many frames
+ static constexpr uint32_t TRACK_PADDING = 4;
+
+ static constexpr uint32_t MAX_TRACKS = 99; /* AFAIK the theoretical limit */
+ static constexpr uint32_t MAX_SECTOR_DATA = 2352;
+ static constexpr uint32_t MAX_SUBCODE_DATA = 96;
+
+ static constexpr uint32_t FRAME_SIZE = MAX_SECTOR_DATA + MAX_SUBCODE_DATA;
+ static constexpr uint32_t FRAMES_PER_HUNK = 8;
+
+ static constexpr uint32_t METADATA_WORDS = 1 + MAX_TRACKS * 6;
+
+ enum
+ {
+ CD_TRACK_MODE1 = 0, /* mode 1 2048 bytes/sector */
+ CD_TRACK_MODE1_RAW, /* mode 1 2352 bytes/sector */
+ CD_TRACK_MODE2, /* mode 2 2336 bytes/sector */
+ CD_TRACK_MODE2_FORM1, /* mode 2 2048 bytes/sector */
+ CD_TRACK_MODE2_FORM2, /* mode 2 2324 bytes/sector */
+ CD_TRACK_MODE2_FORM_MIX, /* mode 2 2336 bytes/sector */
+ CD_TRACK_MODE2_RAW, /* mode 2 2352 bytes / sector */
+ CD_TRACK_AUDIO, /* redbook audio track 2352 bytes/sector (588 samples) */
+
+ CD_TRACK_RAW_DONTCARE /* special flag for cdrom_read_data: just return me whatever is there */
+ };
+
+ enum
+ {
+ CD_SUB_NORMAL = 0, /* "cooked" 96 bytes per sector */
+ CD_SUB_RAW, /* raw uninterleaved 96 bytes per sector */
+ CD_SUB_NONE /* no subcode data stored */
+ };
+
+ enum
+ {
+ CD_FLAG_GDROM = 0x00000001, // disc is a GD-ROM, all tracks should be stored with GD-ROM metadata
+ CD_FLAG_GDROMLE = 0x00000002 // legacy GD-ROM, with little-endian CDDA data
+ };
+
+ struct track_info
+ {
+ /* fields used by CHDMAN and in MAME */
+ uint32_t trktype; /* track type */
+ uint32_t subtype; /* subcode data type */
+ uint32_t datasize; /* size of data in each sector of this track */
+ uint32_t subsize; /* size of subchannel data in each sector of this track */
+ uint32_t frames; /* number of frames in this track */
+ uint32_t extraframes; /* number of "spillage" frames in this track */
+ uint32_t pregap; /* number of pregap frames */
+ uint32_t postgap; /* number of postgap frames */
+ uint32_t pgtype; /* type of sectors in pregap */
+ uint32_t pgsub; /* type of subchannel data in pregap */
+ uint32_t pgdatasize; /* size of data in each sector of the pregap */
+ uint32_t pgsubsize; /* size of subchannel data in each sector of the pregap */
+
+ /* fields used in CHDMAN only */
+ uint32_t padframes; /* number of frames of padding to add to the end of the track; needed for GDI */
+ uint32_t splitframes; /* number of frames to read from the next file; needed for Redump split-bin GDI */
+
+ /* fields used in MAME/MESS only */
+ 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;
+ };
+
+
+ struct toc
+ {
+ uint32_t numtrks; /* number of tracks */
+ uint32_t flags; /* see FLAG_ above */
+ track_info tracks[MAX_TRACKS];
+ };
+
+ struct track_input_entry
+ {
+ track_input_entry() { reset(); }
+ void reset() { fname.clear(); offset = idx0offs = idx1offs = 0; swap = false; }
+
+ std::string fname; // filename for each track
+ uint32_t offset; // offset in the data file for each track
+ bool swap; // data needs to be byte swapped
+ uint32_t idx0offs;
+ uint32_t idx1offs;
+ };
+
+ struct track_input_info
+ {
+ void reset() { for (auto & elem : track) elem.reset(); }
+
+ track_input_entry track[MAX_TRACKS];
+ };
+
+
+ cdrom_file(chd_file *chd);
+ cdrom_file(const char *inputfile);
+ ~cdrom_file();
+
+
+ /* core read access */
+ bool read_data(uint32_t lbasector, void *buffer, uint32_t datatype, bool phys=false);
+ bool read_subcode(uint32_t lbasector, void *buffer, bool phys=false);
+
+ /* handy utilities */
+ uint32_t get_track(uint32_t frame) const;
+ uint32_t get_track_start(uint32_t track) const {return cdtoc.tracks[track == 0xaa ? cdtoc.numtrks : track].logframeofs; }
+ uint32_t get_track_start_phys(uint32_t track) const { return cdtoc.tracks[track == 0xaa ? cdtoc.numtrks : track].physframeofs; }
+ chd_file *get_chd() const { return chd; }
+
+ /* TOC utilities */
+ static std::error_condition parse_nero(const char *tocfname, toc &outtoc, track_input_info &outinfo);
+ static std::error_condition parse_iso(const char *tocfname, toc &outtoc, track_input_info &outinfo);
+ static std::error_condition parse_gdi(const char *tocfname, toc &outtoc, track_input_info &outinfo);
+ static std::error_condition parse_cue(const char *tocfname, toc &outtoc, track_input_info &outinfo);
+ static bool is_gdicue(const char *tocfname);
+ static std::error_condition parse_gdicue(const char *tocfname, toc &outtoc, track_input_info &outinfo);
+ static std::error_condition parse_toc(const char *tocfname, toc &outtoc, track_input_info &outinfo);
+ int get_last_track() const { return cdtoc.numtrks; }
+ int get_adr_control(int track) const { return track == 0xaa || cdtoc.tracks[track].trktype == CD_TRACK_AUDIO ? 0x10 : 0x14; }
+ int get_track_type(int track) const { return cdtoc.tracks[track].trktype; }
+ const toc &get_toc() const { return cdtoc; }
+
+ /* extra utilities */
+ static void convert_type_string_to_track_info(const char *typestring, track_info *info);
+ static void convert_type_string_to_pregap_info(const char *typestring, track_info *info);
+ static void convert_subtype_string_to_track_info(const char *typestring, track_info *info);
+ static void convert_subtype_string_to_pregap_info(const char *typestring, track_info *info);
+ static const char *get_type_string(uint32_t trktype);
+ static const char *get_subtype_string(uint32_t subtype);
+ static std::error_condition parse_metadata(chd_file *chd, toc &toc);
+ static std::error_condition write_metadata(chd_file *chd, const toc &toc);
+
+ // ECC utilities
+ static bool ecc_verify(const uint8_t *sector);
+ static void ecc_generate(uint8_t *sector);
+ static void ecc_clear(uint8_t *sector);
+
+
+
+ static inline uint32_t msf_to_lba(uint32_t msf)
+ {
+ return ( ((msf&0x00ff0000)>>16) * 60 * 75) + (((msf&0x0000ff00)>>8) * 75) + ((msf&0x000000ff)>>0);
+ }
+
+ static inline uint32_t lba_to_msf(uint32_t lba)
+ {
+ uint8_t m, s, f;
+
+ m = lba / (60 * 75);
+ lba -= m * (60 * 75);
+ s = lba / 75;
+ f = lba % 75;
+
+ return ((m / 10) << 20) | ((m % 10) << 16) |
((s / 10) << 12) | ((s % 10) << 8) |
((f / 10) << 4) | ((f % 10) << 0);
-}
-
-// segacd needs it like this.. investigate
-// Angelo also says PCE tracks often start playing at the
-// wrong address.. related?
-static inline uint32_t lba_to_msf_alt(int lba)
-{
- uint32_t ret = 0;
-
- ret |= ((lba / (60 * 75))&0xff)<<16;
- ret |= (((lba / 75) % 60)&0xff)<<8;
- ret |= ((lba % 75)&0xff)<<0;
-
- return ret;
-}
+ }
+
+ // segacd needs it like this.. investigate
+ // Angelo also says PCE tracks often start playing at the
+ // wrong address.. related?
+ static inline uint32_t lba_to_msf_alt(int lba)
+ {
+ uint32_t ret = 0;
+
+ ret |= ((lba / (60 * 75))&0xff)<<16;
+ ret |= (((lba / 75) % 60)&0xff)<<8;
+ ret |= ((lba % 75)&0xff)<<0;
+
+ return ret;
+ }
+
+private:
+ enum gdi_area {
+ SINGLE_DENSITY,
+ HIGH_DENSITY
+ };
+
+ enum gdi_pattern {
+ TYPE_UNKNOWN = 0,
+ TYPE_I,
+ TYPE_II,
+ TYPE_III,
+ TYPE_III_SPLIT
+ };
+
+ /** @brief offset within sector. */
+ static constexpr int SYNC_OFFSET = 0x000;
+ /** @brief 12 bytes. */
+ static constexpr int SYNC_NUM_BYTES = 12;
+
+ /** @brief offset within sector. */
+ static constexpr int MODE_OFFSET = 0x00f;
+
+ /** @brief offset within sector. */
+ static constexpr int ECC_P_OFFSET = 0x81c;
+ /** @brief 2 lots of 86. */
+ static constexpr int ECC_P_NUM_BYTES = 86;
+ /** @brief 24 bytes each. */
+ static constexpr int ECC_P_COMP = 24;
+
+ /** @brief The ECC q offset. */
+ static constexpr int ECC_Q_OFFSET = ECC_P_OFFSET + 2 * ECC_P_NUM_BYTES;
+ /** @brief 2 lots of 52. */
+ static constexpr int ECC_Q_NUM_BYTES = 52;
+ /** @brief 43 bytes each. */
+ static constexpr int ECC_Q_COMP = 43;
+
+ // ECC tables
+ static const uint8_t ecclow[256];
+ static const uint8_t ecchigh[256];
+ static const uint16_t poffsets[ECC_P_NUM_BYTES][ECC_P_COMP];
+ static const uint16_t qoffsets[ECC_Q_NUM_BYTES][ECC_Q_COMP];
+
+ /** @brief The chd. */
+ chd_file * chd; /* CHD file */
+ /** @brief The cdtoc. */
+ toc cdtoc; /* TOC for the CD */
+ /** @brief Information describing the track. */
+ track_input_info cdtrack_info; /* track info */
+ /** @brief The fhandle[ CD maximum tracks]. */
+ util::core_file::ptr fhandle[MAX_TRACKS];/* file handle */
+
+ inline uint32_t physical_to_chd_lba(uint32_t physlba, uint32_t &tracknum) const;
+ inline uint32_t logical_to_chd_lba(uint32_t physlba, uint32_t &tracknum) const;
+
+ static void get_info_from_type_string(const char *typestring, uint32_t *trktype, uint32_t *datasize);
+ static uint8_t ecc_source_byte(const uint8_t *sector, uint32_t offset);
+ static void ecc_compute_bytes(const uint8_t *sector, const uint16_t *row, int rowlen, uint8_t &val1, uint8_t &val2);
+ std::error_condition read_partial_sector(void *dest, uint32_t lbasector, uint32_t chdsector, uint32_t tracknum, uint32_t startoffs, uint32_t length, bool phys=false);
+
+ static std::string get_file_path(std::string &path);
+ static uint64_t get_file_size(const char *filename);
+ static int tokenize( const char *linebuffer, int i, int linebuffersize, char *token, int tokensize );
+ static int msf_to_frames( char *token );
+ static uint32_t parse_wav_sample(const char *filename, uint32_t *dataoffs);
+ static uint16_t read_uint16(FILE *infile);
+ static uint32_t read_uint32(FILE *infile);
+ static uint64_t read_uint64(FILE *infile);
+};
#endif // MAME_LIB_UTIL_CDROM_H
diff --git a/src/lib/util/chd.cpp b/src/lib/util/chd.cpp
index 1b4800c74f1..c7b98113063 100644
--- a/src/lib/util/chd.cpp
+++ b/src/lib/util/chd.cpp
@@ -1743,7 +1743,7 @@ uint32_t chd_file::guess_unitbytes()
!read_metadata(CDROM_TRACK_METADATA2_TAG, 0, metadata) ||
!read_metadata(GDROM_OLD_METADATA_TAG, 0, metadata) ||
!read_metadata(GDROM_TRACK_METADATA_TAG, 0, metadata))
- return CD_FRAME_SIZE;
+ return cdrom_file::FRAME_SIZE;
// otherwise, just map 1:1 with the hunk size
return m_hunkbytes;
diff --git a/src/lib/util/chdcd.cpp b/src/lib/util/chdcd.cpp
deleted file mode 100644
index 63b633536bf..00000000000
--- a/src/lib/util/chdcd.cpp
+++ /dev/null
@@ -1,1848 +0,0 @@
-// license:BSD-3-Clause
-// copyright-holders:R. Belmont
-/***************************************************************************
-
- TOC parser for CHD compression frontend
- Handles CDRDAO .toc, CDRWIN .cue, Nero .nrg, and Sega GDROM .gdi
-
-***************************************************************************/
-
-#include "chdcd.h"
-
-#include "chd.h"
-#include "corefile.h"
-#include "corestr.h"
-
-#include "osdcore.h"
-
-#include <cassert>
-#include <cctype>
-#include <cerrno>
-#include <cstdlib>
-
-
-
-/***************************************************************************
- CONSTANTS & DEFINES
-***************************************************************************/
-
-/**
- * @def TOKENIZE();
- *
- * @brief A macro that defines tokenize.
- *
- * @param linebuffer The linebuffer.
- * @param i Zero-based index of the.
- * @param sizeof(linebuffer) The sizeof(linebuffer)
- * @param token The token.
- * @param sizeof(token) The sizeof(token)
- */
-
-#define TOKENIZE i = tokenize( linebuffer, i, sizeof(linebuffer), token, sizeof(token) );
-
-
-enum gdi_area {
- SINGLE_DENSITY,
- HIGH_DENSITY
-};
-
-enum gdi_pattern {
- TYPE_UNKNOWN = 0,
- TYPE_I,
- TYPE_II,
- TYPE_III,
- TYPE_III_SPLIT
-};
-
-
-/***************************************************************************
- GLOBAL VARIABLES
-***************************************************************************/
-
-/** @brief The linebuffer[ 512]. */
-static char linebuffer[512];
-
-
-
-/***************************************************************************
- IMPLEMENTATION
-***************************************************************************/
-
-/**
- * @fn static std::string get_file_path(std::string &path)
- *
- * @brief Gets file path.
- *
- * @param [in,out] path Full pathname of the file.
- *
- * @return The file path.
- */
-
-static std::string get_file_path(std::string &path)
-{
- int pos = path.find_last_of('\\');
- if (pos!=-1) {
- path = path.substr(0,pos+1);
- } else {
- pos = path.find_last_of('/');
- path = path.substr(0,pos+1);
- }
- return path;
-}
-/*-------------------------------------------------
- get_file_size - get the size of a file
--------------------------------------------------*/
-
-/**
- * @fn static uint64_t get_file_size(const char *filename)
- *
- * @brief Gets file size.
- *
- * @param filename Filename of the file.
- *
- * @return The file size.
- */
-
-static uint64_t get_file_size(const char *filename)
-{
- osd_file::ptr file;
- std::uint64_t filesize = 0;
-
- osd_file::open(filename, OPEN_FLAG_READ, file, filesize);
-
- return filesize;
-}
-
-
-/*-------------------------------------------------
- tokenize - get a token from the line buffer
--------------------------------------------------*/
-
-/**
- * @fn static int tokenize( const char *linebuffer, int i, int linebuffersize, char *token, int tokensize )
- *
- * @brief Tokenizes.
- *
- * @param linebuffer The linebuffer.
- * @param i Zero-based index of the.
- * @param linebuffersize The linebuffersize.
- * @param [in,out] token If non-null, the token.
- * @param tokensize The tokensize.
- *
- * @return An int.
- */
-
-static int tokenize( const char *linebuffer, int i, int linebuffersize, char *token, int tokensize )
-{
- int j = 0;
- int singlequote = 0;
- int doublequote = 0;
-
- while ((i < linebuffersize) && isspace((uint8_t)linebuffer[i]))
- {
- i++;
- }
-
- while ((i < linebuffersize) && (j < tokensize))
- {
- if (!singlequote && linebuffer[i] == '"' )
- {
- doublequote = !doublequote;
- }
- else if (!doublequote && linebuffer[i] == '\'')
- {
- singlequote = !singlequote;
- }
- else if (!singlequote && !doublequote && isspace((uint8_t)linebuffer[i]))
- {
- break;
- }
- else
- {
- token[j] = linebuffer[i];
- j++;
- }
-
- i++;
- }
-
- token[j] = '\0';
-
- return i;
-}
-
-
-/*-------------------------------------------------
- msf_to_frames - convert m:s:f into a number of frames
--------------------------------------------------*/
-
-/**
- * @fn static int msf_to_frames( char *token )
- *
- * @brief Msf to frames.
- *
- * @param [in,out] token If non-null, the token.
- *
- * @return An int.
- */
-
-static int msf_to_frames( char *token )
-{
- int m = 0;
- int s = 0;
- int f = 0;
-
- if( sscanf( token, "%d:%d:%d", &m, &s, &f ) == 1 )
- {
- f = m;
- }
- else
- {
- /* convert to just frames */
- s += (m * 60);
- f += (s * 75);
- }
-
- return f;
-}
-
-/*-------------------------------------------------
- parse_wav_sample - takes a .WAV file, verifies
- that the file is 16 bits, and returns the
- length in bytes of the data and the offset in
- bytes to where the data starts in the file.
--------------------------------------------------*/
-
-/**
- * @fn static uint32_t parse_wav_sample(const char *filename, uint32_t *dataoffs)
- *
- * @brief Parse WAV sample.
- *
- * @param filename Filename of the file.
- * @param [in,out] dataoffs If non-null, the dataoffs.
- *
- * @return An uint32_t.
- */
-
-static uint32_t parse_wav_sample(const char *filename, uint32_t *dataoffs)
-{
- unsigned long offset = 0;
- uint32_t length, rate, filesize;
- uint16_t bits, temp16;
- char buf[32];
- osd_file::ptr file;
- uint64_t fsize = 0;
- std::uint32_t actual;
-
- std::error_condition const filerr = osd_file::open(filename, OPEN_FLAG_READ, file, fsize);
- if (filerr)
- {
- printf("ERROR: could not open (%s)\n", filename);
- return 0;
- }
-
- /* read the core header and make sure it's a WAVE file */
- file->read(buf, 0, 4, actual);
- offset += actual;
- if (offset < 4)
- {
- printf("ERROR: unexpected RIFF offset %lu (%s)\n", offset, filename);
- return 0;
- }
- if (memcmp(&buf[0], "RIFF", 4) != 0)
- {
- printf("ERROR: could not find RIFF header (%s)\n", filename);
- return 0;
- }
-
- /* get the total size */
- file->read(&filesize, offset, 4, actual);
- offset += actual;
- if (offset < 8)
- {
- printf("ERROR: unexpected size offset %lu (%s)\n", offset, filename);
- return 0;
- }
- filesize = little_endianize_int32(filesize);
-
- /* read the RIFF file type and make sure it's a WAVE file */
- file->read(buf, offset, 4, actual);
- offset += actual;
- if (offset < 12)
- {
- printf("ERROR: unexpected WAVE offset %lu (%s)\n", offset, filename);
- return 0;
- }
- if (memcmp(&buf[0], "WAVE", 4) != 0)
- {
- printf("ERROR: could not find WAVE header (%s)\n", filename);
- return 0;
- }
-
- /* seek until we find a format tag */
- while (true)
- {
- file->read(buf, offset, 4, actual);
- offset += actual;
- file->read(&length, offset, 4, actual);
- offset += actual;
- length = little_endianize_int32(length);
- if (memcmp(&buf[0], "fmt ", 4) == 0)
- break;
-
- /* seek to the next block */
- offset += length;
- if (offset >= filesize)
- {
- printf("ERROR: could not find fmt tag (%s)\n", filename);
- return 0;
- }
- }
-
- /* read the format -- make sure it is PCM */
- file->read(&temp16, offset, 2, actual);
- offset += actual;
- temp16 = little_endianize_int16(temp16);
- if (temp16 != 1)
- {
- printf("ERROR: unsupported format %u - only PCM is supported (%s)\n", temp16, filename);
- return 0;
- }
-
- /* number of channels -- only stereo is supported */
- file->read(&temp16, offset, 2, actual);
- offset += actual;
- temp16 = little_endianize_int16(temp16);
- if (temp16 != 2)
- {
- printf("ERROR: unsupported number of channels %u - only stereo is supported (%s)\n", temp16, filename);
- return 0;
- }
-
- /* sample rate */
- file->read(&rate, offset, 4, actual);
- offset += actual;
- rate = little_endianize_int32(rate);
- if (rate != 44100)
- {
- printf("ERROR: unsupported samplerate %u - only 44100 is supported (%s)\n", rate, filename);
- return 0;
- }
-
- /* bytes/second and block alignment are ignored */
- file->read(buf, offset, 6, actual);
- offset += actual;
-
- /* bits/sample */
- file->read(&bits, offset, 2, actual);
- offset += actual;
- bits = little_endianize_int16(bits);
- if (bits != 16)
- {
- printf("ERROR: unsupported bits/sample %u - only 16 is supported (%s)\n", bits, filename);
- return 0;
- }
-
- /* seek past any extra data */
- offset += length - 16;
-
- /* seek until we find a data tag */
- while (true)
- {
- file->read(buf, offset, 4, actual);
- offset += actual;
- file->read(&length, offset, 4, actual);
- offset += actual;
- length = little_endianize_int32(length);
- if (memcmp(&buf[0], "data", 4) == 0)
- break;
-
- /* seek to the next block */
- offset += length;
- if (offset >= filesize)
- {
- printf("ERROR: could not find data tag (%s)\n", filename);
- return 0;
- }
- }
-
- /* if there was a 0 length data block, we're done */
- if (length == 0)
- {
- printf("ERROR: empty data block (%s)\n", filename);
- return 0;
- }
-
- *dataoffs = offset;
-
- return length;
-}
-
-/**
- * @fn uint16_t read_uint16(FILE *infile)
- *
- * @brief Reads uint 16.
- *
- * @param [in,out] infile If non-null, the infile.
- *
- * @return The uint 16.
- */
-
-uint16_t read_uint16(FILE *infile)
-{
- uint16_t res = 0;
- unsigned char buffer[2];
-
- fread(buffer, 2, 1, infile);
-
- res = buffer[1] | buffer[0]<<8;
-
- return res;
-}
-
-/**
- * @fn uint32_t read_uint32(FILE *infile)
- *
- * @brief Reads uint 32.
- *
- * @param [in,out] infile If non-null, the infile.
- *
- * @return The uint 32.
- */
-
-uint32_t read_uint32(FILE *infile)
-{
- uint32_t res = 0;
- unsigned char buffer[4];
-
- fread(buffer, 4, 1, infile);
-
- res = buffer[3] | buffer[2]<<8 | buffer[1]<<16 | buffer[0]<<24;
-
- return res;
-}
-
-/**
- * @fn uint64_t read_uint64(FILE *infile)
- *
- * @brief Reads uint 64.
- *
- * @param [in,out] infile If non-null, the infile.
- *
- * @return The uint 64.
- */
-
-uint64_t read_uint64(FILE *infile)
-{
- uint64_t res0(0), res1(0);
- uint64_t res;
- unsigned char buffer[8];
-
- fread(buffer, 8, 1, infile);
-
- res0 = buffer[3] | buffer[2]<<8 | buffer[1]<<16 | buffer[0]<<24;
- res1 = buffer[7] | buffer[6]<<8 | buffer[5]<<16 | buffer[4]<<24;
-
- res = res0<<32 | res1;
-
- return res;
-}
-
-/*-------------------------------------------------
- chdcd_parse_nero - parse a Nero .NRG file
--------------------------------------------------*/
-
-/**
- * @fn std::error_condition chdcd_parse_nero(const char *tocfname, cdrom_toc &outtoc, chdcd_track_input_info &outinfo)
- *
- * @brief Chdcd parse nero.
- *
- * @param tocfname The tocfname.
- * @param [in,out] outtoc The outtoc.
- * @param [in,out] outinfo The outinfo.
- *
- * @return A std::error_condition.
- */
-
-std::error_condition chdcd_parse_nero(const char *tocfname, cdrom_toc &outtoc, chdcd_track_input_info &outinfo)
-{
- unsigned char buffer[12];
- uint32_t chain_offs, chunk_size;
- int done = 0;
-
- std::string path = std::string(tocfname);
-
- FILE *infile = fopen(tocfname, "rb");
- if (!infile)
- {
- return std::error_condition(errno, std::generic_category());
- }
-
- path = get_file_path(path);
-
- /* clear structures */
- memset(&outtoc, 0, sizeof(outtoc));
- outinfo.reset();
-
- // seek to 12 bytes before the end
- fseek(infile, -12, SEEK_END);
- fread(buffer, 12, 1, infile);
-
- if (memcmp(buffer, "NER5", 4))
- {
- printf("ERROR: Not a Nero 5.5 or later image!\n");
- fclose(infile);
- return chd_file::error::UNSUPPORTED_FORMAT;
- }
-
- chain_offs = buffer[11] | (buffer[10]<<8) | (buffer[9]<<16) | (buffer[8]<<24);
-
- if ((buffer[7] != 0) || (buffer[6] != 0) || (buffer[5] != 0) || (buffer[4] != 0))
- {
- printf("ERROR: File size is > 4GB, this version of CHDMAN cannot handle it.");
- fclose(infile);
- return chd_file::error::UNSUPPORTED_FORMAT;
- }
-
-// printf("NER5 detected, chain offset: %x\n", chain_offs);
-
- while (!done)
- {
- uint32_t offset;
- uint8_t start, end;
- int track;
-
- fseek(infile, chain_offs, SEEK_SET);
- fread(buffer, 8, 1, infile);
-
- chunk_size = (buffer[7] | buffer[6]<<8 | buffer[5]<<16 | buffer[4]<<24);
-
-// printf("Chunk type: %c%c%c%c, size %x\n", buffer[0], buffer[1], buffer[2], buffer[3], chunk_size);
-
- // we want the DAOX chunk, which has the TOC information
- if (!memcmp(buffer, "DAOX", 4))
- {
- // skip second chunk size and UPC code
- fseek(infile, 20, SEEK_CUR);
-
- fread(&start, 1, 1, infile);
- fread(&end, 1, 1, infile);
-
-// printf("Start track %d End track: %d\n", start, end);
-
- outtoc.numtrks = (end-start) + 1;
-
- offset = 0;
- for (track = start; track <= end; track++)
- {
- uint32_t size, mode;
- uint64_t index0, index1, track_end;
-
- fseek(infile, 12, SEEK_CUR); // skip ISRC code
- size = read_uint16(infile);
- mode = read_uint16(infile);
- fseek(infile, 2, SEEK_CUR);
- index0 = read_uint64(infile);
- index1 = read_uint64(infile);
- track_end = read_uint64(infile);
-
-// printf("Track %d: sector size %d mode %x index0 %llx index1 %llx track_end %llx (pregap %d sectors, length %d sectors)\n", track, size, mode, index0, index1, track_end, (uint32_t)(index1-index0)/size, (uint32_t)(track_end-index1)/size);
- outinfo.track[track-1].fname.assign(tocfname);
- outinfo.track[track-1].offset = offset + (uint32_t)(index1-index0);
- outinfo.track[track-1].idx0offs = 0;
- outinfo.track[track-1].idx1offs = 0;
-
- switch (mode)
- {
- case 0x0000: // 2048 byte data
- outtoc.tracks[track-1].trktype = CD_TRACK_MODE1;
- outinfo.track[track-1].swap = false;
- break;
-
- case 0x0300: // Mode 2 Form 1
- printf("ERROR: Mode 2 Form 1 tracks not supported\n");
- fclose(infile);
- return chd_file::error::UNSUPPORTED_FORMAT;
-
- case 0x0500: // raw data
- printf("ERROR: Raw data tracks not supported\n");
- fclose(infile);
- return chd_file::error::UNSUPPORTED_FORMAT;
-
- case 0x0600: // 2352 byte mode 2 raw
- outtoc.tracks[track-1].trktype = CD_TRACK_MODE2_RAW;
- outinfo.track[track-1].swap = false;
- break;
-
- case 0x0700: // 2352 byte audio
- outtoc.tracks[track-1].trktype = CD_TRACK_AUDIO;
- outinfo.track[track-1].swap = true;
- break;
-
- case 0x0f00: // raw data with sub-channel
- printf("ERROR: Raw data tracks with sub-channel not supported\n");
- fclose(infile);
- return chd_file::error::UNSUPPORTED_FORMAT;
-
- case 0x1000: // audio with sub-channel
- printf("ERROR: Audio tracks with sub-channel not supported\n");
- fclose(infile);
- return chd_file::error::UNSUPPORTED_FORMAT;
-
- case 0x1100: // raw Mode 2 Form 1 with sub-channel
- printf("ERROR: Raw Mode 2 Form 1 tracks with sub-channel not supported\n");
- fclose(infile);
- return chd_file::error::UNSUPPORTED_FORMAT;
-
- default:
- printf("ERROR: Unknown track type %x, contact MAMEDEV!\n", mode);
- fclose(infile);
- return chd_file::error::UNSUPPORTED_FORMAT;
- }
-
- outtoc.tracks[track-1].datasize = size;
-
- outtoc.tracks[track-1].subtype = CD_SUB_NONE;
- outtoc.tracks[track-1].subsize = 0;
-
- outtoc.tracks[track-1].pregap = (uint32_t)(index1-index0)/size;
- outtoc.tracks[track-1].frames = (uint32_t)(track_end-index1)/size;
- outtoc.tracks[track-1].postgap = 0;
- outtoc.tracks[track-1].pgtype = 0;
- outtoc.tracks[track-1].pgsub = CD_SUB_NONE;
- outtoc.tracks[track-1].pgdatasize = 0;
- outtoc.tracks[track-1].pgsubsize = 0;
- outtoc.tracks[track-1].padframes = 0;
-
- offset += (uint32_t)track_end-index1;
- }
- }
-
- if (!memcmp(buffer, "END!", 4))
- {
- done = 1;
- }
- else
- {
- chain_offs += chunk_size + 8;
- }
- }
-
- fclose(infile);
-
- return std::error_condition();
-}
-
-/*-------------------------------------------------
- chdcd_parse_iso - parse a .ISO file
--------------------------------------------------*/
-
-/**
- * @fn std::error_condition chdcd_parse_iso(const char *tocfname, cdrom_toc &outtoc, chdcd_track_input_info &outinfo)
- *
- * @brief Chdcd parse ISO.
- *
- * @param tocfname The tocfname.
- * @param [in,out] outtoc The outtoc.
- * @param [in,out] outinfo The outinfo.
- *
- * @return A std::error_condition.
- */
-
-std::error_condition chdcd_parse_iso(const char *tocfname, cdrom_toc &outtoc, chdcd_track_input_info &outinfo)
-{
- std::string path = std::string(tocfname);
-
- FILE *infile = fopen(tocfname, "rb");
- if (!infile)
- {
- return std::error_condition(errno, std::generic_category());
- }
-
- path = get_file_path(path);
-
- /* clear structures */
- memset(&outtoc, 0, sizeof(outtoc));
- outinfo.reset();
-
- uint64_t size = get_file_size(tocfname);
- fclose(infile);
-
-
- outtoc.numtrks = 1;
-
- outinfo.track[0].fname = tocfname;
- outinfo.track[0].offset = 0;
- outinfo.track[0].idx0offs = 0;
- outinfo.track[0].idx1offs = 0;
-
- if ((size % 2048)==0 ) {
- outtoc.tracks[0].trktype = CD_TRACK_MODE1;
- outtoc.tracks[0].frames = size / 2048;
- outtoc.tracks[0].datasize = 2048;
- outinfo.track[0].swap = false;
- } else if ((size % 2336)==0 ) {
- // 2352 byte mode 2
- outtoc.tracks[0].trktype = CD_TRACK_MODE2;
- outtoc.tracks[0].frames = size / 2336;
- outtoc.tracks[0].datasize = 2336;
- outinfo.track[0].swap = false;
- } else if ((size % 2352)==0 ) {
- // 2352 byte mode 2 raw
- outtoc.tracks[0].trktype = CD_TRACK_MODE2_RAW;
- outtoc.tracks[0].frames = size / 2352;
- outtoc.tracks[0].datasize = 2352;
- outinfo.track[0].swap = false;
- } else {
- printf("ERROR: Unrecognized track type\n");
- return chd_file::error::UNSUPPORTED_FORMAT;
- }
-
- outtoc.tracks[0].subtype = CD_SUB_NONE;
- outtoc.tracks[0].subsize = 0;
-
- outtoc.tracks[0].pregap = 0;
-
- outtoc.tracks[0].postgap = 0;
- outtoc.tracks[0].pgtype = 0;
- outtoc.tracks[0].pgsub = CD_SUB_NONE;
- outtoc.tracks[0].pgdatasize = 0;
- outtoc.tracks[0].pgsubsize = 0;
- outtoc.tracks[0].padframes = 0;
-
-
- return std::error_condition();
-}
-
-/*-------------------------------------------------
- chdcd_parse_gdi - parse a Sega GD-ROM rip
--------------------------------------------------*/
-
-/**
- * @fn static std::error_condition chdcd_parse_gdi(const char *tocfname, cdrom_toc &outtoc, chdcd_track_input_info &outinfo)
- *
- * @brief Chdcd parse GDI.
- *
- * @param tocfname The tocfname.
- * @param [in,out] outtoc The outtoc.
- * @param [in,out] outinfo The outinfo.
- *
- * @return A std::error_condition.
- */
-
-static std::error_condition chdcd_parse_gdi(const char *tocfname, cdrom_toc &outtoc, chdcd_track_input_info &outinfo)
-{
- int i, numtracks;
-
- std::string path = std::string(tocfname);
-
- FILE *infile = fopen(tocfname, "rt");
- if (!infile)
- {
- return std::error_condition(errno, std::generic_category());
- }
-
- path = get_file_path(path);
-
- /* clear structures */
- memset(&outtoc, 0, sizeof(outtoc));
- outinfo.reset();
-
- outtoc.flags = CD_FLAG_GDROM;
-
- fgets(linebuffer,511,infile);
- numtracks=atoi(linebuffer);
-
- for(i=0;i<numtracks;++i)
- {
- char *tok;
- int trknum;
- int trksize,trktype;
- int sz;
-
- fgets(linebuffer,511,infile);
-
- tok=strtok(linebuffer," ");
-
- trknum=atoi(tok)-1;
-
- outinfo.track[trknum].swap=false;
- outinfo.track[trknum].offset=0;
-
- outtoc.tracks[trknum].datasize = 0;
- outtoc.tracks[trknum].subtype = CD_SUB_NONE;
- outtoc.tracks[trknum].subsize = 0;
- outtoc.tracks[trknum].pgsub = CD_SUB_NONE;
-
- tok=strtok(nullptr," ");
- outtoc.tracks[trknum].physframeofs=atoi(tok);
-
- tok=strtok(nullptr," ");
- trktype=atoi(tok);
-
- tok=strtok(nullptr," ");
- trksize=atoi(tok);
-
- if(trktype==4 && trksize==2352)
- {
- outtoc.tracks[trknum].trktype=CD_TRACK_MODE1_RAW;
- outtoc.tracks[trknum].datasize=2352;
- }
- if(trktype==4 && trksize==2048)
- {
- outtoc.tracks[trknum].trktype=CD_TRACK_MODE1;
- outtoc.tracks[trknum].datasize=2048;
- }
- if(trktype==0)
- {
- outtoc.tracks[trknum].trktype=CD_TRACK_AUDIO;
- outtoc.tracks[trknum].datasize=2352;
- outinfo.track[trknum].swap = true;
- }
-
- std::string name;
-
- tok=strtok(nullptr," ");
- name = tok;
- if (tok[0]=='"') {
- do {
- tok=strtok(nullptr," ");
- if (tok!=nullptr) {
- name += " ";
- name += tok;
- }
- } while(tok!=nullptr && (strrchr(tok,'"')-tok !=(strlen(tok)-1)));
- strdelchr(name,'"');
- }
- outinfo.track[trknum].fname.assign(path).append(name);
-
- sz = get_file_size(outinfo.track[trknum].fname.c_str());
-
- outtoc.tracks[trknum].frames = sz/trksize;
- outtoc.tracks[trknum].padframes = 0;
-
- if (trknum != 0)
- {
- int dif=outtoc.tracks[trknum].physframeofs-(outtoc.tracks[trknum-1].frames+outtoc.tracks[trknum-1].physframeofs);
- outtoc.tracks[trknum-1].frames += dif;
- outtoc.tracks[trknum-1].padframes = dif;
- }
- }
-
- #if 0
- for(i=0; i < numtracks; i++)
- {
- printf("%s %d %d %d (true %d)\n", outinfo.track[i].fname.c_str(), outtoc.tracks[i].frames, outtoc.tracks[i].padframes, outtoc.tracks[i].physframeofs, outtoc.tracks[i].frames - outtoc.tracks[i].padframes);
- }
- #endif
-
- /* close the input TOC */
- fclose(infile);
-
- /* store the number of tracks found */
- outtoc.numtrks = numtracks;
-
- return std::error_condition();
-}
-
-/*-------------------------------------------------
- chdcd_parse_cue - parse a CDRWin format CUE file
--------------------------------------------------*/
-
-/**
- * @fn std::error_condition chdcd_parse_cue(const char *tocfname, cdrom_toc &outtoc, chdcd_track_input_info &outinfo)
- *
- * @brief Chdcd parse cue.
- *
- * @param tocfname The tocfname.
- * @param [in,out] outtoc The outtoc.
- * @param [in,out] outinfo The outinfo.
- *
- * @return A std::error_condition.
- */
-
-std::error_condition chdcd_parse_cue(const char *tocfname, cdrom_toc &outtoc, chdcd_track_input_info &outinfo)
-{
- int i, trknum;
- static char token[512];
- std::string lastfname;
- uint32_t wavlen, wavoffs;
- std::string path = std::string(tocfname);
-
- FILE *infile = fopen(tocfname, "rt");
- if (!infile)
- {
- return std::error_condition(errno, std::generic_category());
- }
-
- path = get_file_path(path);
-
- /* clear structures */
- memset(&outtoc, 0, sizeof(outtoc));
- outinfo.reset();
-
- trknum = -1;
- wavoffs = wavlen = 0;
-
- while (!feof(infile))
- {
- /* get the next line */
- fgets(linebuffer, 511, infile);
-
- /* if EOF didn't hit, keep going */
- if (!feof(infile))
- {
- i = 0;
-
- TOKENIZE
-
- if (!strcmp(token, "FILE"))
- {
- /* found the data file for a track */
- TOKENIZE
-
- /* keep the filename */
- lastfname.assign(path).append(token);
-
- /* get the file type */
- TOKENIZE
-
- if (!strcmp(token, "BINARY"))
- {
- outinfo.track[trknum+1].swap = false;
- }
- else if (!strcmp(token, "MOTOROLA"))
- {
- outinfo.track[trknum+1].swap = true;
- }
- else if (!strcmp(token, "WAVE"))
- {
- wavlen = parse_wav_sample(lastfname.c_str(), &wavoffs);
- if (!wavlen)
- {
- fclose(infile);
- printf("ERROR: couldn't read [%s] or not a valid .WAV\n", lastfname.c_str());
- return chd_file::error::INVALID_DATA;
- }
- }
- else
- {
- fclose(infile);
- printf("ERROR: Unhandled track type %s\n", token);
- return chd_file::error::UNSUPPORTED_FORMAT;
- }
- }
- else if (!strcmp(token, "TRACK"))
- {
- /* get the track number */
- TOKENIZE
- trknum = strtoul(token, nullptr, 10) - 1;
-
- /* next token on the line is the track type */
- TOKENIZE
-
- if (wavlen != 0)
- {
- outtoc.tracks[trknum].trktype = CD_TRACK_AUDIO;
- outtoc.tracks[trknum].frames = wavlen/2352;
- outinfo.track[trknum].offset = wavoffs;
- wavoffs = wavlen = 0;
- }
- else
- {
- outtoc.tracks[trknum].trktype = CD_TRACK_MODE1;
- outtoc.tracks[trknum].datasize = 0;
- outinfo.track[trknum].offset = 0;
- }
- outtoc.tracks[trknum].subtype = CD_SUB_NONE;
- outtoc.tracks[trknum].subsize = 0;
- outtoc.tracks[trknum].pgsub = CD_SUB_NONE;
- outtoc.tracks[trknum].pregap = 0;
- outtoc.tracks[trknum].padframes = 0;
- outinfo.track[trknum].idx0offs = -1;
- outinfo.track[trknum].idx1offs = 0;
-
- outinfo.track[trknum].fname.assign(lastfname); // default filename to the last one
-
-// printf("trk %d: fname %s offset %d\n", trknum, outinfo.track[trknum].fname.c_str(), outinfo.track[trknum].offset);
-
- cdrom_convert_type_string_to_track_info(token, &outtoc.tracks[trknum]);
- if (outtoc.tracks[trknum].datasize == 0)
- {
- fclose(infile);
- printf("ERROR: Unknown track type [%s]. Contact MAMEDEV.\n", token);
- return chd_file::error::UNSUPPORTED_FORMAT;
- }
-
- /* next (optional) token on the line is the subcode type */
- TOKENIZE
-
- cdrom_convert_subtype_string_to_track_info(token, &outtoc.tracks[trknum]);
- }
- else if (!strcmp(token, "INDEX")) /* only in bin/cue files */
- {
- int idx, frames;
-
- /* get index number */
- TOKENIZE
- idx = strtoul(token, nullptr, 10);
-
- /* get index */
- TOKENIZE
- frames = msf_to_frames( token );
-
- if (idx == 0)
- {
- outinfo.track[trknum].idx0offs = frames;
- }
- else if (idx == 1)
- {
- outinfo.track[trknum].idx1offs = frames;
- if ((outtoc.tracks[trknum].pregap == 0) && (outinfo.track[trknum].idx0offs != -1))
- {
- outtoc.tracks[trknum].pregap = frames - outinfo.track[trknum].idx0offs;
- outtoc.tracks[trknum].pgtype = outtoc.tracks[trknum].trktype;
- switch (outtoc.tracks[trknum].pgtype)
- {
- case CD_TRACK_MODE1:
- case CD_TRACK_MODE2_FORM1:
- outtoc.tracks[trknum].pgdatasize = 2048;
- break;
-
- case CD_TRACK_MODE1_RAW:
- case CD_TRACK_MODE2_RAW:
- case CD_TRACK_AUDIO:
- outtoc.tracks[trknum].pgdatasize = 2352;
- break;
-
- case CD_TRACK_MODE2:
- case CD_TRACK_MODE2_FORM_MIX:
- outtoc.tracks[trknum].pgdatasize = 2336;
- break;
-
- case CD_TRACK_MODE2_FORM2:
- outtoc.tracks[trknum].pgdatasize = 2324;
- break;
- }
- }
- else // pregap sectors not in file, but we're always using idx0ofs for track length calc now
- {
- outinfo.track[trknum].idx0offs = frames;
- }
- }
- }
- else if (!strcmp(token, "PREGAP"))
- {
- int frames;
-
- /* get index */
- TOKENIZE
- frames = msf_to_frames( token );
-
- outtoc.tracks[trknum].pregap = frames;
- }
- else if (!strcmp(token, "POSTGAP"))
- {
- int frames;
-
- /* get index */
- TOKENIZE
- frames = msf_to_frames( token );
-
- outtoc.tracks[trknum].postgap = frames;
- }
- }
- }
-
- /* close the input CUE */
- fclose(infile);
-
- /* store the number of tracks found */
- outtoc.numtrks = trknum + 1;
-
- /* now go over the files again and set the lengths */
- for (trknum = 0; trknum < outtoc.numtrks; trknum++)
- {
- uint64_t tlen = 0;
-
- // this is true for cue/bin and cue/iso, and we need it for cue/wav since .WAV is little-endian
- if (outtoc.tracks[trknum].trktype == CD_TRACK_AUDIO)
- {
- outinfo.track[trknum].swap = true;
- }
-
- // don't do this for .WAV tracks, we already have their length and offset filled out
- if (outinfo.track[trknum].offset == 0)
- {
- // is this the last track?
- if (trknum == (outtoc.numtrks-1))
- {
- /* if we have the same filename as the last track, do it that way */
- if (trknum != 0 && (outinfo.track[trknum].fname.compare(outinfo.track[trknum-1].fname)==0))
- {
- tlen = get_file_size(outinfo.track[trknum].fname.c_str());
- if (tlen == 0)
- {
- printf("ERROR: couldn't find bin file [%s]\n", outinfo.track[trknum-1].fname.c_str());
- return std::errc::no_such_file_or_directory;
- }
- outinfo.track[trknum].offset = outinfo.track[trknum-1].offset + outtoc.tracks[trknum-1].frames * (outtoc.tracks[trknum-1].datasize + outtoc.tracks[trknum-1].subsize);
- outtoc.tracks[trknum].frames = (tlen - outinfo.track[trknum].offset) / (outtoc.tracks[trknum].datasize + outtoc.tracks[trknum].subsize);
- }
- else /* data files are different */
- {
- tlen = get_file_size(outinfo.track[trknum].fname.c_str());
- if (tlen == 0)
- {
- printf("ERROR: couldn't find bin file [%s]\n", outinfo.track[trknum-1].fname.c_str());
- return std::errc::no_such_file_or_directory;
- }
- tlen /= (outtoc.tracks[trknum].datasize + outtoc.tracks[trknum].subsize);
- outtoc.tracks[trknum].frames = tlen;
- outinfo.track[trknum].offset = 0;
- }
- }
- else
- {
- /* if we have the same filename as the next track, do it that way */
- if (outinfo.track[trknum].fname.compare(outinfo.track[trknum+1].fname)==0)
- {
- outtoc.tracks[trknum].frames = outinfo.track[trknum+1].idx0offs - outinfo.track[trknum].idx0offs;
-
- if (trknum == 0) // track 0 offset is 0
- {
- outinfo.track[trknum].offset = 0;
- }
- else
- {
- outinfo.track[trknum].offset = outinfo.track[trknum-1].offset + outtoc.tracks[trknum-1].frames * (outtoc.tracks[trknum-1].datasize + outtoc.tracks[trknum-1].subsize);
- }
-
- if (!outtoc.tracks[trknum].frames)
- {
- printf("ERROR: unable to determine size of track %d, missing INDEX 01 markers?\n", trknum+1);
- return chd_file::error::INVALID_DATA;
- }
- }
- else /* data files are different */
- {
- tlen = get_file_size(outinfo.track[trknum].fname.c_str());
- if (tlen == 0)
- {
- printf("ERROR: couldn't find bin file [%s]\n", outinfo.track[trknum].fname.c_str());
- return std::errc::no_such_file_or_directory;
- }
- tlen /= (outtoc.tracks[trknum].datasize + outtoc.tracks[trknum].subsize);
- outtoc.tracks[trknum].frames = tlen;
- outinfo.track[trknum].offset = 0;
- }
- }
- }
- //printf("trk %d: %d frames @ offset %d\n", trknum+1, outtoc.tracks[trknum].frames, outinfo.track[trknum].offset);
- }
-
- return std::error_condition();
-}
-
-/*---------------------------------------------------------------------------------------
- chdcd_is_gdicue - determine if CUE contains Redump multi-CUE format for Dreamcast GDI
-----------------------------------------------------------------------------------------*/
-
-/**
- * Dreamcast GDI has two images on one disc, SINGLE-DENSITY and HIGH-DENSITY.
- *
- * Redump stores both images in a single .cue with a REM comment separating the images.
- * This multi-cue format replaces the old flawed .gdi format.
- *
- * http://forum.redump.org/topic/19969/done-sega-dreamcast-multicue-gdi/
- *
- * This function looks for strings "REM SINGLE-DENSITY AREA" & "REM HIGH-DENSITY AREA"
- * indicating the Redump multi-cue format and therefore a Dreamcast GDI disc.
- */
-
-bool chdcd_is_gdicue(const char *tocfname)
-{
- bool has_rem_singledensity = false;
- bool has_rem_highdensity = false;
- std::string path = std::string(tocfname);
-
- FILE *infile = fopen(tocfname, "rt");
- if (!infile)
- {
- return false;
- }
-
- path = get_file_path(path);
-
- while (!feof(infile))
- {
- fgets(linebuffer, 511, infile);
-
- /* if EOF didn't hit, keep going */
- if (!feof(infile))
- {
- has_rem_singledensity = has_rem_singledensity || !strncmp(linebuffer, "REM SINGLE-DENSITY AREA", 23);
- has_rem_highdensity = has_rem_highdensity || !strncmp(linebuffer, "REM HIGH-DENSITY AREA", 21);
- }
- }
-
- fclose(infile);
-
- return has_rem_singledensity && has_rem_highdensity;
-}
-
-/*-----------------------------------------------------------------
- chdcd_parse_gdicue - parse a Redump multi-CUE for Dreamcast GDI
-------------------------------------------------------------------*/
-
-/**
- * @fn std::error_condition chdcd_parse_gdicue(const char *tocfname, cdrom_toc &outtoc, chdcd_track_input_info &outinfo)
- *
- * @brief Chdcd parse cue.
- *
- * @param tocfname The tocfname.
- * @param [in,out] outtoc The outtoc.
- * @param [in,out] outinfo The outinfo.
- *
- * @return A std::error_condition.
- *
- * Dreamcast discs have two images on a single disc. The first image is SINGLE-DENSITY and the second image
- * is HIGH-DENSITY. The SINGLE-DENSITY area starts 0 LBA and HIGH-DENSITY area starts 45000 LBA.
- *
- * There are three Dreamcast disc patterns.
- *
- * Pattern I - (SD) DATA + AUDIO, (HD) DATA
- * Pattern II - (SD) DATA + AUDIO, (HD) DATA + ... + AUDIO
- * Pattern III - (SD) DATA + AUDIO, (HD) DATA + ... + DATA
- *
- * TOSEC layout is preferred and this code adjusts the TOC and INFO generated by a Redump .cue to match the
- * layout from a TOSEC .gdi.
- */
-
-std::error_condition chdcd_parse_gdicue(const char *tocfname, cdrom_toc &outtoc, chdcd_track_input_info &outinfo)
-{
- int i, trknum;
- static char token[512];
- std::string lastfname;
- uint32_t wavlen, wavoffs;
- std::string path = std::string(tocfname);
- enum gdi_area current_area = SINGLE_DENSITY;
- enum gdi_pattern disc_pattern = TYPE_UNKNOWN;
-
- FILE *infile = fopen(tocfname, "rt");
- if (!infile)
- {
- return std::error_condition(errno, std::generic_category());
- }
-
- path = get_file_path(path);
-
- /* clear structures */
- memset(&outtoc, 0, sizeof(outtoc));
- outinfo.reset();
-
- trknum = -1;
- wavoffs = wavlen = 0;
-
- outtoc.flags = CD_FLAG_GDROM;
-
- while (!feof(infile))
- {
- /* get the next line */
- fgets(linebuffer, 511, infile);
-
- /* if EOF didn't hit, keep going */
- if (!feof(infile))
- {
- /* single-density area starts LBA = 0 */
- if (!strncmp(linebuffer, "REM SINGLE-DENSITY AREA", 23))
- {
- current_area = SINGLE_DENSITY;
- continue;
- }
-
- /* high-density area starts LBA = 45000 */
- if (!strncmp(linebuffer, "REM HIGH-DENSITY AREA", 21))
- {
- current_area = HIGH_DENSITY;
- continue;
- }
-
- i = 0;
-
- TOKENIZE
-
- if (!strcmp(token, "FILE"))
- {
- /* found the data file for a track */
- TOKENIZE
-
- /* keep the filename */
- lastfname.assign(path).append(token);
-
- /* get the file type */
- TOKENIZE
-
- if (!strcmp(token, "BINARY"))
- {
- outinfo.track[trknum+1].swap = false;
- }
- else if (!strcmp(token, "MOTOROLA"))
- {
- outinfo.track[trknum+1].swap = true;
- }
- else if (!strcmp(token, "WAVE"))
- {
- wavlen = parse_wav_sample(lastfname.c_str(), &wavoffs);
- if (!wavlen)
- {
- fclose(infile);
- printf("ERROR: couldn't read [%s] or not a valid .WAV\n", lastfname.c_str());
- return chd_file::error::INVALID_DATA;
- }
- }
- else
- {
- fclose(infile);
- printf("ERROR: Unhandled track type %s\n", token);
- return chd_file::error::UNSUPPORTED_FORMAT;
- }
- }
- else if (!strcmp(token, "TRACK"))
- {
- /* get the track number */
- TOKENIZE
- trknum = strtoul(token, nullptr, 10) - 1;
-
- /* next token on the line is the track type */
- TOKENIZE
-
- if (wavlen != 0)
- {
- outtoc.tracks[trknum].trktype = CD_TRACK_AUDIO;
- outtoc.tracks[trknum].frames = wavlen/2352;
- outinfo.track[trknum].offset = wavoffs;
- wavoffs = wavlen = 0;
- }
- else
- {
- outtoc.tracks[trknum].trktype = CD_TRACK_MODE1;
- outtoc.tracks[trknum].datasize = 0;
- outinfo.track[trknum].offset = 0;
- }
- outtoc.tracks[trknum].subtype = CD_SUB_NONE;
- outtoc.tracks[trknum].subsize = 0;
- outtoc.tracks[trknum].pgsub = CD_SUB_NONE;
- outtoc.tracks[trknum].pregap = 0;
- outtoc.tracks[trknum].padframes = 0;
- outtoc.tracks[trknum].multicuearea = current_area;
- outinfo.track[trknum].idx0offs = -1;
- outinfo.track[trknum].idx1offs = 0;
-
- outinfo.track[trknum].fname.assign(lastfname); // default filename to the last one
-
-#if 0
- printf("trk %d: fname %s offset %d area %d\n", trknum, outinfo.track[trknum].fname.c_str(), outinfo.track[trknum].offset, outtoc.tracks[trknum].multicuearea);
-#endif
-
- cdrom_convert_type_string_to_track_info(token, &outtoc.tracks[trknum]);
- if (outtoc.tracks[trknum].datasize == 0)
- {
- fclose(infile);
- printf("ERROR: Unknown track type [%s]. Contact MAMEDEV.\n", token);
- return chd_file::error::UNSUPPORTED_FORMAT;
- }
-
- /* next (optional) token on the line is the subcode type */
- TOKENIZE
-
- cdrom_convert_subtype_string_to_track_info(token, &outtoc.tracks[trknum]);
- }
- else if (!strcmp(token, "INDEX")) /* only in bin/cue files */
- {
- int idx, frames;
-
- /* get index number */
- TOKENIZE
- idx = strtoul(token, nullptr, 10);
-
- /* get index */
- TOKENIZE
- frames = msf_to_frames( token );
-
- if (idx == 0)
- {
- outinfo.track[trknum].idx0offs = frames;
- }
- else if (idx == 1)
- {
- outinfo.track[trknum].idx1offs = frames;
- if ((outtoc.tracks[trknum].pregap == 0) && (outinfo.track[trknum].idx0offs != -1))
- {
- outtoc.tracks[trknum].pregap = frames - outinfo.track[trknum].idx0offs;
- outtoc.tracks[trknum].pgtype = outtoc.tracks[trknum].trktype;
- switch (outtoc.tracks[trknum].pgtype)
- {
- case CD_TRACK_MODE1:
- case CD_TRACK_MODE2_FORM1:
- outtoc.tracks[trknum].pgdatasize = 2048;
- break;
-
- case CD_TRACK_MODE1_RAW:
- case CD_TRACK_MODE2_RAW:
- case CD_TRACK_AUDIO:
- outtoc.tracks[trknum].pgdatasize = 2352;
- break;
-
- case CD_TRACK_MODE2:
- case CD_TRACK_MODE2_FORM_MIX:
- outtoc.tracks[trknum].pgdatasize = 2336;
- break;
-
- case CD_TRACK_MODE2_FORM2:
- outtoc.tracks[trknum].pgdatasize = 2324;
- break;
- }
- }
- else // pregap sectors not in file, but we're always using idx0ofs for track length calc now
- {
- outinfo.track[trknum].idx0offs = frames;
- }
- }
- }
- else if (!strcmp(token, "PREGAP"))
- {
- int frames;
-
- /* get index */
- TOKENIZE
- frames = msf_to_frames( token );
-
- outtoc.tracks[trknum].pregap = frames;
- }
- else if (!strcmp(token, "POSTGAP"))
- {
- int frames;
-
- /* get index */
- TOKENIZE
- frames = msf_to_frames( token );
-
- outtoc.tracks[trknum].postgap = frames;
- }
- }
- }
-
- /* close the input CUE */
- fclose(infile);
-
- /* store the number of tracks found */
- outtoc.numtrks = trknum + 1;
-
- /* now go over the files again and set the lengths */
- for (trknum = 0; trknum < outtoc.numtrks; trknum++)
- {
- uint64_t tlen = 0;
-
- // this is true for cue/bin and cue/iso, and we need it for cue/wav since .WAV is little-endian
- if (outtoc.tracks[trknum].trktype == CD_TRACK_AUDIO)
- {
- outinfo.track[trknum].swap = true;
- }
-
- // don't do this for .WAV tracks, we already have their length and offset filled out
- if (outinfo.track[trknum].offset == 0)
- {
- // is this the last track?
- if (trknum == (outtoc.numtrks-1))
- {
- /* if we have the same filename as the last track, do it that way */
- if (trknum != 0 && (outinfo.track[trknum].fname.compare(outinfo.track[trknum-1].fname)==0))
- {
- tlen = get_file_size(outinfo.track[trknum].fname.c_str());
- if (tlen == 0)
- {
- printf("ERROR: couldn't find bin file [%s]\n", outinfo.track[trknum-1].fname.c_str());
- return std::errc::no_such_file_or_directory;
- }
- outinfo.track[trknum].offset = outinfo.track[trknum-1].offset + outtoc.tracks[trknum-1].frames * (outtoc.tracks[trknum-1].datasize + outtoc.tracks[trknum-1].subsize);
- outtoc.tracks[trknum].frames = (tlen - outinfo.track[trknum].offset) / (outtoc.tracks[trknum].datasize + outtoc.tracks[trknum].subsize);
- }
- else /* data files are different */
- {
- tlen = get_file_size(outinfo.track[trknum].fname.c_str());
- if (tlen == 0)
- {
- printf("ERROR: couldn't find bin file [%s]\n", outinfo.track[trknum-1].fname.c_str());
- return std::errc::no_such_file_or_directory;
- }
- tlen /= (outtoc.tracks[trknum].datasize + outtoc.tracks[trknum].subsize);
- outtoc.tracks[trknum].frames = tlen;
- outinfo.track[trknum].offset = 0;
- }
- }
- else
- {
- /* if we have the same filename as the next track, do it that way */
- if (outinfo.track[trknum].fname.compare(outinfo.track[trknum+1].fname)==0)
- {
- outtoc.tracks[trknum].frames = outinfo.track[trknum+1].idx0offs - outinfo.track[trknum].idx0offs;
-
- if (trknum == 0) // track 0 offset is 0
- {
- outinfo.track[trknum].offset = 0;
- }
- else
- {
- outinfo.track[trknum].offset = outinfo.track[trknum-1].offset + outtoc.tracks[trknum-1].frames * (outtoc.tracks[trknum-1].datasize + outtoc.tracks[trknum-1].subsize);
- }
-
- if (!outtoc.tracks[trknum].frames)
- {
- printf("ERROR: unable to determine size of track %d, missing INDEX 01 markers?\n", trknum+1);
- return chd_file::error::INVALID_DATA;
- }
- }
- else /* data files are different */
- {
- tlen = get_file_size(outinfo.track[trknum].fname.c_str());
- if (tlen == 0)
- {
- printf("ERROR: couldn't find bin file [%s]\n", outinfo.track[trknum].fname.c_str());
- return std::errc::no_such_file_or_directory;
- }
- tlen /= (outtoc.tracks[trknum].datasize + outtoc.tracks[trknum].subsize);
- outtoc.tracks[trknum].frames = tlen;
- outinfo.track[trknum].offset = 0;
- }
- }
- }
- }
-
- /*
- * Dreamcast patterns are identified by track types and number of tracks
- */
- if (outtoc.numtrks > 4 && outtoc.tracks[outtoc.numtrks-1].pgtype == CD_TRACK_MODE1_RAW)
- {
- if (outtoc.tracks[outtoc.numtrks-2].pgtype == CD_TRACK_AUDIO)
- disc_pattern = TYPE_III_SPLIT;
- else
- disc_pattern = TYPE_III;
- }
- else if (outtoc.numtrks > 3)
- {
- if (outtoc.tracks[outtoc.numtrks-1].pgtype == CD_TRACK_AUDIO)
- disc_pattern = TYPE_II;
- else
- disc_pattern = TYPE_III;
- }
- else if (outtoc.numtrks == 3)
- {
- disc_pattern = TYPE_I;
- }
-
- /*
- * Strip pregaps from Redump tracks and adjust the LBA offset to match TOSEC layout
- */
- for (trknum = 1; trknum < outtoc.numtrks; trknum++)
- {
- uint32_t prev_pregap = outtoc.tracks[trknum-1].pregap;
- uint32_t prev_offset = prev_pregap * (outtoc.tracks[trknum-1].datasize + outtoc.tracks[trknum-1].subsize);
- uint32_t this_pregap = outtoc.tracks[trknum].pregap;
- uint32_t this_offset = this_pregap * (outtoc.tracks[trknum].datasize + outtoc.tracks[trknum].subsize);
-
- if (outtoc.tracks[trknum-1].pgtype != CD_TRACK_AUDIO)
- {
- // pad previous DATA track to match TOSEC layout
- outtoc.tracks[trknum-1].frames += this_pregap;
- outtoc.tracks[trknum-1].padframes += this_pregap;
- }
-
- if (outtoc.tracks[trknum-1].pgtype == CD_TRACK_AUDIO && outtoc.tracks[trknum].pgtype == CD_TRACK_AUDIO)
- {
- // shift previous AUDIO track to match TOSEC layout
- outinfo.track[trknum-1].offset += prev_offset;
- outtoc.tracks[trknum-1].splitframes += prev_pregap;
- }
-
- if (outtoc.tracks[trknum-1].pgtype == CD_TRACK_AUDIO && outtoc.tracks[trknum].pgtype != CD_TRACK_AUDIO)
- {
- // shrink previous AUDIO track to match TOSEC layout
- outtoc.tracks[trknum-1].frames -= prev_pregap;
- outinfo.track[trknum-1].offset += prev_offset;
- }
-
- if (outtoc.tracks[trknum].pgtype == CD_TRACK_AUDIO && trknum == outtoc.numtrks-1)
- {
- // shrink final AUDIO track to match TOSEC layout
- outtoc.tracks[trknum].frames -= this_pregap;
- outinfo.track[trknum].offset += this_offset;
- }
- }
-
- /*
- * Special handling for TYPE_III_SPLIT, pregap in last track contains 75 frames audio and 150 frames data
- */
- if (disc_pattern == TYPE_III_SPLIT)
- {
- assert(outtoc.tracks[outtoc.numtrks-1].pregap == 225);
-
- // grow the AUDIO track into DATA track by 75 frames as per Pattern III
- outtoc.tracks[outtoc.numtrks-2].frames += 225;
- outtoc.tracks[outtoc.numtrks-2].padframes += 150;
- outinfo.track[outtoc.numtrks-2].offset = 150 * (outtoc.tracks[outtoc.numtrks-2].datasize+outtoc.tracks[outtoc.numtrks-2].subsize);
- outtoc.tracks[outtoc.numtrks-2].splitframes = 75;
-
- // skip the pregap when reading the DATA track
- outtoc.tracks[outtoc.numtrks-1].frames -= 225;
- outinfo.track[outtoc.numtrks-1].offset += 225 * (outtoc.tracks[outtoc.numtrks-1].datasize+outtoc.tracks[outtoc.numtrks-1].subsize);
- }
-
- /*
- * TOC now matches TOSEC layout, set LBA for every track with HIGH-DENSITY area @ LBA 45000
- */
- for (trknum = 1; trknum < outtoc.numtrks; trknum++)
- {
- if (outtoc.tracks[trknum].multicuearea == HIGH_DENSITY && outtoc.tracks[trknum-1].multicuearea == SINGLE_DENSITY)
- {
- outtoc.tracks[trknum].physframeofs = 45000;
- int dif=outtoc.tracks[trknum].physframeofs-(outtoc.tracks[trknum-1].frames+outtoc.tracks[trknum-1].physframeofs);
- outtoc.tracks[trknum-1].frames += dif;
- outtoc.tracks[trknum-1].padframes = dif;
- }
- else
- {
- outtoc.tracks[trknum].physframeofs = outtoc.tracks[trknum-1].physframeofs + outtoc.tracks[trknum-1].frames;
- }
-
- // no longer need the pregap info, zeroed out to match TOSEC layout
- outtoc.tracks[trknum].pregap = 0;
- outtoc.tracks[trknum].pgtype = 0;
- }
-
-#if 0
- for (trknum = 0; trknum < outtoc.numtrks; trknum++)
- {
- printf("trk %d: %d frames @ offset %d, pad=%d, split=%d, area=%d, phys=%d, pregap=%d, pgtype=%d, idx0=%d, idx1=%d, (true %d)\n",
- trknum+1,
- outtoc.tracks[trknum].frames,
- outinfo.track[trknum].offset,
- outtoc.tracks[trknum].padframes,
- outtoc.tracks[trknum].splitframes,
- outtoc.tracks[trknum].multicuearea,
- outtoc.tracks[trknum].physframeofs,
- outtoc.tracks[trknum].pregap,
- outtoc.tracks[trknum].pgtype,
- outinfo.track[trknum].idx0offs,
- outinfo.track[trknum].idx1offs,
- outtoc.tracks[trknum].frames - outtoc.tracks[trknum].padframes);
- }
-#endif
-
- return std::error_condition();
-}
-
-/*-------------------------------------------------
- chdcd_parse_toc - parse a CDRDAO format TOC file
--------------------------------------------------*/
-
-/**
- * @fn std::error_condition chdcd_parse_toc(const char *tocfname, cdrom_toc &outtoc, chdcd_track_input_info &outinfo)
- *
- * @brief Chdcd parse TOC.
- *
- * @param tocfname The tocfname.
- * @param [in,out] outtoc The outtoc.
- * @param [in,out] outinfo The outinfo.
- *
- * @return A std::error_condition.
- */
-
-std::error_condition chdcd_parse_toc(const char *tocfname, cdrom_toc &outtoc, chdcd_track_input_info &outinfo)
-{
- int i, trknum;
- static char token[512];
- char tocftemp[512];
-
- strcpy(tocftemp, tocfname);
- for (i = 0; i < strlen(tocfname); i++)
- {
- tocftemp[i] = tolower(tocftemp[i]);
- }
-
- if (strstr(tocftemp,".gdi"))
- {
- return chdcd_parse_gdi(tocfname, outtoc, outinfo);
- }
-
- if (strstr(tocftemp,".cue"))
- {
- if (chdcd_is_gdicue(tocfname))
- return chdcd_parse_gdicue(tocfname, outtoc, outinfo);
- else
- return chdcd_parse_cue(tocfname, outtoc, outinfo);
- }
-
- if (strstr(tocftemp,".nrg"))
- {
- return chdcd_parse_nero(tocfname, outtoc, outinfo);
- }
-
- if (strstr(tocftemp,".iso") || strstr(tocftemp,".cdr") || strstr(tocftemp,".toast"))
- {
- return chdcd_parse_iso(tocfname, outtoc, outinfo);
- }
-
- std::string path = std::string(tocfname);
-
- FILE *infile = fopen(tocfname, "rt");
- if (!infile)
- {
- return std::error_condition(errno, std::generic_category());
- }
-
- path = get_file_path(path);
-
- /* clear structures */
- memset(&outtoc, 0, sizeof(outtoc));
- outinfo.reset();
-
- trknum = -1;
-
- while (!feof(infile))
- {
- /* get the next line */
- fgets(linebuffer, 511, infile);
-
- /* if EOF didn't hit, keep going */
- if (!feof(infile))
- {
- i = 0;
-
- TOKENIZE
-
- if ((!strcmp(token, "DATAFILE")) || (!strcmp(token, "AUDIOFILE")) || (!strcmp(token, "FILE")))
- {
- int f;
-
- /* found the data file for a track */
- TOKENIZE
-
- /* keep the filename */
- outinfo.track[trknum].fname.assign(path).append(token);
-
- /* get either the offset or the length */
- TOKENIZE
-
- if (!strcmp(token, "SWAP"))
- {
- TOKENIZE
-
- outinfo.track[trknum].swap = true;
- }
- else
- {
- outinfo.track[trknum].swap = false;
- }
-
- if (token[0] == '#')
- {
- /* it's a decimal offset, use it */
- f = strtoul(&token[1], nullptr, 10);
- }
- else if (isdigit((uint8_t)token[0]))
- {
- /* convert the time to an offset */
- f = msf_to_frames( token );
-
- f *= (outtoc.tracks[trknum].datasize + outtoc.tracks[trknum].subsize);
- }
- else
- {
- f = 0;
- }
-
- outinfo.track[trknum].offset = f;
-
- TOKENIZE
-
- if (isdigit((uint8_t)token[0]))
- {
- // this could be the length or an offset from the previous field.
- f = msf_to_frames( token );
-
- TOKENIZE
-
- if (isdigit((uint8_t)token[0]))
- {
- // it was an offset.
- f *= (outtoc.tracks[trknum].datasize + outtoc.tracks[trknum].subsize);
-
- outinfo.track[trknum].offset += f;
-
- // this is the length.
- f = msf_to_frames( token );
- }
- }
- else if( trknum == 0 && outinfo.track[trknum].offset != 0 )
- {
- /* the 1st track might have a length with no offset */
- f = outinfo.track[trknum].offset / (outtoc.tracks[trknum].datasize + outtoc.tracks[trknum].subsize);
- outinfo.track[trknum].offset = 0;
- }
- else
- {
- /* guesstimate the track length? */
- f = 0;
- }
-
- outtoc.tracks[trknum].frames = f;
- }
- else if (!strcmp(token, "TRACK"))
- {
- trknum++;
-
- /* next token on the line is the track type */
- TOKENIZE
-
- outtoc.tracks[trknum].trktype = CD_TRACK_MODE1;
- outtoc.tracks[trknum].datasize = 0;
- outtoc.tracks[trknum].subtype = CD_SUB_NONE;
- outtoc.tracks[trknum].subsize = 0;
- outtoc.tracks[trknum].pgsub = CD_SUB_NONE;
- outtoc.tracks[trknum].padframes = 0;
-
- cdrom_convert_type_string_to_track_info(token, &outtoc.tracks[trknum]);
- if (outtoc.tracks[trknum].datasize == 0)
- {
- fclose(infile);
- printf("ERROR: Unknown track type [%s]. Contact MAMEDEV.\n", token);
- return chd_file::error::UNSUPPORTED_FORMAT;
- }
-
- /* next (optional) token on the line is the subcode type */
- TOKENIZE
-
- cdrom_convert_subtype_string_to_track_info(token, &outtoc.tracks[trknum]);
- }
- else if (!strcmp(token, "START"))
- {
- int frames;
-
- /* get index */
- TOKENIZE
- frames = msf_to_frames( token );
-
- outtoc.tracks[trknum].pregap = frames;
- }
- }
- }
-
- /* close the input TOC */
- fclose(infile);
-
- /* store the number of tracks found */
- outtoc.numtrks = trknum + 1;
-
- return std::error_condition();
-}
diff --git a/src/lib/util/chdcd.h b/src/lib/util/chdcd.h
deleted file mode 100644
index 95f214e5831..00000000000
--- a/src/lib/util/chdcd.h
+++ /dev/null
@@ -1,40 +0,0 @@
-// license:BSD-3-Clause
-// copyright-holders:R. Belmont
-/***************************************************************************
-
- CDRDAO TOC parser for CHD compression frontend
-
-***************************************************************************/
-#ifndef MAME_LIB_UTIL_CHDCD_H
-#define MAME_LIB_UTIL_CHDCD_H
-
-#pragma once
-
-#include "cdrom.h"
-
-#include <system_error>
-
-
-struct chdcd_track_input_entry
-{
- chdcd_track_input_entry() { reset(); }
- void reset() { fname.clear(); offset = idx0offs = idx1offs = 0; swap = false; }
-
- std::string fname; // filename for each track
- uint32_t offset; // offset in the data file for each track
- bool swap; // data needs to be byte swapped
- uint32_t idx0offs;
- uint32_t idx1offs;
-};
-
-struct chdcd_track_input_info
-{
- void reset() { for (auto & elem : track) elem.reset(); }
-
- chdcd_track_input_entry track[CD_MAX_TRACKS];
-};
-
-
-std::error_condition chdcd_parse_toc(const char *tocfname, cdrom_toc &outtoc, chdcd_track_input_info &outinfo);
-
-#endif // MAME_LIB_UTIL_CHDCD_H
diff --git a/src/lib/util/chdcodec.cpp b/src/lib/util/chdcodec.cpp
index cd708d0f507..7d3f3185212 100644
--- a/src/lib/util/chdcodec.cpp
+++ b/src/lib/util/chdcodec.cpp
@@ -300,12 +300,12 @@ public:
// construction/destruction
chd_cd_compressor(chd_file &chd, uint32_t hunkbytes, bool lossy)
: chd_compressor(chd, hunkbytes, lossy),
- m_base_compressor(chd, (hunkbytes / CD_FRAME_SIZE) * CD_MAX_SECTOR_DATA, lossy),
- m_subcode_compressor(chd, (hunkbytes / CD_FRAME_SIZE) * CD_MAX_SUBCODE_DATA, lossy),
- m_buffer(hunkbytes + (hunkbytes / CD_FRAME_SIZE) * CD_MAX_SUBCODE_DATA)
+ m_base_compressor(chd, (hunkbytes / cdrom_file::FRAME_SIZE) * cdrom_file::MAX_SECTOR_DATA, lossy),
+ m_subcode_compressor(chd, (hunkbytes / cdrom_file::FRAME_SIZE) * cdrom_file::MAX_SUBCODE_DATA, lossy),
+ m_buffer(hunkbytes + (hunkbytes / cdrom_file::FRAME_SIZE) * cdrom_file::MAX_SUBCODE_DATA)
{
// make sure the CHD's hunk size is an even multiple of the frame size
- if (hunkbytes % CD_FRAME_SIZE != 0)
+ if (hunkbytes % cdrom_file::FRAME_SIZE != 0)
throw std::error_condition(chd_file::error::CODEC_ERROR);
}
@@ -313,7 +313,7 @@ public:
virtual uint32_t compress(const uint8_t *src, uint32_t srclen, uint8_t *dest) override
{
// determine header bytes
- uint32_t frames = srclen / CD_FRAME_SIZE;
+ uint32_t frames = srclen / cdrom_file::FRAME_SIZE;
uint32_t complen_bytes = (srclen < 65536) ? 2 : 3;
uint32_t ecc_bytes = (frames + 7) / 8;
uint32_t header_bytes = ecc_bytes + complen_bytes;
@@ -324,21 +324,21 @@ public:
// copy audio data followed by subcode data
for (uint32_t framenum = 0; framenum < frames; framenum++)
{
- memcpy(&m_buffer[framenum * CD_MAX_SECTOR_DATA], &src[framenum * CD_FRAME_SIZE], CD_MAX_SECTOR_DATA);
- memcpy(&m_buffer[frames * CD_MAX_SECTOR_DATA + framenum * CD_MAX_SUBCODE_DATA], &src[framenum * CD_FRAME_SIZE + CD_MAX_SECTOR_DATA], CD_MAX_SUBCODE_DATA);
+ memcpy(&m_buffer[framenum * cdrom_file::MAX_SECTOR_DATA], &src[framenum * cdrom_file::FRAME_SIZE], cdrom_file::MAX_SECTOR_DATA);
+ memcpy(&m_buffer[frames * cdrom_file::MAX_SECTOR_DATA + framenum * cdrom_file::MAX_SUBCODE_DATA], &src[framenum * cdrom_file::FRAME_SIZE + cdrom_file::MAX_SECTOR_DATA], cdrom_file::MAX_SUBCODE_DATA);
// clear out ECC data if we can
- uint8_t *sector = &m_buffer[framenum * CD_MAX_SECTOR_DATA];
- if (memcmp(sector, f_cd_sync_header, sizeof(f_cd_sync_header)) == 0 && ecc_verify(sector))
+ uint8_t *sector = &m_buffer[framenum * cdrom_file::MAX_SECTOR_DATA];
+ if (memcmp(sector, f_cd_sync_header, sizeof(f_cd_sync_header)) == 0 && cdrom_file::ecc_verify(sector))
{
dest[framenum / 8] |= 1 << (framenum % 8);
memset(sector, 0, sizeof(f_cd_sync_header));
- ecc_clear(sector);
+ cdrom_file::ecc_clear(sector);
}
}
// encode the base portion
- uint32_t complen = m_base_compressor.compress(&m_buffer[0], frames * CD_MAX_SECTOR_DATA, &dest[header_bytes]);
+ uint32_t complen = m_base_compressor.compress(&m_buffer[0], frames * cdrom_file::MAX_SECTOR_DATA, &dest[header_bytes]);
if (complen >= srclen)
throw std::error_condition(chd_file::error::COMPRESSION_ERROR);
@@ -349,7 +349,7 @@ public:
dest[ecc_bytes + 2] = complen >> ((complen_bytes - 3) * 8);
// encode the subcode
- return header_bytes + complen + m_subcode_compressor.compress(&m_buffer[frames * CD_MAX_SECTOR_DATA], frames * CD_MAX_SUBCODE_DATA, &dest[header_bytes + complen]);
+ return header_bytes + complen + m_subcode_compressor.compress(&m_buffer[frames * cdrom_file::MAX_SECTOR_DATA], frames * cdrom_file::MAX_SUBCODE_DATA, &dest[header_bytes + complen]);
}
private:
@@ -369,12 +369,12 @@ public:
// construction/destruction
chd_cd_decompressor(chd_file &chd, uint32_t hunkbytes, bool lossy)
: chd_decompressor(chd, hunkbytes, lossy),
- m_base_decompressor(chd, (hunkbytes / CD_FRAME_SIZE) * CD_MAX_SECTOR_DATA, lossy),
- m_subcode_decompressor(chd, (hunkbytes / CD_FRAME_SIZE) * CD_MAX_SUBCODE_DATA, lossy),
+ m_base_decompressor(chd, (hunkbytes / cdrom_file::FRAME_SIZE) * cdrom_file::MAX_SECTOR_DATA, lossy),
+ m_subcode_decompressor(chd, (hunkbytes / cdrom_file::FRAME_SIZE) * cdrom_file::MAX_SUBCODE_DATA, lossy),
m_buffer(hunkbytes)
{
// make sure the CHD's hunk size is an even multiple of the frame size
- if (hunkbytes % CD_FRAME_SIZE != 0)
+ if (hunkbytes % cdrom_file::FRAME_SIZE != 0)
throw std::error_condition(chd_file::error::CODEC_ERROR);
}
@@ -382,7 +382,7 @@ public:
virtual void decompress(const uint8_t *src, uint32_t complen, uint8_t *dest, uint32_t destlen) override
{
// determine header bytes
- uint32_t frames = destlen / CD_FRAME_SIZE;
+ uint32_t frames = destlen / cdrom_file::FRAME_SIZE;
uint32_t complen_bytes = (destlen < 65536) ? 2 : 3;
uint32_t ecc_bytes = (frames + 7) / 8;
uint32_t header_bytes = ecc_bytes + complen_bytes;
@@ -393,21 +393,21 @@ public:
complen_base = (complen_base << 8) | src[ecc_bytes + 2];
// reset and decode
- m_base_decompressor.decompress(&src[header_bytes], complen_base, &m_buffer[0], frames * CD_MAX_SECTOR_DATA);
- m_subcode_decompressor.decompress(&src[header_bytes + complen_base], complen - complen_base - header_bytes, &m_buffer[frames * CD_MAX_SECTOR_DATA], frames * CD_MAX_SUBCODE_DATA);
+ m_base_decompressor.decompress(&src[header_bytes], complen_base, &m_buffer[0], frames * cdrom_file::MAX_SECTOR_DATA);
+ m_subcode_decompressor.decompress(&src[header_bytes + complen_base], complen - complen_base - header_bytes, &m_buffer[frames * cdrom_file::MAX_SECTOR_DATA], frames * cdrom_file::MAX_SUBCODE_DATA);
// reassemble the data
for (uint32_t framenum = 0; framenum < frames; framenum++)
{
- memcpy(&dest[framenum * CD_FRAME_SIZE], &m_buffer[framenum * CD_MAX_SECTOR_DATA], CD_MAX_SECTOR_DATA);
- memcpy(&dest[framenum * CD_FRAME_SIZE + CD_MAX_SECTOR_DATA], &m_buffer[frames * CD_MAX_SECTOR_DATA + framenum * CD_MAX_SUBCODE_DATA], CD_MAX_SUBCODE_DATA);
+ memcpy(&dest[framenum * cdrom_file::FRAME_SIZE], &m_buffer[framenum * cdrom_file::MAX_SECTOR_DATA], cdrom_file::MAX_SECTOR_DATA);
+ memcpy(&dest[framenum * cdrom_file::FRAME_SIZE + cdrom_file::MAX_SECTOR_DATA], &m_buffer[frames * cdrom_file::MAX_SECTOR_DATA + framenum * cdrom_file::MAX_SUBCODE_DATA], cdrom_file::MAX_SUBCODE_DATA);
// reconstitute the ECC data and sync header
- uint8_t *sector = &dest[framenum * CD_FRAME_SIZE];
+ uint8_t *sector = &dest[framenum * cdrom_file::FRAME_SIZE];
if ((src[framenum / 8] & (1 << (framenum % 8))) != 0)
{
memcpy(sector, f_cd_sync_header, sizeof(f_cd_sync_header));
- ecc_generate(sector);
+ cdrom_file::ecc_generate(sector);
}
}
}
@@ -1427,7 +1427,7 @@ chd_cd_flac_compressor::chd_cd_flac_compressor(chd_file &chd, uint32_t hunkbytes
m_buffer(hunkbytes)
{
// make sure the CHD's hunk size is an even multiple of the frame size
- if (hunkbytes % CD_FRAME_SIZE != 0)
+ if (hunkbytes % cdrom_file::FRAME_SIZE != 0)
throw std::error_condition(chd_file::error::CODEC_ERROR);
// determine whether we want native or swapped samples
@@ -1438,7 +1438,7 @@ chd_cd_flac_compressor::chd_cd_flac_compressor(chd_file &chd, uint32_t hunkbytes
// configure the encoder
m_encoder.set_sample_rate(44100);
m_encoder.set_num_channels(2);
- m_encoder.set_block_size(blocksize((hunkbytes / CD_FRAME_SIZE) * CD_MAX_SECTOR_DATA));
+ m_encoder.set_block_size(blocksize((hunkbytes / cdrom_file::FRAME_SIZE) * cdrom_file::MAX_SECTOR_DATA));
m_encoder.set_strip_metadata(true);
// initialize the deflater
@@ -1473,25 +1473,25 @@ chd_cd_flac_compressor::~chd_cd_flac_compressor()
uint32_t chd_cd_flac_compressor::compress(const uint8_t *src, uint32_t srclen, uint8_t *dest)
{
// copy audio data followed by subcode data
- uint32_t frames = hunkbytes() / CD_FRAME_SIZE;
+ uint32_t frames = hunkbytes() / cdrom_file::FRAME_SIZE;
for (uint32_t framenum = 0; framenum < frames; framenum++)
{
- memcpy(&m_buffer[framenum * CD_MAX_SECTOR_DATA], &src[framenum * CD_FRAME_SIZE], CD_MAX_SECTOR_DATA);
- memcpy(&m_buffer[frames * CD_MAX_SECTOR_DATA + framenum * CD_MAX_SUBCODE_DATA], &src[framenum * CD_FRAME_SIZE + CD_MAX_SECTOR_DATA], CD_MAX_SUBCODE_DATA);
+ memcpy(&m_buffer[framenum * cdrom_file::MAX_SECTOR_DATA], &src[framenum * cdrom_file::FRAME_SIZE], cdrom_file::MAX_SECTOR_DATA);
+ memcpy(&m_buffer[frames * cdrom_file::MAX_SECTOR_DATA + framenum * cdrom_file::MAX_SUBCODE_DATA], &src[framenum * cdrom_file::FRAME_SIZE + cdrom_file::MAX_SECTOR_DATA], cdrom_file::MAX_SUBCODE_DATA);
}
// reset and encode the audio portion
m_encoder.reset(dest, hunkbytes());
uint8_t *buffer = &m_buffer[0];
- if (!m_encoder.encode_interleaved(reinterpret_cast<int16_t *>(buffer), frames * CD_MAX_SECTOR_DATA/4, m_swap_endian))
+ if (!m_encoder.encode_interleaved(reinterpret_cast<int16_t *>(buffer), frames * cdrom_file::MAX_SECTOR_DATA/4, m_swap_endian))
throw std::error_condition(chd_file::error::COMPRESSION_ERROR);
// finish up
uint32_t complen = m_encoder.finish();
// deflate the subcode data
- m_deflater.next_in = const_cast<Bytef *>(&m_buffer[frames * CD_MAX_SECTOR_DATA]);
- m_deflater.avail_in = frames * CD_MAX_SUBCODE_DATA;
+ m_deflater.next_in = const_cast<Bytef *>(&m_buffer[frames * cdrom_file::MAX_SECTOR_DATA]);
+ m_deflater.avail_in = frames * cdrom_file::MAX_SUBCODE_DATA;
m_deflater.total_in = 0;
m_deflater.next_out = &dest[complen];
m_deflater.avail_out = hunkbytes() - complen;
@@ -1526,7 +1526,7 @@ uint32_t chd_cd_flac_compressor::blocksize(uint32_t bytes)
{
// for CDs it seems that CD_MAX_SECTOR_DATA is the right target
uint32_t blocksize = bytes / 4;
- while (blocksize > CD_MAX_SECTOR_DATA)
+ while (blocksize > cdrom_file::MAX_SECTOR_DATA)
blocksize /= 2;
return blocksize;
}
@@ -1556,7 +1556,7 @@ chd_cd_flac_decompressor::chd_cd_flac_decompressor(chd_file &chd, uint32_t hunkb
m_buffer(hunkbytes)
{
// make sure the CHD's hunk size is an even multiple of the frame size
- if (hunkbytes % CD_FRAME_SIZE != 0)
+ if (hunkbytes % cdrom_file::FRAME_SIZE != 0)
throw std::error_condition(chd_file::error::CODEC_ERROR);
// determine whether we want native or swapped samples
@@ -1609,11 +1609,11 @@ chd_cd_flac_decompressor::~chd_cd_flac_decompressor()
void chd_cd_flac_decompressor::decompress(const uint8_t *src, uint32_t complen, uint8_t *dest, uint32_t destlen)
{
// reset and decode
- uint32_t frames = destlen / CD_FRAME_SIZE;
- if (!m_decoder.reset(44100, 2, chd_cd_flac_compressor::blocksize(frames * CD_MAX_SECTOR_DATA), src, complen))
+ uint32_t frames = destlen / cdrom_file::FRAME_SIZE;
+ if (!m_decoder.reset(44100, 2, chd_cd_flac_compressor::blocksize(frames * cdrom_file::MAX_SECTOR_DATA), src, complen))
throw std::error_condition(chd_file::error::DECOMPRESSION_ERROR);
uint8_t *buffer = &m_buffer[0];
- if (!m_decoder.decode_interleaved(reinterpret_cast<int16_t *>(buffer), frames * CD_MAX_SECTOR_DATA/4, m_swap_endian))
+ if (!m_decoder.decode_interleaved(reinterpret_cast<int16_t *>(buffer), frames * cdrom_file::MAX_SECTOR_DATA/4, m_swap_endian))
throw std::error_condition(chd_file::error::DECOMPRESSION_ERROR);
// inflate the subcode data
@@ -1621,8 +1621,8 @@ void chd_cd_flac_decompressor::decompress(const uint8_t *src, uint32_t complen,
m_inflater.next_in = const_cast<Bytef *>(src + offset);
m_inflater.avail_in = complen - offset;
m_inflater.total_in = 0;
- m_inflater.next_out = &m_buffer[frames * CD_MAX_SECTOR_DATA];
- m_inflater.avail_out = frames * CD_MAX_SUBCODE_DATA;
+ m_inflater.next_out = &m_buffer[frames * cdrom_file::MAX_SECTOR_DATA];
+ m_inflater.avail_out = frames * cdrom_file::MAX_SUBCODE_DATA;
m_inflater.total_out = 0;
int zerr = inflateReset(&m_inflater);
if (zerr != Z_OK)
@@ -1632,14 +1632,14 @@ void chd_cd_flac_decompressor::decompress(const uint8_t *src, uint32_t complen,
zerr = inflate(&m_inflater, Z_FINISH);
if (zerr != Z_STREAM_END)
throw std::error_condition(chd_file::error::DECOMPRESSION_ERROR);
- if (m_inflater.total_out != frames * CD_MAX_SUBCODE_DATA)
+ if (m_inflater.total_out != frames * cdrom_file::MAX_SUBCODE_DATA)
throw std::error_condition(chd_file::error::DECOMPRESSION_ERROR);
// reassemble the data
for (uint32_t framenum = 0; framenum < frames; framenum++)
{
- memcpy(&dest[framenum * CD_FRAME_SIZE], &m_buffer[framenum * CD_MAX_SECTOR_DATA], CD_MAX_SECTOR_DATA);
- memcpy(&dest[framenum * CD_FRAME_SIZE + CD_MAX_SECTOR_DATA], &m_buffer[frames * CD_MAX_SECTOR_DATA + framenum * CD_MAX_SUBCODE_DATA], CD_MAX_SUBCODE_DATA);
+ memcpy(&dest[framenum * cdrom_file::FRAME_SIZE], &m_buffer[framenum * cdrom_file::MAX_SECTOR_DATA], cdrom_file::MAX_SECTOR_DATA);
+ memcpy(&dest[framenum * cdrom_file::FRAME_SIZE + cdrom_file::MAX_SECTOR_DATA], &m_buffer[frames * cdrom_file::MAX_SECTOR_DATA + framenum * cdrom_file::MAX_SUBCODE_DATA], cdrom_file::MAX_SUBCODE_DATA);
}
}
diff --git a/src/mame/drivers/fmtowns.cpp b/src/mame/drivers/fmtowns.cpp
index 9336706a8bd..60af7838709 100644
--- a/src/mame/drivers/fmtowns.cpp
+++ b/src/mame/drivers/fmtowns.cpp
@@ -1447,7 +1447,7 @@ uint8_t towns_state::towns_cd_get_track()
for(track=1;track<99;track++)
{
- if(cdrom_get_track_start(cdrom->get_cdrom_file(),track) > lba)
+ if(cdrom->get_cdrom_file()->get_track_start(track) > lba)
break;
}
return track;
@@ -1495,7 +1495,7 @@ TIMER_CALLBACK_MEMBER(towns_state::towns_cdrom_read_byte)
m_towns_cd.extra_status = 0;
towns_cd_set_status(0x22,0x00,0x00,0x00);
towns_cdrom_set_irq(TOWNS_CD_IRQ_DMA,1);
- cdrom_read_data(m_cdrom->get_cdrom_file(),++m_towns_cd.lba_current,m_towns_cd.buffer,CD_TRACK_MODE1);
+ m_cdrom->get_cdrom_file()->read_data(++m_towns_cd.lba_current,m_towns_cd.buffer,cdrom_file::CD_TRACK_MODE1);
m_towns_cd.read_timer->adjust(attotime::from_hz(300000),1);
m_towns_cd.buffer_ptr = -1;
}
@@ -1526,7 +1526,7 @@ uint8_t towns_state::towns_cdrom_read_byte_software()
}
else
{
- cdrom_read_data(m_cdrom->get_cdrom_file(),++m_towns_cd.lba_current,m_towns_cd.buffer,CD_TRACK_MODE1);
+ m_cdrom->get_cdrom_file()->read_data(++m_towns_cd.lba_current,m_towns_cd.buffer,cdrom_file::CD_TRACK_MODE1);
m_towns_cd.extra_status = 0;
towns_cd_set_status(0x21,0x00,0x00,0x00);
towns_cdrom_set_irq(TOWNS_CD_IRQ_DMA,1);
@@ -1558,7 +1558,7 @@ void towns_state::towns_cdrom_read(cdrom_image_device* device)
m_towns_cd.lba_current = msf_to_lbafm(lba1);
m_towns_cd.lba_last = msf_to_lbafm(lba2);
- track = cdrom_get_track(device->get_cdrom_file(),m_towns_cd.lba_current);
+ track = device->get_cdrom_file()->get_track(m_towns_cd.lba_current);
// parameter 7 = sector count?
// lemmings 2 sets this to 4 but hates 4 extra sectors being read
@@ -1574,7 +1574,7 @@ void towns_state::towns_cdrom_read(cdrom_image_device* device)
}
else
{
- cdrom_read_data(device->get_cdrom_file(),m_towns_cd.lba_current,m_towns_cd.buffer,CD_TRACK_MODE1);
+ device->get_cdrom_file()->read_data(m_towns_cd.lba_current,m_towns_cd.buffer,cdrom_file::CD_TRACK_MODE1);
if(m_towns_cd.software_tx)
{
m_towns_cd.status &= ~0x10; // not a DMA transfer
@@ -1816,7 +1816,7 @@ uint8_t towns_state::towns_cdrom_r(offs_t offset)
break;
case 4: // st1 = last track number (BCD)
towns_cd_set_status(0x17,
- byte_to_bcd(cdrom_get_last_track(m_cdrom->get_cdrom_file())),
+ byte_to_bcd(m_cdrom->get_cdrom_file()->get_last_track()),
0x00,0x00);
m_towns_cd.extra_status++;
break;
@@ -1825,8 +1825,8 @@ uint8_t towns_state::towns_cdrom_r(offs_t offset)
m_towns_cd.extra_status++;
break;
case 6: // st1/2/3 = address of track 0xaa? (BCD)
- addr = cdrom_get_track_start(m_cdrom->get_cdrom_file(),0xaa);
- addr = lba_to_msf(addr + 150);
+ addr = m_cdrom->get_cdrom_file()->get_track_start(0xaa);
+ addr = cdrom_file::lba_to_msf(addr + 150);
towns_cd_set_status(0x17,
(addr & 0xff0000) >> 16,(addr & 0x00ff00) >> 8,addr & 0x0000ff);
m_towns_cd.extra_status++;
@@ -1835,19 +1835,19 @@ uint8_t towns_state::towns_cdrom_r(offs_t offset)
if(m_towns_cd.extra_status & 0x01)
{
towns_cd_set_status(0x16,
- ((cdrom_get_adr_control(m_cdrom->get_cdrom_file(),(m_towns_cd.extra_status/2)-3) & 0x0f) << 4)
- | ((cdrom_get_adr_control(m_cdrom->get_cdrom_file(),(m_towns_cd.extra_status/2)-3) & 0xf0) >> 4),
+ ((m_cdrom->get_cdrom_file()->get_adr_control((m_towns_cd.extra_status/2)-3) & 0x0f) << 4)
+ | ((m_cdrom->get_cdrom_file()->get_adr_control((m_towns_cd.extra_status/2)-3) & 0xf0) >> 4),
byte_to_bcd((m_towns_cd.extra_status/2)-2),0x00);
m_towns_cd.extra_status++;
}
else
{
int track = (m_towns_cd.extra_status/2)-4;
- addr = cdrom_get_track_start(m_cdrom->get_cdrom_file(),track);
- addr = lba_to_msf(addr + 150);
+ addr = m_cdrom->get_cdrom_file()->get_track_start(track);
+ addr = cdrom_file::lba_to_msf(addr + 150);
towns_cd_set_status(0x17,
(addr & 0xff0000) >> 16,(addr & 0x00ff00) >> 8,addr & 0x0000ff);
- if(track >= cdrom_get_last_track(m_cdrom->get_cdrom_file()))
+ if(track >= m_cdrom->get_cdrom_file()->get_last_track())
{
m_towns_cd.extra_status = 0;
}
@@ -1867,21 +1867,21 @@ uint8_t towns_state::towns_cdrom_r(offs_t offset)
break;
case 2: // st0/1/2 = MSF from beginning of current track
addr = m_cdda->get_audio_lba();
- addr = lba_to_msf(addr - m_towns_cd.cdda_current);
+ addr = cdrom_file::lba_to_msf(addr - m_towns_cd.cdda_current);
towns_cd_set_status(0x19,
(addr & 0xff0000) >> 16,(addr & 0x00ff00) >> 8,addr & 0x0000ff);
m_towns_cd.extra_status++;
break;
case 3: // st1/2 = current MSF
addr = m_cdda->get_audio_lba();
- addr = lba_to_msf(addr); // this data is incorrect, but will do until exact meaning is found
+ addr = cdrom_file::lba_to_msf(addr); // this data is incorrect, but will do until exact meaning is found
towns_cd_set_status(0x19,
0x00,(addr & 0xff0000) >> 16,(addr & 0x00ff00) >> 8);
m_towns_cd.extra_status++;
break;
case 4:
addr = m_cdda->get_audio_lba();
- addr = lba_to_msf(addr); // this data is incorrect, but will do until exact meaning is found
+ addr = cdrom_file::lba_to_msf(addr); // this data is incorrect, but will do until exact meaning is found
towns_cd_set_status(0x20,
addr & 0x0000ff,0x00,0x00);
m_towns_cd.extra_status = 0;
diff --git a/src/mame/drivers/jaguar.cpp b/src/mame/drivers/jaguar.cpp
index 2237060691a..6767856bfd6 100644
--- a/src/mame/drivers/jaguar.cpp
+++ b/src/mame/drivers/jaguar.cpp
@@ -1242,12 +1242,12 @@ void jaguarcd_state::butch_regs_w(offs_t offset, uint32_t data, uint32_t mem_mas
return;
}
- msf = cdrom_get_track_start(m_cd_file, 0) + 150;
+ msf = m_cd_file->get_track_start(0) + 150;
/* first track number */
m_butch_cmd_response[0] = 0x2000 | 1;
/* last track number */
- m_butch_cmd_response[1] = 0x2100 | cdrom_get_last_track(m_cd_file);
+ m_butch_cmd_response[1] = 0x2100 | m_cd_file->get_last_track();
/* start of first track minutes */
m_butch_cmd_response[2] = 0x2200 | ((msf / 60) / 60);
@@ -1262,11 +1262,11 @@ void jaguarcd_state::butch_regs_w(offs_t offset, uint32_t data, uint32_t mem_mas
case 0x14: // Read Long TOC
{
uint32_t msf;
- int ntrks = cdrom_get_last_track(m_cd_file);
+ int ntrks = m_cd_file->get_last_track();
for(int i=0;i<ntrks;i++)
{
- msf = cdrom_get_track_start(m_cd_file, i) + 150;
+ msf = m_cd_file->get_track_start(i) + 150;
/* track number */
m_butch_cmd_response[i*5+0] = 0x6000 | (i+1);
diff --git a/src/mame/drivers/konamim2.cpp b/src/mame/drivers/konamim2.cpp
index 2a5b6651c7a..c29ca46fbaf 100644
--- a/src/mame/drivers/konamim2.cpp
+++ b/src/mame/drivers/konamim2.cpp
@@ -696,7 +696,7 @@ void konamim2_state::machine_start()
m_ppc1->ppcdrc_add_fastram(m_bda->ram_start(), m_bda->ram_end(), false, m_bda->ram_ptr());
m_ppc2->ppcdrc_add_fastram(m_bda->ram_start(), m_bda->ram_end(), false, m_bda->ram_ptr());
- m_available_cdroms = cdrom_open(machine().rom_load().get_disk_handle(":cdrom"));
+ m_available_cdroms = new cdrom_file(machine().rom_load().get_disk_handle(":cdrom"));
// TODO: REMOVE
m_atapi_timer = machine().scheduler().timer_alloc(timer_expired_delegate(FUNC(konamim2_state::atapi_delay), this));
diff --git a/src/mame/drivers/ksys573.cpp b/src/mame/drivers/ksys573.cpp
index 4dad8c5d747..dc4192c021b 100644
--- a/src/mame/drivers/ksys573.cpp
+++ b/src/mame/drivers/ksys573.cpp
@@ -1107,8 +1107,8 @@ void ksys573_state::driver_start()
m_atapi_timer = machine().scheduler().timer_alloc( timer_expired_delegate( FUNC( ksys573_state::atapi_xfer_end ),this ) );
m_atapi_timer->adjust( attotime::never );
- m_available_cdroms[ 0 ] = cdrom_open(machine().rom_load().get_disk_handle(":cdrom0"));
- m_available_cdroms[ 1 ] = cdrom_open(machine().rom_load().get_disk_handle(":cdrom1"));
+ m_available_cdroms[ 0 ] = new cdrom_file(machine().rom_load().get_disk_handle(":cdrom0"));
+ m_available_cdroms[ 1 ] = new cdrom_file(machine().rom_load().get_disk_handle(":cdrom1"));
save_item( NAME( m_n_security_control ) );
save_item( NAME( m_control ) );
diff --git a/src/mame/machine/cdicdic.cpp b/src/mame/machine/cdicdic.cpp
index f858bb73864..6786f3c69b4 100644
--- a/src/mame/machine/cdicdic.cpp
+++ b/src/mame/machine/cdicdic.cpp
@@ -931,7 +931,7 @@ void cdicdic_device::process_disc_sector()
LOGMASKED(LOG_SECTORS, "Disc sector, current LBA: %08x, MSF: %02x %02x %02x\n", real_lba, mins_bcd, secs_bcd, frac_bcd);
uint8_t buffer[2560] = { 0 };
- cdrom_read_data(m_cd, m_curr_lba, buffer, CD_TRACK_RAW_DONTCARE);
+ m_cd->read_data(m_curr_lba, buffer, cdrom_file::CD_TRACK_RAW_DONTCARE);
// Detect (badly) if we're dealing with a byteswapped loose-bin image
if (buffer[0] == 0xff && buffer[1] == 0x00)
@@ -1022,23 +1022,23 @@ void cdicdic_device::process_disc_sector()
if (m_disc_mode == DISC_TOC)
{
uint8_t *toc_buffer = buffer;
- const cdrom_toc *toc = cdrom_get_toc(m_cd);
+ const cdrom_file::toc &toc = m_cd->get_toc();
uint32_t entry_count = 0;
// Determine total frame count for data, and total audio track count
- uint32_t frames = toc->tracks[0].pregap;
+ uint32_t frames = toc.tracks[0].pregap;
int audio_tracks = 0;
int other_tracks = 0;
- uint32_t audio_starts[CD_MAX_TRACKS];
- for (uint32_t i = 0; i < toc->numtrks; i++)
+ uint32_t audio_starts[cdrom_file::MAX_TRACKS];
+ for (uint32_t i = 0; i < toc.numtrks; i++)
{
- if (toc->tracks[i].trktype != CD_TRACK_AUDIO)
+ if (toc.tracks[i].trktype != cdrom_file::CD_TRACK_AUDIO)
{
- frames += toc->tracks[i].frames + toc->tracks[i].extraframes;
+ frames += toc.tracks[i].frames + toc.tracks[i].extraframes;
}
else
{
- audio_starts[audio_tracks++] = toc->tracks[i].logframeofs;
+ audio_starts[audio_tracks++] = toc.tracks[i].logframeofs;
}
}
@@ -1572,7 +1572,7 @@ void cdicdic_device::device_reset()
else
{
// Arcade case
- m_cd = cdrom_open(machine().rom_load().get_disk_handle(":cdrom"));
+ m_cd = new cdrom_file(machine().rom_load().get_disk_handle(":cdrom"));
}
m_audio_timer->adjust(attotime::from_hz(75), 0, attotime::from_hz(75));
diff --git a/src/mame/machine/gdrom.cpp b/src/mame/machine/gdrom.cpp
index 257bf116d00..db01fc5ebea 100644
--- a/src/mame/machine/gdrom.cpp
+++ b/src/mame/machine/gdrom.cpp
@@ -248,7 +248,7 @@ void gdrom_device::ExecCommand()
{
// TODO: is this correct?
int start_trk = command[2];
- int end_trk = cdrom_get_last_track(m_cdrom);
+ int end_trk = m_cdrom->get_last_track();
int length;
int allocation_length = SCSILengthFromUINT16( &command[ 3 ] );
@@ -335,7 +335,7 @@ void gdrom_device::ReadData( uint8_t *data, int dataLength )
{
while (dataLength > 0)
{
- if (!cdrom_read_data(m_cdrom, m_lba, tmp_buffer, CD_TRACK_MODE1))
+ if (!m_cdrom->read_data(m_lba, tmp_buffer, cdrom_file::CD_TRACK_MODE1))
{
LOGWARN("CD read error!\n");
}
@@ -387,7 +387,7 @@ void gdrom_device::ReadData( uint8_t *data, int dataLength )
start_trk = 1;
}
- end_trk = cdrom_get_last_track(m_cdrom);
+ end_trk = m_cdrom->get_last_track();
len = (end_trk * 8) + 2;
// the returned TOC DATA LENGTH must be the full amount,
@@ -419,13 +419,13 @@ void gdrom_device::ReadData( uint8_t *data, int dataLength )
}
data[dptr++] = 0;
- data[dptr++] = cdrom_get_adr_control(m_cdrom, cdrom_track);
+ data[dptr++] = m_cdrom->get_adr_control(cdrom_track);
data[dptr++] = i;
data[dptr++] = 0;
- tstart = cdrom_get_track_start(m_cdrom, cdrom_track);
+ tstart = m_cdrom->get_track_start(cdrom_track);
if ((command[1]&2)>>1)
- tstart = lba_to_msf(tstart);
+ tstart = cdrom_file::lba_to_msf(tstart);
data[dptr++] = (tstart>>24) & 0xff;
data[dptr++] = (tstart>>16) & 0xff;
data[dptr++] = (tstart>>8) & 0xff;
@@ -494,7 +494,7 @@ void gdrom_device::SetDevice(void *device)
// try to find if the mounted chd is from an actual gd-rom disc
if (m_cdrom)
- if (cdrom_get_toc(m_cdrom)->flags & CD_FLAG_GDROM)
+ if (m_cdrom->get_toc().flags & cdrom_file::CD_FLAG_GDROM)
is_real_gdrom_disc = true;
}
diff --git a/src/mame/machine/megacdcd.cpp b/src/mame/machine/megacdcd.cpp
index a9a5f44da81..5414f5ff57c 100644
--- a/src/mame/machine/megacdcd.cpp
+++ b/src/mame/machine/megacdcd.cpp
@@ -113,7 +113,7 @@
#define CURRENT_TRACK_IS_DATA \
- (segacd.toc->tracks[SCD_CURTRK - 1].trktype != CD_TRACK_AUDIO)
+ (segacd.toc->tracks[SCD_CURTRK - 1].trktype != cdrom_file::CD_TRACK_AUDIO)
#define CDD_PLAYINGCDDA 0x0100
#define CDD_READY 0x0400
@@ -314,7 +314,7 @@ void lc89510_temp_device::CDD_GetPos(void)
if(segacd.cd == nullptr) // no CD is there, bail out
return;
CDD_STATUS |= SCD_STATUS;
- msf = lba_to_msf_alt(SCD_CURLBA+150);
+ msf = cdrom_file::lba_to_msf_alt(SCD_CURLBA+150);
CDD_MIN = to_bcd(((msf & 0x00ff0000)>>16),false);
CDD_SEC = to_bcd(((msf & 0x0000ff00)>>8),false);
CDD_FRAME = to_bcd(((msf & 0x000000ff)>>0),false);
@@ -330,8 +330,8 @@ void lc89510_temp_device::CDD_GetTrackPos(void)
if(segacd.cd == nullptr) // no CD is there, bail out
return;
CDD_STATUS |= SCD_STATUS;
- elapsedlba = SCD_CURLBA - segacd.toc->tracks[ cdrom_get_track(segacd.cd, SCD_CURLBA) ].logframeofs;
- msf = lba_to_msf_alt (elapsedlba);
+ elapsedlba = SCD_CURLBA - segacd.toc->tracks[ segacd.cd->get_track(SCD_CURLBA) ].logframeofs;
+ msf = cdrom_file::lba_to_msf_alt (elapsedlba);
//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);
@@ -345,7 +345,7 @@ void lc89510_temp_device::CDD_GetTrack(void)
if(segacd.cd == nullptr) // no CD is there, bail out
return;
CDD_STATUS |= SCD_STATUS;
- SCD_CURTRK = cdrom_get_track(segacd.cd, SCD_CURLBA)+1;
+ SCD_CURTRK = segacd.cd->get_track(SCD_CURLBA)+1;
CDD_MIN = to_bcd(SCD_CURTRK, false);
}
@@ -357,8 +357,8 @@ void lc89510_temp_device::CDD_Length(void)
return;
CDD_STATUS |= SCD_STATUS;
- uint32_t startlba = (segacd.toc->tracks[cdrom_get_last_track(segacd.cd)].logframeofs);
- uint32_t startmsf = lba_to_msf_alt( startlba );
+ uint32_t startlba = (segacd.toc->tracks[segacd.cd->get_last_track()].logframeofs);
+ uint32_t startmsf = cdrom_file::lba_to_msf_alt( startlba );
CDD_MIN = to_bcd((startmsf&0x00ff0000)>>16,false);
CDD_SEC = to_bcd((startmsf&0x0000ff00)>>8,false);
@@ -374,7 +374,7 @@ void lc89510_temp_device::CDD_FirstLast(void)
return;
CDD_STATUS |= SCD_STATUS;
CDD_MIN = 1; // first
- CDD_SEC = to_bcd(cdrom_get_last_track(segacd.cd),false); // last
+ CDD_SEC = to_bcd(segacd.cd->get_last_track(),false); // last
}
void lc89510_temp_device::CDD_GetTrackAdr(void)
@@ -382,7 +382,7 @@ void lc89510_temp_device::CDD_GetTrackAdr(void)
CLEAR_CDD_RESULT
int track = (CDD_TX[5] & 0xF) + (CDD_TX[4] & 0xF) * 10;
- int last_track = cdrom_get_last_track(segacd.cd);
+ int last_track = segacd.cd->get_last_track();
CDD_STATUS &= 0xFF;
if(segacd.cd == nullptr) // no CD is there, bail out
@@ -396,14 +396,14 @@ void lc89510_temp_device::CDD_GetTrackAdr(void)
track = 1;
uint32_t startlba = (segacd.toc->tracks[track-1].logframeofs);
- uint32_t startmsf = lba_to_msf_alt( startlba+150 );
+ uint32_t startmsf = cdrom_file::lba_to_msf_alt( startlba+150 );
CDD_MIN = to_bcd((startmsf&0x00ff0000)>>16,false);
CDD_SEC = to_bcd((startmsf&0x0000ff00)>>8,false);
CDD_FRAME = to_bcd((startmsf&0x000000ff)>>0,false);
CDD_EXT = track % 10;
- if (segacd.toc->tracks[track - 1].trktype != CD_TRACK_AUDIO)
+ if (segacd.toc->tracks[track - 1].trktype != cdrom_file::CD_TRACK_AUDIO)
CDD_FRAME |= 0x0800;
}
@@ -414,7 +414,7 @@ void lc89510_temp_device::CDD_GetTrackType(void)
CLEAR_CDD_RESULT
int track = (CDD_TX[5] & 0xF) + (CDD_TX[4] & 0xF) * 10;
- int last_track = cdrom_get_last_track(segacd.cd);
+ int last_track = segacd.cd->get_last_track();
CDD_STATUS &= 0xFF;
if(segacd.cd == nullptr) // no CD is there, bail out
@@ -427,7 +427,7 @@ void lc89510_temp_device::CDD_GetTrackType(void)
if (track < 1)
track = 1;
- if (segacd.toc->tracks[track - 1].trktype != CD_TRACK_AUDIO)
+ if (segacd.toc->tracks[track - 1].trktype != cdrom_file::CD_TRACK_AUDIO)
{
CDD_EXT = 0x08;
CDD_FRAME |= 0x0800;
@@ -452,11 +452,11 @@ void lc89510_temp_device::CDD_Play()
{
CLEAR_CDD_RESULT
uint32_t msf = getmsf_from_regs();
- SCD_CURLBA = msf_to_lba(msf)-150;
+ SCD_CURLBA = cdrom_file::msf_to_lba(msf)-150;
if(segacd.cd == nullptr) // no CD is there, bail out
return;
- 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;
+ uint32_t track_length = segacd.toc->tracks[ segacd.cd->get_track(SCD_CURLBA) ].logframes;
+ SCD_CURTRK = segacd.cd->get_track(SCD_CURLBA)+1;
LC8951UpdateHeader();
SCD_STATUS = CDD_PLAYINGCDDA;
CDD_STATUS = 0x0102;
@@ -477,10 +477,10 @@ void lc89510_temp_device::CDD_Seek(void)
{
CLEAR_CDD_RESULT
uint32_t msf = getmsf_from_regs();
- SCD_CURLBA = msf_to_lba(msf)-150;
+ SCD_CURLBA = cdrom_file::msf_to_lba(msf)-150;
if(segacd.cd == nullptr) // no CD is there, bail out
return;
- SCD_CURTRK = cdrom_get_track(segacd.cd, SCD_CURLBA)+1;
+ SCD_CURTRK = segacd.cd->get_track(SCD_CURLBA)+1;
LC8951UpdateHeader();
STOP_CDC_READ
SCD_STATUS = CDD_READY;
@@ -513,7 +513,7 @@ void lc89510_temp_device::CDD_Resume()
STOP_CDC_READ
if(segacd.cd == nullptr) // no CD is there, bail out
return;
- SCD_CURTRK = cdrom_get_track(segacd.cd, SCD_CURLBA)+1;
+ SCD_CURTRK = segacd.cd->get_track(SCD_CURLBA)+1;
SCD_STATUS = CDD_PLAYINGCDDA;
CDD_STATUS = 0x0102;
set_data_audio_mode();
@@ -1108,7 +1108,7 @@ void lc89510_temp_device::reset_cd(void)
segacd.cd = m_cdrom->get_cdrom_file();
if ( segacd.cd )
{
- segacd.toc = cdrom_get_toc( segacd.cd );
+ segacd.toc = &segacd.cd->get_toc();
m_cdda->set_cdrom(segacd.cd);
m_cdda->stop_audio(); //stop any pending CD-DA
}
@@ -1219,7 +1219,7 @@ void lc89510_temp_device::LC8951UpdateHeader() // neocd
} else {
// HEAD registers have header
- uint32_t msf = lba_to_msf_alt(SCD_CURLBA+150);
+ uint32_t msf = cdrom_file::lba_to_msf_alt(SCD_CURLBA+150);
LC8951RegistersR[REG_R_HEAD0] = to_bcd (((msf & 0x00ff0000)>>16), true); // HEAD0
LC8951RegistersR[REG_R_HEAD1] = to_bcd (((msf & 0x0000ff00)>>8), true); // HEAD1
@@ -1333,7 +1333,7 @@ int lc89510_temp_device::Read_LBA_To_Buffer()
if (CDD_CONTROL & 0x0100) data_track = true;
if (data_track)
- cdrom_read_data(segacd.cd, SCD_CURLBA, SCD_BUFFER, CD_TRACK_MODE1);
+ segacd.cd->read_data(SCD_CURLBA, SCD_BUFFER, cdrom_file::CD_TRACK_MODE1);
LC8951UpdateHeader();
diff --git a/src/mame/machine/megacdcd.h b/src/mame/machine/megacdcd.h
index 1ee0f562094..21fc407896b 100644
--- a/src/mame/machine/megacdcd.h
+++ b/src/mame/machine/megacdcd.h
@@ -92,7 +92,7 @@ protected:
struct segacd_t
{
cdrom_file *cd;
- const cdrom_toc *toc;
+ const cdrom_file::toc *toc;
uint32_t current_frame;
};
diff --git a/src/mame/machine/naomigd.cpp b/src/mame/machine/naomigd.cpp
index 92fd9bc79e7..0b80bd8d36d 100644
--- a/src/mame/machine/naomigd.cpp
+++ b/src/mame/machine/naomigd.cpp
@@ -960,17 +960,17 @@ void naomi_gdrom_board::device_start()
logerror("key is %08x%08x\n", (uint32_t)((key & 0xffffffff00000000ULL)>>32), (uint32_t)(key & 0x00000000ffffffffULL));
uint8_t buffer[2048];
- cdrom_file *gdromfile = cdrom_open(machine().rom_load().get_disk_handle(image_tag));
+ cdrom_file *gdromfile = new cdrom_file(machine().rom_load().get_disk_handle(image_tag));
// primary volume descriptor
// read frame 0xb06e (frame=sector+150)
// dimm board firmware starts straight from this frame
- cdrom_read_data(gdromfile, (netpic ? 0 : 45000) + 16, buffer, CD_TRACK_MODE1);
+ gdromfile->read_data((netpic ? 0 : 45000) + 16, buffer, cdrom_file::CD_TRACK_MODE1);
uint32_t path_table = ((buffer[0x8c+0] << 0) |
(buffer[0x8c+1] << 8) |
(buffer[0x8c+2] << 16) |
(buffer[0x8c+3] << 24));
// path table
- cdrom_read_data(gdromfile, path_table, buffer, CD_TRACK_MODE1);
+ gdromfile->read_data(path_table, buffer, cdrom_file::CD_TRACK_MODE1);
// directory
uint8_t dir_sector[2048]{};
@@ -983,12 +983,12 @@ void naomi_gdrom_board::device_start()
(buffer[0x2 + 2] << 16) |
(buffer[0x2 + 3] << 24));
- cdrom_read_data(gdromfile, dir, dir_sector, CD_TRACK_MODE1);
+ gdromfile->read_data(dir, dir_sector, cdrom_file::CD_TRACK_MODE1);
find_file(name, dir_sector, file_start, file_size);
if (file_start && (file_size == 0x100)) {
// read file
- cdrom_read_data(gdromfile, file_start, buffer, CD_TRACK_MODE1);
+ gdromfile->read_data(file_start, buffer, cdrom_file::CD_TRACK_MODE1);
// get "rom" file name
memset(name, '\0', 128);
memcpy(name, buffer + 0xc0, FILENAME_LENGTH - 1);
@@ -1004,7 +1004,7 @@ void naomi_gdrom_board::device_start()
(buffer[i + 4] << 16) |
(buffer[i + 5] << 24));
memcpy(name, "ROM.BIN", 7);
- cdrom_read_data(gdromfile, dir, dir_sector, CD_TRACK_MODE1);
+ gdromfile->read_data(dir, dir_sector, cdrom_file::CD_TRACK_MODE1);
break;
}
i += buffer[i] + 8 + (buffer[i] & 1);
@@ -1024,7 +1024,7 @@ void naomi_gdrom_board::device_start()
// read encrypted data into dimm_des_data
uint32_t sectors = file_rounded_size / 2048;
for (uint32_t sec = 0; sec != sectors; sec++)
- cdrom_read_data(gdromfile, file_start + sec, &dimm_des_data[2048 * sec], CD_TRACK_MODE1);
+ gdromfile->read_data(file_start + sec, &dimm_des_data[2048 * sec], cdrom_file::CD_TRACK_MODE1);
uint32_t des_subkeys[32];
des_generate_subkeys(rev64(key), des_subkeys);
@@ -1034,7 +1034,7 @@ void naomi_gdrom_board::device_start()
write_from_qword(&dimm_data[i], rev64(des_encrypt_decrypt(true, rev64(read_to_qword(&dimm_des_data[i])), des_subkeys)));
}
- cdrom_close(gdromfile);
+ delete gdromfile;
if(!dimm_data)
throw emu_fatalerror("GDROM: Could not find the file to decrypt.");
diff --git a/src/mame/machine/pce_cd.cpp b/src/mame/machine/pce_cd.cpp
index 30027256512..8667f48fc53 100644
--- a/src/mame/machine/pce_cd.cpp
+++ b/src/mame/machine/pce_cd.cpp
@@ -261,10 +261,10 @@ void pce_cd_device::late_setup()
m_cd_file = m_cdrom->get_cdrom_file();
if (m_cd_file)
{
- m_toc = cdrom_get_toc(m_cd_file);
+ m_toc = &m_cd_file->get_toc();
m_cdda->set_cdrom(m_cd_file);
- m_last_frame = cdrom_get_track_start(m_cd_file, cdrom_get_last_track(m_cd_file) - 1);
- m_last_frame += m_toc->tracks[cdrom_get_last_track(m_cd_file) - 1].frames;
+ m_last_frame = m_cd_file->get_track_start(m_cd_file->get_last_track() - 1);
+ m_last_frame += m_toc->tracks[m_cd_file->get_last_track() - 1].frames;
m_end_frame = m_last_frame;
}
@@ -466,7 +466,7 @@ void pce_cd_device::nec_set_audio_start_position()
frame = f + 75 * (s + m * 60);
// 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 -= m_toc->tracks[cdrom_get_track(m_cd_file, frame)].pregap;
+ frame -= m_toc->tracks[m_cd_file->get_track(frame)].pregap;
break;
}
case 0x80:
@@ -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) ].logframeofs + m_toc->tracks[ cdrom_get_track(m_cd_file, m_current_frame) ].logframes; //get the end of THIS track
+ m_end_frame = m_toc->tracks[ m_cd_file->get_track(m_current_frame) ].logframeofs + m_toc->tracks[ m_cd_file->get_track(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;
@@ -637,11 +637,11 @@ void pce_cd_device::nec_get_subq()
break;
}
- msf_abs = lba_to_msf_alt(frame);
- track = cdrom_get_track(m_cd_file, frame);
- msf_rel = lba_to_msf_alt(frame - cdrom_get_track_start(m_cd_file, track));
+ msf_abs = cdrom_file::lba_to_msf_alt(frame);
+ track = m_cd_file->get_track(frame);
+ msf_rel = cdrom_file::lba_to_msf_alt(frame - m_cd_file->get_track_start(track));
- m_data_buffer[1] = 0x01 | ((cdrom_get_track_type(m_cd_file, cdrom_get_track(m_cd_file, track+1)) == CD_TRACK_AUDIO) ? 0x00 : 0x40);
+ m_data_buffer[1] = 0x01 | ((m_cd_file->get_track_type(m_cd_file->get_track(track+1)) == cdrom_file::CD_TRACK_AUDIO) ? 0x00 : 0x40);
m_data_buffer[2] = dec_2_bcd(track+1); /* track */
m_data_buffer[3] = 1; /* index */
m_data_buffer[4] = dec_2_bcd((msf_rel >> 16) & 0xFF);/* M (relative) */
@@ -662,7 +662,6 @@ void pce_cd_device::nec_get_subq()
void pce_cd_device::nec_get_dir_info()
{
uint32_t frame, msf, track = 0;
- const cdrom_toc *toc;
logerror("nec get dir info\n");
if (!m_cd_file)
@@ -671,19 +670,19 @@ void pce_cd_device::nec_get_dir_info()
reply_status_byte(SCSI_CHECK_CONDITION);
}
- toc = cdrom_get_toc(m_cd_file);
+ const cdrom_file::toc &toc = m_cd_file->get_toc();
switch (m_command_buffer[1])
{
case 0x00: /* Get first and last track numbers */
m_data_buffer[0] = dec_2_bcd(1);
- m_data_buffer[1] = dec_2_bcd(toc->numtrks);
+ m_data_buffer[1] = dec_2_bcd(toc.numtrks);
m_data_buffer_size = 2;
break;
case 0x01: /* Get total disk size in MSF format */
- frame = toc->tracks[toc->numtrks-1].logframeofs;
- frame += toc->tracks[toc->numtrks-1].frames;
- msf = lba_to_msf(frame + 150);
+ frame = toc.tracks[toc.numtrks-1].logframeofs;
+ frame += toc.tracks[toc.numtrks-1].frames;
+ msf = cdrom_file::lba_to_msf(frame + 150);
m_data_buffer[0] = (msf >> 16) & 0xFF; /* M */
m_data_buffer[1] = (msf >> 8) & 0xFF; /* S */
@@ -693,17 +692,17 @@ void pce_cd_device::nec_get_dir_info()
case 0x02: /* Get track information */
if (m_command_buffer[2] == 0xAA)
{
- frame = toc->tracks[toc->numtrks-1].logframeofs;
- frame += toc->tracks[toc->numtrks-1].frames;
+ frame = toc.tracks[toc.numtrks-1].logframeofs;
+ frame += toc.tracks[toc.numtrks-1].frames;
m_data_buffer[3] = 0x04; /* correct? */
} else
{
track = std::max(bcd_2_dec(m_command_buffer[2]), 1U);
- frame = toc->tracks[track-1].logframeofs;
- m_data_buffer[3] = (toc->tracks[track-1].trktype == CD_TRACK_AUDIO) ? 0x00 : 0x04;
+ frame = toc.tracks[track-1].logframeofs;
+ m_data_buffer[3] = (toc.tracks[track-1].trktype == cdrom_file::CD_TRACK_AUDIO) ? 0x00 : 0x04;
}
logerror("track = %d, frame = %d\n", track, frame);
- msf = lba_to_msf(frame + 150);
+ msf = cdrom_file::lba_to_msf(frame + 150);
m_data_buffer[0] = (msf >> 16) & 0xFF; /* M */
m_data_buffer[1] = (msf >> 8) & 0xFF; /* S */
m_data_buffer[2] = msf & 0xFF; /* F */
@@ -978,7 +977,7 @@ TIMER_CALLBACK_MEMBER(pce_cd_device::data_timer_callback)
{
/* Read next data sector */
logerror("read sector %d\n", m_current_frame);
- if (! cdrom_read_data(m_cd_file, m_current_frame, m_data_buffer.get(), CD_TRACK_MODE1))
+ if (! m_cd_file->read_data(m_current_frame, m_data_buffer.get(), cdrom_file::CD_TRACK_MODE1))
{
logerror("Mode1 CD read failed for frame #%d\n", m_current_frame);
}
diff --git a/src/mame/machine/pce_cd.h b/src/mame/machine/pce_cd.h
index 7da4f631581..3d2e3e9a354 100644
--- a/src/mame/machine/pce_cd.h
+++ b/src/mame/machine/pce_cd.h
@@ -199,7 +199,7 @@ private:
required_device<cdrom_image_device> m_cdrom;
cdrom_file *m_cd_file = nullptr;
- const cdrom_toc* m_toc = nullptr;
+ const cdrom_file::toc* m_toc = nullptr;
emu_timer *m_data_timer = nullptr;
emu_timer *m_adpcm_dma_timer = nullptr;
diff --git a/src/mame/machine/psxcd.cpp b/src/mame/machine/psxcd.cpp
index 4039e3cc2c9..503df61339c 100644
--- a/src/mame/machine/psxcd.cpp
+++ b/src/mame/machine/psxcd.cpp
@@ -473,7 +473,7 @@ void psxcd_device::cdcmd_setloc()
void psxcd_device::cdcmd_play()
{
if(cmdbuf[0] && m_param_count)
- loc.w = lba_to_msf_ps(cdrom_get_track_start(m_cdrom_handle, bcd_to_decimal(cmdbuf[0]) - 1));
+ loc.w = lba_to_msf_ps(m_cdrom_handle->get_track_start(bcd_to_decimal(cmdbuf[0]) - 1));
curpos.w = loc.w;
if (!curpos.w)
@@ -631,8 +631,8 @@ void psxcd_device::cdcmd_getlocl()
void psxcd_device::cdcmd_getlocp()
{
CDPOS tloc, start;
- uint8_t track = cdrom_get_track(m_cdrom_handle, msf_to_lba_ps(loc.w)) + 1;
- start.w = (track == 1) ? 0x000200 : lba_to_msf_ps(cdrom_get_track_start(m_cdrom_handle, track - 1));
+ uint8_t track = m_cdrom_handle->get_track(msf_to_lba_ps(loc.w)) + 1;
+ start.w = (track == 1) ? 0x000200 : lba_to_msf_ps(m_cdrom_handle->get_track_start(track - 1));
tloc.w = sub_loc(loc, start);
unsigned char data[8]=
@@ -664,7 +664,7 @@ void psxcd_device::cdcmd_gettn()
{
status,
decimal_to_bcd(1),
- decimal_to_bcd(cdrom_get_last_track(m_cdrom_handle))
+ decimal_to_bcd(m_cdrom_handle->get_last_track())
};
send_result(intr_complete,data,3);
@@ -678,14 +678,14 @@ void psxcd_device::cdcmd_gettn()
void psxcd_device::cdcmd_gettd()
{
uint8_t track = bcd_to_decimal(cmdbuf[0]);
- uint8_t last = cdrom_get_last_track(m_cdrom_handle);
+ uint8_t last = m_cdrom_handle->get_last_track();
if(track <= last)
{
CDPOS trkstart;
if(!track) // length of disk
- trkstart.w = lba_to_msf_ps(cdrom_get_track_start(m_cdrom_handle, 0xaa));
+ trkstart.w = lba_to_msf_ps(m_cdrom_handle->get_track_start(0xaa));
else
- trkstart.w = lba_to_msf_ps(cdrom_get_track_start(m_cdrom_handle, track - 1));
+ trkstart.w = lba_to_msf_ps(m_cdrom_handle->get_track_start(track - 1));
unsigned char data[3]=
{
@@ -760,7 +760,7 @@ void psxcd_device::cdcmd_id()
memset(cdid, '\0', 8);
send_result(intr_complete);
- if(cdrom_get_track_type(m_cdrom_handle, 0) == CD_TRACK_AUDIO)
+ if(m_cdrom_handle->get_track_type(0) == cdrom_file::CD_TRACK_AUDIO)
{
irq = intr_diskerror;
cdid[0] = status | status_invalid;
@@ -954,7 +954,7 @@ void psxcd_device::read_sector()
bool isend = false;
uint32_t sector = msf_to_lba_ps(curpos.w);
uint8_t *buf = secbuf[sectail];
- if (cdrom_read_data(m_cdrom_handle, sector, buf, CD_TRACK_RAW_DONTCARE))
+ if (m_cdrom_handle->read_data(sector, buf, cdrom_file::CD_TRACK_RAW_DONTCARE))
{
subheader *sub=(subheader *)(buf+16);
memcpy(lastsechdr, buf+12, 8);
@@ -1027,14 +1027,14 @@ void psxcd_device::play_sector()
{
uint32_t sector = msf_to_lba_ps(curpos.w);
- if(cdrom_read_data(m_cdrom_handle, sector, secbuf[sectail], CD_TRACK_AUDIO))
+ if(m_cdrom_handle->read_data(sector, secbuf[sectail], cdrom_file::CD_TRACK_AUDIO))
{
if(!m_mute)
m_spu->play_cdda(0, secbuf[sectail]);
}
else
{
- if(!cdrom_read_data(m_cdrom_handle, sector, secbuf[sectail], CD_TRACK_RAW_DONTCARE))
+ if(!m_cdrom_handle->read_data(sector, secbuf[sectail], cdrom_file::CD_TRACK_RAW_DONTCARE))
{
stop_read(); // assume we've reached the end
cmd_complete(prepare_result(intr_dataend));
@@ -1074,7 +1074,7 @@ void psxcd_device::play_sector()
if ((mode&mode_report) && !(sector & 15)) // slow the int rate
{
auto res=new command_result;
- uint8_t track = cdrom_get_track(m_cdrom_handle, sector) + 1;
+ uint8_t track = m_cdrom_handle->get_track(sector) + 1;
res->res=intr_dataready;
res->data[0]=status;
@@ -1083,7 +1083,7 @@ void psxcd_device::play_sector()
if(sector & 0x10)
{
CDPOS tloc, start;
- start.w = (track == 1) ? 0x000200 : lba_to_msf_ps(cdrom_get_track_start(m_cdrom_handle, track - 1));
+ start.w = (track == 1) ? 0x000200 : lba_to_msf_ps(m_cdrom_handle->get_track_start(track - 1));
tloc.w = sub_loc(loc, start);
res->data[3]=decimal_to_bcd(tloc.b[M]);
res->data[4]=decimal_to_bcd(tloc.b[S]) | 0x80;
@@ -1115,7 +1115,7 @@ void psxcd_device::start_read()
assert((status&(status_reading|status_playing))==0);
- if(!(mode & mode_cdda) && (cdrom_get_track_type(m_cdrom_handle, cdrom_get_track(m_cdrom_handle, sector + 150)) == CD_TRACK_AUDIO))
+ if(!(mode & mode_cdda) && (m_cdrom_handle->get_track_type(m_cdrom_handle->get_track(sector + 150)) == cdrom_file::CD_TRACK_AUDIO))
{
stop_read();
cmd_complete(prepare_result(intr_diskerror, nullptr, 0, 0x40));
@@ -1139,9 +1139,9 @@ void psxcd_device::start_read()
void psxcd_device::start_play()
{
- uint8_t track = cdrom_get_track(m_cdrom_handle, msf_to_lba_ps(curpos.w) + 150);
+ uint8_t track = m_cdrom_handle->get_track(msf_to_lba_ps(curpos.w) + 150);
- if(cdrom_get_track_type(m_cdrom_handle, track) != CD_TRACK_AUDIO)
+ if(m_cdrom_handle->get_track_type(track) != cdrom_file::CD_TRACK_AUDIO)
verboselog(*this, 0, "psxcd: playing data track\n");
status|=status_playing;
@@ -1150,8 +1150,8 @@ void psxcd_device::start_play()
if (mode&mode_autopause)
{
- auto toc = cdrom_get_toc(m_cdrom_handle);
- autopause_sector = cdrom_get_track_start(m_cdrom_handle, track) + toc->tracks[track].logframes;
+ const auto &toc = m_cdrom_handle->get_toc();
+ autopause_sector = m_cdrom_handle->get_track_start(track) + toc.tracks[track].logframes;
// printf("pos=%d auto=%d\n",pos,autopause_sector);
}
diff --git a/src/mame/machine/psxcd.h b/src/mame/machine/psxcd.h
index 90c11dcc52d..8c20b9dca1a 100644
--- a/src/mame/machine/psxcd.h
+++ b/src/mame/machine/psxcd.h
@@ -103,8 +103,8 @@ private:
uint8_t bcd_to_decimal(const uint8_t bcd) { return ((bcd>>4)*10)+(bcd&0xf); }
uint8_t decimal_to_bcd(const uint8_t dec) { return ((dec/10)<<4)|(dec%10); }
- uint32_t msf_to_lba_ps(uint32_t msf) { msf = msf_to_lba(msf); return (msf>150)?(msf-150):msf; }
- uint32_t lba_to_msf_ps(uint32_t lba) { return lba_to_msf_alt(lba+150); }
+ uint32_t msf_to_lba_ps(uint32_t msf) { msf = cdrom_file::msf_to_lba(msf); return (msf>150)?(msf-150):msf; }
+ uint32_t lba_to_msf_ps(uint32_t lba) { return cdrom_file::lba_to_msf_alt(lba+150); }
static const unsigned int sector_buffer_size=16, default_irq_delay=16000; //480; //8000; //2000<<2;
static const unsigned int raw_sector_size=2352;
diff --git a/src/tools/chdman.cpp b/src/tools/chdman.cpp
index b2922720969..a0aebb0fb83 100644
--- a/src/tools/chdman.cpp
+++ b/src/tools/chdman.cpp
@@ -11,7 +11,7 @@
#include "avhuff.h"
#include "aviio.h"
#include "bitmap.h"
-#include "chdcd.h"
+#include "cdrom.h"
#include "corefile.h"
#include "hashing.h"
#include "md5.h"
@@ -309,11 +309,11 @@ public:
// if we have TOC - detect audio sectors and swap data
if (m_toc)
{
- assert(offset % CD_FRAME_SIZE == 0);
- assert(length % CD_FRAME_SIZE == 0);
+ assert(offset % cdrom_file::FRAME_SIZE == 0);
+ assert(length % cdrom_file::FRAME_SIZE == 0);
- int startlba = offset / CD_FRAME_SIZE;
- int lenlba = length / CD_FRAME_SIZE;
+ int startlba = offset / cdrom_file::FRAME_SIZE;
+ int lenlba = length / cdrom_file::FRAME_SIZE;
uint8_t *_dest = reinterpret_cast<uint8_t *>(dest);
for (int chdlba = 0; chdlba < lenlba; chdlba++)
@@ -327,11 +327,11 @@ public:
break;
}
// is it audio ?
- if (m_toc->tracks[tracknum].trktype != CD_TRACK_AUDIO)
+ if (m_toc->tracks[tracknum].trktype != cdrom_file::CD_TRACK_AUDIO)
continue;
// byteswap if yes
- int dataoffset = chdlba * CD_FRAME_SIZE;
- for (uint32_t swapindex = dataoffset; swapindex < (dataoffset + CD_MAX_SECTOR_DATA); swapindex += 2)
+ int dataoffset = chdlba * cdrom_file::FRAME_SIZE;
+ for (uint32_t swapindex = dataoffset; swapindex < (dataoffset + cdrom_file::MAX_SECTOR_DATA); swapindex += 2)
{
uint8_t temp = _dest[swapindex];
_dest[swapindex] = _dest[swapindex + 1];
@@ -343,7 +343,7 @@ public:
return length;
}
-const cdrom_toc * m_toc;
+const cdrom_file::toc * m_toc;
private:
// internal state
@@ -359,7 +359,7 @@ class chd_cd_compressor : public chd_file_compressor
{
public:
// construction/destruction
- chd_cd_compressor(cdrom_toc &toc, chdcd_track_input_info &info)
+ chd_cd_compressor(cdrom_file::toc &toc, cdrom_file::track_input_info &info)
: m_file(),
m_toc(toc),
m_info(info) { }
@@ -372,8 +372,8 @@ public:
virtual uint32_t read_data(void *_dest, uint64_t offset, uint32_t length)
{
// verify assumptions made below
- assert(offset % CD_FRAME_SIZE == 0);
- assert(length % CD_FRAME_SIZE == 0);
+ assert(offset % cdrom_file::FRAME_SIZE == 0);
+ assert(length % cdrom_file::FRAME_SIZE == 0);
// initialize destination to 0 so that unused areas are filled
uint8_t *dest = reinterpret_cast<uint8_t *>(_dest);
@@ -384,8 +384,8 @@ public:
uint32_t length_remaining = length;
for (int tracknum = 0; tracknum < m_toc.numtrks; tracknum++)
{
- const cdrom_track_info &trackinfo = m_toc.tracks[tracknum];
- uint64_t endoffs = startoffs + (uint64_t)(trackinfo.frames + trackinfo.extraframes) * CD_FRAME_SIZE;
+ const cdrom_file::track_info &trackinfo = m_toc.tracks[tracknum];
+ uint64_t endoffs = startoffs + (uint64_t)(trackinfo.frames + trackinfo.extraframes) * cdrom_file::FRAME_SIZE;
if (offset >= startoffs && offset < endoffs)
{
// if we don't already have this file open, open it now
@@ -412,7 +412,7 @@ public:
while (length_remaining != 0 && offset < endoffs)
{
// determine start of current frame
- uint64_t src_frame_start = src_track_start + ((offset - startoffs) / CD_FRAME_SIZE) * bytesperframe;
+ uint64_t src_frame_start = src_track_start + ((offset - startoffs) / cdrom_file::FRAME_SIZE) * bytesperframe;
// auto-advance next track for split-bin read
if (src_frame_start == split_track_start && m_lastfile.compare(m_info.track[tracknum+1].fname)!=0)
@@ -456,9 +456,9 @@ public:
}
// advance
- offset += CD_FRAME_SIZE;
- dest += CD_FRAME_SIZE;
- length_remaining -= CD_FRAME_SIZE;
+ offset += cdrom_file::FRAME_SIZE;
+ dest += cdrom_file::FRAME_SIZE;
+ length_remaining -= cdrom_file::FRAME_SIZE;
if (length_remaining == 0)
break;
}
@@ -472,10 +472,10 @@ public:
private:
// internal state
- std::string m_lastfile;
- util::core_file::ptr m_file;
- cdrom_toc & m_toc;
- chdcd_track_input_info & m_info;
+ std::string m_lastfile;
+ util::core_file::ptr m_file;
+ cdrom_file::toc & m_toc;
+ cdrom_file::track_input_info &m_info;
};
@@ -1290,7 +1290,7 @@ static void compress_common(chd_file_compressor &chd)
// to a CUE file
//-------------------------------------------------
-void output_track_metadata(int mode, util::core_file &file, int tracknum, const cdrom_track_info &info, const std::string &filename, uint32_t frameoffs, uint64_t discoffs)
+void output_track_metadata(int mode, util::core_file &file, int tracknum, const cdrom_file::track_info &info, const std::string &filename, uint32_t frameoffs, uint64_t discoffs)
{
if (mode == MODE_GDI)
{
@@ -1298,42 +1298,42 @@ void output_track_metadata(int mode, util::core_file &file, int tracknum, const
switch (info.trktype)
{
- case CD_TRACK_MODE1:
+ case cdrom_file::CD_TRACK_MODE1:
mode = 4;
size = 2048;
break;
- case CD_TRACK_MODE1_RAW:
+ case cdrom_file::CD_TRACK_MODE1_RAW:
mode = 4;
size = 2352;
break;
- case CD_TRACK_MODE2:
+ case cdrom_file::CD_TRACK_MODE2:
mode = 4;
size = 2336;
break;
- case CD_TRACK_MODE2_FORM1:
+ case cdrom_file::CD_TRACK_MODE2_FORM1:
mode = 4;
size = 2048;
break;
- case CD_TRACK_MODE2_FORM2:
+ case cdrom_file::CD_TRACK_MODE2_FORM2:
mode = 4;
size = 2324;
break;
- case CD_TRACK_MODE2_FORM_MIX:
+ case cdrom_file::CD_TRACK_MODE2_FORM_MIX:
mode = 4;
size = 2336;
break;
- case CD_TRACK_MODE2_RAW:
+ case cdrom_file::CD_TRACK_MODE2_RAW:
mode = 4;
size = 2352;
break;
- case CD_TRACK_AUDIO:
+ case cdrom_file::CD_TRACK_AUDIO:
mode = 0;
size = 2352;
break;
@@ -1352,20 +1352,20 @@ void output_track_metadata(int mode, util::core_file &file, int tracknum, const
std::string tempstr;
switch (info.trktype)
{
- case CD_TRACK_MODE1:
- case CD_TRACK_MODE1_RAW:
+ case cdrom_file::CD_TRACK_MODE1:
+ case cdrom_file::CD_TRACK_MODE1_RAW:
tempstr = string_format("MODE1/%04d", info.datasize);
break;
- case CD_TRACK_MODE2:
- case CD_TRACK_MODE2_FORM1:
- case CD_TRACK_MODE2_FORM2:
- case CD_TRACK_MODE2_FORM_MIX:
- case CD_TRACK_MODE2_RAW:
+ case cdrom_file::CD_TRACK_MODE2:
+ case cdrom_file::CD_TRACK_MODE2_FORM1:
+ case cdrom_file::CD_TRACK_MODE2_FORM2:
+ case cdrom_file::CD_TRACK_MODE2_FORM_MIX:
+ case cdrom_file::CD_TRACK_MODE2_RAW:
tempstr = string_format("MODE2/%04d", info.datasize);
break;
- case CD_TRACK_AUDIO:
+ case cdrom_file::CD_TRACK_AUDIO:
tempstr.assign("AUDIO");
break;
}
@@ -1405,15 +1405,15 @@ void output_track_metadata(int mode, util::core_file &file, int tracknum, const
// write out the track type
std::string modesubmode;
- if (info.subtype != CD_SUB_NONE)
- modesubmode = string_format("%s %s", cdrom_get_type_string(info.trktype), cdrom_get_subtype_string(info.subtype));
+ if (info.subtype != cdrom_file::CD_SUB_NONE)
+ modesubmode = string_format("%s %s", cdrom_file::get_type_string(info.trktype), cdrom_file::get_subtype_string(info.subtype));
else
- modesubmode = string_format("%s", cdrom_get_type_string(info.trktype));
+ modesubmode = string_format("%s", cdrom_file::get_type_string(info.trktype));
file.printf("TRACK %s\n", modesubmode);
// write out the attributes
file.printf("NO COPY\n");
- if (info.trktype == CD_TRACK_AUDIO)
+ if (info.trktype == cdrom_file::CD_TRACK_AUDIO)
{
file.printf("NO PRE_EMPHASIS\n");
file.printf("TWO_CHANNEL_AUDIO\n");
@@ -1982,12 +1982,12 @@ static void do_create_hd(parameters_map &params)
static void do_create_cd(parameters_map &params)
{
// process input file
- chdcd_track_input_info track_info;
- cdrom_toc toc = { 0 };
+ cdrom_file::track_input_info track_info;
+ cdrom_file::toc toc = { 0 };
auto input_file_str = params.find(OPTION_INPUT);
if (input_file_str != params.end())
{
- std::error_condition err = chdcd_parse_toc(input_file_str->second->c_str(), toc, track_info);
+ std::error_condition err = cdrom_file::parse_toc(input_file_str->second->c_str(), toc, track_info);
if (err)
report_error(1, "Error parsing input file (%s: %s)\n", *input_file_str->second, err.message());
}
@@ -1997,8 +1997,8 @@ static void do_create_cd(parameters_map &params)
std::string *output_chd_str = parse_output_chd_parameters(params, output_parent);
// process hunk size
- uint32_t hunk_size = output_parent.opened() ? output_parent.hunk_bytes() : CD_FRAMES_PER_HUNK * CD_FRAME_SIZE;
- parse_hunk_size(params, CD_FRAME_SIZE, hunk_size);
+ uint32_t hunk_size = output_parent.opened() ? output_parent.hunk_bytes() : cdrom_file::FRAMES_PER_HUNK * cdrom_file::FRAME_SIZE;
+ parse_hunk_size(params, cdrom_file::FRAME_SIZE, hunk_size);
// process compression
chd_codec_type compression[4];
@@ -2013,9 +2013,9 @@ static void do_create_cd(parameters_map &params)
uint32_t totalsectors = 0;
for (int tracknum = 0; tracknum < toc.numtrks; tracknum++)
{
- cdrom_track_info &trackinfo = toc.tracks[tracknum];
- int padded = (trackinfo.frames + CD_TRACK_PADDING - 1) / CD_TRACK_PADDING;
- trackinfo.extraframes = padded * CD_TRACK_PADDING - trackinfo.frames;
+ cdrom_file::track_info &trackinfo = toc.tracks[tracknum];
+ int padded = (trackinfo.frames + cdrom_file::TRACK_PADDING - 1) / cdrom_file::TRACK_PADDING;
+ trackinfo.extraframes = padded * cdrom_file::TRACK_PADDING - trackinfo.frames;
origtotalsectors += trackinfo.frames;
totalsectors += trackinfo.frames + trackinfo.extraframes;
}
@@ -2028,7 +2028,7 @@ static void do_create_cd(parameters_map &params)
printf("Input tracks: %d\n", toc.numtrks);
printf("Input length: %s\n", msf_string_from_frames(origtotalsectors).c_str());
printf("Compression: %s\n", compression_string(compression).c_str());
- printf("Logical size: %s\n", big_int_string(uint64_t(totalsectors) * CD_FRAME_SIZE).c_str());
+ printf("Logical size: %s\n", big_int_string(uint64_t(totalsectors) * cdrom_file::FRAME_SIZE).c_str());
// catch errors so we can close & delete the output file
chd_cd_compressor *chd = nullptr;
@@ -2038,14 +2038,14 @@ static void do_create_cd(parameters_map &params)
chd = new chd_cd_compressor(toc, track_info);
std::error_condition err;
if (output_parent.opened())
- err = chd->create(output_chd_str->c_str(), uint64_t(totalsectors) * uint64_t(CD_FRAME_SIZE), hunk_size, compression, output_parent);
+ err = chd->create(output_chd_str->c_str(), uint64_t(totalsectors) * uint64_t(cdrom_file::FRAME_SIZE), hunk_size, compression, output_parent);
else
- err = chd->create(output_chd_str->c_str(), uint64_t(totalsectors) * uint64_t(CD_FRAME_SIZE), hunk_size, CD_FRAME_SIZE, compression);
+ err = chd->create(output_chd_str->c_str(), uint64_t(totalsectors) * uint64_t(cdrom_file::FRAME_SIZE), hunk_size, cdrom_file::FRAME_SIZE, compression);
if (err)
report_error(1, "Error creating CHD file (%s): %s", *output_chd_str, err.message());
// add the standard CD metadata; we do this even if we have a parent because it might be different
- err = cdrom_write_metadata(chd, &toc);
+ err = cdrom_file::write_metadata(chd, toc);
if (err)
report_error(1, "Error adding CD metadata: %s", err.message());
@@ -2299,15 +2299,13 @@ static void do_copy(parameters_map &params)
// if we need to re-do the CD metadata, do it now
if (redo_cd)
{
- cdrom_file *cdrom = cdrom_open(&input_chd);
- if (cdrom == nullptr)
- report_error(1, "Error upgrading CD metadata");
- const cdrom_toc *toc = cdrom_get_toc(cdrom);
- err = cdrom_write_metadata(chd, toc);
+ cdrom_file *cdrom = new cdrom_file(&input_chd);
+ const cdrom_file::toc &toc = cdrom->get_toc();
+ err = cdrom_file::write_metadata(chd, toc);
if (err)
report_error(1, "Error writing upgraded CD metadata: %s", err.message());
if (cdda_swap)
- chd->m_toc = toc;
+ chd->m_toc = &toc;
}
// compress it generically
@@ -2418,10 +2416,8 @@ static void do_extract_cd(parameters_map &params)
parse_input_chd_parameters(params, input_chd, input_parent_chd);
// further process input file
- cdrom_file *cdrom = cdrom_open(&input_chd);
- if (cdrom == nullptr)
- report_error(1, "Unable to recognize CHD file as a CD");
- const cdrom_toc *toc = cdrom_get_toc(cdrom);
+ cdrom_file *cdrom = new cdrom_file(&input_chd);
+ const cdrom_file::toc &toc = cdrom->get_toc();
// verify output file doesn't exist
auto output_file_str = params.find(OPTION_OUTPUT);
@@ -2481,20 +2477,20 @@ static void do_extract_cd(parameters_map &params)
// determine total frames
uint64_t total_bytes = 0;
- for (int tracknum = 0; tracknum < toc->numtrks; tracknum++)
- total_bytes += toc->tracks[tracknum].frames * (toc->tracks[tracknum].datasize + toc->tracks[tracknum].subsize);
+ for (int tracknum = 0; tracknum < toc.numtrks; tracknum++)
+ total_bytes += toc.tracks[tracknum].frames * (toc.tracks[tracknum].datasize + toc.tracks[tracknum].subsize);
// GDI must start with the # of tracks
if (mode == MODE_GDI)
{
- output_toc_file->printf("%d\n", toc->numtrks);
+ output_toc_file->printf("%d\n", toc.numtrks);
}
// iterate over tracks and copy all data
uint64_t outputoffs = 0;
uint32_t discoffs = 0;
std::vector<uint8_t> buffer;
- for (int tracknum = 0; tracknum < toc->numtrks; tracknum++)
+ for (int tracknum = 0; tracknum < toc.numtrks; tracknum++)
{
std::string trackbin_name(basename);
@@ -2503,7 +2499,7 @@ static void do_extract_cd(parameters_map &params)
char temp[11];
sprintf(temp, "%02d", tracknum+1);
trackbin_name.append(temp);
- if (toc->tracks[tracknum].trktype == CD_TRACK_AUDIO)
+ if (toc.tracks[tracknum].trktype == cdrom_file::CD_TRACK_AUDIO)
trackbin_name.append(".raw");
else
trackbin_name.append(".bin");
@@ -2518,7 +2514,7 @@ static void do_extract_cd(parameters_map &params)
}
// output the metadata about the track to the TOC file
- const cdrom_track_info &trackinfo = toc->tracks[tracknum];
+ const cdrom_file::track_info &trackinfo = toc.tracks[tracknum];
if (mode == MODE_GDI)
{
output_track_metadata(mode, *output_toc_file, tracknum, trackinfo, std::string(core_filename_extract_base(trackbin_name)), discoffs, outputoffs);
@@ -2530,8 +2526,8 @@ static void do_extract_cd(parameters_map &params)
// If this is bin/cue output and the CHD contains subdata, warn the user and don't include
// the subdata size in the buffer calculation.
- uint32_t output_frame_size = trackinfo.datasize + ((trackinfo.subtype != CD_SUB_NONE) ? trackinfo.subsize : 0);
- if (trackinfo.subtype != CD_SUB_NONE && ((mode == MODE_CUEBIN) || (mode == MODE_GDI)))
+ uint32_t output_frame_size = trackinfo.datasize + ((trackinfo.subtype != cdrom_file::CD_SUB_NONE) ? trackinfo.subsize : 0);
+ if (trackinfo.subtype != cdrom_file::CD_SUB_NONE && ((mode == MODE_CUEBIN) || (mode == MODE_GDI)))
{
printf("Warning: Track %d has subcode data. bin/cue and gdi formats cannot contain subcode data and it will be omitted.\n", tracknum+1);
printf(" : This may affect usage of the output image. Use bin/toc output to keep all data.\n");
@@ -2549,11 +2545,11 @@ static void do_extract_cd(parameters_map &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_phys(cdrom, tracknum) + frame, &buffer[bufferoffs], trackinfo.trktype, true);
+ cdrom->read_data(cdrom->get_track_start_phys(tracknum) + frame, &buffer[bufferoffs], trackinfo.trktype, true);
// for CDRWin and GDI audio tracks must be reversed
// in the case of GDI and CHD version < 5 we assuming source CHD image is GDROM so audio tracks is already reversed
- if (((mode == MODE_GDI && input_chd.version() > 4) || (mode == MODE_CUEBIN)) && (trackinfo.trktype == CD_TRACK_AUDIO))
+ if (((mode == MODE_GDI && input_chd.version() > 4) || (mode == MODE_CUEBIN)) && (trackinfo.trktype == cdrom_file::CD_TRACK_AUDIO))
for (int swapindex = 0; swapindex < trackinfo.datasize; swapindex += 2)
{
uint8_t swaptemp = buffer[bufferoffs + swapindex];
@@ -2564,9 +2560,9 @@ static void do_extract_cd(parameters_map &params)
discoffs++;
// read the subcode data
- if (trackinfo.subtype != CD_SUB_NONE && (mode == MODE_NORMAL))
+ if (trackinfo.subtype != cdrom_file::CD_SUB_NONE && (mode == MODE_NORMAL))
{
- cdrom_read_subcode(cdrom, cdrom_get_track_start_phys(cdrom, tracknum) + frame, &buffer[bufferoffs], true);
+ cdrom->read_subcode(cdrom->get_track_start_phys(tracknum) + frame, &buffer[bufferoffs], true);
bufferoffs += trackinfo.subsize;
}