From e4564eb99a5513e4044eecc070cbb09cb689a657 Mon Sep 17 00:00:00 2001 From: Olivier Galibert Date: Fri, 1 Apr 2022 11:36:41 +0200 Subject: cdrom_file: classify. Could use more internal work, but it's a step --- scripts/src/lib.lua | 2 - src/devices/bus/isa/mcd.cpp | 22 +- src/devices/bus/nscsi/cd.cpp | 24 +- src/devices/imagedev/chd_cd.cpp | 12 +- src/devices/machine/akiko.cpp | 52 +- src/devices/machine/spg290_cdservo.cpp | 50 +- src/devices/machine/stvcd.cpp | 74 +- src/devices/machine/stvcd.h | 2 +- src/devices/machine/t10mmc.cpp | 54 +- src/devices/sound/cdda.cpp | 10 +- src/lib/util/cdrom.cpp | 2587 +++++++++++++++++++++++++------- src/lib/util/cdrom.h | 412 ++--- src/lib/util/chd.cpp | 2 +- src/lib/util/chdcd.cpp | 1848 ----------------------- src/lib/util/chdcd.h | 40 - src/lib/util/chdcodec.cpp | 80 +- src/mame/drivers/fmtowns.cpp | 32 +- src/mame/drivers/jaguar.cpp | 8 +- src/mame/drivers/konamim2.cpp | 2 +- src/mame/drivers/ksys573.cpp | 4 +- src/mame/machine/cdicdic.cpp | 18 +- src/mame/machine/gdrom.cpp | 14 +- src/mame/machine/megacdcd.cpp | 44 +- src/mame/machine/megacdcd.h | 2 +- src/mame/machine/naomigd.cpp | 16 +- src/mame/machine/pce_cd.cpp | 41 +- src/mame/machine/pce_cd.h | 2 +- src/mame/machine/psxcd.cpp | 36 +- src/mame/machine/psxcd.h | 4 +- src/tools/chdman.cpp | 150 +- 30 files changed, 2680 insertions(+), 2964 deletions(-) delete mode 100644 src/lib/util/chdcd.cpp delete mode 100644 src/lib/util/chdcd.h diff --git a/scripts/src/lib.lua b/scripts/src/lib.lua index 1c9037b9f60..bb3c14b0535 100644 --- a/scripts/src/lib.lua +++ b/scripts/src/lib.lua @@ -45,8 +45,6 @@ end MAME_DIR .. "src/lib/util/cdrom.h", MAME_DIR .. "src/lib/util/chd.cpp", MAME_DIR .. "src/lib/util/chd.h", - MAME_DIR .. "src/lib/util/chdcd.cpp", - MAME_DIR .. "src/lib/util/chdcd.h", MAME_DIR .. "src/lib/util/chdcodec.cpp", MAME_DIR .. "src/lib/util/chdcodec.h", MAME_DIR .. "src/lib/util/client_http.hpp", 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(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(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(CD_MAX_SECTOR_DATA * MAX_SECTORS ); + m_audio_cache = std::make_unique(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 #include @@ -69,58 +68,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 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(&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(§or[ECC_P_OFFSET], 0, 2 * ECC_P_NUM_BYTES); memset(§or[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 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 -#include -#include -#include - - - -/*************************************************************************** - 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 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 - - -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(buffer), frames * CD_MAX_SECTOR_DATA/4, m_swap_endian)) + if (!m_encoder.encode_interleaved(reinterpret_cast(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(&m_buffer[frames * CD_MAX_SECTOR_DATA]); - m_deflater.avail_in = frames * CD_MAX_SUBCODE_DATA; + m_deflater.next_in = const_cast(&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(buffer), frames * CD_MAX_SECTOR_DATA/4, m_swap_endian)) + if (!m_decoder.decode_interleaved(reinterpret_cast(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(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;iget_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 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(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(_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 ¶ms) static void do_create_cd(parameters_map ¶ms) { // 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 ¶ms) 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 ¶ms) 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 ¶ms) 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 ¶ms) 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 ¶ms) // 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 ¶ms) 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 ¶ms) // 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 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 ¶ms) 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 ¶ms) } // 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 ¶ms) // 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 ¶ms) progress(false, "Extracting, %.1f%% complete... \r", 100.0 * double(outputoffs) / double(total_bytes)); // read the data - cdrom_read_data(cdrom, cdrom_get_track_start_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 ¶ms) 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; } -- cgit v1.2.3