1 // license:BSD-3-Clause
2 // copyright-holders:Ryan Holtz
3 /***************************************************************************
4 
5   gio64.cpp - SGI GIO64 slot bus and GIO64 device emulation
6 
7 ***************************************************************************/
8 
9 #include "emu.h"
10 
11 // Display boards
12 #include "newport.h"
13 
14 #include "gio64.h"
15 
gio64_cards(device_slot_interface & device)16 void gio64_cards(device_slot_interface &device)
17 {
18 	device.option_add("xl8",    GIO64_XL8);  /* SGI 8-bit XL board */
19 	device.option_add("xl24",   GIO64_XL24); /* SGI 24-bit XL board */
20 }
21 
22 DEFINE_DEVICE_TYPE(GIO64_SLOT, gio64_slot_device, "gio64_slot", "SGI GIO64 Slot")
23 
gio64_slot_device(const machine_config & mconfig,const char * tag,device_t * owner,uint32_t clock,slot_type_t slot_type)24 gio64_slot_device::gio64_slot_device(const machine_config &mconfig, const char *tag, device_t *owner, uint32_t clock, slot_type_t slot_type)
25 	: device_t(mconfig, GIO64_SLOT, tag, owner, clock)
26 	, device_slot_interface(mconfig, *this)
27 	, m_gio64(*this, finder_base::DUMMY_TAG)
28 	, m_slot_type(slot_type)
29 {
30 }
31 
device_validity_check(validity_checker & valid) const32 void gio64_slot_device::device_validity_check(validity_checker &valid) const
33 {
34 	device_t *const card(get_card_device());
35 	if (card && !dynamic_cast<device_gio64_card_interface *>(card))
36 		osd_printf_error("Card device %s (%s) does not implement device_gio64_card_interface\n", card->tag(), card->name());
37 }
38 
device_resolve_objects()39 void gio64_slot_device::device_resolve_objects()
40 {
41 	device_gio64_card_interface *const gio64_card(dynamic_cast<device_gio64_card_interface *>(get_card_device()));
42 	if (gio64_card)
43 		gio64_card->set_gio64(m_gio64, m_slot_type);
44 }
45 
device_start()46 void gio64_slot_device::device_start()
47 {
48 	device_t *const card(get_card_device());
49 	if (card && !dynamic_cast<device_gio64_card_interface *>(card))
50 		throw emu_fatalerror("gio64_slot_device: card device %s (%s) does not implement device_gio64_card_interface\n", card->tag(), card->name());
51 }
52 
53 
54 DEFINE_DEVICE_TYPE(GIO64, gio64_device, "gio64", "SGI GIO64 Bus")
55 
memory_space_config() const56 device_memory_interface::space_config_vector gio64_device::memory_space_config() const
57 {
58 	return space_config_vector {
59 		std::make_pair(0, &m_space_config)
60 	};
61 }
62 
gio64_device(const machine_config & mconfig,const char * tag,device_t * owner,uint32_t clock)63 gio64_device::gio64_device(const machine_config &mconfig, const char *tag, device_t *owner, uint32_t clock)
64 	: gio64_device(mconfig, GIO64, tag, owner, clock)
65 {
66 }
67 
gio64_device(const machine_config & mconfig,device_type type,const char * tag,device_t * owner,uint32_t clock)68 gio64_device::gio64_device(const machine_config &mconfig, device_type type, const char *tag, device_t *owner, uint32_t clock)
69 	: device_t(mconfig, type, tag, owner, clock)
70 	, device_memory_interface(mconfig, *this)
71 	, m_space_config("GIO64 Space", ENDIANNESS_BIG, 64, 32, 0)
72 	, m_interrupt_cb(*this)
73 {
74 }
75 
device_resolve_objects()76 void gio64_device::device_resolve_objects()
77 {
78 	m_interrupt_cb.resolve_all_safe();
79 }
80 
device_start()81 void gio64_device::device_start()
82 {
83 	std::fill(std::begin(m_device_list), std::end(m_device_list), nullptr);
84 }
85 
read(offs_t offset,u64 mem_mask)86 u64 gio64_device::read(offs_t offset, u64 mem_mask)
87 {
88 	return space(0).read_qword(offset << 3, mem_mask);
89 }
90 
write(offs_t offset,u64 data,u64 mem_mask)91 void gio64_device::write(offs_t offset, u64 data, u64 mem_mask)
92 {
93 	space(0).write_qword(offset << 3, data, mem_mask);
94 }
95 
get_gio64_card(int slot)96 device_gio64_card_interface *gio64_device::get_gio64_card(int slot)
97 {
98 	if (slot < 0)
99 	{
100 		return nullptr;
101 	}
102 
103 	if (m_device_list[slot])
104 	{
105 		return m_device_list[slot];
106 	}
107 
108 	return nullptr;
109 }
110 
111 
device_gio64_card_interface(const machine_config & mconfig,device_t & device)112 device_gio64_card_interface::device_gio64_card_interface(const machine_config &mconfig, device_t &device)
113 	: device_interface(device, "sgigio64")
114 	, m_gio64(nullptr)
115 {
116 }
117 
~device_gio64_card_interface()118 device_gio64_card_interface::~device_gio64_card_interface()
119 {
120 }
121 
interface_pre_start()122 void device_gio64_card_interface::interface_pre_start()
123 {
124 	if (!m_gio64)
125 	{
126 		fatalerror("Can't find SGI GIO64 device\n");
127 	}
128 
129 	if (!m_gio64->started())
130 		throw device_missing_dependencies();
131 }
132 
set_gio64(gio64_device * gio64,gio64_slot_device::slot_type_t slot_type)133 void device_gio64_card_interface::set_gio64(gio64_device *gio64, gio64_slot_device::slot_type_t slot_type)
134 {
135 	m_gio64 = gio64;
136 
137 	m_gio64->install_card(slot_type, *this, &device_gio64_card_interface::mem_map);
138 }
139