From 890ae60839bb4f79859287723623579db1bc9caf Mon Sep 17 00:00:00 2001 From: Patrick Mackinlay Date: Mon, 23 Jul 2018 20:42:08 +0700 Subject: nscsi_cd: support media changes (nw) Together, these changes enable softlist CD-ROM media changes for InterPro, and presumably other nscsi_cd systems. Haven't looked into how other CD-ROM devices work, but the romload fix should apply equally to them too. * nscsi_cd: detect and respond to media changes * romload: fix disk entry processing --- src/devices/machine/nscsi_cd.cpp | 34 ++++++++++++++++++++++++---------- src/devices/machine/nscsi_cd.h | 2 ++ src/emu/romload.cpp | 4 ++++ 3 files changed, 30 insertions(+), 10 deletions(-) diff --git a/src/devices/machine/nscsi_cd.cpp b/src/devices/machine/nscsi_cd.cpp index 8211657b73c..8827af488ea 100644 --- a/src/devices/machine/nscsi_cd.cpp +++ b/src/devices/machine/nscsi_cd.cpp @@ -2,7 +2,6 @@ // copyright-holders:Olivier Galibert #include "emu.h" #include "machine/nscsi_cd.h" -#include "imagedev/chd_cd.h" #define VERBOSE 1 #include "logmacro.h" @@ -10,7 +9,7 @@ DEFINE_DEVICE_TYPE(NSCSI_CDROM, nscsi_cdrom_device, "scsi_cdrom", "SCSI CD-ROM") nscsi_cdrom_device::nscsi_cdrom_device(const machine_config &mconfig, const char *tag, device_t *owner, uint32_t clock) : - nscsi_full_device(mconfig, NSCSI_CDROM, tag, owner, clock), cdrom(nullptr), bytes_per_block(bytes_per_sector), lba(0), cur_sector(0) + nscsi_full_device(mconfig, NSCSI_CDROM, tag, owner, clock), cdrom(nullptr), bytes_per_block(bytes_per_sector), lba(0), cur_sector(0), image(*this, "image") { } @@ -26,7 +25,7 @@ void nscsi_cdrom_device::device_start() void nscsi_cdrom_device::device_reset() { nscsi_full_device::device_reset(); - cdrom = subdevice("image")->get_cdrom_file(); + cdrom = image->get_cdrom_file(); lba = 0; cur_sector = -1; } @@ -49,7 +48,7 @@ uint8_t nscsi_cdrom_device::scsi_get_data(int id, int pos) { if(id != 2) return nscsi_full_device::scsi_get_data(id, pos); - int sector = (lba * bytes_per_block + pos) / bytes_per_sector; + const int sector = (lba * bytes_per_block + pos) / bytes_per_sector; if(sector != cur_sector) { cur_sector = sector; if(!cdrom_read_data(cdrom, sector, sector_buffer, CD_TRACK_MODE1)) { @@ -70,6 +69,19 @@ void nscsi_cdrom_device::scsi_command() { int blocks; + // check for media change + if((cdrom != image->get_cdrom_file()) && (scsi_cmdbuf[0] != SC_INQUIRY)) + { + // clear media change condition + cdrom = image->get_cdrom_file(); + cur_sector = -1; + + // report unit attention condition + sense(false, 6); + scsi_status_complete(SS_CHECK_CONDITION); + return; + } + switch(scsi_cmdbuf[0]) { case SC_TEST_UNIT_READY: LOG("command TEST UNIT READY\n"); @@ -109,7 +121,7 @@ void nscsi_cdrom_device::scsi_command() int size = scsi_cmdbuf[4]; switch(page) { case 0: - std::fill_n(scsi_cmdbuf, 148, 0); + std::fill_n(scsi_cmdbuf, 36, 0); // vendor and product information must be padded with spaces std::fill_n(&scsi_cmdbuf[8], 28, 0x20); @@ -118,13 +130,14 @@ void nscsi_cdrom_device::scsi_command() scsi_cmdbuf[1] = 0x80; // media is removable scsi_cmdbuf[2] = 0x05; // device complies with SPC-3 standard scsi_cmdbuf[3] = 0x02; // response data format = SPC-3 standard + scsi_cmdbuf[4] = 32; // additional length // some Konami games freak out if this isn't "Sony", so we'll lie // this is the actual drive on my Nagano '98 board strncpy((char *)&scsi_cmdbuf[8], "Sony", 4); strncpy((char *)&scsi_cmdbuf[16], "CDU-76S", 7); strncpy((char *)&scsi_cmdbuf[32], "1.0", 3); - if(size > 148) - size = 148; + if(size > 36) + size = 36; scsi_data_in(SBUF_MAIN, size); break; } @@ -133,7 +146,8 @@ void nscsi_cdrom_device::scsi_command() } case SC_START_STOP_UNIT: - LOG("command START STOP UNIT\n"); + LOG("command %s UNIT%s\n", (scsi_cmdbuf[4] & 0x1) ? "START" : "STOP", + (scsi_cmdbuf[4] & 0x2) ? (scsi_cmdbuf[4] & 0x1) ? " (LOAD)" : " (EJECT)" : ""); scsi_status_complete(SS_GOOD); break; @@ -196,7 +210,7 @@ void nscsi_cdrom_device::scsi_command() const uint32_t temp = cdrom_get_track_start(cdrom, 0xaa) * (bytes_per_sector / bytes_per_block) - 1; scsi_cmdbuf[pos++] = 0x08; // Block descriptor length - scsi_cmdbuf[pos++] = (temp>>24) & 0xff; + scsi_cmdbuf[pos++] = 0x00; // density code scsi_cmdbuf[pos++] = (temp>>16) & 0xff; scsi_cmdbuf[pos++] = (temp>>8) & 0xff; scsi_cmdbuf[pos++] = (temp & 0xff); @@ -251,7 +265,7 @@ void nscsi_cdrom_device::scsi_command() case SC_PREVENT_ALLOW_MEDIUM_REMOVAL: // TODO: support eject prevention - LOG("command PREVENT ALLOW MEDIUM REMOVAL\n"); + LOG("command %s MEDIUM REMOVAL\n", (scsi_cmdbuf[4] & 0x1) ? "PREVENT" : "ALLOW"); scsi_status_complete(SS_GOOD); break; diff --git a/src/devices/machine/nscsi_cd.h b/src/devices/machine/nscsi_cd.h index 95afedfdf66..45e470b4c32 100644 --- a/src/devices/machine/nscsi_cd.h +++ b/src/devices/machine/nscsi_cd.h @@ -6,6 +6,7 @@ #pragma once #include "machine/nscsi_bus.h" +#include "imagedev/chd_cd.h" #include "cdrom.h" class nscsi_cdrom_device : public nscsi_full_device @@ -30,6 +31,7 @@ private: cdrom_file *cdrom; uint32_t bytes_per_block; int lba, cur_sector; + required_device image; void return_no_cd(); }; diff --git a/src/emu/romload.cpp b/src/emu/romload.cpp index ff680b173a1..4945de6a197 100644 --- a/src/emu/romload.cpp +++ b/src/emu/romload.cpp @@ -1173,6 +1173,10 @@ chd_error rom_load_manager::open_disk_diff(emu_options &options, const rom_entry void rom_load_manager::process_disk_entries(const char *regiontag, const rom_entry *parent_region, const rom_entry *romp, const char *locationtag) { + /* remove existing disk entries for this region */ + m_chd_list.erase(std::remove_if(m_chd_list.begin(), m_chd_list.end(), + [regiontag](std::unique_ptr &chd){ return !strcmp(chd->region(), regiontag); }), m_chd_list.end()); + /* loop until we hit the end of this region */ for ( ; !ROMENTRY_ISREGIONEND(romp); romp++) { -- cgit v1.2.3