mirror of
https://github.com/holub/mame
synced 2025-04-25 09:50:04 +03:00
Changed DEVICE_START functions to return an error code. Currently this
is either DEVICE_START_OK or DEVICE_START_MISSING_DEPENDENCY. The latter should be returned by a device if there is another device it depends on which hasn't been started yet. Added new flag in the device interface to indicate whether a device has been started. Changed laserdisc interface to explicitly specify the screen and sound devices it should route to. Drivers no longer have to manually call laserdisc_vsync(). Instead, the laserdisc code connects up to the routed screen device and works based on that screen's VBLANK timing. Removed all existing calls to laserdisc_vsync(). Changed laserdisc behavior so that it completes the previous video read and initiates the next read at the end of VBLANK instead of the beginning. This gives player logic time during VBLANK to alter the slider position prior to fetching the next frame. Added new laserdisc callback for vsync begin and changed the update callback to be called at the end of VBLANK. Also added functions to set the slider speed, advance the slider, and directly control the video/ audio squelch. In addition, there is a new status function to get the slider position in general terms. Added parameter to the VBLANK callbacks supported in emu/video.c. Updated all callers to provide a callback value. Fixed bug that would cause watchpoints to trigger if you had a memory window open to the watchpoint address. Further updates to the PR-8210 ROM simulation. Still not quite there but the system is much better understood now. Added layout to the PR-8210 which displays the state of the front-panel LEDs.
This commit is contained in:
parent
bd8c06c155
commit
9b4e46fad5
1
.gitattributes
vendored
1
.gitattributes
vendored
@ -986,6 +986,7 @@ src/emu/video/voodoo.c svneol=native#text/plain
|
||||
src/emu/video/voodoo.h svneol=native#text/plain
|
||||
src/emu/watchdog.c svneol=native#text/plain
|
||||
src/emu/watchdog.h svneol=native#text/plain
|
||||
src/ldplayer/layout/pr8210.lay svneol=native#text/plain
|
||||
src/ldplayer/ldpdriv.c svneol=native#text/plain
|
||||
src/ldplayer/ldplayer.c svneol=native#text/plain
|
||||
src/ldplayer/ldplayer.mak svneol=native#text/plain
|
||||
|
@ -765,7 +765,7 @@ int cpu_getiloops(void)
|
||||
for this screen
|
||||
-------------------------------------------------*/
|
||||
|
||||
static void on_vblank(const device_config *device, int vblank_state)
|
||||
static void on_vblank(const device_config *device, void *param, int vblank_state)
|
||||
{
|
||||
/* VBLANK starting */
|
||||
if (vblank_state)
|
||||
@ -971,7 +971,7 @@ static void cpu_inittimers(running_machine *machine)
|
||||
|
||||
assert(screen != NULL);
|
||||
|
||||
video_screen_register_vblank_callback(screen, on_vblank);
|
||||
video_screen_register_vblank_callback(screen, on_vblank, NULL);
|
||||
}
|
||||
|
||||
/* periodic interrupts */
|
||||
|
@ -121,7 +121,7 @@ static const rgb_t crosshair_colors[] =
|
||||
***************************************************************************/
|
||||
|
||||
static void crosshair_exit(running_machine *machine);
|
||||
static void animate(const device_config *device, int vblank_state);
|
||||
static void animate(const device_config *device, void *param, int vblank_state);
|
||||
|
||||
|
||||
/***************************************************************************
|
||||
@ -212,7 +212,7 @@ void crosshair_init(running_machine *machine)
|
||||
|
||||
/* register the animation callback */
|
||||
if (machine->primary_screen != NULL)
|
||||
video_screen_register_vblank_callback(machine->primary_screen, animate);
|
||||
video_screen_register_vblank_callback(machine->primary_screen, animate, NULL);
|
||||
}
|
||||
|
||||
|
||||
@ -272,7 +272,7 @@ void crosshair_toggle(running_machine *machine)
|
||||
animate - animates the crosshair once a frame
|
||||
-------------------------------------------------*/
|
||||
|
||||
static void animate(const device_config *device, int vblank_state)
|
||||
static void animate(const device_config *device, void *param, int vblank_state)
|
||||
{
|
||||
int player;
|
||||
|
||||
|
@ -59,6 +59,7 @@ struct _debugger_private
|
||||
UINT8 within_instruction_hook;
|
||||
UINT8 vblank_occurred;
|
||||
UINT8 memory_modified;
|
||||
UINT8 debugger_access;
|
||||
|
||||
int execution_state;
|
||||
|
||||
@ -158,7 +159,7 @@ int debug_cpu_within_instruction_hook(running_machine *machine)
|
||||
on_vblank - called when a VBLANK hits
|
||||
-------------------------------------------------*/
|
||||
|
||||
static void on_vblank(const device_config *device, int vblank_state)
|
||||
static void on_vblank(const device_config *device, void *param, int vblank_state)
|
||||
{
|
||||
/* just set a global flag to be consumed later */
|
||||
if (vblank_state)
|
||||
@ -300,7 +301,7 @@ void debug_cpu_init(running_machine *machine)
|
||||
|
||||
/* add callback for breaking on VBLANK */
|
||||
if (machine->primary_screen != NULL)
|
||||
video_screen_register_vblank_callback(machine->primary_screen, on_vblank);
|
||||
video_screen_register_vblank_callback(machine->primary_screen, on_vblank, NULL);
|
||||
|
||||
add_exit_callback(machine, debug_cpu_exit);
|
||||
}
|
||||
@ -1361,7 +1362,7 @@ static void watchpoint_check(running_machine *machine, int cpunum, int spacenum,
|
||||
UINT64 result;
|
||||
|
||||
/* if we're within debugger code, don't stop */
|
||||
if (global.within_instruction_hook)
|
||||
if (global.within_instruction_hook || global.debugger_access)
|
||||
return;
|
||||
|
||||
global.within_instruction_hook = TRUE;
|
||||
@ -1642,7 +1643,7 @@ UINT8 debug_read_byte(int spacenum, offs_t address, int apply_translation)
|
||||
address &= info->space[spacenum].logbytemask;
|
||||
|
||||
/* all accesses from this point on are for the debugger */
|
||||
memory_set_debugger_access(1);
|
||||
memory_set_debugger_access(global.debugger_access = TRUE);
|
||||
|
||||
/* translate if necessary; if not mapped, return 0xff */
|
||||
if (apply_translation && info->translate != NULL && !(*info->translate)(spacenum, TRANSLATE_READ_DEBUG, &address))
|
||||
@ -1657,7 +1658,7 @@ UINT8 debug_read_byte(int spacenum, offs_t address, int apply_translation)
|
||||
result = (*active_address_space[spacenum].accessors->read_byte)(address);
|
||||
|
||||
/* no longer accessing via the debugger */
|
||||
memory_set_debugger_access(0);
|
||||
memory_set_debugger_access(global.debugger_access = FALSE);
|
||||
return result;
|
||||
}
|
||||
|
||||
@ -1693,7 +1694,7 @@ UINT16 debug_read_word(int spacenum, offs_t address, int apply_translation)
|
||||
else
|
||||
{
|
||||
/* all accesses from this point on are for the debugger */
|
||||
memory_set_debugger_access(1);
|
||||
memory_set_debugger_access(global.debugger_access = TRUE);
|
||||
|
||||
/* translate if necessary; if not mapped, return 0xffff */
|
||||
if (apply_translation && info->translate != NULL && !(*info->translate)(spacenum, TRANSLATE_READ_DEBUG, &address))
|
||||
@ -1708,7 +1709,7 @@ UINT16 debug_read_word(int spacenum, offs_t address, int apply_translation)
|
||||
result = (*active_address_space[spacenum].accessors->read_word)(address);
|
||||
|
||||
/* no longer accessing via the debugger */
|
||||
memory_set_debugger_access(0);
|
||||
memory_set_debugger_access(global.debugger_access = FALSE);
|
||||
}
|
||||
|
||||
return result;
|
||||
@ -1746,7 +1747,7 @@ UINT32 debug_read_dword(int spacenum, offs_t address, int apply_translation)
|
||||
else
|
||||
{
|
||||
/* all accesses from this point on are for the debugger */
|
||||
memory_set_debugger_access(1);
|
||||
memory_set_debugger_access(global.debugger_access = TRUE);
|
||||
|
||||
/* translate if necessary; if not mapped, return 0xffffffff */
|
||||
if (apply_translation && info->translate != NULL && !(*info->translate)(spacenum, TRANSLATE_READ_DEBUG, &address))
|
||||
@ -1761,7 +1762,7 @@ UINT32 debug_read_dword(int spacenum, offs_t address, int apply_translation)
|
||||
result = (*active_address_space[spacenum].accessors->read_dword)(address);
|
||||
|
||||
/* no longer accessing via the debugger */
|
||||
memory_set_debugger_access(0);
|
||||
memory_set_debugger_access(global.debugger_access = FALSE);
|
||||
}
|
||||
|
||||
return result;
|
||||
@ -1799,7 +1800,7 @@ UINT64 debug_read_qword(int spacenum, offs_t address, int apply_translation)
|
||||
else
|
||||
{
|
||||
/* all accesses from this point on are for the debugger */
|
||||
memory_set_debugger_access(1);
|
||||
memory_set_debugger_access(global.debugger_access = TRUE);
|
||||
|
||||
/* translate if necessary; if not mapped, return 0xffffffffffffffff */
|
||||
if (apply_translation && info->translate != NULL && !(*info->translate)(spacenum, TRANSLATE_READ_DEBUG, &address))
|
||||
@ -1814,7 +1815,7 @@ UINT64 debug_read_qword(int spacenum, offs_t address, int apply_translation)
|
||||
result = (*active_address_space[spacenum].accessors->read_qword)(address);
|
||||
|
||||
/* no longer accessing via the debugger */
|
||||
memory_set_debugger_access(0);
|
||||
memory_set_debugger_access(global.debugger_access = FALSE);
|
||||
}
|
||||
|
||||
return result;
|
||||
@ -1834,7 +1835,7 @@ void debug_write_byte(int spacenum, offs_t address, UINT8 data, int apply_transl
|
||||
address &= info->space[spacenum].logbytemask;
|
||||
|
||||
/* all accesses from this point on are for the debugger */
|
||||
memory_set_debugger_access(1);
|
||||
memory_set_debugger_access(global.debugger_access = TRUE);
|
||||
|
||||
/* translate if necessary; if not mapped, we're done */
|
||||
if (apply_translation && info->translate != NULL && !(*info->translate)(spacenum, TRANSLATE_WRITE_DEBUG, &address))
|
||||
@ -1849,7 +1850,7 @@ void debug_write_byte(int spacenum, offs_t address, UINT8 data, int apply_transl
|
||||
(*active_address_space[spacenum].accessors->write_byte)(address, data);
|
||||
|
||||
/* no longer accessing via the debugger */
|
||||
memory_set_debugger_access(0);
|
||||
memory_set_debugger_access(global.debugger_access = FALSE);
|
||||
global.memory_modified = TRUE;
|
||||
}
|
||||
|
||||
@ -1885,7 +1886,7 @@ void debug_write_word(int spacenum, offs_t address, UINT16 data, int apply_trans
|
||||
else
|
||||
{
|
||||
/* all accesses from this point on are for the debugger */
|
||||
memory_set_debugger_access(1);
|
||||
memory_set_debugger_access(global.debugger_access = TRUE);
|
||||
|
||||
/* translate if necessary; if not mapped, we're done */
|
||||
if (apply_translation && info->translate && !(*info->translate)(spacenum, TRANSLATE_WRITE_DEBUG, &address))
|
||||
@ -1900,7 +1901,7 @@ void debug_write_word(int spacenum, offs_t address, UINT16 data, int apply_trans
|
||||
(*active_address_space[spacenum].accessors->write_word)(address, data);
|
||||
|
||||
/* no longer accessing via the debugger */
|
||||
memory_set_debugger_access(0);
|
||||
memory_set_debugger_access(global.debugger_access = FALSE);
|
||||
global.memory_modified = TRUE;
|
||||
}
|
||||
}
|
||||
@ -1937,7 +1938,7 @@ void debug_write_dword(int spacenum, offs_t address, UINT32 data, int apply_tran
|
||||
else
|
||||
{
|
||||
/* all accesses from this point on are for the debugger */
|
||||
memory_set_debugger_access(1);
|
||||
memory_set_debugger_access(global.debugger_access = TRUE);
|
||||
|
||||
/* translate if necessary; if not mapped, we're done */
|
||||
if (apply_translation && info->translate && !(*info->translate)(spacenum, TRANSLATE_WRITE_DEBUG, &address))
|
||||
@ -1952,7 +1953,7 @@ void debug_write_dword(int spacenum, offs_t address, UINT32 data, int apply_tran
|
||||
(*active_address_space[spacenum].accessors->write_dword)(address, data);
|
||||
|
||||
/* no longer accessing via the debugger */
|
||||
memory_set_debugger_access(0);
|
||||
memory_set_debugger_access(global.debugger_access = FALSE);
|
||||
global.memory_modified = TRUE;
|
||||
}
|
||||
}
|
||||
@ -1988,7 +1989,7 @@ void debug_write_qword(int spacenum, offs_t address, UINT64 data, int apply_tran
|
||||
else
|
||||
{
|
||||
/* all accesses from this point on are for the debugger */
|
||||
memory_set_debugger_access(1);
|
||||
memory_set_debugger_access(global.debugger_access = TRUE);
|
||||
|
||||
/* translate if necessary; if not mapped, we're done */
|
||||
if (apply_translation && info->translate && !(*info->translate)(spacenum, TRANSLATE_WRITE_DEBUG, &address))
|
||||
@ -2003,7 +2004,7 @@ void debug_write_qword(int spacenum, offs_t address, UINT64 data, int apply_tran
|
||||
(*active_address_space[spacenum].accessors->write_qword)(address, data);
|
||||
|
||||
/* no longer accessing via the debugger */
|
||||
memory_set_debugger_access(0);
|
||||
memory_set_debugger_access(global.debugger_access = FALSE);
|
||||
global.memory_modified = TRUE;
|
||||
}
|
||||
}
|
||||
|
@ -107,8 +107,11 @@ device_config *device_list_add(device_config **listheadptr, device_type type, co
|
||||
device->class = devtype_get_info_int(type, DEVINFO_INT_CLASS);
|
||||
device->static_config = NULL;
|
||||
device->inline_config = (configlen == 0) ? NULL : (device->tag + strlen(tag) + 1);
|
||||
device->started = FALSE;
|
||||
device->token = NULL;
|
||||
device->machine = NULL;
|
||||
device->region = NULL;
|
||||
device->regionbytes = 0;
|
||||
strcpy(device->tag, tag);
|
||||
|
||||
/* reset the inline_config to 0 */
|
||||
@ -450,6 +453,8 @@ const device_config *device_list_class_find_by_index(const device_config *listhe
|
||||
void device_list_start(running_machine *machine)
|
||||
{
|
||||
device_config *device;
|
||||
int numstarted = 0;
|
||||
int devcount = 0;
|
||||
|
||||
assert(machine != NULL);
|
||||
|
||||
@ -457,15 +462,18 @@ void device_list_start(running_machine *machine)
|
||||
add_reset_callback(machine, device_list_reset);
|
||||
add_exit_callback(machine, device_list_stop);
|
||||
|
||||
/* iterate over devices and start them */
|
||||
/* iterate over devices and allocate memory for them */
|
||||
for (device = (device_config *)machine->config->devicelist; device != NULL; device = device->next)
|
||||
{
|
||||
UINT32 tokenlen;
|
||||
|
||||
assert(!device->started);
|
||||
assert(device->token == NULL);
|
||||
assert(device->type != NULL);
|
||||
assert(device->start != NULL);
|
||||
|
||||
devcount++;
|
||||
|
||||
/* get the size of the token data */
|
||||
tokenlen = (UINT32)devtype_get_info_int(device->type, DEVINFO_INT_TOKEN_BYTES);
|
||||
if (tokenlen == 0)
|
||||
@ -479,9 +487,25 @@ void device_list_start(running_machine *machine)
|
||||
device->machine = machine;
|
||||
device->region = memory_region(machine, device->tag);
|
||||
device->regionbytes = memory_region_length(machine, device->tag);
|
||||
}
|
||||
|
||||
/* iterate until we've started everything */
|
||||
while (numstarted < devcount)
|
||||
{
|
||||
int prevstarted = numstarted;
|
||||
numstarted = 0;
|
||||
|
||||
/* call the start function */
|
||||
(*device->start)(device);
|
||||
/* iterate over devices and start them */
|
||||
for (device = (device_config *)machine->config->devicelist; device != NULL; device = device->next)
|
||||
{
|
||||
if (!device->started && (*device->start)(device) == DEVICE_START_OK)
|
||||
device->started = TRUE;
|
||||
numstarted += device->started;
|
||||
}
|
||||
|
||||
/* if we didn't start anything new, we're in trouble */
|
||||
if (numstarted == prevstarted)
|
||||
fatalerror("Circular dependency in device startup; unable to start %d/%d devices\n", devcount - numstarted, devcount);
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -37,6 +37,15 @@ enum _device_class
|
||||
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
|
||||
|
||||
@ -104,7 +113,7 @@ enum
|
||||
#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) void DEVICE_START_NAME(name)(const device_config *device)
|
||||
#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
|
||||
@ -137,7 +146,7 @@ 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 void (*device_start_func)(const device_config *device);
|
||||
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);
|
||||
@ -181,7 +190,8 @@ struct _device_config
|
||||
const void * static_config; /* static device configuration */
|
||||
void * inline_config; /* inline device configuration */
|
||||
|
||||
/* these four fields are only valid if the device is live */
|
||||
/* 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 */
|
||||
|
@ -467,6 +467,8 @@ static DEVICE_START( riot6532 )
|
||||
|
||||
state_save_register_item(unique_tag, 0, riot->timershift);
|
||||
state_save_register_item(unique_tag, 0, riot->timerstate);
|
||||
|
||||
return DEVICE_START_OK;
|
||||
}
|
||||
|
||||
|
||||
|
@ -585,7 +585,8 @@ static DEVICE_START(duart68681)
|
||||
state_save_register_item(unique_tag, 0, duart68681->channel[1].tx_enabled);
|
||||
state_save_register_item(unique_tag, 0, duart68681->channel[1].tx_data);
|
||||
state_save_register_item(unique_tag, 0, duart68681->channel[1].tx_ready);
|
||||
|
||||
|
||||
return DEVICE_START_OK;
|
||||
}
|
||||
|
||||
/*-------------------------------------------------
|
||||
|
@ -395,6 +395,8 @@ static DEVICE_START( dma8237 ) {
|
||||
dma8237_t *dma8237 = get_safe_token(device);
|
||||
|
||||
dma8237->intf = device->static_config;
|
||||
|
||||
return DEVICE_START_OK;
|
||||
}
|
||||
|
||||
|
||||
|
@ -537,6 +537,8 @@ static DEVICE_START( ppi8255 ) {
|
||||
state_save_register_item_array(unique_tag, 0, ppi8255->out_mask);
|
||||
state_save_register_item_array(unique_tag, 0, ppi8255->read);
|
||||
state_save_register_item_array(unique_tag, 0, ppi8255->latch);
|
||||
|
||||
return DEVICE_START_OK;
|
||||
}
|
||||
|
||||
|
||||
|
@ -388,7 +388,8 @@ static DEVICE_START( dma8257 )
|
||||
state_save_register_item(unique_tag, 0, dma8257->msb);
|
||||
state_save_register_item(unique_tag, 0, dma8257->drq);
|
||||
state_save_register_item(unique_tag, 0, dma8257->status);
|
||||
|
||||
|
||||
return DEVICE_START_OK;
|
||||
}
|
||||
|
||||
|
||||
|
@ -156,6 +156,8 @@ static DEVICE_START(at28c16)
|
||||
state_save_register_item( unique_tag, 0, c->a9_12v );
|
||||
state_save_register_item( unique_tag, 0, c->oe_12v );
|
||||
state_save_register_item( unique_tag, 0, c->last_write );
|
||||
|
||||
return DEVICE_START_OK;
|
||||
}
|
||||
|
||||
/*-------------------------------------------------
|
||||
|
@ -156,6 +156,8 @@ static DEVICE_START( cdp1852 )
|
||||
state_save_register_item(unique_tag, 0, cdp1852->next_data);
|
||||
state_save_register_item(unique_tag, 0, cdp1852->sr);
|
||||
state_save_register_item(unique_tag, 0, cdp1852->next_sr);
|
||||
|
||||
return DEVICE_START_OK;
|
||||
}
|
||||
|
||||
static DEVICE_RESET( cdp1852 )
|
||||
|
@ -1756,6 +1756,8 @@ static DEVICE_START( ide_controller )
|
||||
|
||||
state_save_register_item(unique_tag, 0, ide->master_password_enable);
|
||||
state_save_register_item(unique_tag, 0, ide->user_password_enable);
|
||||
|
||||
return DEVICE_START_OK;
|
||||
}
|
||||
|
||||
|
||||
|
@ -1963,6 +1963,8 @@ static DEVICE_START( laserdisc )
|
||||
|
||||
/* register callbacks */
|
||||
config_register(device->machine, "laserdisc", configuration_load, configuration_save);
|
||||
|
||||
return DEVICE_START_OK;
|
||||
}
|
||||
|
||||
|
||||
|
@ -72,8 +72,7 @@ struct _laserdisc_config
|
||||
{
|
||||
UINT32 type;
|
||||
laserdisc_audio_func audio;
|
||||
|
||||
/* rendering information */
|
||||
const char * sound;
|
||||
const char * screen;
|
||||
|
||||
/* overlay information */
|
||||
@ -90,16 +89,15 @@ struct _laserdisc_config
|
||||
DEVICE CONFIGURATION MACROS
|
||||
***************************************************************************/
|
||||
|
||||
#define MDRV_LASERDISC_ADD(_tag, _type) \
|
||||
#define MDRV_LASERDISC_ADD(_tag, _type, _screen, _sound) \
|
||||
MDRV_DEVICE_ADD(_tag, LASERDISC) \
|
||||
MDRV_DEVICE_CONFIG_DATA32(laserdisc_config, type, LASERDISC_TYPE_##_type)
|
||||
MDRV_DEVICE_CONFIG_DATA32(laserdisc_config, type, LASERDISC_TYPE_##_type) \
|
||||
MDRV_DEVICE_CONFIG_DATAPTR(laserdisc_config, screen, _screen) \
|
||||
MDRV_DEVICE_CONFIG_DATAPTR(laserdisc_config, sound, _sound) \
|
||||
|
||||
#define MDRV_LASERDISC_AUDIO(_func) \
|
||||
MDRV_DEVICE_CONFIG_DATAPTR(laserdisc_config, audio, _func)
|
||||
|
||||
#define MDRV_LASERDISC_SCREEN(_tag) \
|
||||
MDRV_DEVICE_CONFIG_DATAPTR(laserdisc_config, screen, _tag)
|
||||
|
||||
#define MDRV_LASERDISC_OVERLAY(_update, _width, _height, _format) \
|
||||
MDRV_DEVICE_CONFIG_DATAPTR(laserdisc_config, overupdate, video_update_##_update) \
|
||||
MDRV_DEVICE_CONFIG_DATA32(laserdisc_config, overwidth, _width) \
|
||||
@ -159,9 +157,6 @@ extern const custom_sound_interface laserdisc_custom_interface;
|
||||
|
||||
/* ----- core control and status ----- */
|
||||
|
||||
/* call this once per field (i.e., 59.94 times/second for NTSC) */
|
||||
void laserdisc_vsync(const device_config *device);
|
||||
|
||||
/* get a bitmap for the current frame (and the frame number) */
|
||||
UINT32 laserdisc_get_video(const device_config *device, bitmap_t **bitmap);
|
||||
|
||||
|
@ -223,6 +223,8 @@ static DEVICE_START( latch8 )
|
||||
state_save_combine_module_and_tag(unique_tag, "latch8", device->tag);
|
||||
|
||||
state_save_register_item(unique_tag, 0, latch8->value);
|
||||
|
||||
return DEVICE_START_OK;
|
||||
}
|
||||
|
||||
|
||||
|
@ -33,6 +33,7 @@
|
||||
|
||||
/* we simulate extra lead-in and lead-out tracks */
|
||||
#define VIRTUAL_LEAD_IN_TRACKS 200
|
||||
#define MAX_TOTAL_TRACKS 54000
|
||||
#define VIRTUAL_LEAD_OUT_TRACKS 200
|
||||
|
||||
|
||||
@ -50,15 +51,22 @@ struct _ldcore_data
|
||||
|
||||
/* disc parameters */
|
||||
chd_file * disc; /* handle to the disc itself */
|
||||
av_codec_decompress_config avconfig; /* decompression configuration */
|
||||
int width; /* width of video */
|
||||
int height; /* height of video */
|
||||
UINT32 fps_times_1million; /* frame rate of video */
|
||||
int samplerate; /* audio samplerate */
|
||||
UINT8 readpending; /* true if a read is pending */
|
||||
UINT32 maxtrack; /* maximum track number */
|
||||
UINT32 chdtracks; /* number of tracks in the CHD */
|
||||
av_codec_decompress_config avconfig; /* decompression configuration */
|
||||
|
||||
/* core states */
|
||||
UINT8 audiosquelch; /* audio squelch state: bit 0 = audio 1, bit 1 = audio 2 */
|
||||
UINT8 videosquelch; /* video squelch state: bit 0 = on/off */
|
||||
UINT8 fieldnum; /* field number (0 or 1) */
|
||||
INT32 curtrack; /* current track */
|
||||
INT32 curtrack; /* current track at this end of this vsync */
|
||||
UINT32 maxtrack; /* maximum track number */
|
||||
attoseconds_t attospertrack; /* attoseconds per track, or 0 if not moving */
|
||||
attotime sliderupdate; /* time of last slider update */
|
||||
|
||||
/* video data */
|
||||
bitmap_t * videoframe[3]; /* currently cached frames */
|
||||
@ -77,7 +85,6 @@ struct _ldcore_data
|
||||
UINT32 audiocursamples; /* current samples this track */
|
||||
UINT32 audiomaxsamples; /* maximum samples per track */
|
||||
int audiocustom; /* custom sound index */
|
||||
int samplerate; /* playback samplerate */
|
||||
|
||||
/* metadata */
|
||||
vbi_metadata metadata[2]; /* metadata parsed from the stream, for each field */
|
||||
@ -261,47 +268,31 @@ INLINE laserdisc_state *get_safe_token(const device_config *device)
|
||||
|
||||
|
||||
/*-------------------------------------------------
|
||||
audio_channel_active - return TRUE if the
|
||||
given audio channel should be output
|
||||
update_audio - update the audio stream to the
|
||||
current time
|
||||
-------------------------------------------------*/
|
||||
|
||||
INLINE int audio_channel_active(ldcore_data *ldcore, int channel)
|
||||
INLINE void update_audio(ldcore_data *ldcore)
|
||||
{
|
||||
return (~ldcore->audiosquelch >> channel) & 1;
|
||||
if (ldcore->audiocustom != -1)
|
||||
{
|
||||
sound_token *token = custom_get_token(ldcore->audiocustom);
|
||||
stream_update(token->stream);
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
/*-------------------------------------------------
|
||||
video_active - return TRUE if the video should
|
||||
be output
|
||||
add_and_clamp_track - add a delta to the
|
||||
current track and clamp to minimum/maximum
|
||||
values
|
||||
-------------------------------------------------*/
|
||||
|
||||
INLINE int video_active(ldcore_data *ldcore)
|
||||
{
|
||||
return !ldcore->videosquelch;
|
||||
}
|
||||
|
||||
|
||||
/*-------------------------------------------------
|
||||
add_to_current_track - add a value to the
|
||||
current track, stopping if we hit the min or
|
||||
max
|
||||
-------------------------------------------------*/
|
||||
|
||||
INLINE int add_to_current_track(ldcore_data *ldcore, INT32 delta)
|
||||
INLINE void add_and_clamp_track(ldcore_data *ldcore, INT32 delta)
|
||||
{
|
||||
ldcore->curtrack += delta;
|
||||
if (ldcore->curtrack < 1)
|
||||
{
|
||||
ldcore->curtrack = 1;
|
||||
return TRUE;
|
||||
}
|
||||
else if (ldcore->curtrack >= ldcore->maxtrack - 1)
|
||||
{
|
||||
ldcore->curtrack = ldcore->maxtrack - 1;
|
||||
return TRUE;
|
||||
}
|
||||
return FALSE;
|
||||
ldcore->curtrack = MAX(ldcore->curtrack, 1);
|
||||
ldcore->curtrack = MIN(ldcore->curtrack, ldcore->maxtrack - 1);
|
||||
}
|
||||
|
||||
|
||||
@ -335,31 +326,75 @@ INLINE void fillbitmap_yuy16(bitmap_t *bitmap, UINT8 yval, UINT8 cr, UINT8 cb)
|
||||
***************************************************************************/
|
||||
|
||||
/*-------------------------------------------------
|
||||
laserdisc_vsync - call this once per field
|
||||
on the VSYNC signal
|
||||
update_slider_pos - based on the current
|
||||
speed and elapsed time, update the current
|
||||
track position
|
||||
-------------------------------------------------*/
|
||||
|
||||
void laserdisc_vsync(const device_config *device)
|
||||
static void update_slider_pos(ldcore_data *ldcore, attotime curtime)
|
||||
{
|
||||
/* if not moving, update to now */
|
||||
if (ldcore->attospertrack == 0)
|
||||
ldcore->sliderupdate = curtime;
|
||||
|
||||
/* otherwise, compute the number of tracks covered */
|
||||
else
|
||||
{
|
||||
attoseconds_t delta = attotime_to_attoseconds(attotime_sub(curtime, ldcore->sliderupdate));
|
||||
INT32 tracks_covered;
|
||||
|
||||
/* determine how many tracks we covered and advance */
|
||||
if (ldcore->attospertrack >= 0)
|
||||
{
|
||||
tracks_covered = delta / ldcore->attospertrack;
|
||||
add_and_clamp_track(ldcore, tracks_covered);
|
||||
if (tracks_covered != 0)
|
||||
ldcore->sliderupdate = attotime_add_attoseconds(ldcore->sliderupdate, tracks_covered * ldcore->attospertrack);
|
||||
}
|
||||
else
|
||||
{
|
||||
tracks_covered = delta / -ldcore->attospertrack;
|
||||
add_and_clamp_track(ldcore, -tracks_covered);
|
||||
if (tracks_covered != 0)
|
||||
ldcore->sliderupdate = attotime_add_attoseconds(ldcore->sliderupdate, tracks_covered * -ldcore->attospertrack);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
/*-------------------------------------------------
|
||||
vblank_state_changed - called on each state
|
||||
change of the VBLANK signal
|
||||
-------------------------------------------------*/
|
||||
|
||||
static void vblank_state_changed(const device_config *screen, void *param, int vblank_state)
|
||||
{
|
||||
const device_config *device = param;
|
||||
laserdisc_state *ld = get_safe_token(device);
|
||||
ldcore_data *ldcore = ld->core;
|
||||
attotime curtime = timer_get_time();
|
||||
|
||||
/* update current track based on slider speed */
|
||||
update_slider_pos(ldcore, curtime);
|
||||
|
||||
/* on rising edge, call the player-specific VSYNC function */
|
||||
if (vblank_state)
|
||||
{
|
||||
if (ldcore->intf.vsync != NULL)
|
||||
(*ldcore->intf.vsync)(ld);
|
||||
return;
|
||||
}
|
||||
|
||||
/* on falling edge, do the bulk of the processing */
|
||||
/* wait for previous read and decode to finish */
|
||||
process_track_data(device);
|
||||
|
||||
/* update the state */
|
||||
if (ldcore->intf.update != NULL)
|
||||
{
|
||||
INT32 advanceby = (*ldcore->intf.update)(ld, &ldcore->metadata[ldcore->fieldnum], ldcore->fieldnum, timer_get_time());
|
||||
add_to_current_track(ldcore, advanceby);
|
||||
}
|
||||
add_and_clamp_track(ldcore, (*ldcore->intf.update)(ld, &ldcore->metadata[ldcore->fieldnum], ldcore->fieldnum, curtime));
|
||||
|
||||
/* flush any audio before we read more */
|
||||
if (ldcore->audiocustom != -1)
|
||||
{
|
||||
sound_token *token = custom_get_token(ldcore->audiocustom);
|
||||
stream_update(token->stream);
|
||||
}
|
||||
update_audio(ldcore);
|
||||
|
||||
/* start reading the track data for the next round */
|
||||
ldcore->fieldnum ^= 1;
|
||||
@ -481,7 +516,7 @@ UINT32 laserdisc_get_video(const device_config *device, bitmap_t **bitmap)
|
||||
frameindex = (frameindex + ARRAY_LENGTH(ldcore->videofields) - 1) % ARRAY_LENGTH(ldcore->videofields);
|
||||
|
||||
/* if no video present, return the empty frame */
|
||||
if (!video_active(ldcore) || ldcore->videofields[frameindex] < 2)
|
||||
if (ldcore->videosquelch || ldcore->videofields[frameindex] < 2)
|
||||
{
|
||||
*bitmap = ldcore->emptyframe;
|
||||
return 0;
|
||||
@ -506,7 +541,7 @@ UINT32 laserdisc_get_field_code(const device_config *device, UINT8 code)
|
||||
int field = ldcore->fieldnum ^ 1;
|
||||
|
||||
/* if no video present, return */
|
||||
if (!video_active(ldcore))
|
||||
if (ldcore->videosquelch)
|
||||
return 0;
|
||||
|
||||
switch (code)
|
||||
@ -551,6 +586,7 @@ laserdisc_state *ldcore_get_safe_token(const device_config *device)
|
||||
|
||||
void ldcore_set_audio_squelch(laserdisc_state *ld, UINT8 squelchleft, UINT8 squelchright)
|
||||
{
|
||||
update_audio(ld->core);
|
||||
ld->core->audiosquelch = (squelchleft ? 1 : 0) | (squelchright ? 2 : 0);
|
||||
}
|
||||
|
||||
@ -566,6 +602,77 @@ void ldcore_set_video_squelch(laserdisc_state *ld, UINT8 squelch)
|
||||
}
|
||||
|
||||
|
||||
/*-------------------------------------------------
|
||||
ldcore_set_slider_speed - dynamically change
|
||||
the slider speed
|
||||
-------------------------------------------------*/
|
||||
|
||||
void ldcore_set_slider_speed(laserdisc_state *ld, INT32 tracks_per_vsync)
|
||||
{
|
||||
ldcore_data *ldcore = ld->core;
|
||||
attotime vsyncperiod = video_screen_get_frame_period(ld->screen);
|
||||
|
||||
update_slider_pos(ldcore, timer_get_time());
|
||||
|
||||
/* if 0, set the time to 0 */
|
||||
if (tracks_per_vsync == 0)
|
||||
ldcore->attospertrack = 0;
|
||||
|
||||
/* positive values store positive times */
|
||||
else if (tracks_per_vsync > 0)
|
||||
ldcore->attospertrack = attotime_to_attoseconds(attotime_div(vsyncperiod, tracks_per_vsync));
|
||||
|
||||
/* negative values store negative times */
|
||||
else
|
||||
ldcore->attospertrack = -attotime_to_attoseconds(attotime_div(vsyncperiod, -tracks_per_vsync));
|
||||
|
||||
printf("Slider speed = %d\n", tracks_per_vsync);
|
||||
}
|
||||
|
||||
|
||||
/*-------------------------------------------------
|
||||
ldcore_advance_slider - advance the slider by
|
||||
a certain number of tracks
|
||||
-------------------------------------------------*/
|
||||
|
||||
void ldcore_advance_slider(laserdisc_state *ld, INT32 numtracks)
|
||||
{
|
||||
ldcore_data *ldcore = ld->core;
|
||||
|
||||
update_slider_pos(ldcore, timer_get_time());
|
||||
add_and_clamp_track(ldcore, numtracks);
|
||||
printf("Advance by %d\n", numtracks);
|
||||
}
|
||||
|
||||
|
||||
/*-------------------------------------------------
|
||||
ldcore_get_slider_position - get the current
|
||||
slider position
|
||||
-------------------------------------------------*/
|
||||
|
||||
slider_position ldcore_get_slider_position(laserdisc_state *ld)
|
||||
{
|
||||
ldcore_data *ldcore = ld->core;
|
||||
|
||||
/* update the slider position first */
|
||||
update_slider_pos(ldcore, timer_get_time());
|
||||
|
||||
/* return the status */
|
||||
if (ldcore->curtrack == 1)
|
||||
return SLIDER_MINIMUM;
|
||||
else if (ldcore->curtrack < VIRTUAL_LEAD_IN_TRACKS)
|
||||
return SLIDER_VIRTUAL_LEADIN;
|
||||
else if (ldcore->curtrack < VIRTUAL_LEAD_IN_TRACKS + ldcore->chdtracks)
|
||||
return SLIDER_CHD;
|
||||
else if (ldcore->curtrack < VIRTUAL_LEAD_IN_TRACKS + MAX_TOTAL_TRACKS)
|
||||
return SLIDER_OUTSIDE_CHD;
|
||||
else if (ldcore->curtrack < ldcore->maxtrack - 1)
|
||||
return SLIDER_VIRTUAL_LEADOUT;
|
||||
else
|
||||
return SLIDER_MAXIMUM;
|
||||
}
|
||||
|
||||
|
||||
|
||||
/***************************************************************************
|
||||
GENERIC HELPER FUNCTIONS
|
||||
@ -792,10 +899,6 @@ static void read_track_data(laserdisc_state *ld)
|
||||
ldcore->avconfig.maxsamples = ldcore->audiomaxsamples;
|
||||
ldcore->avconfig.actsamples = &ldcore->audiocursamples;
|
||||
ldcore->audiocursamples = 0;
|
||||
if (!audio_channel_active(ldcore, 0))
|
||||
ldcore->avconfig.audio[0] = NULL;
|
||||
if (!audio_channel_active(ldcore, 1))
|
||||
ldcore->avconfig.audio[1] = NULL;
|
||||
|
||||
/* configure the codec and then read */
|
||||
if (ldcore->disc != NULL)
|
||||
@ -803,12 +906,11 @@ static void read_track_data(laserdisc_state *ld)
|
||||
err = chd_codec_config(ldcore->disc, AV_CODEC_DECOMPRESS_CONFIG, &ldcore->avconfig);
|
||||
if (err == CHDERR_NONE)
|
||||
{
|
||||
INT32 maxtrack = chd_get_header(ldcore->disc)->totalhunks / 2;
|
||||
INT32 chdtrack = tracknum - 1 - VIRTUAL_LEAD_IN_TRACKS;
|
||||
|
||||
/* clamp the track */
|
||||
chdtrack = MAX(chdtrack, 0);
|
||||
chdtrack = MIN(chdtrack, maxtrack - 1);
|
||||
chdtrack = MIN(chdtrack, ldcore->chdtracks - 1);
|
||||
err = chd_read_async(ldcore->disc, chdtrack * 2 + fieldnum, NULL);
|
||||
ldcore->readpending = TRUE;
|
||||
}
|
||||
@ -1005,7 +1107,12 @@ static void custom_stream_callback(void *param, stream_sample_t **inputs, stream
|
||||
ldcore_data *ldcore = ld->core;
|
||||
stream_sample_t *dst0 = outputs[0];
|
||||
stream_sample_t *dst1 = outputs[1];
|
||||
INT16 leftand, rightand;
|
||||
int samples_avail = 0;
|
||||
|
||||
/* compute AND values based on the squelch */
|
||||
leftand = (ldcore->audiosquelch & 1) ? 0x0000 : 0xffff;
|
||||
rightand = (ldcore->audiosquelch & 2) ? 0x0000 : 0xffff;
|
||||
|
||||
/* see if we have enough samples to fill the buffer; if not, drop out */
|
||||
if (ld != NULL)
|
||||
@ -1032,8 +1139,8 @@ static void custom_stream_callback(void *param, stream_sample_t **inputs, stream
|
||||
/* copy samples, clearing behind us as we go */
|
||||
while (sampout != ldcore->audiobufin && samples-- > 0)
|
||||
{
|
||||
*dst0++ = buffer0[sampout];
|
||||
*dst1++ = buffer1[sampout];
|
||||
*dst0++ = buffer0[sampout] & leftand;
|
||||
*dst1++ = buffer1[sampout] & rightand;
|
||||
buffer0[sampout] = 0;
|
||||
buffer1[sampout] = 0;
|
||||
sampout++;
|
||||
@ -1046,8 +1153,8 @@ static void custom_stream_callback(void *param, stream_sample_t **inputs, stream
|
||||
if (samples > 0)
|
||||
{
|
||||
int sampout = (ldcore->audiobufout == 0) ? ldcore->audiobufsize - 1 : ldcore->audiobufout - 1;
|
||||
stream_sample_t fill0 = buffer0[sampout];
|
||||
stream_sample_t fill1 = buffer1[sampout];
|
||||
stream_sample_t fill0 = buffer0[sampout] & leftand;
|
||||
stream_sample_t fill1 = buffer1[sampout] & rightand;
|
||||
|
||||
while (samples-- > 0)
|
||||
{
|
||||
@ -1307,6 +1414,148 @@ void laserdisc_set_config(const device_config *device, const laserdisc_config *c
|
||||
|
||||
|
||||
|
||||
/***************************************************************************
|
||||
INITIALIZATION
|
||||
***************************************************************************/
|
||||
|
||||
/*-------------------------------------------------
|
||||
init_disc - initialize the state of the
|
||||
CHD disc
|
||||
-------------------------------------------------*/
|
||||
|
||||
static void init_disc(const device_config *device)
|
||||
{
|
||||
laserdisc_state *ld = get_safe_token(device);
|
||||
ldcore_data *ldcore = ld->core;
|
||||
chd_error err;
|
||||
|
||||
/* find the disc */
|
||||
ldcore->disc = get_disk_handle(device->tag);
|
||||
|
||||
/* set default parameters */
|
||||
ldcore->width = 720;
|
||||
ldcore->height = 240;
|
||||
ldcore->fps_times_1million = 59940000;
|
||||
ldcore->samplerate = 48000;
|
||||
|
||||
/* get the disc metadata and extract the ld */
|
||||
ldcore->chdtracks = 0;
|
||||
ldcore->maxtrack = VIRTUAL_LEAD_IN_TRACKS + MAX_TOTAL_TRACKS + VIRTUAL_LEAD_OUT_TRACKS;
|
||||
if (ldcore->disc != NULL)
|
||||
{
|
||||
int fps, fpsfrac, interlaced, channels;
|
||||
char metadata[256];
|
||||
|
||||
/* require the A/V codec */
|
||||
if (chd_get_header(ldcore->disc)->compression != CHDCOMPRESSION_AV)
|
||||
fatalerror("Laserdisc video must be compressed with the A/V codec!");
|
||||
|
||||
/* read the metadata */
|
||||
err = chd_get_metadata(ldcore->disc, AV_METADATA_TAG, 0, metadata, sizeof(metadata), NULL, NULL);
|
||||
if (err != CHDERR_NONE)
|
||||
fatalerror("Non-A/V CHD file specified");
|
||||
|
||||
/* extract the metadata */
|
||||
if (sscanf(metadata, AV_METADATA_FORMAT, &fps, &fpsfrac, &ldcore->width, &ldcore->height, &interlaced, &channels, &ldcore->samplerate) != 7)
|
||||
fatalerror("Invalid metadata in CHD file");
|
||||
else
|
||||
ldcore->fps_times_1million = fps * 1000000 + fpsfrac;
|
||||
|
||||
/* require interlaced video */
|
||||
if (!interlaced)
|
||||
fatalerror("Laserdisc video must be interlaced!");
|
||||
|
||||
/* determine the maximum track and allocate a frame buffer */
|
||||
ldcore->chdtracks = chd_get_header(ldcore->disc)->totalhunks / 2;
|
||||
}
|
||||
ldcore->maxtrack = MAX(ldcore->maxtrack, VIRTUAL_LEAD_IN_TRACKS + VIRTUAL_LEAD_OUT_TRACKS + ldcore->chdtracks);
|
||||
}
|
||||
|
||||
|
||||
/*-------------------------------------------------
|
||||
init_video - initialize the state of the
|
||||
video rendering
|
||||
-------------------------------------------------*/
|
||||
|
||||
static void init_video(const device_config *device)
|
||||
{
|
||||
laserdisc_state *ld = get_safe_token(device);
|
||||
ldcore_data *ldcore = ld->core;
|
||||
int index;
|
||||
|
||||
/* register for VBLANK callbacks */
|
||||
video_screen_register_vblank_callback(ld->screen, vblank_state_changed, (void *)device);
|
||||
|
||||
/* allocate video frames */
|
||||
for (index = 0; index < ARRAY_LENGTH(ldcore->videofields); index++)
|
||||
{
|
||||
/* first allocate a YUY16 bitmap at 2x the height */
|
||||
ldcore->videoframe[index] = auto_bitmap_alloc(ldcore->width, ldcore->height * 2, BITMAP_FORMAT_YUY16);
|
||||
fillbitmap_yuy16(ldcore->videoframe[index], 40, 109, 240);
|
||||
|
||||
/* make a copy of the bitmap that clips out the VBI and horizontal blanking areas */
|
||||
ldcore->videovisframe[index] = auto_malloc(sizeof(*ldcore->videovisframe[index]));
|
||||
*ldcore->videovisframe[index] = *ldcore->videoframe[index];
|
||||
ldcore->videovisframe[index]->base = BITMAP_ADDR16(ldcore->videovisframe[index], 44, ldcore->videoframe[index]->width * 8 / 720);
|
||||
ldcore->videovisframe[index]->height -= 44;
|
||||
ldcore->videovisframe[index]->width -= 2 * ldcore->videoframe[index]->width * 8 / 720;
|
||||
}
|
||||
|
||||
/* allocate an empty frame of the same size */
|
||||
ldcore->emptyframe = auto_bitmap_alloc(ldcore->width, ldcore->height * 2, BITMAP_FORMAT_YUY16);
|
||||
fillbitmap_yuy16(ldcore->emptyframe, 0, 128, 128);
|
||||
|
||||
/* allocate texture for rendering */
|
||||
ldcore->videoenable = TRUE;
|
||||
ldcore->videotex = render_texture_alloc(NULL, NULL);
|
||||
if (ldcore->videotex == NULL)
|
||||
fatalerror("Out of memory allocating video texture");
|
||||
|
||||
/* allocate overlay */
|
||||
if (ldcore->config.overwidth > 0 && ldcore->config.overheight > 0 && ldcore->config.overupdate != NULL)
|
||||
{
|
||||
ldcore->overenable = TRUE;
|
||||
ldcore->overbitmap[0] = auto_bitmap_alloc(ldcore->config.overwidth, ldcore->config.overheight, ldcore->config.overformat);
|
||||
ldcore->overbitmap[1] = auto_bitmap_alloc(ldcore->config.overwidth, ldcore->config.overheight, ldcore->config.overformat);
|
||||
ldcore->overtex = render_texture_alloc(NULL, NULL);
|
||||
if (ldcore->overtex == NULL)
|
||||
fatalerror("Out of memory allocating overlay texture");
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
/*-------------------------------------------------
|
||||
init_audio - initialize the state of the
|
||||
audio rendering
|
||||
-------------------------------------------------*/
|
||||
|
||||
static void init_audio(const device_config *device)
|
||||
{
|
||||
laserdisc_state *ld = get_safe_token(device);
|
||||
ldcore_data *ldcore = ld->core;
|
||||
int sndnum;
|
||||
|
||||
/* find the custom audio */
|
||||
ldcore->audiocustom = 0;
|
||||
for (sndnum = 0; sndnum < MAX_SOUND; sndnum++)
|
||||
{
|
||||
if (device->machine->config->sound[sndnum].tag != NULL && strcmp(device->machine->config->sound[sndnum].tag, ldcore->config.sound) == 0)
|
||||
break;
|
||||
if (device->machine->config->sound[sndnum].type == SOUND_CUSTOM)
|
||||
ldcore->audiocustom++;
|
||||
}
|
||||
if (sndnum == MAX_SOUND)
|
||||
ldcore->audiocustom = -1;
|
||||
|
||||
/* allocate audio buffers */
|
||||
ldcore->audiomaxsamples = ((UINT64)ldcore->samplerate * 1000000 + ldcore->fps_times_1million - 1) / ldcore->fps_times_1million;
|
||||
ldcore->audiobufsize = ldcore->audiomaxsamples * 4;
|
||||
ldcore->audiobuffer[0] = auto_malloc(ldcore->audiobufsize * sizeof(ldcore->audiobuffer[0][0]));
|
||||
ldcore->audiobuffer[1] = auto_malloc(ldcore->audiobufsize * sizeof(ldcore->audiobuffer[1][0]));
|
||||
}
|
||||
|
||||
|
||||
|
||||
/***************************************************************************
|
||||
DEVICE INTERFACE
|
||||
***************************************************************************/
|
||||
@ -1317,15 +1566,17 @@ void laserdisc_set_config(const device_config *device, const laserdisc_config *c
|
||||
|
||||
static DEVICE_START( laserdisc )
|
||||
{
|
||||
int fps = 30, fpsfrac = 0, width = 720, height = 240, interlaced = 1, channels = 2, rate = 44100;
|
||||
const laserdisc_config *config = device->inline_config;
|
||||
laserdisc_state *ld = get_safe_token(device);
|
||||
UINT32 fps_times_1million;
|
||||
ldcore_data *ldcore;
|
||||
char metadata[256];
|
||||
int sndnum, index;
|
||||
int statesize;
|
||||
chd_error err;
|
||||
int index;
|
||||
|
||||
/* ensure that our screen is started first */
|
||||
ld->screen = devtag_get_device(device->machine, VIDEO_SCREEN, config->screen);
|
||||
assert(ld->screen != NULL);
|
||||
if (!ld->screen->started)
|
||||
return DEVICE_START_MISSING_DEPENDENCY;
|
||||
|
||||
/* save a copy of the device pointer */
|
||||
ld->device = device;
|
||||
@ -1354,91 +1605,16 @@ static DEVICE_START( laserdisc )
|
||||
ldcore->config.overscalex = 1.0f;
|
||||
if (ldcore->config.overscaley == 0)
|
||||
ldcore->config.overscaley = 1.0f;
|
||||
|
||||
/* find the disc */
|
||||
ldcore->disc = get_disk_handle(device->tag);
|
||||
ldcore->audiocustom = 0;
|
||||
for (sndnum = 0; sndnum < MAX_SOUND; sndnum++)
|
||||
{
|
||||
if (device->machine->config->sound[sndnum].tag != NULL && strcmp(device->machine->config->sound[sndnum].tag, device->tag) == 0)
|
||||
break;
|
||||
if (device->machine->config->sound[sndnum].type == SOUND_CUSTOM)
|
||||
ldcore->audiocustom++;
|
||||
}
|
||||
if (sndnum == MAX_SOUND)
|
||||
ldcore->audiocustom = -1;
|
||||
|
||||
/* get the disc metadata and extract the ld */
|
||||
if (ldcore->disc != NULL)
|
||||
{
|
||||
/* require the A/V codec */
|
||||
if (chd_get_header(ldcore->disc)->compression != CHDCOMPRESSION_AV)
|
||||
fatalerror("Laserdisc video must be compressed with the A/V codec!");
|
||||
|
||||
/* read and extract the metadata */
|
||||
err = chd_get_metadata(ldcore->disc, AV_METADATA_TAG, 0, metadata, sizeof(metadata), NULL, NULL);
|
||||
if (err != CHDERR_NONE)
|
||||
fatalerror("Non-A/V CHD file specified");
|
||||
if (sscanf(metadata, AV_METADATA_FORMAT, &fps, &fpsfrac, &width, &height, &interlaced, &channels, &rate) != 7)
|
||||
fatalerror("Invalid metadata in CHD file");
|
||||
|
||||
/* require interlaced video */
|
||||
if (!interlaced)
|
||||
fatalerror("Laserdisc video must be interlaced!");
|
||||
|
||||
/* determine the maximum track and allocate a frame buffer */
|
||||
ldcore->maxtrack = chd_get_header(ldcore->disc)->totalhunks / 2;
|
||||
}
|
||||
else
|
||||
ldcore->maxtrack = 54000;
|
||||
ldcore->maxtrack += VIRTUAL_LEAD_IN_TRACKS + VIRTUAL_LEAD_OUT_TRACKS;
|
||||
|
||||
/* allocate video frames */
|
||||
for (index = 0; index < ARRAY_LENGTH(ldcore->videofields); index++)
|
||||
{
|
||||
/* first allocate a YUY16 bitmap at 2x the height */
|
||||
ldcore->videoframe[index] = auto_bitmap_alloc(width, height * 2, BITMAP_FORMAT_YUY16);
|
||||
fillbitmap_yuy16(ldcore->videoframe[index], 40, 109, 240);
|
||||
|
||||
/* make a copy of the bitmap that clips out the VBI and horizontal blanking areas */
|
||||
ldcore->videovisframe[index] = auto_malloc(sizeof(*ldcore->videovisframe[index]));
|
||||
*ldcore->videovisframe[index] = *ldcore->videoframe[index];
|
||||
ldcore->videovisframe[index]->base = BITMAP_ADDR16(ldcore->videovisframe[index], 44, ldcore->videoframe[index]->width * 8 / 720);
|
||||
ldcore->videovisframe[index]->height -= 44;
|
||||
ldcore->videovisframe[index]->width -= 2 * ldcore->videoframe[index]->width * 8 / 720;
|
||||
}
|
||||
|
||||
/* allocate an empty frame of the same size */
|
||||
ldcore->emptyframe = auto_bitmap_alloc(width, height * 2, BITMAP_FORMAT_YUY16);
|
||||
fillbitmap_yuy16(ldcore->emptyframe, 0, 128, 128);
|
||||
|
||||
/* allocate audio buffers */
|
||||
fps_times_1million = fps * 1000000 + fpsfrac;
|
||||
ldcore->audiomaxsamples = ((UINT64)rate * 1000000 + fps_times_1million - 1) / fps_times_1million;
|
||||
ldcore->audiobufsize = ldcore->audiomaxsamples * 4;
|
||||
ldcore->audiobuffer[0] = auto_malloc(ldcore->audiobufsize * sizeof(ldcore->audiobuffer[0][0]));
|
||||
ldcore->audiobuffer[1] = auto_malloc(ldcore->audiobufsize * sizeof(ldcore->audiobuffer[1][0]));
|
||||
ldcore->samplerate = rate;
|
||||
|
||||
/* allocate texture for rendering */
|
||||
ldcore->videoenable = TRUE;
|
||||
ldcore->videotex = render_texture_alloc(NULL, NULL);
|
||||
if (ldcore->videotex == NULL)
|
||||
fatalerror("Out of memory allocating video texture");
|
||||
|
||||
/* allocate overlay */
|
||||
if (ldcore->config.overwidth > 0 && ldcore->config.overheight > 0 && ldcore->config.overupdate != NULL)
|
||||
{
|
||||
ldcore->overenable = TRUE;
|
||||
ldcore->overbitmap[0] = auto_bitmap_alloc(ldcore->config.overwidth, ldcore->config.overheight, ldcore->config.overformat);
|
||||
ldcore->overbitmap[1] = auto_bitmap_alloc(ldcore->config.overwidth, ldcore->config.overheight, ldcore->config.overformat);
|
||||
ldcore->overtex = render_texture_alloc(NULL, NULL);
|
||||
if (ldcore->overtex == NULL)
|
||||
fatalerror("Out of memory allocating overlay texture");
|
||||
}
|
||||
|
||||
/* initialize the various pieces */
|
||||
init_disc(device);
|
||||
init_video(device);
|
||||
init_audio(device);
|
||||
|
||||
/* register callbacks */
|
||||
config_register(device->machine, "laserdisc", configuration_load, configuration_save);
|
||||
|
||||
return DEVICE_START_OK;
|
||||
}
|
||||
|
||||
|
||||
@ -1470,6 +1646,7 @@ static DEVICE_STOP( laserdisc )
|
||||
static DEVICE_RESET( laserdisc )
|
||||
{
|
||||
laserdisc_state *ld = get_safe_token(device);
|
||||
attotime curtime = timer_get_time();
|
||||
ldcore_data *ldcore = ld->core;
|
||||
int pltype, line;
|
||||
|
||||
@ -1490,11 +1667,14 @@ static DEVICE_RESET( laserdisc )
|
||||
}
|
||||
|
||||
/* set up the general ld */
|
||||
ldcore->videosquelch = 1;
|
||||
ldcore->audiosquelch = 3;
|
||||
|
||||
/* default to track 1 */
|
||||
ldcore->videosquelch = 1;
|
||||
ldcore->fieldnum = 0;
|
||||
ldcore->curtrack = 1;
|
||||
ldcore->attospertrack = 0;
|
||||
ldcore->sliderupdate = curtime;
|
||||
|
||||
/* reset metadata */
|
||||
ldcore->last_frame = 0;
|
||||
ldcore->last_chapter = 0;
|
||||
|
||||
|
@ -55,6 +55,20 @@ enum
|
||||
LDSTATE_OTHER /* other states start here */
|
||||
};
|
||||
|
||||
|
||||
/* slider position */
|
||||
enum _slider_position
|
||||
{
|
||||
SLIDER_MINIMUM, /* at the minimum value */
|
||||
SLIDER_VIRTUAL_LEADIN, /* within the virtual lead-in area */
|
||||
SLIDER_CHD, /* within the boundaries of the CHD */
|
||||
SLIDER_OUTSIDE_CHD, /* outside of the CHD area but before the virtual lead-out area */
|
||||
SLIDER_VIRTUAL_LEADOUT, /* within the virtual lead-out area */
|
||||
SLIDER_MAXIMUM /* at the maximum value */
|
||||
};
|
||||
typedef enum _slider_position slider_position;
|
||||
|
||||
|
||||
/* special frame and chapter numbers from VBI conversion */
|
||||
#define FRAME_NOT_PRESENT -2 /* no frame number information present */
|
||||
#define FRAME_LEAD_IN -1 /* lead-in code detected */
|
||||
@ -109,6 +123,7 @@ typedef struct _laserdisc_state laserdisc_state;
|
||||
struct _laserdisc_state
|
||||
{
|
||||
const device_config * device; /* pointer to owning device */
|
||||
const device_config * screen; /* pointer to the screen device */
|
||||
ldcore_data * core; /* private core data */
|
||||
ldplayer_data * player; /* private player data */
|
||||
|
||||
@ -119,6 +134,7 @@ struct _laserdisc_state
|
||||
|
||||
/* player-specific callbacks */
|
||||
typedef void (*laserdisc_init_func)(laserdisc_state *ld);
|
||||
typedef void (*laserdisc_vsync_func)(laserdisc_state *ld);
|
||||
typedef INT32 (*laserdisc_update_func)(laserdisc_state *ld, const vbi_metadata *vbi, int fieldnum, attotime curtime);
|
||||
typedef void (*laserdisc_w_func)(laserdisc_state *ld, UINT8 prev, UINT8 new);
|
||||
typedef UINT8 (*laserdisc_r_func)(laserdisc_state *ld);
|
||||
@ -134,7 +150,8 @@ struct _ldplayer_interface
|
||||
const rom_entry * romregion; /* pointer to ROM region information */
|
||||
const machine_config_token *machine_config; /* pointer to machine configuration */
|
||||
laserdisc_init_func init; /* initialization callback */
|
||||
laserdisc_update_func update; /* update callback */
|
||||
laserdisc_vsync_func vsync; /* vsync begin callback */
|
||||
laserdisc_update_func update; /* update callback (vblank end) */
|
||||
laserdisc_w_func writedata; /* parallel data write */
|
||||
laserdisc_w_func writeline[LASERDISC_INPUT_LINES]; /* single line write */
|
||||
laserdisc_r_func readdata; /* parallel data read */
|
||||
@ -173,6 +190,15 @@ void ldcore_set_audio_squelch(laserdisc_state *ld, UINT8 squelchleft, UINT8 sque
|
||||
/* set the video squelch state */
|
||||
void ldcore_set_video_squelch(laserdisc_state *ld, UINT8 squelch);
|
||||
|
||||
/* dynamically change the slider speed */
|
||||
void ldcore_set_slider_speed(laserdisc_state *ld, INT32 tracks_per_vsync);
|
||||
|
||||
/* advance the slider by a certain number of tracks */
|
||||
void ldcore_advance_slider(laserdisc_state *ld, INT32 numtracks);
|
||||
|
||||
/* get the current slider position */
|
||||
slider_position ldcore_get_slider_position(laserdisc_state *ld);
|
||||
|
||||
|
||||
|
||||
/* ----- generic implementations ----- */
|
||||
|
@ -76,6 +76,7 @@ struct _ldplayer_data
|
||||
/* low-level emulation data */
|
||||
int cpunum;
|
||||
UINT8 pia[0x100];
|
||||
UINT8 vsync;
|
||||
UINT8 porta;
|
||||
UINT8 portb;
|
||||
UINT8 pia_porta;
|
||||
@ -92,9 +93,12 @@ static void pr8210_init(laserdisc_state *ld);
|
||||
static void pr8210_soft_reset(laserdisc_state *ld);
|
||||
static void pr8210_update_squelch(laserdisc_state *ld);
|
||||
static int pr8210_switch_state(laserdisc_state *ld, UINT8 newstate, INT32 stateparam);
|
||||
static INT32 pr8210_hle_update(laserdisc_state *ld, const vbi_metadata *vbi, int fieldnum, attotime curtime);
|
||||
#if (EMULATE_PR8210_ROM)
|
||||
static void pr8210_vsync(laserdisc_state *ld);
|
||||
static INT32 pr8210_update(laserdisc_state *ld, const vbi_metadata *vbi, int fieldnum, attotime curtime);
|
||||
#if (!EMULATE_PR8210_ROM)
|
||||
static void pr8210_command(laserdisc_state *ld);
|
||||
#else
|
||||
static void pr8210_hle_command(laserdisc_state *ld);
|
||||
#endif
|
||||
static void pr8210_control_w(laserdisc_state *ld, UINT8 prev, UINT8 data);
|
||||
|
||||
@ -131,12 +135,16 @@ const ldplayer_interface pr8210_interface =
|
||||
#if EMULATE_PR8210_ROM
|
||||
rom_pr8210, /* pointer to ROM region information */
|
||||
machine_config_pr8210, /* pointer to machine configuration */
|
||||
pr8210_init, /* initialization callback */
|
||||
pr8210_vsync, /* vsync callback */
|
||||
pr8210_update, /* update callback */
|
||||
#else
|
||||
NULL, /* pointer to ROM region information */
|
||||
NULL, /* pointer to machine configuration */
|
||||
#endif
|
||||
pr8210_init, /* initialization callback */
|
||||
pr8210_update, /* update callback */
|
||||
NULL, /* vsync callback */
|
||||
pr8210_hle_update, /* update callback */
|
||||
#endif
|
||||
NULL, /* parallel data write */
|
||||
{ /* single line write: */
|
||||
NULL, /* LASERDISC_LINE_ENTER */
|
||||
@ -160,7 +168,8 @@ const ldplayer_interface simutrek_interface =
|
||||
NULL, /* pointer to ROM region information */
|
||||
NULL, /* pointer to machine configuration */
|
||||
simutrek_init, /* initialization callback */
|
||||
pr8210_update, /* update callback */
|
||||
NULL, /* vsync callback */
|
||||
pr8210_hle_update, /* update callback */
|
||||
simutrek_data_w, /* parallel data write */
|
||||
{ /* single line write: */
|
||||
NULL, /* LASERDISC_LINE_ENTER */
|
||||
@ -178,7 +187,7 @@ const ldplayer_interface simutrek_interface =
|
||||
|
||||
|
||||
/***************************************************************************
|
||||
PIONEER PR-8210 IMPLEMENTATION
|
||||
INLINE FUNCTIONS
|
||||
***************************************************************************/
|
||||
|
||||
/*-------------------------------------------------
|
||||
@ -193,6 +202,20 @@ INLINE int requires_state_save(UINT8 state)
|
||||
}
|
||||
|
||||
|
||||
/*-------------------------------------------------
|
||||
requires_state_save - returns TRUE if the
|
||||
given state will return to the previous
|
||||
state when done
|
||||
-------------------------------------------------*/
|
||||
|
||||
INLINE void update_audio_squelch(laserdisc_state *ld)
|
||||
{
|
||||
ldplayer_data *player = ld->player;
|
||||
ldcore_set_audio_squelch(ld, (player->porta & 0x40) || !(player->pia_portb & 0x01), (player->porta & 0x40) || !(player->pia_portb & 0x02));
|
||||
}
|
||||
|
||||
|
||||
|
||||
|
||||
/***************************************************************************
|
||||
PIONEER PR-8210 IMPLEMENTATION
|
||||
@ -350,11 +373,102 @@ static int pr8210_switch_state(laserdisc_state *ld, UINT8 newstate, INT32 parame
|
||||
|
||||
|
||||
/*-------------------------------------------------
|
||||
pr8210_update - Pioneer PR-8210-specific
|
||||
update callback
|
||||
pr8210_vsync - Start of VSYNC callback
|
||||
-------------------------------------------------*/
|
||||
|
||||
#if (EMULATE_PR8210_ROM)
|
||||
static TIMER_CALLBACK( vsync_off )
|
||||
{
|
||||
ldplayer_data *player = ptr;
|
||||
player->vsync = FALSE;
|
||||
}
|
||||
|
||||
static void pr8210_vsync(laserdisc_state *ld)
|
||||
{
|
||||
ldplayer_data *player = ld->player;
|
||||
player->vsync = TRUE;
|
||||
timer_set(attotime_mul(video_screen_get_scan_period(ld->screen), 4), player, 0, vsync_off);
|
||||
}
|
||||
#endif
|
||||
|
||||
|
||||
/*-------------------------------------------------
|
||||
pr8210_update - Pioneer PR-8210-specific
|
||||
update callback when using a ROM
|
||||
-------------------------------------------------*/
|
||||
|
||||
#if (EMULATE_PR8210_ROM)
|
||||
|
||||
static INT32 pr8210_update(laserdisc_state *ld, const vbi_metadata *vbi, int fieldnum, attotime curtime)
|
||||
{
|
||||
ldplayer_data *player = ld->player;
|
||||
UINT8 focus_on = !(player->porta & 0x08);
|
||||
UINT8 laser_on = !(player->portb & 0x01);
|
||||
UINT8 spdl_on = !(player->porta & 0x10);
|
||||
INT32 advanceby = 0;
|
||||
int frame, chapter;
|
||||
|
||||
/* update PIA registers based on vbi code */
|
||||
frame = frame_from_metadata(vbi);
|
||||
chapter = chapter_from_metadata(vbi);
|
||||
if (focus_on && laser_on && !(player->pia[0x80] & 1))
|
||||
{
|
||||
if (frame == FRAME_LEAD_IN)
|
||||
player->pia[0xc0] = 0x10; /* or 0x12 */
|
||||
else if (frame == FRAME_LEAD_OUT)
|
||||
player->pia[0xc0] = 0x11;
|
||||
else if (frame != FRAME_NOT_PRESENT)
|
||||
{
|
||||
player->pia[0xc0] = 0x00;
|
||||
player->pia[0x22] = 0xf0 | ((frame / 10000) % 10);
|
||||
player->pia[0x23] = 0xf0 | ((frame / 1000) % 10);
|
||||
player->pia[0x24] = 0xf0 | ((frame / 100) % 10);
|
||||
player->pia[0x25] = 0xf0 | ((frame / 10) % 10);
|
||||
player->pia[0x26] = 0xf0 | ((frame / 1) % 10);
|
||||
}
|
||||
else if (chapter != CHAPTER_NOT_PRESENT)
|
||||
{
|
||||
player->pia[0xc0] = 0x13;
|
||||
player->pia[0x20] = 0xf0 | ((chapter / 10) % 10);
|
||||
player->pia[0x21] = 0xf0 | ((chapter / 1) % 10);
|
||||
}
|
||||
}
|
||||
player->pia[0xc0] |= 4;//fieldnum << 2;
|
||||
|
||||
if (spdl_on)
|
||||
advanceby = fieldnum;
|
||||
|
||||
/* update overlay */
|
||||
if ((player->pia[0x80] & 1) || player->framedisplay)
|
||||
{
|
||||
char buffer[16] = { 0 };
|
||||
int i;
|
||||
for (i = 0; i < 15; i++)
|
||||
{
|
||||
UINT8 c = player->pia[0x22 + i];
|
||||
if (c >= 0xf0 && c <= 0xf9)
|
||||
c = '0' + (c - 0xf0);
|
||||
else if (c < 0x20 || c > 0x7f)
|
||||
c = '?';
|
||||
buffer[i] = c;
|
||||
}
|
||||
popmessage("%s", buffer);
|
||||
}
|
||||
player->framedisplay = 0;
|
||||
|
||||
if (advanceby != 0)
|
||||
printf("Advancing by %d\n", advanceby);
|
||||
return advanceby;
|
||||
}
|
||||
#endif
|
||||
|
||||
|
||||
/*-------------------------------------------------
|
||||
pr8210_hle_update - Pioneer PR-8210-specific
|
||||
update callback when using HLE
|
||||
-------------------------------------------------*/
|
||||
|
||||
static INT32 pr8210_hle_update(laserdisc_state *ld, const vbi_metadata *vbi, int fieldnum, attotime curtime)
|
||||
{
|
||||
ldplayer_state newstate;
|
||||
INT32 advanceby = 0;
|
||||
@ -422,13 +536,14 @@ static INT32 pr8210_update(laserdisc_state *ld, const vbi_metadata *vbi, int fie
|
||||
}
|
||||
|
||||
|
||||
|
||||
/*-------------------------------------------------
|
||||
pr8210_command - Pioneer PR-8210-specific
|
||||
pr8210_hle_command - Pioneer PR-8210-specific
|
||||
command processing
|
||||
-------------------------------------------------*/
|
||||
|
||||
#if (!EMULATE_PR8210_ROM)
|
||||
static void pr8210_command(laserdisc_state *ld)
|
||||
static void pr8210_hle_command(laserdisc_state *ld)
|
||||
{
|
||||
ldplayer_data *player = ld->player;
|
||||
UINT8 cmd = player->lastcommand;
|
||||
@ -623,12 +738,14 @@ static void pr8210_control_w(laserdisc_state *ld, UINT8 prev, UINT8 data)
|
||||
//printf("New command = %02X (last=%02X)\n", newcommand, player->lastcommand);
|
||||
|
||||
#if EMULATE_PR8210_ROM
|
||||
printf("Command = %02X\n", newcommand);
|
||||
// player->pia_porta = BITSWAP8(newcommand, 4,3,2,1,0,5,6,7);
|
||||
player->pia_porta = BITSWAP8(newcommand, 0,1,2,3,4,5,6,7);
|
||||
#else
|
||||
/* if we got a double command, act on it */
|
||||
if (newcommand == player->lastcommand)
|
||||
{
|
||||
pr8210_command(ld);
|
||||
pr8210_hle_command(ld);
|
||||
player->lastcommand = 0;
|
||||
}
|
||||
else
|
||||
@ -783,22 +900,33 @@ void simutrek_set_cmd_ack_callback(const device_config *device, void (*callback)
|
||||
*
|
||||
*************************************/
|
||||
|
||||
static ldplayer_data *find_pr8210(running_machine *machine)
|
||||
static laserdisc_state *find_pr8210(running_machine *machine)
|
||||
{
|
||||
return ldcore_get_safe_token(device_list_first(machine->config->devicelist, LASERDISC))->player;
|
||||
return ldcore_get_safe_token(device_list_first(machine->config->devicelist, LASERDISC));
|
||||
}
|
||||
|
||||
|
||||
static READ8_HANDLER( pr8210_pia_r )
|
||||
{
|
||||
ldplayer_data *player = find_pr8210(machine);
|
||||
laserdisc_state *ld = find_pr8210(machine);
|
||||
ldplayer_data *player = ld->player;
|
||||
UINT8 result = player->pia[offset];
|
||||
switch (offset)
|
||||
{
|
||||
case 0x22:
|
||||
case 0x23:
|
||||
case 0x24:
|
||||
case 0x25:
|
||||
case 0x26:
|
||||
case 0x27:
|
||||
case 0xc0:
|
||||
case 0xe0:
|
||||
break;
|
||||
|
||||
case 0xa0:
|
||||
// printf("%03X:pia_r(%02X) = %02X\n", activecpu_get_pc(), offset, player->pia_porta);
|
||||
result = player->pia_porta;
|
||||
player->pia_porta = 0;
|
||||
// player->pia_porta = 0;
|
||||
break;
|
||||
|
||||
default:
|
||||
@ -837,21 +965,30 @@ static WRITE8_HANDLER( pr8210_pia_w )
|
||||
$C0 (R) = stored to ($2E)
|
||||
$E0 (R) = stored to ($2F)
|
||||
*/
|
||||
ldplayer_data *player = find_pr8210(machine);
|
||||
laserdisc_state *ld = find_pr8210(machine);
|
||||
ldplayer_data *player = ld->player;
|
||||
if (player->pia[offset] != data)
|
||||
{
|
||||
switch (offset)
|
||||
{
|
||||
case 0x40:
|
||||
if (!(data & 0x02) && (player->pia[offset] & 0x02))
|
||||
player->framedisplay = 1;
|
||||
break;
|
||||
|
||||
case 0x60:
|
||||
printf("%03X:pia_w(%02X) = %02X (PORT B LEDS:", activecpu_get_pc(), offset, data);
|
||||
if (!(data & 0x01)) printf(" AUDIO1");
|
||||
if (!(data & 0x02)) printf(" AUDIO2");
|
||||
if (!(data & 0x04)) printf(" CLV");
|
||||
if (!(data & 0x08)) printf(" CAV");
|
||||
printf(" LED123=%c%c%c", (data & 0x10) ? 'H' : 'L', (data & 0x20) ? 'H' : 'L', (data & 0x40) ? 'H' : 'L');
|
||||
output_set_value("pr8210_audio1", (data & 0x01) != 0);
|
||||
output_set_value("pr8210_audio2", (data & 0x02) != 0);
|
||||
output_set_value("pr8210_clv", (data & 0x04) != 0);
|
||||
output_set_value("pr8210_cav", (data & 0x08) != 0);
|
||||
output_set_value("pr8210_led1", (data & 0x10) == 0);
|
||||
output_set_value("pr8210_led2", (data & 0x20) == 0);
|
||||
output_set_value("pr8210_led3", (data & 0x40) == 0);
|
||||
if (!(data & 0x80)) printf(" ???");
|
||||
printf(")\n");
|
||||
player->pia_portb = data;
|
||||
update_audio_squelch(ld);
|
||||
break;
|
||||
|
||||
default:
|
||||
@ -866,7 +1003,7 @@ static READ8_HANDLER( pr8210_bus_r )
|
||||
{
|
||||
/*
|
||||
$80 = n/c
|
||||
$40 = (in) slide pot interrupt source (slider position limit detector, inside and outside)
|
||||
$40 = (in) slider pot interrupt source (slider position limit detector, inside and outside)
|
||||
$20 = n/c
|
||||
$10 = (in) /FOCUS LOCK
|
||||
$08 = (in) /SPDL LOCK
|
||||
@ -874,12 +1011,31 @@ static READ8_HANDLER( pr8210_bus_r )
|
||||
$02 = (in) FG via op-amp (spindle motor stop detector)
|
||||
$01 = (in) SLOW TIMER OUT
|
||||
*/
|
||||
offs_t pc = activecpu_get_pc();
|
||||
if (pc != 0x11c)
|
||||
printf("%03X:bus_r\n", pc);
|
||||
laserdisc_state *ld = find_pr8210(machine);
|
||||
ldplayer_data *player = ld->player;
|
||||
slider_position sliderpos = ldcore_get_slider_position(ld);
|
||||
UINT8 focus_on = !(player->porta & 0x08);
|
||||
UINT8 spdl_on = !(player->porta & 0x10);
|
||||
UINT8 result = 0x00;
|
||||
|
||||
/* bus bit 6: slider position limit detector, inside and outside */
|
||||
if (sliderpos != SLIDER_MINIMUM && sliderpos != SLIDER_MAXIMUM)
|
||||
result |= 0x40;
|
||||
|
||||
/* bus bit 4: /FOCUS LOCK */
|
||||
if (!focus_on)
|
||||
result |= 0x10;
|
||||
|
||||
/* bus bit 3: /SPDL LOCK */
|
||||
if (!spdl_on)
|
||||
result |= 0x08;
|
||||
|
||||
/* bus bit 1: spindle motor stop detector */
|
||||
if (!spdl_on)
|
||||
result |= 0x02;
|
||||
|
||||
/* loop at beginning waits for $40=0, $02=1 */
|
||||
return 0xff & ~0x40 & ~0x04;
|
||||
return result;
|
||||
}
|
||||
|
||||
static WRITE8_HANDLER( pr8210_porta_w )
|
||||
@ -894,21 +1050,33 @@ static WRITE8_HANDLER( pr8210_porta_w )
|
||||
$02 = (out) SCAN A (/SCAN)
|
||||
$01 = (out) JUMP TRG (jump back trigger, clock on high->low)
|
||||
*/
|
||||
ldplayer_data *player = find_pr8210(machine);
|
||||
if (data != player->porta)
|
||||
laserdisc_state *ld = find_pr8210(machine);
|
||||
ldplayer_data *player = ld->player;
|
||||
if ((data & 0xfe) != (player->porta & 0xfe))
|
||||
{
|
||||
int direction = (data & 0x80) ? 1 : -1;
|
||||
|
||||
printf("%03X:porta_w = %02X", activecpu_get_pc(), data);
|
||||
if (!(data & 0x01)) printf(" JUMPTRG");
|
||||
if (!(data & 0x01) && (player->porta & 0x01))
|
||||
ldcore_advance_slider(ld, direction);
|
||||
if (!(data & 0x02))
|
||||
{
|
||||
printf(" SCAN:%c:%c", (data & 0x80) ? 'F' : 'R', (data & 0x04) ? 'L' : 'H');
|
||||
}
|
||||
if (!(data & 0x08)) printf(" /FOCUSON");
|
||||
if (!(data & 0x10)) printf(" /SPDLON");
|
||||
if (data & 0x20) printf(" VIDEOSQ");
|
||||
if (data & 0x40) printf(" AUDIOSQ");
|
||||
printf("\n");
|
||||
player->porta = data;
|
||||
|
||||
ldcore_set_video_squelch(ld, (data & 0x20) != 0);
|
||||
update_audio_squelch(ld);
|
||||
if (!(data & 0x02))
|
||||
{
|
||||
int delta = (data & 0x04) ? PR8210_SCAN_SPEED : PR8210_SEEK_FAST_SPEED;
|
||||
ldcore_set_slider_speed(ld, delta * direction);
|
||||
}
|
||||
else
|
||||
ldcore_set_slider_speed(ld, 0);
|
||||
}
|
||||
}
|
||||
|
||||
@ -924,7 +1092,8 @@ static WRITE8_HANDLER( pr8210_portb_w )
|
||||
$02 = (out) ???
|
||||
$01 = (out) LASER ON
|
||||
*/
|
||||
ldplayer_data *player = find_pr8210(machine);
|
||||
laserdisc_state *ld = find_pr8210(machine);
|
||||
ldplayer_data *player = ld->player;
|
||||
cpunum_set_input_line(machine, player->cpunum, 0, (data & 0x40) ? CLEAR_LINE : ASSERT_LINE);
|
||||
if ((data & 0x7f) != (player->portb & 0x7f))
|
||||
{
|
||||
@ -933,7 +1102,7 @@ static WRITE8_HANDLER( pr8210_portb_w )
|
||||
if (!(data & 0x02)) printf(" ???");
|
||||
if (!(data & 0x04)) printf(" TP1");
|
||||
if (!(data & 0x08)) printf(" TP2");
|
||||
if (!(data & 0x10)) printf(" STANDBYLED");
|
||||
output_set_value("pr8210_standby", !(data & 0x10));
|
||||
if (!(data & 0x20)) printf(" SLOWTRG");
|
||||
if (!(data & 0x40)) printf(" IRQGEN");
|
||||
// if (data & 0x80) printf(" PIASEL");
|
||||
@ -943,6 +1112,21 @@ static WRITE8_HANDLER( pr8210_portb_w )
|
||||
}
|
||||
|
||||
|
||||
static READ8_HANDLER( pr8210_t0_r )
|
||||
{
|
||||
/* returns VSYNC state */
|
||||
laserdisc_state *ld = find_pr8210(machine);
|
||||
return !ld->player->vsync;
|
||||
}
|
||||
|
||||
|
||||
static READ8_HANDLER( pr8210_t1_r )
|
||||
{
|
||||
/* must return 1 or else it tries to jump to an external ROM */
|
||||
return 1;
|
||||
}
|
||||
|
||||
|
||||
static ADDRESS_MAP_START( pr8210_map, ADDRESS_SPACE_PROGRAM, 8 )
|
||||
AM_RANGE(0x000, 0x7ff) AM_ROM
|
||||
ADDRESS_MAP_END
|
||||
@ -953,6 +1137,8 @@ static ADDRESS_MAP_START( pr8210_portmap, ADDRESS_SPACE_IO, 8 )
|
||||
AM_RANGE(MCS48_PORT_BUS, MCS48_PORT_BUS) AM_READ(pr8210_bus_r)
|
||||
AM_RANGE(MCS48_PORT_P1, MCS48_PORT_P1) AM_WRITE(pr8210_porta_w)
|
||||
AM_RANGE(MCS48_PORT_P2, MCS48_PORT_P2) AM_WRITE(pr8210_portb_w)
|
||||
AM_RANGE(MCS48_PORT_T0, MCS48_PORT_T0) AM_READ(pr8210_t0_r)
|
||||
AM_RANGE(MCS48_PORT_T1, MCS48_PORT_T1) AM_READ(pr8210_t1_r)
|
||||
ADDRESS_MAP_END
|
||||
|
||||
|
||||
|
@ -102,6 +102,7 @@ const ldplayer_interface ldv1000_interface =
|
||||
NULL, /* pointer to ROM region information */
|
||||
NULL, /* pointer to machine configuration */
|
||||
ldv1000_init, /* initialization callback */
|
||||
NULL, /* vsync callback */
|
||||
ldv1000_update, /* update callback */
|
||||
ldv1000_data_w, /* parallel data write */
|
||||
{ /* single line write: */
|
||||
|
@ -153,6 +153,8 @@ static DEVICE_START( msm6242 )
|
||||
msm6242->reg[1] = 0;
|
||||
msm6242->reg[2] = 0;
|
||||
memset(&msm6242->hold_time, 0, sizeof(mame_system_time));
|
||||
|
||||
return DEVICE_START_OK;
|
||||
}
|
||||
|
||||
|
||||
|
@ -372,6 +372,8 @@ static DEVICE_START( pic8259 ) {
|
||||
pic8259_t *pic8259 = get_safe_token(device);
|
||||
|
||||
pic8259->intf = device->static_config;
|
||||
|
||||
return DEVICE_START_OK;
|
||||
}
|
||||
|
||||
|
||||
|
@ -1044,7 +1044,7 @@ void pit8253_set_clock_signal(const device_config *device, int timerno, int stat
|
||||
}
|
||||
|
||||
|
||||
static void common_start( const device_config *device, int device_type ) {
|
||||
static device_start_err common_start( const device_config *device, int device_type ) {
|
||||
pit8253_t *pit8253 = get_safe_token(device);
|
||||
char unique_tag[30];
|
||||
int timerno;
|
||||
@ -1087,16 +1087,18 @@ static void common_start( const device_config *device, int device_type ) {
|
||||
state_save_register_item(unique_tag, timerno, timer->programmed);
|
||||
state_save_register_item(unique_tag, timerno, timer->clock);
|
||||
}
|
||||
|
||||
return DEVICE_START_OK;
|
||||
}
|
||||
|
||||
|
||||
static DEVICE_START( pit8253 ) {
|
||||
common_start( device, TYPE_PIT8253 );
|
||||
return common_start( device, TYPE_PIT8253 );
|
||||
}
|
||||
|
||||
|
||||
static DEVICE_START( pit8254 ) {
|
||||
common_start( device, TYPE_PIT8254 );
|
||||
return common_start( device, TYPE_PIT8254 );
|
||||
}
|
||||
|
||||
|
||||
|
@ -539,6 +539,8 @@ static DEVICE_START( smc91c9x )
|
||||
state_save_register_item_array(unique_tag, 0, smc->tx);
|
||||
state_save_register_item(unique_tag, 0, smc->sent);
|
||||
state_save_register_item(unique_tag, 0, smc->recd);
|
||||
|
||||
return DEVICE_START_OK;
|
||||
}
|
||||
|
||||
|
||||
|
@ -339,6 +339,8 @@ static DEVICE_START(timekeeper)
|
||||
timer = timer_alloc( timekeeper_tick, c );
|
||||
duration = ATTOTIME_IN_SEC(1);
|
||||
timer_adjust_periodic( timer, duration, 0, duration );
|
||||
|
||||
return DEVICE_START_OK;
|
||||
}
|
||||
|
||||
static DEVICE_START(m48t02)
|
||||
@ -357,7 +359,7 @@ static DEVICE_START(m48t02)
|
||||
c->offset_flags = -1;
|
||||
c->size = 0x800;
|
||||
|
||||
DEVICE_START_CALL( timekeeper );
|
||||
return DEVICE_START_CALL( timekeeper );
|
||||
}
|
||||
|
||||
static DEVICE_START(m48t35)
|
||||
@ -376,7 +378,7 @@ static DEVICE_START(m48t35)
|
||||
c->offset_flags = -1;
|
||||
c->size = 0x8000;
|
||||
|
||||
DEVICE_START_CALL( timekeeper );
|
||||
return DEVICE_START_CALL( timekeeper );
|
||||
}
|
||||
|
||||
static DEVICE_START(m48t58)
|
||||
@ -395,7 +397,7 @@ static DEVICE_START(m48t58)
|
||||
c->offset_flags = -1;
|
||||
c->size = 0x2000;
|
||||
|
||||
DEVICE_START_CALL( timekeeper );
|
||||
return DEVICE_START_CALL( timekeeper );
|
||||
}
|
||||
|
||||
static DEVICE_START(mk48t08)
|
||||
@ -414,7 +416,7 @@ static DEVICE_START(mk48t08)
|
||||
c->offset_flags = 0x1ff0;
|
||||
c->size = 0x2000;
|
||||
|
||||
DEVICE_START_CALL( timekeeper );
|
||||
return DEVICE_START_CALL( timekeeper );
|
||||
}
|
||||
|
||||
/*-------------------------------------------------
|
||||
|
@ -447,6 +447,8 @@ static DEVICE_START( z80dma )
|
||||
state_save_register_item(unique_tag, 0, z80dma->is_read);
|
||||
state_save_register_item(unique_tag, 0, z80dma->cur_cycle);
|
||||
state_save_register_item(unique_tag, 0, z80dma->latch);
|
||||
|
||||
return DEVICE_START_OK;
|
||||
}
|
||||
|
||||
|
||||
|
@ -822,6 +822,8 @@ static DEVICE_START( speaker_output )
|
||||
/* copy in all the relevant info */
|
||||
info->speaker = device->inline_config;
|
||||
info->tag = device->tag;
|
||||
|
||||
return DEVICE_START_OK;
|
||||
}
|
||||
|
||||
|
||||
|
@ -1071,6 +1071,8 @@ static DEVICE_START( timer )
|
||||
fatalerror("Unknown timer device type");
|
||||
break;
|
||||
}
|
||||
|
||||
return DEVICE_START_OK;
|
||||
}
|
||||
|
||||
|
||||
|
@ -79,6 +79,7 @@ struct _screen_state
|
||||
|
||||
/* screen specific VBLANK callbacks */
|
||||
vblank_state_changed_func vblank_callback[MAX_VBLANK_CALLBACKS]; /* the array of callbacks */
|
||||
void * vblank_callback_param[MAX_VBLANK_CALLBACKS]; /* array of parameters */
|
||||
};
|
||||
|
||||
|
||||
@ -1140,10 +1141,10 @@ UINT64 video_screen_get_frame_number(const device_config *screen)
|
||||
VBLANK callback for a specific screen
|
||||
-------------------------------------------------*/
|
||||
|
||||
void video_screen_register_vblank_callback(const device_config *screen, vblank_state_changed_func vblank_callback)
|
||||
void video_screen_register_vblank_callback(const device_config *screen, vblank_state_changed_func vblank_callback, void *param)
|
||||
{
|
||||
int i, found;
|
||||
screen_state *state = get_safe_token(screen);
|
||||
int i, found;
|
||||
|
||||
/* validate arguments */
|
||||
assert(vblank_callback != NULL);
|
||||
@ -1164,7 +1165,10 @@ void video_screen_register_vblank_callback(const device_config *screen, vblank_s
|
||||
|
||||
/* if not found, register and increment count */
|
||||
if (!found)
|
||||
{
|
||||
state->vblank_callback[i] = vblank_callback;
|
||||
state->vblank_callback_param[i] = param;
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
@ -1264,6 +1268,8 @@ static DEVICE_START( video_screen )
|
||||
state_save_register_item(unique_tag, 0, state->vblank_end_time.attoseconds);
|
||||
state_save_register_item(unique_tag, 0, state->frame_number);
|
||||
state_save_register_postload(device->machine, video_screen_postload, (void *)device);
|
||||
|
||||
return DEVICE_START_OK;
|
||||
}
|
||||
|
||||
|
||||
@ -1366,7 +1372,7 @@ static TIMER_CALLBACK( vblank_begin_callback )
|
||||
|
||||
/* call the screen specific callbacks */
|
||||
for (i = 0; state->vblank_callback[i] != NULL; i++)
|
||||
(*state->vblank_callback[i])(screen, TRUE);
|
||||
(*state->vblank_callback[i])(screen, state->vblank_callback_param[i], TRUE);
|
||||
|
||||
/* if this is the primary screen and we need to update now */
|
||||
if (screen == machine->primary_screen && !(machine->config->video_attributes & VIDEO_UPDATE_AFTER_VBLANK))
|
||||
@ -1396,7 +1402,7 @@ static TIMER_CALLBACK( vblank_end_callback )
|
||||
|
||||
/* call the screen specific callbacks */
|
||||
for (i = 0; state->vblank_callback[i] != NULL; i++)
|
||||
(*state->vblank_callback[i])(screen, FALSE);
|
||||
(*state->vblank_callback[i])(screen, state->vblank_callback_param[i], FALSE);
|
||||
|
||||
/* if this is the primary screen and we need to update now */
|
||||
if (screen == machine->primary_screen && (machine->config->video_attributes & VIDEO_UPDATE_AFTER_VBLANK))
|
||||
|
@ -87,7 +87,7 @@ struct _screen_config
|
||||
in the VBLANK state
|
||||
-------------------------------------------------*/
|
||||
|
||||
typedef void (*vblank_state_changed_func)(const device_config *device, int vblank_state);
|
||||
typedef void (*vblank_state_changed_func)(const device_config *device, void *param, int vblank_state);
|
||||
|
||||
|
||||
|
||||
@ -209,7 +209,7 @@ attotime video_screen_get_frame_period(const device_config *screen);
|
||||
UINT64 video_screen_get_frame_number(const device_config *screen);
|
||||
|
||||
/* registers a VBLANK callback for the given screen */
|
||||
void video_screen_register_vblank_callback(const device_config *screen, vblank_state_changed_func vblank_callback);
|
||||
void video_screen_register_vblank_callback(const device_config *screen, vblank_state_changed_func vblank_callback, void *param);
|
||||
|
||||
|
||||
/* ----- video screen device interface ----- */
|
||||
|
@ -839,6 +839,8 @@ static DEVICE_START( cdp1869 )
|
||||
state_save_register_item(unique_tag, 0, cdp1869->toneamp);
|
||||
state_save_register_item(unique_tag, 0, cdp1869->wnfreq);
|
||||
state_save_register_item(unique_tag, 0, cdp1869->wnamp);
|
||||
|
||||
return DEVICE_START_OK;
|
||||
}
|
||||
|
||||
static DEVICE_SET_INFO( cdp1869 )
|
||||
|
@ -675,7 +675,7 @@ void mc6845_update(const device_config *device, bitmap_t *bitmap, const rectangl
|
||||
|
||||
|
||||
/* device interface */
|
||||
static void common_start(const device_config *device, int device_type)
|
||||
static device_start_err common_start(const device_config *device, int device_type)
|
||||
{
|
||||
mc6845_t *mc6845 = get_safe_token(device);
|
||||
char unique_tag[30];
|
||||
@ -746,41 +746,43 @@ static void common_start(const device_config *device, int device_type)
|
||||
state_save_register_item(unique_tag, 0, mc6845->light_pen_latched);
|
||||
state_save_register_item(unique_tag, 0, mc6845->cursor_state);
|
||||
state_save_register_item(unique_tag, 0, mc6845->cursor_blink_count);
|
||||
|
||||
return DEVICE_START_OK;
|
||||
}
|
||||
|
||||
static DEVICE_START( mc6845 )
|
||||
{
|
||||
common_start(device, TYPE_MC6845);
|
||||
return common_start(device, TYPE_MC6845);
|
||||
}
|
||||
|
||||
static DEVICE_START( mc6845_1 )
|
||||
{
|
||||
common_start(device, TYPE_MC6845_1);
|
||||
return common_start(device, TYPE_MC6845_1);
|
||||
}
|
||||
|
||||
static DEVICE_START( c6545_1 )
|
||||
{
|
||||
common_start(device, TYPE_C6545_1);
|
||||
return common_start(device, TYPE_C6545_1);
|
||||
}
|
||||
|
||||
static DEVICE_START( r6545_1 )
|
||||
{
|
||||
common_start(device, TYPE_R6545_1);
|
||||
return common_start(device, TYPE_R6545_1);
|
||||
}
|
||||
|
||||
static DEVICE_START( h46505 )
|
||||
{
|
||||
common_start(device, TYPE_H46505);
|
||||
return common_start(device, TYPE_H46505);
|
||||
}
|
||||
|
||||
static DEVICE_START( hd6845 )
|
||||
{
|
||||
common_start(device, TYPE_HD6845);
|
||||
return common_start(device, TYPE_HD6845);
|
||||
}
|
||||
|
||||
static DEVICE_START( sy6545_1 )
|
||||
{
|
||||
common_start(device, TYPE_SY6545_1);
|
||||
return common_start(device, TYPE_SY6545_1);
|
||||
}
|
||||
|
||||
|
||||
|
@ -4616,6 +4616,8 @@ static DEVICE_START( voodoo )
|
||||
|
||||
/* register for save states */
|
||||
init_save_state(device);
|
||||
|
||||
return DEVICE_START_OK;
|
||||
}
|
||||
|
||||
|
||||
|
@ -87,7 +87,7 @@ static TIMER_CALLBACK( watchdog_callback )
|
||||
timers
|
||||
-------------------------------------------------*/
|
||||
|
||||
static void on_vblank(const device_config *screen, int vblank_state)
|
||||
static void on_vblank(const device_config *screen, void *param, int vblank_state)
|
||||
{
|
||||
/* VBLANK starting */
|
||||
if (vblank_state && watchdog_enabled)
|
||||
@ -121,7 +121,7 @@ void watchdog_reset(running_machine *machine)
|
||||
|
||||
/* register a VBLANK callback for the primary screen */
|
||||
if (machine->primary_screen != NULL)
|
||||
video_screen_register_vblank_callback(machine->primary_screen, on_vblank);
|
||||
video_screen_register_vblank_callback(machine->primary_screen, on_vblank, NULL);
|
||||
}
|
||||
|
||||
/* timer-based watchdog? */
|
||||
|
121
src/ldplayer/layout/pr8210.lay
Normal file
121
src/ldplayer/layout/pr8210.lay
Normal file
@ -0,0 +1,121 @@
|
||||
<?xml version="1.0"?>
|
||||
<mamelayout version="2">
|
||||
<element name="audio1" defstate="0">
|
||||
<text string="AUDIO1" state="0">
|
||||
<color red="0.1" green="0.1" blue="0.1" />
|
||||
<bounds x="0" y="0.1" width="1" height="0.8" />
|
||||
</text>
|
||||
<text string="AUDIO1" state="1">
|
||||
<color red="1.0" green="1.0" blue="1.0" />
|
||||
<bounds x="0" y="0.1" width="1" height="0.8" />
|
||||
</text>
|
||||
</element>
|
||||
|
||||
<element name="audio2" defstate="0">
|
||||
<text string="AUDIO2" state="0">
|
||||
<color red="0.1" green="0.1" blue="0.1" />
|
||||
<bounds x="0" y="0.1" width="1" height="0.8" />
|
||||
</text>
|
||||
<text string="AUDIO2" state="1">
|
||||
<color red="1.0" green="1.0" blue="1.0" />
|
||||
<bounds x="0" y="0.1" width="1" height="0.8" />
|
||||
</text>
|
||||
</element>
|
||||
|
||||
<element name="clv" defstate="0">
|
||||
<text string="CLV" state="0">
|
||||
<color red="0.1" green="0.1" blue="0.1" />
|
||||
<bounds x="0" y="0.1" width="1" height="0.8" />
|
||||
</text>
|
||||
<text string="CLV" state="1">
|
||||
<color red="1.0" green="1.0" blue="1.0" />
|
||||
<bounds x="0" y="0.1" width="1" height="0.8" />
|
||||
</text>
|
||||
</element>
|
||||
|
||||
<element name="cav" defstate="0">
|
||||
<text string="CAV" state="0">
|
||||
<color red="0.1" green="0.1" blue="0.1" />
|
||||
<bounds x="0" y="0.1" width="1" height="0.8" />
|
||||
</text>
|
||||
<text string="CAV" state="1">
|
||||
<color red="1.0" green="1.0" blue="1.0" />
|
||||
<bounds x="0" y="0.1" width="1" height="0.8" />
|
||||
</text>
|
||||
</element>
|
||||
|
||||
<element name="led1" defstate="0">
|
||||
<text string="LED1" state="0">
|
||||
<color red="0.1" green="0.1" blue="0.1" />
|
||||
<bounds x="0" y="0.1" width="1" height="0.8" />
|
||||
</text>
|
||||
<text string="LED1" state="1">
|
||||
<color red="1.0" green="1.0" blue="1.0" />
|
||||
<bounds x="0" y="0.1" width="1" height="0.8" />
|
||||
</text>
|
||||
</element>
|
||||
|
||||
<element name="led2" defstate="0">
|
||||
<text string="LED2" state="0">
|
||||
<color red="0.1" green="0.1" blue="0.1" />
|
||||
<bounds x="0" y="0.1" width="1" height="0.8" />
|
||||
</text>
|
||||
<text string="LED2" state="1">
|
||||
<color red="1.0" green="1.0" blue="1.0" />
|
||||
<bounds x="0" y="0.1" width="1" height="0.8" />
|
||||
</text>
|
||||
</element>
|
||||
|
||||
<element name="led3" defstate="0">
|
||||
<text string="LED3" state="0">
|
||||
<color red="0.1" green="0.1" blue="0.1" />
|
||||
<bounds x="0" y="0.1" width="1" height="0.8" />
|
||||
</text>
|
||||
<text string="LED3" state="1">
|
||||
<color red="1.0" green="1.0" blue="1.0" />
|
||||
<bounds x="0" y="0.1" width="1" height="0.8" />
|
||||
</text>
|
||||
</element>
|
||||
|
||||
<element name="standby" defstate="0">
|
||||
<text string="STANDBY" state="0">
|
||||
<color red="0.1" green="0.1" blue="0.1" />
|
||||
<bounds x="0" y="0.1" width="1" height="0.8" />
|
||||
</text>
|
||||
<text string="STANDBY" state="1">
|
||||
<color red="1.0" green="1.0" blue="1.0" />
|
||||
<bounds x="0" y="0.1" width="1" height="0.8" />
|
||||
</text>
|
||||
</element>
|
||||
|
||||
|
||||
<view name="Lamps">
|
||||
<screen index="0">
|
||||
<bounds left="0" top="0" right="4" bottom="3" />
|
||||
</screen>
|
||||
<bezel name="pr8210_standby" element="standby">
|
||||
<bounds x="0" y="3.1" width="0.4" height="0.1" />
|
||||
</bezel>
|
||||
<bezel name="pr8210_clv" element="clv">
|
||||
<bounds x="0.5" y="3.1" width="0.4" height="0.1" />
|
||||
</bezel>
|
||||
<bezel name="pr8210_cav" element="cav">
|
||||
<bounds x="1.0" y="3.1" width="0.4" height="0.1" />
|
||||
</bezel>
|
||||
<bezel name="pr8210_audio1" element="audio1">
|
||||
<bounds x="1.5" y="3.1" width="0.4" height="0.1" />
|
||||
</bezel>
|
||||
<bezel name="pr8210_audio2" element="audio2">
|
||||
<bounds x="2.0" y="3.1" width="0.4" height="0.1" />
|
||||
</bezel>
|
||||
<bezel name="pr8210_led1" element="led1">
|
||||
<bounds x="2.5" y="3.1" width="0.4" height="0.1" />
|
||||
</bezel>
|
||||
<bezel name="pr8210_led2" element="led2">
|
||||
<bounds x="3.0" y="3.1" width="0.4" height="0.1" />
|
||||
</bezel>
|
||||
<bezel name="pr8210_led3" element="led3">
|
||||
<bounds x="3.5" y="3.1" width="0.4" height="0.1" />
|
||||
</bezel>
|
||||
</view>
|
||||
</mamelayout>
|
@ -15,6 +15,9 @@
|
||||
#include "machine/laserdsc.h"
|
||||
#include <ctype.h>
|
||||
|
||||
#include "pr8210.lh"
|
||||
|
||||
|
||||
|
||||
/*************************************
|
||||
*
|
||||
@ -59,7 +62,6 @@ static input_port_value last_controls;
|
||||
static UINT8 playing;
|
||||
static UINT8 displaying;
|
||||
|
||||
static UINT8 pr8210_last_was_number;
|
||||
static emu_timer *pr8210_bit_timer;
|
||||
static UINT32 pr8210_command_buffer_in, pr8210_command_buffer_out;
|
||||
static UINT8 pr8210_command_buffer[10];
|
||||
@ -138,13 +140,8 @@ static TIMER_CALLBACK( vsync_update )
|
||||
|
||||
/* handle commands */
|
||||
if (!param)
|
||||
{
|
||||
process_commands(laserdisc);
|
||||
|
||||
/* update the laserdisc */
|
||||
laserdisc_vsync(laserdisc);
|
||||
}
|
||||
|
||||
/* set a timer to go off on the next VBLANK */
|
||||
vblank_scanline = video_screen_get_visible_area(machine->primary_screen)->max_y + 1;
|
||||
target = video_screen_get_time_until_pos(machine->primary_screen, vblank_scanline, 0);
|
||||
@ -251,9 +248,7 @@ static MACHINE_RESET( pr8210 )
|
||||
static void pr8210_execute(const device_config *laserdisc, int command)
|
||||
{
|
||||
static const UINT8 digits[10] = { 0x01, 0x11, 0x09, 0x19, 0x05, 0x15, 0x0d, 0x1d, 0x03, 0x13 };
|
||||
int prev_was_number = pr8210_last_was_number;
|
||||
|
||||
pr8210_last_was_number = FALSE;
|
||||
switch (command)
|
||||
{
|
||||
case CMD_SCAN_REVERSE:
|
||||
@ -293,13 +288,8 @@ static void pr8210_execute(const device_config *laserdisc, int command)
|
||||
break;
|
||||
|
||||
case CMD_DISPLAY_ON:
|
||||
// pr8210_add_command(digits[1]);
|
||||
// pr8210_add_command(0xf1);
|
||||
break;
|
||||
|
||||
case CMD_DISPLAY_OFF:
|
||||
// pr8210_add_command(digits[0]);
|
||||
// pr8210_add_command(0xf1);
|
||||
pr8210_add_command(0x0b);
|
||||
break;
|
||||
|
||||
case CMD_0:
|
||||
@ -312,10 +302,7 @@ static void pr8210_execute(const device_config *laserdisc, int command)
|
||||
case CMD_7:
|
||||
case CMD_8:
|
||||
case CMD_9:
|
||||
if (!prev_was_number)
|
||||
pr8210_add_command(0x1a);
|
||||
pr8210_add_command(digits[command - CMD_0]);
|
||||
pr8210_last_was_number = TRUE;
|
||||
break;
|
||||
|
||||
case CMD_SEARCH:
|
||||
@ -443,7 +430,7 @@ static MACHINE_DRIVER_START( ldplayer_core )
|
||||
/* audio hardware */
|
||||
MDRV_SPEAKER_STANDARD_STEREO("left", "right")
|
||||
|
||||
MDRV_SOUND_ADD("laserdisc", CUSTOM, 0)
|
||||
MDRV_SOUND_ADD("ldsound", CUSTOM, 0)
|
||||
MDRV_SOUND_CONFIG(laserdisc_custom_interface)
|
||||
MDRV_SOUND_ROUTE(0, "left", 1.0)
|
||||
MDRV_SOUND_ROUTE(1, "right", 1.0)
|
||||
@ -458,7 +445,7 @@ MACHINE_DRIVER_END
|
||||
|
||||
static MACHINE_DRIVER_START( ldv1000 )
|
||||
MDRV_IMPORT_FROM(ldplayer_ntsc)
|
||||
MDRV_LASERDISC_ADD("laserdisc", PIONEER_LDV1000)
|
||||
MDRV_LASERDISC_ADD("laserdisc", PIONEER_LDV1000, "main", "ldsound")
|
||||
MACHINE_DRIVER_END
|
||||
|
||||
|
||||
@ -466,7 +453,7 @@ static MACHINE_DRIVER_START( pr8210 )
|
||||
MDRV_IMPORT_FROM(ldplayer_ntsc)
|
||||
MDRV_MACHINE_START(pr8210)
|
||||
MDRV_MACHINE_RESET(pr8210)
|
||||
MDRV_LASERDISC_ADD("laserdisc", PIONEER_PR8210)
|
||||
MDRV_LASERDISC_ADD("laserdisc", PIONEER_PR8210, "main", "ldsound")
|
||||
MACHINE_DRIVER_END
|
||||
|
||||
|
||||
@ -569,4 +556,4 @@ static DRIVER_INIT( pr8210 ) { execute_command = pr8210_execute; DRIVER_INIT_CA
|
||||
*************************************/
|
||||
|
||||
GAME( 2008, ldv1000, 0, ldv1000, ldplayer, ldv1000, ROT0, "MAME", "Pioneer LDV-1000 Simulator", 0 )
|
||||
GAME( 2008, pr8210, 0, pr8210, ldplayer, pr8210, ROT0, "MAME", "Pioneer PR-8210 Simulator", 0 )
|
||||
GAMEL( 2008, pr8210, 0, pr8210, ldplayer, pr8210, ROT0, "MAME", "Pioneer PR-8210 Simulator", 0, layout_pr8210 )
|
||||
|
@ -13,8 +13,11 @@
|
||||
LDPSRC = $(SRC)/ldplayer
|
||||
LDPOBJ = $(OBJ)/ldplayer
|
||||
|
||||
LAYOUT = $(LDPOBJ)/layout
|
||||
|
||||
OBJDIRS += \
|
||||
$(LDPOBJ) \
|
||||
$(LAYOUT) \
|
||||
|
||||
|
||||
|
||||
@ -42,3 +45,10 @@ SOUNDS += CUSTOM
|
||||
DRVLIBS = \
|
||||
$(LDPOBJ)/ldpdriv.o \
|
||||
$(LDPOBJ)/ldplayer.o \
|
||||
|
||||
|
||||
#-------------------------------------------------
|
||||
# layout dependencies
|
||||
#-------------------------------------------------
|
||||
|
||||
$(LDPOBJ)/ldplayer.o: $(LAYOUT)/pr8210.lh \
|
||||
|
@ -126,9 +126,6 @@ static TIMER_CALLBACK( response_timer )
|
||||
|
||||
static void vsync_callback(void)
|
||||
{
|
||||
/* only clock the disc every other frame */
|
||||
laserdisc_vsync(laserdisc);
|
||||
|
||||
/* if we have data available, set a timer to read it */
|
||||
if (!serial_timer_active && laserdisc_line_r(laserdisc, LASERDISC_LINE_DATA_AVAIL) == ASSERT_LINE)
|
||||
{
|
||||
@ -400,7 +397,7 @@ static MACHINE_DRIVER_START( alg_r1 )
|
||||
MDRV_MACHINE_RESET(alg)
|
||||
MDRV_NVRAM_HANDLER(generic_0fill)
|
||||
|
||||
MDRV_LASERDISC_ADD("laserdisc", SONY_LDP1450)
|
||||
MDRV_LASERDISC_ADD("laserdisc", SONY_LDP1450, "main", "ldsound")
|
||||
MDRV_LASERDISC_OVERLAY(amiga, 512*2, 262, BITMAP_FORMAT_INDEXED16)
|
||||
MDRV_LASERDISC_OVERLAY_CLIP((129-8)*2, (449+8-1)*2, 44-8, 244+8-1)
|
||||
|
||||
@ -425,7 +422,7 @@ static MACHINE_DRIVER_START( alg_r1 )
|
||||
MDRV_SOUND_ROUTE(2, "right", 0.25)
|
||||
MDRV_SOUND_ROUTE(3, "left", 0.25)
|
||||
|
||||
MDRV_SOUND_ADD("laserdisc", CUSTOM, 0)
|
||||
MDRV_SOUND_ADD("ldsound", CUSTOM, 0)
|
||||
MDRV_SOUND_CONFIG(laserdisc_custom_interface)
|
||||
MDRV_SOUND_ROUTE(0, "left", 1.0)
|
||||
MDRV_SOUND_ROUTE(1, "right", 1.0)
|
||||
|
@ -172,8 +172,7 @@ static WRITE8_HANDLER( cliff_ldwire_w )
|
||||
|
||||
static INTERRUPT_GEN( cliff_vsync )
|
||||
{
|
||||
/* clock the laserdisc and video chip every 60Hz */
|
||||
laserdisc_vsync(laserdisc);
|
||||
/* clock the video chip every 60Hz */
|
||||
TMS9928A_interrupt(machine);
|
||||
}
|
||||
|
||||
@ -691,7 +690,7 @@ static MACHINE_DRIVER_START( cliffhgr )
|
||||
|
||||
MDRV_NVRAM_HANDLER(generic_0fill)
|
||||
|
||||
MDRV_LASERDISC_ADD("laserdisc", PIONEER_PR8210)
|
||||
MDRV_LASERDISC_ADD("laserdisc", PIONEER_PR8210, "main", "ldsound")
|
||||
MDRV_LASERDISC_OVERLAY(tms9928a, 15+32*8+15, 27+24*8+24, BITMAP_FORMAT_INDEXED16)
|
||||
MDRV_LASERDISC_OVERLAY_CLIP(15-12, 15+32*8+12-1, 27-9, 27+24*8+9-1)
|
||||
|
||||
@ -705,7 +704,7 @@ static MACHINE_DRIVER_START( cliffhgr )
|
||||
/* sound hardware */
|
||||
MDRV_SPEAKER_STANDARD_STEREO("left", "right")
|
||||
|
||||
MDRV_SOUND_ADD("laserdisc", CUSTOM, 0)
|
||||
MDRV_SOUND_ADD("ldsound", CUSTOM, 0)
|
||||
MDRV_SOUND_CONFIG(laserdisc_custom_interface)
|
||||
MDRV_SOUND_ROUTE(0, "left", 1.0)
|
||||
MDRV_SOUND_ROUTE(1, "right", 1.0)
|
||||
|
@ -210,7 +210,6 @@ static INTERRUPT_GEN( vblank )
|
||||
cpunum_set_input_line(machine, MAIN_CPU, int_level, HOLD_LINE);
|
||||
|
||||
/* Update the laserdisc */
|
||||
laserdisc_vsync(laserdisc);
|
||||
video_field ^= 1;
|
||||
}
|
||||
|
||||
@ -577,14 +576,14 @@ static MACHINE_DRIVER_START( cubeqst )
|
||||
MDRV_PALETTE_LENGTH(8192 + 1)
|
||||
MDRV_PALETTE_INIT(cubeqst)
|
||||
|
||||
MDRV_LASERDISC_ADD("laserdisc", SIMUTREK_SPECIAL)
|
||||
MDRV_LASERDISC_ADD("laserdisc", SIMUTREK_SPECIAL, "main", "ldsound")
|
||||
MDRV_LASERDISC_OVERLAY(cubeqst, CUBEQST_HBLANK, CUBEQST_VCOUNT, BITMAP_FORMAT_INDEXED16)
|
||||
MDRV_LASERDISC_OVERLAY_CLIP(0, 320-1, 0, 256-8)
|
||||
MDRV_LASERDISC_OVERLAY_POSITION(0.002, -0.018)
|
||||
|
||||
MDRV_SPEAKER_STANDARD_STEREO("left", "right")
|
||||
|
||||
MDRV_SOUND_ADD("laserdisc", CUSTOM, 0)
|
||||
MDRV_SOUND_ADD("ldsound", CUSTOM, 0)
|
||||
MDRV_SOUND_CONFIG(laserdisc_custom_interface)
|
||||
MDRV_SOUND_ROUTE(0, "left", 1.0)
|
||||
MDRV_SOUND_ROUTE(1, "right", 1.0)
|
||||
|
@ -222,9 +222,6 @@ static MACHINE_RESET( dlair )
|
||||
|
||||
static INTERRUPT_GEN( vblank_callback )
|
||||
{
|
||||
/* update the laserdisc */
|
||||
laserdisc_vsync(laserdisc);
|
||||
|
||||
/* also update the speaker on the European version */
|
||||
if (sndti_exists(SOUND_BEEP, 0))
|
||||
{
|
||||
@ -727,7 +724,7 @@ static MACHINE_DRIVER_START( dlair_base )
|
||||
MDRV_SOUND_CONFIG(ay8910_config)
|
||||
MDRV_SOUND_ROUTE(ALL_OUTPUTS, "right", 0.33)
|
||||
|
||||
MDRV_SOUND_ADD("laserdisc", CUSTOM, 0)
|
||||
MDRV_SOUND_ADD("ldsound", CUSTOM, 0)
|
||||
MDRV_SOUND_CONFIG(laserdisc_custom_interface)
|
||||
MDRV_SOUND_ROUTE(0, "left", 1.0)
|
||||
MDRV_SOUND_ROUTE(1, "right", 1.0)
|
||||
@ -736,13 +733,13 @@ MACHINE_DRIVER_END
|
||||
|
||||
static MACHINE_DRIVER_START( dlair_pr7820 )
|
||||
MDRV_IMPORT_FROM(dlair_base)
|
||||
MDRV_LASERDISC_ADD("laserdisc", PIONEER_PR7820)
|
||||
MDRV_LASERDISC_ADD("laserdisc", PIONEER_PR7820, "main", "ldsound")
|
||||
MACHINE_DRIVER_END
|
||||
|
||||
|
||||
static MACHINE_DRIVER_START( dlair_ldv1000 )
|
||||
MDRV_IMPORT_FROM(dlair_base)
|
||||
MDRV_LASERDISC_ADD("laserdisc", PIONEER_LDV1000)
|
||||
MDRV_LASERDISC_ADD("laserdisc", PIONEER_LDV1000, "main", "ldsound")
|
||||
MACHINE_DRIVER_END
|
||||
|
||||
|
||||
@ -760,7 +757,7 @@ static MACHINE_DRIVER_START( dleuro )
|
||||
MDRV_MACHINE_START(dleuro)
|
||||
MDRV_MACHINE_RESET(dlair)
|
||||
|
||||
MDRV_LASERDISC_ADD("laserdisc", PHILLIPS_22VP932)
|
||||
MDRV_LASERDISC_ADD("laserdisc", PHILLIPS_22VP932, "main", "ldsound")
|
||||
MDRV_LASERDISC_OVERLAY(dleuro, 256, 256, BITMAP_FORMAT_INDEXED16)
|
||||
|
||||
/* video hardware */
|
||||
|
@ -266,8 +266,6 @@ static INTERRUPT_GEN( vblank_callback_esh )
|
||||
// IRQ
|
||||
cpunum_set_input_line(machine, 0, 0, ASSERT_LINE);
|
||||
timer_set(ATTOTIME_IN_USEC(50), NULL, 0, irq_stop);
|
||||
|
||||
laserdisc_vsync(laserdisc);
|
||||
}
|
||||
|
||||
static MACHINE_START( esh )
|
||||
@ -289,7 +287,7 @@ static MACHINE_DRIVER_START( esh )
|
||||
|
||||
MDRV_MACHINE_START(esh)
|
||||
|
||||
MDRV_LASERDISC_ADD("laserdisc", PIONEER_LDV1000)
|
||||
MDRV_LASERDISC_ADD("laserdisc", PIONEER_LDV1000, "main", "ldsound")
|
||||
MDRV_LASERDISC_OVERLAY(esh, 256, 256, BITMAP_FORMAT_INDEXED16)
|
||||
|
||||
/* video hardware */
|
||||
@ -303,7 +301,7 @@ static MACHINE_DRIVER_START( esh )
|
||||
/* sound hardware */
|
||||
MDRV_SPEAKER_STANDARD_STEREO("left", "right")
|
||||
|
||||
MDRV_SOUND_ADD("laserdisc", CUSTOM, 0)
|
||||
MDRV_SOUND_ADD("ldsound", CUSTOM, 0)
|
||||
MDRV_SOUND_CONFIG(laserdisc_custom_interface)
|
||||
MDRV_SOUND_ROUTE(0, "left", 1.0)
|
||||
MDRV_SOUND_ROUTE(1, "right", 1.0)
|
||||
|
@ -679,8 +679,6 @@ static INTERRUPT_GEN( gottlieb_interrupt )
|
||||
{
|
||||
bitmap_t *dummy;
|
||||
|
||||
laserdisc_vsync(laserdisc);
|
||||
|
||||
/* set the "disc ready" bit, which basically indicates whether or not we have a proper video frame */
|
||||
if (laserdisc_get_video(laserdisc, &dummy) == 0)
|
||||
laserdisc_status &= ~0x20;
|
||||
@ -1889,7 +1887,7 @@ static MACHINE_DRIVER_START( g2laser )
|
||||
MDRV_IMPORT_FROM(gottlieb_core)
|
||||
MDRV_IMPORT_FROM(gottlieb_soundrev2)
|
||||
|
||||
MDRV_LASERDISC_ADD("laserdisc", PIONEER_PR8210)
|
||||
MDRV_LASERDISC_ADD("laserdisc", PIONEER_PR8210, "main", "ldsound")
|
||||
MDRV_LASERDISC_AUDIO(laserdisc_audio_process)
|
||||
MDRV_LASERDISC_OVERLAY(gottlieb, GOTTLIEB_VIDEO_HCOUNT, GOTTLIEB_VIDEO_VCOUNT, BITMAP_FORMAT_INDEXED16)
|
||||
MDRV_LASERDISC_OVERLAY_CLIP(0, GOTTLIEB_VIDEO_HBLANK-1, 0, GOTTLIEB_VIDEO_VBLANK-8)
|
||||
@ -1897,7 +1895,7 @@ static MACHINE_DRIVER_START( g2laser )
|
||||
MDRV_SCREEN_REMOVE("main")
|
||||
MDRV_LASERDISC_SCREEN_ADD_NTSC("main", BITMAP_FORMAT_INDEXED16)
|
||||
|
||||
MDRV_SOUND_ADD("laserdisc", CUSTOM, 0)
|
||||
MDRV_SOUND_ADD("ldsound", CUSTOM, 0)
|
||||
MDRV_SOUND_CONFIG(laserdisc_custom_interface)
|
||||
MDRV_SOUND_ROUTE(0, "mono", 1.0)
|
||||
/* right channel is processed as data */
|
||||
|
@ -405,8 +405,6 @@ static INTERRUPT_GEN( vblank_callback_gpworld )
|
||||
/* The time the IRQ line stays high is set just long enough to happen after the NMI - hacky? */
|
||||
cpunum_set_input_line(machine, 0, 0, ASSERT_LINE);
|
||||
timer_set(ATTOTIME_IN_USEC(100), NULL, 0, irq_stop);
|
||||
|
||||
laserdisc_vsync(laserdisc);
|
||||
}
|
||||
|
||||
static const gfx_layout gpworld_tile_layout =
|
||||
@ -435,7 +433,7 @@ static MACHINE_DRIVER_START( gpworld )
|
||||
|
||||
MDRV_MACHINE_START(gpworld)
|
||||
|
||||
MDRV_LASERDISC_ADD("laserdisc", PIONEER_LDV1000)
|
||||
MDRV_LASERDISC_ADD("laserdisc", PIONEER_LDV1000, "main", "ldsound")
|
||||
MDRV_LASERDISC_OVERLAY(gpworld, 512, 256, BITMAP_FORMAT_INDEXED16)
|
||||
|
||||
/* video hardware */
|
||||
@ -447,7 +445,7 @@ static MACHINE_DRIVER_START( gpworld )
|
||||
/* sound hardware */
|
||||
MDRV_SPEAKER_STANDARD_STEREO("left", "right")
|
||||
|
||||
MDRV_SOUND_ADD("laserdisc", CUSTOM, 0)
|
||||
MDRV_SOUND_ADD("ldsound", CUSTOM, 0)
|
||||
MDRV_SOUND_CONFIG(laserdisc_custom_interface)
|
||||
MDRV_SOUND_ROUTE(0, "left", 1.0)
|
||||
MDRV_SOUND_ROUTE(1, "right", 1.0)
|
||||
|
@ -315,10 +315,6 @@ static INTERRUPT_GEN( vblank_callback_istellar )
|
||||
|
||||
/* Interrupt presumably comes from the LDP's status strobe */
|
||||
cpunum_set_input_line(machine, 2, 0, ASSERT_LINE);
|
||||
|
||||
/* Only do the LDP's sync once */
|
||||
if (cpunum == 0)
|
||||
laserdisc_vsync(laserdisc);
|
||||
}
|
||||
|
||||
|
||||
@ -342,7 +338,7 @@ static MACHINE_DRIVER_START( istellar )
|
||||
|
||||
MDRV_MACHINE_START(istellar)
|
||||
|
||||
MDRV_LASERDISC_ADD("laserdisc", PIONEER_LDV1000)
|
||||
MDRV_LASERDISC_ADD("laserdisc", PIONEER_LDV1000, "main", "ldsound")
|
||||
MDRV_LASERDISC_OVERLAY(istellar, 256, 256, BITMAP_FORMAT_INDEXED16)
|
||||
|
||||
/* video hardware */
|
||||
@ -356,7 +352,7 @@ static MACHINE_DRIVER_START( istellar )
|
||||
/* sound hardware */
|
||||
MDRV_SPEAKER_STANDARD_STEREO("left", "right")
|
||||
|
||||
MDRV_SOUND_ADD("laserdisc", CUSTOM, 0)
|
||||
MDRV_SOUND_ADD("ldsound", CUSTOM, 0)
|
||||
MDRV_SOUND_CONFIG(laserdisc_custom_interface)
|
||||
MDRV_SOUND_ROUTE(0, "left", 1.0)
|
||||
MDRV_SOUND_ROUTE(1, "right", 1.0)
|
||||
|
@ -326,8 +326,6 @@ static INTERRUPT_GEN( vblank_callback_lgp )
|
||||
// IRQ
|
||||
cpunum_set_input_line(machine, 0, 0, ASSERT_LINE);
|
||||
timer_set(ATTOTIME_IN_USEC(50), NULL, 0, irq_stop);
|
||||
|
||||
laserdisc_vsync(laserdisc);
|
||||
}
|
||||
|
||||
|
||||
@ -352,7 +350,7 @@ static MACHINE_DRIVER_START( lgp )
|
||||
|
||||
MDRV_MACHINE_START(lgp)
|
||||
|
||||
MDRV_LASERDISC_ADD("laserdisc", PIONEER_LDV1000)
|
||||
MDRV_LASERDISC_ADD("laserdisc", PIONEER_LDV1000, "main", "ldsound")
|
||||
MDRV_LASERDISC_OVERLAY(lgp, 256, 256, BITMAP_FORMAT_INDEXED16)
|
||||
|
||||
/* video hardware */
|
||||
@ -366,7 +364,7 @@ static MACHINE_DRIVER_START( lgp )
|
||||
/* sound hardware */
|
||||
MDRV_SPEAKER_STANDARD_STEREO("left", "right")
|
||||
|
||||
MDRV_SOUND_ADD("laserdisc", CUSTOM, 0)
|
||||
MDRV_SOUND_ADD("ldsound", CUSTOM, 0)
|
||||
MDRV_SOUND_CONFIG(laserdisc_custom_interface)
|
||||
MDRV_SOUND_ROUTE(0, "left", 1.0)
|
||||
MDRV_SOUND_ROUTE(1, "right", 1.0)
|
||||
|
@ -321,11 +321,6 @@ static INPUT_PORTS_START( astron )
|
||||
PORT_BIT ( 0x80, IP_ACTIVE_LOW, IPT_UNUSED ) /* SW15 = nonJAMMA pin W = unused? */
|
||||
INPUT_PORTS_END
|
||||
|
||||
static INTERRUPT_GEN( vblank_callback_astron )
|
||||
{
|
||||
laserdisc_vsync(laserdisc);
|
||||
}
|
||||
|
||||
static GFXDECODE_START( segald )
|
||||
GFXDECODE_ENTRY( "gfx1", 0, gfx_8x8x1, 0, 1 ) /* CHARACTERS */
|
||||
/* SPRITES are apparently non-uniform in width - not straightforward to decode */
|
||||
@ -345,12 +340,11 @@ static MACHINE_DRIVER_START( astron )
|
||||
MDRV_CPU_ADD("main", Z80, SCHEMATIC_CLOCK/4)
|
||||
MDRV_CPU_PROGRAM_MAP(mainmem,0)
|
||||
MDRV_CPU_IO_MAP(mainport,0)
|
||||
MDRV_CPU_VBLANK_INT("main", vblank_callback_astron)
|
||||
MDRV_CPU_PERIODIC_INT(nmi_line_pulse, 1000.0/59.94)
|
||||
|
||||
MDRV_MACHINE_START(astron)
|
||||
|
||||
MDRV_LASERDISC_ADD("laserdisc", PIONEER_LDV1000)
|
||||
MDRV_LASERDISC_ADD("laserdisc", PIONEER_LDV1000, "main", "ldsound")
|
||||
MDRV_LASERDISC_OVERLAY(astron, 256, 256, BITMAP_FORMAT_INDEXED16)
|
||||
|
||||
/* video hardware */
|
||||
@ -362,7 +356,7 @@ static MACHINE_DRIVER_START( astron )
|
||||
/* sound hardare */
|
||||
MDRV_SPEAKER_STANDARD_STEREO("left", "right")
|
||||
|
||||
MDRV_SOUND_ADD("laserdisc", CUSTOM, 0)
|
||||
MDRV_SOUND_ADD("ldsound", CUSTOM, 0)
|
||||
MDRV_SOUND_CONFIG(laserdisc_custom_interface)
|
||||
MDRV_SOUND_ROUTE(0, "left", 1.0)
|
||||
MDRV_SOUND_ROUTE(1, "right", 1.0)
|
||||
|
@ -111,8 +111,6 @@ static MACHINE_RESET( superdq )
|
||||
|
||||
static INTERRUPT_GEN( superdq_vblank )
|
||||
{
|
||||
laserdisc_vsync(laserdisc);
|
||||
|
||||
/* status is read when the STATUS line from the laserdisc
|
||||
toggles (600usec after the vblank). We could set up a
|
||||
timer to do that, but this works as well */
|
||||
@ -305,7 +303,7 @@ static MACHINE_DRIVER_START( superdq )
|
||||
MDRV_MACHINE_START(superdq)
|
||||
MDRV_MACHINE_RESET(superdq)
|
||||
|
||||
MDRV_LASERDISC_ADD("laserdisc", PIONEER_LDV1000)
|
||||
MDRV_LASERDISC_ADD("laserdisc", PIONEER_LDV1000, "main", "ldsound")
|
||||
MDRV_LASERDISC_OVERLAY(superdq, 256, 256, BITMAP_FORMAT_INDEXED16)
|
||||
|
||||
/* video hardware */
|
||||
@ -323,7 +321,7 @@ static MACHINE_DRIVER_START( superdq )
|
||||
MDRV_SOUND_ADD("sn", SN76496, MASTER_CLOCK/8)
|
||||
MDRV_SOUND_ROUTE(ALL_OUTPUTS, "left", 0.8)
|
||||
|
||||
MDRV_SOUND_ADD("laserdisc", CUSTOM, 0)
|
||||
MDRV_SOUND_ADD("ldsound", CUSTOM, 0)
|
||||
MDRV_SOUND_CONFIG(laserdisc_custom_interface)
|
||||
MDRV_SOUND_ROUTE(0, "left", 1.0)
|
||||
MDRV_SOUND_ROUTE(1, "right", 1.0)
|
||||
|
@ -747,11 +747,6 @@ static MACHINE_RESET( thayers )
|
||||
device_set_info_int(laserdisc, LDINFO_INT_TYPE, newtype);
|
||||
}
|
||||
|
||||
static INTERRUPT_GEN( vblank_callback_thayers )
|
||||
{
|
||||
laserdisc_vsync(laserdisc);
|
||||
}
|
||||
|
||||
/* COP400 Interface */
|
||||
|
||||
static COP400_INTERFACE( thayers_cop_intf )
|
||||
@ -768,7 +763,6 @@ static MACHINE_DRIVER_START( thayers )
|
||||
MDRV_CPU_ADD("main", Z80, XTAL_4MHz)
|
||||
MDRV_CPU_PROGRAM_MAP(thayers_map, 0)
|
||||
MDRV_CPU_IO_MAP(thayers_io_map, 0)
|
||||
MDRV_CPU_VBLANK_INT("main", vblank_callback_thayers)
|
||||
|
||||
MDRV_CPU_ADD("mcu", COP421, XTAL_4MHz/2) // COP421L-PCA/N
|
||||
MDRV_CPU_PROGRAM_MAP(thayers_cop_map, 0)
|
||||
@ -778,7 +772,7 @@ static MACHINE_DRIVER_START( thayers )
|
||||
MDRV_MACHINE_START(thayers)
|
||||
MDRV_MACHINE_RESET(thayers)
|
||||
|
||||
MDRV_LASERDISC_ADD("laserdisc", PIONEER_PR7820)
|
||||
MDRV_LASERDISC_ADD("laserdisc", PIONEER_PR7820, "main", "ldsound")
|
||||
|
||||
/* video hardware */
|
||||
MDRV_LASERDISC_SCREEN_ADD_NTSC("main", BITMAP_FORMAT_RGB32)
|
||||
@ -786,7 +780,13 @@ static MACHINE_DRIVER_START( thayers )
|
||||
MDRV_PALETTE_LENGTH(256)
|
||||
|
||||
/* sound hardware */
|
||||
MDRV_SPEAKER_STANDARD_STEREO("left", "right")
|
||||
// SSI 263 @ 2MHz
|
||||
|
||||
MDRV_SOUND_ADD("ldsound", CUSTOM, 0)
|
||||
MDRV_SOUND_CONFIG(laserdisc_custom_interface)
|
||||
MDRV_SOUND_ROUTE(0, "left", 1.0)
|
||||
MDRV_SOUND_ROUTE(1, "right", 1.0)
|
||||
MACHINE_DRIVER_END
|
||||
|
||||
/* ROMs */
|
||||
|
Loading…
Reference in New Issue
Block a user