From 12225830053e205c0884fca7770cc0cfb4611cf3 Mon Sep 17 00:00:00 2001 From: tyfighter Date: Fri, 8 Feb 2019 11:33:44 -0600 Subject: nscsi_cd: Add new nscsi_cdrom_device derived type for SGI systems Some versions of IRIX will always send an SGI vendor specific SCSI command to the CDROM, so we need some specialization to acknowledge this command. --- src/devices/machine/nscsi_bus.cpp | 17 ++++++------- src/devices/machine/nscsi_bus.h | 2 +- src/devices/machine/nscsi_cd.cpp | 51 ++++++++++++++++++++++++++++++++++++++- src/devices/machine/nscsi_cd.h | 11 +++++++++ src/mame/drivers/indy_indigo2.cpp | 2 +- src/mame/machine/hpc1.cpp | 2 +- 6 files changed, 72 insertions(+), 13 deletions(-) diff --git a/src/devices/machine/nscsi_bus.cpp b/src/devices/machine/nscsi_bus.cpp index a16ff1f5b03..ef3c0dd9f9a 100644 --- a/src/devices/machine/nscsi_bus.cpp +++ b/src/devices/machine/nscsi_bus.cpp @@ -442,7 +442,7 @@ void nscsi_full_device::step(bool timeout) break; } - if(command_done()) { + if(scsi_command_done(scsi_cmdbuf[0], data_buffer_pos)) { scsi_cmdsize = data_buffer_pos; scsi_bus->ctrl_wait(scsi_refid, 0, S_ACK); scsi_command(); @@ -509,18 +509,17 @@ void nscsi_full_device::target_send_buffer_byte() target_send_byte(scsi_get_data(data_buffer_id, data_buffer_pos++)); } -bool nscsi_full_device::command_done() +bool nscsi_full_device::scsi_command_done(uint8_t command, uint8_t length) { - if(!data_buffer_pos) + if(!length) return false; - uint8_t h = scsi_cmdbuf[0]; - switch(h >> 5) { - case 0: return data_buffer_pos == 6; - case 1: return data_buffer_pos == 10; - case 2: return data_buffer_pos == 10; + switch(command >> 5) { + case 0: return length == 6; + case 1: return length == 10; + case 2: return length == 10; case 3: return true; case 4: return true; - case 5: return data_buffer_pos == 12; + case 5: return length == 12; case 6: return true; case 7: return true; } diff --git a/src/devices/machine/nscsi_bus.h b/src/devices/machine/nscsi_bus.h index f3404ceb526..244eda94fe8 100644 --- a/src/devices/machine/nscsi_bus.h +++ b/src/devices/machine/nscsi_bus.h @@ -308,6 +308,7 @@ protected: virtual void scsi_message(); virtual void scsi_command(); + virtual bool scsi_command_done(uint8_t command, uint8_t length); void scsi_unknown_command(); void scsi_status_complete(uint8_t st); @@ -448,7 +449,6 @@ private: void target_recv_byte(); void target_send_byte(uint8_t val); void target_send_buffer_byte(); - bool command_done(); }; diff --git a/src/devices/machine/nscsi_cd.cpp b/src/devices/machine/nscsi_cd.cpp index 186f22b1704..06ecb71bb04 100644 --- a/src/devices/machine/nscsi_cd.cpp +++ b/src/devices/machine/nscsi_cd.cpp @@ -3,10 +3,11 @@ #include "emu.h" #include "machine/nscsi_cd.h" -#define VERBOSE 1 +#define VERBOSE 0 #include "logmacro.h" DEFINE_DEVICE_TYPE(NSCSI_CDROM, nscsi_cdrom_device, "scsi_cdrom", "SCSI CD-ROM") +DEFINE_DEVICE_TYPE(NSCSI_CDROM_SGI, nscsi_cdrom_sgi_device, "scsi_cdrom_sgi", "SCSI CD-ROM SGI") DEFINE_DEVICE_TYPE(NSCSI_RRD45, nscsi_dec_rrd45_device, "nrrd45", "RRD45 CD-ROM (New)") DEFINE_DEVICE_TYPE(NSCSI_XM3301, nscsi_toshiba_xm3301_device, "nxm3301", "XM-3301TA CD-ROM (New)") DEFINE_DEVICE_TYPE(NSCSI_XM5301SUN, nscsi_toshiba_xm5301_sun_device, "nxm5301sun", "XM-5301B Sun 4x CD-ROM (New)") @@ -19,6 +20,11 @@ nscsi_cdrom_device::nscsi_cdrom_device(const machine_config &mconfig, const char { } +nscsi_cdrom_sgi_device::nscsi_cdrom_sgi_device(const machine_config &mconfig, const char *tag, device_t *owner, uint32_t clock) : + nscsi_cdrom_device(mconfig, NSCSI_CDROM_SGI, tag, owner, "Sony", "CDU-76S", "1.0", 0x00, 0x05) +{ +} + nscsi_dec_rrd45_device::nscsi_dec_rrd45_device(const machine_config &mconfig, const char *tag, device_t *owner, uint32_t clock) : nscsi_cdrom_device(mconfig, NSCSI_RRD45, tag, owner, "DEC ", "RRD45 (C) DEC ", "0436", 0x98, 0x02) { @@ -559,3 +565,46 @@ void nscsi_cdrom_device::scsi_command() break; } } + +enum sgi_scsi_command_e : uint8_t { + /* + * The SGI supplied CD-ROM drives (and possibly those from some other vendors) + * identify themselves as hard disk drives at poweron, and after SCSI bus resets, + * until issued a vendor specific command (0xc9). This is done because older + * systems would otherwise be unable to boot and load miniroots from CD, due to + * their design (they attempted to protect the user from booting from + * "ridiculous" devices, long before CD-ROM drives existed). The SGI drives are + * sent a command to "revert" to CD-ROM inquiry information during boot if on + * a SCSI bus handled by the PROM, but not all possible buses are handled by all + * PROMs; additionally, a SCSI bus reset causes the CD-ROM drives to revert to + * the poweron default, and this could happen before the hardware inventory code + * in the kernel runs, if there are SCSI problems. + */ + SGI_HD2CDROM = 0xc9, +}; + +void nscsi_cdrom_sgi_device::scsi_command() +{ + switch (scsi_cmdbuf[0]) { + case SGI_HD2CDROM: + LOG("command SGI_HD2CDROM"); + // No need to do anything (yet). Just acknowledge the command. + scsi_status_complete(SS_GOOD); + break; + + default: + nscsi_cdrom_device::scsi_command(); + break; + } +} + +bool nscsi_cdrom_sgi_device::scsi_command_done(uint8_t command, uint8_t length) +{ + switch (command) { + case SGI_HD2CDROM: + return length == 10; + + default: + return nscsi_full_device::scsi_command_done(command, length); + } +} \ No newline at end of file diff --git a/src/devices/machine/nscsi_cd.h b/src/devices/machine/nscsi_cd.h index 3a5f67b7170..48097cea42f 100644 --- a/src/devices/machine/nscsi_cd.h +++ b/src/devices/machine/nscsi_cd.h @@ -57,6 +57,16 @@ private: static int to_msf(int frame); }; +class nscsi_cdrom_sgi_device : public nscsi_cdrom_device +{ +public: + nscsi_cdrom_sgi_device(const machine_config &mconfig, const char *tag, device_t *owner, uint32_t clock = 0); + +protected: + virtual void scsi_command() override; + virtual bool scsi_command_done(uint8_t command, uint8_t length) override; +}; + class nscsi_dec_rrd45_device : public nscsi_cdrom_device { public: @@ -94,6 +104,7 @@ public: }; DECLARE_DEVICE_TYPE(NSCSI_CDROM, nscsi_cdrom_device) +DECLARE_DEVICE_TYPE(NSCSI_CDROM_SGI, nscsi_cdrom_sgi_device) DECLARE_DEVICE_TYPE(NSCSI_RRD45, nscsi_dec_rrd45_device) DECLARE_DEVICE_TYPE(NSCSI_XM3301, nscsi_toshiba_xm3301_device) DECLARE_DEVICE_TYPE(NSCSI_XM5301SUN, nscsi_toshiba_xm5301_sun_device) diff --git a/src/mame/drivers/indy_indigo2.cpp b/src/mame/drivers/indy_indigo2.cpp index bd75c7c3a5b..882b167bad7 100644 --- a/src/mame/drivers/indy_indigo2.cpp +++ b/src/mame/drivers/indy_indigo2.cpp @@ -200,7 +200,7 @@ void ip22_state::wd33c93(device_t *device) void ip22_state::scsi_devices(device_slot_interface &device) { - device.option_add("cdrom", NSCSI_CDROM); + device.option_add("cdrom", NSCSI_CDROM_SGI); device.option_add("harddisk", NSCSI_HARDDISK); //device.set_option_machine_config("cdrom", cdrom_config); } diff --git a/src/mame/machine/hpc1.cpp b/src/mame/machine/hpc1.cpp index c7c5bb3d619..75ec6f368f5 100644 --- a/src/mame/machine/hpc1.cpp +++ b/src/mame/machine/hpc1.cpp @@ -123,7 +123,7 @@ void hpc1_device::indigo_mice(device_slot_interface &device) void hpc1_device::scsi_devices(device_slot_interface &device) { - device.option_add("cdrom", NSCSI_CDROM); + device.option_add("cdrom", NSCSI_CDROM_SGI); device.option_add("harddisk", NSCSI_HARDDISK); } -- cgit v1.2.3