mirror of
https://github.com/dingusdev/dingusppc.git
synced 2025-01-11 05:29:43 +00:00
Sc53C94: implement information transfer command.
This commit is contained in:
parent
fbfae98d6d
commit
7ab44886c4
@ -229,6 +229,18 @@ void Sc53C94::exec_command()
|
||||
}
|
||||
exec_next_command();
|
||||
break;
|
||||
case CMD_XFER:
|
||||
if (!this->is_initiator) {
|
||||
// clear command FIFO
|
||||
this->cmd_fifo_pos = 0;
|
||||
this->int_status |= INTSTAT_ICMD;
|
||||
this->update_irq();
|
||||
} else {
|
||||
this->seq_step = 0;
|
||||
this->cur_state = SeqState::XFER_BEGIN;
|
||||
this->sequencer();
|
||||
}
|
||||
break;
|
||||
case CMD_SELECT_NO_ATN:
|
||||
static SeqDesc * sel_no_atn_desc = new SeqDesc[3]{
|
||||
{SeqState::SEL_BEGIN, 0, INTSTAT_DIS },
|
||||
@ -351,6 +363,37 @@ void Sc53C94::sequencer()
|
||||
this->update_irq();
|
||||
exec_next_command();
|
||||
break;
|
||||
case SeqState::XFER_BEGIN:
|
||||
this->cur_bus_phase = this->bus_obj->current_phase();
|
||||
switch (this->cur_bus_phase) {
|
||||
case ScsiPhase::COMMAND:
|
||||
case ScsiPhase::DATA_OUT:
|
||||
case ScsiPhase::MESSAGE_OUT:
|
||||
LOG_F(WARNING, "Sc53C94: sending data not unimplemented");
|
||||
break;
|
||||
case ScsiPhase::STATUS:
|
||||
case ScsiPhase::DATA_IN:
|
||||
case ScsiPhase::MESSAGE_IN:
|
||||
this->cur_state = SeqState::RCV_DATA;
|
||||
this->bus_obj->target_request_data();
|
||||
this->rcv_data();
|
||||
}
|
||||
break;
|
||||
case SeqState::XFER_END:
|
||||
this->int_status |= INTSTAT_SR;
|
||||
this->update_irq();
|
||||
exec_next_command();
|
||||
break;
|
||||
case SeqState::RCV_DATA:
|
||||
// check for unexpected bus phase changes
|
||||
if (this->bus_obj->current_phase() != this->cur_bus_phase) {
|
||||
this->cmd_fifo_pos = 0; // clear command FIFO
|
||||
this->int_status |= INTSTAT_SR;
|
||||
this->update_irq();
|
||||
} else {
|
||||
this->rcv_data();
|
||||
}
|
||||
break;
|
||||
default:
|
||||
ABORT_F("SC53C94: unimplemented sequencer state %d", this->cur_state);
|
||||
}
|
||||
@ -404,11 +447,23 @@ bool Sc53C94::send_bytes(uint8_t* dst_ptr, int count)
|
||||
// remove the just readed data from the data FIFO
|
||||
this->data_fifo_pos -= count;
|
||||
if (this->data_fifo_pos > 0) {
|
||||
std::memcpy(this->data_fifo, &this->data_fifo[count], this->data_fifo_pos);
|
||||
std::memmove(this->data_fifo, &this->data_fifo[count], this->data_fifo_pos);
|
||||
}
|
||||
return true;
|
||||
}
|
||||
|
||||
bool Sc53C94::rcv_data()
|
||||
{
|
||||
// return if REQ line is negated
|
||||
if (!this->bus_obj->test_ctrl_lines(SCSI_CTRL_REQ)) {
|
||||
return false;
|
||||
}
|
||||
|
||||
this->bus_obj->target_pull_data(this->data_fifo, DATA_FIFO_MAX);
|
||||
this->data_fifo_pos = DATA_FIFO_MAX;
|
||||
return true;
|
||||
}
|
||||
|
||||
static const DeviceDescription Sc53C94_Descriptor = {
|
||||
Sc53C94::create, {}, {}
|
||||
};
|
||||
|
@ -85,6 +85,7 @@ enum {
|
||||
CMD_RESET_DEVICE = 2,
|
||||
CMD_RESET_BUS = 3,
|
||||
CMD_DMA_STOP = 4,
|
||||
CMD_XFER = 0x10,
|
||||
CMD_SELECT_NO_ATN = 0x41,
|
||||
CMD_ENA_SEL_RESEL = 0x44,
|
||||
};
|
||||
@ -116,6 +117,10 @@ namespace SeqState {
|
||||
SEL_END,
|
||||
CMD_BEGIN,
|
||||
CMD_COMPLETE,
|
||||
XFER_BEGIN,
|
||||
XFER_END,
|
||||
SEND_DATA,
|
||||
RCV_DATA,
|
||||
};
|
||||
};
|
||||
|
||||
@ -158,6 +163,8 @@ protected:
|
||||
void sequencer();
|
||||
void seq_defer_state(uint64_t delay_ns);
|
||||
|
||||
bool rcv_data();
|
||||
|
||||
void update_irq();
|
||||
|
||||
private:
|
||||
@ -191,6 +198,7 @@ private:
|
||||
SeqDesc* cmd_steps;
|
||||
bool is_initiator;
|
||||
uint8_t cur_cmd;
|
||||
int cur_bus_phase;
|
||||
|
||||
// interrupt related stuff
|
||||
InterruptCtrl* int_ctrl = nullptr;
|
||||
|
Loading…
x
Reference in New Issue
Block a user