summaryrefslogtreecommitdiffstatshomepage
path: root/src/devices/imagedev/cdromimg.cpp
diff options
context:
space:
mode:
Diffstat (limited to 'src/devices/imagedev/cdromimg.cpp')
-rw-r--r--src/devices/imagedev/cdromimg.cpp283
1 files changed, 283 insertions, 0 deletions
diff --git a/src/devices/imagedev/cdromimg.cpp b/src/devices/imagedev/cdromimg.cpp
new file mode 100644
index 00000000000..b4deb9fc4ad
--- /dev/null
+++ b/src/devices/imagedev/cdromimg.cpp
@@ -0,0 +1,283 @@
+// license:BSD-3-Clause
+// copyright-holders:Nathan Woods, R. Belmont, Miodrag Milanovic
+/*********************************************************************
+
+ CD/DVD reader
+
+*********************************************************************/
+
+#include "emu.h"
+#include "cdromimg.h"
+
+#include "romload.h"
+
+// device type definition
+DEFINE_DEVICE_TYPE(CDROM, cdrom_image_device, "cdrom_image", "CD-ROM Image")
+DEFINE_DEVICE_TYPE(GDROM, gdrom_image_device, "gdrom_image", "CD/GD-ROM Image")
+DEFINE_DEVICE_TYPE(DVDROM, dvdrom_image_device, "dvdrom_image", "CD/DVD-ROM Image")
+
+//-------------------------------------------------
+// cdrom_image_device - constructor
+//-------------------------------------------------
+
+cdrom_image_device::cdrom_image_device(const machine_config &mconfig, const char *tag, device_t *owner, uint32_t clock)
+ : cdrom_image_device(mconfig, CDROM, tag, owner, clock)
+{
+}
+
+cdrom_image_device::cdrom_image_device(const machine_config &mconfig, device_type type, const char *tag, device_t *owner, uint32_t clock, bool dvd_compat, bool gd_compat)
+ : device_t(mconfig, type, tag, owner, clock),
+ device_image_interface(mconfig, *this),
+ m_gd_compat(gd_compat),
+ m_dvd_compat(dvd_compat),
+ m_cdrom_handle(nullptr),
+ m_dvdrom_handle(nullptr),
+ m_extension_list(nullptr),
+ m_interface(nullptr)
+{
+}
+
+//-------------------------------------------------
+// cdrom_image_device - destructor
+//-------------------------------------------------
+
+cdrom_image_device::~cdrom_image_device()
+{
+}
+
+//-------------------------------------------------
+// device_config_complete - perform any
+// operations now that the configuration is
+// complete
+//-------------------------------------------------
+
+void cdrom_image_device::device_config_complete()
+{
+ m_extension_list = "chd,cue,toc,nrg,gdi,iso,cdr";
+
+ add_format("chdcd", m_dvd_compat ? "CD/DVD-ROM drive" : "CD-ROM drive", m_extension_list, "");
+}
+
+//-------------------------------------------------
+// device_start - device-specific startup
+//-------------------------------------------------
+
+void cdrom_image_device::device_start()
+{
+ if (has_preset_images())
+ setup_current_preset_image();
+ else
+ {
+ m_cdrom_handle.reset();
+ m_dvdrom_handle.reset();
+ }
+}
+
+void cdrom_image_device::setup_current_preset_image()
+{
+ m_cdrom_handle.reset();
+ m_dvdrom_handle.reset();
+
+ chd_file *chd = current_preset_image_chd();
+ if (!chd->check_is_cd() || (m_gd_compat && !chd->check_is_gd()))
+ m_cdrom_handle = std::make_unique<cdrom_file>(chd);
+ else if(m_dvd_compat && !chd->check_is_dvd())
+ m_dvdrom_handle = std::make_unique<dvdrom_file>(chd);
+ else
+ fatalerror("chd for region %s is not compatible with the cdrom image device\n", preset_images_list()[current_preset_image_id()]);
+}
+
+void cdrom_image_device::device_stop()
+{
+ m_cdrom_handle.reset();
+ m_dvdrom_handle.reset();
+ if (m_self_chd.opened())
+ m_self_chd.close();
+}
+
+std::pair<std::error_condition, std::string> cdrom_image_device::call_load()
+{
+ if (has_preset_images())
+ {
+ setup_current_preset_image();
+ return std::make_pair(image_error(0), std::string());
+ }
+
+ std::error_condition err;
+ chd_file *chd = nullptr;
+
+ m_cdrom_handle.reset();
+ m_dvdrom_handle.reset();
+
+ if (!loaded_through_softlist())
+ {
+ if (is_filetype("chd") && is_loaded())
+ {
+ util::core_file::ptr proxy;
+ err = util::core_file::open_proxy(image_core_file(), proxy);
+ if (!err)
+ err = m_self_chd.open(std::move(proxy)); // CDs are never writeable
+ if (err)
+ goto error;
+ chd = &m_self_chd;
+ }
+ }
+ else
+ {
+ chd = device().machine().rom_load().get_disk_handle(device().subtag("cdrom"));
+ }
+
+ // open the CHD file
+ if (chd)
+ {
+ err = chd->check_is_cd();
+ if (err == chd_file::error::METADATA_NOT_FOUND && m_gd_compat)
+ err = chd->check_is_gd();
+ if (!err)
+ {
+ m_cdrom_handle.reset(new cdrom_file(chd));
+ return std::make_pair(std::error_condition(), std::string());
+ }
+ if (err != chd_file::error::METADATA_NOT_FOUND)
+ goto error;
+
+ if (m_dvd_compat)
+ {
+ err = chd->check_is_dvd();
+ if (!err)
+ {
+ m_dvdrom_handle.reset(new dvdrom_file(chd));
+ return std::make_pair(std::error_condition(), std::string());
+ }
+ if (err != chd_file::error::METADATA_NOT_FOUND)
+ goto error;
+ }
+
+ err = image_error::INVALIDIMAGE;
+ goto error;
+ }
+ else
+ {
+ try
+ {
+ m_cdrom_handle.reset(new cdrom_file(filename()));
+ }
+ catch (...)
+ {
+ try
+ {
+ m_dvdrom_handle.reset(new dvdrom_file(filename()));
+ }
+ catch (...)
+ {
+ err = image_error::INVALIDIMAGE;
+ goto error;
+ }
+ }
+ }
+
+ return std::make_pair(std::error_condition(), std::string());
+
+error:
+ if (chd && chd == &m_self_chd)
+ m_self_chd.close();
+ return std::make_pair(err ? err : image_error::UNSPECIFIED, std::string());
+}
+
+void cdrom_image_device::call_unload()
+{
+ assert(m_cdrom_handle || m_dvdrom_handle);
+ m_cdrom_handle.reset();
+ m_dvdrom_handle.reset();
+ if (m_self_chd.opened())
+ m_self_chd.close();
+}
+
+int cdrom_image_device::get_last_track() const
+{
+ if (m_cdrom_handle)
+ return m_cdrom_handle->get_last_track();
+ return 0;
+}
+
+int cdrom_image_device::get_last_session() const
+{
+ if (m_cdrom_handle)
+ return m_cdrom_handle->get_last_session();
+ return 0;
+}
+
+uint32_t cdrom_image_device::get_track(uint32_t frame) const
+{
+ if (m_cdrom_handle)
+ return m_cdrom_handle->get_track(frame);
+ return 0;
+}
+
+uint32_t cdrom_image_device::get_track_index(uint32_t frame) const
+{
+ if (m_cdrom_handle)
+ return m_cdrom_handle->get_track_index(frame);
+ return 0;
+}
+
+uint32_t cdrom_image_device::get_track_start(uint32_t track) const
+{
+ if (m_cdrom_handle)
+ return m_cdrom_handle->get_track_start(track);
+ return 0;
+}
+
+bool cdrom_image_device::read_data(uint32_t lbasector, void *buffer, uint32_t datatype, bool phys)
+{
+ if (m_cdrom_handle)
+ return m_cdrom_handle->read_data(lbasector, buffer, datatype, phys);
+ if (m_dvdrom_handle)
+ return !m_dvdrom_handle->read_data(lbasector, buffer);
+ return 0;
+}
+
+bool cdrom_image_device::read_subcode(uint32_t lbasector, void *buffer, bool phys)
+{
+ if (m_cdrom_handle)
+ return m_cdrom_handle->read_subcode(lbasector, buffer, phys);
+ return 0;
+}
+
+int cdrom_image_device::get_adr_control(int track) const
+{
+ if (m_cdrom_handle)
+ return m_cdrom_handle->get_adr_control(track);
+ return 0;
+}
+
+const cdrom_file::toc &cdrom_image_device::get_toc() const
+{
+ static cdrom_file::toc notoc;
+ if (m_cdrom_handle)
+ return m_cdrom_handle->get_toc();
+ return notoc;
+}
+
+int cdrom_image_device::get_track_type(int track) const
+{
+ if (m_cdrom_handle)
+ return m_cdrom_handle->get_track_type(track);
+ return 0;
+}
+
+bool cdrom_image_device::is_cd() const
+{
+ return m_cdrom_handle != nullptr;
+}
+
+bool cdrom_image_device::is_gd() const
+{
+ return m_cdrom_handle && m_cdrom_handle->is_gdrom();
+}
+
+bool cdrom_image_device::is_dvd() const
+{
+ return m_dvdrom_handle != nullptr;
+}
+