mirror of
https://github.com/dingusdev/dingusppc.git
synced 2025-01-06 16:31:45 +00:00
sc53c94: switch to the new DMA API.
This commit is contained in:
parent
5057792d4d
commit
85d5b10f61
@ -33,7 +33,7 @@ along with this program. If not, see <https://www.gnu.org/licenses/>.
|
||||
#include <cinttypes>
|
||||
#include <cstring>
|
||||
|
||||
Sc53C94::Sc53C94(uint8_t chip_id, uint8_t my_id) : ScsiDevice("SC53C94", my_id)
|
||||
Sc53C94::Sc53C94(uint8_t chip_id, uint8_t my_id) : ScsiDevice("SC53C94", my_id), DmaDevice()
|
||||
{
|
||||
this->chip_id = chip_id;
|
||||
this->my_bus_id = my_id;
|
||||
@ -751,6 +751,73 @@ void Sc53C94::dma_stop()
|
||||
}
|
||||
}
|
||||
|
||||
int Sc53C94::xfer_from(uint8_t *buf, int len) {
|
||||
if (len > this->xfer_count + this->data_fifo_pos)
|
||||
LOG_F(WARNING, "%s: DMA xfer len > command xfer len", this->name.c_str());
|
||||
|
||||
if (this->data_fifo_pos) {
|
||||
int fifo_bytes = std::min(this->data_fifo_pos, len);
|
||||
std::memcpy(buf, this->data_fifo, fifo_bytes);
|
||||
this->data_fifo_pos -= fifo_bytes;
|
||||
this->xfer_count -= fifo_bytes;
|
||||
len -= fifo_bytes;
|
||||
buf += fifo_bytes;
|
||||
if (!this->xfer_count) {
|
||||
this->status |= STAT_TC; // signal zero transfer count
|
||||
this->cur_state = SeqState::XFER_END;
|
||||
this->sequencer();
|
||||
return 0;
|
||||
}
|
||||
}
|
||||
|
||||
if (this->bus_obj->pull_data(this->target_id, buf, this->xfer_count)) {
|
||||
this->xfer_count = 0;
|
||||
this->status |= STAT_TC; // signal zero transfer count
|
||||
this->cur_state = SeqState::XFER_END;
|
||||
this->sequencer();
|
||||
return 0;
|
||||
}
|
||||
|
||||
return len;
|
||||
}
|
||||
|
||||
int Sc53C94::xfer_to(uint8_t *buf, int len) {
|
||||
if (!this->xfer_count)
|
||||
return len;
|
||||
|
||||
// Being in the DATA_OUT phase means that we're about to move
|
||||
// a big chunk of data. The real device uses its FIFO as buffer.
|
||||
// For simplicity, the code below transfers the whole chunk at once.
|
||||
// This can be broken into smaller chunks later if desired.
|
||||
if (this->cur_bus_phase == ScsiPhase::DATA_OUT) {
|
||||
if (this->bus_obj->push_data(this->target_id, buf, len)) {
|
||||
this->xfer_count -= len;
|
||||
if (!this->xfer_count) {
|
||||
this->status |= STAT_TC; // signal zero transfer count
|
||||
this->cur_state = SeqState::XFER_END;
|
||||
this->sequencer();
|
||||
}
|
||||
len = 0;
|
||||
} else
|
||||
LOG_F(WARNING, "%s: xfer_to failed to transfer data", this->name.c_str());
|
||||
}
|
||||
|
||||
if (this->xfer_count) {
|
||||
// fill in the data FIFO first
|
||||
uint32_t fifo_bytes = std::min(len, DATA_FIFO_MAX - this->data_fifo_pos);
|
||||
std::memcpy(&this->data_fifo[this->data_fifo_pos], buf, fifo_bytes);
|
||||
len -= fifo_bytes;
|
||||
this->data_fifo_pos += fifo_bytes;
|
||||
this->xfer_count -= fifo_bytes;
|
||||
if (!this->xfer_count) {
|
||||
this->status |= STAT_TC; // signal zero transfer count
|
||||
this->sequencer();
|
||||
}
|
||||
}
|
||||
|
||||
return len;
|
||||
}
|
||||
|
||||
static const PropMap Sc53C94_properties = {
|
||||
{"hdd_img", new StrProperty("")},
|
||||
{"cdr_img", new StrProperty("")},
|
||||
|
@ -187,7 +187,7 @@ typedef struct {
|
||||
|
||||
typedef std::function<void(const uint8_t drq_state)> DrqCb;
|
||||
|
||||
class Sc53C94 : public ScsiDevice {
|
||||
class Sc53C94 : public ScsiDevice, public DmaDevice {
|
||||
public:
|
||||
Sc53C94(uint8_t chip_id=12, uint8_t my_id=7);
|
||||
~Sc53C94() = default;
|
||||
@ -235,6 +235,10 @@ public:
|
||||
int send_data(uint8_t* dst_ptr, int count);
|
||||
void process_command() {};
|
||||
|
||||
// DmaChannel methods
|
||||
int xfer_from(uint8_t *buf, int len); // Must be marked override!
|
||||
int xfer_to(uint8_t *buf, int len); // Must be marked override!
|
||||
|
||||
protected:
|
||||
void reset_device();
|
||||
void update_command_reg(uint8_t cmd);
|
||||
|
@ -125,7 +125,9 @@ GrandCentral::GrandCentral() : PCIDevice("mac-io_grandcentral"), InterruptCtrl()
|
||||
this->curio = dynamic_cast<Sc53C94*>(gMachineObj->get_comp_by_name("Sc53C94"));
|
||||
this->curio_dma = std::unique_ptr<DMAChannel> (new DMAChannel("curio_scsi"));
|
||||
this->curio_dma->register_dma_int(this, this->register_dma_int(IntSrc::DMA_SCSI_CURIO));
|
||||
this->curio->set_dma_channel(this->curio_dma.get());
|
||||
this->curio_dma->connect(this->curio);
|
||||
this->curio->connect(this->curio_dma.get());
|
||||
//this->curio->set_dma_channel(this->curio_dma.get());
|
||||
this->curio->set_drq_callback([this](const uint8_t drq_state) {
|
||||
this->curio_dma->set_stat((drq_state & 1) << 5);
|
||||
});
|
||||
|
Loading…
Reference in New Issue
Block a user