From cabb52c75bc9a86ce375ced82a5ff1db500c813f Mon Sep 17 00:00:00 2001 From: David Haywood <28625134+DavidHaywood@users.noreply.github.com> Date: Thu, 21 Nov 2019 13:55:34 +0000 Subject: vt1682.cpp - (plug & play) mostly fixed raster effects (#5937) * some kind of rasters (nw) * fix raster timer, clean up (nw) * srcclean (nw) --- src/mame/drivers/vt1682.cpp | 90 +++++++++++++++++++++++++-------------- src/mame/machine/vt1682_alu.cpp | 2 +- src/mame/machine/vt1682_timer.cpp | 52 +++++++++++++--------- src/mame/machine/vt1682_timer.h | 2 + 4 files changed, 93 insertions(+), 53 deletions(-) diff --git a/src/mame/drivers/vt1682.cpp b/src/mame/drivers/vt1682.cpp index ae04567ff73..761a41fb163 100644 --- a/src/mame/drivers/vt1682.cpp +++ b/src/mame/drivers/vt1682.cpp @@ -31,6 +31,23 @@ #define VERBOSE (0) #include "logmacro.h" +// NTSC uses XTAL(21'477'272) Sound CPU runs at exactly this, Main CPU runs at this / 4 +// PAL uses XTAL(26'601'712) Sound CPU runs at exactly this, Main CPU runs at this / 5 + +// can also be used with the following +// PAL M 21.453669MHz +// PAL N 21.492336MHz + +#define MAIN_CPU_CLOCK_NTSC XTAL(21'477'272)/4 +#define SOUND_CPU_CLOCK_NTSC XTAL(21'477'272) +#define TIMER_ALT_SPEED_NTSC (15746) + +#define MAIN_CPU_CLOCK_PAL XTAL(26'601'712)/5 +#define SOUND_CPU_CLOCK_PAL XTAL(26'601'712) +#define TIMER_ALT_SPEED_PAL (15602) + + + class vt_vt1682_state : public driver_device { public: @@ -488,6 +505,13 @@ private: m_system_timer_dev->vt1682_timer_enable_w(space, offset, data); }; + DECLARE_WRITE8_MEMBER(vt1682_timer_preload_15_8_trampoline_w) + { + logerror("%s: vt1682_timer_preload_15_8_trampoline_w: %02x @ position y%d, x%d\n", machine().describe_context(), data, m_screen->vpos(), m_screen->hpos()); + m_system_timer_dev->vt1682_timer_preload_15_8_w(space, offset, data); + }; + + void update_banks(); uint8_t translate_prg0select(uint8_t tp20_tp13); uint32_t translate_address_4000_to_7fff(uint16_t address); @@ -1498,7 +1522,7 @@ READ8_MEMBER(vt_vt1682_state::vt1682_2010_bk1_xscroll_7_0_r) WRITE8_MEMBER(vt_vt1682_state::vt1682_2010_bk1_xscroll_7_0_w) { - m_screen->update_partial(m_screen->vpos()); + m_screen->update_partial(m_screen->vpos()); logerror("%s: vt1682_2010_bk1_xscroll_7_0_w writing: %02x\n", machine().describe_context(), data); m_xscroll_7_0_bk[0] = data; @@ -1554,7 +1578,7 @@ READ8_MEMBER(vt_vt1682_state::vt1682_2012_bk1_scroll_control_r) WRITE8_MEMBER(vt_vt1682_state::vt1682_2012_bk1_scroll_control_w) { - m_screen->update_partial(m_screen->vpos()); + m_screen->update_partial(m_screen->vpos()); logerror("%s: vt1682_2012_bk1_scroll_control_w writing: %02x (hclr: %1x page_layout:%1x ymsb:%1x xmsb:%1x)\n", machine().describe_context(), data, (data & 0x10) >> 4, (data & 0x0c) >> 2, (data & 0x02) >> 1, (data & 0x01) >> 0); @@ -1585,7 +1609,7 @@ READ8_MEMBER(vt_vt1682_state::vt1682_2013_bk1_main_control_r) WRITE8_MEMBER(vt_vt1682_state::vt1682_2013_bk1_main_control_w) { - m_screen->update_partial(m_screen->vpos()); + m_screen->update_partial(m_screen->vpos()); logerror("%s: vt1682_2013_bk1_main_control_w writing: %02x (enable:%01x palette:%01x depth:%01x bpp:%01x linemode:%01x tilesize:%01x)\n", machine().describe_context(), data, (data & 0x80) >> 7, (data & 0x40) >> 6, (data & 0x30) >> 4, (data & 0x0c) >> 2, (data & 0x02) >> 1, (data & 0x01) >> 0 ); @@ -1616,7 +1640,7 @@ READ8_MEMBER(vt_vt1682_state::vt1682_2014_bk2_xscroll_7_0_r) WRITE8_MEMBER(vt_vt1682_state::vt1682_2014_bk2_xscroll_7_0_w) { - m_screen->update_partial(m_screen->vpos()); + m_screen->update_partial(m_screen->vpos()); logerror("%s: vt1682_2014_bk2_xscroll_7_0_w writing: %02x\n", machine().describe_context(), data); m_xscroll_7_0_bk[1] = data; @@ -1672,7 +1696,7 @@ READ8_MEMBER(vt_vt1682_state::vt1682_2016_bk2_scroll_control_r) WRITE8_MEMBER(vt_vt1682_state::vt1682_2016_bk2_scroll_control_w) { - m_screen->update_partial(m_screen->vpos()); + m_screen->update_partial(m_screen->vpos()); logerror("%s: vt1682_2016_bk2_scroll_control_w writing: %02x ((invalid): %1x page_layout:%1x ymsb:%1x xmsb:%1x)\n", machine().describe_context(), data, (data & 0x10) >> 4, (data & 0x0c) >> 2, (data & 0x02) >> 1, (data & 0x01) >> 0); @@ -1703,7 +1727,7 @@ READ8_MEMBER(vt_vt1682_state::vt1682_2017_bk2_main_control_r) WRITE8_MEMBER(vt_vt1682_state::vt1682_2017_bk2_main_control_w) { - m_screen->update_partial(m_screen->vpos()); + m_screen->update_partial(m_screen->vpos()); logerror("%s: vt1682_2017_bk2_main_control_w writing: %02x (enable:%01x palette:%01x depth:%01x bpp:%01x (invalid):%01x tilesize:%01x)\n", machine().describe_context(), data, (data & 0x80) >> 7, (data & 0x40) >> 6, (data & 0x30) >> 4, (data & 0x0c) >> 2, (data & 0x02) >> 1, (data & 0x01) >> 0 ); @@ -1945,7 +1969,7 @@ READ8_MEMBER(vt_vt1682_state::vt1682_2020_bk_linescroll_r) WRITE8_MEMBER(vt_vt1682_state::vt1682_2020_bk_linescroll_w) { - m_screen->update_partial(m_screen->vpos()); + m_screen->update_partial(m_screen->vpos()); logerror("%s: vt1682_2020_bk_linescroll_w writing: %02x\n", machine().describe_context(), data); m_2020_bk_linescroll = data; @@ -2600,7 +2624,7 @@ WRITE8_MEMBER(vt_vt1682_state::vt1682_210a_prgbank0_r3_w) /* Address 0x210b r/w (MAIN CPU) - 0x80 - TSYSN Enable + 0x80 - TSYSN En (Timer Clock Select) 0x40 - PQ2 Enable 0x20 - BUS Tristate 0x10 - CS Control:1 @@ -2623,6 +2647,17 @@ WRITE8_MEMBER(vt_vt1682_state::vt1682_210b_misc_cs_prg0_bank_sel_w) logerror("%s: vt1682_210b_misc_cs_prg0_bank_sel_w writing: %02x\n", machine().describe_context(), data); m_210b_misc_cs_prg0_bank_sel = data; + + // TODO: allow PAL + if (data & 0x80) + { + m_system_timer_dev->set_clock(TIMER_ALT_SPEED_NTSC); + } + else + { + m_system_timer_dev->set_clock(MAIN_CPU_CLOCK_NTSC); + } + update_banks(); } @@ -4881,11 +4916,12 @@ void vt_vt1682_state::vt_vt1682_map(address_map &map) /* System */ map(0x2100, 0x2100).rw(FUNC(vt_vt1682_state::vt1682_2100_prgbank1_r3_r), FUNC(vt_vt1682_state::vt1682_2100_prgbank1_r3_w)); - map(0x2101, 0x2101).rw(m_system_timer_dev, FUNC(vrt_vt1682_timer_device::vt1682_timer_preload_15_8_r), FUNC(vrt_vt1682_timer_device::vt1682_timer_preload_15_8_w)); + map(0x2101, 0x2101).rw(m_system_timer_dev, FUNC(vrt_vt1682_timer_device::vt1682_timer_preload_7_0_r), FUNC(vrt_vt1682_timer_device::vt1682_timer_preload_7_0_w)); map(0x2102, 0x2102).r(m_system_timer_dev, FUNC(vrt_vt1682_timer_device::vt1682_timer_enable_r)); map(0x2102, 0x2102).w(FUNC(vt_vt1682_state::vt1682_timer_enable_trampoline_w)); map(0x2103, 0x2103).w( m_system_timer_dev, FUNC(vrt_vt1682_timer_device::vt1682_timer_irqclear_w)); - map(0x2104, 0x2104).rw(m_system_timer_dev, FUNC(vrt_vt1682_timer_device::vt1682_timer_preload_7_0_r), FUNC(vrt_vt1682_timer_device::vt1682_timer_preload_7_0_w)); // not on 2100 as you might expect + map(0x2104, 0x2104).r(m_system_timer_dev, FUNC(vrt_vt1682_timer_device::vt1682_timer_preload_15_8_r)); + map(0x2104, 0x2104).w(FUNC(vt_vt1682_state::vt1682_timer_preload_15_8_trampoline_w)); map(0x2105, 0x2105).w(FUNC(vt_vt1682_state::vt1682_2105_comr6_tvmodes_w)); map(0x2106, 0x2106).rw(FUNC(vt_vt1682_state::vt1682_2106_enable_regs_r), FUNC(vt_vt1682_state::vt1682_2106_enable_regs_w)); map(0x2107, 0x2107).rw(FUNC(vt_vt1682_state::vt1682_2107_prgbank0_r0_r), FUNC(vt_vt1682_state::vt1682_2107_prgbank0_r0_w)); @@ -4984,10 +5020,10 @@ WRITE_LINE_MEMBER(vt_vt1682_state::soundcpu_timerb_irq) { // need to set proper vector (need IRQ priority manager function?) /* - if (state) - m_soundcpu->set_input_line(0, ASSERT_LINE); - else - m_soundcpu->set_input_line(0, CLEAR_LINE); + if (state) + m_soundcpu->set_input_line(0, ASSERT_LINE); + else + m_soundcpu->set_input_line(0, CLEAR_LINE); */ } @@ -4996,7 +5032,7 @@ WRITE_LINE_MEMBER(vt_vt1682_state::maincpu_timer_irq) // need to set proper vector (need IRQ priority manager function?) /* rasters are used on: - + Highway Racing (title screen - scrolling split) Fire Man (title screen - scrolling split) Bee Fighting (title screen - scrolling split) @@ -5033,11 +5069,11 @@ TIMER_DEVICE_CALLBACK_MEMBER(vt_vt1682_state::scanline) /* INTERRUPT_GEN_MEMBER(vt_vt1682_state::nmi) { - if (m_2000 & 0x01) - { - m_maincpu->pulse_input_line(INPUT_LINE_NMI, attotime::zero); - m_soundcpu->pulse_input_line(INPUT_LINE_NMI, attotime::zero); // same enable? (NMI_EN on sub is 'wakeup NMI') - } + if (m_2000 & 0x01) + { + m_maincpu->pulse_input_line(INPUT_LINE_NMI, attotime::zero); + m_soundcpu->pulse_input_line(INPUT_LINE_NMI, attotime::zero); // same enable? (NMI_EN on sub is 'wakeup NMI') + } } */ @@ -5103,18 +5139,6 @@ static GFXDECODE_START( gfx_test ) GFXDECODE_END -// NTSC uses XTAL(21'477'272) Sound CPU runs at exactly this, Main CPU runs at this / 4 -// PAL uses XTAL(26'601'712) Sound CPU runs at exactly this, Main CPU runs at this / 5 - -// can also be used with the following -// PAL M 21.453669MHz -// PAL N 21.492336MHz - -#define MAIN_CPU_CLOCK_NTSC XTAL(21'477'272)/4 -#define SOUND_CPU_CLOCK_NTSC XTAL(21'477'272) - -#define MAIN_CPU_CLOCK_PAL XTAL(26'601'712)/5 -#define SOUND_CPU_CLOCK_PAL XTAL(26'601'712) void vt_vt1682_state::vt_vt1682(machine_config &config) @@ -5158,7 +5182,7 @@ void vt_vt1682_state::vt_vt1682(machine_config &config) SCREEN(config, m_screen, SCREEN_TYPE_RASTER); m_screen->set_refresh_hz(60); m_screen->set_vblank_time(ATTOSECONDS_IN_USEC(0)); - m_screen->set_size(256, 256); + m_screen->set_size(256, 262); // 262 for NTSC, might be 261 if Vblank line is changed m_screen->set_visarea(0, 256-1, 0, 240-1); m_screen->set_screen_update(FUNC(vt_vt1682_state::screen_update)); diff --git a/src/mame/machine/vt1682_alu.cpp b/src/mame/machine/vt1682_alu.cpp index 292a33a81da..3dfb7635d50 100644 --- a/src/mame/machine/vt1682_alu.cpp +++ b/src/mame/machine/vt1682_alu.cpp @@ -346,4 +346,4 @@ WRITE8_MEMBER(vrt_vt1682_alu_device::alu_oprand_6_div_w) m_alu_out[5] = 0x00;// machine().rand(); } -} \ No newline at end of file +} diff --git a/src/mame/machine/vt1682_timer.cpp b/src/mame/machine/vt1682_timer.cpp index 8cf92f74299..393dadf2ea8 100644 --- a/src/mame/machine/vt1682_timer.cpp +++ b/src/mame/machine/vt1682_timer.cpp @@ -1,6 +1,9 @@ // license:BSD-3-Clause // copyright-holders:David Haywood +// Do timers auto reload? +// Does writing to Enable actually turn on the timer, or writing to preload MSB? (which appears to be done AFTER turning on in many cases) + #include "emu.h" #include "machine/vt1682_timer.h" @@ -42,10 +45,10 @@ void vrt_vt1682_timer_device::device_reset() /* - Address 0x2100 r/w (SOUND CPU, Timer A) - Address 0x2110 r/w (SOUND CPU, Timer B) + Address 0x2100 r/w (SOUND CPU, Timer A) + Address 0x2110 r/w (SOUND CPU, Timer B) - Address 0x2101 r/w (MAIN CPU, Timer) + Address 0x2101 r/w (MAIN CPU, Timer) 0x80 - Timer xx Preload:7 0x40 - Timer xx Preload:6 @@ -73,7 +76,7 @@ WRITE8_MEMBER(vrt_vt1682_timer_device::vt1682_timer_preload_7_0_w) /* Address 0x2101 r/w (SOUND CPU, Timer A) - Address 0x2111 r/w (SOUND CPU, Timer B) + Address 0x2111 r/w (SOUND CPU, Timer B) Address 0x2104 r/w (MAIN CPU, Timer) @@ -94,16 +97,31 @@ READ8_MEMBER(vrt_vt1682_timer_device::vt1682_timer_preload_15_8_r) return ret; } +void vrt_vt1682_timer_device::update_timer() +{ + if (m_timer_enable & 0x01) + { + uint16_t preload = (m_timer_preload_15_8 << 8) | m_timer_preload_7_0; + int realpreload = 65536 - preload; + m_timer->adjust(attotime::from_hz(clock()) * realpreload, 0, attotime::from_hz(clock()) * realpreload); + } +} + WRITE8_MEMBER(vrt_vt1682_timer_device::vt1682_timer_preload_15_8_w) { if (!m_is_sound_timer) LOGMASKED(LOG_TIMER,"%s: vt1682_timer_preload_15_8_w writing: %02x\n", machine().describe_context(), data); m_timer_preload_15_8 = data; + + update_timer(); } + + + /* Address 0x2102 r/w (SOUND CPU, Timer A) - Address 0x2112 r/w (SOUND CPU, Timer B) + Address 0x2112 r/w (SOUND CPU, Timer B) Address 0x2102 r/w (MAIN CPU, Timer) @@ -135,26 +153,17 @@ WRITE8_MEMBER(vrt_vt1682_timer_device::vt1682_timer_enable_w) // Period = (65536 - Timer PreLoad) / 26.601712 MHz //Timer PreLoad = 65536 - (Period in seconds) * 26.601712 * 1000000 ) - /* - */ - - if (!m_is_sound_timer) LOGMASKED(LOG_TIMER, "%s: vt1682_timer_enable_w writing: %02x\n", machine().describe_context(), data); m_timer_enable = data; if (m_timer_enable & 0x01) { - uint16_t preload = (m_timer_preload_15_8 << 8) | m_timer_preload_7_0; - - double period = (double)(65536 - preload) / (clock() / 1000000); // in microseconds? - if (!m_is_sound_timer) LOGMASKED(LOG_TIMER, "preload %d period in usec %f\n", preload, period ); - m_timer->adjust(attotime::from_usec(period), 0, attotime::from_usec(period)); + update_timer(); } else { m_timer->adjust(attotime::never); } - } TIMER_DEVICE_CALLBACK_MEMBER(vrt_vt1682_timer_device::timer_expired) @@ -167,10 +176,10 @@ TIMER_DEVICE_CALLBACK_MEMBER(vrt_vt1682_timer_device::timer_expired) /* Address 0x2103 r/w (SOUND CPU, Timer A) - Address 0x2113 r/w (SOUND CPU, Timer B) + Address 0x2113 r/w (SOUND CPU, Timer B) + + Address 0x2103 r/w (MAIN CPU, Timer) (read or write?) - Address 0x2103 r/w (MAIN CPU, Timer) (read or write?) - 0x80 - Timer xx IRQ Clear 0x40 - Timer xx IRQ Clear 0x20 - Timer xx IRQ Clear @@ -191,4 +200,9 @@ WRITE8_MEMBER(vrt_vt1682_timer_device::vt1682_timer_irqclear_w) void vrt_vt1682_timer_device::device_add_mconfig(machine_config& config) { TIMER(config, m_timer).configure_periodic(FUNC(vrt_vt1682_timer_device::timer_expired), attotime::never); -} \ No newline at end of file +} + +void vrt_vt1682_timer_device::change_clock() +{ + notify_clock_changed(); +} diff --git a/src/mame/machine/vt1682_timer.h b/src/mame/machine/vt1682_timer.h index b901cf7521d..97f6cc263c9 100644 --- a/src/mame/machine/vt1682_timer.h +++ b/src/mame/machine/vt1682_timer.h @@ -32,6 +32,7 @@ public: DECLARE_WRITE8_MEMBER(vt1682_timer_irqclear_w); + void change_clock(); protected: virtual void device_start() override; @@ -42,6 +43,7 @@ private: bool m_is_sound_timer; required_device m_timer; + void update_timer(void); uint8_t m_timer_preload_7_0; uint8_t m_timer_preload_15_8; -- cgit v1.2.3