gio64: Get rid of strcmp hacks; decouple interrupts from HPC3 device (nw)

This commit is contained in:
AJR 2019-05-29 16:57:34 -04:00
parent b630126137
commit 1de17bc025
6 changed files with 79 additions and 48 deletions

View File

@ -30,11 +30,15 @@ gio64_slot_device::gio64_slot_device(const machine_config &mconfig, device_type
: device_t(mconfig, type, tag, owner, clock) : device_t(mconfig, type, tag, owner, clock)
, device_slot_interface(mconfig, *this) , device_slot_interface(mconfig, *this)
, m_gio64(*this, finder_base::DUMMY_TAG) , m_gio64(*this, finder_base::DUMMY_TAG)
, m_slot_type(GIO64_SLOT_COUNT)
{ {
} }
void gio64_slot_device::device_validity_check(validity_checker &valid) const void gio64_slot_device::device_validity_check(validity_checker &valid) const
{ {
if (m_slot_type == GIO64_SLOT_COUNT)
osd_printf_error("Slot type not defined\n");
device_t *const card(get_card_device()); device_t *const card(get_card_device());
if (card && !dynamic_cast<device_gio64_card_interface *>(card)) if (card && !dynamic_cast<device_gio64_card_interface *>(card))
osd_printf_error("Card device %s (%s) does not implement device_gio64_card_interface\n", card->tag(), card->name()); osd_printf_error("Card device %s (%s) does not implement device_gio64_card_interface\n", card->tag(), card->name());
@ -44,7 +48,7 @@ void gio64_slot_device::device_resolve_objects()
{ {
device_gio64_card_interface *const gio64_card(dynamic_cast<device_gio64_card_interface *>(get_card_device())); device_gio64_card_interface *const gio64_card(dynamic_cast<device_gio64_card_interface *>(get_card_device()));
if (gio64_card) if (gio64_card)
gio64_card->set_gio64(m_gio64, tag()); gio64_card->set_gio64(m_gio64, m_slot_type);
} }
void gio64_slot_device::device_start() void gio64_slot_device::device_start()
@ -74,12 +78,14 @@ gio64_device::gio64_device(const machine_config &mconfig, device_type type, cons
, device_memory_interface(mconfig, *this) , device_memory_interface(mconfig, *this)
, m_space_config("GIO64 Space", ENDIANNESS_BIG, 64, 32, 0, address_map_constructor()) , m_space_config("GIO64 Space", ENDIANNESS_BIG, 64, 32, 0, address_map_constructor())
, m_maincpu(*this, finder_base::DUMMY_TAG) , m_maincpu(*this, finder_base::DUMMY_TAG)
, m_hpc3(*this, finder_base::DUMMY_TAG) , m_interrupt_cb{{*this}, {*this}, {*this}}
{ {
} }
void gio64_device::device_resolve_objects() void gio64_device::device_resolve_objects()
{ {
for (auto &cb : m_interrupt_cb)
cb.resolve_safe();
} }
void gio64_device::device_start() void gio64_device::device_start()
@ -124,8 +130,9 @@ device_gio64_card_interface *gio64_device::get_gio64_card(int slot)
return nullptr; return nullptr;
} }
void gio64_device::add_gio64_card(device_gio64_card_interface::gio64_slot_type_t slot_type, device_gio64_card_interface *card) void gio64_device::add_gio64_card(gio64_slot_device::slot_type_t slot_type, device_gio64_card_interface *card)
{ {
assert(slot_type >= 0 && slot_type < gio64_slot_device::GIO64_SLOT_COUNT);
m_device_list[slot_type] = card; m_device_list[slot_type] = card;
card->install_device(); card->install_device();
} }
@ -136,7 +143,7 @@ device_gio64_card_interface::device_gio64_card_interface(const machine_config &m
: device_slot_card_interface(mconfig, device) : device_slot_card_interface(mconfig, device)
, m_gio64(nullptr) , m_gio64(nullptr)
, m_gio64_slottag(nullptr) , m_gio64_slottag(nullptr)
, m_slot_type(GIO64_SLOT_COUNT) , m_slot_type(gio64_slot_device::GIO64_SLOT_COUNT)
{ {
} }
@ -157,26 +164,17 @@ void device_gio64_card_interface::interface_pre_start()
fatalerror("Can't find SGI GIO64 device\n"); fatalerror("Can't find SGI GIO64 device\n");
} }
if (GIO64_SLOT_COUNT == m_slot_type) if (!m_gio64->started())
{ throw device_missing_dependencies();
if (!m_gio64->started())
throw device_missing_dependencies();
if (strcmp(m_gio64_slottag, ":gio64_gfx") == 0)
m_slot_type = GIO64_SLOT_GFX;
else if (strcmp(m_gio64_slottag, ":gio64_exp0") == 0)
m_slot_type = GIO64_SLOT_EXP0;
else if (strcmp(m_gio64_slottag, ":gio64_exp1") == 0)
m_slot_type = GIO64_SLOT_EXP1;
else
fatalerror("Slot %s incorrectly named for SGI GIO64 graphics slot\n", m_gio64_slottag);
m_gio64->add_gio64_card(m_slot_type, this);
}
} }
void device_gio64_card_interface::set_gio64(gio64_device *gio64, const char *slottag) void device_gio64_card_interface::interface_post_start()
{
m_gio64->add_gio64_card(m_slot_type, this);
}
void device_gio64_card_interface::set_gio64(gio64_device *gio64, gio64_slot_device::slot_type_t slot_type)
{ {
m_gio64 = gio64; m_gio64 = gio64;
m_gio64_slottag = slottag; m_slot_type = slot_type;
} }

View File

@ -12,16 +12,24 @@
#pragma once #pragma once
#include "cpu/mips/r4000.h" #include "cpu/mips/r4000.h"
#include "machine/hpc3.h"
class gio64_device; class gio64_device;
class gio64_slot_device : public device_t, public device_slot_interface class gio64_slot_device : public device_t, public device_slot_interface
{ {
public: public:
enum slot_type_t : uint32_t
{
GIO64_SLOT_GFX,
GIO64_SLOT_EXP0,
GIO64_SLOT_EXP1,
GIO64_SLOT_COUNT
};
// construction/destruction // construction/destruction
template <typename T, typename U> template <typename T, typename U>
gio64_slot_device(const machine_config &mconfig, const char *tag, device_t *owner, T &&gio64_tag, U &&opts, const char *dflt) gio64_slot_device(const machine_config &mconfig, const char *tag, device_t *owner, T &&gio64_tag, slot_type_t slot_type, U &&opts, const char *dflt)
: gio64_slot_device(mconfig, tag, owner, (uint32_t)0) : gio64_slot_device(mconfig, tag, owner, (uint32_t)0)
{ {
option_reset(); option_reset();
@ -29,6 +37,7 @@ public:
set_default_option(dflt); set_default_option(dflt);
set_fixed(false); set_fixed(false);
m_gio64.set_tag(std::forward<T>(gio64_tag)); m_gio64.set_tag(std::forward<T>(gio64_tag));
m_slot_type = slot_type;
} }
gio64_slot_device(const machine_config &mconfig, const char *tag, device_t *owner, uint32_t clock); gio64_slot_device(const machine_config &mconfig, const char *tag, device_t *owner, uint32_t clock);
@ -42,6 +51,7 @@ protected:
// configuration // configuration
required_device<gio64_device> m_gio64; required_device<gio64_device> m_gio64;
slot_type_t m_slot_type;
DECLARE_READ32_MEMBER(timeout_r); DECLARE_READ32_MEMBER(timeout_r);
DECLARE_WRITE32_MEMBER(timeout_w); DECLARE_WRITE32_MEMBER(timeout_w);
@ -59,31 +69,23 @@ public:
virtual ~device_gio64_card_interface(); virtual ~device_gio64_card_interface();
// inline configuration // inline configuration
void set_gio64(gio64_device *gio64, const char *slottag); void set_gio64(gio64_device *gio64, gio64_slot_device::slot_type_t slot_type);
virtual void mem_map(address_map &map) = 0; virtual void mem_map(address_map &map) = 0;
protected: protected:
device_gio64_card_interface(const machine_config &mconfig, device_t &device); device_gio64_card_interface(const machine_config &mconfig, device_t &device);
enum gio64_slot_type_t : uint32_t
{
GIO64_SLOT_GFX,
GIO64_SLOT_EXP0,
GIO64_SLOT_EXP1,
GIO64_SLOT_COUNT
};
virtual void interface_validity_check(validity_checker &valid) const override; virtual void interface_validity_check(validity_checker &valid) const override;
virtual void interface_pre_start() override; virtual void interface_pre_start() override;
virtual void interface_post_start() override;
virtual void install_device() = 0; virtual void install_device() = 0;
gio64_device &gio64() { assert(m_gio64); return *m_gio64; } gio64_device &gio64() { assert(m_gio64); return *m_gio64; }
gio64_device *m_gio64; gio64_device *m_gio64;
const char *m_gio64_slottag; const char *m_gio64_slottag;
gio64_slot_type_t m_slot_type; gio64_slot_device::slot_type_t m_slot_type;
}; };
@ -93,25 +95,24 @@ class gio64_device : public device_t,
friend class device_gio64_card_interface; friend class device_gio64_card_interface;
public: public:
// construction/destruction // construction/destruction
template <typename T, typename U> template <typename T>
gio64_device(const machine_config &mconfig, const char *tag, device_t *owner, T &&cpu_tag, U &&hpc3_tag) gio64_device(const machine_config &mconfig, const char *tag, device_t *owner, T &&cpu_tag)
: gio64_device(mconfig, tag, owner, (uint32_t)0) : gio64_device(mconfig, tag, owner, (uint32_t)0)
{ {
set_cpu_tag(std::forward<T>(cpu_tag)); set_cpu_tag(std::forward<T>(cpu_tag));
set_hpc3_tag(std::forward<U>(hpc3_tag));
} }
gio64_device(const machine_config &mconfig, const char *tag, device_t *owner, uint32_t clock); gio64_device(const machine_config &mconfig, const char *tag, device_t *owner, uint32_t clock);
// inline configuration // inline configuration
template <typename T> void set_cpu_tag(T &&tag) { m_maincpu.set_tag(std::forward<T>(tag)); } template <typename T> void set_cpu_tag(T &&tag) { m_maincpu.set_tag(std::forward<T>(tag)); }
template <typename T> void set_hpc3_tag(T &&tag) { m_hpc3.set_tag(std::forward<T>(tag)); } template <int N> auto interrupt_cb() { return m_interrupt_cb[N].bind(); }
virtual space_config_vector memory_space_config() const override; virtual space_config_vector memory_space_config() const override;
const address_space_config m_space_config; const address_space_config m_space_config;
void add_gio64_card(device_gio64_card_interface::gio64_slot_type_t slot_type, device_gio64_card_interface *card); void add_gio64_card(gio64_slot_device::slot_type_t slot_type, device_gio64_card_interface *card);
device_gio64_card_interface *get_gio64_card(int slot); device_gio64_card_interface *get_gio64_card(int slot);
template<typename T> void install_graphics(T &device, void (T::*map)(class address_map &map), uint64_t unitmask = ~u64(0)) template<typename T> void install_graphics(T &device, void (T::*map)(class address_map &map), uint64_t unitmask = ~u64(0))
@ -129,7 +130,7 @@ public:
fatalerror("Invalid SGI GIO64 expansion slot index: %d\n", index); fatalerror("Invalid SGI GIO64 expansion slot index: %d\n", index);
} }
hpc3_base_device* get_hpc3() { return m_hpc3.target(); } template <int N> DECLARE_WRITE_LINE_MEMBER(interrupt) { m_interrupt_cb[N](state); }
DECLARE_READ64_MEMBER(read); DECLARE_READ64_MEMBER(read);
DECLARE_WRITE64_MEMBER(write); DECLARE_WRITE64_MEMBER(write);
@ -143,12 +144,13 @@ protected:
// internal state // internal state
required_device<r4000_base_device> m_maincpu; required_device<r4000_base_device> m_maincpu;
required_device<hpc3_base_device> m_hpc3;
address_space *m_space; address_space *m_space;
device_gio64_card_interface *m_device_list[3]; device_gio64_card_interface *m_device_list[3];
private: private:
devcb_write_line m_interrupt_cb[3];
DECLARE_READ64_MEMBER(no_gfx_r); DECLARE_READ64_MEMBER(no_gfx_r);
DECLARE_READ64_MEMBER(no_exp0_r); DECLARE_READ64_MEMBER(no_exp0_r);
DECLARE_READ64_MEMBER(no_exp1_r); DECLARE_READ64_MEMBER(no_exp1_r);

View File

@ -1348,7 +1348,7 @@ WRITE_LINE_MEMBER(newport_base_device::vblank_w)
if (BIT(m_vc2.m_display_ctrl, 0)) if (BIT(m_vc2.m_display_ctrl, 0))
{ {
m_rex3.m_status |= STATUS_VRINT; m_rex3.m_status |= STATUS_VRINT;
m_gio64->get_hpc3()->raise_local_irq(1, ioc2_device::INT3_LOCAL1_RETRACE); m_gio64->interrupt<2>(ASSERT_LINE);
} }
} }
} }
@ -1784,7 +1784,7 @@ READ64_MEMBER(newport_base_device::rex3_r)
LOGMASKED(LOG_REX3, "REX3 Status Read: %08x\n", m_rex3.m_status); LOGMASKED(LOG_REX3, "REX3 Status Read: %08x\n", m_rex3.m_status);
uint32_t old_status = m_rex3.m_status; uint32_t old_status = m_rex3.m_status;
m_rex3.m_status &= ~STATUS_VRINT; m_rex3.m_status &= ~STATUS_VRINT;
m_gio64->get_hpc3()->lower_local_irq(1, ioc2_device::INT3_LOCAL1_RETRACE); m_gio64->interrupt<2>(CLEAR_LINE);
ret |= (uint64_t)(old_status | 3) << 32; ret |= (uint64_t)(old_status | 3) << 32;
} }
if (ACCESSING_BITS_0_31) if (ACCESSING_BITS_0_31)

View File

@ -245,10 +245,13 @@ void ip22_state::ip22_base(machine_config &config)
NSCSI_CONNECTOR(config, "scsibus:7", scsi_devices, nullptr, false); NSCSI_CONNECTOR(config, "scsibus:7", scsi_devices, nullptr, false);
// GIO64 // GIO64
GIO64(config, m_gio64, m_maincpu, m_hpc3); GIO64(config, m_gio64, m_maincpu);
GIO64_SLOT(config, m_gio64_gfx, m_gio64, gio64_cards, "xl24"); m_gio64->interrupt_cb<0>().set(m_hpc3, FUNC(hpc3_base_device::gio_int0));
GIO64_SLOT(config, m_gio64_exp0, m_gio64, gio64_cards, nullptr); m_gio64->interrupt_cb<1>().set(m_hpc3, FUNC(hpc3_base_device::gio_int1));
GIO64_SLOT(config, m_gio64_exp1, m_gio64, gio64_cards, nullptr); m_gio64->interrupt_cb<2>().set(m_hpc3, FUNC(hpc3_base_device::gio_int2));
GIO64_SLOT(config, m_gio64_gfx, m_gio64, gio64_slot_device::GIO64_SLOT_GFX, gio64_cards, "xl24");
GIO64_SLOT(config, m_gio64_exp0, m_gio64, gio64_slot_device::GIO64_SLOT_EXP0, gio64_cards, nullptr);
GIO64_SLOT(config, m_gio64_exp1, m_gio64, gio64_slot_device::GIO64_SLOT_EXP1, gio64_cards, nullptr);
} }
void ip22_state::ip225015(machine_config &config) void ip22_state::ip225015(machine_config &config)

View File

@ -1055,3 +1055,27 @@ WRITE32_MEMBER(hpc3_base_device::eeprom_w)
m_eeprom->cs_write(BIT(data, 1)); m_eeprom->cs_write(BIT(data, 1));
m_eeprom->clk_write(BIT(data, 2)); m_eeprom->clk_write(BIT(data, 2));
} }
WRITE_LINE_MEMBER(hpc3_base_device::gio_int0)
{
if (state == ASSERT_LINE)
raise_local_irq(0, ioc2_device::INT3_LOCAL0_FIFO);
else
lower_local_irq(0, ioc2_device::INT3_LOCAL0_FIFO);
}
WRITE_LINE_MEMBER(hpc3_base_device::gio_int1)
{
if (state == ASSERT_LINE)
raise_local_irq(0, ioc2_device::INT3_LOCAL0_GRAPHICS);
else
lower_local_irq(0, ioc2_device::INT3_LOCAL0_GRAPHICS);
}
WRITE_LINE_MEMBER(hpc3_base_device::gio_int2)
{
if (state == ASSERT_LINE)
raise_local_irq(1, ioc2_device::INT3_LOCAL1_RETRACE);
else
lower_local_irq(1, ioc2_device::INT3_LOCAL1_RETRACE);
}

View File

@ -36,6 +36,10 @@ public:
DECLARE_WRITE_LINE_MEMBER(scsi1_irq); DECLARE_WRITE_LINE_MEMBER(scsi1_irq);
DECLARE_WRITE_LINE_MEMBER(scsi1_drq); DECLARE_WRITE_LINE_MEMBER(scsi1_drq);
DECLARE_WRITE_LINE_MEMBER(gio_int0);
DECLARE_WRITE_LINE_MEMBER(gio_int1);
DECLARE_WRITE_LINE_MEMBER(gio_int2);
protected: protected:
hpc3_base_device(const machine_config &mconfig, device_type type, const char *tag, device_t *owner, uint32_t clock); hpc3_base_device(const machine_config &mconfig, device_type type, const char *tag, device_t *owner, uint32_t clock);