summaryrefslogtreecommitdiffstatshomepage
path: root/src/emu/devintrf.h
blob: c3f6336fe60a59c0912bf6311cdbbb2ba28f8abf (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
262
263
264
265
266
267
268
269
270
271
272
273
274
275
276
277
278
279
280
281
282
283
284
285
286
287
288
289
290
291
292
293
294
295
296
297
298
299
300
301
302
303
304
305
306
307
308
309
310
311
312
313
314
315
316
317
318
319
320
321
322
323
324
325
326
327
328
329
330
331
332
333
334
335
336
337
338
339
340
341
342
343
344
345
/***************************************************************************

    devintrf.h

    Device interface functions.

    Copyright Nicola Salmoria and the MAME Team.
    Visit http://mamedev.org for licensing and usage restrictions.

***************************************************************************/

#pragma once

#ifndef __DEVINTRF_H__
#define __DEVINTRF_H__

#include "mamecore.h"
#include "romload.h"


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

/* device classes */
enum _device_class
{
	DEVICE_CLASS_GENERAL = 0,			/* default class for general devices */
	DEVICE_CLASS_PERIPHERAL,			/* peripheral devices: PIAs, timers, etc. */
	DEVICE_CLASS_AUDIO,					/* audio devices (not sound chips), including speakers */
	DEVICE_CLASS_VIDEO,					/* video devices, including screens */
	DEVICE_CLASS_CPU_CHIP,				/* CPU chips; only CPU cores should return this class */
	DEVICE_CLASS_SOUND_CHIP,			/* sound chips; only sound cores should return this class */
	DEVICE_CLASS_TIMER,					/* timer devices */
	DEVICE_CLASS_OTHER					/* anything else (the list may expand in the future) */
};
typedef enum _device_class device_class;


/* device start results */
enum _device_start_err
{
	DEVICE_START_OK = 0,				/* everything is fine */
	DEVICE_START_MISSING_DEPENDENCY		/* at least one device we depend on is not yet started */
};
typedef enum _device_start_err device_start_err;


/* useful in device_list functions for scanning through all devices */
#define DEVICE_TYPE_WILDCARD			NULL


/* state constants passed to the device_get_info_func */
enum
{
	/* --- the following bits of info are returned as 64-bit signed integers --- */
	DEVINFO_INT_FIRST = 0x00000,

		DEVINFO_INT_TOKEN_BYTES = DEVINFO_INT_FIRST,	/* R/O: bytes to allocate for the token */
		DEVINFO_INT_INLINE_CONFIG_BYTES,				/* R/O: bytes to allocate for the inline configuration */
		DEVINFO_INT_CLASS,								/* R/O: the device's class */

	DEVINFO_INT_DEVICE_SPECIFIC = 0x08000,				/* R/W: device-specific values start here */
	DEVINFO_INT_LAST = 0x0ffff,

	/* --- the following bits of info are returned as pointers --- */
	DEVINFO_PTR_FIRST = 0x10000,

		DEVINFO_PTR_ROM_REGION = DEVINFO_PTR_FIRST,		/* R/O: pointer to device-specific ROM region */
		DEVINFO_PTR_MACHINE_CONFIG,						/* R/O: pointer to device-specific machine config */

	DEVINFO_PTR_DEVICE_SPECIFIC = 0x18000,				/* R/W: device-specific values start here */
	DEVINFO_PTR_LAST = 0x1ffff,

	/* --- the following bits of info are returned as pointers to functions --- */
	DEVINFO_FCT_FIRST = 0x20000,

		DEVINFO_FCT_SET_INFO = DEVINFO_FCT_FIRST,		/* R/O: device_set_info_func */
		DEVINFO_FCT_START,								/* R/O: device_start_func */
		DEVINFO_FCT_STOP,								/* R/O: device_stop_func */
		DEVINFO_FCT_RESET,								/* R/O: device_reset_func */
		DEVINFO_FCT_VALIDITY_CHECK,						/* R/O: device_validity_check_func */
		DEVINFO_FCT_NVRAM,								/* R/O: device_nvram_func */

	DEVINFO_FCT_DEVICE_SPECIFIC = 0x28000,				/* R/W: device-specific values start here */
	DEVINFO_FCT_LAST = 0x2ffff,

	/* --- the following bits of info are returned as NULL-terminated strings --- */
	DEVINFO_STR_FIRST = 0x30000,

		DEVINFO_STR_NAME = DEVINFO_STR_FIRST,			/* R/O: name of the device */
		DEVINFO_STR_FAMILY,								/* R/O: family of the device */
		DEVINFO_STR_VERSION,							/* R/O: version of the device */
		DEVINFO_STR_SOURCE_FILE,						/* R/O: file containing the device implementation */
		DEVINFO_STR_CREDITS,							/* R/O: credits for the device implementation */

	DEVINFO_STR_DEVICE_SPECIFIC = 0x38000,				/* R/W: device-specific values start here */
	DEVINFO_STR_LAST = 0x3ffff
};



/***************************************************************************
    MACROS
***************************************************************************/

#define DEVICE_GET_INFO_NAME(name)	device_get_info_##name
#define DEVICE_GET_INFO(name)		void DEVICE_GET_INFO_NAME(name)(const device_config *device, UINT32 state, deviceinfo *info)
#define DEVICE_GET_INFO_CALL(name)	DEVICE_GET_INFO_NAME(name)(device, state, info)

#define DEVICE_SET_INFO_NAME(name)	device_set_info_##name
#define DEVICE_SET_INFO(name)		void DEVICE_SET_INFO_NAME(name)(const device_config *device, UINT32 state, const deviceinfo *info)
#define DEVICE_SET_INFO_CALL(name)	DEVICE_SET_INFO_NAME(name)(device, state, info)

#define DEVICE_START_NAME(name)		device_start_##name
#define DEVICE_START(name)			device_start_err DEVICE_START_NAME(name)(const device_config *device)
#define DEVICE_START_CALL(name)		DEVICE_START_NAME(name)(device)

#define DEVICE_STOP_NAME(name)		device_stop_##name
#define DEVICE_STOP(name)			void DEVICE_STOP_NAME(name)(const device_config *device)
#define DEVICE_STOP_CALL(name)		DEVICE_STOP_NAME(name)(device)

#define DEVICE_RESET_NAME(name)		device_reset_##name
#define DEVICE_RESET(name)			void DEVICE_RESET_NAME(name)(const device_config *device)
#define DEVICE_RESET_CALL(name)		DEVICE_RESET_NAME(name)(device)

#define DEVICE_NVRAM_NAME(name)		device_NVRAM_##name
#define DEVICE_NVRAM(name)			void DEVICE_NVRAM_NAME(name)(const device_config *device, mame_file *file, int read_or_write)
#define DEVICE_NVRAM_CALL(name)		DEVICE_NVRAM_NAME(name)(device, file, read_or_write)

#define DEVICE_VALIDITY_CHECK_NAME(name)	device_validity_check_##name
#define DEVICE_VALIDITY_CHECK(name)			int DEVICE_VALIDITY_CHECK_NAME(name)(const game_driver *driver, const device_config *device)
#define DEVICE_VALIDITY_CHECK_CALL(name)	DEVICE_VALIDITY_CHECK(name)(driver, device)



/***************************************************************************
    TYPE DEFINITIONS
***************************************************************************/

/* forward-declare these types */
typedef union _deviceinfo deviceinfo;
typedef struct _device_config device_config;


/* device interface function types */
typedef void (*device_get_info_func)(const device_config *device, UINT32 state, deviceinfo *info);
typedef void (*device_set_info_func)(const device_config *device, UINT32 state, const deviceinfo *info);
typedef device_start_err (*device_start_func)(const device_config *device);
typedef void (*device_stop_func)(const device_config *device);
typedef void (*device_reset_func)(const device_config *device);
typedef void (*device_nvram_func)(const device_config *device, mame_file *file, int read_or_write);
typedef int (*device_validity_check_func)(const game_driver *driver, const device_config *device);


/* a device_type is simply a pointer to its get_info function */
typedef device_get_info_func device_type;


/* the actual deviceinfo union */
union _deviceinfo
{
	INT64					i;						/* generic integers */
	void *					p;						/* generic pointers */
	genf *  				f;						/* generic function pointers */
	const char *			s;						/* generic strings */

	device_set_info_func 	set_info;				/* DEVINFO_FCT_SET_INFO */
	device_start_func		start;					/* DEVINFO_FCT_START */
	device_stop_func		stop;					/* DEVINFO_FCT_STOP */
	device_reset_func		reset;					/* DEVINFO_FCT_RESET */
	device_validity_check_func validity_check;		/* DEVINFO_FCT_VALIDITY_CHECK */
	device_nvram_func		nvram;					/* DEVINFO_FCT_NVRAM */
	const rom_entry *		romregion;				/* DEVINFO_PTR_ROM_REGION */
	const union _machine_config_token *machine_config;/* DEVINFO_PTR_MACHINE_CONFIG */
};


/* the configuration for a general device */
struct _device_config
{
	device_config *			next;					/* next device */
	device_type				type;					/* device type */
	device_class			class;					/* device class */
	device_set_info_func 	set_info;				/* quick pointer to set_info callback */
	device_start_func		start;					/* quick pointer to start callback */
	device_stop_func		stop;					/* quick pointer to stop callback */
	device_reset_func		reset;					/* quick pointer to reset callback */
	device_nvram_func		nvram;					/* quick pointer to nvram callback */
	const void *			static_config;			/* static device configuration */
	void *					inline_config;			/* inline device configuration */

	/* these fields are only valid if the device is live */
	UINT8					started;				/* TRUE if the start function has succeeded */
	void *					token;					/* token if device is live */
	running_machine *		machine;				/* machine if device is live */
	UINT8 *					region;					/* pointer to region with the device's tag, or NULL */
	UINT32					regionbytes;			/* size of the region, in bytes */

	char					tag[1];					/* tag for this instance */
};



/***************************************************************************
    FUNCTION PROTOTYPES
***************************************************************************/


/* ----- device configuration ----- */

/* add a new device to the end of a device list */
device_config *device_list_add(device_config **listheadptr, device_type type, const char *tag);

/* remove a device from a device list */
void device_list_remove(device_config **listheadptr, device_type type, const char *tag);



/* ----- type-based device access ----- */

/* return the number of items of a given type; DEVICE_TYPE_WILDCARD is allowed */
int device_list_items(const device_config *listhead, device_type type);

/* return the first device in the list of a given type; DEVICE_TYPE_WILDCARD is allowed */
const device_config *device_list_first(const device_config *listhead, device_type type);

/* return the next device in the list of a given type; DEVICE_TYPE_WILDCARD is allowed */
const device_config *device_list_next(const device_config *prevdevice, device_type type);

/* retrieve a device configuration based on a type and tag; DEVICE_TYPE_WILDCARD is allowed */
const device_config *device_list_find_by_tag(const device_config *listhead, device_type type, const char *tag);

/* return the index of a device based on its type and tag; DEVICE_TYPE_WILDCARD is allowed */
int device_list_index(const device_config *listhead, device_type type, const char *tag);

/* retrieve a device configuration based on a type and index; DEVICE_TYPE_WILDCARD is allowed */
const device_config *device_list_find_by_index(const device_config *listhead, device_type type, int index);



/* ----- class-based device access ----- */

/* return the number of items of a given class */
int device_list_class_items(const device_config *listhead, device_class class);

/* return the first device in the list of a given class */
const device_config *device_list_class_first(const device_config *listhead, device_class class);

/* return the next device in the list of a given class */
const device_config *device_list_class_next(const device_config *prevdevice, device_class class);

/* retrieve a device configuration based on a class and tag */
const device_config *device_list_class_find_by_tag(const device_config *listhead, device_class class, const char *tag);

/* return the index of a device based on its class and tag */
int device_list_class_index(const device_config *listhead, device_class class, const char *tag);

/* retrieve a device configuration based on a class and index */
const device_config *device_list_class_find_by_index(const device_config *listhead, device_class class, int index);



/* ----- live device management ----- */

/* start the configured list of devices for a machine */
void device_list_start(running_machine *machine);

/* reset a device based on an allocated device_config */
void device_reset(const device_config *device);
void devtag_reset(running_machine *machine, device_type type, const char *tag);



/* ----- device information getters ----- */

/* return the device associated with a tag */
const device_config *devtag_get_device(running_machine *machine, device_type type, const char *tag);

/* return the token associated with an allocated device */
void *devtag_get_token(running_machine *machine, device_type type, const char *tag);

/* return a pointer to the static configuration for a device based on type and tag */
const void *devtag_get_static_config(running_machine *machine, device_type type, const char *tag);

/* return a pointer to the inline configuration for a device based on type and tag */
const void *devtag_get_inline_config(running_machine *machine, device_type type, const char *tag);

/* return an integer state value from an allocated device */
INT64 device_get_info_int(const device_config *device, UINT32 state);
INT64 devtag_get_info_int(running_machine *machine, device_type type, const char *tag, UINT32 state);

/* return a pointer state value from an allocated device */
void *device_get_info_ptr(const device_config *device, UINT32 state);
void *devtag_get_info_ptr(running_machine *machine, device_type type, const char *tag, UINT32 state);

/* return a function pointer state value from an allocated device */
genf *device_get_info_fct(const device_config *device, UINT32 state);
genf *devtag_get_info_fct(running_machine *machine, device_type type, const char *tag, UINT32 state);

/* return a string value from an allocated device */
const char *device_get_info_string(const device_config *device, UINT32 state);
const char *devtag_get_info_string(running_machine *machine, device_type type, const char *tag, UINT32 state);



/* ----- device type information getters ----- */

/* return an integer value from a device type (does not need to be allocated) */
INT64 devtype_get_info_int(device_type type, UINT32 state);

/* return a string value from a device type (does not need to be allocated) */
const char *devtype_get_info_string(device_type type, UINT32 state);



/* ----- device information setters ----- */

/* set an integer state value for an allocated device */
void device_set_info_int(const device_config *device, UINT32 state, INT64 data);
void devtag_set_info_int(running_machine *machine, device_type type, const char *tag, UINT32 state, INT64 data);

/* set a pointer state value for an allocated device */
void device_set_info_ptr(const device_config *device, UINT32 state, void *data);
void devtag_set_info_ptr(running_machine *machine, device_type type, const char *tag, UINT32 state, void *data);

/* set a function pointer state value for an allocated device */
void device_set_info_fct(const device_config *device, UINT32 state, genf *data);
void devtag_set_info_fct(running_machine *machine, device_type type, const char *tag, UINT32 state, genf *data);



/***************************************************************************
    INLINE FUNCTIONS
***************************************************************************/

/* return common strings based on device types */
INLINE const char *devtype_name(device_type devtype)		{ return devtype_get_info_string(devtype, DEVINFO_STR_NAME); }
INLINE const char *devtype_family(device_type devtype) 		{ return devtype_get_info_string(devtype, DEVINFO_STR_FAMILY); }
INLINE const char *devtype_version(device_type devtype) 	{ return devtype_get_info_string(devtype, DEVINFO_STR_VERSION); }
INLINE const char *devtype_source_file(device_type devtype) { return devtype_get_info_string(devtype, DEVINFO_STR_SOURCE_FILE); }
INLINE const char *devtype_credits(device_type devtype) 	{ return devtype_get_info_string(devtype, DEVINFO_STR_CREDITS); }


#endif	/* __DEVINTRF_H__ */