nscsi_cd: set block size with mode select (nw)

Solaris 2.3 uses MODE SELECT (6) to specify a 512-byte block size during boot from CD-ROM on sun4_40. This patch is very limited (only a single mode parameter block, and no other parameters are supported), but sufficient to make sun4 happy.
This commit is contained in:
Patrick Mackinlay 2018-10-02 13:55:48 +07:00
parent 6f54f6aa97
commit dacf82932a
2 changed files with 31 additions and 1 deletions

View File

@ -37,7 +37,6 @@ MACHINE_CONFIG_END
void nscsi_cdrom_device::set_block_size(u32 block_size)
{
assert_always(!started(), "block size should not be set after device start");
assert_always(bytes_per_sector % block_size == 0, "block size must be a factor of sector size");
bytes_per_block = block_size;
@ -60,6 +59,25 @@ uint8_t nscsi_cdrom_device::scsi_get_data(int id, int pos)
return sector_buffer[(pos + extra_pos) & (bytes_per_sector - 1)];
}
void nscsi_cdrom_device::scsi_put_data(int id, int pos, uint8_t data)
{
if(id != 2) {
nscsi_full_device::scsi_put_data(id, pos, data);
return;
}
// process mode parameter header and one block descriptor
if(pos < sizeof(mode_data)) {
mode_data[pos] = data;
// is this the last byte of the mode parameter block descriptor?
if(pos == sizeof(mode_data) - 1)
// is there exactly one block descriptor?
if(mode_data[3] == 8)
set_block_size((mode_data[9] << 16) | (mode_data[10] << 8) | (mode_data[11] << 0));
}
}
void nscsi_cdrom_device::return_no_cd()
{
sense(false, 3);
@ -162,6 +180,16 @@ void nscsi_cdrom_device::scsi_command()
break;
}
case SC_MODE_SELECT_6:
LOG("command MODE SELECT 6 length %d\n", scsi_cmdbuf[4]);
// accept mode select parameter data
if(scsi_cmdbuf[4])
scsi_data_out(2, scsi_cmdbuf[4]);
scsi_status_complete(SS_GOOD);
break;
case SC_START_STOP_UNIT:
LOG("command %s UNIT%s\n", (scsi_cmdbuf[4] & 0x1) ? "START" : "STOP",
(scsi_cmdbuf[4] & 0x2) ? (scsi_cmdbuf[4] & 0x1) ? " (LOAD)" : " (EJECT)" : "");

View File

@ -23,6 +23,7 @@ protected:
virtual void scsi_command() override;
virtual uint8_t scsi_get_data(int id, int pos) override;
virtual void scsi_put_data(int buf, int offset, uint8_t data) override;
private:
static constexpr uint32_t bytes_per_sector = 2048;
@ -32,6 +33,7 @@ private:
uint32_t bytes_per_block;
int lba, cur_sector;
required_device<cdrom_image_device> image;
uint8_t mode_data[12];
void return_no_cd();
};