mirror of
https://github.com/holub/mame
synced 2025-05-22 05:38:52 +03:00
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:
parent
3df44083f8
commit
2d6453c98a
@ -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);
|
||||
|
@ -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 */
|
||||
|
@ -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;
|
||||
}
|
||||
|
||||
|
@ -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);
|
||||
|
@ -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);
|
||||
|
@ -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
|
||||
|
@ -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;
|
||||
|
@ -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
@ -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;
|
||||
}
|
||||
}
|
||||
|
@ -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)
|
||||
|
@ -26,6 +26,7 @@ OBJDIRS += \
|
||||
#-------------------------------------------------
|
||||
|
||||
CPUS += I8049
|
||||
CPUS += Z80
|
||||
|
||||
|
||||
|
||||
|
Loading…
Reference in New Issue
Block a user