1 /***************************************************************************
2 
3 	driver.h
4 
5 	Include this with all MAME files. Includes all the core system pieces.
6 
7 ***************************************************************************/
8 
9 #ifndef DRIVER_H
10 #define DRIVER_H
11 
12 
13 /***************************************************************************
14 
15 	Macros for declaring common callbacks
16 
17 ***************************************************************************/
18 
19 #define DRIVER_INIT(name)		void init_##name(void)
20 
21 #define INTERRUPT_GEN(func)		void func(void)
22 
23 #define MACHINE_INIT(name)		void machine_init_##name(void)
24 #define MACHINE_STOP(name)		void machine_stop_##name(void)
25 
26 #define NVRAM_HANDLER(name)		void nvram_handler_##name(mame_file *file, int read_or_write)
27 
28 #define PALETTE_INIT(name)		void palette_init_##name(UINT16 *colortable, const UINT8 *color_prom)
29 
30 #define VIDEO_START(name)		int video_start_##name(void)
31 #define VIDEO_STOP(name)		void video_stop_##name(void)
32 #define VIDEO_EOF(name)			void video_eof_##name(void)
33 #define VIDEO_UPDATE(name)		void video_update_##name(struct mame_bitmap *bitmap, const struct rectangle *cliprect)
34 
35 #define MIXER_USE_CLIPPING
36 
37 #if defined(MIXER_USE_CLIPPING)
38 #define MAME_CLAMP_SAMPLE(a) \
39    if ((int16_t)a != a) \
40       a = (a >> 31) ^ 0x7FFF
41 #else
42 #define MAME_CLAMP_SAMPLE(a) ((void)0)
43 #endif
44 
45 /* NULL versions */
46 #define init_NULL				NULL
47 #define machine_init_NULL 		NULL
48 #define nvram_handler_NULL 		NULL
49 #define palette_init_NULL		NULL
50 #define video_start_NULL 		NULL
51 #define video_stop_NULL 		NULL
52 #define video_eof_NULL 			NULL
53 #define video_update_NULL 		NULL
54 
55 
56 
57 /***************************************************************************
58 
59 	Core MAME includes
60 
61 ***************************************************************************/
62 
63 #include "osd_cpu.h"
64 #include "memory.h"
65 #include "mamedbg.h"
66 #include "mame2003.h"
67 #include "mame.h"
68 #include "common.h"
69 #include "drawgfx.h"
70 #include "palette.h"
71 #include "cpuintrf.h"
72 #include "cpuexec.h"
73 #include "cpuint.h"
74 #include "sndintrf.h"
75 #include "input.h"
76 #include "inptport.h"
77 #include "usrintrf.h"
78 #include "cheat.h"
79 #include "tilemap.h"
80 #include "profiler.h"
81 
82 #include "controls.h"
83 
84 
85 /***************************************************************************
86 
87 	Macros for building machine drivers
88 
89 ***************************************************************************/
90 
91 /* use this to declare external references to a machine driver */
92 #define MACHINE_DRIVER_EXTERN(game)										\
93 	void construct_##game(struct InternalMachineDriver *machine)		\
94 
95 
96 /* start/end tags for the machine driver */
97 #define MACHINE_DRIVER_START(game) 										\
98 	void construct_##game(struct InternalMachineDriver *machine)		\
99 	{																	\
100 		struct MachineCPU *cpu = NULL;									\
101 		(void)cpu;														\
102 
103 #define MACHINE_DRIVER_END 												\
104 	}																	\
105 
106 
107 /* importing data from other machine drivers */
108 #define MDRV_IMPORT_FROM(game) 											\
109 	construct_##game(machine); 											\
110 
111 
112 /* add/modify/remove/replace CPUs */
113 #define MDRV_CPU_ADD_TAG(tag, type, clock)								\
114 	cpu = machine_add_cpu(machine, (tag), CPU_##type, (clock));			\
115 
116 #define MDRV_CPU_ADD(type, clock)										\
117 	MDRV_CPU_ADD_TAG(NULL, type, clock)									\
118 
119 #define MDRV_CPU_MODIFY(tag)											\
120 	cpu = machine_find_cpu(machine, tag);								\
121 
122 #define MDRV_CPU_REMOVE(tag)											\
123 	machine_remove_cpu(machine, tag);									\
124 	cpu = NULL;															\
125 
126 #define MDRV_CPU_REPLACE(tag, type, clock)								\
127 	cpu = machine_find_cpu(machine, tag);								\
128 	if (cpu)															\
129 	{																	\
130 		cpu->cpu_type = (CPU_##type);									\
131 		cpu->cpu_clock = (clock);										\
132 	}																	\
133 
134 
135 /* CPU parameters */
136 #define MDRV_CPU_FLAGS(flags)											\
137 	if (cpu)															\
138 		cpu->cpu_flags = (flags);										\
139 
140 #define MDRV_CPU_CONFIG(config)											\
141 	if (cpu)															\
142 		cpu->reset_param = &(config);									\
143 
144 #define MDRV_CPU_MEMORY(readmem, writemem)								\
145 	if (cpu)															\
146 	{																	\
147 		cpu->memory_read = (readmem);									\
148 		cpu->memory_write = (writemem);									\
149 	}																	\
150 
151 #define MDRV_CPU_PORTS(readport, writeport)								\
152 	if (cpu)															\
153 	{																	\
154 		cpu->port_read = (readport);									\
155 		cpu->port_write = (writeport);									\
156 	}																	\
157 
158 #define MDRV_CPU_VBLANK_INT(func, rate)									\
159 	if (cpu)															\
160 	{																	\
161 		cpu->vblank_interrupt = func;									\
162 		cpu->vblank_interrupts_per_frame = (rate);						\
163 	}																	\
164 
165 #define MDRV_CPU_PERIODIC_INT(func, rate)								\
166 	if (cpu)															\
167 	{																	\
168 		cpu->timed_interrupt = func;									\
169 		cpu->timed_interrupts_per_second = (rate);						\
170 	}																	\
171 
172 
173 /* core parameters */
174 #define MDRV_FRAMES_PER_SECOND(rate)									\
175 	machine->frames_per_second = (rate);								\
176 
177 #define MDRV_VBLANK_DURATION(duration)									\
178 	machine->vblank_duration = (duration);								\
179 
180 #define MDRV_INTERLEAVE(interleave)										\
181 	machine->cpu_slices_per_frame = (interleave);						\
182 
183 
184 /* core functions */
185 #define MDRV_MACHINE_INIT(name)											\
186 	machine->machine_init = machine_init_##name;						\
187 
188 #define MDRV_MACHINE_STOP(name)											\
189 	machine->machine_stop = machine_stop_##name;						\
190 
191 #define MDRV_NVRAM_HANDLER(name)										\
192 	machine->nvram_handler = nvram_handler_##name;						\
193 
194 
195 /* core video parameters */
196 #define MDRV_VIDEO_ATTRIBUTES(flags)									\
197 	machine->video_attributes = (flags);								\
198 
199 #define MDRV_ASPECT_RATIO(num, den)										\
200 	machine->aspect_x = (num);											\
201 	machine->aspect_y = (den);											\
202 
203 #define MDRV_SCREEN_SIZE(width, height)									\
204 	machine->screen_width = (width);									\
205 	machine->screen_height = (height);									\
206 
207 #define MDRV_VISIBLE_AREA(minx, maxx, miny, maxy)						\
208 	machine->default_visible_area.min_x = (minx);						\
209 	machine->default_visible_area.max_x = (maxx);						\
210 	machine->default_visible_area.min_y = (miny);						\
211 	machine->default_visible_area.max_y = (maxy);						\
212 
213 #define MDRV_GFXDECODE(gfx)												\
214 	machine->gfxdecodeinfo = (gfx);										\
215 
216 #define MDRV_PALETTE_LENGTH(length)										\
217 	machine->total_colors = (length);									\
218 
219 #define MDRV_COLORTABLE_LENGTH(length)									\
220 	machine->color_table_len = (length);								\
221 
222 
223 /* core video functions */
224 #define MDRV_PALETTE_INIT(name)											\
225 	machine->init_palette = palette_init_##name;						\
226 
227 #define MDRV_VIDEO_START(name)											\
228 	machine->video_start = video_start_##name;							\
229 
230 #define MDRV_VIDEO_STOP(name)											\
231 	machine->video_stop = video_stop_##name;							\
232 
233 #define MDRV_VIDEO_EOF(name)											\
234 	machine->video_eof = video_eof_##name;								\
235 
236 #define MDRV_VIDEO_UPDATE(name)											\
237 	machine->video_update = video_update_##name;						\
238 
239 
240 /* core sound parameters */
241 #define MDRV_SOUND_ATTRIBUTES(flags)									\
242 	machine->sound_attributes = (flags);								\
243 
244 
245 /* add/remove/replace sounds */
246 #define MDRV_SOUND_ADD_TAG(tag, type, interface)						\
247 	machine_add_sound(machine, (tag), SOUND_##type, &(interface));		\
248 
249 #define MDRV_SOUND_ADD(type, interface)									\
250 	MDRV_SOUND_ADD_TAG(NULL, type, interface)							\
251 
252 #define MDRV_SOUND_REMOVE(tag)											\
253 	machine_remove_sound(machine, tag);									\
254 
255 #define MDRV_SOUND_REPLACE(tag, type, interface)						\
256 	{																	\
257 		struct MachineSound *sound = machine_find_sound(machine, tag);	\
258 		if (sound)														\
259 		{																\
260 			sound->sound_type = SOUND_##type;							\
261 			sound->sound_interface = &(interface);						\
262 		}																\
263 	}																	\
264 
265 
266 struct MachineCPU *machine_add_cpu(struct InternalMachineDriver *machine, const char *tag, int type, int cpuclock);
267 struct MachineCPU *machine_find_cpu(struct InternalMachineDriver *machine, const char *tag);
268 void machine_remove_cpu(struct InternalMachineDriver *machine, const char *tag);
269 
270 struct MachineSound *machine_add_sound(struct InternalMachineDriver *machine, const char *tag, int type, void *sndintf);
271 struct MachineSound *machine_find_sound(struct InternalMachineDriver *machine, const char *tag);
272 void machine_remove_sound(struct InternalMachineDriver *machine, const char *tag);
273 
274 
275 
276 /***************************************************************************
277 
278 	Internal representation of a machine driver, built from the constructor
279 
280 ***************************************************************************/
281 
282 #define MAX_CPU 8	/* MAX_CPU is the maximum number of CPUs which cpuintrf.c */
283 					/* can run at the same time. Currently, 8 is enough. */
284 
285 #define MAX_SOUND 5	/* MAX_SOUND is the maximum number of sound subsystems */
286 					/* which can run at the same time. Currently, 5 is enough. */
287 
288 struct InternalMachineDriver
289 {
290 	struct MachineCPU cpu[MAX_CPU];
291 	float frames_per_second;
292 	int vblank_duration;
293 	UINT32 cpu_slices_per_frame;
294 
295 	void (*machine_init)(void);
296 	void (*machine_stop)(void);
297 	void (*nvram_handler)(mame_file *file, int read_or_write);
298 
299 	UINT32 video_attributes;
300 	UINT32 aspect_x, aspect_y;
301 	int screen_width,screen_height;
302 	struct rectangle default_visible_area;
303 	struct GfxDecodeInfo *gfxdecodeinfo;
304 	UINT32 total_colors;
305 	UINT32 color_table_len;
306 
307 	void (*init_palette)(UINT16 *colortable,const UINT8 *color_prom);
308 	int (*video_start)(void);
309 	void (*video_stop)(void);
310 	void (*video_eof)(void);
311 	void (*video_update)(struct mame_bitmap *bitmap,const struct rectangle *cliprect);
312 
313 	UINT32 sound_attributes;
314 	struct MachineSound sound[MAX_SOUND+1]; /* add one code is assuming its +1 in a lot of places and is causing overflows */
315 };
316 
317 
318 
319 /***************************************************************************
320 
321 	Machine driver constants and flags
322 
323 ***************************************************************************/
324 
325 /* VBlank is the period when the video beam is outside of the visible area and */
326 /* returns from the bottom to the top of the screen to prepare for a new video frame. */
327 /* VBlank duration is an important factor in how the game renders itself. MAME */
328 /* generates the vblank_interrupt, lets the game run for vblank_duration microseconds, */
329 /* and then updates the screen. This faithfully reproduces the behaviour of the real */
330 /* hardware. In many cases, the game does video related operations both in its vblank */
331 /* interrupt, and in the normal game code; it is therefore important to set up */
332 /* vblank_duration accurately to have everything properly in sync. An example of this */
333 /* is Commando: if you set vblank_duration to 0, therefore redrawing the screen BEFORE */
334 /* the vblank interrupt is executed, sprites will be misaligned when the screen scrolls. */
335 
336 /* Here are some predefined, TOTALLY ARBITRARY values for vblank_duration, which should */
337 /* be OK for most cases. I have NO IDEA how accurate they are compared to the real */
338 /* hardware, they could be completely wrong. */
339 #define DEFAULT_60HZ_VBLANK_DURATION 0
340 #define DEFAULT_30HZ_VBLANK_DURATION 0
341 /* If you use IPT_VBLANK, you need a duration different from 0. */
342 #define DEFAULT_REAL_60HZ_VBLANK_DURATION 2500
343 #define DEFAULT_REAL_30HZ_VBLANK_DURATION 2500
344 
345 
346 /* ----- flags for video_attributes ----- */
347 
348 /* bit 0 of the video attributes indicates raster or vector video hardware */
349 #define	VIDEO_TYPE_RASTER			0x0000
350 #define	VIDEO_TYPE_VECTOR			0x0001
351 
352 /* bit 3 of the video attributes indicates that the game's palette has 6 or more bits */
353 /*       per gun, and would therefore require a 24-bit display. This is entirely up to */
354 /*       the OS dependant layer, the bitmap will still be 16-bit. */
355 #define VIDEO_NEEDS_6BITS_PER_GUN	0x0008
356 
357 /* ASG 980417 - added: */
358 /* bit 4 of the video attributes indicates that the driver wants its refresh after */
359 /*       the VBLANK instead of before. */
360 #define	VIDEO_UPDATE_BEFORE_VBLANK	0x0000
361 #define	VIDEO_UPDATE_AFTER_VBLANK	0x0010
362 
363 /* In most cases we assume pixels are square (1:1 aspect ratio) but some games need */
364 /* different proportions, e.g. 1:2 for Blasteroids */
365 #define VIDEO_PIXEL_ASPECT_RATIO_MASK 0x0060
366 #define VIDEO_PIXEL_ASPECT_RATIO_1_1 0x0000
367 #define VIDEO_PIXEL_ASPECT_RATIO_1_2 0x0020
368 #define VIDEO_PIXEL_ASPECT_RATIO_2_1 0x0040
369 
370 #define VIDEO_DUAL_MONITOR			0x0080
371 
372 /* Mish 181099:  See comments in vidhrdw/generic.c for details */
373 #define VIDEO_BUFFERS_SPRITERAM		0x0100
374 
375 /* game wants to use a hicolor or truecolor bitmap (e.g. for alpha blending) */
376 #define VIDEO_RGB_DIRECT 			0x0200
377 
378 /* automatically extend the palette creating a darker copy for shadows */
379 #define VIDEO_HAS_SHADOWS			0x0400
380 
381 /* automatically extend the palette creating a brighter copy for highlights */
382 #define VIDEO_HAS_HIGHLIGHTS		0x0800
383 
384 
385 /* ----- flags for sound_attributes ----- */
386 #define	SOUND_SUPPORTS_STEREO		0x0001
387 
388 
389 
390 /***************************************************************************
391 
392 	Game driver structure
393 
394 ***************************************************************************/
395 
396 struct GameDriver
397 {
398   const char   *source_file;          /* set this to __FILE__ */
399   const struct GameDriver *clone_of;	/* if this is a clone, point to */
400                                       /* the main version of the game */
401   const char *name;
402   const struct SystemBios *bios;      /* if this system has alternate bios roms use this */
403                                       /* structure to list names and ROM_BIOSFLAGS. */
404   const char *description;
405   const char *year;
406   const char *manufacturer;
407   void (*drv)(struct InternalMachineDriver *);
408   const struct InputPortTiny *input_ports;
409   void (*driver_init)(void);          /* optional function to be called during initialization */
410                                       /* This is called ONCE, unlike Machine->init_machine */
411                                       /* which is called every time the game is reset. */
412   const struct RomModule *rom;
413 
414   UINT32 flags;	/* orientation and other flags; see defines below */
415 
416   const struct ControlInfo *ctrl_dat;
417   const struct bin2cFILE *bootstrap;
418 };
419 
420 
421 
422 /***************************************************************************
423 
424 	Game driver flags
425 
426 ***************************************************************************/
427 
428 /* ----- values for the flags field ----- */
429 
430 #define ORIENTATION_MASK        	  0x0007
431 #define	ORIENTATION_FLIP_X			    0x0001	/* mirror everything in the X direction */
432 #define	ORIENTATION_FLIP_Y			    0x0002	/* mirror everything in the Y direction */
433 #define ORIENTATION_SWAP_XY			    0x0004	/* mirror along the top-left/bottom-right diagonal */
434 
435 #define GAME_NOT_WORKING			      0x0008
436 #define GAME_UNEMULATED_PROTECTION	0x0010	/* game's protection not fully emulated */
437 #define GAME_WRONG_COLORS           0x0020	/* colors are totally wrong */
438 #define GAME_IMPERFECT_COLORS       0x0040	/* colors are not 100% accurate, but close */
439 #define GAME_IMPERFECT_GRAPHICS     0x0080	/* graphics are wrong/incomplete */
440 #define GAME_NO_COCKTAIL            0x0100	/* screen flip support is missing */
441 #define GAME_NO_SOUND               0x0200	/* sound is missing */
442 #define GAME_IMPERFECT_SOUND        0x0400	/* sound is known to be wrong */
443 #define GAME_DOESNT_SERIALIZE       0x0420  /* game can not be saved through serailization */
444 #define NOT_A_DRIVER                0x4000	/* set by the fake "root" driver_0 and by "containers" */
445                                             /* e.g. driver_neogeo. */
446 
447 
448 /***************************************************************************
449 
450   Macros for building game drivers
451 
452 ***************************************************************************/
453 
454 #define GAME(YEAR, NAME, PARENT, MACHINE, INPUT, INIT, MONITOR, COMPANY, FULLNAME)  \
455 extern const struct GameDriver driver_##PARENT;  \
456 const struct GameDriver driver_##NAME =          \
457 {                       \
458   __FILE__,             \
459   &driver_##PARENT,     \
460   #NAME,                \
461   system_bios_0,        \
462   FULLNAME,             \
463   #YEAR,                \
464   COMPANY,              \
465   construct_##MACHINE,  \
466   input_ports_##INPUT,  \
467   init_##INIT,          \
468   rom_##NAME,           \
469   MONITOR,              \
470   (&generic_ctrl), \
471   NULL                  \
472 };
473 
474 #define GAMEX(YEAR, NAME, PARENT, MACHINE, INPUT, INIT, MONITOR, COMPANY, FULLNAME, FLAGS)  \
475 extern const struct GameDriver driver_##PARENT;   \
476 const struct GameDriver driver_##NAME =           \
477 {                       \
478   __FILE__,             \
479   &driver_##PARENT,     \
480   #NAME,                \
481   system_bios_0,        \
482   FULLNAME,             \
483   #YEAR,                \
484   COMPANY,              \
485   construct_##MACHINE,  \
486   input_ports_##INPUT,  \
487   init_##INIT,          \
488   rom_##NAME,           \
489   (MONITOR)|(FLAGS),    \
490   (&generic_ctrl), \
491   NULL                  \
492 };
493 
494 #define GAMEC(YEAR, NAME, PARENT, MACHINE, INPUT, INIT, MONITOR, COMPANY, FULLNAME, CTRL_INFO, BOOTSTRAP)  \
495 extern const struct GameDriver driver_##PARENT;  \
496 const struct GameDriver driver_##NAME =          \
497 {                       \
498   __FILE__,             \
499   &driver_##PARENT,     \
500   #NAME,                \
501   system_bios_0,        \
502   FULLNAME,             \
503   #YEAR,                \
504   COMPANY,              \
505   construct_##MACHINE,  \
506   input_ports_##INPUT,  \
507   init_##INIT,          \
508   rom_##NAME,           \
509   MONITOR,              \
510   CTRL_INFO,            \
511   BOOTSTRAP             \
512 };
513 
514 #define GAMECX(YEAR, NAME, PARENT, MACHINE, INPUT, INIT, MONITOR, COMPANY, FULLNAME, FLAGS, CTRL_INFO, BOOTSTRAP)  \
515 extern const struct GameDriver driver_##PARENT;   \
516 const struct GameDriver driver_##NAME =           \
517 {                       \
518   __FILE__,             \
519   &driver_##PARENT,     \
520   #NAME,                \
521   system_bios_0,        \
522   FULLNAME,             \
523   #YEAR,                \
524   COMPANY,              \
525   construct_##MACHINE,  \
526   input_ports_##INPUT,  \
527   init_##INIT,          \
528   rom_##NAME,           \
529   (MONITOR)|(FLAGS),    \
530   CTRL_INFO,            \
531   BOOTSTRAP             \
532 };
533 
534 #define GAMEB(YEAR, NAME, PARENT, BIOS, MACHINE, INPUT, INIT, MONITOR, COMPANY, FULLNAME, CTRL_INFO, BOOTSTRAP)  \
535 extern const struct GameDriver driver_##PARENT;    \
536 const struct GameDriver driver_##NAME =            \
537 {                       \
538   __FILE__,             \
539   &driver_##PARENT,     \
540   #NAME,                \
541   system_bios_##BIOS,   \
542   FULLNAME,             \
543   #YEAR,                \
544   COMPANY,              \
545   construct_##MACHINE,  \
546   input_ports_##INPUT,  \
547   init_##INIT,          \
548   rom_##NAME,           \
549   MONITOR,              \
550   CTRL_INFO,          \
551   BOOTSTRAP             \
552 };
553 
554 #define GAMEBX(YEAR, NAME, PARENT, BIOS, MACHINE, INPUT, INIT, MONITOR, COMPANY, FULLNAME, FLAGS, BTN_LABELER, BOOTSTRAP)  \
555 extern const struct GameDriver driver_##PARENT;  \
556 const struct GameDriver driver_##NAME =          \
557 {                       \
558   __FILE__,             \
559   &driver_##PARENT,     \
560   #NAME,                \
561   system_bios_##BIOS,   \
562   FULLNAME,             \
563   #YEAR,                \
564   COMPANY,              \
565   construct_##MACHINE,  \
566   input_ports_##INPUT,  \
567   init_##INIT,          \
568   rom_##NAME,           \
569   (MONITOR)|(FLAGS),    \
570   BTN_LABELER,          \
571   BOOTSTRAP             \
572 };
573 
574 /* monitor parameters to be used with the GAME() macro */
575 #define	ROT0    0
576 #define	ROT90   (ORIENTATION_SWAP_XY | ORIENTATION_FLIP_X)	/* rotate clockwise 90 degrees */
577 #define	ROT180  (ORIENTATION_FLIP_X  | ORIENTATION_FLIP_Y)		/* rotate 180 degrees */
578 #define	ROT270  (ORIENTATION_SWAP_XY | ORIENTATION_FLIP_Y)	/* rotate counter-clockwise 90 degrees */
579 
580 /* this allows to leave the INIT field empty in the GAME() macro call */
581 #define init_0 0
582 
583 /* this allows to leave the BIOS field empty in the GAMEB() macro call */
584 #define system_bios_0 0
585 
586 
587 /***************************************************************************
588 
589 	Global variables
590 
591 ***************************************************************************/
592 
593 extern const struct GameDriver *drivers[];
594 extern const struct GameDriver *test_drivers[];
595 
596 extern const int total_drivers;
597 
598 extern unsigned activate_dcs_speedhack;
599 
600 #endif
601