mirror of
https://github.com/holub/mame
synced 2025-04-23 00:39:36 +03:00
pci/pdc20262: add base bus master interface
This commit is contained in:
parent
f5efc5fd3c
commit
308b6f0f30
@ -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);
|
||||
}
|
||||
|
@ -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);
|
||||
|
Loading…
Reference in New Issue
Block a user