summaryrefslogtreecommitdiffstatshomepage
path: root/src/devices/machine/mediagx_cs5530_ide.cpp
diff options
context:
space:
mode:
Diffstat (limited to 'src/devices/machine/mediagx_cs5530_ide.cpp')
-rw-r--r--src/devices/machine/mediagx_cs5530_ide.cpp142
1 files changed, 142 insertions, 0 deletions
diff --git a/src/devices/machine/mediagx_cs5530_ide.cpp b/src/devices/machine/mediagx_cs5530_ide.cpp
new file mode 100644
index 00000000000..a48b35821db
--- /dev/null
+++ b/src/devices/machine/mediagx_cs5530_ide.cpp
@@ -0,0 +1,142 @@
+// license: BSD-3-Clause
+// copyright-holders: Angelo Salese
+/**************************************************************************************************
+
+[Cyrix/National Semiconductor/AMD] [MediaGX/Geode] [Cx/CS]5530 IDE implementation
+
+TODO:
+- Derive from common pci-ide.cpp interface
+
+**************************************************************************************************/
+
+#include "emu.h"
+#include "mediagx_cs5530_ide.h"
+
+#define VERBOSE (LOG_GENERAL)
+//#define LOG_OUTPUT_FUNC osd_printf_warning
+
+#include "logmacro.h"
+
+DEFINE_DEVICE_TYPE(MEDIAGX_CS5530_IDE, mediagx_cs5530_ide_device, "mediagx_cs5530_ide", "MediaGX CS5530 IDE Controller")
+
+mediagx_cs5530_ide_device::mediagx_cs5530_ide_device(const machine_config &mconfig, const char *tag, device_t *owner, uint32_t clock)
+ : pci_device(mconfig, MEDIAGX_CS5530_IDE, tag, owner, clock)
+ , m_ide1(*this, "ide1")
+ , m_ide2(*this, "ide2")
+ , m_irq_pri_callback(*this)
+ , m_irq_sec_callback(*this)
+ , m_bus_master_space(*this, finder_base::DUMMY_TAG, AS_PROGRAM)
+{
+}
+
+void mediagx_cs5530_ide_device::device_add_mconfig(machine_config &config)
+{
+ BUS_MASTER_IDE_CONTROLLER(config, m_ide1).options(ata_devices, "hdd", nullptr, false);
+ m_ide1->irq_handler().set([this](int state) { m_irq_pri_callback(state); });
+ m_ide1->set_bus_master_space(m_bus_master_space);
+
+ BUS_MASTER_IDE_CONTROLLER(config, m_ide2).options(ata_devices, "cdrom", nullptr, false);
+ m_ide2->irq_handler().set([this](int state) { m_irq_sec_callback(state); });
+ m_ide2->set_bus_master_space(m_bus_master_space);
+}
+
+void mediagx_cs5530_ide_device::config_map(address_map &map)
+{
+ pci_device::config_map(map);
+// index 0x24-0xff reserved
+}
+
+//
+void mediagx_cs5530_ide_device::primary_ide_map(address_map &map)
+{
+ map(0x01f0, 0x01f7).rw(FUNC(mediagx_cs5530_ide_device::ide1_read32_cs0_r), FUNC(mediagx_cs5530_ide_device::ide1_write32_cs0_w));
+ map(0x03f6, 0x03f6).rw(FUNC(mediagx_cs5530_ide_device::ide1_read_cs1_r), FUNC(mediagx_cs5530_ide_device::ide1_write_cs1_w));
+}
+
+void mediagx_cs5530_ide_device::secondary_ide_map(address_map &map)
+{
+ map(0x0170, 0x0177).rw(FUNC(mediagx_cs5530_ide_device::ide2_read32_cs0_r), FUNC(mediagx_cs5530_ide_device::ide2_write32_cs0_w));
+ map(0x0376, 0x0376).rw(FUNC(mediagx_cs5530_ide_device::ide2_read_cs1_r), FUNC(mediagx_cs5530_ide_device::ide2_write_cs1_w));
+}
+
+uint32_t mediagx_cs5530_ide_device::ide1_read32_cs0_r(offs_t offset, uint32_t mem_mask)
+{
+ if (!(command & 1))
+ return 0xffffffff;
+ return m_ide1->read_cs0(offset, mem_mask);
+}
+
+void mediagx_cs5530_ide_device::ide1_write32_cs0_w(offs_t offset, uint32_t data, uint32_t mem_mask)
+{
+ if (!(command & 1))
+ return;
+ m_ide1->write_cs0(offset, data, mem_mask);
+}
+
+uint32_t mediagx_cs5530_ide_device::ide2_read32_cs0_r(offs_t offset, uint32_t mem_mask)
+{
+ if (!(command & 1))
+ return 0xffffffff;
+ return m_ide2->read_cs0(offset, mem_mask);
+}
+
+void mediagx_cs5530_ide_device::ide2_write32_cs0_w(offs_t offset, uint32_t data, uint32_t mem_mask)
+{
+ if (!(command & 1))
+ return;
+ m_ide2->write_cs0(offset, data, mem_mask);
+}
+
+uint8_t mediagx_cs5530_ide_device::ide1_read_cs1_r()
+{
+ if (!(command & 1))
+ return 0xff;
+ return m_ide1->read_cs1(1, 0xff0000) >> 16;
+}
+
+void mediagx_cs5530_ide_device::ide1_write_cs1_w(uint8_t data)
+{
+ if (!(command & 1))
+ return;
+ m_ide1->write_cs1(1, data << 16, 0xff0000);
+}
+
+uint8_t mediagx_cs5530_ide_device::ide2_read_cs1_r()
+{
+ if (!(command & 1))
+ return 0xff;
+ return m_ide2->read_cs1(1, 0xff0000) >> 16;
+}
+
+void mediagx_cs5530_ide_device::ide2_write_cs1_w(uint8_t data)
+{
+ if (!(command & 1))
+ return;
+ m_ide2->write_cs1(1, data << 16, 0xff0000);
+}
+
+
+// F2BAR
+void mediagx_cs5530_ide_device::io_map(address_map &map)
+{
+ map(0x00, 0x07).rw(m_ide1, FUNC(bus_master_ide_controller_device::bmdma_r), FUNC(bus_master_ide_controller_device::bmdma_w));
+ map(0x08, 0x0f).rw(m_ide2, FUNC(bus_master_ide_controller_device::bmdma_r), FUNC(bus_master_ide_controller_device::bmdma_w));
+// map(0x20, 0x23).select(0x18) Channel # (bit 5) Drive # (bit 3) PIO
+// map(0x24, 0x27).select(0x18) Channel # (bit 5) Drive # (bit 3) DMA Control
+}
+
+void mediagx_cs5530_ide_device::device_start()
+{
+ pci_device::device_start();
+
+ skip_map_regs(4);
+ add_map(128, M_IO, FUNC(mediagx_cs5530_ide_device::io_map));
+}
+
+void mediagx_cs5530_ide_device::device_reset()
+{
+ pci_device::device_reset();
+
+ command = 0x0000;
+ status = 0x0280;
+}