summaryrefslogtreecommitdiffstatshomepage
path: root/src/devices/bus/vme/vme.h
blob: ed4bd7efd5f79caa285b6230b2946a3f62e20d33 (plain) (blame)
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
198
199
200
201
202
203
204
205
206
207
208
209
210
211
212
213
214
215
216
217
218
219
220
221
222
223
224
225
226
227
228
229
230
231
232
233
234
235
236
237
238
239
240
241
242
243
244
245
246
247
248
249
250
251
252
253
254
255
256
257
258
259
260
261
// license:BSD-3-Clause
// copyright-holders: Joakim Larsson Edstrom

/*
 * vme.h
 *
 * VME bus system
 *
 * Pinout: (from http://pinouts.ru/Slots/vmebus_pinout.shtml)

     P1/J1                                   P2/J2 (optional for 32 bit)
    +-A-B-C--+  A        B         C        +-A-B-C--+  A     B        C
 01 | [][][] | D00      BBSY*     D08       | [][][] | n/a   +5v      n/a
 02 | [][][] | D01      BCLR*     D09       | [][][] | n/a   GROUND   n/a
 03 | [][][] | D02      ACFAIL*   D10       | [][][] | n/a   RESERVED n/a
 04 | [][][] | D03      BG0IN*    D11       | [][][] | n/a   A24      n/a
 05 | [][][] | D04      BG0OUT*   D12       | [][][] | n/a   A25      n/a
 06 | [][][] | D05      BG1IN*    D13       | [][][] | n/a   A26      n/a
 07 | [][][] | D06      BG1OUT*   D14       | [][][] | n/a   A27      n/a
 08 | [][][] | D07      BG2IN*    D15       | [][][] | n/a   A28      n/a
 09 | [][][] | GROUND   BG2OUT*   GROUND    | [][][] | n/a   A29      n/a
 10 | [][][] | SYSCLK   BG3IN*    SYSFAIL*  | [][][] | n/a   A30      n/a
 11 | [][][] | GROUND   BG3OUT*   BERR*     | [][][] | n/a   A31      n/a
 12 | [][][] | DS1*     BR0*      SYSRESET* | [][][] | n/a   GROUND   n/a
 13 | [][][] | DS0*     BR1*      LWORD*    | [][][] | n/a   +5v      n/a
 14 | [][][] | WRITE*   BR2*      AM5       | [][][] | n/a   D16      n/a
 15 | [][][] | GROUND   BR3*      A23       | [][][] | n/a   D17      n/a
 16 | [][][] | DTACK*   AM0       A22       | [][][] | n/a   D18      n/a
 17 | [][][] | GROUND   AM1       A21       | [][][] | n/a   D19      n/a
 18 | [][][] | AS*      AM2       A20       | [][][] | n/a   D20      n/a
 19 | [][][] | GROUND   AM3       A19       | [][][] | n/a   D21      n/a
 20 | [][][] | IACK*    GROUND    A18       | [][][] | n/a   D22      n/a
 21 | [][][] | IACKIN*  SERCLK*   A17       | [][][] | n/a   D23      n/a
 22 | [][][] | IACKOUT* SERDAT*   A16       | [][][] | n/a   GROUND   n/a
 23 | [][][] | AM4      GROUND    A15       | [][][] | n/a   D24      n/a
 24 | [][][] | A07      IRQ7*     A14       | [][][] | n/a   D25      n/a
 25 | [][][] | A06      IRQ6*     A13       | [][][] | n/a   D26      n/a
 26 | [][][] | A05      IRQ5*     A12       | [][][] | n/a   D27      n/a
 27 | [][][] | A04      IRQ4*     A11       | [][][] | n/a   D28      n/a
 28 | [][][] | A03      IRQ3*     A10       | [][][] | n/a   D29      n/a
 29 | [][][] | A02      IRQ2*     A09       | [][][] | n/a   D30      n/a
 30 | [][][] | A01      IRQ1*     A08       | [][][] | n/a   D31      n/a
 31 | [][][] | -12v     +5v STDBY +12v      | [][][] | n/a   GROUND   n/a
 32 | [][][] | +5v      +5v       +5v       | [][][] | n/a   +5v      n/a

 */

#ifndef MAME_BUS_VME_VME_H
#define MAME_BUS_VME_VME_H

#pragma once


//**************************************************************************
//  CONSTANTS
//**************************************************************************

#define VME_BUS_TAG        "vme"

// Callbacks to the board from the VME bus comes through here
#define MCFG_VME_J1_CB(_devcb) \
	devcb = &vme_slot_device::static_set_vme_j1_callback(*device, DEVCB_##_devcb);

//SLOT_INTERFACE_EXTERN(vme_slot1); // Disabled until we know how to combine a board driver and a slot device.
SLOT_INTERFACE_EXTERN(vme_slots);

class device_vme_card_interface; // This interface is standardized

class vme_slot_device : public device_t,
	public device_slot_interface
{
public:
	// VME BUS signals driven to or drived by the VME bus
	enum class control
	{
		AS,
		DS0,
		DS1,
		BERR,
		DTACK,
		WRITE
	};

	enum class address
	{
		DS0,
		DS1,
		LWORD
	};

	// construction/destruction
	vme_slot_device(const machine_config &mconfig, const char *tag, device_t *owner, uint32_t clock);

	template <class Object> static devcb_base &static_set_vme_j1_callback(device_t &device, Object &&cb)  { return downcast<vme_slot_device &>(device).m_vme_j1_callback.set_callback(std::forward<Object>(cb)); }

	static void static_set_vme_slot(device_t &device, const char *tag, const char *slottag);
	static void static_update_vme_chains(device_t &device, uint32_t slot_nbr);

	virtual DECLARE_READ8_MEMBER(read8);
	virtual DECLARE_WRITE8_MEMBER(write8);

protected:
	vme_slot_device(const machine_config &mconfig, device_type type, const char *tag, device_t *owner, uint32_t clock);

	// device-level overrides
	virtual void device_start() override;
	virtual void device_config_complete() override;

	// configuration
	const char *m_vme_tag, *m_vme_slottag;

	// callbacks
	devcb_write_line        m_vme_j1_callback;
	device_vme_card_interface *m_card;
};

DECLARE_DEVICE_TYPE(VME, vme_device)

//**************************************************************************
//  INTERFACE CONFIGURATION MACROS
//**************************************************************************

#define MCFG_VME_DEVICE_ADD(_tag) \
	MCFG_DEVICE_ADD(_tag, VME, 0)

#define MCFG_VME_CPU(_cputag) \
	vme_device::static_set_cputag(*device, _cputag);

#define MCFG_VME_BUS_OWNER_SPACES() \
	vme_device::static_use_owner_spaces(*device);

class vme_card_interface;

class vme_device : public device_t,
	public device_memory_interface
{
public:
	vme_device(const machine_config &mconfig, const char *tag, device_t *owner, uint32_t clock);
	~vme_device();

	// inline configuration
	static void static_set_cputag(device_t &device, const char *tag);
	static void static_use_owner_spaces(device_t &device);

	virtual const address_space_config *memory_space_config(address_spacenum spacenum) const override
	{
		switch (spacenum)
		{
		case AS_PROGRAM: return &m_a32_config;
		default:         return nullptr;
		}
	}
	const address_space_config m_a32_config;

	void add_vme_card(device_vme_card_interface *card);

	//
	// Address Modifiers
	//
	/* There are 6 address modifier lines. They allow the MASTER to pass additional binary
	   information to the SLAVE during data transfers. Table 2-3 lists all of the 64 possible
	   address modifier (AM) codes and classifies each into one of three categories:
	   - Defined
	   - Reserved
	   - User defined
	   The defined address modifier codes can be further classified into three categories:
	   Short addressing AM codes indicate that address lines A02-A15 are being used to select a BYTE(0-3) group.
	   Standard addressing AM codes ,indicate that address lines A02-A23 are being used to select a BYTE(0-3) group.
	   Extended addressing AM codes indicate that address lines A02-A31 are being used to select a BYTE(0-3) group.*/

	enum vme_amod_t
	{   // Defined and User Defined Address Modifier Values (long bnames from VME standard text. please use short)
		AMOD_EXTENDED_NON_PRIV_DATA = 0x09, //A32 SC (Single Cycle)
		A32_SC                      = 0x09, //A32 SC (Single Cycle)
		AMOD_EXTENDED_NON_PRIV_PRG  = 0x0A,
		AMOD_EXTENDED_NON_PRIV_BLK  = 0x0B,
		AMOD_EXTENDED_SUPERVIS_DATA = 0x0D,
		AMOD_EXTENDED_SUPERVIS_PRG  = 0x0E,
		AMOD_EXTENDED_SUPERVIS_BLK  = 0x0F,
		AMOD_USER_DEFINED_FIRST     = 0x10,
		AMOD_USER_DEFINED_LAST      = 0x1F,
		AMOD_SHORT_NON_PRIV_ACCESS  = 0x29, //A16 SC
		A16_SC                      = 0x29, //A16 SC
		AMOD_SHORT_SUPERVIS_ACCESS  = 0x2D,
		AMOD_STANDARD_NON_PRIV_DATA = 0x39, //A24 SC
		A24_SC                      = 0x39, //A24 SC
		AMOD_STANDARD_NON_PRIV_PRG  = 0x3A,
		AMOD_STANDARD_NON_PRIV_BLK  = 0x3B, //A24 BLT
		AMOD_STANDARD_SUPERVIS_DATA = 0x3D,
		AMOD_STANDARD_SUPERVIS_PRG  = 0x3E,
		AMOD_STANDARD_SUPERVIS_BLK  = 0x3F
	};
	void install_device(vme_amod_t amod, offs_t start, offs_t end, read8_delegate rhandler, write8_delegate whandler, uint32_t mask);
	//  void install_device(vme_amod_t amod, offs_t start, offs_t end, read8_delegate rhandler, write8_delegate whandler);
	void install_device(vme_amod_t amod, offs_t start, offs_t end, read16_delegate rhandler, write16_delegate whandler, uint32_t mask);
	void install_device(vme_amod_t amod, offs_t start, offs_t end, read32_delegate rhandler, write32_delegate whandler, uint32_t mask);

protected:
	vme_device(const machine_config &mconfig, device_type type, const char *tag, device_t *owner, uint32_t clock);

	// device-level overrides
	virtual void device_start() override;
	virtual void device_reset() override;
	simple_list<device_vme_card_interface> m_device_list;

	// internal state
	cpu_device   *m_maincpu;

	// address spaces
	address_space *m_prgspace;
	int m_prgwidth;
	bool m_allocspaces;

	const char                 *m_cputag;

};



// device type definition
DECLARE_DEVICE_TYPE(VME_SLOT, vme_slot_device)

class device_vme_card_interface : public device_slot_card_interface
{
	template <class ElementType> friend class simple_list;
public:
	// inline configuration
	static void static_set_vme_tag(device_t &device, const char *tag, const char *slottag);

	// construction/destruction
	virtual ~device_vme_card_interface();
	void set_vme_device();

	virtual DECLARE_READ8_MEMBER(read8);
	virtual DECLARE_WRITE8_MEMBER(write8);

	device_vme_card_interface(const machine_config &mconfig, device_t &device);

protected:
	device_t *m_device;

	vme_device  *m_vme;
	const char *m_vme_tag, *m_vme_slottag;
	int m_slot;

private:
	device_vme_card_interface *m_next;
};

#define MCFG_VME_SLOT_ADD(_tag, _slotnbr, _slot_intf,_def_slot)            \
	{   std::string stag = "slot" + std::to_string(_slotnbr);              \
		MCFG_DEVICE_ADD(stag.c_str(), VME_SLOT, 0);                        \
		MCFG_DEVICE_SLOT_INTERFACE(_slot_intf, _def_slot, false);          \
		vme_slot_device::static_set_vme_slot(*device, _tag, stag.c_str()); \
		vme_slot_device::static_update_vme_chains(*device, _slotnbr);      \
	}

#define MCFG_VME_SLOT_REMOVE(_tag)        \
	MCFG_DEVICE_REMOVE(_tag)

#endif // MAME_BUS_VME_VME_H