Store SCSI bus object pointer during registration.

This commit is contained in:
Maxim Poliakovski 2023-11-01 16:07:29 +01:00
parent 9ae863d7c4
commit 94872b3ebb
5 changed files with 24 additions and 19 deletions

View File

@ -539,7 +539,7 @@ void Sc53C94::update_irq()
}
}
void Sc53C94::notify(ScsiBus* bus_obj, ScsiMsg msg_type, int param)
void Sc53C94::notify(ScsiMsg msg_type, int param)
{
switch (msg_type) {
case ScsiMsg::CONFIRM_SEL:

View File

@ -170,7 +170,7 @@ public:
};
// ScsiDevice methods
void notify(ScsiBus* bus_obj, ScsiMsg msg_type, int param);
void notify(ScsiMsg msg_type, int param);
bool prepare_data() { return false; };
bool has_data() { return this->data_fifo_pos != 0; };
int send_data(uint8_t* dst_ptr, int count);

View File

@ -170,8 +170,8 @@ public:
};
~ScsiDevice() = default;
virtual void notify(ScsiBus* bus_obj, ScsiMsg msg_type, int param);
virtual void next_step(ScsiBus* bus_obj);
virtual void notify(ScsiMsg msg_type, int param);
virtual void next_step();
virtual void prepare_xfer(ScsiBus* bus_obj, int& bytes_in, int& bytes_out);
virtual void switch_phase(const int new_phase);
@ -182,6 +182,10 @@ public:
virtual bool prepare_data() = 0;
virtual void process_command() = 0;
void set_bus_object_ptr(ScsiBus *bus_obj_ptr) {
this->bus_obj = bus_obj_ptr;
}
protected:
uint8_t cmd_buf[16] = {};
uint8_t msg_buf[16] = {}; // TODO: clarify how big this one should be

View File

@ -52,6 +52,8 @@ void ScsiBus::register_device(int id, ScsiDevice* dev_obj)
}
this->devices[id] = dev_obj;
dev_obj->set_bus_object_ptr(this);
}
void ScsiBus::change_bus_phase(int initiator_id)
@ -60,7 +62,7 @@ void ScsiBus::change_bus_phase(int initiator_id)
if (i == initiator_id)
continue; // don't notify the initiator
if (this->devices[i] != nullptr) {
this->devices[i]->notify(this, ScsiMsg::BUS_PHASE_CHANGE, this->cur_phase);
this->devices[i]->notify(ScsiMsg::BUS_PHASE_CHANGE, this->cur_phase);
}
}
}
@ -225,7 +227,7 @@ void ScsiBus::confirm_selection(int target_id)
// notify initiator about selection confirmation from target
if (this->initiator_id >= 0) {
this->devices[this->initiator_id]->notify(this, ScsiMsg::CONFIRM_SEL, target_id);
this->devices[this->initiator_id]->notify(ScsiMsg::CONFIRM_SEL, target_id);
}
}
@ -261,7 +263,7 @@ bool ScsiBus::push_data(const int id, const uint8_t* src_ptr, const int size)
void ScsiBus::target_next_step()
{
this->devices[this->target_id]->next_step(this);
this->devices[this->target_id]->next_step();
}
bool ScsiBus::negotiate_xfer(int& bytes_in, int& bytes_out)

View File

@ -1,6 +1,6 @@
/*
DingusPPC - The Experimental PowerPC Macintosh emulator
Copyright (C) 2018-22 divingkatae and maximum
Copyright (C) 2018-23 divingkatae and maximum
(theweirdo) spatium
(Contact divingkatae#1017 or powermax#2286 on Discord for more info)
@ -26,7 +26,7 @@ along with this program. If not, see <https://www.gnu.org/licenses/>.
#include <cinttypes>
#include <cstring>
void ScsiDevice::notify(ScsiBus* bus_obj, ScsiMsg msg_type, int param)
void ScsiDevice::notify(ScsiMsg msg_type, int param)
{
if (msg_type == ScsiMsg::BUS_PHASE_CHANGE) {
switch (param) {
@ -35,19 +35,18 @@ void ScsiDevice::notify(ScsiBus* bus_obj, ScsiMsg msg_type, int param)
break;
case ScsiPhase::SELECTION:
// check if something tries to select us
if (bus_obj->get_data_lines() & (1 << scsi_id)) {
if (this->bus_obj->get_data_lines() & (1 << scsi_id)) {
LOG_F(9, "ScsiDevice %d selected", this->scsi_id);
TimerManager::get_instance()->add_oneshot_timer(
BUS_SETTLE_DELAY,
[this, bus_obj]() {
[this]() {
// don't confirm selection if BSY or I/O are asserted
if (bus_obj->test_ctrl_lines(SCSI_CTRL_BSY | SCSI_CTRL_IO))
if (this->bus_obj->test_ctrl_lines(SCSI_CTRL_BSY | SCSI_CTRL_IO))
return;
bus_obj->assert_ctrl_line(this->scsi_id, SCSI_CTRL_BSY);
bus_obj->confirm_selection(this->scsi_id);
this->initiator_id = bus_obj->get_initiator_id();
this->bus_obj = bus_obj;
if (bus_obj->test_ctrl_lines(SCSI_CTRL_ATN)) {
this->bus_obj->assert_ctrl_line(this->scsi_id, SCSI_CTRL_BSY);
this->bus_obj->confirm_selection(this->scsi_id);
this->initiator_id = this->bus_obj->get_initiator_id();
if (this->bus_obj->test_ctrl_lines(SCSI_CTRL_ATN)) {
this->switch_phase(ScsiPhase::MESSAGE_OUT);
if (this->msg_buf[0] != 0x80) {
LOG_F(INFO, "ScsiDevice: received message 0x%X", this->msg_buf[0]);
@ -73,7 +72,7 @@ void ScsiDevice::switch_phase(const int new_phase)
this->bus_obj->switch_phase(this->scsi_id, this->cur_phase);
}
void ScsiDevice::next_step(ScsiBus* bus_obj)
void ScsiDevice::next_step()
{
switch (this->cur_phase) {
case ScsiPhase::COMMAND:
@ -98,7 +97,7 @@ void ScsiDevice::next_step(ScsiBus* bus_obj)
break;
case ScsiPhase::MESSAGE_IN:
case ScsiPhase::BUS_FREE:
bus_obj->release_ctrl_lines(this->scsi_id);
this->bus_obj->release_ctrl_lines(this->scsi_id);
this->switch_phase(ScsiPhase::BUS_FREE);
break;
default: