Made the Z80 daisy chain aware of referencing device-specific devices.

Added preliminary LD-V1000 emulation. Not fully working yet, but mostly
there.

Cleaned up and normalized the three existing laserdisc emulations.
Removed obsolete code from the laserdisc core.
This commit is contained in:
Aaron Giles 2008-10-09 05:31:15 +00:00
parent 3df44083f8
commit 2d6453c98a
12 changed files with 795 additions and 978 deletions

View File

@ -78,6 +78,7 @@ Hitachi HD647180 series:
#include "debugger.h"
#include "deprecat.h"
#include "driver.h"
#include "z180.h"
#include "cpu/z80/z80daisy.h"
@ -1900,7 +1901,7 @@ static void z180_init(int index, int clock, const void *config, int (*irqcallbac
{
Z180.daisy = NULL;
if (config)
Z180.daisy = z80daisy_init(Machine, config);
Z180.daisy = z80daisy_init(Machine, Machine->config->cpu[cpu_getactivecpu()].tag, config);
Z180.irq_callback = irqcallback;
state_save_register_item("z180", index, Z180.AF.w.l);

View File

@ -95,6 +95,7 @@
#include "debugger.h"
#include "deprecat.h"
#include "driver.h"
#include "z80.h"
#include "z80daisy.h"
@ -3499,7 +3500,7 @@ static void z80_init(int index, int clock, const void *config, int (*irqcallback
/* Reset registers to their initial values */
memset(&Z80, 0, sizeof(Z80));
if (config != NULL)
Z80.daisy = z80daisy_init(Machine, config);
Z80.daisy = z80daisy_init(Machine, Machine->config->cpu[cpu_getactivecpu()].tag, config);
Z80.irq_callback = irqcallback;
IX = IY = 0xffff; /* IX and IY are FFFF after a reset! */
F = ZF; /* Zero flag is set */

View File

@ -20,8 +20,9 @@ struct _z80_daisy_state
};
z80_daisy_state *z80daisy_init(running_machine *machine, const z80_daisy_chain *daisy)
z80_daisy_state *z80daisy_init(running_machine *machine, const char *cputag, const z80_daisy_chain *daisy)
{
astring *tempstring = astring_alloc();
z80_daisy_state *head = NULL;
z80_daisy_state **tailptr = &head;
@ -30,13 +31,16 @@ z80_daisy_state *z80daisy_init(running_machine *machine, const z80_daisy_chain *
{
*tailptr = auto_malloc(sizeof(**tailptr));
(*tailptr)->next = NULL;
(*tailptr)->device = devtag_get_device(machine, daisy->devtype, daisy->devname);
(*tailptr)->device = devtag_get_device(machine, daisy->devtype, device_inherit_tag(tempstring, cputag, daisy->devname));
if ((*tailptr)->device == NULL)
fatalerror("Unable to locate device '%s'", daisy->devname);
(*tailptr)->irq_state = (z80_daisy_irq_state)device_get_info_fct((*tailptr)->device, DEVINFO_FCT_IRQ_STATE);
(*tailptr)->irq_ack = (z80_daisy_irq_ack)device_get_info_fct((*tailptr)->device, DEVINFO_FCT_IRQ_ACK);
(*tailptr)->irq_reti = (z80_daisy_irq_reti)device_get_info_fct((*tailptr)->device, DEVINFO_FCT_IRQ_RETI);
tailptr = &(*tailptr)->next;
}
astring_free(tempstring);
return head;
}

View File

@ -60,7 +60,7 @@ struct _z80_daisy_chain
FUNCTION PROTOTYPES
***************************************************************************/
z80_daisy_state *z80daisy_init(running_machine *machine, const z80_daisy_chain *daisy);
z80_daisy_state *z80daisy_init(running_machine *machine, const char *cputag, const z80_daisy_chain *daisy);
void z80daisy_reset(z80_daisy_state *daisy);
int z80daisy_update_irq_state(z80_daisy_state *chain);

View File

@ -68,6 +68,8 @@ enum
typedef void (*laserdisc_audio_func)(const device_config *device, int samplerate, int samples, const INT16 *ch0, const INT16 *ch1);
typedef void (*vp931_data_ready_func)(const device_config *device, int state);
typedef struct _laserdisc_config laserdisc_config;
struct _laserdisc_config
{
@ -188,7 +190,7 @@ UINT8 laserdisc_line_r(const device_config *device, UINT8 line);
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));
void vp931_set_data_ready_callback(const device_config *device, vp931_data_ready_func callback);
/* control the audio squelch of the Simutrek modified players */
void simutrek_set_audio_squelch(const device_config *device, int state);

View File

@ -31,10 +31,22 @@
CONSTANTS
***************************************************************************/
/* these specs code from IEC 60857, for NTSC players */
#define LEAD_IN_MIN_RADIUS_IN_UM 53500 /* 53.5 mm */
#define PROGRAM_MIN_RADIUS_IN_UM 55000 /* 55 mm */
#define PROGRAM_MAX_RADIUS_IN_UM 145000 /* 145 mm */
#define LEAD_OUT_MIN_SIZE_IN_UM 2000 /* 2 mm */
/* the track pitch is defined as a range; we pick a nominal pitch
that ensures we can fit 54,000 tracks */
#define MIN_TRACK_PITCH_IN_NM 1400 /* 1.4 um */
#define MAX_TRACK_PITCH_IN_NM 2000 /* 2 um */
#define NOMINAL_TRACK_PITCH_IN_NM ((PROGRAM_MAX_RADIUS_IN_UM - PROGRAM_MIN_RADIUS_IN_UM) * 1000 / 54000)
/* we simulate extra lead-in and lead-out tracks */
#define VIRTUAL_LEAD_IN_TRACKS 200
#define VIRTUAL_LEAD_IN_TRACKS ((PROGRAM_MIN_RADIUS_IN_UM - LEAD_IN_MIN_RADIUS_IN_UM) * 1000 / NOMINAL_TRACK_PITCH_IN_NM)
#define MAX_TOTAL_TRACKS 54000
#define VIRTUAL_LEAD_OUT_TRACKS 200
#define VIRTUAL_LEAD_OUT_TRACKS (LEAD_OUT_MIN_SIZE_IN_UM * 1000 / NOMINAL_TRACK_PITCH_IN_NM)
@ -133,7 +145,6 @@ struct _sound_token
static TIMER_CALLBACK( perform_player_update );
static void read_track_data(laserdisc_state *ld);
static void process_track_data(const device_config *device);
//static void render_display(UINT16 *videodata, UINT32 rowpixels, UINT32 width, int frame);
static void *custom_start(int clock, const custom_sound_interface *config);
static void custom_stream_callback(void *param, stream_sample_t **inputs, stream_sample_t **outputs, int samples);
static void configuration_load(running_machine *machine, int config_type, xml_data_node *parentnode);
@ -161,100 +172,6 @@ const custom_sound_interface laserdisc_custom_interface =
custom_start
};
static const UINT8 numberfont[10][8] =
{
{
0x30, // ..xx....
0x48, // .x..x...
0x84, // x....x..
0x84, // x....x..
0x84, // x....x..
0x48, // .x..x...
0x30 // ..xx....
},
{
0x10, // ...x....
0x30, // ..xx....
0x50, // .x.x....
0x10, // ...x....
0x10, // ...x....
0x10, // ...x....
0x7c // .xxxxx..
},
{
0x78, // .xxxx...
0x84, // x....x..
0x04, // .....x..
0x38, // ..xxx...
0x40, // .x......
0x80, // x.......
0xfc // xxxxxx..
},
{
0x78, // .xxxx...
0x84, // x....x..
0x04, // .....x..
0x38, // ..xxx...
0x04, // .....x..
0x84, // x....x..
0x78 // .xxxx...
},
{
0x08, // ....x...
0x18, // ...xx...
0x28, // ..x.x...
0x48, // .x..x...
0xfc, // xxxxxx..
0x08, // ....x...
0x08 // ....x...
},
{
0xfc, // xxxxxx..
0x80, // x.......
0x80, // x.......
0xf8, // xxxxx...
0x04, // .....x..
0x84, // x....x..
0x78 // .xxxx...
},
{
0x38, // ..xxx...
0x40, // .x......
0x80, // x.......
0xf8, // xxxxx...
0x84, // x....x..
0x84, // x....x..
0x78 // .xxxx...
},
{
0xfc, // xxxxxx..
0x04, // .....x..
0x08, // ....x...
0x10, // ...x....
0x20, // ..x.....
0x20, // ..x.....
0x20 // ..x.....
},
{
0x78, // .xxxx...
0x84, // x....x..
0x84, // x....x..
0x78, // .xxxx...
0x84, // x....x..
0x84, // x....x..
0x78 // .xxxx...
},
{
0x78, // .xxxx..
0x84, // x....x.
0x84, // x....x.
0x7c, // .xxxxx.
0x04, // .....x.
0x08, // ....x..
0x70, // .xxx...
}
};
/***************************************************************************
@ -1021,65 +938,6 @@ static void process_track_data(const device_config *device)
}
/*-------------------------------------------------
render_display - draw the frame display
-------------------------------------------------*/
#ifdef UNUSED_FUNCTION
static void render_display(UINT16 *videodata, UINT32 rowpixels, UINT32 width, int frame)
{
const int xscale = 4, yscale = 2;
char buffer[10];
int x = width / 10;
int y = 50;
int ch;
int delta;
/* do nothing if no data */
if (videodata == NULL)
return;
/* convert to a character string and render */
sprintf(buffer, "%5d", frame);
/* iterate over 5 positions: (-1,-1), (-1,1), (1,-1), (1,1) and (0,0) */
/* render all in black except the last one */
for (delta = 0; delta < 5; delta++)
{
int color = (delta < 4) ? 0x0080 : 0xff80;
int dx = (delta < 4) ? ((delta & 1) ? -1 : 1) : 0;
int dy = (delta < 4) ? ((delta & 2) ? -1 : 1) : 0;
/* iterate over 5 characters */
for (ch = 0; ch < 5; ch++)
if (buffer[ch] >= '0' && buffer[ch] <= '9')
{
const UINT8 *fontdata = &numberfont[buffer[ch] - '0'][0];
int cy, cx;
/* iterate over the rows of the character */
for (cy = 0; cy < 8; cy++)
{
UINT8 bits = *fontdata++;
/* and over the columns */
for (cx = 0; cx < 8; cx++)
if (bits & (0x80 >> cx))
{
int ix, iy;
/* fill in an xscale x yscale pixel */
for (iy = 0; iy < yscale; iy++)
for (ix = 0; ix < xscale; ix++)
videodata[(y + cy * yscale + iy + dy) * rowpixels + (x + (ch * 9 + cx) * xscale + ix + dx)] = color;
}
}
}
}
}
#endif
/*-------------------------------------------------
custom_start - custom audio start
for laserdiscs

View File

@ -225,7 +225,7 @@ INLINE int is_start_of_frame(const vbi_metadata *vbi)
/* is it not known if the white flag or the presence of a frame code
determines the start of frame; the former seems to be the "official"
way, but the latter seems to be the practical implementation */
return (vbi->white || (vbi->line1718 & 0xf80000) == 0xf80000);
return (vbi->white || (vbi->line1718 & VBI_MASK_CAV_PICTURE) == VBI_CODE_CAV_PICTURE);
}
@ -255,7 +255,7 @@ INLINE int frame_from_metadata(const vbi_metadata *metadata)
INLINE int chapter_from_metadata(const vbi_metadata *metadata)
{
if ((metadata->line1718 & 0xf00fff) == 0x800ddd)
if ((metadata->line1718 & VBI_MASK_CHAPTER) == VBI_CODE_CHAPTER)
return VBI_CHAPTER(metadata->line1718);
else if (metadata->line1718 == VBI_CODE_LEADIN)
return CHAPTER_LEAD_IN;

View File

@ -11,7 +11,6 @@
Still to do:
* add overlay properly (need capture)
* implement SLOW TRG
* figure out Simutrek without jump hack
* figure out serial protocol issues (current hack works nicely)
@ -49,17 +48,17 @@
#define OVERLAY_X_PIXELS 5
#define OVERLAY_Y_PIXELS 7
/* Pioneer PR-8210 specific information */
#define PR8210_SCAN_SPEED (2000 / 30) /* 2000 frames/second */
#define PR8210_SEEK_FAST_SPEED (4000 / 30) /* 4000 frames/second */
/* scanning speeds */
#define SCAN_SPEED (2000 / 30) /* 2000 frames/second */
#define SEEK_FAST_SPEED (4000 / 30) /* 4000 frames/second */
/* serial timing, mostly from the service manual, derived from the XTAL */
#define PR8210_SERIAL_CLOCK XTAL_455kHz
#define PR8210_0_BIT_TIME ATTOTIME_IN_HZ(PR8210_SERIAL_CLOCK / 512)
#define PR8210_1_BIT_TIME ATTOTIME_IN_HZ(PR8210_SERIAL_CLOCK / 1024)
#define PR8210_MIDPOINT_TIME ATTOTIME_IN_HZ(PR8210_SERIAL_CLOCK / 600)
#define PR8210_MAX_WORD_TIME ATTOTIME_IN_HZ(PR8210_SERIAL_CLOCK / 11520)
#define PR8210_REJECT_DUPLICATE_TIME ATTOTIME_IN_HZ(PR8210_SERIAL_CLOCK / 11520 / 4)
#define SERIAL_CLOCK XTAL_455kHz
#define SERIAL_0_BIT_TIME ATTOTIME_IN_HZ(SERIAL_CLOCK / 512)
#define SERIAL_1_BIT_TIME ATTOTIME_IN_HZ(SERIAL_CLOCK / 1024)
#define SERIAL_MIDPOINT_TIME ATTOTIME_IN_HZ(SERIAL_CLOCK / 600)
#define SERIAL_MAX_WORD_TIME ATTOTIME_IN_HZ(SERIAL_CLOCK / 11520)
#define SERIAL_REJECT_DUPLICATE_TIME ATTOTIME_IN_HZ(SERIAL_CLOCK / 11520 / 4)
@ -129,8 +128,10 @@ static void pr8210_vsync(laserdisc_state *ld, const vbi_metadata *vbi, int field
static INT32 pr8210_update(laserdisc_state *ld, const vbi_metadata *vbi, int fieldnum, attotime curtime);
static void pr8210_overlay(laserdisc_state *ld, bitmap_t *bitmap);
static void pr8210_control_w(laserdisc_state *ld, UINT8 prev, UINT8 data);
static TIMER_CALLBACK( vsync_off );
static TIMER_CALLBACK( vbi_data_fetch );
static READ8_HANDLER( pr8210_pia_r );
static WRITE8_HANDLER( pr8210_pia_w );
static READ8_HANDLER( pr8210_bus_r );
@ -138,6 +139,7 @@ static WRITE8_HANDLER( pr8210_port1_w );
static WRITE8_HANDLER( pr8210_port2_w );
static READ8_HANDLER( pr8210_t0_r );
static READ8_HANDLER( pr8210_t1_r );
static void overlay_draw_group(bitmap_t *bitmap, const UINT8 *text, int count, float xstart);
static void overlay_erase(bitmap_t *bitmap, float xstart, float xend);
static void overlay_draw_char(bitmap_t *bitmap, UINT8 ch, float xstart);
@ -148,7 +150,9 @@ static INT32 simutrek_update(laserdisc_state *ld, const vbi_metadata *vbi, int f
static UINT8 simutrek_ready_r(laserdisc_state *ld);
static UINT8 simutrek_status_r(laserdisc_state *ld);
static void simutrek_data_w(laserdisc_state *ld, UINT8 prev, UINT8 data);
static TIMER_CALLBACK( simutrek_latched_data_w );
static READ8_HANDLER( simutrek_port2_r );
static WRITE8_HANDLER( simutrek_port2_w );
static READ8_HANDLER( simutrek_data_r );
@ -169,7 +173,7 @@ static const UINT8 text_bitmap[0x40][7] =
{ 0x70,0x88,0x80,0x80,0x80,0x88,0x70 }, /* C */
{ 0 }, /* D */
{ 0xf8,0x80,0x80,0xf0,0x80,0x80,0xf8 }, /* E */
{ 0xf8,0x80,0x80,0xf0,0x80,0x80,0x80 }, /* E */
{ 0xf8,0x80,0x80,0xf0,0x80,0x80,0x80 }, /* F */
{ 0 }, /* G */
{ 0x88,0x88,0x88,0xf8,0x88,0x88,0x88 }, /* H */
{ 0 }, /* I */
@ -338,8 +342,7 @@ const ldplayer_interface pr8210_interface =
***************************************************************************/
/*-------------------------------------------------
pr8210_init - Pioneer PR-8210-specific
initialization
pr8210_init - player-specific initialization
-------------------------------------------------*/
static void pr8210_init(laserdisc_state *ld)
@ -348,18 +351,17 @@ static void pr8210_init(laserdisc_state *ld)
attotime curtime = timer_get_time();
ldplayer_data *player = ld->player;
/* find our CPU */
player->cpunum = mame_find_cpu_index(ld->device->machine, device_build_tag(tempstring, ld->device->tag, "pr8210"));
astring_free(tempstring);
/* do a soft reset */
player->lastcommand = 0;
player->accumulator = 0;
/* reset our state */
memset(player, 0, sizeof(*player));
player->lastcommandtime = curtime;
player->firstbittime = curtime;
player->lastbittime = curtime;
player->slowtrg = curtime;
/* find our CPU */
player->cpunum = mame_find_cpu_index(ld->device->machine, device_build_tag(tempstring, ld->device->tag, "pr8210"));
astring_free(tempstring);
/* we don't have the Simutrek player overrides */
player->simutrek.cpunum = -1;
player->simutrek.audio_squelch = FALSE;
@ -463,7 +465,7 @@ static void pr8210_control_w(laserdisc_state *ld, UINT8 prev, UINT8 data)
/* if we timed out since the first bit, reset the accumulator */
delta = attotime_sub(curtime, player->firstbittime);
if (attotime_compare(delta, PR8210_MAX_WORD_TIME) > 0)
if (attotime_compare(delta, SERIAL_MAX_WORD_TIME) > 0)
{
player->firstbittime = curtime;
player->accumulator = 0x5555;
@ -477,7 +479,7 @@ static void pr8210_control_w(laserdisc_state *ld, UINT8 prev, UINT8 data)
player->lastbittime = curtime;
/* 0 bit delta is 1.05 msec, 1 bit delta is 2.11 msec */
longpulse = (attotime_compare(delta, PR8210_MIDPOINT_TIME) < 0) ? 0 : 1;
longpulse = (attotime_compare(delta, SERIAL_MIDPOINT_TIME) < 0) ? 0 : 1;
player->accumulator = (player->accumulator << 1) | longpulse;
/* log the deltas for debugging */
@ -500,7 +502,7 @@ static void pr8210_control_w(laserdisc_state *ld, UINT8 prev, UINT8 data)
/* the MCU logic requires a 0 to execute many commands; however, nobody
consistently sends a 0, whereas they do tend to send duplicate commands...
if we assume that each duplicate causes a 0, we get the correct results */
rejectuntil = attotime_add(player->lastcommandtime, PR8210_REJECT_DUPLICATE_TIME);
rejectuntil = attotime_add(player->lastcommandtime, SERIAL_REJECT_DUPLICATE_TIME);
player->lastcommandtime = curtime;
if (player->pia.porta == player->lastcommand && attotime_compare(curtime, rejectuntil) < 0)
player->pia.porta = 0x00;
@ -516,7 +518,7 @@ static void pr8210_control_w(laserdisc_state *ld, UINT8 prev, UINT8 data)
}
/* reset the first bit time so that the accumulator clears on the next write */
player->firstbittime = attotime_sub(curtime, PR8210_MAX_WORD_TIME);
player->firstbittime = attotime_sub(curtime, SERIAL_MAX_WORD_TIME);
}
}
}
@ -810,7 +812,7 @@ static WRITE8_HANDLER( pr8210_port1_w )
if (!(data & 0x02))
{
/* bit 2 selects the speed */
int delta = (data & 0x04) ? PR8210_SCAN_SPEED : PR8210_SEEK_FAST_SPEED;
int delta = (data & 0x04) ? SCAN_SPEED : SEEK_FAST_SPEED;
ldcore_set_slider_speed(ld, delta * direction);
}

File diff suppressed because it is too large Load Diff

View File

@ -34,9 +34,9 @@
CONSTANTS
***************************************************************************/
/* Philips 22VP931 specific information */
#define VP931_SCAN_SPEED (2000 / 30) /* 2000 frames/second */
#define VP931_SCAN_FAST_SPEED (4000 / 30) /* 4000 frames/second */
/* scanning speeds */
#define SCAN_SPEED (2000 / 30) /* 2000 frames/second */
#define SCAN_FAST_SPEED (4000 / 30) /* 4000 frames/second */
@ -50,23 +50,32 @@ struct _ldplayer_data
/* low-level emulation data */
int cpunum; /* CPU index of the 8049 */
const device_config *tracktimer; /* timer device */
int lastframe;
vp931_data_ready_func data_ready_cb; /* data ready callback */
/* I/O port states */
UINT8 out0; /* output 0 state */
UINT8 out1; /* output 1 state */
UINT8 port1; /* port 1 state */
/* DATIC circuit implementation */
UINT8 daticval; /* latched DATIC value */
UINT8 daticerp; /* /ERP value from DATIC */
UINT8 datastrobe; /* DATA STROBE line from DATIC */
/* communication status */
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 */
/* tracking */
INT8 trackdir; /* direction of tracking */
UINT8 trackstate; /* state of tracking */
/* debugging */
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 */
};
@ -83,6 +92,13 @@ static UINT8 vp931_data_r(laserdisc_state *ld);
static UINT8 vp931_ready(laserdisc_state *ld);
static UINT8 vp931_data_ready(laserdisc_state *ld);
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 );
static WRITE8_HANDLER( output0_w );
static WRITE8_HANDLER( output1_w );
static WRITE8_HANDLER( lcd_w );
@ -96,12 +112,6 @@ 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 );
@ -152,7 +162,7 @@ ROM_END
/***************************************************************************
PR-8210 PLAYER INTERFACE
22VP931 PLAYER INTERFACE
***************************************************************************/
const ldplayer_interface vp931_interface =
@ -191,7 +201,7 @@ const ldplayer_interface vp931_interface =
ready callback
-------------------------------------------------*/
void vp931_set_data_ready_callback(const device_config *device, void (*callback)(const device_config *device, int state))
void vp931_set_data_ready_callback(const device_config *device, vp931_data_ready_func callback)
{
laserdisc_state *ld = ldcore_get_safe_token(device);
ld->player->data_ready_cb = callback;
@ -204,22 +214,24 @@ void vp931_set_data_ready_callback(const device_config *device, void (*callback)
***************************************************************************/
/*-------------------------------------------------
vp931_init - Pioneer PR-8210-specific
initialization
vp931_init - player-specific initialization
-------------------------------------------------*/
static void vp931_init(laserdisc_state *ld)
{
astring *tempstring = astring_alloc();
ldplayer_data *player = ld->player;
vp931_data_ready_func cbsave;
/* reset our state */
cbsave = player->data_ready_cb;
memset(player, 0, sizeof(*player));
player->data_ready_cb = cbsave;
/* find our CPU */
/* find our devices */
player->cpunum = mame_find_cpu_index(ld->device->machine, device_build_tag(tempstring, ld->device->tag, "vp931"));
/* find our timer */
player->tracktimer = device_list_find_by_tag(ld->device->machine->config->devicelist, TIMER, device_build_tag(tempstring, ld->device->tag, "tracktimer"));
player->tracktimer = devtag_get_device(ld->device->machine, TIMER, device_build_tag(tempstring, ld->device->tag, "tracktimer"));
timer_device_set_ptr(player->tracktimer, ld);
astring_free(tempstring);
}
@ -316,6 +328,127 @@ static UINT8 vp931_data_ready(laserdisc_state *ld)
}
/*-------------------------------------------------
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;
}
}
/*-------------------------------------------------
output0_w - controls audio/video squelch
and other bits
@ -392,7 +525,7 @@ static WRITE8_HANDLER( output1_w )
if (!(data & 0x02))
{
/* fast/slow is based on bit 2 */
speed = (data & 0x04) ? VP931_SCAN_FAST_SPEED : VP931_SCAN_SPEED;
speed = (data & 0x04) ? SCAN_FAST_SPEED : SCAN_SPEED;
/* direction is based on bit 0 */
if (data & 0x01)
@ -647,124 +780,3 @@ 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;
}
}

View File

@ -807,7 +807,7 @@ static int validate_cpu(int drivnum, const machine_config *config, const input_p
/* validate the global map parameters */
if (map->spacenum != spacenum)
{
mame_printf_error("%s: %s CPU #%d space %d has address space %d handlers!", driver->source_file, driver->name, cpunum, spacenum, map->spacenum);
mame_printf_error("%s: %s CPU #%d space %d has address space %d handlers!\n", driver->source_file, driver->name, cpunum, spacenum, map->spacenum);
error = TRUE;
}
if (map->databits != databus_width)

View File

@ -26,6 +26,7 @@ OBJDIRS += \
#-------------------------------------------------
CPUS += I8049
CPUS += Z80