Add SCSI devices.

scsibus has a new method attach_scsi_devices which is used by all machines to populate a SCSI bus with one or more hard drives or CD-ROM drives.

HDDs are specified by the hdd_img property.
CDs are specified by the cdr_img property.
Multiple images are delimited by a colon :

attach_scsi_devices is called by the scsi controller after the scsi controller has attached itself to the scsi bus.
The bus suffix is applied to the property name.
Curio has no suffix so it will use hdd_img and cdr_img properties.
Mesh is expected to have a suffix of 2 so it will use hdd_img2 and cdr_img2 properties.

HDDs will skip SCSI ID 3 unless 7 HDDs are added, in which case, the seventh HDD will use ID 3.
CDs will start at SCSI ID 3, go to 7, then down to 0.
SCSI IDs are skipped if a device is already using that SCSI ID.

ScsiCdrom and ScsiHD no longer use REGISTER_DEVICE or DeviceDescription or PropMap which is normal for devices that can have multiple instances.
This commit is contained in:
joevt 2023-10-30 17:05:20 -07:00 committed by dingusdev
parent cfca42e577
commit 45a9d45e3f
13 changed files with 85 additions and 84 deletions

View File

@ -263,12 +263,17 @@ void MeshController::update_irq()
}
}
static const PropMap Mesh_properties = {
{"hdd_img2", new StrProperty("")},
{"cdr_img2", new StrProperty("")},
};
static const DeviceDescription Mesh_Tnt_Descriptor = {
MeshController::create_for_tnt, {}, {}
MeshController::create_for_tnt, {}, Mesh_properties
};
static const DeviceDescription Mesh_Heathrow_Descriptor = {
MeshController::create_for_heathrow, {}, {}
MeshController::create_for_heathrow, {}, Mesh_properties
};
REGISTER_DEVICE(MeshTnt, Mesh_Tnt_Descriptor);

View File

@ -44,7 +44,10 @@ Sc53C94::Sc53C94(uint8_t chip_id, uint8_t my_id) : ScsiDevice("SC53C94", my_id)
int Sc53C94::device_postinit()
{
this->bus_obj = dynamic_cast<ScsiBus*>(gMachineObj->get_comp_by_name("ScsiCurio"));
this->bus_obj->register_device(7, static_cast<ScsiDevice*>(this));
if (this->bus_obj) {
this->bus_obj->register_device(7, static_cast<ScsiDevice*>(this));
this->bus_obj->attach_scsi_devices("");
}
this->int_ctrl = dynamic_cast<InterruptCtrl*>(
gMachineObj->get_comp_by_type(HWCompType::INT_CTRL));
@ -682,8 +685,13 @@ void Sc53C94::real_dma_xfer_in()
}
}
static const PropMap Sc53C94_properties = {
{"hdd_img", new StrProperty("")},
{"cdr_img", new StrProperty("")},
};
static const DeviceDescription Sc53C94_Descriptor = {
Sc53C94::create, {}, {}
Sc53C94::create, {}, Sc53C94_properties
};
REGISTER_DEVICE(Sc53C94, Sc53C94_Descriptor);

View File

@ -239,6 +239,8 @@ public:
return std::unique_ptr<ScsiBus>(new ScsiBus("ScsiCurio"));
}
void attach_scsi_devices(const std::string bus_suffix);
// low-level state management
void register_device(int id, ScsiDevice* dev_obj);
int current_phase() { return this->cur_phase; };

View File

@ -23,10 +23,14 @@ along with this program. If not, see <https://www.gnu.org/licenses/>.
#include <devices/common/hwcomponent.h>
#include <devices/common/scsi/scsi.h>
#include <devices/common/scsi/scsihd.h>
#include <devices/common/scsi/scsicdrom.h>
#include <devices/deviceregistry.h>
#include <machines/machinebase.h>
#include <loguru.hpp>
#include <cinttypes>
#include <sstream>
ScsiBus::ScsiBus(const std::string name)
{
@ -292,6 +296,53 @@ void ScsiBus::disconnect(int dev_id)
}
}
void ScsiBus::attach_scsi_devices(const std::string bus_suffix)
{
std::string path;
int scsi_id;
std::string image_path;
image_path = GET_STR_PROP("hdd_img" + bus_suffix);
if (!image_path.empty()) {
std::istringstream image_stream(image_path);
while (std::getline(image_stream, path, ':')) {
// do two passes because we skip ID 3.
for (scsi_id = 0; scsi_id < SCSI_MAX_DEVS * 2 && (scsi_id == 3 || this->devices[scsi_id % SCSI_MAX_DEVS]); scsi_id++) {}
if (scsi_id < SCSI_MAX_DEVS * 2) {
scsi_id = scsi_id % SCSI_MAX_DEVS;
std::string scsi_device_name = "ScsiHD" + bus_suffix + "," + std::to_string(scsi_id);
ScsiHardDisk *scsi_device = new ScsiHardDisk(scsi_device_name, scsi_id);
gMachineObj->add_device(scsi_device_name, std::unique_ptr<ScsiHardDisk>(scsi_device));
this->register_device(scsi_id, scsi_device);
scsi_device->insert_image(path);
}
else {
LOG_F(ERROR, "%s: Too many devices. HDD \"%s\" was not added.", this->get_name().c_str(), path.c_str());
}
}
}
image_path = GET_STR_PROP("cdr_img" + bus_suffix);
if (!image_path.empty()) {
std::istringstream image_stream(image_path);
while (std::getline(image_stream, path, ':')) {
// do two passes because we start at ID 3.
for (scsi_id = 3; scsi_id < SCSI_MAX_DEVS * 2 && this->devices[scsi_id % SCSI_MAX_DEVS]; scsi_id++) {}
if (scsi_id < SCSI_MAX_DEVS * 2) {
scsi_id = scsi_id % SCSI_MAX_DEVS;
std::string scsi_device_name = "ScsiCdrom" + bus_suffix + "," + std::to_string(scsi_id);
ScsiCdrom *scsi_device = new ScsiCdrom(scsi_device_name, scsi_id);
gMachineObj->add_device(scsi_device_name, std::unique_ptr<ScsiCdrom>(scsi_device));
this->register_device(scsi_id, scsi_device);
scsi_device->insert_image(path);
}
else {
LOG_F(ERROR, "%s: Too many devices. CD-ROM \"%s\" was not added.", this->get_name().c_str(), path.c_str());
}
}
}
}
static const DeviceDescription ScsiCurio_Descriptor = {
ScsiBus::create_ScsiCurio, {}, {}
};

View File

@ -1,6 +1,6 @@
/*
DingusPPC - The Experimental PowerPC Macintosh emulator
Copyright (C) 2018-23 divingkatae and maximum
Copyright (C) 2018-24 divingkatae and maximum
(theweirdo) spatium
(Contact divingkatae#1017 or powermax#2286 on Discord for more info)
@ -395,12 +395,3 @@ void ScsiCdrom::read_capacity_10()
this->switch_phase(ScsiPhase::DATA_IN);
}
static const PropMap ScsiCdromProperties = {
{"cdr_img", new StrProperty("")},
};
static const DeviceDescription ScsiCdromDescriptor =
{ScsiCdrom::create, {}, ScsiCdromProperties};
REGISTER_DEVICE(ScsiCdrom, ScsiCdromDescriptor);

View File

@ -37,10 +37,6 @@ public:
ScsiCdrom(std::string name, int my_id);
~ScsiCdrom() = default;
static std::unique_ptr<HWComponent> create() {
return std::unique_ptr<ScsiCdrom>(new ScsiCdrom("SCSI-CDROM", 3));
}
virtual void process_command() override;
virtual bool prepare_data() override;
virtual bool get_more_data() override;

View File

@ -1,6 +1,6 @@
/*
DingusPPC - The Experimental PowerPC Macintosh emulator
Copyright (C) 2018-23 divingkatae and maximum
Copyright (C) 2018-24 divingkatae and maximum
(theweirdo) spatium
(Contact divingkatae#1017 or powermax#2286 on Discord for more info)
@ -406,13 +406,3 @@ void ScsiHardDisk::read_buffer() {
this->switch_phase(ScsiPhase::DATA_IN);
}
static const PropMap SCSI_HD_Properties = {
{"hdd_img", new StrProperty("")},
{"hdd_wr_prot", new BinProperty(0)},
};
static const DeviceDescription SCSI_HD_Descriptor =
{ScsiHardDisk::create, {}, SCSI_HD_Properties};
REGISTER_DEVICE(ScsiHD, SCSI_HD_Descriptor);

View File

@ -1,6 +1,6 @@
/*
DingusPPC - The Experimental PowerPC Macintosh emulator
Copyright (C) 2018-23 divingkatae and maximum
Copyright (C) 2018-24 divingkatae and maximum
(theweirdo) spatium
(Contact divingkatae#1017 or powermax#2286 on Discord for more info)
@ -36,10 +36,6 @@ public:
ScsiHardDisk(std::string name, int my_id);
~ScsiHardDisk() = default;
static std::unique_ptr<HWComponent> create() {
return std::unique_ptr<ScsiHardDisk>(new ScsiHardDisk("SCSI_HD", 0));
}
void insert_image(std::string filename);
void process_command();
bool prepare_data();

View File

@ -25,6 +25,8 @@ along with this program. If not, see <https://www.gnu.org/licenses/>.
#include <devices/common/machineid.h>
#include <devices/common/pci/pcidevice.h>
#include <devices/common/pci/pcihost.h>
#include <devices/common/scsi/scsicdrom.h>
#include <devices/common/scsi/scsihd.h>
#include <devices/memctrl/platinum.h>
#include <loguru.hpp>
#include <machines/machinebase.h>

View File

@ -1,6 +1,6 @@
/*
DingusPPC - The Experimental PowerPC Macintosh emulator
Copyright (C) 2018-23 divingkatae and maximum
Copyright (C) 2018-24 divingkatae and maximum
(theweirdo) spatium
(Contact divingkatae#1017 or powermax#2286 on Discord for more info)
@ -79,10 +79,11 @@ static const map<string, string> PropHelp = {
{"fdd_img", "specifies path to floppy disk image"},
{"fdd_fmt", "specifies floppy disk format"},
{"fdd_wr_prot", "toggles floppy disk's write protection"},
{"hdd_img", "specifies path to hard disk image"},
{"hdd_wr_prot", "toggles hard disk's write protection"},
{"hdd_img", "specifies path(s) to hard disk image(s)"},
{"hdd_img2", "specifies path(s) to secondary hard disk image(s)"},
{"cdr_config", "CD-ROM device path in [bus]:[device#] format"},
{"cdr_img", "specifies path to CD-ROM image"},
{"cdr_img", "specifies path(s) to CD-ROM image(s)"},
{"cdr_img2", "specifies path(s) to secondary CD-ROM image(s)"},
{"mon_id", "specifies which monitor to emulate"},
{"pci_PERCH", "insert a PCI device into PERCH slot"},
{"pci_A1", "insert a PCI device into A1 slot"},

View File

@ -1,6 +1,6 @@
/*
DingusPPC - The Experimental PowerPC Macintosh emulator
Copyright (C) 2018-22 divingkatae and maximum
Copyright (C) 2018-24 divingkatae and maximum
(theweirdo) spatium
(Contact divingkatae#1017 or powermax#2286 on Discord for more info)
@ -30,6 +30,7 @@ along with this program. If not, see <https://www.gnu.org/licenses/>.
#include <devices/common/i2c/athens.h>
#include <devices/common/i2c/i2cprom.h>
#include <devices/common/machineid.h>
#include <devices/common/scsi/scsihd.h>
#include <devices/memctrl/mpc106.h>
#include <devices/memctrl/spdram.h>
#include <loguru.hpp>

View File

@ -37,7 +37,6 @@ along with this program. If not, see <https://www.gnu.org/licenses/>.
#include <machines/machinefactory.h>
#include <machines/machineproperties.h>
#include <sstream>
#include <string>
#include <vector>
@ -85,48 +84,6 @@ int initialize_pdm(std::string& id)
return -1;
}
// get internal SCSI bus object
auto scsi_bus = dynamic_cast<ScsiBus*>(gMachineObj->get_comp_by_name("ScsiCurio"));
std::string hd_image_path = GET_STR_PROP("hdd_img");
if (!hd_image_path.empty()) {
std::istringstream hd_image_stream(hd_image_path);
std::string path;
int scsi_id = 0;
while (std::getline(hd_image_stream, path, ':')) {
// Avoid overlapping with the CD-ROM drive at ID 3.
if (scsi_id >= 3) {
LOG_F(WARNING, "Ignoring SCSI ID %d: only IDs 0-2 are supported", scsi_id);
continue;
}
ScsiHardDisk *scsi_hd;
if (scsi_id == 0) {
// There's always a built-in SCSI hard disk at ID #0
scsi_hd = dynamic_cast<ScsiHardDisk*>(gMachineObj->get_comp_by_name("ScsiHD"));
} else {
// Register additional SCSI hard disks as needed
std::string scsi_hd_name = "ScsiHD" + std::to_string(scsi_id);
scsi_hd = new ScsiHardDisk(scsi_hd_name, scsi_id);
gMachineObj->add_device(scsi_hd_name, std::unique_ptr<ScsiHardDisk>(scsi_hd));
}
scsi_bus->register_device(scsi_id, scsi_hd);
scsi_hd->insert_image(path);
scsi_id++;
}
}
std::string cdr_image_path = GET_STR_PROP("cdr_img");
if (!cdr_image_path.empty()) {
// attach SCSI CD-ROM to the main bus, ID #3
auto my_cdr = dynamic_cast<ScsiCdrom*>(gMachineObj->get_comp_by_name("ScsiCdrom"));
scsi_bus->register_device(3, my_cdr);
// insert specified disk image
my_cdr->insert_image(cdr_image_path);
}
// Init virtual CPU and request MPC601
ppc_cpu_init(hmc_obj, PPC_VER::MPC601, 7812500ULL);
@ -153,7 +110,7 @@ static const PropMap pm6100_settings = {
};
static vector<string> pm6100_devices = {
"HMC", "Amic", "ScsiHD", "ScsiCdrom"
"HMC", "Amic"
};
static const MachineDescription pm6100_descriptor = {

View File

@ -25,6 +25,7 @@ along with this program. If not, see <https://www.gnu.org/licenses/>.
#include <devices/common/machineid.h>
#include <devices/common/pci/pcihost.h>
#include <devices/common/pci/pcidevice.h>
#include <devices/common/scsi/scsihd.h>
#include <devices/ioctrl/macio.h>
#include <devices/memctrl/hammerhead.h>
#include <loguru.hpp>
@ -114,7 +115,7 @@ static const PropMap pm7500_settings = {
};
static vector<string> pm7500_devices = {
"Hammerhead", "Bandit1", "Chaos", "MeshTnt", "GrandCentral", "ControlVideo"
"Hammerhead", "Bandit1", "Chaos", "ScsiMesh", "MeshTnt", "GrandCentral", "ControlVideo"
};
static const MachineDescription pm7300_descriptor = {