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.
This commit is contained in:
tyfighter 2019-02-08 11:33:44 -06:00
parent 17cd12e896
commit 1222583005
6 changed files with 72 additions and 13 deletions

View File

@ -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;
}

View File

@ -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();
};

View File

@ -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);
}
}

View File

@ -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)

View File

@ -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);
}

View File

@ -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);
}