Sc53C94: implement cycle completion commands.

This commit is contained in:
Maxim Poliakovski 2022-11-02 22:28:43 +01:00
parent 5a33fba75e
commit 5a59b97257
2 changed files with 75 additions and 14 deletions

View File

@ -267,6 +267,9 @@ void Sc53C94::exec_command()
exec_next_command();
break;
case CMD_XFER:
static SeqDesc * xfer_desc = new SeqDesc[3]{
{SeqState::IDLE, 0, INTSTAT_SR}
};
if (!this->is_initiator) {
// clear command FIFO
this->cmd_fifo_pos = 0;
@ -274,10 +277,34 @@ void Sc53C94::exec_command()
this->update_irq();
} else {
this->seq_step = 0;
this->cmd_steps = xfer_desc;
this->cur_state = SeqState::XFER_BEGIN;
this->sequencer();
}
break;
case CMD_COMPLETE_STEPS:
static SeqDesc * complete_steps_desc = new SeqDesc[3]{
{SeqState::RCV_MESSAGE, 0, 0},
{SeqState::XFER_END, 0, 0},
{SeqState::IDLE, 0, INTSTAT_SR}
};
if (this->bus_obj->current_phase() != ScsiPhase::STATUS) {
ABORT_F("Sc53C94: complete steps only works in the STATUS phase");
}
this->seq_step = 0;
this->cmd_steps = complete_steps_desc;
this->cur_state = SeqState::RCV_STATUS;
this->sequencer();
break;
case CMD_MSG_ACCEPTED:
if (this->is_initiator) {
this->bus_obj->target_next_step();
}
this->bus_obj->release_ctrl_line(this->my_bus_id, SCSI_CTRL_ACK);
this->int_status |= INTSTAT_SR | INTSTAT_DIS;
this->update_irq();
exec_next_command();
break;
case CMD_SELECT_NO_ATN:
static SeqDesc * sel_no_atn_desc = new SeqDesc[3]{
{SeqState::SEL_BEGIN, 0, INTSTAT_DIS },
@ -291,7 +318,6 @@ void Sc53C94::exec_command()
LOG_F(INFO, "SC53C94: SELECT W/O ATN command started");
break;
case CMD_ENA_SEL_RESEL:
LOG_F(INFO, "SC53C94: ENABLE SELECTION/RESELECTION command executed");
exec_next_command();
break;
default:
@ -408,7 +434,7 @@ void Sc53C94::sequencer()
}
break;
case SeqState::CMD_BEGIN:
LOG_F(INFO, "CMD_BEGIN reached");
LOG_F(9, "CMD_BEGIN reached");
break;
case SeqState::CMD_COMPLETE:
this->cmd_steps++;
@ -433,9 +459,17 @@ void Sc53C94::sequencer()
}
break;
case SeqState::XFER_END:
this->int_status |= INTSTAT_SR;
if (this->is_initiator) {
this->bus_obj->target_next_step();
}
this->int_status |= this->cmd_steps->status;
this->update_irq();
exec_next_command();
if (this->cmd_steps->next_step > 0) {
this->cur_state = this->cmd_steps->next_step;
this->cmd_steps++;
} else {
exec_next_command();
}
break;
case SeqState::RCV_DATA:
// check for unexpected bus phase changes
@ -447,6 +481,21 @@ void Sc53C94::sequencer()
this->rcv_data();
}
break;
case SeqState::RCV_STATUS:
case SeqState::RCV_MESSAGE:
this->bus_obj->target_request_data();
this->rcv_data();
if (this->is_initiator) {
if (this->cur_state == SeqState::RCV_STATUS) {
this->bus_obj->target_next_step();
} else if (this->cur_state == SeqState::RCV_MESSAGE) {
this->bus_obj->assert_ctrl_line(this->my_bus_id, SCSI_CTRL_ACK);
}
}
this->cur_state = this->cmd_steps->next_step;
this->cmd_steps++;
this->sequencer();
break;
default:
ABORT_F("SC53C94: unimplemented sequencer state %d", this->cur_state);
}
@ -507,13 +556,21 @@ bool Sc53C94::send_bytes(uint8_t* dst_ptr, int count)
bool Sc53C94::rcv_data()
{
int req_count;
// 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;
if (this->cmd_fifo[0] & 0x80) {
req_count = std::min((int)this->xfer_count, DATA_FIFO_MAX);
} else {
req_count = 1;
}
this->bus_obj->target_pull_data(&this->data_fifo[this->data_fifo_pos], req_count);
this->data_fifo_pos += req_count;
return true;
}

View File

@ -80,14 +80,16 @@ namespace Write {
/** NCR53C94/Am53CF94 commands. */
enum {
CMD_NOP = 0,
CMD_CLEAR_FIFO = 1,
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,
CMD_NOP = 0,
CMD_CLEAR_FIFO = 1,
CMD_RESET_DEVICE = 2,
CMD_RESET_BUS = 3,
CMD_DMA_STOP = 4,
CMD_XFER = 0x10,
CMD_COMPLETE_STEPS = 0x11,
CMD_MSG_ACCEPTED = 0x12,
CMD_SELECT_NO_ATN = 0x41,
CMD_ENA_SEL_RESEL = 0x44,
};
/** Status register bits. **/
@ -127,6 +129,8 @@ namespace SeqState {
XFER_END,
SEND_DATA,
RCV_DATA,
RCV_STATUS,
RCV_MESSAGE,
};
};