pci/pdc20262: add base bus master interface

This commit is contained in:
angelosa 2024-03-01 23:37:29 +01:00
parent f5efc5fd3c
commit 308b6f0f30
2 changed files with 99 additions and 40 deletions

View File

@ -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);
}

View File

@ -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<bus_master_ide_controller_device> m_ide1;
// required_device<bus_master_ide_controller_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<bus_master_ide_controller_device> m_ide1;
required_device<bus_master_ide_controller_device> m_ide2;
required_device<input_merger_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);