mirror of
https://github.com/dingusdev/dingusppc.git
synced 2025-01-11 05:29:43 +00:00
amic: implement SCSI DMA.
This commit is contained in:
parent
a00b87790b
commit
c87fc10376
@ -53,6 +53,8 @@ AMIC::AMIC() : MMIODevice()
|
||||
|
||||
// connect internal SCSI controller
|
||||
this->scsi = dynamic_cast<Sc53C94*>(gMachineObj->get_comp_by_name("Sc53C94"));
|
||||
this->scsi_dma = std::unique_ptr<AmicScsiDma> (new AmicScsiDma());
|
||||
this->scsi->set_dma_channel(this->scsi_dma.get());
|
||||
|
||||
// connect serial HW
|
||||
this->escc = dynamic_cast<EsccController*>(gMachineObj->get_comp_by_name("Escc"));
|
||||
@ -170,7 +172,7 @@ uint32_t AMIC::read(uint32_t rgn_start, uint32_t offset, int size)
|
||||
case AMICReg::DMA_Base_Addr_3:
|
||||
return (this->dma_base >> (3 - (offset & 3)) * 8) & 0xFF;
|
||||
case AMICReg::SCSI_DMA_Ctrl:
|
||||
return this->scsi_dma_cs;
|
||||
return this->scsi_dma->read_stat();
|
||||
case AMICReg::Floppy_Addr_Ptr_0:
|
||||
case AMICReg::Floppy_Addr_Ptr_1:
|
||||
case AMICReg::Floppy_Addr_Ptr_2:
|
||||
@ -324,9 +326,24 @@ void AMIC::write(uint32_t rgn_start, uint32_t offset, uint32_t value, int size)
|
||||
case AMICReg::Enet_DMA_Xmt_Ctrl:
|
||||
LOG_F(INFO, "AMIC Ethernet Transmit DMA Ctrl updated, val=%x", value);
|
||||
break;
|
||||
case AMICReg::SCSI_DMA_Base_0:
|
||||
case AMICReg::SCSI_DMA_Base_1:
|
||||
case AMICReg::SCSI_DMA_Base_2:
|
||||
case AMICReg::SCSI_DMA_Base_3:
|
||||
SET_ADDR_BYTE(this->scsi_dma_base, offset, value);
|
||||
this->scsi_dma_base &= 0xFFFFFFF8UL;
|
||||
LOG_F(9, "AMIC: SCSI DMA base address set to 0x%X", this->scsi_dma_base);
|
||||
break;
|
||||
case AMICReg::SCSI_DMA_Ctrl:
|
||||
LOG_F(INFO, "AMIC SCSI DMA Ctrl updated, val=%x", value);
|
||||
this->scsi_dma_cs = value;
|
||||
if (value & 1) { // RST bit set?
|
||||
this->scsi_addr_ptr = this->scsi_dma_base;
|
||||
this->scsi_dma->reset(this->scsi_addr_ptr);
|
||||
}
|
||||
if (value & 2) { // RUN bit set?
|
||||
this->scsi_dma->reinit(this->scsi_dma_base);
|
||||
this->scsi->real_dma_xfer((value >> 6) & 1);
|
||||
}
|
||||
this->scsi_dma->write_ctrl(value);
|
||||
break;
|
||||
case AMICReg::Enet_DMA_Rcv_Ctrl:
|
||||
LOG_F(INFO, "AMIC Ethernet Receive DMA Ctrl updated, val=%x", value);
|
||||
@ -554,6 +571,50 @@ DmaPullResult AmicFloppyDma::pull_data(uint32_t req_len, uint32_t *avail_len,
|
||||
return DmaPullResult::NoMoreData;
|
||||
}
|
||||
|
||||
// ============================ SCSI DMA stuff ================================
|
||||
void AmicScsiDma::reset(const uint32_t addr_ptr)
|
||||
{
|
||||
this->stat &= 0x48; // clear interrupt flag, RUN and RST bits
|
||||
this->addr_ptr = addr_ptr;
|
||||
this->byte_count = 0;
|
||||
}
|
||||
|
||||
void AmicScsiDma::reinit(const uint32_t addr_ptr)
|
||||
{
|
||||
this->addr_ptr = addr_ptr;
|
||||
this->byte_count = 0;
|
||||
}
|
||||
|
||||
void AmicScsiDma::write_ctrl(uint8_t value)
|
||||
{
|
||||
// copy over DIR, IE and RUN bits
|
||||
this->stat = (this->stat & 0x81) | (value & 0x4A);
|
||||
|
||||
// clear interrupt flag if requested
|
||||
if (value & 0x80) {
|
||||
this->stat &= 0x7F;
|
||||
}
|
||||
}
|
||||
|
||||
int AmicScsiDma::push_data(const char* src_ptr, int len)
|
||||
{
|
||||
uint8_t *p_data = mmu_get_dma_mem(this->addr_ptr, len);
|
||||
std::memcpy(p_data, src_ptr, len);
|
||||
|
||||
this->addr_ptr += len;
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
DmaPullResult AmicScsiDma::pull_data(uint32_t req_len, uint32_t *avail_len,
|
||||
uint8_t **p_data)
|
||||
{
|
||||
*p_data = mmu_get_dma_mem(this->addr_ptr, req_len);
|
||||
this->addr_ptr += req_len;
|
||||
*avail_len = req_len;
|
||||
return DmaPullResult::MoreData;
|
||||
}
|
||||
|
||||
static vector<string> Amic_Subdevices = {
|
||||
"Sc53C94", "Escc", "Mace", "ViaCuda", "Swim3"
|
||||
};
|
||||
|
@ -102,6 +102,27 @@ private:
|
||||
uint8_t stat;
|
||||
};
|
||||
|
||||
/** AMIC-specific SCSI DMA implementation. */
|
||||
class AmicScsiDma : public DmaBidirChannel {
|
||||
public:
|
||||
AmicScsiDma() = default;
|
||||
~AmicScsiDma() = default;
|
||||
|
||||
void reinit(const uint32_t addr_ptr);
|
||||
void reset(const uint32_t addr_ptr);
|
||||
void write_ctrl(const uint8_t value);
|
||||
uint8_t read_stat() { return this->stat; };
|
||||
|
||||
int push_data(const char* src_ptr, int len);
|
||||
DmaPullResult pull_data(uint32_t req_len, uint32_t *avail_len,
|
||||
uint8_t **p_data);
|
||||
|
||||
private:
|
||||
uint32_t addr_ptr;
|
||||
uint16_t byte_count;
|
||||
uint8_t stat;
|
||||
};
|
||||
|
||||
// macro for byte wise updating of AMIC DMA address registers
|
||||
#define SET_ADDR_BYTE(reg, offset, value) \
|
||||
mask = 0xFF000000UL >> (8 * ((offset) & 3)); \
|
||||
@ -164,9 +185,15 @@ enum AMICReg : uint32_t {
|
||||
DMA_Base_Addr_2 = 0x31002,
|
||||
DMA_Base_Addr_3 = 0x31003,
|
||||
Enet_DMA_Xmt_Ctrl = 0x31C20,
|
||||
SCSI_DMA_Ctrl = 0x32008,
|
||||
Enet_DMA_Rcv_Ctrl = 0x32028,
|
||||
|
||||
// SCSI DMA registers
|
||||
SCSI_DMA_Base_0 = 0x32000,
|
||||
SCSI_DMA_Base_1 = 0x32001,
|
||||
SCSI_DMA_Base_2 = 0x32002,
|
||||
SCSI_DMA_Base_3 = 0x32003,
|
||||
SCSI_DMA_Ctrl = 0x32008,
|
||||
|
||||
// Floppy (SWIM3) DMA registers
|
||||
Floppy_Addr_Ptr_0 = 0x32060,
|
||||
Floppy_Addr_Ptr_1 = 0x32061,
|
||||
@ -214,15 +241,19 @@ private:
|
||||
|
||||
uint8_t emmo_pin; // EMMO aka factory tester pin status, active low
|
||||
|
||||
uint32_t dma_base = 0; // DMA physical base address
|
||||
uint16_t snd_buf_size = 0; // sound buffer size in bytes
|
||||
uint8_t snd_out_ctrl = 0;
|
||||
uint32_t dma_base = 0; // DMA physical base address
|
||||
uint32_t scsi_dma_base = 0; // physical base address for SCSI DMA
|
||||
uint16_t snd_buf_size = 0; // sound buffer size in bytes
|
||||
uint8_t snd_out_ctrl = 0;
|
||||
|
||||
// floppy DMA state
|
||||
uint32_t floppy_addr_ptr;
|
||||
uint16_t floppy_byte_cnt;
|
||||
|
||||
uint8_t scsi_dma_cs = 0; // SCSI DMA control/status register value
|
||||
// SCSI DMA state
|
||||
uint32_t scsi_addr_ptr;
|
||||
|
||||
//uint8_t scsi_dma_cs = 0; // SCSI DMA control/status register value
|
||||
|
||||
// interrupt state
|
||||
uint8_t int_ctrl = 0;
|
||||
@ -245,6 +276,7 @@ private:
|
||||
std::unique_ptr<AwacDevicePdm> awacs;
|
||||
std::unique_ptr<AmicSndOutDma> snd_out_dma;
|
||||
std::unique_ptr<AmicFloppyDma> floppy_dma;
|
||||
std::unique_ptr<AmicScsiDma> scsi_dma;
|
||||
|
||||
// on-board video
|
||||
std::unique_ptr<DisplayID> disp_id;
|
||||
|
Loading…
x
Reference in New Issue
Block a user