mirror of
https://github.com/holub/mame
synced 2025-04-20 15:32:45 +03:00
Added 22VP931 emulation, which is mostly working. Communication works
fine and basic searching/playback/skipping is functional. Still a bit glitchy. Firefox improvements: - removed need for deprecat.h - memory map is complete from schematics - gutted laserdisc hacks in favor of actual laserdisc implementation - fixed all CPU and sound clocks Removed old laserdsc.c implementation. Added generic timer devices, which simply allocate a timer but don't prime it. This is the preferred method for allocating timers, and may eventually be the only mechanism for doing so in the future.
This commit is contained in:
parent
e4dc04a323
commit
9b72b5abc4
2
.gitattributes
vendored
2
.gitattributes
vendored
@ -630,7 +630,6 @@ src/emu/machine/idectrl.c svneol=native#text/plain
|
||||
src/emu/machine/idectrl.h svneol=native#text/plain
|
||||
src/emu/machine/intelfsh.c svneol=native#text/plain
|
||||
src/emu/machine/intelfsh.h svneol=native#text/plain
|
||||
src/emu/machine/laserdsc.c svneol=native#text/plain
|
||||
src/emu/machine/laserdsc.h svneol=native#text/plain
|
||||
src/emu/machine/latch8.c svneol=native#text/plain
|
||||
src/emu/machine/latch8.h svneol=native#text/plain
|
||||
@ -638,6 +637,7 @@ src/emu/machine/ldcore.c svneol=native#text/plain
|
||||
src/emu/machine/ldcore.h svneol=native#text/plain
|
||||
src/emu/machine/ldpr8210.c svneol=native#text/plain
|
||||
src/emu/machine/ldv1000.c svneol=native#text/plain
|
||||
src/emu/machine/ldvp931.c svneol=native#text/plain
|
||||
src/emu/machine/mb3773.c svneol=native#text/plain
|
||||
src/emu/machine/mb3773.h svneol=native#text/plain
|
||||
src/emu/machine/mb87078.c svneol=native#text/plain
|
||||
|
@ -142,6 +142,7 @@ EMUMACHINEOBJS = \
|
||||
$(EMUMACHINE)/ldcore.o \
|
||||
$(EMUMACHINE)/ldpr8210.o \
|
||||
$(EMUMACHINE)/ldv1000.o \
|
||||
$(EMUMACHINE)/ldvp931.o \
|
||||
$(EMUMACHINE)/mb3773.o \
|
||||
$(EMUMACHINE)/mb87078.o \
|
||||
$(EMUMACHINE)/mc146818.o \
|
||||
|
File diff suppressed because it is too large
Load Diff
@ -37,7 +37,8 @@ enum
|
||||
/* laserdisc control lines */
|
||||
#define LASERDISC_LINE_ENTER 0 /* "ENTER" key/line */
|
||||
#define LASERDISC_LINE_CONTROL 1 /* "CONTROL" line */
|
||||
#define LASERDISC_INPUT_LINES 2
|
||||
#define LASERDISC_LINE_RESET 2 /* "RESET" line */
|
||||
#define LASERDISC_INPUT_LINES 3
|
||||
|
||||
/* laserdisc status lines */
|
||||
#define LASERDISC_LINE_READY 0 /* "READY" line */
|
||||
@ -47,11 +48,11 @@ enum
|
||||
#define LASERDISC_OUTPUT_LINES 4
|
||||
|
||||
/* laserdisc field codes */
|
||||
#define LASERDISC_CODE_WHITE_FLAG 0 /* boolean white flag */
|
||||
#define LASERDISC_CODE_LINE16 1 /* 24-bit line 16 code */
|
||||
#define LASERDISC_CODE_LINE17 2 /* 24-bit line 17 code */
|
||||
#define LASERDISC_CODE_LINE18 3 /* 24-bit line 18 code */
|
||||
#define LASERDISC_CODE_LINE1718 4 /* 24-bit best of line 17/18 code */
|
||||
#define LASERDISC_CODE_WHITE_FLAG 11 /* boolean white flag */
|
||||
#define LASERDISC_CODE_LINE16 16 /* 24-bit line 16 code */
|
||||
#define LASERDISC_CODE_LINE17 17 /* 24-bit line 17 code */
|
||||
#define LASERDISC_CODE_LINE18 18 /* 24-bit line 18 code */
|
||||
#define LASERDISC_CODE_LINE1718 1718 /* 24-bit best of line 17/18 code */
|
||||
|
||||
/* device configuration */
|
||||
enum
|
||||
@ -161,7 +162,7 @@ extern const custom_sound_interface laserdisc_custom_interface;
|
||||
int laserdisc_get_video(const device_config *device, bitmap_t **bitmap);
|
||||
|
||||
/* return the raw philips or white flag codes */
|
||||
UINT32 laserdisc_get_field_code(const device_config *device, UINT8 code);
|
||||
UINT32 laserdisc_get_field_code(const device_config *device, UINT32 code);
|
||||
|
||||
|
||||
|
||||
@ -186,6 +187,9 @@ UINT8 laserdisc_line_r(const device_config *device, UINT8 line);
|
||||
/* specify the "slow" speed of the Pioneer PR-7820 */
|
||||
void pr7820_set_slow_speed(const device_config *device, double frame_rate_scaler);
|
||||
|
||||
/* set a callback for data ready on the Phillips 22VP931 */
|
||||
void vp931_set_data_ready_callback(const device_config *device, void (*callback)(const device_config *device, int state));
|
||||
|
||||
/* control the audio squelch of the Simutrek modified players */
|
||||
void simutrek_set_audio_squelch(const device_config *device, int state);
|
||||
|
||||
|
@ -151,7 +151,8 @@ static const ldplayer_interface *player_interfaces[] =
|
||||
&simutrek_interface,
|
||||
&ldv1000_interface,
|
||||
// &ldp1450_interface,
|
||||
// &vp932_interface
|
||||
// &vp932_interface,
|
||||
&vp931_interface
|
||||
};
|
||||
|
||||
const custom_sound_interface laserdisc_custom_interface =
|
||||
@ -560,7 +561,7 @@ int laserdisc_get_video(const device_config *device, bitmap_t **bitmap)
|
||||
information read from the disc
|
||||
-------------------------------------------------*/
|
||||
|
||||
UINT32 laserdisc_get_field_code(const device_config *device, UINT8 code)
|
||||
UINT32 laserdisc_get_field_code(const device_config *device, UINT32 code)
|
||||
{
|
||||
laserdisc_state *ld = get_safe_token(device);
|
||||
ldcore_data *ldcore = ld->core;
|
||||
@ -888,27 +889,44 @@ static void read_track_data(laserdisc_state *ld)
|
||||
ldcore_data *ldcore = ld->core;
|
||||
UINT32 tracknum = ldcore->curtrack;
|
||||
UINT32 fieldnum = ldcore->fieldnum;
|
||||
UINT32 curfield = tracknum * 2 + fieldnum;
|
||||
frame_data *frame;
|
||||
UINT32 vbiframe;
|
||||
UINT32 readhunk;
|
||||
INT32 chdtrack;
|
||||
|
||||
/* if the previous field had a frame number, and the new field immediately follows it,
|
||||
force the new field to pair with the previous one */
|
||||
|
||||
frame = &ldcore->frame[ldcore->videoindex];
|
||||
if ((ldcore->metadata[fieldnum ^ 1].line1718 & VBI_MASK_CAV_PICTURE) == VBI_CODE_CAV_PICTURE && (tracknum * 2 + fieldnum == frame->lastfield + 1))
|
||||
frame->numfields = 1;
|
||||
|
||||
/* otherwise, keep the frames in sync with the absolute field numbers */
|
||||
else if (frame->numfields == 2 && fieldnum != 0)
|
||||
frame->numfields--;
|
||||
|
||||
/* if we already have both fields on the current videoindex, advance */
|
||||
else if (frame->numfields >= 2)
|
||||
/* special cases for playing forward */
|
||||
if (curfield == frame->lastfield + 1)
|
||||
{
|
||||
ldcore->videoindex = (ldcore->videoindex + 1) % ARRAY_LENGTH(ldcore->frame);
|
||||
frame = &ldcore->frame[ldcore->videoindex];
|
||||
frame->numfields = 0;
|
||||
/* if the previous field had a frame number, force the new field to pair with the previous one */
|
||||
if ((ldcore->metadata[fieldnum ^ 1].line1718 & VBI_MASK_CAV_PICTURE) == VBI_CODE_CAV_PICTURE)
|
||||
frame->numfields = 1;
|
||||
|
||||
/* if the twice-previous field was a frame number, and we've moved one since then, consider this one done */
|
||||
else if (frame->numfields >= 2 && (ldcore->metadata[fieldnum].line1718 & VBI_MASK_CAV_PICTURE) == VBI_CODE_CAV_PICTURE)
|
||||
{
|
||||
ldcore->videoindex = (ldcore->videoindex + 1) % ARRAY_LENGTH(ldcore->frame);
|
||||
frame = &ldcore->frame[ldcore->videoindex];
|
||||
frame->numfields = 0;
|
||||
}
|
||||
}
|
||||
|
||||
/* all other cases */
|
||||
else
|
||||
{
|
||||
/* otherwise, keep the frames in sync with the absolute field numbers */
|
||||
if (frame->numfields == 2 && fieldnum != 0)
|
||||
frame->numfields--;
|
||||
|
||||
/* if we already have both fields on the current videoindex, advance */
|
||||
else if (frame->numfields >= 2)
|
||||
{
|
||||
ldcore->videoindex = (ldcore->videoindex + 1) % ARRAY_LENGTH(ldcore->frame);
|
||||
frame = &ldcore->frame[ldcore->videoindex];
|
||||
frame->numfields = 0;
|
||||
}
|
||||
}
|
||||
|
||||
/* if we're squelched, reset the frame counter */
|
||||
@ -1333,8 +1351,8 @@ VIDEO_UPDATE( laserdisc )
|
||||
rectangle clip = *cliprect;
|
||||
|
||||
/* scale the cliprect to the overlay size and then call the update callback */
|
||||
clip.min_x = 0;
|
||||
clip.max_x = ldcore->config.overwidth - 1;
|
||||
clip.min_x = ldcore->config.overclip.min_x;
|
||||
clip.max_x = ldcore->config.overclip.max_x;
|
||||
clip.min_y = cliprect->min_y * overbitmap->height / bitmap->height;
|
||||
if (cliprect->min_y == visarea->min_y)
|
||||
clip.min_y = MIN(clip.min_y, ldcore->config.overclip.min_y);
|
||||
|
@ -172,6 +172,7 @@ extern const ldplayer_interface pr8210_interface;
|
||||
extern const ldplayer_interface simutrek_interface;
|
||||
extern const ldplayer_interface ldv1000_interface;
|
||||
extern const ldplayer_interface ldp1450_interface;
|
||||
extern const ldplayer_interface vp931_interface;
|
||||
extern const ldplayer_interface vp932_interface;
|
||||
|
||||
|
||||
|
@ -349,7 +349,7 @@ static INT32 pr8210_update(laserdisc_state *ld, const vbi_metadata *vbi, int fie
|
||||
player data
|
||||
-------------------------------------------------*/
|
||||
|
||||
void pr8210_overlay(laserdisc_state *ld, bitmap_t *bitmap)
|
||||
static void pr8210_overlay(laserdisc_state *ld, bitmap_t *bitmap)
|
||||
{
|
||||
// ldplayer_data *player = ld->player;
|
||||
}
|
||||
|
772
src/emu/machine/ldvp931.c
Normal file
772
src/emu/machine/ldvp931.c
Normal file
@ -0,0 +1,772 @@
|
||||
/*************************************************************************
|
||||
|
||||
ldvp931.c
|
||||
|
||||
Philips 22VP931 laserdisc emulation.
|
||||
|
||||
Copyright Nicola Salmoria and the MAME Team.
|
||||
Visit http://mamedev.org for licensing and usage restrictions.
|
||||
|
||||
**************************************************************************
|
||||
|
||||
Still to do:
|
||||
|
||||
* determine actual slow/fast speeds
|
||||
*
|
||||
|
||||
*************************************************************************/
|
||||
|
||||
#include "ldcore.h"
|
||||
#include "cpu/mcs48/mcs48.h"
|
||||
|
||||
|
||||
|
||||
/***************************************************************************
|
||||
DEBUGGING
|
||||
***************************************************************************/
|
||||
|
||||
#define LOG_COMMANDS 0
|
||||
#define LOG_PORTS 0
|
||||
|
||||
|
||||
|
||||
/***************************************************************************
|
||||
CONSTANTS
|
||||
***************************************************************************/
|
||||
|
||||
/* Philips 22VP931 specific information */
|
||||
#define VP931_SCAN_SPEED (2000 / 30) /* 2000 frames/second */
|
||||
#define VP931_SCAN_FAST_SPEED (4000 / 30) /* 4000 frames/second */
|
||||
|
||||
|
||||
|
||||
/***************************************************************************
|
||||
TYPE DEFINITIONS
|
||||
***************************************************************************/
|
||||
|
||||
/* player-specific data */
|
||||
struct _ldplayer_data
|
||||
{
|
||||
/* low-level emulation data */
|
||||
int cpunum; /* CPU index of the 8049 */
|
||||
const device_config *tracktimer; /* timer device */
|
||||
int lastframe;
|
||||
UINT8 out0; /* output 0 state */
|
||||
UINT8 out1; /* output 1 state */
|
||||
UINT8 port1; /* port 1 state */
|
||||
UINT8 daticval; /* latched DATIC value */
|
||||
UINT8 daticerp; /* /ERP value from DATIC */
|
||||
UINT8 datastrobe; /* DATA STROBE line from DATIC */
|
||||
UINT8 fromcontroller; /* command byte from the controller */
|
||||
UINT8 fromcontroller_pending; /* TRUE if data is pending */
|
||||
UINT8 tocontroller; /* command byte to the controller */
|
||||
UINT8 tocontroller_pending; /* TRUE if data is pending */
|
||||
INT8 trackdir; /* direction of tracking */
|
||||
UINT8 trackstate; /* state of tracking */
|
||||
UINT8 cmdbuf[3]; /* 3 bytes worth of commands */
|
||||
UINT8 cmdcount; /* number of command bytes seen */
|
||||
INT16 advanced; /* number of frames advanced */
|
||||
void (*data_ready_cb)(const device_config *device, int state); /* data ready callback */
|
||||
};
|
||||
|
||||
|
||||
|
||||
/***************************************************************************
|
||||
FUNCTION PROTOTYPES
|
||||
***************************************************************************/
|
||||
|
||||
static void vp931_init(laserdisc_state *ld);
|
||||
static void vp931_vsync(laserdisc_state *ld, const vbi_metadata *vbi, int fieldnum, attotime curtime);
|
||||
static INT32 vp931_update(laserdisc_state *ld, const vbi_metadata *vbi, int fieldnum, attotime curtime);
|
||||
static void vp931_data_w(laserdisc_state *ld, UINT8 prev, UINT8 data);
|
||||
static UINT8 vp931_data_r(laserdisc_state *ld);
|
||||
static UINT8 vp931_ready(laserdisc_state *ld);
|
||||
static UINT8 vp931_data_ready(laserdisc_state *ld);
|
||||
|
||||
static WRITE8_HANDLER( output0_w );
|
||||
static WRITE8_HANDLER( output1_w );
|
||||
static WRITE8_HANDLER( lcd_w );
|
||||
static READ8_HANDLER( keypad_r );
|
||||
static READ8_HANDLER( datic_r );
|
||||
static READ8_HANDLER( from_controller_r );
|
||||
static WRITE8_HANDLER( to_controller_w );
|
||||
static READ8_HANDLER( port1_r );
|
||||
static WRITE8_HANDLER( port1_w );
|
||||
static READ8_HANDLER( port2_r );
|
||||
static WRITE8_HANDLER( port2_w );
|
||||
static READ8_HANDLER( t0_r );
|
||||
static READ8_HANDLER( t1_r );
|
||||
static TIMER_CALLBACK( vbi_data_fetch );
|
||||
static TIMER_CALLBACK( deferred_data_w );
|
||||
static TIMER_CALLBACK( irq_off );
|
||||
static TIMER_CALLBACK( datastrobe_off );
|
||||
static TIMER_CALLBACK( erp_off );
|
||||
static TIMER_DEVICE_CALLBACK( track_timer );
|
||||
|
||||
|
||||
|
||||
/***************************************************************************
|
||||
INLINE FUNCTIONS
|
||||
***************************************************************************/
|
||||
|
||||
/*-------------------------------------------------
|
||||
find_vp931 - find our device; assumes there
|
||||
is only one
|
||||
-------------------------------------------------*/
|
||||
|
||||
INLINE laserdisc_state *find_vp931(running_machine *machine)
|
||||
{
|
||||
return ldcore_get_safe_token(device_list_first(machine->config->devicelist, LASERDISC));
|
||||
}
|
||||
|
||||
|
||||
|
||||
/***************************************************************************
|
||||
22VP931 ROM AND MACHINE INTERFACES
|
||||
***************************************************************************/
|
||||
|
||||
static ADDRESS_MAP_START( vp931_portmap, ADDRESS_SPACE_IO, 8 )
|
||||
AM_RANGE(0x00, 0x00) AM_MIRROR(0xcf) AM_READWRITE(keypad_r, output0_w)
|
||||
AM_RANGE(0x10, 0x10) AM_MIRROR(0xcf) AM_WRITE(output1_w)
|
||||
AM_RANGE(0x20, 0x20) AM_MIRROR(0xcf) AM_READWRITE(datic_r, lcd_w)
|
||||
AM_RANGE(0x30, 0x30) AM_MIRROR(0xcf) AM_READWRITE(from_controller_r, to_controller_w)
|
||||
AM_RANGE(MCS48_PORT_P1, MCS48_PORT_P1) AM_READWRITE(port1_r, port1_w)
|
||||
AM_RANGE(MCS48_PORT_P2, MCS48_PORT_P2) AM_READWRITE(port2_r, port2_w)
|
||||
AM_RANGE(MCS48_PORT_T0, MCS48_PORT_T0) AM_READ(t0_r)
|
||||
AM_RANGE(MCS48_PORT_T1, MCS48_PORT_T1) AM_READ(t1_r)
|
||||
ADDRESS_MAP_END
|
||||
|
||||
|
||||
static MACHINE_DRIVER_START( vp931 )
|
||||
MDRV_CPU_ADD("vp931", I8049, XTAL_11MHz)
|
||||
MDRV_CPU_IO_MAP(vp931_portmap,0)
|
||||
MDRV_TIMER_ADD("tracktimer", track_timer)
|
||||
MACHINE_DRIVER_END
|
||||
|
||||
|
||||
ROM_START( vp931 )
|
||||
ROM_REGION( 0x800, "vp931", ROMREGION_LOADBYNAME )
|
||||
ROM_LOAD( "at-6-1_a.bin", 0x000, 0x800, CRC(e11b3c8d) SHA1(ea2d7f6a044ed085ce5e09d8b1b1a21c37f0e9b8) )
|
||||
ROM_END
|
||||
|
||||
|
||||
|
||||
/***************************************************************************
|
||||
PR-8210 PLAYER INTERFACE
|
||||
***************************************************************************/
|
||||
|
||||
const ldplayer_interface vp931_interface =
|
||||
{
|
||||
LASERDISC_TYPE_PHILLIPS_22VP931, /* type of the player */
|
||||
sizeof(ldplayer_data), /* size of the state */
|
||||
"Phillips 22VP931", /* name of the player */
|
||||
rom_vp931, /* pointer to ROM region information */
|
||||
machine_config_vp931, /* pointer to machine configuration */
|
||||
vp931_init, /* initialization callback */
|
||||
vp931_vsync, /* vsync callback */
|
||||
vp931_update, /* update callback */
|
||||
NULL, /* overlay callback */
|
||||
vp931_data_w, /* parallel data write */
|
||||
{ /* single line write: */
|
||||
NULL, /* LASERDISC_LINE_ENTER */
|
||||
NULL /* LASERDISC_LINE_CONTROL */
|
||||
},
|
||||
vp931_data_r, /* parallel data read */
|
||||
{ /* single line read: */
|
||||
vp931_ready, /* LASERDISC_LINE_READY */
|
||||
NULL, /* LASERDISC_LINE_STATUS */
|
||||
NULL, /* LASERDISC_LINE_COMMAND */
|
||||
vp931_data_ready, /* LASERDISC_LINE_DATA_AVAIL */
|
||||
}
|
||||
};
|
||||
|
||||
|
||||
|
||||
/***************************************************************************
|
||||
PUBLIC FUNCTIONS
|
||||
***************************************************************************/
|
||||
|
||||
/*-------------------------------------------------
|
||||
vp931_set_data_ready_callback - set the data
|
||||
ready callback
|
||||
-------------------------------------------------*/
|
||||
|
||||
void vp931_set_data_ready_callback(const device_config *device, void (*callback)(const device_config *device, int state))
|
||||
{
|
||||
laserdisc_state *ld = ldcore_get_safe_token(device);
|
||||
ld->player->data_ready_cb = callback;
|
||||
}
|
||||
|
||||
|
||||
|
||||
/***************************************************************************
|
||||
PHILLIPS 22VP931 IMPLEMENTATION
|
||||
***************************************************************************/
|
||||
|
||||
/*-------------------------------------------------
|
||||
vp931_init - Pioneer PR-8210-specific
|
||||
initialization
|
||||
-------------------------------------------------*/
|
||||
|
||||
static void vp931_init(laserdisc_state *ld)
|
||||
{
|
||||
astring *tempstring = astring_alloc();
|
||||
ldplayer_data *player = ld->player;
|
||||
|
||||
/* find our CPU */
|
||||
astring_printf(tempstring, "%s:%s", ld->device->tag, "vp931");
|
||||
player->cpunum = mame_find_cpu_index(ld->device->machine, astring_c(tempstring));
|
||||
|
||||
/* find our timer */
|
||||
astring_printf(tempstring, "%s:%s", ld->device->tag, "tracktimer");
|
||||
player->tracktimer = device_list_find_by_tag(ld->device->machine->config->devicelist, TIMER, astring_c(tempstring));
|
||||
timer_device_set_ptr(player->tracktimer, ld);
|
||||
|
||||
astring_free(tempstring);
|
||||
}
|
||||
|
||||
|
||||
/*-------------------------------------------------
|
||||
vp931_vsync - VSYNC callback, called at the
|
||||
start of the blanking period
|
||||
-------------------------------------------------*/
|
||||
|
||||
static void vp931_vsync(laserdisc_state *ld, const vbi_metadata *vbi, int fieldnum, attotime curtime)
|
||||
{
|
||||
/* reset our command counter (debugging only) */
|
||||
ld->player->cmdcount = 0;
|
||||
|
||||
/* set the ERP signal to 1 to indicate start of frame, and set a timer to turn it off */
|
||||
ld->player->daticerp = 1;
|
||||
timer_set(video_screen_get_time_until_pos(ld->screen, 15*2, 0), ld, 0, erp_off);
|
||||
}
|
||||
|
||||
|
||||
/*-------------------------------------------------
|
||||
vp931_update - update callback, called on
|
||||
the first visible line of the frame
|
||||
-------------------------------------------------*/
|
||||
|
||||
static INT32 vp931_update(laserdisc_state *ld, const vbi_metadata *vbi, int fieldnum, attotime curtime)
|
||||
{
|
||||
/* set the first VBI timer to go at the start of line 16 */
|
||||
timer_set(video_screen_get_time_until_pos(ld->screen, 16*2, 0), ld, LASERDISC_CODE_LINE16 << 2, vbi_data_fetch);
|
||||
|
||||
/* play forward by default */
|
||||
return fieldnum;
|
||||
}
|
||||
|
||||
|
||||
/*-------------------------------------------------
|
||||
vp931_data_w - handle a parallel data write
|
||||
to the 22VP931
|
||||
-------------------------------------------------*/
|
||||
|
||||
static void vp931_data_w(laserdisc_state *ld, UINT8 prev, UINT8 data)
|
||||
{
|
||||
/* set a timer to synchronize execution before sending the data */
|
||||
timer_call_after_resynch(ld, data, deferred_data_w);
|
||||
}
|
||||
|
||||
|
||||
/*-------------------------------------------------
|
||||
vp931_data_r - handle a parallel data read
|
||||
from the 22VP931
|
||||
-------------------------------------------------*/
|
||||
|
||||
static UINT8 vp931_data_r(laserdisc_state *ld)
|
||||
{
|
||||
ldplayer_data *player = ld->player;
|
||||
|
||||
/* if data is pending, clear the pending flag and notify any callbacks */
|
||||
if (player->tocontroller_pending)
|
||||
{
|
||||
player->tocontroller_pending = FALSE;
|
||||
if (player->data_ready_cb != NULL)
|
||||
(*player->data_ready_cb)(ld->device, FALSE);
|
||||
}
|
||||
|
||||
/* also boost interleave for 4 scanlines to ensure proper communications */
|
||||
cpu_boost_interleave(attotime_zero, attotime_mul(video_screen_get_scan_period(ld->screen), 4));
|
||||
return player->tocontroller;
|
||||
}
|
||||
|
||||
|
||||
/*-------------------------------------------------
|
||||
vp931_ready - return the status of "ready"
|
||||
to the caller (ready to accept another
|
||||
command)
|
||||
-------------------------------------------------*/
|
||||
|
||||
static UINT8 vp931_ready(laserdisc_state *ld)
|
||||
{
|
||||
/* if data is pending, we are not ready */
|
||||
ldplayer_data *player = ld->player;
|
||||
return player->fromcontroller_pending ? CLEAR_LINE : ASSERT_LINE;
|
||||
}
|
||||
|
||||
|
||||
/*-------------------------------------------------
|
||||
vp931_data_ready - return the status of
|
||||
"data available" to the caller
|
||||
-------------------------------------------------*/
|
||||
|
||||
static UINT8 vp931_data_ready(laserdisc_state *ld)
|
||||
{
|
||||
ldplayer_data *player = ld->player;
|
||||
return player->tocontroller_pending ? ASSERT_LINE : CLEAR_LINE;
|
||||
}
|
||||
|
||||
|
||||
/*-------------------------------------------------
|
||||
output0_w - controls audio/video squelch
|
||||
and other bits
|
||||
-------------------------------------------------*/
|
||||
|
||||
static WRITE8_HANDLER( output0_w )
|
||||
{
|
||||
laserdisc_state *ld = find_vp931(machine);
|
||||
ldplayer_data *player = ld->player;
|
||||
|
||||
/*
|
||||
$80 = n/c
|
||||
$40 = LED (?) -> C335
|
||||
$20 = LED (?)
|
||||
$10 = LED (?) -> CX
|
||||
$08 = EJECT
|
||||
$04 = inverted -> AUDIO MUTE II
|
||||
$02 = inverted -> AUDIO MUTE I
|
||||
$01 = inverted -> VIDEO MUTE
|
||||
*/
|
||||
|
||||
if (LOG_PORTS && (player->out0 ^ data) & 0xff)
|
||||
{
|
||||
printf("%03X:out0:", activecpu_get_pc());
|
||||
if ( (data & 0x80)) printf(" ???");
|
||||
if ( (data & 0x40)) printf(" LED1");
|
||||
if ( (data & 0x20)) printf(" LED2");
|
||||
if ( (data & 0x10)) printf(" LED3");
|
||||
if ( (data & 0x08)) printf(" EJECT");
|
||||
if (!(data & 0x04)) printf(" AUDMUTE2");
|
||||
if (!(data & 0x02)) printf(" AUDMUTE1");
|
||||
if (!(data & 0x01)) printf(" VIDMUTE");
|
||||
printf("\n");
|
||||
player->out0 = data;
|
||||
}
|
||||
|
||||
/* update a/v squelch */
|
||||
ldcore_set_audio_squelch(ld, !(data & 0x02), !(data & 0x04));
|
||||
ldcore_set_video_squelch(ld, !(data & 0x01));
|
||||
}
|
||||
|
||||
|
||||
/*-------------------------------------------------
|
||||
output1_w - controls scanning behaviors
|
||||
-------------------------------------------------*/
|
||||
|
||||
static WRITE8_HANDLER( output1_w )
|
||||
{
|
||||
laserdisc_state *ld = find_vp931(machine);
|
||||
ldplayer_data *player = ld->player;
|
||||
INT32 speed = 0;
|
||||
|
||||
/*
|
||||
$80 = n/c
|
||||
$40 = n/c
|
||||
$20 = n/c
|
||||
$10 = n/c
|
||||
$08 = inverted -> SMS
|
||||
$04 = inverted -> SSS
|
||||
$02 = inverted -> SCAN CMD
|
||||
$01 = OSM
|
||||
*/
|
||||
|
||||
if (LOG_PORTS && (player->out1 ^ data) & 0x08)
|
||||
{
|
||||
mame_printf_debug("%03X:out1:", activecpu_get_pc());
|
||||
if (!(data & 0x08)) mame_printf_debug(" SMS");
|
||||
mame_printf_debug("\n");
|
||||
player->out1 = data;
|
||||
}
|
||||
|
||||
/* speed is 0 unless SCAN CMD is clear */
|
||||
speed = 0;
|
||||
if (!(data & 0x02))
|
||||
{
|
||||
/* fast/slow is based on bit 2 */
|
||||
speed = (data & 0x04) ? VP931_SCAN_FAST_SPEED : VP931_SCAN_SPEED;
|
||||
|
||||
/* direction is based on bit 0 */
|
||||
if (data & 0x01)
|
||||
speed = -speed;
|
||||
}
|
||||
|
||||
/* update the speed */
|
||||
ldcore_set_slider_speed(ld, speed);
|
||||
}
|
||||
|
||||
|
||||
/*-------------------------------------------------
|
||||
lcd_w - vestigial LCD frame display
|
||||
-------------------------------------------------*/
|
||||
|
||||
static WRITE8_HANDLER( lcd_w )
|
||||
{
|
||||
/*
|
||||
Frame number is written as 5 digits here; however, it is not actually
|
||||
connected
|
||||
*/
|
||||
}
|
||||
|
||||
|
||||
/*-------------------------------------------------
|
||||
keypad_r - vestigial keypad/button controls
|
||||
-------------------------------------------------*/
|
||||
|
||||
static READ8_HANDLER( keypad_r )
|
||||
{
|
||||
/*
|
||||
From the code, this is apparently a vestigial keypad with basic controls:
|
||||
$01 = play
|
||||
$02 = still
|
||||
$04 = jump 25 frames backward
|
||||
$08 = jump 25 frames forward
|
||||
$10 = search for frame 50(?)
|
||||
$20 = search for frame 350(?)
|
||||
$40 = reset
|
||||
$80 = play reverse
|
||||
*/
|
||||
return 0x00;
|
||||
}
|
||||
|
||||
|
||||
/*-------------------------------------------------
|
||||
datic_r - read the latched value from the
|
||||
DATIC circuit
|
||||
-------------------------------------------------*/
|
||||
|
||||
static READ8_HANDLER( datic_r )
|
||||
{
|
||||
laserdisc_state *ld = find_vp931(machine);
|
||||
return ld->player->daticval;
|
||||
}
|
||||
|
||||
|
||||
/*-------------------------------------------------
|
||||
from_controller_r - read the value the
|
||||
external controller wrote
|
||||
-------------------------------------------------*/
|
||||
|
||||
static READ8_HANDLER( from_controller_r )
|
||||
{
|
||||
laserdisc_state *ld = find_vp931(machine);
|
||||
ldplayer_data *player = ld->player;
|
||||
|
||||
/* clear the pending flag and return the data */
|
||||
player->fromcontroller_pending = FALSE;
|
||||
return player->fromcontroller;
|
||||
}
|
||||
|
||||
|
||||
/*-------------------------------------------------
|
||||
to_controller_w - write a value back to the
|
||||
external controller
|
||||
-------------------------------------------------*/
|
||||
|
||||
static WRITE8_HANDLER( to_controller_w )
|
||||
{
|
||||
laserdisc_state *ld = find_vp931(machine);
|
||||
ldplayer_data *player = ld->player;
|
||||
|
||||
/* set the pending flag and stash the data */
|
||||
player->tocontroller_pending = TRUE;
|
||||
player->tocontroller = data;
|
||||
|
||||
/* signal to the callback if provided */
|
||||
if (player->data_ready_cb != NULL)
|
||||
(*player->data_ready_cb)(ld->device, TRUE);
|
||||
|
||||
/* also boost interleave for 4 scanlines to ensure proper communications */
|
||||
cpu_boost_interleave(attotime_zero, attotime_mul(video_screen_get_scan_period(ld->screen), 4));
|
||||
}
|
||||
|
||||
|
||||
/*-------------------------------------------------
|
||||
port1_r - read the 8048 I/O port 1
|
||||
-------------------------------------------------*/
|
||||
|
||||
static READ8_HANDLER( port1_r )
|
||||
{
|
||||
laserdisc_state *ld = find_vp931(machine);
|
||||
ldplayer_data *player = ld->player;
|
||||
UINT8 result = 0x00;
|
||||
|
||||
/*
|
||||
$80 = P17 = (in) unsure
|
||||
$40 = P16 = (in) /ERP from datic circuit
|
||||
$20 = P15 = (in) D105
|
||||
*/
|
||||
|
||||
if (!player->daticerp)
|
||||
result |= 0x40;
|
||||
|
||||
return result;
|
||||
}
|
||||
|
||||
|
||||
/*-------------------------------------------------
|
||||
port1_w - write the 8048 I/O port 1
|
||||
-------------------------------------------------*/
|
||||
|
||||
static WRITE8_HANDLER( port1_w )
|
||||
{
|
||||
laserdisc_state *ld = find_vp931(machine);
|
||||
ldplayer_data *player = ld->player;
|
||||
|
||||
/*
|
||||
$10 = P14 = (out) D104 -> /SPEED
|
||||
$08 = P13 = (out) D103 -> /TIMER ENABLE
|
||||
$04 = P12 = (out) D102 -> /REV
|
||||
$02 = P11 = (out) D101 -> /FORW
|
||||
$01 = P10 = (out) D100 -> some op-amp then to C334, B56, B332
|
||||
*/
|
||||
|
||||
if (LOG_PORTS && (player->port1 ^ data) & 0x1f)
|
||||
{
|
||||
printf("%03X:port1:", activecpu_get_pc());
|
||||
if (!(data & 0x10)) printf(" SPEED");
|
||||
if (!(data & 0x08)) printf(" TIMENABLE");
|
||||
if (!(data & 0x04)) printf(" REV");
|
||||
if (!(data & 0x02)) printf(" FORW");
|
||||
if (!(data & 0x01)) printf(" OPAMP");
|
||||
printf("\n");
|
||||
}
|
||||
|
||||
/* if bit 0 is set, we are not tracking */
|
||||
if (data & 0x01)
|
||||
player->trackdir = 0;
|
||||
|
||||
/* if bit 0 is clear and we weren't tracking before, initialize the state */
|
||||
else if (player->trackdir == 0)
|
||||
{
|
||||
player->advanced = 0;
|
||||
|
||||
/* if bit 2 is clear, we are moving backwards */
|
||||
if (!(data & 0x04))
|
||||
{
|
||||
player->trackdir = -1;
|
||||
player->trackstate = 1;
|
||||
}
|
||||
|
||||
/* if bit 1 is clear, we are moving forward */
|
||||
else if (!(data & 0x02))
|
||||
{
|
||||
player->trackdir = 1;
|
||||
player->trackstate = 0;
|
||||
}
|
||||
}
|
||||
|
||||
/* if we have a timer, adjust it */
|
||||
if (player->tracktimer != NULL)
|
||||
{
|
||||
/* turn it off if we're not tracking */
|
||||
if (player->trackdir == 0)
|
||||
timer_device_adjust_periodic(player->tracktimer, attotime_never, 0, attotime_never);
|
||||
|
||||
/* if we just started tracking, or if the speed was changed, reprime the timer */
|
||||
else if (((player->port1 ^ data) & 0x11) != 0)
|
||||
{
|
||||
/* speeds here are just guesses, but work with the player logic; this is the time per half-track */
|
||||
attotime speed = (data & 0x10) ? ATTOTIME_IN_USEC(60) : ATTOTIME_IN_USEC(10);
|
||||
|
||||
/* always start with an initial long delay; the code expects this */
|
||||
timer_device_adjust_periodic(player->tracktimer, ATTOTIME_IN_USEC(100), 0, speed);
|
||||
}
|
||||
}
|
||||
|
||||
player->port1 = data;
|
||||
}
|
||||
|
||||
|
||||
/*-------------------------------------------------
|
||||
port2_r - read from the 8048 I/O port 2
|
||||
-------------------------------------------------*/
|
||||
|
||||
static READ8_HANDLER( port2_r )
|
||||
{
|
||||
laserdisc_state *ld = find_vp931(machine);
|
||||
ldplayer_data *player = ld->player;
|
||||
UINT8 result = 0x00;
|
||||
|
||||
/*
|
||||
$80 = P27 = (in) set/reset latch; set by FOC LS, reset by IGR
|
||||
$20 = P25 = (in) D125 -> 0 when data written to controller is preset, reset to 1 when read
|
||||
$10 = P24 = (in) D124 -> 0 when data from controller is present, reset to 1 on a read
|
||||
*/
|
||||
|
||||
if (!player->tocontroller_pending)
|
||||
result |= 0x20;
|
||||
if (!player->fromcontroller_pending)
|
||||
result |= 0x10;
|
||||
|
||||
return result;
|
||||
}
|
||||
|
||||
|
||||
/*-------------------------------------------------
|
||||
port2_w - write the 8048 I/O port 2
|
||||
-------------------------------------------------*/
|
||||
|
||||
static WRITE8_HANDLER( port2_w )
|
||||
{
|
||||
/*
|
||||
$40 = P26 = (out) cleared while data is sent back & forth; set afterwards
|
||||
[Not actually connected, but this is done in the code]
|
||||
*/
|
||||
}
|
||||
|
||||
|
||||
/*-------------------------------------------------
|
||||
t0_r - return the T0 line status, which is
|
||||
connected to the DATIC's data strobe line
|
||||
-------------------------------------------------*/
|
||||
|
||||
static READ8_HANDLER( t0_r )
|
||||
{
|
||||
laserdisc_state *ld = find_vp931(machine);
|
||||
return ld->player->datastrobe;
|
||||
}
|
||||
|
||||
|
||||
/*-------------------------------------------------
|
||||
t1_r - return the T1 line status, which is
|
||||
connected to the tracking state and is used
|
||||
to count the number of tracks advanced
|
||||
-------------------------------------------------*/
|
||||
|
||||
static READ8_HANDLER( t1_r )
|
||||
{
|
||||
laserdisc_state *ld = find_vp931(machine);
|
||||
return ld->player->trackstate;
|
||||
}
|
||||
|
||||
|
||||
/*-------------------------------------------------
|
||||
vbi_data_fetch - called 4 times per scanline
|
||||
on lines 16, 17, and 18 to feed the VBI data
|
||||
through one byte at a time
|
||||
-------------------------------------------------*/
|
||||
|
||||
static TIMER_CALLBACK( vbi_data_fetch )
|
||||
{
|
||||
laserdisc_state *ld = ptr;
|
||||
ldplayer_data *player = ld->player;
|
||||
int which = param & 3;
|
||||
int line = param >> 2;
|
||||
UINT32 code = 0;
|
||||
|
||||
/* fetch the code and compute the DATIC latched value */
|
||||
if (line >= LASERDISC_CODE_LINE16 && line <= LASERDISC_CODE_LINE18)
|
||||
code = laserdisc_get_field_code(ld->device, line);
|
||||
|
||||
/* at the start of each line, signal an interrupt and use a timer to turn it off */
|
||||
if (which == 0)
|
||||
{
|
||||
cpunum_set_input_line(machine, player->cpunum, MCS48_INPUT_IRQ, ASSERT_LINE);
|
||||
timer_set(ATTOTIME_IN_NSEC(5580), ld, 0, irq_off);
|
||||
}
|
||||
|
||||
/* clock the data strobe on each subsequent callback */
|
||||
else if (code != 0)
|
||||
{
|
||||
player->daticval = code >> (8 * (3 - which));
|
||||
player->datastrobe = 1;
|
||||
timer_set(ATTOTIME_IN_NSEC(5000), ld, 0, datastrobe_off);
|
||||
}
|
||||
|
||||
/* determine the next bit to fetch and reprime ourself */
|
||||
if (++which == 4)
|
||||
{
|
||||
which = 0;
|
||||
line++;
|
||||
}
|
||||
if (line <= LASERDISC_CODE_LINE18 + 1)
|
||||
timer_set(video_screen_get_time_until_pos(ld->screen, line*2, which * 2 * video_screen_get_width(ld->screen) / 4), ld, (line << 2) | which, vbi_data_fetch);
|
||||
}
|
||||
|
||||
|
||||
/*-------------------------------------------------
|
||||
deferred_data_w - handle a write from the
|
||||
external controller
|
||||
-------------------------------------------------*/
|
||||
|
||||
static TIMER_CALLBACK( deferred_data_w )
|
||||
{
|
||||
laserdisc_state *ld = ptr;
|
||||
ldplayer_data *player = ld->player;
|
||||
|
||||
/* set the value and mark it pending */
|
||||
player->fromcontroller = param;
|
||||
player->fromcontroller_pending = TRUE;
|
||||
|
||||
/* track the commands for debugging purposes */
|
||||
if (player->cmdcount < ARRAY_LENGTH(player->cmdbuf))
|
||||
{
|
||||
player->cmdbuf[player->cmdcount++] = param;
|
||||
if (LOG_COMMANDS && player->cmdcount == 3)
|
||||
printf("Cmd: %02X %02X %02X\n", player->cmdbuf[0], player->cmdbuf[1], player->cmdbuf[2]);
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
/*-------------------------------------------------
|
||||
irq_off - turn off the 8048 IRQ signal
|
||||
-------------------------------------------------*/
|
||||
|
||||
static TIMER_CALLBACK( irq_off )
|
||||
{
|
||||
laserdisc_state *ld = ptr;
|
||||
cpunum_set_input_line(machine, ld->player->cpunum, MCS48_INPUT_IRQ, CLEAR_LINE);
|
||||
}
|
||||
|
||||
|
||||
/*-------------------------------------------------
|
||||
datastrobe_off - turn off the DATIC data
|
||||
strobe signal
|
||||
-------------------------------------------------*/
|
||||
|
||||
static TIMER_CALLBACK( datastrobe_off )
|
||||
{
|
||||
laserdisc_state *ld = ptr;
|
||||
ld->player->datastrobe = 0;
|
||||
}
|
||||
|
||||
|
||||
/*-------------------------------------------------
|
||||
erp_off - turn off the DATIC ERP signal
|
||||
-------------------------------------------------*/
|
||||
|
||||
static TIMER_CALLBACK( erp_off )
|
||||
{
|
||||
laserdisc_state *ld = ptr;
|
||||
ld->player->daticerp = 0;
|
||||
}
|
||||
|
||||
|
||||
/*-------------------------------------------------
|
||||
track_timer - advance by one half-track
|
||||
-------------------------------------------------*/
|
||||
|
||||
static TIMER_DEVICE_CALLBACK( track_timer )
|
||||
{
|
||||
laserdisc_state *ld = ptr;
|
||||
ldplayer_data *player = ld->player;
|
||||
|
||||
/* advance by the count and toggle the state */
|
||||
player->trackstate ^= 1;
|
||||
if ((player->trackdir < 0 && !player->trackstate) || (player->trackdir > 0 && player->trackstate))
|
||||
{
|
||||
ldcore_advance_slider(ld, player->trackdir);
|
||||
player->advanced += player->trackdir;
|
||||
}
|
||||
}
|
105
src/emu/timer.c
105
src/emu/timer.c
@ -572,11 +572,11 @@ void timer_adjust_oneshot(emu_timer *which, attotime duration, INT32 param)
|
||||
|
||||
void timer_device_adjust_oneshot(const device_config *timer, attotime duration, INT32 param)
|
||||
{
|
||||
#ifndef NDEBUG
|
||||
#ifdef MAME_DEBUG
|
||||
timer_config *config = timer->inline_config;
|
||||
|
||||
/* only makes sense for periodic timers */
|
||||
assert(config->type == TIMER_TYPE_PERIODIC);
|
||||
/* doesn't make sense for scanline timers */
|
||||
assert(config->type != TIMER_TYPE_SCANLINE);
|
||||
#endif
|
||||
|
||||
timer_device_adjust_periodic(timer, duration, param, attotime_never);
|
||||
@ -624,11 +624,11 @@ void timer_adjust_periodic(emu_timer *which, attotime start_delay, INT32 param,
|
||||
void timer_device_adjust_periodic(const device_config *timer, attotime start_delay, INT32 param, attotime period)
|
||||
{
|
||||
timer_state *state = get_safe_token(timer);
|
||||
#ifndef NDEBUG
|
||||
#ifdef MAME_DEBUG
|
||||
timer_config *config = timer->inline_config;
|
||||
|
||||
/* only makes sense for periodic timers */
|
||||
assert(config->type == TIMER_TYPE_PERIODIC);
|
||||
/* doesn't make sense for scanline timers */
|
||||
assert(config->type != TIMER_TYPE_SCANLINE);
|
||||
#endif
|
||||
|
||||
state->start_delay = start_delay;
|
||||
@ -688,11 +688,11 @@ void timer_reset(emu_timer *which, attotime duration)
|
||||
void timer_device_reset(const device_config *timer)
|
||||
{
|
||||
timer_state *state = get_safe_token(timer);
|
||||
#ifndef NDEBUG
|
||||
#ifdef MAME_DEBUG
|
||||
timer_config *config = timer->inline_config;
|
||||
|
||||
/* only makes sense for periodic timers */
|
||||
assert(config->type == TIMER_TYPE_PERIODIC);
|
||||
/* doesn't make sense for scanline timers */
|
||||
assert(config->type != TIMER_TYPE_SCANLINE);
|
||||
#endif
|
||||
|
||||
timer_adjust_periodic(state->timer, state->start_delay, 0, state->period);
|
||||
@ -745,8 +745,7 @@ int timer_device_enabled(const device_config *timer)
|
||||
|
||||
|
||||
/*-------------------------------------------------
|
||||
timer_get_param
|
||||
timer_get_param_ptr - returns the callback
|
||||
timer_get_param - returns the callback
|
||||
parameter of a timer
|
||||
-------------------------------------------------*/
|
||||
|
||||
@ -759,30 +758,79 @@ int timer_get_param(emu_timer *which)
|
||||
int timer_device_get_param(const device_config *timer)
|
||||
{
|
||||
timer_state *state = get_safe_token(timer);
|
||||
#ifndef NDEBUG
|
||||
#ifdef MAME_DEBUG
|
||||
timer_config *config = timer->inline_config;
|
||||
|
||||
/* only makes sense for periodic timers */
|
||||
assert(config->type == TIMER_TYPE_PERIODIC);
|
||||
/* doesn't make sense for scanline timers */
|
||||
assert(config->type != TIMER_TYPE_SCANLINE);
|
||||
#endif
|
||||
|
||||
return state->param;
|
||||
}
|
||||
|
||||
|
||||
void *timer_get_param_ptr(emu_timer *which)
|
||||
/*-------------------------------------------------
|
||||
timer_set_param - changes the callback
|
||||
parameter of a timer
|
||||
-------------------------------------------------*/
|
||||
|
||||
void timer_set_param(emu_timer *which, int param)
|
||||
{
|
||||
which->param = param;
|
||||
}
|
||||
|
||||
|
||||
void timer_device_set_param(const device_config *timer, int param)
|
||||
{
|
||||
timer_state *state = get_safe_token(timer);
|
||||
#ifdef MAME_DEBUG
|
||||
timer_config *config = timer->inline_config;
|
||||
|
||||
/* doesn't make sense for scanline timers */
|
||||
assert(config->type != TIMER_TYPE_SCANLINE);
|
||||
#endif
|
||||
|
||||
state->param = param;
|
||||
}
|
||||
|
||||
|
||||
/*-------------------------------------------------
|
||||
timer_get_ptr - returns the callback pointer
|
||||
of a timer
|
||||
-------------------------------------------------*/
|
||||
|
||||
void *timer_get_ptr(emu_timer *which)
|
||||
{
|
||||
return which->ptr;
|
||||
}
|
||||
|
||||
|
||||
void *timer_device_get_param_ptr(const device_config *timer)
|
||||
void *timer_device_get_ptr(const device_config *timer)
|
||||
{
|
||||
timer_state *state = get_safe_token(timer);
|
||||
return state->ptr;
|
||||
}
|
||||
|
||||
|
||||
/*-------------------------------------------------
|
||||
timer_set_ptr - changes the callback pointer
|
||||
of a timer
|
||||
-------------------------------------------------*/
|
||||
|
||||
void timer_set_ptr(emu_timer *which, void *ptr)
|
||||
{
|
||||
which->ptr = ptr;
|
||||
}
|
||||
|
||||
|
||||
void timer_device_set_ptr(const device_config *timer, void *ptr)
|
||||
{
|
||||
timer_state *state = get_safe_token(timer);
|
||||
state->ptr = ptr;
|
||||
}
|
||||
|
||||
|
||||
|
||||
/***************************************************************************
|
||||
TIMING FUNCTIONS
|
||||
***************************************************************************/
|
||||
@ -994,7 +1042,7 @@ static DEVICE_START( timer )
|
||||
|
||||
/* get and validate the configuration */
|
||||
config = device->inline_config;
|
||||
assert((config->type == TIMER_TYPE_PERIODIC) || (config->type == TIMER_TYPE_SCANLINE));
|
||||
assert(config->type == TIMER_TYPE_PERIODIC || config->type == TIMER_TYPE_SCANLINE || config->type == TIMER_TYPE_GENERIC);
|
||||
assert(config->callback != NULL);
|
||||
|
||||
/* copy the pointer parameter */
|
||||
@ -1007,6 +1055,29 @@ static DEVICE_START( timer )
|
||||
/* type based configuration */
|
||||
switch (config->type)
|
||||
{
|
||||
case TIMER_TYPE_GENERIC:
|
||||
/* make sure that only the applicable parameters are filled in */
|
||||
assert(config->screen == NULL);
|
||||
assert(config->first_vpos == 0);
|
||||
assert(config->increment == 0);
|
||||
assert(config->start_delay == 0);
|
||||
assert(config->period == 0);
|
||||
|
||||
/* copy the optional integer parameter */
|
||||
state->param = config->param;
|
||||
|
||||
/* convert the start_delay and period into attotime */
|
||||
state->period = attotime_never;
|
||||
state->start_delay = attotime_zero;
|
||||
|
||||
/* register for state saves */
|
||||
state_save_register_item(unique_tag, 0, state->param);
|
||||
|
||||
/* allocate the backing timer */
|
||||
param = (void *)device;
|
||||
state->timer = timer_alloc(periodic_timer_device_timer_callback, param);
|
||||
break;
|
||||
|
||||
case TIMER_TYPE_PERIODIC:
|
||||
/* make sure that only the applicable parameters are filled in */
|
||||
assert(config->screen == NULL);
|
||||
|
@ -28,7 +28,8 @@
|
||||
enum
|
||||
{
|
||||
TIMER_TYPE_PERIODIC = 0,
|
||||
TIMER_TYPE_SCANLINE
|
||||
TIMER_TYPE_SCANLINE,
|
||||
TIMER_TYPE_GENERIC
|
||||
};
|
||||
|
||||
|
||||
@ -105,6 +106,11 @@ typedef struct _emu_timer emu_timer;
|
||||
TIMER DEVICE CONFIGURATION MACROS
|
||||
***************************************************************************/
|
||||
|
||||
#define MDRV_TIMER_ADD(_tag, _callback) \
|
||||
MDRV_DEVICE_ADD(_tag, TIMER) \
|
||||
MDRV_DEVICE_CONFIG_DATA32(timer_config, type, TIMER_TYPE_GENERIC) \
|
||||
MDRV_DEVICE_CONFIG_DATAPTR(timer_config, callback, _callback) \
|
||||
|
||||
#define MDRV_TIMER_ADD_PERIODIC(_tag, _callback, _period) \
|
||||
MDRV_DEVICE_ADD(_tag, TIMER) \
|
||||
MDRV_DEVICE_CONFIG_DATA32(timer_config, type, TIMER_TYPE_PERIODIC) \
|
||||
@ -224,8 +230,17 @@ int timer_device_enabled(const device_config *timer);
|
||||
int timer_get_param(emu_timer *which);
|
||||
int timer_device_get_param(const device_config *timer);
|
||||
|
||||
void *timer_get_param_ptr(emu_timer *which);
|
||||
void *timer_device_get_param_ptr(const device_config *timer);
|
||||
/* changes the callback parameter of a timer */
|
||||
void timer_set_param(emu_timer *which, int param);
|
||||
void timer_device_set_param(const device_config *timer, int param);
|
||||
|
||||
/* returns the callback pointer of a timer */
|
||||
void *timer_get_ptr(emu_timer *which);
|
||||
void *timer_device_get_ptr(const device_config *timer);
|
||||
|
||||
/* changes the callback pointer of a timer */
|
||||
void timer_set_ptr(emu_timer *which, void *ptr);
|
||||
void timer_device_set_ptr(const device_config *timer, void *ptr);
|
||||
|
||||
|
||||
|
||||
|
@ -26,7 +26,6 @@ but requires a special level III player for proper control. Video: CAV. Audio: A
|
||||
*/
|
||||
|
||||
#include "mame.h"
|
||||
#include "deprecat.h"
|
||||
#include "driver.h"
|
||||
#include "cpu/m6809/m6809.h"
|
||||
#include "cpu/m6502/m6502.h"
|
||||
@ -37,6 +36,10 @@ but requires a special level III player for proper control. Video: CAV. Audio: A
|
||||
#include "machine/6532riot.h"
|
||||
#include "machine/x2212.h"
|
||||
|
||||
|
||||
#define MASTER_XTAL XTAL_14_31818MHz
|
||||
|
||||
|
||||
/*
|
||||
fff6=firq e4a2 when dav goes active/low
|
||||
fff8=irq e38f This is through a flip-flop so goes off (high as active low) only when reset_irq is active - low.
|
||||
@ -56,226 +59,77 @@ fffe=reset e7cc
|
||||
/* FXXXXX for first field
|
||||
AXXXXX for second field */
|
||||
|
||||
static const device_config *laserdisc;
|
||||
static int m_n_disc_lock;
|
||||
static int m_n_disc_left_audio;
|
||||
static int m_n_disc_right_audio;
|
||||
static int m_n_disc_data;
|
||||
static int command_offset;
|
||||
static int command_data[ 3 ];
|
||||
static int manchester_data[ 6 ];
|
||||
static int manchester_offset;
|
||||
static int disc_reset;
|
||||
static int disk_opr = 0;
|
||||
static int dav = 0x80;
|
||||
static int dak_just_low = 0; /* simulate the 15 uS time for the player to read the data */
|
||||
static int dak = 0x40; /* DAK or DSKFULL active low indicates player has data,
|
||||
reset when player has read data */
|
||||
static int disk_data; /* after a command is sent the first bit indicates an error, except of the data is 0x00 which indicates an invalid manchester data read (whatever that means) */
|
||||
|
||||
int laser_disc_speed = 0;
|
||||
int laser_disc_field = 0;
|
||||
void laser_seek_frame( int frame )
|
||||
{
|
||||
}
|
||||
|
||||
static int m_n_disc_read_data;
|
||||
|
||||
/* 20 = DISKOPR - Active low
|
||||
40 = DISKFULL - Active low
|
||||
80 = DISKDAV - Active low data available
|
||||
*/
|
||||
READ8_HANDLER( firefox_disc_status_r )
|
||||
static READ8_HANDLER( firefox_disc_status_r )
|
||||
{
|
||||
int n_data;
|
||||
n_data = dav | dak | disk_opr; /* always operational */
|
||||
logerror( "%08x: disc status r %02x\n", activecpu_get_pc(), n_data & ( 0x80 | 0x40 | 0x20 ) );
|
||||
/*
|
||||
fprintf(stderr, "%08x: reading disc status r %02x\n", activecpu_get_pc(), n_data & ( 0x80 | 0x40 | 0x20 ) );
|
||||
*/
|
||||
if(dak_just_low)
|
||||
{
|
||||
/* assume that the next status read will be after 15uS */
|
||||
dak = 0x40;
|
||||
dak_just_low = 0;
|
||||
}
|
||||
return n_data;
|
||||
UINT8 result = 0xff;
|
||||
|
||||
result ^= 0x20;
|
||||
if (!laserdisc_line_r(laserdisc, LASERDISC_LINE_READY))
|
||||
result ^= 0x40;
|
||||
if (laserdisc_line_r(laserdisc, LASERDISC_LINE_DATA_AVAIL))
|
||||
result ^= 0x80;
|
||||
|
||||
return result;
|
||||
}
|
||||
|
||||
/* 4105 - DREAD */
|
||||
/* this reset RDDSK (&DSKRD) */
|
||||
READ8_HANDLER( firefox_disc_data_r )
|
||||
static READ8_HANDLER( firefox_disc_data_r )
|
||||
{
|
||||
return disk_data;
|
||||
return m_n_disc_read_data;
|
||||
}
|
||||
|
||||
/* DISK READ ENABLE */
|
||||
/* 4218 - DSKREAD, set RDDSK */
|
||||
WRITE8_HANDLER( firefox_disc_read_w )
|
||||
static WRITE8_HANDLER( firefox_disc_read_w )
|
||||
{
|
||||
dav=0x80;
|
||||
if( manchester_offset < 6 )
|
||||
{
|
||||
disk_data = manchester_data[ manchester_offset++ ];
|
||||
if(manchester_offset < 6)
|
||||
{
|
||||
dav = 0; /* more data */
|
||||
cpunum_set_input_line( machine, 0, M6809_FIRQ_LINE, ASSERT_LINE );
|
||||
}
|
||||
|
||||
}
|
||||
m_n_disc_read_data = laserdisc_data_r(laserdisc);
|
||||
}
|
||||
|
||||
WRITE8_HANDLER( firefox_disc_lock_w )
|
||||
static WRITE8_HANDLER( firefox_disc_lock_w )
|
||||
{
|
||||
m_n_disc_lock = data & 0x80;
|
||||
}
|
||||
|
||||
WRITE8_HANDLER( firefox_disc_right_audio_enable_w )
|
||||
static WRITE8_HANDLER( audio_enable_w )
|
||||
{
|
||||
m_n_disc_right_audio = data & 0x80;
|
||||
if (!(offset & 1))
|
||||
m_n_disc_right_audio = data & 0x80;
|
||||
else
|
||||
m_n_disc_left_audio = data & 0x80;
|
||||
}
|
||||
|
||||
WRITE8_HANDLER( firefox_disc_left_audio_enable_w )
|
||||
static WRITE8_HANDLER( firefox_disc_reset_w )
|
||||
{
|
||||
m_n_disc_left_audio = data & 0x80;
|
||||
}
|
||||
|
||||
WRITE8_HANDLER( firefox_disc_reset_w )
|
||||
{
|
||||
disc_reset = (data & 0x80);
|
||||
if(!disc_reset)
|
||||
{
|
||||
laser_disc_speed = 0;
|
||||
manchester_offset = 6; /* no data available */
|
||||
command_offset = 0;
|
||||
dak = 0x40;
|
||||
dav = 0x80;
|
||||
}
|
||||
laserdisc_line_w(laserdisc, LASERDISC_LINE_RESET, (data & 0x80) ? CLEAR_LINE : ASSERT_LINE);
|
||||
}
|
||||
|
||||
/* active low on dbb7 */
|
||||
WRITE8_HANDLER( firefox_disc_write_w )
|
||||
static WRITE8_HANDLER( firefox_disc_write_w )
|
||||
{
|
||||
if( ( data & 0x80 ) == 0 )
|
||||
{
|
||||
dak = 0; /* should go high after 15 uS */
|
||||
dak_just_low = 1;
|
||||
command_data[ command_offset++ ] = m_n_disc_data;
|
||||
if( command_offset == 3 )
|
||||
{
|
||||
command_offset = 0;
|
||||
switch( command_data[ 0 ] & 0xf0 )
|
||||
{
|
||||
case 0xf0:
|
||||
logerror( "CMD: goto Frame #%01x%02x%02x & play forward\n", command_data[ 0 ] & 0x0f, command_data[ 1 ], command_data[ 2 ] );
|
||||
laser_disc_field =
|
||||
( ( command_data[ 0 ] & 0x0f ) * 20000 ) +
|
||||
( (( command_data[ 1 ] & 0xf0 ) >> 4) * 2000 ) +
|
||||
( ( command_data[ 1 ] & 0x0f ) * 200 ) +
|
||||
( (( command_data[ 2 ] & 0xf0 ) >> 4) * 20 ) +
|
||||
( ( command_data[ 2 ] & 0x0f ) * 2 );
|
||||
laser_seek_frame(laser_disc_field >> 1);
|
||||
/*
|
||||
fprintf(stderr, "CMD: goto frame #%01x%02x%02x & play forward disc_field %d\n", command_data[ 0 ] & 0x0f, command_data[ 1 ], command_data[ 2 ] , laser_disc_field);
|
||||
*/
|
||||
laser_disc_speed = 1;
|
||||
return;
|
||||
case 0xd0:
|
||||
/*
|
||||
fprintf(stderr, "CMD: goto Frame #%01x%02x%02x & halt (first field)\n", command_data[ 0 ] & 0x0f, command_data[ 1 ], command_data[ 2 ] );
|
||||
*/
|
||||
laser_disc_field =
|
||||
( ( command_data[ 0 ] & 0x0f ) * 20000 ) +
|
||||
( (( command_data[ 1 ] & 0xf0 ) >> 4) * 2000 ) +
|
||||
( ( command_data[ 1 ] & 0x0f ) * 200 ) +
|
||||
( (( command_data[ 2 ] & 0xf0 ) >> 4) * 20 ) +
|
||||
( ( command_data[ 2 ] & 0x0f ) * 2 );
|
||||
laser_seek_frame(laser_disc_field >> 1);
|
||||
laser_disc_speed = 0;
|
||||
return;
|
||||
case 0x00:
|
||||
switch( command_data[ 0 ] & 0x0f )
|
||||
{
|
||||
case 0x00:
|
||||
switch( command_data[ 1 ] & 0xf0 )
|
||||
{
|
||||
case 0x00:
|
||||
laser_disc_speed = 1;
|
||||
return;
|
||||
case 0x10:
|
||||
laser_disc_speed = -1;
|
||||
return;
|
||||
case 0x20:
|
||||
laser_disc_speed = 0;
|
||||
return;
|
||||
case 0x40:
|
||||
return;
|
||||
case 0x50:
|
||||
return;
|
||||
case 0xa0:
|
||||
laser_disc_speed = 75;
|
||||
return;
|
||||
case 0xb0:
|
||||
laser_disc_speed = -75;
|
||||
return;
|
||||
case 0xe0:
|
||||
return;
|
||||
case 0xf0:
|
||||
return;
|
||||
}
|
||||
break;
|
||||
case 0x02:
|
||||
switch( command_data[ 1 ] )
|
||||
{
|
||||
case 0xb0:
|
||||
logerror( "CMD: Video ON/OFF %02x\n", command_data[ 2 ] );
|
||||
return;
|
||||
case 0xb1:
|
||||
logerror( "CMD: Audio-I ON/OFF %02x\n", command_data[ 2 ] );
|
||||
return;
|
||||
case 0xb2:
|
||||
logerror( "CMD: Audio-II ON/OFF %02x\n", command_data[ 2 ] );
|
||||
return;
|
||||
case 0xb3:
|
||||
logerror( "CMD: CX ON/OFF %02x\n", command_data[ 2 ] );
|
||||
return;
|
||||
}
|
||||
break;
|
||||
}
|
||||
break;
|
||||
}
|
||||
logerror( "CMD: invalid %02x%02x%02x\n", command_data[ 0 ], command_data[ 1 ], command_data[ 2 ] );
|
||||
}
|
||||
}
|
||||
if ( ( data & 0x80 ) == 0 )
|
||||
laserdisc_data_w(laserdisc, m_n_disc_data);
|
||||
}
|
||||
|
||||
/* latch the data */
|
||||
WRITE8_HANDLER( firefox_disc_data_w )
|
||||
static WRITE8_HANDLER( firefox_disc_data_w )
|
||||
{
|
||||
m_n_disc_data = data;
|
||||
}
|
||||
|
||||
static TIMER_DEVICE_CALLBACK( laserdisk_timer_callback )
|
||||
{
|
||||
if(param == 0 && laser_disc_speed != 0)
|
||||
{
|
||||
manchester_data[ 0 ] = ( ( laser_disc_field & 0x01 )?0xA0:0xF0 ) | ( ( laser_disc_field / 20000 ) % 10 );
|
||||
manchester_data[ 1 ] = ( ( ( laser_disc_field / 2000 ) % 10 ) << 4 ) | ( ( laser_disc_field / 200 ) % 10 );
|
||||
manchester_data[ 2 ] = ( ( ( laser_disc_field / 20 ) % 10 ) << 4 ) | ( ( laser_disc_field / 2 ) % 10 );
|
||||
manchester_data[ 3 ] = 0xff;
|
||||
manchester_data[ 4 ] = 0xff;
|
||||
manchester_data[ 5 ] = 0xff;
|
||||
manchester_offset = 0;
|
||||
cpunum_set_input_line( Machine, 0, M6809_FIRQ_LINE, ASSERT_LINE );
|
||||
dav = 0; /* buffer contains info */
|
||||
|
||||
laser_disc_field += laser_disc_speed;
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
|
||||
static unsigned char *tileram;
|
||||
static size_t tileram_size;
|
||||
static unsigned char *tile_palette;
|
||||
static unsigned char *sprite_palette;
|
||||
static const device_config *nvram_1c;
|
||||
@ -292,20 +146,20 @@ static int sprite_bank;
|
||||
*
|
||||
*************************************/
|
||||
|
||||
VIDEO_UPDATE( firefox )
|
||||
static VIDEO_UPDATE( firefox )
|
||||
{
|
||||
int x;
|
||||
int y;
|
||||
int sprite;
|
||||
const rectangle *visarea = video_screen_get_visible_area( Machine->primary_screen );
|
||||
int gfxtop = video_screen_get_visible_area(screen)->min_y;
|
||||
|
||||
fillbitmap( bitmap, 256, visarea );
|
||||
fillbitmap( bitmap, 256, cliprect );
|
||||
|
||||
for( y = 0; y < 64; y++ )
|
||||
{
|
||||
for( x = 0; x < 64; x++ )
|
||||
{
|
||||
drawgfx( bitmap, Machine->gfx[ 0 ], tileram[ x + ( y * 64 ) ], 0, 0, 0, x * 8, y * 8, visarea, TRANSPARENCY_PEN, 0 );
|
||||
drawgfx( bitmap, screen->machine->gfx[ 0 ], tileram[ x + ( y * 64 ) ], 0, 0, 0, x * 8, gfxtop + y * 8, cliprect, TRANSPARENCY_PEN, 0 );
|
||||
}
|
||||
}
|
||||
|
||||
@ -327,7 +181,7 @@ VIDEO_UPDATE( firefox )
|
||||
int flipx = flags & 0x20;
|
||||
int code = sprite_data[ 15 - row ] + ( 256 * ( ( flags >> 6 ) & 3 ) );
|
||||
|
||||
drawgfx( bitmap, Machine->gfx[ 1 ], code, color, flipx, flipy, x + 16, 500 - y - ( row * 16 ), visarea, TRANSPARENCY_PEN, 0 );
|
||||
drawgfx( bitmap, screen->machine->gfx[ 1 ], code, color, flipx, flipy, x + 16, gfxtop + 500 - y - ( row * 16 ), cliprect, TRANSPARENCY_PEN, 0 );
|
||||
}
|
||||
}
|
||||
}
|
||||
@ -339,33 +193,33 @@ static TIMER_DEVICE_CALLBACK( video_timer_callback )
|
||||
{
|
||||
video_screen_update_now(timer->machine->primary_screen);
|
||||
|
||||
cpunum_set_input_line( Machine, 0, M6809_IRQ_LINE, ASSERT_LINE );
|
||||
cputag_set_input_line( timer->machine, "main", M6809_IRQ_LINE, ASSERT_LINE );
|
||||
}
|
||||
|
||||
static void set_rgba( int start, int index, unsigned char *palette_ram )
|
||||
static void set_rgba( running_machine *machine, int start, int index, unsigned char *palette_ram )
|
||||
{
|
||||
int r = palette_ram[ index ];
|
||||
int g = palette_ram[ index + 256 ];
|
||||
int b = palette_ram[ index + 512 ];
|
||||
int a = ( b & 3 ) * 0x55;
|
||||
|
||||
palette_set_color( Machine, start + index, MAKE_RGB( r, g, b ) );
|
||||
render_container_set_palette_alpha(render_container_get_screen(Machine->primary_screen), start + index, a);
|
||||
palette_set_color( machine, start + index, MAKE_RGB( r, g, b ) );
|
||||
render_container_set_palette_alpha(render_container_get_screen(machine->primary_screen), start + index, a);
|
||||
}
|
||||
|
||||
static WRITE8_HANDLER( tile_palette_w )
|
||||
{
|
||||
tile_palette[ offset ] = data;
|
||||
set_rgba( 0, offset & 0xff, tile_palette );
|
||||
set_rgba( machine, 0, offset & 0xff, tile_palette );
|
||||
}
|
||||
|
||||
static WRITE8_HANDLER( sprite_palette_w )
|
||||
{
|
||||
sprite_palette[ offset ] = data;
|
||||
set_rgba( 256, offset & 0xff, sprite_palette );
|
||||
set_rgba( machine, 256, offset & 0xff, sprite_palette );
|
||||
}
|
||||
|
||||
WRITE8_HANDLER( firefox_objram_bank_w )
|
||||
static WRITE8_HANDLER( firefox_objram_bank_w )
|
||||
{
|
||||
sprite_bank = data & 0x03;
|
||||
}
|
||||
@ -397,8 +251,8 @@ static READ8_HANDLER( sound_to_main_r )
|
||||
static WRITE8_HANDLER( main_to_sound_w )
|
||||
{
|
||||
main_to_sound_flag = 1;
|
||||
soundlatch_w(Machine, 0, data);
|
||||
cputag_set_input_line(Machine, "audio", INPUT_LINE_NMI, PULSE_LINE);
|
||||
soundlatch_w(machine, 0, data);
|
||||
cputag_set_input_line(machine, "audio", INPUT_LINE_NMI, PULSE_LINE);
|
||||
}
|
||||
|
||||
static WRITE8_HANDLER( sound_reset_w )
|
||||
@ -411,13 +265,13 @@ static WRITE8_HANDLER( sound_reset_w )
|
||||
static READ8_HANDLER( main_to_sound_r )
|
||||
{
|
||||
main_to_sound_flag = 0;
|
||||
return soundlatch_r(Machine, 0);
|
||||
return soundlatch_r(machine, 0);
|
||||
}
|
||||
|
||||
static WRITE8_HANDLER( sound_to_main_w )
|
||||
{
|
||||
sound_to_main_flag = 1;
|
||||
soundlatch2_w(Machine, 0, data);
|
||||
soundlatch2_w(machine, 0, data);
|
||||
}
|
||||
|
||||
|
||||
@ -472,10 +326,10 @@ static READ8_HANDLER( adc_r )
|
||||
{
|
||||
if( control_num == 0 )
|
||||
{
|
||||
return input_port_read( Machine, "PITCH" );
|
||||
return input_port_read( machine, "PITCH" );
|
||||
}
|
||||
|
||||
return input_port_read( Machine, "YAW" );
|
||||
return input_port_read( machine, "YAW" );
|
||||
}
|
||||
|
||||
static WRITE8_HANDLER( adc_select_w )
|
||||
@ -522,24 +376,24 @@ static WRITE8_HANDLER( novram_store_w )
|
||||
*
|
||||
*************************************/
|
||||
|
||||
WRITE8_HANDLER( rom_bank_w )
|
||||
static WRITE8_HANDLER( rom_bank_w )
|
||||
{
|
||||
memory_set_bank(1, data & 0x1f);
|
||||
}
|
||||
|
||||
static WRITE8_HANDLER( main_irq_clear_w )
|
||||
{
|
||||
cpunum_set_input_line( machine, 0, M6809_IRQ_LINE, CLEAR_LINE );
|
||||
cputag_set_input_line( machine, "main", M6809_IRQ_LINE, CLEAR_LINE );
|
||||
}
|
||||
|
||||
static WRITE8_HANDLER( main_firq_clear_w )
|
||||
{
|
||||
cpunum_set_input_line( machine, 0, M6809_FIRQ_LINE, CLEAR_LINE );
|
||||
cputag_set_input_line( machine, "main", M6809_FIRQ_LINE, CLEAR_LINE );
|
||||
}
|
||||
|
||||
WRITE8_HANDLER( self_reset_w )
|
||||
static WRITE8_HANDLER( self_reset_w )
|
||||
{
|
||||
cpunum_set_input_line( Machine, 0, INPUT_LINE_RESET, PULSE_LINE );
|
||||
cputag_set_input_line( machine, "main", INPUT_LINE_RESET, PULSE_LINE );
|
||||
}
|
||||
|
||||
|
||||
@ -550,42 +404,36 @@ WRITE8_HANDLER( self_reset_w )
|
||||
*
|
||||
*************************************/
|
||||
|
||||
WRITE8_HANDLER( led_w )
|
||||
static WRITE8_HANDLER( led_w )
|
||||
{
|
||||
if( ( data & 0x80 ) != 0 )
|
||||
{
|
||||
set_led_status( offset, 0 );
|
||||
}
|
||||
else
|
||||
{
|
||||
set_led_status( offset, 1 );
|
||||
}
|
||||
set_led_status( offset, ( data & 0x80 ) == 0 );
|
||||
}
|
||||
|
||||
WRITE8_HANDLER( firefox_coin_counter_w )
|
||||
static WRITE8_HANDLER( firefox_coin_counter_w )
|
||||
{
|
||||
coin_counter_w( offset, data & 0x80 );
|
||||
}
|
||||
|
||||
|
||||
|
||||
MACHINE_START( firefox )
|
||||
static void firq_gen(const device_config *device, int state)
|
||||
{
|
||||
if (state)
|
||||
cputag_set_input_line( device->machine, "main", M6809_FIRQ_LINE, ASSERT_LINE );
|
||||
}
|
||||
|
||||
|
||||
static MACHINE_START( firefox )
|
||||
{
|
||||
memory_configure_bank(1, 0, 32, memory_region(machine, "main") + 0x10000, 0x1000);
|
||||
nvram_1c = device_list_find_by_tag(machine->config->devicelist, X2212, "nvram_1c");
|
||||
nvram_1d = device_list_find_by_tag(machine->config->devicelist, X2212, "nvram_1d");
|
||||
|
||||
laserdisc = device_list_find_by_tag(machine->config->devicelist, LASERDISC, "laserdisc");
|
||||
vp931_set_data_ready_callback(laserdisc, firq_gen);
|
||||
|
||||
control_num = 0;
|
||||
sprite_bank = 0;
|
||||
|
||||
command_data[ 0 ] = 0;
|
||||
command_data[ 1 ] = 0;
|
||||
command_data[ 2 ] = 0;
|
||||
command_offset = 0;
|
||||
|
||||
laser_disc_field = 0;
|
||||
laser_disc_speed = 0;
|
||||
manchester_offset = 6;
|
||||
}
|
||||
|
||||
|
||||
@ -595,44 +443,41 @@ MACHINE_START( firefox )
|
||||
*
|
||||
*************************************/
|
||||
|
||||
static ADDRESS_MAP_START( main_map , ADDRESS_SPACE_PROGRAM, 8)
|
||||
static ADDRESS_MAP_START( main_map, ADDRESS_SPACE_PROGRAM, 8)
|
||||
AM_RANGE(0x0000, 0x0fff) AM_RAM
|
||||
AM_RANGE(0x1000, 0x1fff) AM_RAM AM_BASE(&tileram) AM_SIZE(&tileram_size)
|
||||
AM_RANGE(0x2000, 0x27ff) AM_RAM AM_BASE(&spriteram) AM_SIZE(&spriteram_size)
|
||||
AM_RANGE(0x1000, 0x1fff) AM_RAM AM_BASE(&tileram)
|
||||
AM_RANGE(0x2000, 0x27ff) AM_RAM AM_BASE(&spriteram)
|
||||
AM_RANGE(0x2800, 0x2aff) AM_READWRITE(SMH_RAM, sprite_palette_w) AM_BASE(&sprite_palette)
|
||||
AM_RANGE(0x2b00, 0x2b00) AM_WRITE(firefox_objram_bank_w)
|
||||
AM_RANGE(0x2b01, 0x2bff) AM_RAM
|
||||
AM_RANGE(0x2b00, 0x2b00) AM_MIRROR(0x04ff) AM_WRITE(firefox_objram_bank_w)
|
||||
AM_RANGE(0x2c00, 0x2eff) AM_READWRITE(SMH_RAM, tile_palette_w) AM_BASE(&tile_palette)
|
||||
AM_RANGE(0x2f00, 0x2fff) AM_RAM
|
||||
AM_RANGE(0x3000, 0x3fff) AM_ROMBANK(1)
|
||||
AM_RANGE(0x4000, 0x40ff) AM_READWRITE(nvram_r, nvram_w)
|
||||
AM_RANGE(0x4100, 0x4100) AM_READ_PORT("IN0")
|
||||
AM_RANGE(0x4101, 0x4101) AM_READ_PORT("IN1")
|
||||
AM_RANGE(0x4102, 0x4102) AM_READ(firefox_disc_status_r)
|
||||
AM_RANGE(0x4103, 0x4103) AM_READ_PORT("IN3")
|
||||
AM_RANGE(0x4104, 0x4104) AM_READ_PORT("IN4")
|
||||
AM_RANGE(0x4105, 0x4105) AM_READ(firefox_disc_data_r)
|
||||
AM_RANGE(0x4106, 0x4106) AM_READ(sound_to_main_r)
|
||||
AM_RANGE(0x4107, 0x4107) AM_READ(adc_r)
|
||||
AM_RANGE(0x4200, 0x4200) AM_WRITE(main_irq_clear_w)
|
||||
AM_RANGE(0x4208, 0x4208) AM_WRITE(main_firq_clear_w)
|
||||
AM_RANGE(0x4210, 0x4210) AM_WRITE(watchdog_reset_w)
|
||||
AM_RANGE(0x4218, 0x4218) AM_WRITE(firefox_disc_read_w)
|
||||
AM_RANGE(0x4220, 0x4221) AM_WRITE(adc_select_w)
|
||||
AM_RANGE(0x4230, 0x4230) AM_WRITE(self_reset_w)
|
||||
AM_RANGE(0x4280, 0x4280) AM_WRITE(novram_recall_w)
|
||||
AM_RANGE(0x4281, 0x4281) AM_WRITE(sound_reset_w)
|
||||
AM_RANGE(0x4282, 0x4282) AM_WRITE(novram_store_w)
|
||||
AM_RANGE(0x4283, 0x4283) AM_WRITE(firefox_disc_lock_w)
|
||||
AM_RANGE(0x4284, 0x4284) AM_WRITE(firefox_disc_right_audio_enable_w)
|
||||
AM_RANGE(0x4285, 0x4285) AM_WRITE(firefox_disc_left_audio_enable_w)
|
||||
AM_RANGE(0x4286, 0x4286) AM_WRITE(firefox_disc_reset_w)
|
||||
AM_RANGE(0x4287, 0x4287) AM_WRITE(firefox_disc_write_w)
|
||||
AM_RANGE(0x4288, 0x4289) AM_WRITE(firefox_coin_counter_w)
|
||||
AM_RANGE(0x428c, 0x428f) AM_WRITE(led_w)
|
||||
AM_RANGE(0x4290, 0x4290) AM_WRITE(rom_bank_w)
|
||||
AM_RANGE(0x4298, 0x4298) AM_WRITE(main_to_sound_w)
|
||||
AM_RANGE(0x42a0, 0x42a7) AM_WRITE(firefox_disc_data_w)
|
||||
AM_RANGE(0x4000, 0x40ff) AM_READWRITE(nvram_r, nvram_w) /* NOVRAM */
|
||||
AM_RANGE(0x4100, 0x4100) AM_MIRROR(0x00f8) AM_READ_PORT("rdin0") /* RDIN0 */
|
||||
AM_RANGE(0x4101, 0x4101) AM_MIRROR(0x00f8) AM_READ_PORT("rdin1") /* RDIN1 */
|
||||
AM_RANGE(0x4102, 0x4102) AM_MIRROR(0x00f8) AM_READ(firefox_disc_status_r) /* RDIN2 */
|
||||
AM_RANGE(0x4103, 0x4103) AM_MIRROR(0x00f8) AM_READ_PORT("opt0") /* OPT0 */
|
||||
AM_RANGE(0x4104, 0x4104) AM_MIRROR(0x00f8) AM_READ_PORT("opt1") /* OPT1 */
|
||||
AM_RANGE(0x4105, 0x4105) AM_MIRROR(0x00f8) AM_READ(firefox_disc_data_r) /* DREAD */
|
||||
AM_RANGE(0x4106, 0x4106) AM_MIRROR(0x00f8) AM_READ(sound_to_main_r) /* RDSOUND */
|
||||
AM_RANGE(0x4107, 0x4107) AM_MIRROR(0x00f8) AM_READ(adc_r) /* ADC */
|
||||
AM_RANGE(0x4200, 0x4200) AM_MIRROR(0x0047) AM_WRITE(main_irq_clear_w) /* RSTIRQ */
|
||||
AM_RANGE(0x4208, 0x4208) AM_MIRROR(0x0047) AM_WRITE(main_firq_clear_w) /* RSTFIRQ */
|
||||
AM_RANGE(0x4210, 0x4210) AM_MIRROR(0x0047) AM_WRITE(watchdog_reset_w) /* WDCLK */
|
||||
AM_RANGE(0x4218, 0x4218) AM_MIRROR(0x0047) AM_WRITE(firefox_disc_read_w) /* DSKREAD */
|
||||
AM_RANGE(0x4220, 0x4223) AM_MIRROR(0x0044) AM_WRITE(adc_select_w) /* ADCSTART */
|
||||
AM_RANGE(0x4230, 0x4230) AM_MIRROR(0x0047) AM_WRITE(self_reset_w) /* AMUCK */
|
||||
AM_RANGE(0x4280, 0x4280) AM_MIRROR(0x0040) AM_WRITE(novram_recall_w) /* LATCH0 -> NVRECALL */
|
||||
AM_RANGE(0x4281, 0x4281) AM_MIRROR(0x0040) AM_WRITE(sound_reset_w) /* LATCH0 -> RSTSOUND */
|
||||
AM_RANGE(0x4282, 0x4282) AM_MIRROR(0x0040) AM_WRITE(novram_store_w) /* LATCH0 -> NVRSTORE */
|
||||
AM_RANGE(0x4283, 0x4283) AM_MIRROR(0x0040) AM_WRITE(firefox_disc_lock_w) /* LATCH0 -> LOCK */
|
||||
AM_RANGE(0x4284, 0x4285) AM_MIRROR(0x0040) AM_WRITE(audio_enable_w) /* LATCH0 -> SWDSKR, SWDSKL */
|
||||
AM_RANGE(0x4286, 0x4286) AM_MIRROR(0x0040) AM_WRITE(firefox_disc_reset_w) /* LATCH0 -> RSTDSK */
|
||||
AM_RANGE(0x4287, 0x4287) AM_MIRROR(0x0040) AM_WRITE(firefox_disc_write_w) /* LATCH0 -> WRDSK */
|
||||
AM_RANGE(0x4288, 0x4289) AM_MIRROR(0x0040) AM_WRITE(firefox_coin_counter_w) /* LATCH1 -> COIN COUNTERR, COUNTERL */
|
||||
AM_RANGE(0x428c, 0x428f) AM_MIRROR(0x0040) AM_WRITE(led_w) /* LATCH1 -> LEDs */
|
||||
AM_RANGE(0x4290, 0x4290) AM_MIRROR(0x0047) AM_WRITE(rom_bank_w) /* WRTREG */
|
||||
AM_RANGE(0x4298, 0x4298) AM_MIRROR(0x0047) AM_WRITE(main_to_sound_w) /* WRSOUND */
|
||||
AM_RANGE(0x42a0, 0x42a0) AM_MIRROR(0x0047) AM_WRITE(firefox_disc_data_w) /* DSKLATCH */
|
||||
AM_RANGE(0x4400, 0xffff) AM_ROM
|
||||
ADDRESS_MAP_END
|
||||
|
||||
@ -666,7 +511,7 @@ ADDRESS_MAP_END
|
||||
*************************************/
|
||||
|
||||
INPUT_PORTS_START( firefox )
|
||||
PORT_START("IN0")
|
||||
PORT_START("rdin0")
|
||||
PORT_BIT( 0x80, IP_ACTIVE_LOW, IPT_BUTTON1 )
|
||||
PORT_BIT( 0x40, IP_ACTIVE_LOW, IPT_BUTTON2 )
|
||||
PORT_BIT( 0x20, IP_ACTIVE_LOW, IPT_BUTTON3 )
|
||||
@ -676,7 +521,7 @@ INPUT_PORTS_START( firefox )
|
||||
PORT_BIT( 0x02, IP_ACTIVE_LOW, IPT_UNKNOWN )
|
||||
PORT_BIT( 0x01, IP_ACTIVE_HIGH, IPT_UNUSED )
|
||||
|
||||
PORT_START("IN1")
|
||||
PORT_START("rdin1")
|
||||
PORT_BIT( 0x80, IP_ACTIVE_HIGH, IPT_SPECIAL ) PORT_CUSTOM(mainflag_r, NULL)
|
||||
PORT_BIT( 0x40, IP_ACTIVE_HIGH, IPT_SPECIAL ) PORT_CUSTOM(soundflag_r, NULL)
|
||||
PORT_BIT( 0x20, IP_ACTIVE_HIGH, IPT_VBLANK )
|
||||
@ -686,7 +531,7 @@ INPUT_PORTS_START( firefox )
|
||||
PORT_BIT( 0x02, IP_ACTIVE_LOW, IPT_COIN1 )
|
||||
PORT_BIT( 0x01, IP_ACTIVE_LOW, IPT_COIN2 )
|
||||
|
||||
PORT_START("IN3")
|
||||
PORT_START("opt0")
|
||||
PORT_DIPNAME( 0x03, 0x00, "Coins Per Credit" )
|
||||
PORT_DIPSETTING( 0x00, "1 Coin 1 Credit" )
|
||||
PORT_DIPSETTING( 0x01, "2 Coins 1 Credit" )
|
||||
@ -709,7 +554,7 @@ INPUT_PORTS_START( firefox )
|
||||
PORT_DIPSETTING( 0x60, "2 Credits for 4 Coin Units" )
|
||||
PORT_DIPSETTING( 0xe0, DEF_STR( Free_Play ) )
|
||||
|
||||
PORT_START("IN4")
|
||||
PORT_START("opt1")
|
||||
PORT_DIPNAME( 0x01, 0x00, "Missions" )
|
||||
PORT_DIPSETTING( 0x00, "All .50" )
|
||||
PORT_DIPSETTING( 0x01, ".50 .75" )
|
||||
@ -770,7 +615,7 @@ static const gfx_layout spritelayout =
|
||||
};
|
||||
|
||||
static GFXDECODE_START( firefox )
|
||||
GFXDECODE_ENTRY("tiles", 0, tilelayout, 0, 16)
|
||||
GFXDECODE_ENTRY("tiles", 0, tilelayout, 0, 16)
|
||||
GFXDECODE_ENTRY("sprites", 0, spritelayout, 256, 32)
|
||||
GFXDECODE_END
|
||||
|
||||
@ -795,14 +640,18 @@ static const riot6532_interface riot_intf =
|
||||
static MACHINE_DRIVER_START( firefox )
|
||||
|
||||
/* basic machine hardware */
|
||||
MDRV_CPU_ADD("main", M6809, 4000000)
|
||||
MDRV_CPU_ADD("main", M6809E, MASTER_XTAL/2)
|
||||
MDRV_CPU_PROGRAM_MAP(main_map, 0)
|
||||
MDRV_TIMER_ADD_SCANLINE("32v", video_timer_callback, "main", 96, 128)
|
||||
/* interrupts count starting at end of VBLANK, which is 44, so add 44 */
|
||||
MDRV_TIMER_ADD_SCANLINE("32v", video_timer_callback, "main", 96+44, 128)
|
||||
|
||||
MDRV_CPU_ADD("audio", M6502, 2000000)
|
||||
MDRV_CPU_ADD("audio", M6502, MASTER_XTAL/8)
|
||||
MDRV_CPU_PROGRAM_MAP(audio_map, 0)
|
||||
|
||||
MDRV_INTERLEAVE(100)
|
||||
|
||||
MDRV_MACHINE_START(firefox)
|
||||
MDRV_WATCHDOG_TIME_INIT(UINT64_ATTOTIME_IN_HZ((double)MASTER_XTAL/8/16/16/16/16))
|
||||
|
||||
/* video hardware */
|
||||
MDRV_LASERDISC_SCREEN_ADD_NTSC("main", BITMAP_FORMAT_INDEXED16)
|
||||
@ -810,35 +659,34 @@ static MACHINE_DRIVER_START( firefox )
|
||||
MDRV_GFXDECODE(firefox)
|
||||
MDRV_PALETTE_LENGTH(512)
|
||||
|
||||
MDRV_LASERDISC_ADD("laserdisc", PIONEER_PR8210, "main", "ldsound")
|
||||
MDRV_LASERDISC_OVERLAY(firefox, 64*8, 64*8, BITMAP_FORMAT_INDEXED16)
|
||||
MDRV_LASERDISC_OVERLAY_CLIP(7*8, 53*8-1, 1*8, 62*8-1)
|
||||
MDRV_TIMER_ADD_SCANLINE("laserdisk", laserdisk_timer_callback, "main", 0, 0)
|
||||
MDRV_LASERDISC_ADD("laserdisc", PHILLIPS_22VP931, "main", "ldsound")
|
||||
MDRV_LASERDISC_OVERLAY(firefox, 64*8, 525, BITMAP_FORMAT_INDEXED16)
|
||||
MDRV_LASERDISC_OVERLAY_CLIP(7*8, 53*8-1, 44, 480+44)
|
||||
|
||||
MDRV_DEVICE_ADD("nvram_1c",X2212)
|
||||
MDRV_DEVICE_ADD("nvram_1d",X2212)
|
||||
MDRV_RIOT6532_ADD("riot", 1500000, riot_intf)
|
||||
MDRV_RIOT6532_ADD("riot", MASTER_XTAL/8, riot_intf)
|
||||
|
||||
/* sound hardware */
|
||||
MDRV_SPEAKER_STANDARD_STEREO("left", "right")
|
||||
|
||||
MDRV_SOUND_ADD("pokey1", POKEY, 1500000)
|
||||
MDRV_SOUND_ADD("pokey1", POKEY, MASTER_XTAL/8)
|
||||
MDRV_SOUND_ROUTE(ALL_OUTPUTS, "left", 0.20)
|
||||
MDRV_SOUND_ROUTE(ALL_OUTPUTS, "right", 0.20)
|
||||
|
||||
MDRV_SOUND_ADD("pokey2", POKEY, 1500000)
|
||||
MDRV_SOUND_ADD("pokey2", POKEY, MASTER_XTAL/8)
|
||||
MDRV_SOUND_ROUTE(ALL_OUTPUTS, "left", 0.20)
|
||||
MDRV_SOUND_ROUTE(ALL_OUTPUTS, "right", 0.20)
|
||||
|
||||
MDRV_SOUND_ADD("pokey3", POKEY, 1500000)
|
||||
MDRV_SOUND_ADD("pokey3", POKEY, MASTER_XTAL/8)
|
||||
MDRV_SOUND_ROUTE(ALL_OUTPUTS, "left", 0.20)
|
||||
MDRV_SOUND_ROUTE(ALL_OUTPUTS, "right", 0.20)
|
||||
|
||||
MDRV_SOUND_ADD("pokey4", POKEY, 1500000)
|
||||
MDRV_SOUND_ADD("pokey4", POKEY, MASTER_XTAL/8)
|
||||
MDRV_SOUND_ROUTE(ALL_OUTPUTS, "left", 0.20)
|
||||
MDRV_SOUND_ROUTE(ALL_OUTPUTS, "right", 0.20)
|
||||
|
||||
MDRV_SOUND_ADD("tms", TMS5220, 640000)
|
||||
MDRV_SOUND_ADD("tms", TMS5220, MASTER_XTAL/2/10)
|
||||
MDRV_SOUND_ROUTE(ALL_OUTPUTS, "left", 0.50)
|
||||
MDRV_SOUND_ROUTE(ALL_OUTPUTS, "right", 0.50)
|
||||
|
||||
@ -846,7 +694,6 @@ static MACHINE_DRIVER_START( firefox )
|
||||
MDRV_SOUND_CONFIG(laserdisc_custom_interface)
|
||||
MDRV_SOUND_ROUTE(0, "left", 1.0)
|
||||
MDRV_SOUND_ROUTE(1, "right", 1.0)
|
||||
|
||||
MACHINE_DRIVER_END
|
||||
|
||||
|
||||
@ -894,6 +741,9 @@ ROM_START( firefox )
|
||||
ROM_LOAD( "136026.120", 0x1c000, 0x4000, CRC(e1b95923) SHA1(b6d0c0af0a8f55e728cd0f4c3222745eefd57f50)) /* 2a */
|
||||
ROM_LOAD( "136026.115", 0x20000, 0x4000, CRC(861abc82) SHA1(1845888d07162ae915364a2a91294731f1c5b3bd)) /* 1c */
|
||||
ROM_LOAD( "136026.119", 0x24000, 0x4000, CRC(959471b1) SHA1(a032209a209f51d34360d5c7ad32ec62150158d2)) /* 1a */
|
||||
|
||||
DISK_REGION( "laserdisc" )
|
||||
DISK_IMAGE_READONLY( "firefox", 0, NO_DUMP )
|
||||
ROM_END
|
||||
|
||||
ROM_START( firefoxa )
|
||||
@ -931,6 +781,9 @@ ROM_START( firefoxa )
|
||||
ROM_LOAD( "136026.120", 0x1c000, 0x4000, CRC(e1b95923) SHA1(b6d0c0af0a8f55e728cd0f4c3222745eefd57f50)) /* 2a */
|
||||
ROM_LOAD( "136026.115", 0x20000, 0x4000, CRC(861abc82) SHA1(1845888d07162ae915364a2a91294731f1c5b3bd)) /* 1c */
|
||||
ROM_LOAD( "136026.119", 0x24000, 0x4000, CRC(959471b1) SHA1(a032209a209f51d34360d5c7ad32ec62150158d2)) /* 1a */
|
||||
|
||||
DISK_REGION( "laserdisc" )
|
||||
DISK_IMAGE_READONLY( "firefox", 0, NO_DUMP )
|
||||
ROM_END
|
||||
|
||||
|
||||
|
Loading…
Reference in New Issue
Block a user