summaryrefslogtreecommitdiffstatshomepage
path: root/src/emu/devcb.h
blob: 0fc1a52fea5edded24ff7420ba68a873a089ba1c (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
/***************************************************************************

    devcb.h

    Device callback interface helpers.

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

****************************************************************************

    These functions are used to adapt multiple read/write handler types
    to be used with device I/O. In general, a device is expected to
    declare its desired callback type, and these functions allow other
    callback types to be adapted appropriately.

    The desired callback types currently supported include:

        read_line_device_func:  (device)
        write_line_device_func: (device, data)
        read8_device_func:      (device, offset)
        write8_device_func:     (device, offset, data)

    The adapted callback types supported are:

        input port              (port)
		cpu input line			(cpu input line)
        read_line_device_func:  (device)
        write_line_device_func: (device, data)
        read8_device_func:      (device, offset)
        write8_device_func:     (device, offset, data)
        read8_space_func:       (space, offset)
        write8_space_func:      (space, offset, data)

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

#pragma once

#ifndef __DEVCB_H__
#define __DEVCB_H__

#include "devintrf.h"
#include "memory.h"


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

#define DEVCB_TYPE_SELF				((device_type)1)
#define DEVCB_TYPE_INPUT			((device_type)2)
#define DEVCB_TYPE_MEMORY(space)	((device_type)(4 + (space)))
#define DEVCB_TYPE_CPU_LINE(line)	((device_type)(4 + ADDRESS_SPACES + (line)))



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

#define DEVCB_NULL							{ 0 }

/* standard line or read/write handlers with the calling device passed */
#define DEVCB_LINE(func)					{ DEVCB_TYPE_SELF, NULL, (func), NULL, NULL }
#define DEVCB_HANDLER(func)					{ DEVCB_TYPE_SELF, NULL, NULL, (func), NULL }

/* line or read/write handlers for another device */
#define DEVCB_DEVICE_LINE(type,tag,func)	{ type, tag, (func), NULL, NULL }
#define DEVCB_DEVICE_HANDLER(type,tag,func)	{ type, tag, NULL, (func), NULL }

/* read/write handlers for a given CPU's address space */
#define DEVCB_MEMORY_HANDLER(cpu,space,func) { DEVCB_TYPE_MEMORY(ADDRESS_SPACE_##space), (cpu), NULL, NULL, (func) }

/* read handlers for an I/O port by tag */
#define DEVCB_INPUT_PORT(tag)				{ DEVCB_TYPE_INPUT, (tag), NULL, NULL, NULL }

/* write handlers for a CPU input line */
#define DEVCB_CPU_INPUT_LINE(tag,line)		{ DEVCB_TYPE_CPU_LINE(line), (tag), NULL, NULL, NULL }


/* macros for defining read_line/write_line functions */
#define READ_LINE_DEVICE_HANDLER(name) 		int  name(ATTR_UNUSED const device_config *device)
#define WRITE_LINE_DEVICE_HANDLER(name) 	void name(ATTR_UNUSED const device_config *device, ATTR_UNUSED int state)



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

/* read/write types for I/O lines (similar to read/write handlers but no offset) */
typedef int (*read_line_device_func)(const device_config *device);
typedef void (*write_line_device_func)(const device_config *device, int state);


/* static structure used for device configuration when the desired callback type is a read_line_device_func */
typedef struct _devcb_read_line devcb_read_line;
struct _devcb_read_line
{
	device_type				type;			/* device type of target, or one of the special DEVCB_TYPE values */
	const char *			tag;			/* tag of target, where appropriate */
	read_line_device_func	readline;		/* read line function */
	read8_device_func		readdevice;		/* read device function */
	read8_space_func		readspace;		/* read space function */
};

typedef struct _devcb_resolved_read_line devcb_resolved_read_line;
struct _devcb_resolved_read_line
{
	const void *			target;			/* target object */
	read_line_device_func	read;			/* read line function */
	const void *			realtarget;		/* real target object for stubs */
	union
	{
		read8_device_func	readdevice;
		read8_space_func	readspace;
	} real;									/* real read function for stubs */
};


/* static structure used for device configuration when the desired callback type is a write_line_device_func */
typedef struct _devcb_write_line devcb_write_line;
struct _devcb_write_line
{
	device_type				type;			/* device type of target, or one of the special DEVCB_TYPE values */
	const char *			tag;			/* tag of target, where appropriate */
	write_line_device_func	writeline;		/* write line function */
	write8_device_func		writedevice;	/* write device function */
	write8_space_func		writespace;		/* write space function */
};

typedef struct _devcb_resolved_write_line devcb_resolved_write_line;
struct _devcb_resolved_write_line
{
	const void *			target;			/* target object */
	write_line_device_func	write;			/* write line function */
	const void *			realtarget;		/* real target object for stubs */
	union
	{
		write8_device_func	writedevice;
		write8_space_func	writespace;
		int					writeline;
	} real;									/* real write function for stubs */
};


/* static structure used for device configuration when the desired callback type is a read8_device_func */
typedef struct _devcb_read8 devcb_read8;
struct _devcb_read8
{
	device_type				type;			/* device type of target, or one of the special DEVCB_TYPE values */
	const char *			tag;			/* tag of target, where appropriate */
	read_line_device_func	readline;		/* read line function */
	read8_device_func		readdevice;		/* read device function */
	read8_space_func		readspace;		/* read space function */
};

typedef struct _devcb_resolved_read8 devcb_resolved_read8;
struct _devcb_resolved_read8
{
	const void *			target;			/* target object */
	read8_device_func		read;			/* read function */
	const void *			realtarget;		/* real target object for stubs */
	union
	{
		read8_device_func	readdevice;
		read8_space_func	readspace;
		read_line_device_func readline;
	} real;									/* real read function for stubs */
};


/* static structure used for device configuration when the desired callback type is a write8_device_func */
typedef struct _devcb_write8 devcb_write8;
struct _devcb_write8
{
	device_type				type;			/* device type of target, or one of the special DEVCB_TYPE values */
	const char *			tag;			/* tag of target, where appropriate */
	write_line_device_func	writeline;		/* write line function */
	write8_device_func		writedevice;	/* write device function */
	write8_space_func		writespace;		/* write space function */
};

typedef struct _devcb_resolved_write8 devcb_resolved_write8;
struct _devcb_resolved_write8
{
	const void *			target;			/* target object */
	write8_device_func		write;			/* write function */
	const void *			realtarget;		/* real target object for stubs */
	union
	{
		write8_device_func	writedevice;
		write8_space_func	writespace;
		write_line_device_func writeline;
	} real;									/* real write function for stubs */
};



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


/* ----- static-to-live conversion ----- */

/* convert a static read line definition to a live definition */
void devcb_resolve_read_line(devcb_resolved_read_line *resolved, const devcb_read_line *config, const device_config *device);

/* convert a static write line definition to a live definition */
void devcb_resolve_write_line(devcb_resolved_write_line *resolved, const devcb_write_line *config, const device_config *device);

/* convert a static 8-bit read definition to a live definition */
void devcb_resolve_read8(devcb_resolved_read8 *resolved, const devcb_read8 *config, const device_config *device);

/* convert a static 8-bit write definition to a live definition */
void devcb_resolve_write8(devcb_resolved_write8 *resolved, const devcb_write8 *config, const device_config *device);



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

/*-------------------------------------------------
    devcb_call_read_line - call through a
    resolved read_line handler
-------------------------------------------------*/

INLINE int devcb_call_read_line(const devcb_resolved_read_line *resolved)
{
	return (resolved->read != NULL) ? (*resolved->read)(resolved->target) : 0;
}


/*-------------------------------------------------
    devcb_call_read8 - call through a
    resolved read8 handler
-------------------------------------------------*/

INLINE int devcb_call_read8(const devcb_resolved_read8 *resolved, offs_t offset)
{
	return (resolved->read != NULL) ? (*resolved->read)(resolved->target, offset) : 0;
}


/*-------------------------------------------------
    devcb_call_write_line - call through a
    resolved write_line handler
-------------------------------------------------*/

INLINE void devcb_call_write_line(const devcb_resolved_write_line *resolved, int state)
{
	if (resolved->write != NULL)
		(*resolved->write)(resolved->target, state);
}


/*-------------------------------------------------
    devcb_call_write8 - call through a
    resolved write8 handler
-------------------------------------------------*/

INLINE void devcb_call_write8(const devcb_resolved_write8 *resolved, offs_t offset, UINT8 data)
{
	if (resolved->write != NULL)
		(*resolved->write)(resolved->target, offset, data);
}


#endif	/* __DEVCB_H__ */