summaryrefslogtreecommitdiffstatshomepage
path: root/src/devices/machine/ldvp931.cpp
diff options
context:
space:
mode:
Diffstat (limited to 'src/devices/machine/ldvp931.cpp')
-rw-r--r--src/devices/machine/ldvp931.cpp271
1 files changed, 148 insertions, 123 deletions
diff --git a/src/devices/machine/ldvp931.cpp b/src/devices/machine/ldvp931.cpp
index 4bcb74e1b6a..a92a8bed283 100644
--- a/src/devices/machine/ldvp931.cpp
+++ b/src/devices/machine/ldvp931.cpp
@@ -25,9 +25,10 @@
// DEBUGGING
//**************************************************************************
-#define LOG_COMMANDS 0
-#define LOG_PORTS 0
-
+#define LOG_COMMANDS (1U << 1)
+#define LOG_PORTS (1U << 2)
+#define VERBOSE (0)
+#include "logmacro.h"
//**************************************************************************
@@ -80,7 +81,11 @@ ROM_END
philips_22vp931_device::philips_22vp931_device(const machine_config &mconfig, const char *tag, device_t *owner, uint32_t clock)
: laserdisc_device(mconfig, PHILIPS_22VP931, tag, owner, clock),
m_i8049_cpu(*this, "vp931"),
- m_tracktimer(nullptr),
+ m_process_vbi_timer(nullptr),
+ m_irq_off_timer(nullptr),
+ m_strobe_off_timer(nullptr),
+ m_erp_off_timer(nullptr),
+ m_track_timer(nullptr),
m_i8049_out0(0),
m_i8049_out1(0),
m_i8049_port1(0),
@@ -130,7 +135,7 @@ uint8_t philips_22vp931_device::data_r()
}
// also boost interleave for 4 scanlines to ensure proper communications
- machine().scheduler().boost_interleave(attotime::zero, screen().scan_period() * 4);
+ machine().scheduler().perfect_quantum(screen().scan_period() * 4);
return m_tocontroller;
}
@@ -144,8 +149,13 @@ void philips_22vp931_device::device_start()
// pass through to the parent
laserdisc_device::device_start();
- // allocate a timer
- m_tracktimer = timer_alloc(TID_HALF_TRACK);
+ // allocate timers
+ m_initial_vbi_timer = timer_alloc(FUNC(philips_22vp931_device::process_vbi_data), this);
+ m_process_vbi_timer = timer_alloc(FUNC(philips_22vp931_device::process_vbi_data), this);
+ m_irq_off_timer = timer_alloc(FUNC(philips_22vp931_device::irq_off), this);
+ m_strobe_off_timer = timer_alloc(FUNC(philips_22vp931_device::data_strobe_off), this);
+ m_erp_off_timer = timer_alloc(FUNC(philips_22vp931_device::erp_off), this);
+ m_track_timer = timer_alloc(FUNC(philips_22vp931_device::half_track_tick), this);
}
@@ -181,92 +191,110 @@ void philips_22vp931_device::device_reset()
//-------------------------------------------------
-// device_timer - handle timers set by this
-// device
+// process_vbi_data - process VBI data which was
+// fetched by the parent device
//-------------------------------------------------
-void philips_22vp931_device::device_timer(emu_timer &timer, device_timer_id id, int param, void *ptr)
+TIMER_CALLBACK_MEMBER(philips_22vp931_device::process_vbi_data)
{
- switch (id)
+ uint32_t line = param >> 2;
+ int which = param & 3;
+ uint32_t code = 0;
+
+ // fetch the code and compute the DATIC latched value
+ if (line >= LASERDISC_CODE_LINE16 && line <= LASERDISC_CODE_LINE18)
+ code = get_field_code(laserdisc_field_code(line), false);
+
+ // at the start of each line, signal an interrupt and use a timer to turn it off
+ if (which == 0)
{
- case TID_VBI_DATA_FETCH:
- {
- uint32_t line = param >> 2;
- int which = param & 3;
- uint32_t code = 0;
-
- // fetch the code and compute the DATIC latched value
- if (line >= LASERDISC_CODE_LINE16 && line <= LASERDISC_CODE_LINE18)
- code = get_field_code(laserdisc_field_code(line), false);
-
- // at the start of each line, signal an interrupt and use a timer to turn it off
- if (which == 0)
- {
- m_i8049_cpu->set_input_line(MCS48_INPUT_IRQ, ASSERT_LINE);
- timer_set(attotime::from_nsec(5580), TID_IRQ_OFF);
- }
-
- // clock the data strobe on each subsequent callback
- else if (code != 0)
- {
- m_daticval = code >> (8 * (3 - which));
- m_datastrobe = 1;
- timer_set(attotime::from_nsec(5000), TID_DATA_STROBE_OFF);
- }
-
- // determine the next bit to fetch and reprime ourself
- if (++which == 4)
- {
- which = 0;
- line++;
- }
- if (line <= LASERDISC_CODE_LINE18 + 1)
- timer_set(screen().time_until_pos(line*2, which * 2 * screen().width() / 4), TID_VBI_DATA_FETCH, (line << 2) + which);
- break;
- }
+ m_i8049_cpu->set_input_line(MCS48_INPUT_IRQ, ASSERT_LINE);
+ m_irq_off_timer->adjust(attotime::from_nsec(5580));
+ }
+
+ // clock the data strobe on each subsequent callback
+ else if (code != 0)
+ {
+ m_daticval = code >> (8 * (3 - which));
+ m_datastrobe = 1;
+ m_strobe_off_timer->adjust(attotime::from_nsec(5000));
+ }
+
+ // determine the next bit to fetch and reprime ourself
+ if (++which == 4)
+ {
+ which = 0;
+ line++;
+ }
+ if (line <= LASERDISC_CODE_LINE18 + 1)
+ m_process_vbi_timer->adjust(screen().time_until_pos(line*2, which * 2 * screen().width() / 4), (line << 2) + which);
+}
+
- case TID_DEFERRED_DATA:
- // set the value and mark it pending
- if (LOG_COMMANDS && m_fromcontroller_pending)
- printf("Dropped previous command byte\n");
- m_fromcontroller = param;
- m_fromcontroller_pending = true;
-
- // track the commands for debugging purposes
- if (m_cmdcount < ARRAY_LENGTH(m_cmdbuf))
- {
- m_cmdbuf[m_cmdcount++ % 3] = param;
- if (LOG_COMMANDS && m_cmdcount % 3 == 0)
- printf("Cmd: %02X %02X %02X\n", m_cmdbuf[0], m_cmdbuf[1], m_cmdbuf[2]);
- }
- break;
-
- case TID_IRQ_OFF:
- m_i8049_cpu->set_input_line(MCS48_INPUT_IRQ, CLEAR_LINE);
- break;
-
- case TID_DATA_STROBE_OFF:
- m_datastrobe = 0;
- break;
-
- case TID_ERP_OFF:
- m_daticerp = 0;
- break;
-
- case TID_HALF_TRACK:
- // advance by the count and toggle the state
- m_trackstate ^= 1;
- if ((m_trackdir < 0 && !m_trackstate) || (m_trackdir > 0 && m_trackstate))
- {
- advance_slider(m_trackdir);
- m_advanced += m_trackdir;
- }
- break;
-
- // pass everything else onto the parent
- default:
- laserdisc_device::device_timer(timer, id, param, ptr);
- break;
+//-------------------------------------------------
+// process_deferred_data -
+//-------------------------------------------------
+
+TIMER_CALLBACK_MEMBER(philips_22vp931_device::process_deferred_data)
+{
+ // set the value and mark it pending
+ if (m_fromcontroller_pending)
+ LOGMASKED(LOG_COMMANDS, "Dropped previous command byte\n");
+ m_fromcontroller = param;
+ m_fromcontroller_pending = true;
+
+ // track the commands for debugging purposes
+ if (m_cmdcount < std::size(m_cmdbuf))
+ {
+ m_cmdbuf[m_cmdcount++ % 3] = param;
+ if (m_cmdcount % 3 == 0)
+ LOGMASKED(LOG_COMMANDS, "Cmd: %02X %02X %02X\n", m_cmdbuf[0], m_cmdbuf[1], m_cmdbuf[2]);
+ }
+}
+
+
+//-------------------------------------------------
+// irq_off -
+//-------------------------------------------------
+
+TIMER_CALLBACK_MEMBER(philips_22vp931_device::irq_off)
+{
+ m_i8049_cpu->set_input_line(MCS48_INPUT_IRQ, CLEAR_LINE);
+}
+
+
+//-------------------------------------------------
+// data_strobe_off -
+//-------------------------------------------------
+
+TIMER_CALLBACK_MEMBER(philips_22vp931_device::data_strobe_off)
+{
+ m_datastrobe = 0;
+}
+
+
+//-------------------------------------------------
+// erp_off -
+//-------------------------------------------------
+
+TIMER_CALLBACK_MEMBER(philips_22vp931_device::erp_off)
+{
+ m_daticerp = 0;
+}
+
+
+//-------------------------------------------------
+// half_track_tick - advance the slider by the
+// current count and toggle the track state
+//-------------------------------------------------
+
+TIMER_CALLBACK_MEMBER(philips_22vp931_device::half_track_tick)
+{
+ m_trackstate ^= 1;
+ if ((m_trackdir < 0 && !m_trackstate) || (m_trackdir > 0 && m_trackstate))
+ {
+ advance_slider(m_trackdir);
+ m_advanced += m_trackdir;
}
}
@@ -311,7 +339,7 @@ void philips_22vp931_device::player_vsync(const vbi_metadata &vbi, int fieldnum,
// set the ERP signal to 1 to indicate start of frame, and set a timer to turn it off
m_daticerp = 1;
- timer_set(screen().time_until_pos(15*2), TID_ERP_OFF);
+ m_erp_off_timer->adjust(screen().time_until_pos(15*2));
}
@@ -322,8 +350,9 @@ void philips_22vp931_device::player_vsync(const vbi_metadata &vbi, int fieldnum,
int32_t philips_22vp931_device::player_update(const vbi_metadata &vbi, int fieldnum, const attotime &curtime)
{
- // set the first VBI timer to go at the start of line 16
- timer_set(screen().time_until_pos(16*2), TID_VBI_DATA_FETCH, LASERDISC_CODE_LINE16 << 2);
+ // player_update is invoked by the parent device at line 16, so call our VBI processing timer directly
+ m_initial_vbi_timer->adjust(screen().time_until_pos(16*2), LASERDISC_CODE_LINE16 << 2);
+ //process_vbi_data(LASERDISC_CODE_LINE16 << 2);
// play forward by default
return fieldnum;
@@ -335,7 +364,7 @@ int32_t philips_22vp931_device::player_update(const vbi_metadata &vbi, int field
// and other bits
//-------------------------------------------------
-WRITE8_MEMBER( philips_22vp931_device::i8049_output0_w )
+void philips_22vp931_device::i8049_output0_w(uint8_t data)
{
/*
$80 = n/c
@@ -348,7 +377,7 @@ WRITE8_MEMBER( philips_22vp931_device::i8049_output0_w )
$01 = inverted -> VIDEO MUTE
*/
- if (LOG_PORTS && (m_i8049_out0 ^ data) & 0xff)
+ if ((VERBOSE & LOG_PORTS) && (m_i8049_out0 ^ data) & 0xff)
{
std::string flags;
if ( (data & 0x80)) flags += " ???";
@@ -374,7 +403,7 @@ WRITE8_MEMBER( philips_22vp931_device::i8049_output0_w )
// i8049_output1_w - controls scanning behaviors
//-------------------------------------------------
-WRITE8_MEMBER( philips_22vp931_device::i8049_output1_w )
+void philips_22vp931_device::i8049_output1_w(uint8_t data)
{
/*
$80 = n/c
@@ -389,7 +418,7 @@ WRITE8_MEMBER( philips_22vp931_device::i8049_output1_w )
int32_t speed;
- if (LOG_PORTS && (m_i8049_out1 ^ data) & 0x08)
+ if ((VERBOSE & LOG_PORTS) && (m_i8049_out1 ^ data) & 0x08)
{
std::string flags;
if (!(data & 0x08)) flags += " SMS";
@@ -418,7 +447,7 @@ WRITE8_MEMBER( philips_22vp931_device::i8049_output1_w )
// i8049_lcd_w - vestigial LCD frame display
//-------------------------------------------------
-WRITE8_MEMBER( philips_22vp931_device::i8049_lcd_w )
+void philips_22vp931_device::i8049_lcd_w(uint8_t data)
{
/*
Frame number is written as 5 digits here; however, it is not actually
@@ -431,7 +460,7 @@ WRITE8_MEMBER( philips_22vp931_device::i8049_lcd_w )
// i8049_unknown_r - unknown input port
//-------------------------------------------------
-READ8_MEMBER( philips_22vp931_device::i8049_unknown_r )
+uint8_t philips_22vp931_device::i8049_unknown_r()
{
// only bit $80 is checked and its effects are minor
return 0x00;
@@ -443,7 +472,7 @@ READ8_MEMBER( philips_22vp931_device::i8049_unknown_r )
// controls
//-------------------------------------------------
-READ8_MEMBER( philips_22vp931_device::i8049_keypad_r )
+uint8_t philips_22vp931_device::i8049_keypad_r()
{
/*
From the code, this is apparently a vestigial keypad with basic controls:
@@ -465,7 +494,7 @@ READ8_MEMBER( philips_22vp931_device::i8049_keypad_r )
// DATIC circuit
//-------------------------------------------------
-READ8_MEMBER( philips_22vp931_device::i8049_datic_r )
+uint8_t philips_22vp931_device::i8049_datic_r()
{
return m_daticval;
}
@@ -476,7 +505,7 @@ READ8_MEMBER( philips_22vp931_device::i8049_datic_r )
// external controller wrote
//-------------------------------------------------
-READ8_MEMBER( philips_22vp931_device::i8049_from_controller_r )
+uint8_t philips_22vp931_device::i8049_from_controller_r()
{
// clear the pending flag and return the data
m_fromcontroller_pending = false;
@@ -489,7 +518,7 @@ READ8_MEMBER( philips_22vp931_device::i8049_from_controller_r )
// the external controller
//-------------------------------------------------
-WRITE8_MEMBER( philips_22vp931_device::i8049_to_controller_w )
+void philips_22vp931_device::i8049_to_controller_w(uint8_t data)
{
// set the pending flag and stash the data
m_tocontroller_pending = true;
@@ -500,7 +529,7 @@ WRITE8_MEMBER( philips_22vp931_device::i8049_to_controller_w )
m_data_ready(*this, true);
// also boost interleave for 4 scanlines to ensure proper communications
- machine().scheduler().boost_interleave(attotime::zero, screen().scan_period() * 4);
+ machine().scheduler().perfect_quantum(screen().scan_period() * 4);
}
@@ -508,7 +537,7 @@ WRITE8_MEMBER( philips_22vp931_device::i8049_to_controller_w )
// i8049_port1_r - read the 8048 I/O port 1
//-------------------------------------------------
-READ8_MEMBER( philips_22vp931_device::i8049_port1_r )
+uint8_t philips_22vp931_device::i8049_port1_r()
{
/*
$80 = P17 = (in) unsure
@@ -527,7 +556,7 @@ READ8_MEMBER( philips_22vp931_device::i8049_port1_r )
// i8049_port1_w - write the 8048 I/O port 1
//-------------------------------------------------
-WRITE8_MEMBER( philips_22vp931_device::i8049_port1_w )
+void philips_22vp931_device::i8049_port1_w(uint8_t data)
{
/*
$10 = P14 = (out) D104 -> /SPEED
@@ -537,7 +566,7 @@ WRITE8_MEMBER( philips_22vp931_device::i8049_port1_w )
$01 = P10 = (out) D100 -> some op-amp then to C334, B56, B332
*/
- if (LOG_PORTS && (m_i8049_port1 ^ data) & 0x1f)
+ if ((VERBOSE & LOG_PORTS) && (m_i8049_port1 ^ data) & 0x1f)
{
std::string flags;
if (!(data & 0x10)) flags += " SPEED";
@@ -572,22 +601,18 @@ WRITE8_MEMBER( philips_22vp931_device::i8049_port1_w )
}
}
- // if we have a timer, adjust it
- if (m_tracktimer != nullptr)
- {
- // turn it off if we're not tracking
- if (m_trackdir == 0)
- m_tracktimer->reset();
+ // turn off the track timer if we're not tracking
+ if (m_trackdir == 0)
+ m_track_timer->reset();
- // if we just started tracking, or if the speed was changed, reprime the timer
- else if (((m_i8049_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::from_usec(60) : attotime::from_usec(10);
+ // if we just started tracking, or if the speed was changed, reprime the timer
+ else if (((m_i8049_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::from_usec(60) : attotime::from_usec(10);
- // always start with an initial long delay; the code expects this
- m_tracktimer->adjust(attotime::from_usec(100), 0, speed);
- }
+ // always start with an initial long delay; the code expects this
+ m_track_timer->adjust(attotime::from_usec(100), 0, speed);
}
m_i8049_port1 = data;
@@ -598,7 +623,7 @@ WRITE8_MEMBER( philips_22vp931_device::i8049_port1_w )
// i8049_port2_r - read from the 8048 I/O port 2
//-------------------------------------------------
-READ8_MEMBER( philips_22vp931_device::i8049_port2_r )
+uint8_t philips_22vp931_device::i8049_port2_r()
{
/*
$80 = P27 = (in) set/reset latch; set by FOC LS, reset by IGR
@@ -619,7 +644,7 @@ READ8_MEMBER( philips_22vp931_device::i8049_port2_r )
// i8049_port2_w - write the 8048 I/O port 2
//-------------------------------------------------
-WRITE8_MEMBER( philips_22vp931_device::i8049_port2_w )
+void philips_22vp931_device::i8049_port2_w(uint8_t data)
{
/*
$40 = P26 = (out) cleared while data is sent back & forth; set afterwards
@@ -633,7 +658,7 @@ WRITE8_MEMBER( philips_22vp931_device::i8049_port2_w )
// connected to the DATIC's data strobe line
//-------------------------------------------------
-READ_LINE_MEMBER( philips_22vp931_device::i8049_t0_r )
+int philips_22vp931_device::i8049_t0_r()
{
return m_datastrobe;
}
@@ -645,7 +670,7 @@ READ_LINE_MEMBER( philips_22vp931_device::i8049_t0_r )
// to count the number of tracks advanced
//-------------------------------------------------
-READ_LINE_MEMBER( philips_22vp931_device::i8049_t1_r )
+int philips_22vp931_device::i8049_t1_r()
{
return m_trackstate;
}