38
38
***************************************************************************/
45
//**************************************************************************
47
//**************************************************************************
49
//-------------------------------------------------
50
// driver_list - constructor
51
//-------------------------------------------------
53
driver_list::driver_list()
58
//-------------------------------------------------
59
// find - find a driver by name
60
//-------------------------------------------------
62
int driver_list::find(const char *name)
68
// create a dummy item for comparison purposes
71
game_driver *driverptr = &driver;
73
// binary search to find it
74
const game_driver **result = reinterpret_cast<const game_driver **>(bsearch(&driverptr, s_drivers_sorted, s_driver_count, sizeof(*s_drivers_sorted), driver_sort_callback));
75
return (result == NULL) ? -1 : result - s_drivers_sorted;
79
//-------------------------------------------------
80
// matches - true if we match, taking into
81
// account wildcards in the wildstring
82
//-------------------------------------------------
84
bool driver_list::matches(const char *wildstring, const char *string)
86
// can only match internal drivers if the wildstring starts with an underscore
87
if (string[0] == '_' && (wildstring == NULL || wildstring[0] != '_'))
90
// match everything else normally
91
return (wildstring == NULL || mame_strwildcmp(wildstring, string) == 0);
95
//-------------------------------------------------
96
// driver_sort_callback - compare two items in
97
// an array of game_driver pointers
98
//-------------------------------------------------
100
int driver_list::driver_sort_callback(const void *elem1, const void *elem2)
102
const game_driver * const *item1 = reinterpret_cast<const game_driver * const *>(elem1);
103
const game_driver * const *item2 = reinterpret_cast<const game_driver * const *>(elem2);
104
return mame_stricmp((*item1)->name, (*item2)->name);
108
//-------------------------------------------------
109
// penalty_compare - compare two strings for
110
// closeness and assign a score.
111
//-------------------------------------------------
113
int driver_list::penalty_compare(const char *source, const char *target)
119
for ( ; *source && *target; target++)
121
// do a case insensitive match
122
bool match = (tolower((UINT8)*source) == tolower((UINT8)*target));
124
// if we matched, advance the source
128
// if the match state changed, count gaps
137
// penalty if short string does not completely fit in
138
for ( ; *source; source++)
141
// if we matched perfectly, gaps == 0
142
if (gaps == 1 && *source == 0 && *target == 0)
150
//**************************************************************************
152
//**************************************************************************
154
//-------------------------------------------------
155
// driver_enumerator - constructor
156
//-------------------------------------------------
158
driver_enumerator::driver_enumerator(emu_options &options)
162
m_included(global_alloc_array(UINT8, s_driver_count)),
163
m_config(global_alloc_array_clear(machine_config *, s_driver_count))
169
driver_enumerator::driver_enumerator(emu_options &options, const char *string)
173
m_included(global_alloc_array(UINT8, s_driver_count)),
174
m_config(global_alloc_array_clear(machine_config *, s_driver_count))
180
driver_enumerator::driver_enumerator(emu_options &options, const game_driver &driver)
184
m_included(global_alloc_array(UINT8, s_driver_count)),
185
m_config(global_alloc_array_clear(machine_config *, s_driver_count))
191
//-------------------------------------------------
192
// ~driver_enumerator - destructor
193
//-------------------------------------------------
195
driver_enumerator::~driver_enumerator()
198
for (int index = 0; index < s_driver_count; index++)
199
global_free(m_config[index]);
202
global_free(m_included);
203
global_free(m_config);
207
//-------------------------------------------------
208
// config - return a machine_config for the given
209
// driver, allocating on demand if needed
210
//-------------------------------------------------
212
machine_config &driver_enumerator::config(int index, emu_options &options) const
214
assert(index >= 0 && index < s_driver_count);
216
// if we don't have it cached, add it
217
if (m_config[index] == NULL)
219
// if our cache is full, release the head entry
220
if (m_config_cache.count() == CONFIG_CACHE_COUNT)
222
config_entry *first = m_config_cache.first();
223
m_config[first->index()] = NULL;
224
m_config_cache.remove(*first);
227
// allocate the config and add it to the end of the list
228
machine_config *config = m_config[index] = global_alloc(machine_config(*s_drivers_sorted[index], options));
229
m_config_cache.append(*global_alloc(config_entry(*config, index)));
231
return *m_config[index];
235
//-------------------------------------------------
236
// filter - filter the driver list against the
238
//-------------------------------------------------
240
int driver_enumerator::filter(const char *filterstring)
245
// match name against each driver in the list
246
for (int index = 0; index < s_driver_count; index++)
247
if (matches(filterstring, s_drivers_sorted[index]->name))
250
return m_filtered_count;
254
//-------------------------------------------------
255
// filter - filter the driver list against the
257
//-------------------------------------------------
259
int driver_enumerator::filter(const game_driver &driver)
264
// match name against each driver in the list
265
for (int index = 0; index < s_driver_count; index++)
266
if (s_drivers_sorted[index] == &driver)
269
return m_filtered_count;
273
//-------------------------------------------------
274
// include_all - include all non-internal drivers
275
//-------------------------------------------------
277
void driver_enumerator::include_all()
279
memset(m_included, 1, sizeof(m_included[0]) * s_driver_count); m_filtered_count = s_driver_count;
280
int empty = find("___empty");
282
m_included[empty] = 0;
286
//-------------------------------------------------
287
// next - get the next driver matching the given
289
//-------------------------------------------------
291
bool driver_enumerator::next()
293
// always advance one
296
// if we have a filter, scan forward to the next match
297
while (m_current < s_driver_count)
299
if (m_included[m_current])
304
// return true if we end up in range
305
return (m_current >= 0 && m_current < s_driver_count);
309
//-------------------------------------------------
310
// next_excluded - get the next driver that is
311
// not currently included in the list
312
//-------------------------------------------------
314
bool driver_enumerator::next_excluded()
316
// always advance one
319
// if we have a filter, scan forward to the next match
320
while (m_current < s_driver_count)
322
if (!m_included[m_current])
327
// return true if we end up in range
328
return (m_current >= 0 && m_current < s_driver_count);
332
//-------------------------------------------------
333
// driver_sort_callback - compare two items in
334
// an array of game_driver pointers
335
//-------------------------------------------------
337
void driver_enumerator::find_approximate_matches(const char *string, int count, int *results)
341
// if no name, pick random entries
342
if (string == NULL || string[0] == 0)
344
// seed the RNG first
347
// allocate a temporary list
348
int *templist = global_alloc_array(int, m_filtered_count);
350
for (int index = 0; index < s_driver_count; index++)
351
if (m_included[index])
352
templist[arrayindex++] = index;
353
assert(arrayindex == m_filtered_count);
356
for (int shufnum = 0; shufnum < 4 * s_driver_count; shufnum++)
358
int item1 = rand() % m_filtered_count;
359
int item2 = rand() % m_filtered_count;
360
int temp = templist[item1];
361
templist[item1] = templist[item2];
362
templist[item2] = temp;
365
// copy out the first few entries
366
for (int matchnum = 0; matchnum < count; matchnum++)
367
results[matchnum] = templist[matchnum % m_filtered_count];
369
global_free(templist);
373
// allocate memory to track the penalty value
374
int *penalty = global_alloc_array(int, count);
376
// initialize everyone's states
377
for (int matchnum = 0; matchnum < count; matchnum++)
379
penalty[matchnum] = 9999;
380
results[matchnum] = -1;
383
// scan the entire drivers array
384
for (int index = 0; index < s_driver_count; index++)
385
if (m_included[index])
387
// skip things that can't run
388
if ((s_drivers_sorted[index]->flags & GAME_NO_STANDALONE) != 0)
391
// pick the best match between driver name and description
392
int curpenalty = penalty_compare(string, s_drivers_sorted[index]->description);
393
int tmp = penalty_compare(string, s_drivers_sorted[index]->name);
394
curpenalty = MIN(curpenalty, tmp);
396
// insert into the sorted table of matches
397
for (int matchnum = count - 1; matchnum >= 0; matchnum--)
399
// stop if we're worse than the current entry
400
if (curpenalty >= penalty[matchnum])
403
// as long as this isn't the last entry, bump this one down
404
if (matchnum < count - 1)
406
penalty[matchnum + 1] = penalty[matchnum];
407
results[matchnum + 1] = results[matchnum];
409
results[matchnum] = index;
410
penalty[matchnum] = curpenalty;
414
// free our temp memory
415
global_free(penalty);
419
driver_enumerator::config_entry::config_entry(machine_config &config, int index)
427
driver_enumerator::config_entry::~config_entry()
429
global_free(m_config);
44
//**************************************************************************
46
//**************************************************************************
48
//-------------------------------------------------
49
// driver_device - constructor
50
//-------------------------------------------------
52
driver_device::driver_device(const machine_config &mconfig, device_type type, const char *tag)
53
: device_t(mconfig, type, "Driver Device", tag, NULL, 0),
54
m_generic_paletteram_8(*this, "paletteram"),
55
m_generic_paletteram2_8(*this, "paletteram2"),
56
m_generic_paletteram_16(*this, "paletteram"),
57
m_generic_paletteram2_16(*this, "paletteram2"),
58
m_generic_paletteram_32(*this, "paletteram"),
59
m_generic_paletteram2_32(*this, "paletteram2"),
61
m_latch_clear_value(0),
65
memset(m_legacy_callbacks, 0, sizeof(m_legacy_callbacks));
66
memset(m_latched_value, 0, sizeof(m_latched_value));
67
memset(m_latch_read, 0, sizeof(m_latch_read));
71
//-------------------------------------------------
72
// driver_device - destructor
73
//-------------------------------------------------
75
driver_device::~driver_device()
80
//-------------------------------------------------
81
// static_set_game - set the game in the device
83
//-------------------------------------------------
85
void driver_device::static_set_game(device_t &device, const game_driver &game)
87
driver_device &driver = downcast<driver_device &>(device);
90
driver.m_system = &game;
92
// set the short name to the game's name
93
driver.m_shortname = game.name;
95
// set the full name to the game's description
96
driver.m_name = game.description;
98
// and set the search path to include all parents
99
driver.m_searchpath = game.name;
100
for (int parent = driver_list::clone(game); parent != -1; parent = driver_list::clone(parent))
101
driver.m_searchpath.cat(";").cat(driver_list::driver(parent).name);
105
//-------------------------------------------------
106
// static_set_callback - set the a callback in
107
// the device configuration
108
//-------------------------------------------------
110
void driver_device::static_set_callback(device_t &device, callback_type type, legacy_callback_func callback)
112
downcast<driver_device &>(device).m_legacy_callbacks[type] = callback;
115
void driver_device::static_set_callback(device_t &device, callback_type type, driver_callback_delegate callback)
117
downcast<driver_device &>(device).m_callbacks[type] = callback;
121
//-------------------------------------------------
122
// driver_start - default implementation which
124
//-------------------------------------------------
126
void driver_device::driver_start()
131
//-------------------------------------------------
132
// machine_start - default implementation which
133
// calls to the legacy machine_start function
134
//-------------------------------------------------
136
void driver_device::machine_start()
141
//-------------------------------------------------
142
// sound_start - default implementation which
143
// calls to the legacy sound_start function
144
//-------------------------------------------------
146
void driver_device::sound_start()
151
//-------------------------------------------------
152
// palette_init - default implementation which
154
//-------------------------------------------------
156
void driver_device::palette_init()
161
//-------------------------------------------------
162
// video_start - default implementation which
163
// calls to the legacy video_start function
164
//-------------------------------------------------
166
void driver_device::video_start()
171
//-------------------------------------------------
172
// driver_reset - default implementation which
174
//-------------------------------------------------
176
void driver_device::driver_reset()
181
//-------------------------------------------------
182
// machine_reset - default implementation which
183
// calls to the legacy machine_reset function
184
//-------------------------------------------------
186
void driver_device::machine_reset()
191
//-------------------------------------------------
192
// sound_reset - default implementation which
193
// calls to the legacy sound_reset function
194
//-------------------------------------------------
196
void driver_device::sound_reset()
201
//-------------------------------------------------
202
// video_reset - default implementation which
203
// calls to the legacy video_reset function
204
//-------------------------------------------------
206
void driver_device::video_reset()
211
//-------------------------------------------------
212
// device_rom_region - return a pointer to the
214
//-------------------------------------------------
216
const rom_entry *driver_device::device_rom_region() const
218
return m_system->rom;
222
//-------------------------------------------------
223
// device_input_ports - return a pointer to the
224
// game's input ports
225
//-------------------------------------------------
227
ioport_constructor driver_device::device_input_ports() const
229
return m_system->ipt;
233
//-------------------------------------------------
234
// device_start - device override which calls
235
// the various helpers
236
//-------------------------------------------------
238
void driver_device::device_start()
240
// bind our legacy callbacks
241
for (int index = 0; index < ARRAY_LENGTH(m_legacy_callbacks); index++)
242
if (m_legacy_callbacks[index] != NULL)
243
m_callbacks[index] = driver_callback_delegate(m_legacy_callbacks[index], "legacy_callback", &machine());
245
// reschedule ourselves to be last
246
device_iterator iter(*this);
247
for (device_t *test = iter.first(); test != NULL; test = iter.next())
248
if (test != this && !test->started())
249
throw device_missing_dependencies();
251
// call the game-specific init
252
if (m_system->driver_init != NULL)
253
(*m_system->driver_init)(machine());
255
// finish image devices init process
256
image_postdevice_init(machine());
258
// call palette_init if present
259
if (!m_callbacks[CB_PALETTE_INIT].isnull())
260
m_callbacks[CB_PALETTE_INIT]();
264
// start the various pieces
267
if (!m_callbacks[CB_MACHINE_START].isnull())
268
m_callbacks[CB_MACHINE_START]();
272
if (!m_callbacks[CB_SOUND_START].isnull())
273
m_callbacks[CB_SOUND_START]();
277
if (!m_callbacks[CB_VIDEO_START].isnull())
278
m_callbacks[CB_VIDEO_START]();
282
// save generic states
283
save_item(NAME(m_flip_screen_x));
284
save_item(NAME(m_flip_screen_y));
288
//-------------------------------------------------
289
// device_reset_after_children - device override
290
// which calls the various helpers; must happen
291
// after all child devices are reset
292
//-------------------------------------------------
294
void driver_device::device_reset_after_children()
299
if (!m_callbacks[CB_MACHINE_RESET].isnull())
300
m_callbacks[CB_MACHINE_RESET]();
304
if (!m_callbacks[CB_SOUND_RESET].isnull())
305
m_callbacks[CB_SOUND_RESET]();
309
if (!m_callbacks[CB_VIDEO_RESET].isnull())
310
m_callbacks[CB_VIDEO_RESET]();
317
//**************************************************************************
318
// INTERRUPT ENABLE AND VECTOR HELPERS
319
//**************************************************************************
321
//-------------------------------------------------
322
// irq_pulse_clear - clear a "pulsed" IRQ line
323
//-------------------------------------------------
325
void driver_device::irq_pulse_clear(void *ptr, INT32 param)
327
device_execute_interface *exec = reinterpret_cast<device_execute_interface *>(ptr);
329
exec->set_input_line(irqline, CLEAR_LINE);
333
//-------------------------------------------------
334
// generic_pulse_irq_line - "pulse" an IRQ line by
335
// asserting it and then clearing it x cycle(s)
337
//-------------------------------------------------
339
void driver_device::generic_pulse_irq_line(device_execute_interface &exec, int irqline, int cycles)
341
assert(irqline != INPUT_LINE_NMI && irqline != INPUT_LINE_RESET && cycles > 0);
342
exec.set_input_line(irqline, ASSERT_LINE);
344
attotime target_time = exec.local_time() + exec.cycles_to_attotime(cycles * exec.min_cycles());
345
machine().scheduler().timer_set(target_time - machine().time(), timer_expired_delegate(FUNC(driver_device::irq_pulse_clear), this), irqline, (void *)&exec);
349
//-------------------------------------------------
350
// generic_pulse_irq_line_and_vector - "pulse" an
351
// IRQ line by asserting it and then clearing it
352
// x cycle(s) later, specifying a vector
353
//-------------------------------------------------
355
void driver_device::generic_pulse_irq_line_and_vector(device_execute_interface &exec, int irqline, int vector, int cycles)
357
assert(irqline != INPUT_LINE_NMI && irqline != INPUT_LINE_RESET && cycles > 0);
358
exec.set_input_line_and_vector(irqline, ASSERT_LINE, vector);
360
attotime target_time = exec.local_time() + exec.cycles_to_attotime(cycles * exec.min_cycles());
361
machine().scheduler().timer_set(target_time - machine().time(), timer_expired_delegate(FUNC(driver_device::irq_pulse_clear), this), irqline, (void *)&exec);
366
//**************************************************************************
367
// INTERRUPT GENERATION CALLBACK HELPERS
368
//**************************************************************************
370
//-------------------------------------------------
372
//-------------------------------------------------
374
INTERRUPT_GEN_MEMBER( driver_device::nmi_line_pulse ) { device.execute().set_input_line(INPUT_LINE_NMI, PULSE_LINE); }
375
INTERRUPT_GEN_MEMBER( driver_device::nmi_line_assert ) { device.execute().set_input_line(INPUT_LINE_NMI, ASSERT_LINE); }
378
//-------------------------------------------------
380
//-------------------------------------------------
382
INTERRUPT_GEN_MEMBER( driver_device::irq0_line_hold ) { device.execute().set_input_line(0, HOLD_LINE); }
383
INTERRUPT_GEN_MEMBER( driver_device::irq0_line_pulse ) { generic_pulse_irq_line(device.execute(), 0, 1); }
384
INTERRUPT_GEN_MEMBER( driver_device::irq0_line_assert ) { device.execute().set_input_line(0, ASSERT_LINE); }
386
INTERRUPT_GEN_MEMBER( driver_device::irq1_line_hold ) { device.execute().set_input_line(1, HOLD_LINE); }
387
INTERRUPT_GEN_MEMBER( driver_device::irq1_line_pulse ) { generic_pulse_irq_line(device.execute(), 1, 1); }
388
INTERRUPT_GEN_MEMBER( driver_device::irq1_line_assert ) { device.execute().set_input_line(1, ASSERT_LINE); }
390
INTERRUPT_GEN_MEMBER( driver_device::irq2_line_hold ) { device.execute().set_input_line(2, HOLD_LINE); }
391
INTERRUPT_GEN_MEMBER( driver_device::irq2_line_pulse ) { generic_pulse_irq_line(device.execute(), 2, 1); }
392
INTERRUPT_GEN_MEMBER( driver_device::irq2_line_assert ) { device.execute().set_input_line(2, ASSERT_LINE); }
394
INTERRUPT_GEN_MEMBER( driver_device::irq3_line_hold ) { device.execute().set_input_line(3, HOLD_LINE); }
395
INTERRUPT_GEN_MEMBER( driver_device::irq3_line_pulse ) { generic_pulse_irq_line(device.execute(), 3, 1); }
396
INTERRUPT_GEN_MEMBER( driver_device::irq3_line_assert ) { device.execute().set_input_line(3, ASSERT_LINE); }
398
INTERRUPT_GEN_MEMBER( driver_device::irq4_line_hold ) { device.execute().set_input_line(4, HOLD_LINE); }
399
INTERRUPT_GEN_MEMBER( driver_device::irq4_line_pulse ) { generic_pulse_irq_line(device.execute(), 4, 1); }
400
INTERRUPT_GEN_MEMBER( driver_device::irq4_line_assert ) { device.execute().set_input_line(4, ASSERT_LINE); }
402
INTERRUPT_GEN_MEMBER( driver_device::irq5_line_hold ) { device.execute().set_input_line(5, HOLD_LINE); }
403
INTERRUPT_GEN_MEMBER( driver_device::irq5_line_pulse ) { generic_pulse_irq_line(device.execute(), 5, 1); }
404
INTERRUPT_GEN_MEMBER( driver_device::irq5_line_assert ) { device.execute().set_input_line(5, ASSERT_LINE); }
406
INTERRUPT_GEN_MEMBER( driver_device::irq6_line_hold ) { device.execute().set_input_line(6, HOLD_LINE); }
407
INTERRUPT_GEN_MEMBER( driver_device::irq6_line_pulse ) { generic_pulse_irq_line(device.execute(), 6, 1); }
408
INTERRUPT_GEN_MEMBER( driver_device::irq6_line_assert ) { device.execute().set_input_line(6, ASSERT_LINE); }
410
INTERRUPT_GEN_MEMBER( driver_device::irq7_line_hold ) { device.execute().set_input_line(7, HOLD_LINE); }
411
INTERRUPT_GEN_MEMBER( driver_device::irq7_line_pulse ) { generic_pulse_irq_line(device.execute(), 7, 1); }
412
INTERRUPT_GEN_MEMBER( driver_device::irq7_line_assert ) { device.execute().set_input_line(7, ASSERT_LINE); }
416
//**************************************************************************
417
// WATCHDOG READ/WRITE HELPERS
418
//**************************************************************************
420
//-------------------------------------------------
421
// 8-bit reset read/write handlers
422
//-------------------------------------------------
424
WRITE8_MEMBER( driver_device::watchdog_reset_w ) { machine().watchdog_reset(); }
425
READ8_MEMBER( driver_device::watchdog_reset_r ) { machine().watchdog_reset(); return space.unmap(); }
428
//-------------------------------------------------
429
// 16-bit reset read/write handlers
430
//-------------------------------------------------
432
WRITE16_MEMBER( driver_device::watchdog_reset16_w ) { machine().watchdog_reset(); }
433
READ16_MEMBER( driver_device::watchdog_reset16_r ) { machine().watchdog_reset(); return space.unmap(); }
436
//-------------------------------------------------
437
// 32-bit reset read/write handlers
438
//-------------------------------------------------
440
WRITE32_MEMBER( driver_device::watchdog_reset32_w ) { machine().watchdog_reset(); }
441
READ32_MEMBER( driver_device::watchdog_reset32_r ) { machine().watchdog_reset(); return space.unmap(); }
445
//**************************************************************************
446
// GENERIC SOUND COMMAND LATCHING
447
//**************************************************************************
449
//-------------------------------------------------
450
// soundlatch_sync_callback - time-delayed
451
// callback to set a latch value
452
//-------------------------------------------------
454
void driver_device::soundlatch_sync_callback(void *ptr, INT32 param)
456
UINT16 value = param >> 8;
457
int which = param & 0xff;
459
// if the latch hasn't been read and the value is changed, log a warning
460
if (!m_latch_read[which] && m_latched_value[which] != value)
461
logerror("Warning: sound latch %d written before being read. Previous: %02x, new: %02x\n", which, m_latched_value[which], value);
463
// store the new value and mark it not read
464
m_latched_value[which] = value;
465
m_latch_read[which] = 0;
469
//-------------------------------------------------
470
// soundlatch_byte_w - global write handlers for
471
// writing to sound latches
472
//-------------------------------------------------
474
WRITE8_MEMBER( driver_device::soundlatch_byte_w ) { machine().scheduler().synchronize(timer_expired_delegate(FUNC(driver_device::soundlatch_sync_callback), this), 0 | (data << 8)); }
475
WRITE16_MEMBER( driver_device::soundlatch_word_w ) { machine().scheduler().synchronize(timer_expired_delegate(FUNC(driver_device::soundlatch_sync_callback), this), 0 | (data << 8)); }
476
WRITE8_MEMBER( driver_device::soundlatch2_byte_w ) { machine().scheduler().synchronize(timer_expired_delegate(FUNC(driver_device::soundlatch_sync_callback), this), 1 | (data << 8)); }
477
WRITE16_MEMBER( driver_device::soundlatch2_word_w ) { machine().scheduler().synchronize(timer_expired_delegate(FUNC(driver_device::soundlatch_sync_callback), this), 1 | (data << 8)); }
478
WRITE8_MEMBER( driver_device::soundlatch3_byte_w ) { machine().scheduler().synchronize(timer_expired_delegate(FUNC(driver_device::soundlatch_sync_callback), this), 2 | (data << 8)); }
479
WRITE16_MEMBER( driver_device::soundlatch3_word_w ) { machine().scheduler().synchronize(timer_expired_delegate(FUNC(driver_device::soundlatch_sync_callback), this), 2 | (data << 8)); }
480
WRITE8_MEMBER( driver_device::soundlatch4_byte_w ) { machine().scheduler().synchronize(timer_expired_delegate(FUNC(driver_device::soundlatch_sync_callback), this), 3 | (data << 8)); }
481
WRITE16_MEMBER( driver_device::soundlatch4_word_w ) { machine().scheduler().synchronize(timer_expired_delegate(FUNC(driver_device::soundlatch_sync_callback), this), 3 | (data << 8)); }
484
//-------------------------------------------------
485
// soundlatch_byte_r - global read handlers for
486
// reading from sound latches
487
//-------------------------------------------------
489
READ8_MEMBER( driver_device::soundlatch_byte_r ) { return m_latched_value[0]; }
490
READ16_MEMBER( driver_device::soundlatch_word_r ) { return m_latched_value[0]; }
491
READ8_MEMBER( driver_device::soundlatch2_byte_r ) { return m_latched_value[1]; }
492
READ16_MEMBER( driver_device::soundlatch2_word_r ) { return m_latched_value[1]; }
493
READ8_MEMBER( driver_device::soundlatch3_byte_r ) { return m_latched_value[2]; }
494
READ16_MEMBER( driver_device::soundlatch3_word_r ) { return m_latched_value[2]; }
495
READ8_MEMBER( driver_device::soundlatch4_byte_r ) { return m_latched_value[3]; }
496
READ16_MEMBER( driver_device::soundlatch4_word_r ) { return m_latched_value[3]; }
499
//-------------------------------------------------
500
// soundlatch_clear_byte_w - global write handlers
501
// for clearing sound latches
502
//-------------------------------------------------
504
WRITE8_MEMBER( driver_device::soundlatch_clear_byte_w ) { m_latched_value[0] = m_latch_clear_value; }
505
WRITE8_MEMBER( driver_device::soundlatch2_clear_byte_w ) { m_latched_value[1] = m_latch_clear_value; }
506
WRITE8_MEMBER( driver_device::soundlatch3_clear_byte_w ) { m_latched_value[2] = m_latch_clear_value; }
507
WRITE8_MEMBER( driver_device::soundlatch4_clear_byte_w ) { m_latched_value[3] = m_latch_clear_value; }
511
//**************************************************************************
512
// GENERIC FLIP SCREEN HANDLING
513
//**************************************************************************
515
//-------------------------------------------------
516
// updateflip - handle global flipping
517
//-------------------------------------------------
519
void driver_device::updateflip()
521
// push the flip state to all tilemaps
522
machine().tilemap().set_flip_all((TILEMAP_FLIPX & m_flip_screen_x) | (TILEMAP_FLIPY & m_flip_screen_y));
524
// flip the visible area within the screen width/height
525
int width = machine().primary_screen->width();
526
int height = machine().primary_screen->height();
527
rectangle visarea = machine().primary_screen->visible_area();
530
int temp = width - visarea.min_x - 1;
531
visarea.min_x = width - visarea.max_x - 1;
532
visarea.max_x = temp;
536
int temp = height - visarea.min_y - 1;
537
visarea.min_y = height - visarea.max_y - 1;
538
visarea.max_y = temp;
541
// reconfigure the screen with the new visible area
542
attoseconds_t period = machine().primary_screen->frame_period().attoseconds;
543
machine().primary_screen->configure(width, height, visarea, period);
547
//-------------------------------------------------
548
// flip_screen_set - set global flip
549
//-------------------------------------------------
551
void driver_device::flip_screen_set(UINT32 on)
553
// normalize to all 1
557
// if something's changed, handle it
558
if (m_flip_screen_x != on || m_flip_screen_y != on)
561
updateflip(); // flip visarea back
562
m_flip_screen_x = m_flip_screen_y = on;
568
//-------------------------------------------------
569
// flip_screen_set_no_update - set global flip
570
// do not call update_flip.
571
//-------------------------------------------------
573
void driver_device::flip_screen_set_no_update(UINT32 on)
575
// flip_screen_y is not updated on purpose
576
// this function is for drivers which
577
// where writing to flip_screen_x to
578
// bypass update_flip
581
m_flip_screen_x = on;
585
//-------------------------------------------------
586
// flip_screen_x_set - set global horizontal flip
587
//-------------------------------------------------
589
void driver_device::flip_screen_x_set(UINT32 on)
591
// normalize to all 1
595
// if something's changed, handle it
596
if (m_flip_screen_x != on)
598
m_flip_screen_x = on;
604
//-------------------------------------------------
605
// flip_screen_y_set - set global vertical flip
606
//-------------------------------------------------
608
void driver_device::flip_screen_y_set(UINT32 on)
610
// normalize to all 1
614
// if something's changed, handle it
615
if (m_flip_screen_y != on)
617
m_flip_screen_y = on;
624
//**************************************************************************
625
// 8-BIT PALETTE WRITE HANDLERS
626
//**************************************************************************
628
// 3-3-2 RGB palette write handlers
629
WRITE8_MEMBER( driver_device::paletteram_BBGGGRRR_byte_w ) { palette_8bit_byte_w<3,3,2, 0,3,6>(space, offset, data, mem_mask); }
630
WRITE8_MEMBER( driver_device::paletteram_RRRGGGBB_byte_w ) { palette_8bit_byte_w<3,3,2, 5,2,0>(space, offset, data, mem_mask); }
631
WRITE8_MEMBER( driver_device::paletteram_BBGGRRII_byte_w )
633
m_generic_paletteram_8[offset] = data;
634
int i = (data >> 0) & 3;
635
palette_set_color_rgb(machine(), offset, pal4bit(((data >> 0) & 0x0c) | i),
636
pal4bit(((data >> 2) & 0x0c) | i),
637
pal4bit(((data >> 4) & 0x0c) | i));
642
//**************************************************************************
643
// 16-BIT PALETTE WRITE HANDLERS
644
//**************************************************************************
646
// 4-4-4 RGB palette write handlers
647
WRITE8_MEMBER( driver_device::paletteram_xxxxBBBBGGGGRRRR_byte_le_w ) { palette_16bit_byte_le_w<4,4,4, 0,4,8>(space, offset, data, mem_mask); }
648
WRITE8_MEMBER( driver_device::paletteram_xxxxBBBBGGGGRRRR_byte_be_w ) { palette_16bit_byte_be_w<4,4,4, 0,4,8>(space, offset, data, mem_mask); }
649
WRITE8_MEMBER( driver_device::paletteram_xxxxBBBBGGGGRRRR_byte_split_lo_w ) { palette_16bit_byte_split_lo_w<4,4,4, 0,4,8>(space, offset, data, mem_mask); }
650
WRITE8_MEMBER( driver_device::paletteram_xxxxBBBBGGGGRRRR_byte_split_hi_w ) { palette_16bit_byte_split_hi_w<4,4,4, 0,4,8>(space, offset, data, mem_mask); }
651
WRITE16_MEMBER( driver_device::paletteram_xxxxBBBBGGGGRRRR_word_w ) { palette_16bit_word_w<4,4,4, 0,4,8>(space, offset, data, mem_mask); }
653
WRITE8_MEMBER( driver_device::paletteram_xxxxBBBBRRRRGGGG_byte_le_w ) { palette_16bit_byte_le_w<4,4,4, 4,0,8>(space, offset, data, mem_mask); }
654
WRITE8_MEMBER( driver_device::paletteram_xxxxBBBBRRRRGGGG_byte_be_w ) { palette_16bit_byte_be_w<4,4,4, 4,0,8>(space, offset, data, mem_mask); }
655
WRITE8_MEMBER( driver_device::paletteram_xxxxBBBBRRRRGGGG_byte_split_lo_w ) { palette_16bit_byte_split_lo_w<4,4,4, 4,0,8>(space, offset, data, mem_mask); }
656
WRITE8_MEMBER( driver_device::paletteram_xxxxBBBBRRRRGGGG_byte_split_hi_w ) { palette_16bit_byte_split_hi_w<4,4,4, 4,0,8>(space, offset, data, mem_mask); }
657
WRITE16_MEMBER( driver_device::paletteram_xxxxBBBBRRRRGGGG_word_w ) { palette_16bit_word_w<4,4,4, 4,0,8>(space, offset, data, mem_mask); }
659
WRITE8_MEMBER( driver_device::paletteram_xxxxRRRRBBBBGGGG_byte_split_lo_w ) { palette_16bit_byte_split_lo_w<4,4,4, 8,0,4>(space, offset, data, mem_mask); }
660
WRITE8_MEMBER( driver_device::paletteram_xxxxRRRRBBBBGGGG_byte_split_hi_w ) { palette_16bit_byte_split_hi_w<4,4,4, 8,0,4>(space, offset, data, mem_mask); }
662
WRITE8_MEMBER( driver_device::paletteram_xxxxRRRRGGGGBBBB_byte_le_w ) { palette_16bit_byte_le_w<4,4,4, 8,4,0>(space, offset, data, mem_mask); }
663
WRITE8_MEMBER( driver_device::paletteram_xxxxRRRRGGGGBBBB_byte_be_w ) { palette_16bit_byte_be_w<4,4,4, 8,4,0>(space, offset, data, mem_mask); }
664
WRITE8_MEMBER( driver_device::paletteram_xxxxRRRRGGGGBBBB_byte_split_lo_w ) { palette_16bit_byte_split_lo_w<4,4,4, 8,4,0>(space, offset, data, mem_mask); }
665
WRITE8_MEMBER( driver_device::paletteram_xxxxRRRRGGGGBBBB_byte_split_hi_w ) { palette_16bit_byte_split_hi_w<4,4,4, 8,4,0>(space, offset, data, mem_mask); }
666
WRITE16_MEMBER( driver_device::paletteram_xxxxRRRRGGGGBBBB_word_w ) { palette_16bit_word_w<4,4,4, 8,4,0>(space, offset, data, mem_mask); }
668
WRITE8_MEMBER( driver_device::paletteram_RRRRGGGGBBBBxxxx_byte_be_w ) { palette_16bit_byte_be_w<4,4,4, 12,8,4>(space, offset, data, mem_mask); }
669
WRITE8_MEMBER( driver_device::paletteram_RRRRGGGGBBBBxxxx_byte_split_lo_w ) { palette_16bit_byte_split_lo_w<4,4,4, 12,8,4>(space, offset, data, mem_mask); }
670
WRITE8_MEMBER( driver_device::paletteram_RRRRGGGGBBBBxxxx_byte_split_hi_w ) { palette_16bit_byte_split_hi_w<4,4,4, 12,8,4>(space, offset, data, mem_mask); }
671
WRITE16_MEMBER( driver_device::paletteram_RRRRGGGGBBBBxxxx_word_w ) { palette_16bit_word_w<4,4,4, 12,8,4>(space, offset, data, mem_mask); }
673
// 4-4-4-4 IRGB palette write handlers
674
template<int _IShift, int _RShift, int _GShift, int _BShift>
675
inline void set_color_irgb(running_machine &machine, pen_t color, UINT16 data)
677
static const UINT8 ztable[16] = { 0x0, 0x3, 0x4, 0x5, 0x6, 0x7, 0x8, 0x9, 0xa, 0xb, 0xc, 0xd, 0xe, 0xf, 0x10, 0x11 };
678
UINT8 i = ztable[(data >> _IShift) & 15];
679
UINT8 r = ((data >> _RShift) & 15) * i;
680
UINT8 g = ((data >> _GShift) & 15) * i;
681
UINT8 b = ((data >> _BShift) & 15) * i;
682
palette_set_color_rgb(machine, color, r, g, b);
685
WRITE16_MEMBER( driver_device::paletteram_IIIIRRRRGGGGBBBB_word_w )
687
COMBINE_DATA(&m_generic_paletteram_16[offset]);
688
set_color_irgb<12,8,4,0>(machine(), offset, m_generic_paletteram_16[offset]);
691
WRITE16_MEMBER( driver_device::paletteram_RRRRGGGGBBBBIIII_word_w )
693
COMBINE_DATA(&m_generic_paletteram_16[offset]);
694
set_color_irgb<0,12,8,4>(machine(), offset, m_generic_paletteram_16[offset]);
697
// 5-5-5 RGB palette write handlers
698
WRITE8_MEMBER( driver_device::paletteram_xBBBBBGGGGGRRRRR_byte_le_w ) { palette_16bit_byte_le_w<5,5,5, 0,5,10>(space, offset, data, mem_mask); }
699
WRITE8_MEMBER( driver_device::paletteram_xBBBBBGGGGGRRRRR_byte_be_w ) { palette_16bit_byte_be_w<5,5,5, 0,5,10>(space, offset, data, mem_mask); }
700
WRITE8_MEMBER( driver_device::paletteram_xBBBBBGGGGGRRRRR_byte_split_lo_w ) { palette_16bit_byte_split_lo_w<5,5,5, 0,5,10>(space, offset, data, mem_mask); }
701
WRITE8_MEMBER( driver_device::paletteram_xBBBBBGGGGGRRRRR_byte_split_hi_w ) { palette_16bit_byte_split_hi_w<5,5,5, 0,5,10>(space, offset, data, mem_mask); }
702
WRITE16_MEMBER( driver_device::paletteram_xBBBBBGGGGGRRRRR_word_w ) { palette_16bit_word_w<5,5,5, 0,5,10>(space, offset, data, mem_mask); }
704
WRITE8_MEMBER( driver_device::paletteram_xBBBBBRRRRRGGGGG_byte_split_lo_w ) { palette_16bit_byte_split_lo_w<5,5,5, 5,0,10>(space, offset, data, mem_mask); }
705
WRITE8_MEMBER( driver_device::paletteram_xBBBBBRRRRRGGGGG_byte_split_hi_w ) { palette_16bit_byte_split_hi_w<5,5,5, 5,0,10>(space, offset, data, mem_mask); }
707
WRITE8_MEMBER( driver_device::paletteram_xRRRRRGGGGGBBBBB_byte_le_w ) { palette_16bit_byte_le_w<5,5,5, 10,5,0>(space, offset, data, mem_mask); }
708
WRITE8_MEMBER( driver_device::paletteram_xRRRRRGGGGGBBBBB_byte_be_w ) { palette_16bit_byte_be_w<5,5,5, 10,5,0>(space, offset, data, mem_mask); }
709
WRITE8_MEMBER( driver_device::paletteram_xRRRRRGGGGGBBBBB_byte_split_lo_w ) { palette_16bit_byte_split_lo_w<5,5,5, 10,5,0>(space, offset, data, mem_mask); }
710
WRITE8_MEMBER( driver_device::paletteram_xRRRRRGGGGGBBBBB_byte_split_hi_w ) { palette_16bit_byte_split_hi_w<5,5,5, 10,5,0>(space, offset, data, mem_mask); }
711
WRITE16_MEMBER( driver_device::paletteram_xRRRRRGGGGGBBBBB_word_w ) { palette_16bit_word_w<5,5,5, 10,5,0>(space, offset, data, mem_mask); }
712
WRITE32_MEMBER( driver_device::paletteram_xRRRRRGGGGGBBBBB_dword_be_w ) { palette_16bit_dword_be_w<5,5,5, 10,5,0>(space, offset, data, mem_mask); }
713
WRITE32_MEMBER( driver_device::paletteram_xRRRRRGGGGGBBBBB_dword_le_w ) { palette_16bit_dword_le_w<5,5,5, 10,5,0>(space, offset, data, mem_mask); }
715
WRITE8_MEMBER( driver_device::paletteram_xGGGGGRRRRRBBBBB_byte_le_w ) { palette_16bit_byte_le_w<5,5,5, 5,10,0>(space, offset, data, mem_mask); }
717
WRITE16_MEMBER( driver_device::paletteram_xGGGGGRRRRRBBBBB_word_w ) { palette_16bit_word_w<5,5,5, 5,10,0>(space, offset, data, mem_mask); }
718
WRITE16_MEMBER( driver_device::paletteram_xGGGGGBBBBBRRRRR_word_w ) { palette_16bit_word_w<5,5,5, 0,10,5>(space, offset, data, mem_mask); }
719
WRITE16_MEMBER( driver_device::paletteram_RRRRRGGGGGBBBBBx_word_w ) { palette_16bit_word_w<5,5,5, 11,6,1>(space, offset, data, mem_mask); }
720
WRITE16_MEMBER( driver_device::paletteram_GGGGGRRRRRBBBBBx_word_w ) { palette_16bit_word_w<5,5,5, 6,11,1>(space, offset, data, mem_mask); }
721
WRITE16_MEMBER( driver_device::paletteram_RRRRGGGGBBBBRGBx_word_w )
723
COMBINE_DATA(&m_generic_paletteram_16[offset]);
724
data = m_generic_paletteram_16[offset];
725
palette_set_color_rgb(machine(), offset, pal5bit(((data >> 11) & 0x1e) | ((data >> 3) & 0x01)),
726
pal5bit(((data >> 7) & 0x1e) | ((data >> 2) & 0x01)),
727
pal5bit(((data >> 3) & 0x1e) | ((data >> 1) & 0x01)));
731
//**************************************************************************
732
// 32-BIT PALETTE WRITE HANDLERS
733
//**************************************************************************
735
// 8-8-8 RGB palette write handlers
736
WRITE16_MEMBER( driver_device::paletteram_xrgb_word_be_w ) { palette_32bit_word_be_w<8,8,8, 16,8,0>(space, offset, data, mem_mask); }
737
WRITE16_MEMBER( driver_device::paletteram_xbgr_word_be_w ) { palette_32bit_word_be_w<8,8,8, 0,8,16>(space, offset, data, mem_mask); }