From 6ffe28a8a4aae1577c64e2be6eacc42b080b8e00 Mon Sep 17 00:00:00 2001 From: Maxim Poliakovski Date: Mon, 31 Oct 2022 23:20:39 +0100 Subject: [PATCH] Implement SCSI Pseudo-DMA register on PDM. --- devices/common/scsi/sc53c94.cpp | 30 ++++++++++++++++++++++++++++++ devices/common/scsi/sc53c94.h | 5 +++-- devices/ioctrl/amic.cpp | 6 +++++- 3 files changed, 38 insertions(+), 3 deletions(-) diff --git a/devices/common/scsi/sc53c94.cpp b/devices/common/scsi/sc53c94.cpp index 753c837..1073727 100644 --- a/devices/common/scsi/sc53c94.cpp +++ b/devices/common/scsi/sc53c94.cpp @@ -152,6 +152,36 @@ void Sc53C94::write(uint8_t reg_offset, uint8_t value) } } +uint16_t Sc53C94::pseudo_dma_read() +{ + uint16_t data_word; + bool is_done = false; + + if (this->data_fifo_pos >= 2) { + // remove one word from FIFO + data_word = (this->data_fifo[0] << 8) | this->data_fifo[1]; + this->data_fifo_pos -= 2; + std:memmove(this->data_fifo, &this->data_fifo[2], this->data_fifo_pos); + + // update DMA status + if ((this->cmd_fifo[0] & 0x80)) { + this->xfer_count -= 2; + if (!this->xfer_count) { + is_done = true; + this->cur_state = SeqState::XFER_END; + this->sequencer(); + } + } + } + + // see if we need to refill FIFO + if (!this->data_fifo_pos && !is_done) { + this->sequencer(); + } + + return data_word; +} + void Sc53C94::update_command_reg(uint8_t cmd) { if (this->on_reset && (cmd & 0x7F) != CMD_NOP) { diff --git a/devices/common/scsi/sc53c94.h b/devices/common/scsi/sc53c94.h index 332b643..095de73 100644 --- a/devices/common/scsi/sc53c94.h +++ b/devices/common/scsi/sc53c94.h @@ -144,8 +144,9 @@ public: int device_postinit(); // 53C94 registers access - uint8_t read(uint8_t reg_offset); - void write(uint8_t reg_offset, uint8_t value); + uint8_t read(uint8_t reg_offset); + void write(uint8_t reg_offset, uint8_t value); + uint16_t pseudo_dma_read(); // ScsiDevice methods void notify(ScsiBus* bus_obj, ScsiMsg msg_type, int param); diff --git a/devices/ioctrl/amic.cpp b/devices/ioctrl/amic.cpp index e2d234c..7a9b7e9 100644 --- a/devices/ioctrl/amic.cpp +++ b/devices/ioctrl/amic.cpp @@ -115,7 +115,11 @@ uint32_t AMIC::read(uint32_t rgn_start, uint32_t offset, int size) case 0xA: // MACE registers return this->mace->read((offset >> 4) & 0x1F); case 0x10: // SCSI registers - return this->scsi->read((offset >> 4) & 0xF); + if (offset & 0x100) { + return this->scsi->pseudo_dma_read(); + } else { + return this->scsi->read((offset >> 4) & 0xF); + } case 0x14: // Sound registers switch (offset) { case AMICReg::Snd_Stat_0: