diff options
-rw-r--r-- | src/devices/bus/vme/vme.cpp | 78 | ||||
-rw-r--r-- | src/devices/bus/vme/vme.h | 51 | ||||
-rw-r--r-- | src/mame/sgi/ip4.cpp | 91 | ||||
-rw-r--r-- | src/mame/sgi/ip4.h | 4 |
4 files changed, 127 insertions, 97 deletions
diff --git a/src/devices/bus/vme/vme.cpp b/src/devices/bus/vme/vme.cpp index d154edaf310..c1ad72e17a4 100644 --- a/src/devices/bus/vme/vme.cpp +++ b/src/devices/bus/vme/vme.cpp @@ -157,7 +157,10 @@ u32 vme_bus_device::read_iack(address_space &space, offs_t offset, u32 mem_mask) { if (!device().machine().side_effects_disabled()) { - LOG("read_iack 0x%08x mem_mask 0x%08x (%s)\n", offset, mem_mask, machine().describe_context()); + // decode the interrupt number from address lines A03-A01 + unsigned const irq = BIT(offset, 1, 3); + + LOG("read_iack 0x%08x mem_mask 0x%08x /IRQ%u /IACKIN asserted (%s)\n", offset, mem_mask, irq, machine().describe_context()); // enable interrupt acknowledge daisy chain m_iack = true; @@ -169,22 +172,24 @@ u32 vme_bus_device::read_iack(address_space &space, offs_t offset, u32 mem_mask) // generate bus errors on unmapped read cycles u32 vme_bus_device::read_berr(address_space &space, offs_t offset, u32 mem_mask) { + u32 const data = space.unmap(); + if (!device().machine().side_effects_disabled()) { - LOG("read_berr 0x%08x mem_mask 0x%08x (%s)\n", offset << 2, mem_mask, machine().describe_context()); + LOG("read_berr %s 0x%08x data 0x%08x mem_mask 0x%08x /BERR asserted (%s)\n", space.name(), offset << 2, data, mem_mask, machine().describe_context()); m_berr(0); } - return space.unmap(); + return data; } // generate bus errors on unmapped write cycles -void vme_bus_device::write_berr(offs_t offset, u32 data, u32 mem_mask) +void vme_bus_device::write_berr(address_space &space, offs_t offset, u32 data, u32 mem_mask) { if (!device().machine().side_effects_disabled()) { - LOG("write_berr 0x%08x data 0x%08x mem_mask 0x%08x (%s)\n", offset << 2, data, mem_mask, machine().describe_context()); + LOG("write_berr %s 0x%08x data 0x%08x mem_mask 0x%08x /BERR asserted (%s)\n", space.name(), offset << 2, data, mem_mask, machine().describe_context()); m_berr(0); } @@ -223,7 +228,7 @@ template <unsigned I> void vme_bus_device::irq_w(int state) // update line state if (irq_active ^ bool(m_irq_count[I - 1])) { - LOG("irq %d state %d\n", I, state); + LOG("bus /IRQ%u %s\n", I, state ? "cleared" : "asserted"); m_irq[I - 1](state); } } @@ -239,10 +244,16 @@ template void vme_bus_device::irq_w<7>(int state); vme_slot_device::vme_slot_device(machine_config const &mconfig, char const *tag, device_t *owner, u32 clock) : device_t(mconfig, VME_SLOT, tag, owner, clock) , device_slot_interface(mconfig, *this) - , m_bus(*this, owner->tag()) { } +void vme_slot_device::device_config_complete() +{ + device_vme_card_interface *const card(dynamic_cast<device_vme_card_interface *>(get_card_device())); + if (card && owner()) + card->set_bus(*dynamic_cast<vme_bus_device *>(owner())); +} + void vme_slot_device::device_start() { } @@ -252,29 +263,15 @@ void vme_slot_device::device_start() device_vme_card_interface::device_vme_card_interface(machine_config const &mconfig, device_t &device) : device_interface(device, "vme") - , m_slot(dynamic_cast<vme_slot_device *>(device.owner())) + , m_bus(nullptr) , m_berr(*this) + , m_irq(*this) , m_iack(*this, 0) , m_irq_active(0) , m_master(false) { } -void device_vme_card_interface::interface_config_complete() -{ - // route bus errors to the card when it is the bus master - if (m_slot) // HACK: avoid breaking listxml until proper fix can be identified - m_slot->berr().append( - [this](int state) - { - if (m_master) - { - LOG("vme berr %d\n", state); - m_berr(state); - } - }); -} - void device_vme_card_interface::interface_post_start() { device().save_item(NAME(m_irq_active)); @@ -298,17 +295,42 @@ void device_vme_card_interface::interface_post_start() * chain input (/IACKIN) is asserted and this device is asserting * the interrupt number being acknowledged. */ - if (m_slot->iackin_r() && BIT(m_irq_active, irq)) + if (!m_bus->iackin_r() && BIT(m_irq_active, irq)) { // deassert interrupt acknowledge daisy chain output - m_slot->iackout_w(1); + m_bus->iackout_w(1); // read and return the interrupting device status/ID data = m_iack(irq); - LOG("vme iack irq %d status 0x%08x (%s)\n", irq, data, device().machine().describe_context()); + LOG("vme iack irq %u status 0x%08x /IACKOUT deasserted (%s)\n", irq, data, device().machine().describe_context()); + } + }); +} + +void device_vme_card_interface::set_bus(vme_bus_device &bus) +{ + m_bus = &bus; + + // route incoming bus errors to a card only when it is the bus master + m_bus->berr().append( + [this](int state) + { + if (m_master) + { + LOG("vme incoming /BERR %s\n", state ? "cleared" : "asserted"); + m_berr(state); } }); + + // route incoming interrupt requests to all cards + m_bus->irq<1>().append([this](int state) { LOG("vme incoming /IRQ1 %s\n", state ? "cleared" : "asserted"); m_irq[0](state); }); + m_bus->irq<2>().append([this](int state) { LOG("vme incoming /IRQ2 %s\n", state ? "cleared" : "asserted"); m_irq[1](state); }); + m_bus->irq<3>().append([this](int state) { LOG("vme incoming /IRQ3 %s\n", state ? "cleared" : "asserted"); m_irq[2](state); }); + m_bus->irq<4>().append([this](int state) { LOG("vme incoming /IRQ4 %s\n", state ? "cleared" : "asserted"); m_irq[3](state); }); + m_bus->irq<5>().append([this](int state) { LOG("vme incoming /IRQ5 %s\n", state ? "cleared" : "asserted"); m_irq[4](state); }); + m_bus->irq<6>().append([this](int state) { LOG("vme incoming /IRQ6 %s\n", state ? "cleared" : "asserted"); m_irq[5](state); }); + m_bus->irq<7>().append([this](int state) { LOG("vme incoming /IRQ7 %s\n", state ? "cleared" : "asserted"); m_irq[6](state); }); } template <unsigned I> void device_vme_card_interface::vme_irq_w(int state) @@ -316,7 +338,7 @@ template <unsigned I> void device_vme_card_interface::vme_irq_w(int state) // check whether the interrupt state has changed if (BIT(m_irq_active, I) == state) { - LOG("vme irq %d state %d\n", I, state); + LOG("vme_irq_w outgoing /IRQ%u %s\n", I, state ? "cleared" : "asserted"); // record device interrupt state if (!state) @@ -325,7 +347,7 @@ template <unsigned I> void device_vme_card_interface::vme_irq_w(int state) m_irq_active &= ~(1U << I); // update the bus irq state - m_slot->irq_w<I>(state); + m_bus->irq_w<I>(state); } } diff --git a/src/devices/bus/vme/vme.h b/src/devices/bus/vme/vme.h index 657e7b8a967..c70a4b1ab73 100644 --- a/src/devices/bus/vme/vme.h +++ b/src/devices/bus/vme/vme.h @@ -88,7 +88,7 @@ public: // runtime void berr_w(int state) { m_berr(state); } - int iackin_r() { return m_iack; } + int iackin_r() { return !m_iack; } void iackout_w(int state) { m_iack = !state; } template <unsigned I> void irq_w(int state); @@ -107,7 +107,7 @@ private: u32 read_iack(address_space &space, offs_t offset, u32 mem_mask); u32 read_berr(address_space &space, offs_t offset, u32 mem_mask); - void write_berr(offs_t offset, u32 data, u32 mem_mask); + void write_berr(address_space &space, offs_t offset, u32 data, u32 mem_mask); address_space_config const m_asc[64]; @@ -135,24 +135,12 @@ public: set_fixed(fixed); } - // configuration - template <unsigned I> auto irq() { return m_bus.lookup()->irq<I>(); } - auto berr() { return m_bus.lookup()->berr(); } - - // runtime - void berr_w(int state) { m_bus->berr_w(state); } - int iackin_r() { return m_bus->iackin_r(); } - void iackout_w(int state) { m_bus->iackout_w(state); } - template <unsigned I> void irq_w(int state) { m_bus->irq_w<I>(state); } - - address_space &space(vme::address_modifier am) const { return m_bus->space(am); } - protected: // device_t implementation + virtual void device_config_complete() override ATTR_COLD; virtual void device_start() override ATTR_COLD; private: - required_device<vme_bus_device> m_bus; }; class device_vme_card_interface : public device_interface @@ -161,7 +149,7 @@ public: template <vme::address_modifier AM, offs_t base = 0> u32 vme_read32(offs_t offset, u32 mem_mask) { m_master = true; - u32 const data = m_slot->space(AM).read_dword(base + (offset << 2), mem_mask); + u32 const data = m_bus->space(AM).read_dword(base + (offset << 2), mem_mask); m_master = false; return data; @@ -169,7 +157,7 @@ public: template <vme::address_modifier AM, offs_t base = 0> u16 vme_read16(offs_t offset, u16 mem_mask) { m_master = true; - u16 const data = m_slot->space(AM).read_word(base + (offset << 1), mem_mask); + u16 const data = m_bus->space(AM).read_word(base + (offset << 1), mem_mask); m_master = false; return data; @@ -177,41 +165,44 @@ public: template <vme::address_modifier AM, offs_t base = 0> void vme_write32(offs_t offset, u32 data, u32 mem_mask) { m_master = true; - m_slot->space(AM).write_dword(base + (offset << 2), data, mem_mask); + m_bus->space(AM).write_dword(base + (offset << 2), data, mem_mask); m_master = false; } template <vme::address_modifier AM, offs_t base = 0> void vme_write16(offs_t offset, u16 data, u16 mem_mask) { m_master = true; - m_slot->space(AM).write_word(base + (offset << 1), data, mem_mask); + m_bus->space(AM).write_word(base + (offset << 1), data, mem_mask); m_master = false; } u32 vme_iack_r(offs_t offset) { - return m_slot->space(vme::IACK).read_dword(offset); + return m_bus->space(vme::IACK).read_dword(offset); } + void set_bus(vme_bus_device &bus); + protected: device_vme_card_interface(machine_config const &mconfig, device_t &device); - // configuration - template <unsigned I> auto vme_irq() { return m_slot->irq<I>(); } - auto vme_berr() { return m_berr.bind(); } - auto vme_iack() { return m_iack.bind(); } - // device_interface implementation - virtual void interface_config_complete() override; virtual void interface_post_start() override; + // configuration + auto vme_berr() { return m_berr.bind(); } // receive a bus error + template <unsigned I> auto vme_irq() { return m_irq[I - 1].bind(); } // receive a bus interrupt + auto vme_iack() { return m_iack.bind(); } // provide an interrupt acknowledge vector + // runtime - template <unsigned I> void vme_irq_w(int state); - void vme_berr_w(int state) { m_slot->berr_w(state); } + void vme_berr_w(int state) { m_bus->berr_w(state); } // generate a bus error + template <unsigned I> void vme_irq_w(int state); // generate a bus interrupt - address_space &vme_space(vme::address_modifier am) const { return m_slot->space(am); } + address_space &vme_space(vme::address_modifier am) const { return m_bus->space(am); } private: - vme_slot_device *m_slot; + vme_bus_device *m_bus; + devcb_write_line m_berr; + devcb_write_line::array<7> m_irq; devcb_read32 m_iack; u8 m_irq_active; diff --git a/src/mame/sgi/ip4.cpp b/src/mame/sgi/ip4.cpp index 6e9abeba3c3..fe7f4bec944 100644 --- a/src/mame/sgi/ip4.cpp +++ b/src/mame/sgi/ip4.cpp @@ -3,6 +3,11 @@ /* * Silicon Graphics Professional IRIS 4D/50 and 4D/70 CPU board. + * + * WIP: + * setenv root dks0d1s0 + * setenv bootfile dksc(0,1,8)sash + * auto */ #include "emu.h" @@ -137,9 +142,7 @@ void sgi_ip4_device::map(address_map &map) NAME([this](offs_t offset) { return m_duart[BIT(offset, 0, 2)]->read(offset >> 2); }), NAME([this](offs_t offset, u8 data) { m_duart[BIT(offset, 0, 2)]->write(offset >> 2, data); })); - map(0x1fbc'0000, 0x1fbc'1fff).umask32(0xff00'0000).lrw8( - NAME([this](offs_t offset) { return m_nvram[offset]; }), - NAME([this](offs_t offset, u8 data) { m_nvram[offset] = data; })); + map(0x1fbc'0000, 0x1fbc'1fff).umask32(0xff00'0000).rw(FUNC(sgi_ip4_device::nvram_r), FUNC(sgi_ip4_device::nvram_w)); map(0x1fc0'0000, 0x1fc3'ffff).rom().region("boot", 0); } @@ -279,23 +282,17 @@ void sgi_ip4_device::device_add_mconfig(machine_config &config) SAA1099(config, m_saa, 8_MHz_XTAL); m_saa->add_route(0, "lspeaker", 0.5); m_saa->add_route(1, "rspeaker", 0.5); -} -void sgi_ip4_device::device_config_complete() -{ - if (owner() && owner()->owner()) - { // TODO: ACFAIL -> vme_irq<0> - device_vme_card_interface::vme_irq<1>().append(*this, FUNC(sgi_ip4_device::vme_irq<1>)); - device_vme_card_interface::vme_irq<2>().append(*this, FUNC(sgi_ip4_device::vme_irq<2>)); - device_vme_card_interface::vme_irq<3>().append(*this, FUNC(sgi_ip4_device::vme_irq<3>)); - device_vme_card_interface::vme_irq<4>().append(*this, FUNC(sgi_ip4_device::vme_irq<4>)); - device_vme_card_interface::vme_irq<5>().append(*this, FUNC(sgi_ip4_device::vme_irq<5>)); - device_vme_card_interface::vme_irq<6>().append(*this, FUNC(sgi_ip4_device::vme_irq<6>)); - device_vme_card_interface::vme_irq<7>().append(*this, FUNC(sgi_ip4_device::vme_irq<7>)); + device_vme_card_interface::vme_irq<1>().set(*this, FUNC(sgi_ip4_device::vme_irq<1>)); + device_vme_card_interface::vme_irq<2>().set(*this, FUNC(sgi_ip4_device::vme_irq<2>)); + device_vme_card_interface::vme_irq<3>().set(*this, FUNC(sgi_ip4_device::vme_irq<3>)); + device_vme_card_interface::vme_irq<4>().set(*this, FUNC(sgi_ip4_device::vme_irq<4>)); + device_vme_card_interface::vme_irq<5>().set(*this, FUNC(sgi_ip4_device::vme_irq<5>)); + device_vme_card_interface::vme_irq<6>().set(*this, FUNC(sgi_ip4_device::vme_irq<6>)); + device_vme_card_interface::vme_irq<7>().set(*this, FUNC(sgi_ip4_device::vme_irq<7>)); vme_berr().set_inputline(m_cpu, INPUT_LINE_IRQ5).invert(); - } } void sgi_ip4_device::device_start() @@ -324,26 +321,6 @@ void sgi_ip4_device::device_start() m_lio_irq = false; m_vme_irq = false; - // install phantom rtc with a memory tap - m_cpu->space(AS_PROGRAM).install_readwrite_tap(0x1fbc'1ffc, 0x1fbc'1fff, "rtc", - [this](offs_t offset, u32 &data, u32 mem_mask) - { - if (m_rtc->chip_enable()) - data = u32(m_rtc->read_data()) << 24; - }, - [this](offs_t offset, u32 &data, u32 mem_mask) - { - if (!m_rtc->chip_enable()) - { - if (data) - m_rtc->read_1(); - else - m_rtc->read_0(); - } - else - m_rtc->write_data(data >> 24); - }); - m_parity_bad = 0; } @@ -407,7 +384,7 @@ void sgi_ip4_device::scsi_drq(int state) void sgi_ip4_device::cpucfg_w(u16 data) { - LOG("cpucfg_w 0x%04x\n", data); + //LOG("cpucfg_w 0x%04x (%s)\n", data, machine().describe_context()); // update leds for (unsigned i = 0; i < 5; i++) @@ -530,14 +507,52 @@ void sgi_ip4_device::mailbox_w(offs_t offset, u8 data) } } +u8 sgi_ip4_device::nvram_r(offs_t offset) +{ + if (offset == 0x7ff && !machine().side_effects_disabled()) + { + if (m_rtc->chip_enable()) + m_rtc->read_data(); + else + return m_rtc->read_data(); + } + + return m_nvram[offset]; +} + +void sgi_ip4_device::nvram_w(offs_t offset, u8 data) +{ + if (offset != 0x7ff || !m_rtc->chip_enable()) + m_nvram[offset] = data; + + if (offset == 0x7ff) + { + if (!m_rtc->chip_enable()) + { + if (data) + m_rtc->read_1(); + else + m_rtc->read_0(); + } + else + m_rtc->write_data(data); + } +} + ROM_START(ip4) ROM_REGION32_BE(0x40000, "boot", 0) - ROM_SYSTEM_BIOS(0, "4d1v3", "Version 4D1-3.0 PROM IP4 Mon Jan 4 20:29:51 PST 1988 SGI") + ROM_SYSTEM_BIOS(0, "4d1v30", "Version 4D1-3.0 PROM IP4 Mon Jan 4 20:29:51 PST 1988 SGI") ROMX_LOAD("070-0093-009.bin", 0x000000, 0x010000, CRC(261b0a4c) SHA1(59f73d0e022a502dc5528289e388700b51b308da), ROM_BIOS(0) | ROM_SKIP(3)) ROMX_LOAD("070-0094-009.bin", 0x000001, 0x010000, CRC(8c05f591) SHA1(d4f86ad274f9dfe10c38551f3b6b9ba73570747f), ROM_BIOS(0) | ROM_SKIP(3)) ROMX_LOAD("070-0095-009.bin", 0x000002, 0x010000, CRC(2dacfcb7) SHA1(0149274a11d61e3ada0f7b055e79d884a65481d3), ROM_BIOS(0) | ROM_SKIP(3)) ROMX_LOAD("070-0096-009.bin", 0x000003, 0x010000, CRC(72dd0246) SHA1(6df99bdf7afaded8ef68a9644dd06ca69a996db0), ROM_BIOS(0) | ROM_SKIP(3)) + ROM_SYSTEM_BIOS(1, "4d1v31", "Version 4D1-3.1 PROM IP4 OPT Thu Dec 8 16:12:10 PST 1988 SGI") + ROMX_LOAD("070-0093-010.bin", 0x000000, 0x010000, CRC(f46871bf) SHA1(bda07b083dbb350d90a9145539c389180c800fb4), ROM_BIOS(1) | ROM_SKIP(3)) + ROMX_LOAD("070-0094-010.bin", 0x000001, 0x010000, CRC(7b183793) SHA1(b5471a990f755333378f77e7a4d1102479ccfdc1), ROM_BIOS(1) | ROM_SKIP(3)) + ROMX_LOAD("070-0095-010.bin", 0x000002, 0x010000, CRC(af2a2f0b) SHA1(beda300a5b1633f7682fdf3b8b0650bfea253567), ROM_BIOS(1) | ROM_SKIP(3)) + ROMX_LOAD("070-0096-010.bin", 0x000003, 0x010000, CRC(eaa2bdc3) SHA1(8f1f37ec8875f36b45d335412ae1c298af84f20f), ROM_BIOS(1) | ROM_SKIP(3)) + ROM_REGION32_BE(0x20, "idprom", 0) ROM_LOAD("idprom.bin", 0, 0x20, NO_DUMP) ROM_END diff --git a/src/mame/sgi/ip4.h b/src/mame/sgi/ip4.h index b51b713004f..0f20770b441 100644 --- a/src/mame/sgi/ip4.h +++ b/src/mame/sgi/ip4.h @@ -27,7 +27,6 @@ public: protected: virtual tiny_rom_entry const *device_rom_region() const override ATTR_COLD; virtual void device_add_mconfig(machine_config &config) override ATTR_COLD; - virtual void device_config_complete() override; virtual ioport_constructor device_input_ports() const override ATTR_COLD; virtual void device_start() override ATTR_COLD; virtual void device_reset() override ATTR_COLD; @@ -48,6 +47,9 @@ protected: void mailbox_w(offs_t offset, u8 data); + u8 nvram_r(offs_t offset); + void nvram_w(offs_t offset, u8 data); + private: required_device<mips1_device_base> m_cpu; required_device<ds1315_device> m_rtc; |