From 308b6f0f307590c6cf497b3bfbea7b8032f50e44 Mon Sep 17 00:00:00 2001 From: angelosa Date: Fri, 1 Mar 2024 23:37:29 +0100 Subject: [PATCH] pci/pdc20262: add base bus master interface --- src/devices/bus/pci/pdc20262.cpp | 116 ++++++++++++++++++++++--------- src/devices/bus/pci/pdc20262.h | 23 +++--- 2 files changed, 99 insertions(+), 40 deletions(-) diff --git a/src/devices/bus/pci/pdc20262.cpp b/src/devices/bus/pci/pdc20262.cpp index 6249123411c..022f1f2fc9c 100644 --- a/src/devices/bus/pci/pdc20262.cpp +++ b/src/devices/bus/pci/pdc20262.cpp @@ -2,11 +2,18 @@ // copyright-holders: Angelo Salese /************************************************************************************************** -Promise PDC20262 +Promise PDC20262 FastTrak66/UDMA66 IDE controller + +No documentation, ATA4 complaint TODO: - how it sets compatible/native modes? Subvendor ID list suggests it can switch at will; -- Marketed as RAID card, verify thru drivers; +- Install win9x driver causes huge loading hiccups, eventually freezes by accessing drive with + explorer.exe (enable UDMA?). For common use is **suggested** to not install them. +- Reportedly has issues with very big HDDs, pinpoint limit and assuming there isn't an issue here. +\- Tested with Seagate Barracuda ST380021A -chs=158816,16,63 (expected: 80GB, actual: 13655MB) +- Marketed as RAID card, verify; +\- Gets classified as SCSI controller in win9x device manager; - ID and hookup Flash ROM type; - PME 1.0 support (no low power states D1/D2, no PME#) @@ -30,8 +37,11 @@ DEFINE_DEVICE_TYPE(PDC20262, pdc20262_device, "pdc20262", "Promise PDC20262 pdc20262_device::pdc20262_device(const machine_config &mconfig, device_type type, const char *tag, device_t *owner, uint32_t clock) : pci_card_device(mconfig, type, tag, owner, clock) -// , m_ide1(*this, "ide1") -// , m_ide2(*this, "ide2") + , m_ide1(*this, "ide1") + , m_ide2(*this, "ide2") + , m_irqs(*this, "irqs") + // HACK: how to get to get_pci_busmaster_space()? + , m_bus_master_space(*this, ":maincpu", 0) , m_bios_rom(*this, "bios_rom") { // Subsystems: @@ -68,13 +78,25 @@ const tiny_rom_entry *pdc20262_device::device_rom_region() const void pdc20262_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(get_pci_busmaster_space()); + INPUT_MERGER_ANY_HIGH(config, m_irqs).output_handler().set([this] (int state) { + irq_pin_w(0, state); + }); -// BUS_MASTER_IDE_CONTROLLER(config, m_ide2).options(ata_devices, nullptr, nullptr, false); -// m_ide2->irq_handler().set([this](int state) { m_irq_sec_callback(state); }); -// m_ide2->set_bus_master_space(get_pci_busmaster_space()); + BUS_MASTER_IDE_CONTROLLER(config, m_ide1).options(ata_devices, "hdd", nullptr, false); + m_ide1->irq_handler().set([this] (int state) { + m_irq_state &= ~0x4; + m_irq_state |= (state << 2); + m_irqs->in_w<0>(state); + }); + m_ide1->set_bus_master_space(m_bus_master_space); + + BUS_MASTER_IDE_CONTROLLER(config, m_ide2).options(ata_devices, nullptr, nullptr, false); + m_ide2->irq_handler().set([this] (int state) { + m_irq_state &= ~0x40; + m_irq_state |= (state << 6); + m_irqs->in_w<1>(state); + }); + m_ide2->set_bus_master_space(m_bus_master_space); } // $1f0 @@ -103,12 +125,43 @@ void pdc20262_device::ide2_control_map(address_map &map) void pdc20262_device::bus_master_ide_control_map(address_map &map) { -// map(0x0, 0x7).rw(m_ide1, FUNC(bus_master_ide_controller_device::bmdma_r), FUNC(bus_master_ide_controller_device::bmdma_w)); -// map(0x8, 0xf).rw(m_ide2, FUNC(bus_master_ide_controller_device::bmdma_r), FUNC(bus_master_ide_controller_device::bmdma_w)); + 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(0x11, 0x11).lrw8( + NAME([this] () { + return m_clock; + }), + NAME([this] (u8 data) { + LOG("extra $11: Clock set %02x\n", data); + m_clock = data; + }) + ); + +// map(0x1a, 0x1a) Primary Mode +// map(0x1b, 0x1b) Secondary Mode +/* + * upper nibble secondary, lower primary + * + * x--- error + * -x-- irq + * --x- FIFO full + * ---x FIFO empty + */ + map(0x1d, 0x1d).lr8( + NAME([this] () { + // FIXME: definitely requires a FIFO i/f + return m_irq_state | 1; + }) + ); +// map(0x1f, 0x1f) Ultra DMA speed flag } -void pdc20262_device::raid_map(address_map &map) +void pdc20262_device::extra_map(address_map &map) { + // TODO: should be memory mapped versions of above, *nix driver seems to use this +// map(0x00, 0x07).m(*this, FUNC(pdc20262_device::ide1_command_map))); +// ... } void pdc20262_device::device_start() @@ -119,9 +172,9 @@ void pdc20262_device::device_start() add_map(4, M_IO, FUNC(pdc20262_device::ide1_control_map)); add_map(8, M_IO, FUNC(pdc20262_device::ide2_command_map)); add_map(4, M_IO, FUNC(pdc20262_device::ide2_control_map)); - add_map(16, M_IO, FUNC(pdc20262_device::bus_master_ide_control_map)); + add_map(32, M_IO, FUNC(pdc20262_device::bus_master_ide_control_map)); // TODO: unknown size (a lot larger?), to be verified later thru PnP - add_map(2048, M_MEM, FUNC(pdc20262_device::raid_map)); + add_map(64, M_MEM, FUNC(pdc20262_device::extra_map)); add_rom((u8 *)m_bios_rom->base(), 0x4000); expansion_rom_base = 0xc8000; @@ -146,6 +199,7 @@ void pdc20262_device::config_map(address_map &map) pci_card_device::config_map(map); // latency timer map(0x0d, 0x0d).lr8(NAME([] () { return 0x01; })); + // TODO: everything, starting from capptr_r override } /* @@ -154,56 +208,56 @@ void pdc20262_device::config_map(address_map &map) uint32_t pdc20262_device::ide1_read32_cs0_r(offs_t offset, uint32_t mem_mask) { - //if (!(command & 1)) + if (!(command & 1)) return 0xffffffff; - //return m_ide1->read_cs0(offset, mem_mask); + return m_ide1->read_cs0(offset, mem_mask); } void pdc20262_device::ide1_write32_cs0_w(offs_t offset, uint32_t data, uint32_t mem_mask) { - //if (!(command & 1)) + if (!(command & 1)) return; - //m_ide1->write_cs0(offset, data, mem_mask); + m_ide1->write_cs0(offset, data, mem_mask); } uint32_t pdc20262_device::ide2_read32_cs0_r(offs_t offset, uint32_t mem_mask) { - //if (!(command & 1)) + if (!(command & 1)) return 0xffffffff; - //return m_ide2->read_cs0(offset, mem_mask); + return m_ide2->read_cs0(offset, mem_mask); } void pdc20262_device::ide2_write32_cs0_w(offs_t offset, uint32_t data, uint32_t mem_mask) { - //if (!(command & 1)) + if (!(command & 1)) return; - //m_ide2->write_cs0(offset, data, mem_mask); + m_ide2->write_cs0(offset, data, mem_mask); } uint8_t pdc20262_device::ide1_read_cs1_r() { - //if (!(command & 1)) + if (!(command & 1)) return 0xff; - //return m_ide1->read_cs1(1, 0xff0000) >> 16; + return m_ide1->read_cs1(1, 0xff0000) >> 16; } void pdc20262_device::ide1_write_cs1_w(uint8_t data) { - //if (!(command & 1)) + if (!(command & 1)) return; - //m_ide1->write_cs1(1, data << 16, 0xff0000); + m_ide1->write_cs1(1, data << 16, 0xff0000); } uint8_t pdc20262_device::ide2_read_cs1_r() { - //if (!(command & 1)) + if (!(command & 1)) return 0xff; - //return m_ide2->read_cs1(1, 0xff0000) >> 16; + return m_ide2->read_cs1(1, 0xff0000) >> 16; } void pdc20262_device::ide2_write_cs1_w(uint8_t data) { - //if (!(command & 1)) + if (!(command & 1)) return; - //m_ide2->write_cs1(1, data << 16, 0xff0000); + m_ide2->write_cs1(1, data << 16, 0xff0000); } diff --git a/src/devices/bus/pci/pdc20262.h b/src/devices/bus/pci/pdc20262.h index af35514cfa6..f448894eb03 100644 --- a/src/devices/bus/pci/pdc20262.h +++ b/src/devices/bus/pci/pdc20262.h @@ -8,13 +8,14 @@ #include "pci_slot.h" #include "machine/idectrl.h" +#include "machine/input_merger.h" class pdc20262_device : public pci_card_device { public: pdc20262_device(const machine_config &mconfig, const char *tag, device_t *owner, uint32_t clock); - static constexpr feature_type unemulated_features() { return feature::MEDIA; } + static constexpr feature_type imperfect_features() { return feature::DISK; } protected: pdc20262_device(const machine_config &mconfig, device_type type, const char *tag, device_t *owner, uint32_t clock); @@ -25,8 +26,8 @@ protected: virtual const tiny_rom_entry *device_rom_region() const override; -// virtual void map_extra(uint64_t memory_window_start, uint64_t memory_window_end, uint64_t memory_offset, address_space *memory_space, -// uint64_t io_window_start, uint64_t io_window_end, uint64_t io_offset, address_space *io_space) override; +// virtual void map_extra(uint64_t memory_window_start, uint64_t memory_window_end, uint64_t memory_offset, address_space *memory_space, +// uint64_t io_window_start, uint64_t io_window_end, uint64_t io_offset, address_space *io_space) override; virtual void config_map(address_map &map) override; @@ -36,15 +37,19 @@ private: void ide2_command_map(address_map &map); void ide2_control_map(address_map &map); void bus_master_ide_control_map(address_map &map); - void raid_map(address_map &map); + void extra_map(address_map &map); -// required_device m_ide1; -// required_device m_ide2; -// devcb_write_line m_irq_pri_callback; -// devcb_write_line m_irq_sec_callback; -// required_address_space m_bus_master_space; +// virtual void device_config_complete() override; + + required_device m_ide1; + required_device m_ide2; + required_device m_irqs; + required_address_space m_bus_master_space; required_memory_region m_bios_rom; + u8 m_clock = 0; + u8 m_irq_state = 0; + uint32_t ide1_read32_cs0_r(offs_t offset, uint32_t mem_mask = ~0); void ide1_write32_cs0_w(offs_t offset, uint32_t data, uint32_t mem_mask = ~0); uint32_t ide2_read32_cs0_r(offs_t offset, uint32_t mem_mask = ~0);