diff --git a/src/devices/machine/pci-ide.cpp b/src/devices/machine/pci-ide.cpp index 398831e6cae..0c29338bcfe 100644 --- a/src/devices/machine/pci-ide.cpp +++ b/src/devices/machine/pci-ide.cpp @@ -14,8 +14,11 @@ ide_pci_device::ide_pci_device(const machine_config &mconfig, const char *tag, d } DEVICE_ADDRESS_MAP_START(config_map, 32, ide_pci_device) + AM_RANGE(0x08, 0x0b) AM_WRITE8(prog_if_w, 0x0000ff00) AM_RANGE(0x10, 0x1f) AM_WRITE(address_base_w) AM_RANGE(0x40, 0x5f) AM_READWRITE(pcictrl_r, pcictrl_w) + AM_RANGE(0x70, 0x77) AM_DEVREADWRITE("ide", bus_master_ide_controller_device, bmdma_r, bmdma_w) // PCI646 + AM_RANGE(0x78, 0x7f) AM_DEVREADWRITE("ide2", bus_master_ide_controller_device, bmdma_r, bmdma_w) // PCI646 AM_INHERIT_FROM(pci_device::config_map) ADDRESS_MAP_END @@ -80,7 +83,17 @@ void ide_pci_device::device_start() add_map(16, M_IO, FUNC(ide_pci_device::bus_master_map)); bank_infos[4].adr = 0xf00; + // Setup stored BARs + pci_bar[0] = 0x1f0; + pci_bar[1] = 0x3f4; + pci_bar[2] = 0x170; + pci_bar[3] = 0x374; + pci_bar[4] = 0xf00; + m_irq_handler.resolve_safe(); + + intr_pin = 0x1; + intr_line = 0xe; } void ide_pci_device::device_reset() @@ -94,8 +107,8 @@ void ide_pci_device::device_reset() READ32_MEMBER(ide_pci_device::ide_read_cs1) { // PCI offset starts at 0x3f4, idectrl expects 0x3f0 - uint32_t data = 0; - data = m_ide->read_cs1(space, ++offset, mem_mask); + uint32_t data; + data = m_ide->read_cs1(space, 1, mem_mask); if (0) logerror("%s:ide_read_cs1 offset=%08X data=%08X mask=%08X\n", machine().describe_context(), offset, data, mem_mask); return data; @@ -104,21 +117,21 @@ READ32_MEMBER(ide_pci_device::ide_read_cs1) WRITE32_MEMBER(ide_pci_device::ide_write_cs1) { // PCI offset starts at 0x3f4, idectrl expects 0x3f0 - m_ide->write_cs1(space, ++offset, data, mem_mask); + m_ide->write_cs1(space, 1, data, mem_mask); } READ32_MEMBER(ide_pci_device::ide2_read_cs1) { // PCI offset starts at 0x374, idectrl expects 0x370 - uint32_t data = 0; - data = m_ide2->read_cs1(space, ++offset, mem_mask); + uint32_t data; + data = m_ide2->read_cs1(space, 1, mem_mask); return data; } WRITE32_MEMBER(ide_pci_device::ide2_write_cs1) { // PCI offset starts at 0x374, idectrl expects 0x370 - m_ide2->write_cs1(space, ++offset, data, mem_mask); + m_ide2->write_cs1(space, 1, data, mem_mask); } WRITE_LINE_MEMBER(ide_pci_device::ide_interrupt) @@ -141,6 +154,42 @@ WRITE_LINE_MEMBER(ide_pci_device::ide_interrupt) logerror("%s:ide_interrupt %i set to %i\n", machine().describe_context(), m_irq_num, state); } +WRITE8_MEMBER(ide_pci_device::prog_if_w) +{ + uint32_t oldVal = pclass; + pclass = (pclass & ~(0xff)) | (data & 0xff); + // Check for switch to/from compatibility (legacy) mode from/to pci mode + if ((oldVal ^ pclass) & 0x5) { + // Map Primary IDE Channel + if (pclass & 0x1) { + // PCI Mode + // Enabling BAR 4 in legacy mode + bank_infos[4].flags &= ~M_DISABLED; + pci_device::address_base_w(space, 0, pci_bar[0]); + pci_device::address_base_w(space, 1, pci_bar[1]); + } else { + // Legacy Mode + // Disabling BAR 4 in legacy mode + bank_infos[4].flags |= M_DISABLED; + pci_device::address_base_w(space, 0, 0x1f0); + pci_device::address_base_w(space, 1, 0x3f4); + } + // Map Primary IDE Channel + if (pclass & 0x4) { + // PCI Mode + pci_device::address_base_w(space, 2, pci_bar[2]); + pci_device::address_base_w(space, 3, pci_bar[3]); + } + else { + // Legacy Mode + pci_device::address_base_w(space, 2, 0x170); + pci_device::address_base_w(space, 3, 0x374); + } + } + if (1) + logerror("%s:prog_if_w pclass = %06X\n", machine().describe_context(), pclass); +} + READ32_MEMBER(ide_pci_device::pcictrl_r) { return m_config_data[offset]; @@ -150,7 +199,7 @@ WRITE32_MEMBER(ide_pci_device::pcictrl_w) { COMBINE_DATA(&m_config_data[offset]); // PCI646U2 Offset 0x50 is interrupt status - if (main_id == 0x10950646 && offset == 0x10 / 4 && (data & 0x4)) { + if (main_id == 0x10950646 && offset == (0x10 / 4) && (data & 0x4)) { m_config_data[0x10 / 4] &= ~0x4; if (0) logerror("%s:ide_pci_device::pcictrl_w Clearing interrupt status\n", machine().describe_context()); @@ -161,24 +210,24 @@ WRITE32_MEMBER(ide_pci_device::address_base_w) { // data==0xffffffff is used to identify required memory space if (data != 0xffffffff) { - // Bits 0 (ide) and 2 (ide2) control if the mapping is legacy or BAR + // Save local copy of BAR + pci_bar[offset] = data; + // Bits 0 (primary) and 2 (secondary) control if the mapping is legacy or BAR switch (offset) { - case 0: - if ((pclass & 0x1) == 0) - data = (data & 0xfffff000) | 0x1f0; + case 0: case 1: + if ((pclass & 0x1) == 1) + pci_device::address_base_w(space, offset, data); break; - case 1: - if ((pclass & 0x1) == 0) - data = (data & 0xfffff000) | 0x3f4; - break; - case 2: - if ((pclass & 0x4) == 0) - data = (data & 0xfffff000) | 0x170; + case 2: case 3: + if ((pclass & 0x4) == 1) + pci_device::address_base_w(space, offset, data); break; default: - if ((pclass & 0x4) == 0) - data = (data & 0xfffff000) | 0x374; + pci_device::address_base_w(space, offset, data); + // Not sure what to do for the bus master ide BAR in legacy mode + // prog_if_w will disable register in legacy mode + if ((pclass & 0x5) == 0) + logerror("Mapping bar[%i] in legacy mode\n", offset); } } - pci_device::address_base_w(space, offset, data); } diff --git a/src/devices/machine/pci-ide.h b/src/devices/machine/pci-ide.h index 2d37ebef990..ed51a487d2f 100644 --- a/src/devices/machine/pci-ide.h +++ b/src/devices/machine/pci-ide.h @@ -53,6 +53,7 @@ private: cpu_device *m_cpu; int m_irq_num; devcb_write_line m_irq_handler; + uint32_t pci_bar[6]; uint32_t m_config_data[0x10]; DECLARE_ADDRESS_MAP(chan1_data_command_map, 32); @@ -60,6 +61,7 @@ private: DECLARE_ADDRESS_MAP(chan2_data_command_map, 32); DECLARE_ADDRESS_MAP(chan2_control_map, 32); DECLARE_ADDRESS_MAP(bus_master_map, 32); + DECLARE_WRITE8_MEMBER(prog_if_w); DECLARE_READ32_MEMBER(pcictrl_r); DECLARE_WRITE32_MEMBER(pcictrl_w); DECLARE_WRITE32_MEMBER(address_base_w); diff --git a/src/devices/machine/pci.cpp b/src/devices/machine/pci.cpp index 97b9e7bccf3..490cd43f4aa 100644 --- a/src/devices/machine/pci.cpp +++ b/src/devices/machine/pci.cpp @@ -23,6 +23,8 @@ DEVICE_ADDRESS_MAP_START(config_map, 32, pci_device) AM_RANGE(0x2c, 0x2f) AM_WRITENOP AM_RANGE(0x30, 0x33) AM_READWRITE (expansion_base_r, expansion_base_w) AM_RANGE(0x34, 0x37) AM_READ8 (capptr_r, 0x000000ff) + AM_RANGE(0x3c, 0x3f) AM_READWRITE8(interrupt_line_r, interrupt_line_w, 0x000000ff) + AM_RANGE(0x3c, 0x3f) AM_READWRITE8(interrupt_pin_r, interrupt_pin_w, 0x0000ff00) ADDRESS_MAP_END DEVICE_ADDRESS_MAP_START(config_map, 32, pci_bridge_device) @@ -67,6 +69,8 @@ pci_device::pci_device(const machine_config &mconfig, device_type type, const ch pclass = 0xffffff; subsystem_id = 0xffffffff; is_multifunction_device = false; + intr_pin = 0x0; + intr_line = 0xff; } void pci_device::set_ids(uint32_t _main_id, uint8_t _revision, uint32_t _pclass, uint32_t _subsystem_id) @@ -245,6 +249,30 @@ READ8_MEMBER(pci_device::capptr_r) return 0x00; } +READ8_MEMBER(pci_device::interrupt_line_r) +{ + logerror("interrupt_line_r = %02x\n", intr_line); + return intr_line; +} + +WRITE8_MEMBER(pci_device::interrupt_line_w) +{ + COMBINE_DATA(&intr_line); + logerror("interrupt_line_w %02x\n", data); +} + +READ8_MEMBER(pci_device::interrupt_pin_r) +{ + logerror("interrupt_pin_r = %02x\n", intr_pin); + return intr_pin; +} + +WRITE8_MEMBER(pci_device::interrupt_pin_w) +{ + COMBINE_DATA(&intr_pin); + logerror("interrupt_pin_w = %02x\n", data); +} + void pci_device::set_remap_cb(mapper_cb _remap_cb) { remap_cb = _remap_cb; @@ -749,28 +777,6 @@ WRITE16_MEMBER(pci_bridge_device::iolimitu_w) logerror("iolimitu_w %04x\n", iolimitu); } -READ8_MEMBER (pci_bridge_device::interrupt_line_r) -{ - logerror("interrupt_line_r\n"); - return 0xff; -} - -WRITE8_MEMBER (pci_bridge_device::interrupt_line_w) -{ - logerror("interrupt_line_w %02x\n", data); -} - -READ8_MEMBER (pci_bridge_device::interrupt_pin_r) -{ - logerror("interrupt_pin_r\n"); - return 0xff; -} - -WRITE8_MEMBER (pci_bridge_device::interrupt_pin_w) -{ - logerror("interrupt_pin_w %02x\n", data); -} - READ16_MEMBER (pci_bridge_device::bridge_control_r) { return bridge_control; diff --git a/src/devices/machine/pci.h b/src/devices/machine/pci.h index a67e17a96e0..a7cfd68c7de 100644 --- a/src/devices/machine/pci.h +++ b/src/devices/machine/pci.h @@ -80,6 +80,10 @@ public: DECLARE_READ32_MEMBER (expansion_base_r); DECLARE_WRITE32_MEMBER(expansion_base_w); virtual DECLARE_READ8_MEMBER(capptr_r); + DECLARE_READ8_MEMBER(interrupt_line_r); + DECLARE_WRITE8_MEMBER(interrupt_line_w); + DECLARE_READ8_MEMBER(interrupt_pin_r); + DECLARE_WRITE8_MEMBER(interrupt_pin_w); protected: optional_memory_region m_region; @@ -118,6 +122,7 @@ protected: uint32_t expansion_rom_size; uint32_t expansion_rom_base; bool is_multifunction_device; + uint8_t intr_line, intr_pin; virtual void device_start() override; virtual void device_reset() override; @@ -192,10 +197,6 @@ public: DECLARE_WRITE16_MEMBER(iobaseu_w); DECLARE_READ16_MEMBER (iolimitu_r); DECLARE_WRITE16_MEMBER(iolimitu_w); - DECLARE_READ8_MEMBER (interrupt_line_r); - DECLARE_WRITE8_MEMBER (interrupt_line_w); - DECLARE_READ8_MEMBER (interrupt_pin_r); - DECLARE_WRITE8_MEMBER (interrupt_pin_w); DECLARE_READ16_MEMBER (bridge_control_r); DECLARE_WRITE16_MEMBER(bridge_control_w);