diff options
Diffstat (limited to 'src/devices/bus/ata/ataintf.cpp')
-rw-r--r-- | src/devices/bus/ata/ataintf.cpp | 264 |
1 files changed, 264 insertions, 0 deletions
diff --git a/src/devices/bus/ata/ataintf.cpp b/src/devices/bus/ata/ataintf.cpp new file mode 100644 index 00000000000..bd6753ee237 --- /dev/null +++ b/src/devices/bus/ata/ataintf.cpp @@ -0,0 +1,264 @@ +// license:BSD-3-Clause +// copyright-holders:smf +/*************************************************************************** + + ataintf.c + + ATA Interface implementation. + +***************************************************************************/ + +#include "emu.h" +#include "ataintf.h" + +#include "debugger.h" + +ata_slot_device &abstract_ata_interface_device::slot(int index) +{ + assert(index < 2); + return *subdevice<ata_slot_device>(m_slot[index].finder_tag()); +} + +void abstract_ata_interface_device::set_irq(int state) +{ +// logerror( "%s: irq %d\n", machine().describe_context(), state ); + + m_irq_handler(state); +} + +void abstract_ata_interface_device::set_dmarq(int state) +{ +// logerror( "%s: dmarq %d\n", machine().describe_context(), state ); + + m_dmarq_handler(state); +} + +void abstract_ata_interface_device::set_dasp(int state) +{ +// logerror( "%s: dasp %d\n", machine().describe_context(), state ); + + m_dasp_handler(state); +} + +void abstract_ata_interface_device::irq0_write_line(int state) +{ + if (m_irq[0] != state) + { + m_irq[0] = state; + + set_irq(m_irq[0] == ASSERT_LINE || m_irq[1] == ASSERT_LINE); + } +} + +void abstract_ata_interface_device::irq1_write_line(int state) +{ + if (m_irq[1] != state) + { + m_irq[1] = state; + + set_irq(m_irq[0] == ASSERT_LINE || m_irq[1] == ASSERT_LINE); + } +} + +void abstract_ata_interface_device::dasp0_write_line(int state) +{ + if (m_dasp[0] != state) + { + m_dasp[0] = state; + + set_dasp(m_dasp[0] == ASSERT_LINE || m_dasp[1] == ASSERT_LINE); + } +} + +void abstract_ata_interface_device::dasp1_write_line(int state) +{ + if (m_dasp[1] != state) + { + m_dasp[1] = state; + + device_ata_interface *dev = m_slot[0]->dev(); + if (dev != nullptr) + dev->write_dasp(state); + + set_dasp(m_dasp[0] == ASSERT_LINE || m_dasp[1] == ASSERT_LINE); + } +} + +void abstract_ata_interface_device::dmarq0_write_line(int state) +{ + if (m_dmarq[0] != state) + { + m_dmarq[0] = state; + + set_dmarq(m_dmarq[0] == ASSERT_LINE || m_dmarq[1] == ASSERT_LINE); + } +} + +void abstract_ata_interface_device::dmarq1_write_line(int state) +{ + if (m_dmarq[1] != state) + { + m_dmarq[1] = state; + + set_dmarq(m_dmarq[0] == ASSERT_LINE || m_dmarq[1] == ASSERT_LINE); + } +} + +void abstract_ata_interface_device::pdiag0_write_line(int state) +{ + m_pdiag[0] = state; +} + +void abstract_ata_interface_device::pdiag1_write_line(int state) +{ + if (m_pdiag[1] != state) + { + m_pdiag[1] = state; + + device_ata_interface *dev = m_slot[0]->dev(); + if (dev != nullptr) + dev->write_pdiag(state); + } +} + +/************************************* + * + * ATA interface read + * + *************************************/ + +uint16_t abstract_ata_interface_device::read_dma() +{ + uint16_t result = 0xffff; + for (auto & elem : m_slot) + if (elem->dev() != nullptr) + result &= elem->dev()->read_dma(); + +// logerror( "%s: read_dma %04x\n", machine().describe_context(), result ); + return result; +} + +uint16_t abstract_ata_interface_device::internal_read_cs0(offs_t offset, uint16_t mem_mask) +{ + uint16_t result = mem_mask; + for (auto & elem : m_slot) + if (elem->dev() != nullptr) + result &= elem->dev()->read_cs0(offset, mem_mask); + +// { static int last_status = -1; if (offset == 7 ) { if( result == last_status ) return last_status; last_status = result; } else last_status = -1; } + +// logerror( "%s: read cs0 %04x %04x %04x\n", machine().describe_context(), offset, result, mem_mask ); + + return result; +} + +uint16_t abstract_ata_interface_device::internal_read_cs1(offs_t offset, uint16_t mem_mask) +{ + uint16_t result = mem_mask; + for (auto & elem : m_slot) + if (elem->dev() != nullptr) + result &= elem->dev()->read_cs1(offset, mem_mask); + +// logerror( "%s: read cs1 %04x %04x %04x\n", machine().describe_context(), offset, result, mem_mask ); + + return result; +} + +/************************************* + * + * ATA interface write + * + *************************************/ + +void abstract_ata_interface_device::write_dma( uint16_t data ) +{ +// logerror( "%s: write_dma %04x\n", machine().describe_context(), data ); + + for (auto & elem : m_slot) + if (elem->dev() != nullptr) + elem->dev()->write_dma(data); +} + +void abstract_ata_interface_device::internal_write_cs0(offs_t offset, uint16_t data, uint16_t mem_mask) +{ +// logerror( "%s: write cs0 %04x %04x %04x\n", machine().describe_context(), offset, data, mem_mask ); + + for (auto & elem : m_slot) + if (elem->dev() != nullptr) + elem->dev()->write_cs0(offset, data, mem_mask); +} + +void abstract_ata_interface_device::internal_write_cs1(offs_t offset, uint16_t data, uint16_t mem_mask) +{ +// logerror( "%s: write cs1 %04x %04x %04x\n", machine().describe_context(), offset, data, mem_mask ); + + for (auto & elem : m_slot) + if (elem->dev() != nullptr) + elem->dev()->write_cs1(offset, data, mem_mask); +} + +void abstract_ata_interface_device::write_dmack(int state) +{ +// logerror( "%s: write_dmack %04x\n", machine().describe_context(), state ); + + for (auto & elem : m_slot) + if (elem->dev() != nullptr) + elem->dev()->write_dmack(state); +} + +abstract_ata_interface_device::abstract_ata_interface_device(const machine_config &mconfig, device_type type, const char *tag, device_t *owner, uint32_t clock) : + device_t(mconfig, type, tag, owner, clock), + m_slot(*this, "%u", 0U), + m_irq_handler(*this), + m_dmarq_handler(*this), + m_dasp_handler(*this) +{ +} + + +DEFINE_DEVICE_TYPE(ATA_INTERFACE, ata_interface_device, "ata_interface", "ATA Interface") + +ata_interface_device::ata_interface_device(const machine_config &mconfig, const char *tag, device_t *owner, uint32_t clock) : + abstract_ata_interface_device(mconfig, ATA_INTERFACE, tag, owner, clock) +{ +} + + +//------------------------------------------------- +// device_start - device-specific startup +//------------------------------------------------- + +void abstract_ata_interface_device::device_start() +{ + for (int i = 0; i < 2; i++) + { + m_irq[i] = 0; + m_dmarq[i] = 0; + m_dasp[i] = 0; + m_pdiag[i] = 0; + + device_ata_interface *const dev = m_slot[i]->dev(); + if (dev) + dev->write_csel(i); + } +} + + +//------------------------------------------------- +// device_add_mconfig - add device configuration +//------------------------------------------------- + +void abstract_ata_interface_device::device_add_mconfig(machine_config &config) +{ + ATA_SLOT(config, m_slot[0]); + m_slot[0]->irq_handler().set(FUNC(abstract_ata_interface_device::irq0_write_line)); + m_slot[0]->dmarq_handler().set(FUNC(abstract_ata_interface_device::dmarq0_write_line)); + m_slot[0]->dasp_handler().set(FUNC(abstract_ata_interface_device::dasp0_write_line)); + m_slot[0]->pdiag_handler().set(FUNC(abstract_ata_interface_device::pdiag0_write_line)); + + ATA_SLOT(config, m_slot[1]); + m_slot[1]->irq_handler().set(FUNC(abstract_ata_interface_device::irq1_write_line)); + m_slot[1]->dmarq_handler().set(FUNC(abstract_ata_interface_device::dmarq1_write_line)); + m_slot[1]->dasp_handler().set(FUNC(abstract_ata_interface_device::dasp1_write_line)); + m_slot[1]->pdiag_handler().set(FUNC(abstract_ata_interface_device::pdiag1_write_line)); +} |