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) { switch (msg_type) {
case ScsiMsg::CONFIRM_SEL: case ScsiMsg::CONFIRM_SEL:

View File

@ -170,7 +170,7 @@ public:
}; };
// ScsiDevice methods // 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 prepare_data() { return false; };
bool has_data() { return this->data_fifo_pos != 0; }; bool has_data() { return this->data_fifo_pos != 0; };
int send_data(uint8_t* dst_ptr, int count); int send_data(uint8_t* dst_ptr, int count);

View File

@ -170,8 +170,8 @@ public:
}; };
~ScsiDevice() = default; ~ScsiDevice() = default;
virtual void notify(ScsiBus* bus_obj, ScsiMsg msg_type, int param); virtual void notify(ScsiMsg msg_type, int param);
virtual void next_step(ScsiBus* bus_obj); virtual void next_step();
virtual void prepare_xfer(ScsiBus* bus_obj, int& bytes_in, int& bytes_out); virtual void prepare_xfer(ScsiBus* bus_obj, int& bytes_in, int& bytes_out);
virtual void switch_phase(const int new_phase); virtual void switch_phase(const int new_phase);
@ -182,6 +182,10 @@ public:
virtual bool prepare_data() = 0; virtual bool prepare_data() = 0;
virtual void process_command() = 0; virtual void process_command() = 0;
void set_bus_object_ptr(ScsiBus *bus_obj_ptr) {
this->bus_obj = bus_obj_ptr;
}
protected: protected:
uint8_t cmd_buf[16] = {}; uint8_t cmd_buf[16] = {};
uint8_t msg_buf[16] = {}; // TODO: clarify how big this one should be 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; this->devices[id] = dev_obj;
dev_obj->set_bus_object_ptr(this);
} }
void ScsiBus::change_bus_phase(int initiator_id) void ScsiBus::change_bus_phase(int initiator_id)
@ -60,7 +62,7 @@ void ScsiBus::change_bus_phase(int initiator_id)
if (i == initiator_id) if (i == initiator_id)
continue; // don't notify the initiator continue; // don't notify the initiator
if (this->devices[i] != nullptr) { 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 // notify initiator about selection confirmation from target
if (this->initiator_id >= 0) { 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() 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) bool ScsiBus::negotiate_xfer(int& bytes_in, int& bytes_out)

View File

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