summaryrefslogtreecommitdiffstatshomepage
diff options
context:
space:
mode:
-rw-r--r--src/devices/bus/vme/vme.cpp78
-rw-r--r--src/devices/bus/vme/vme.h51
-rw-r--r--src/mame/sgi/ip4.cpp91
-rw-r--r--src/mame/sgi/ip4.h4
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;