mirror of
https://github.com/holub/mame
synced 2025-04-22 16:31:49 +03:00
vt1682.cpp - (plug & play) mostly fixed raster effects (#5937)
* some kind of rasters (nw) * fix raster timer, clean up (nw) * srcclean (nw)
This commit is contained in:
parent
bf22b6ba95
commit
cabb52c75b
@ -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));
|
||||
|
||||
|
@ -346,4 +346,4 @@ WRITE8_MEMBER(vrt_vt1682_alu_device::alu_oprand_6_div_w)
|
||||
m_alu_out[5] = 0x00;// machine().rand();
|
||||
|
||||
}
|
||||
}
|
||||
}
|
||||
|
@ -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);
|
||||
}
|
||||
}
|
||||
|
||||
void vrt_vt1682_timer_device::change_clock()
|
||||
{
|
||||
notify_clock_changed();
|
||||
}
|
||||
|
@ -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<timer_device> m_timer;
|
||||
|
||||
void update_timer(void);
|
||||
|
||||
uint8_t m_timer_preload_7_0;
|
||||
uint8_t m_timer_preload_15_8;
|
||||
|
Loading…
Reference in New Issue
Block a user