diff options
Diffstat (limited to 'src/devices/machine/ldvp931.cpp')
-rw-r--r-- | src/devices/machine/ldvp931.cpp | 271 |
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; } |