sc53c94: Split real_dma_xfer.

Create real_dma_xfer_out and real_dma_xfer_in methods.
This commit is contained in:
joevt 2024-03-10 21:10:40 -07:00 committed by dingusdev
parent bc5153dd4a
commit e1e00c951b
3 changed files with 37 additions and 30 deletions

View File

@ -632,20 +632,38 @@ bool Sc53C94::rcv_data()
return true; return true;
} }
void Sc53C94::real_dma_xfer(int direction) void Sc53C94::real_dma_xfer_out()
{
// transfer data from host's memory to target
while (this->xfer_count) {
uint32_t got_bytes;
uint8_t* src_ptr;
this->dma_ch->pull_data(std::min((int)this->xfer_count, DATA_FIFO_MAX),
&got_bytes, &src_ptr);
std::memcpy(this->data_fifo, src_ptr, got_bytes);
this->data_fifo_pos = got_bytes;
this->bus_obj->push_data(this->target_id, this->data_fifo, this->data_fifo_pos);
this->xfer_count -= this->data_fifo_pos;
this->data_fifo_pos = 0;
if (!this->xfer_count) {
this->status |= STAT_TC; // signal zero transfer count
this->cur_state = SeqState::XFER_END;
this->sequencer();
}
}
}
void Sc53C94::real_dma_xfer_in()
{ {
bool is_done = false; bool is_done = false;
if (direction) { // transfer data from target to host's memory
uint32_t got_bytes;
uint8_t* src_ptr;
while (this->xfer_count) { while (this->xfer_count) {
this->dma_ch->pull_data(std::min((int)this->xfer_count, DATA_FIFO_MAX), if (this->data_fifo_pos) {
&got_bytes, &src_ptr); this->dma_ch->push_data((char*)this->data_fifo, this->data_fifo_pos);
std::memcpy(this->data_fifo, src_ptr, got_bytes);
this->data_fifo_pos = got_bytes;
this->bus_obj->push_data(this->target_id, this->data_fifo, this->data_fifo_pos);
this->xfer_count -= this->data_fifo_pos; this->xfer_count -= this->data_fifo_pos;
this->data_fifo_pos = 0; this->data_fifo_pos = 0;
@ -656,25 +674,10 @@ void Sc53C94::real_dma_xfer(int direction)
this->sequencer(); this->sequencer();
} }
} }
} else { // transfer data from target to host's memory
while (this->xfer_count) {
if (this->data_fifo_pos) {
this->dma_ch->push_data((char*)this->data_fifo, this->data_fifo_pos);
this->xfer_count -= this->data_fifo_pos; // see if we need to refill FIFO
this->data_fifo_pos = 0; if (!this->data_fifo_pos && !is_done) {
if (!this->xfer_count) { this->sequencer();
is_done = true;
this->status |= STAT_TC; // signal zero transfer count
this->cur_state = SeqState::XFER_END;
this->sequencer();
}
}
// see if we need to refill FIFO
if (!this->data_fifo_pos && !is_done) {
this->sequencer();
}
} }
} }
} }

View File

@ -207,7 +207,8 @@ public:
void pseudo_dma_write(uint16_t data); void pseudo_dma_write(uint16_t data);
// real DMA control // real DMA control
void real_dma_xfer(int direction); void real_dma_xfer_out();
void real_dma_xfer_in();
void set_dma_channel(DmaBidirChannel *dma_ch) { void set_dma_channel(DmaBidirChannel *dma_ch) {
this->dma_ch = dma_ch; this->dma_ch = dma_ch;

View File

@ -384,7 +384,10 @@ void AMIC::write(uint32_t rgn_start, uint32_t offset, uint32_t value, int size)
} }
if (value & 2) { // RUN bit set? if (value & 2) { // RUN bit set?
this->curio_dma->reinit(this->scsi_dma_base); this->curio_dma->reinit(this->scsi_dma_base);
this->scsi->real_dma_xfer((value >> 6) & 1); if (value & (1 << 6))
this->scsi->real_dma_xfer_out();
else
this->scsi->real_dma_xfer_in();
} }
this->curio_dma->write_ctrl(value); this->curio_dma->write_ctrl(value);
break; break;