summaryrefslogtreecommitdiffstatshomepage
path: root/src
diff options
context:
space:
mode:
author David Haywood <28625134+DavidHaywood@users.noreply.github.com>2021-03-02 18:53:31 +0000
committer GitHub <noreply@github.com>2021-03-02 13:53:31 -0500
commit2746058dcf20b92e083c8d77051285663dee707f (patch)
treeecfc02d6f4b39e8035cc25b8371c4cfd290a3ee9 /src
parent323250bbee0b0cab43ccc4f698346e43f2a63074 (diff)
new WORKING machines (TV Board Games 6-in-1) (#7824)
new WORKING machines ------- TV Board Games 6-in-1: Silly 6 Pins, Candy Land, Hungry Hungry Hippos, Match 'em, Mixin' Pics, Checkers [Sean Riddle, David Haywood] TV Board Games 6-in-1: Simon, Battleship, Mouse Trap, Checkers, Link-a-Line, Roll Over [Sean Riddle, David Haywood]
Diffstat (limited to 'src')
-rw-r--r--src/mame/drivers/elan_ep3a19a.cpp372
-rw-r--r--src/mame/machine/elan_ep3a19asys.cpp117
-rw-r--r--src/mame/machine/elan_ep3a19asys.h38
-rw-r--r--src/mame/mame.lst4
-rw-r--r--src/mame/mess.flt1
-rw-r--r--src/mame/video/elan_eu3a05vid.cpp411
-rw-r--r--src/mame/video/elan_eu3a05vid.h9
7 files changed, 801 insertions, 151 deletions
diff --git a/src/mame/drivers/elan_ep3a19a.cpp b/src/mame/drivers/elan_ep3a19a.cpp
new file mode 100644
index 00000000000..8235955bd06
--- /dev/null
+++ b/src/mame/drivers/elan_ep3a19a.cpp
@@ -0,0 +1,372 @@
+// license:BSD-3-Clause
+// copyright-holders:David Haywood
+
+
+#include "emu.h"
+#include "cpu/m6502/m6502.h"
+//#include "cpu/m6502/m65c02.h"
+#include "emupal.h"
+#include "screen.h"
+#include "speaker.h"
+#include "machine/bankdev.h"
+#include "audio/elan_eu3a05.h"
+#include "machine/elan_eu3a05gpio.h"
+#include "machine/elan_ep3a19asys.h"
+#include "video/elan_eu3a05vid.h"
+
+class elan_ep3a19a_state : public driver_device
+{
+public:
+ elan_ep3a19a_state(const machine_config &mconfig, device_type type, const char *tag)
+ : driver_device(mconfig, type, tag),
+ m_sys(*this, "sys"),
+ m_gpio(*this, "gpio"),
+ m_maincpu(*this, "maincpu"),
+ m_screen(*this, "screen"),
+ m_ram(*this, "ram"),
+ m_sound(*this, "eu3a05sound"),
+ m_vid(*this, "vid"),
+ m_bank(*this, "bank"),
+ m_gfxdecode(*this, "gfxdecode"),
+ m_palette(*this, "palette")
+ { }
+
+ void elan_ep3a19a(machine_config &config);
+
+ void init_tvbg();
+
+protected:
+ // driver_device overrides
+ virtual void machine_start() override;
+ virtual void machine_reset() override;
+
+ required_device<elan_ep3a19asys_device> m_sys;
+ required_device<elan_eu3a05gpio_device> m_gpio;
+
+ required_device<cpu_device> m_maincpu;
+ required_device<screen_device> m_screen;
+
+private:
+ // screen updates
+ uint32_t screen_update(screen_device &screen, bitmap_ind16 &bitmap, const rectangle &cliprect);
+
+ INTERRUPT_GEN_MEMBER(interrupt);
+
+ // for callback
+ uint8_t read_full_space(offs_t offset);
+
+ void elan_ep3a19a_bank_map(address_map &map);
+ void elan_ep3a19a_map(address_map &map);
+
+ virtual void video_start() override;
+
+ required_shared_ptr<uint8_t> m_ram;
+ required_device<elan_eu3a05_sound_device> m_sound;
+ required_device<elan_eu3a05vid_device> m_vid;
+ required_device<address_map_bank_device> m_bank;
+ required_device<gfxdecode_device> m_gfxdecode;
+ required_device<palette_device> m_palette;
+
+ //DECLARE_WRITE_LINE_MEMBER(sound_end0) { m_sys->generate_custom_interrupt(2); }
+ //DECLARE_WRITE_LINE_MEMBER(sound_end1) { m_sys->generate_custom_interrupt(3); }
+ //DECLARE_WRITE_LINE_MEMBER(sound_end2) { m_sys->generate_custom_interrupt(4); }
+ //DECLARE_WRITE_LINE_MEMBER(sound_end3) { m_sys->generate_custom_interrupt(5); }
+ //DECLARE_WRITE_LINE_MEMBER(sound_end4) { m_sys->generate_custom_interrupt(6); }
+ //DECLARE_WRITE_LINE_MEMBER(sound_end5) { m_sys->generate_custom_interrupt(7); }
+
+ uint8_t nmi_vector_r(offs_t offset)
+ {
+ return 0xffd4 >> (offset * 8);
+ }
+
+};
+
+void elan_ep3a19a_state::video_start()
+{
+}
+
+uint32_t elan_ep3a19a_state::screen_update(screen_device& screen, bitmap_ind16& bitmap, const rectangle& cliprect)
+{
+ return m_vid->screen_update(screen, bitmap, cliprect);
+}
+
+// sound callback
+uint8_t elan_ep3a19a_state::read_full_space(offs_t offset)
+{
+ address_space& fullbankspace = m_bank->space(AS_PROGRAM);
+ return fullbankspace.read_byte(offset);
+}
+
+void elan_ep3a19a_state::elan_ep3a19a_map(address_map &map)
+{
+ // can the addresses move around?
+ map(0x0000, 0x3fff).ram().share("ram");
+ map(0x4800, 0x49ff).rw(m_vid, FUNC(elan_eu3a05commonvid_device::palette_r), FUNC(elan_eu3a05commonvid_device::palette_w));
+
+ map(0x5000, 0x5014).m(m_sys, FUNC(elan_ep3a19asys_device::map)); // including DMA controller
+ map(0x5020, 0x503f).m(m_vid, FUNC(elan_eu3a05vid_device::map));
+
+ // 504x GPIO area?
+ map(0x5040, 0x5046).rw(m_gpio, FUNC(elan_eu3a05gpio_device::gpio_r), FUNC(elan_eu3a05gpio_device::gpio_w));
+ // 5047
+ //map(0x5048, 0x504a).w(m_gpio, FUNC(elan_eu3a05gpio_device::gpio_unk_w));
+
+ // 506x unknown
+ //map(0x5060, 0x506d).ram(); // read/written by tetris (ADC?)
+
+ // 508x sound
+ map(0x5080, 0x50bf).m(m_sound, FUNC(elan_eu3a05_sound_device::map));
+
+ //map(0x5000, 0x50ff).ram();
+ map(0x6000, 0xdfff).m(m_bank, FUNC(address_map_bank_device::amap8));
+
+ map(0xe000, 0xffff).rom().region("maincpu", 0x0000);
+ // not sure how these work, might be a modified 6502 core instead.
+ //map(0xfffa, 0xfffb).r(m_sys, FUNC(elan_eu3a05commonsys_device::nmi_vector_r)); // custom vectors handled with NMI for now
+ map(0xfffa, 0xfffb).r(FUNC(elan_ep3a19a_state::nmi_vector_r)); // custom vectors handled with NMI for now
+
+ //map(0xfffe, 0xffff).r(m_sys, FUNC(elan_eu3a05commonsys_device::irq_vector_r)); // allow normal IRQ for brk
+}
+
+void elan_ep3a19a_state::elan_ep3a19a_bank_map(address_map &map)
+{
+ map(0x000000, 0x3fffff).mirror(0xc00000).noprw();
+ map(0x000000, 0x3fffff).mirror(0xc00000).rom().region("maincpu", 0);
+}
+
+
+static INPUT_PORTS_START( elan_ep3a19a )
+ PORT_START("IN0")
+ PORT_DIPNAME( 0x0001, 0x0001, "IN0" )
+ PORT_DIPSETTING( 0x0001, DEF_STR( Off ) )
+ PORT_DIPSETTING( 0x0000, DEF_STR( On ) )
+ PORT_DIPNAME( 0x0002, 0x0002, DEF_STR( Unknown ) )
+ PORT_DIPSETTING( 0x0002, DEF_STR( Off ) )
+ PORT_DIPSETTING( 0x0000, DEF_STR( On ) )
+ PORT_DIPNAME( 0x0004, 0x0004, DEF_STR( Unknown ) )
+ PORT_DIPSETTING( 0x0004, DEF_STR( Off ) )
+ PORT_DIPSETTING( 0x0000, DEF_STR( On ) )
+ PORT_DIPNAME( 0x0008, 0x0008, DEF_STR( Unknown ) )
+ PORT_DIPSETTING( 0x0008, DEF_STR( Off ) )
+ PORT_DIPSETTING( 0x0000, DEF_STR( On ) )
+ PORT_DIPNAME( 0x0010, 0x0010, DEF_STR( Unknown ) )
+ PORT_DIPSETTING( 0x0010, DEF_STR( Off ) )
+ PORT_DIPSETTING( 0x0000, DEF_STR( On ) )
+ PORT_DIPNAME( 0x0020, 0x0020, DEF_STR( Unknown ) )
+ PORT_DIPSETTING( 0x0020, DEF_STR( Off ) )
+ PORT_DIPSETTING( 0x0000, DEF_STR( On ) )
+ PORT_DIPNAME( 0x0040, 0x0040, DEF_STR( Unknown ) )
+ PORT_DIPSETTING( 0x0040, DEF_STR( Off ) )
+ PORT_DIPSETTING( 0x0000, DEF_STR( On ) )
+ PORT_DIPNAME( 0x0080, 0x0080, DEF_STR( Unknown ) )
+ PORT_DIPSETTING( 0x0080, DEF_STR( Off ) )
+ PORT_DIPSETTING( 0x0000, DEF_STR( On ) )
+
+ PORT_START("IN1")
+ PORT_DIPNAME( 0x0001, 0x0001, "IN1" )
+ PORT_DIPSETTING( 0x0001, DEF_STR( Off ) )
+ PORT_DIPSETTING( 0x0000, DEF_STR( On ) )
+ PORT_DIPNAME( 0x0002, 0x0002, DEF_STR( Unknown ) )
+ PORT_DIPSETTING( 0x0002, DEF_STR( Off ) )
+ PORT_DIPSETTING( 0x0000, DEF_STR( On ) )
+ PORT_DIPNAME( 0x0004, 0x0004, DEF_STR( Unknown ) )
+ PORT_DIPSETTING( 0x0004, DEF_STR( Off ) )
+ PORT_DIPSETTING( 0x0000, DEF_STR( On ) )
+ PORT_DIPNAME( 0x0008, 0x0008, DEF_STR( Unknown ) )
+ PORT_DIPSETTING( 0x0008, DEF_STR( Off ) )
+ PORT_DIPSETTING( 0x0000, DEF_STR( On ) )
+ PORT_DIPNAME( 0x0010, 0x0010, DEF_STR( Unknown ) )
+ PORT_DIPSETTING( 0x0010, DEF_STR( Off ) )
+ PORT_DIPSETTING( 0x0000, DEF_STR( On ) )
+ PORT_DIPNAME( 0x0020, 0x0020, DEF_STR( Unknown ) )
+ PORT_DIPSETTING( 0x0020, DEF_STR( Off ) )
+ PORT_DIPSETTING( 0x0000, DEF_STR( On ) )
+ PORT_DIPNAME( 0x0040, 0x0040, DEF_STR( Unknown ) )
+ PORT_DIPSETTING( 0x0040, DEF_STR( Off ) )
+ PORT_DIPSETTING( 0x0000, DEF_STR( On ) )
+ PORT_DIPNAME( 0x0080, 0x0080, DEF_STR( Unknown ) )
+ PORT_DIPSETTING( 0x0080, DEF_STR( Off ) )
+ PORT_DIPSETTING( 0x0000, DEF_STR( On ) )
+
+ PORT_START("IN2")
+ PORT_BIT( 0x01, IP_ACTIVE_LOW, IPT_JOYSTICK_UP )
+ PORT_BIT( 0x02, IP_ACTIVE_LOW, IPT_JOYSTICK_DOWN )
+ PORT_BIT( 0x04, IP_ACTIVE_LOW, IPT_JOYSTICK_LEFT )
+ PORT_BIT( 0x08, IP_ACTIVE_LOW, IPT_JOYSTICK_RIGHT )
+ PORT_BIT( 0x10, IP_ACTIVE_LOW, IPT_BUTTON1 )
+ PORT_DIPNAME( 0x0020, 0x0020, "IN2" )
+ PORT_DIPSETTING( 0x0020, DEF_STR( Off ) )
+ PORT_DIPSETTING( 0x0000, DEF_STR( On ) )
+ PORT_DIPNAME( 0x0040, 0x0040, DEF_STR( Unknown ) )
+ PORT_DIPSETTING( 0x0040, DEF_STR( Off ) )
+ PORT_DIPSETTING( 0x0000, DEF_STR( On ) )
+ PORT_DIPNAME( 0x0080, 0x0080, DEF_STR( Unknown ) )
+ PORT_DIPSETTING( 0x0080, DEF_STR( Off ) )
+ PORT_DIPSETTING( 0x0000, DEF_STR( On ) )
+
+INPUT_PORTS_END
+
+
+void elan_ep3a19a_state::machine_start()
+{
+}
+
+void elan_ep3a19a_state::machine_reset()
+{
+ m_maincpu->set_state_int(M6502_S, 0x1ff);
+}
+
+static const gfx_layout helper_4bpp_8_layout =
+{
+ 8,1,
+ RGN_FRAC(1,1),
+ 4,
+ { 0,1,2,3 },
+ { STEP8(0,4) },
+ { 0 },
+ 8 * 4
+};
+
+static const gfx_layout helper_8bpp_8_layout =
+{
+ 8,1,
+ RGN_FRAC(1,1),
+ 8,
+ { 0,1,2,3,4,5,6,7 },
+ { STEP8(0,8) },
+ { 0 },
+ 8 * 8
+};
+
+// these are fake just to make looking at the texture pages easier
+static const uint32_t texlayout_xoffset_8bpp[256] = { STEP256(0,8) };
+static const uint32_t texlayout_yoffset_8bpp[256] = { STEP256(0,256*8) };
+static const gfx_layout texture_helper_8bpp_layout =
+{
+ 256, 256,
+ RGN_FRAC(1,1),
+ 8,
+ { 0,1,2,3,4,5,6,7 },
+ EXTENDED_XOFFS,
+ EXTENDED_YOFFS,
+ 256*256*8,
+ texlayout_xoffset_8bpp,
+ texlayout_yoffset_8bpp
+};
+
+static const uint32_t texlayout_xoffset_4bpp[256] = { STEP256(0,4) };
+static const uint32_t texlayout_yoffset_4bpp[256] = { STEP256(0,256*4) };
+static const gfx_layout texture_helper_4bpp_layout =
+{
+ 256, 256,
+ RGN_FRAC(1,1),
+ 4,
+ { 0,1,2,3 },
+ EXTENDED_XOFFS,
+ EXTENDED_YOFFS,
+ 256*256*4,
+ texlayout_xoffset_4bpp,
+ texlayout_yoffset_4bpp
+};
+
+static GFXDECODE_START( gfx_elan_eu3a05_fake )
+ GFXDECODE_ENTRY( "maincpu", 0, helper_4bpp_8_layout, 0x0, 1 )
+ GFXDECODE_ENTRY( "maincpu", 0, texture_helper_4bpp_layout, 0x0, 1 )
+ GFXDECODE_ENTRY( "maincpu", 0, helper_8bpp_8_layout, 0x0, 1 )
+ GFXDECODE_ENTRY( "maincpu", 0, texture_helper_8bpp_layout, 0x0, 1 )
+GFXDECODE_END
+
+INTERRUPT_GEN_MEMBER(elan_ep3a19a_state::interrupt)
+{
+ //m_sys->generate_custom_interrupt(9);
+ m_maincpu->pulse_input_line(INPUT_LINE_NMI, attotime::zero);
+}
+
+void elan_ep3a19a_state::elan_ep3a19a(machine_config &config)
+{
+ /* basic machine hardware */
+ M6502(config, m_maincpu, XTAL(21'477'272)/8);
+ m_maincpu->set_addrmap(AS_PROGRAM, &elan_ep3a19a_state::elan_ep3a19a_map);
+ m_maincpu->set_vblank_int("screen", FUNC(elan_ep3a19a_state::interrupt));
+
+ ADDRESS_MAP_BANK(config, "bank").set_map(&elan_ep3a19a_state::elan_ep3a19a_bank_map).set_options(ENDIANNESS_LITTLE, 8, 24, 0x8000);
+
+ PALETTE(config, m_palette).set_entries(256);
+
+ SCREEN(config, m_screen, SCREEN_TYPE_RASTER);
+ m_screen->set_refresh_hz(60);
+ m_screen->set_vblank_time(ATTOSECONDS_IN_USEC(2500));
+ m_screen->set_screen_update(FUNC(elan_ep3a19a_state::screen_update));
+ m_screen->set_size(32*8, 32*8);
+ m_screen->set_visarea(0*8, 32*8-1, 0*8, 28*8-1);
+ m_screen->set_palette(m_palette);
+
+ GFXDECODE(config, m_gfxdecode, m_palette, gfx_elan_eu3a05_fake);
+
+ ELAN_EU3A05_GPIO(config, m_gpio, 0);
+ m_gpio->read_0_callback().set_ioport("IN0");
+ m_gpio->read_1_callback().set_ioport("IN1");
+ m_gpio->read_2_callback().set_ioport("IN2");
+
+ ELAN_EP3A19A_SYS(config, m_sys, 0);
+ m_sys->set_cpu("maincpu");
+ m_sys->set_addrbank("bank");
+
+ ELAN_EU3A05_VID(config, m_vid, 0);
+ m_vid->set_cpu("maincpu");
+ m_vid->set_addrbank("bank");
+ m_vid->set_palette("palette");
+ m_vid->set_entries(256);
+ m_vid->set_is_pvmilfin();
+ m_vid->set_use_spritepages();
+ m_vid->set_force_transpen_ff();
+ m_vid->set_force_basic_scroll();
+
+ /* sound hardware */
+ SPEAKER(config, "mono").front_center();
+
+
+ ELAN_EU3A05_SOUND(config, m_sound, 8000);
+ m_sound->space_read_callback().set(FUNC(elan_ep3a19a_state::read_full_space));
+ m_sound->add_route(ALL_OUTPUTS, "mono", 1.0);
+
+ /*
+ m_sound->sound_end_cb<0>().set(FUNC(elan_ep3a19a_state::sound_end0));
+ m_sound->sound_end_cb<1>().set(FUNC(elan_ep3a19a_state::sound_end1));
+ m_sound->sound_end_cb<2>().set(FUNC(elan_ep3a19a_state::sound_end2));
+ m_sound->sound_end_cb<3>().set(FUNC(elan_ep3a19a_state::sound_end3));
+ m_sound->sound_end_cb<4>().set(FUNC(elan_ep3a19a_state::sound_end4));
+ m_sound->sound_end_cb<5>().set(FUNC(elan_ep3a19a_state::sound_end5));
+ */
+}
+
+ROM_START( tvbg6a )
+ ROM_REGION( 0x400000, "maincpu", ROMREGION_ERASE00 )
+ ROM_LOAD( "candyland_hhh_silly6.bin", 0x00000, 0x200000, CRC(8b16d725) SHA1(06af509d03df0e5a2ca502743797af9f4a5dc6f1) )
+ ROM_RELOAD(0x200000,0x200000)
+ROM_END
+
+ROM_START( tvbg6b )
+ ROM_REGION( 0x400000, "maincpu", ROMREGION_ERASE00 )
+ ROM_LOAD( "bship_simon_mousetrap.bin", 0x00000, 0x200000, CRC(b0627a98) SHA1(6157e26916bb415037a4d122d3075cbfb8e61dcf) )
+ ROM_RELOAD(0x200000,0x200000)
+ROM_END
+
+void elan_ep3a19a_state::init_tvbg()
+{
+ // is this swapping internal to the ep3a19a type ELAN, or external; ROM glob had standard TSOP pinout pads that were used for dumping.
+ uint8_t* ROM = memregion("maincpu")->base();
+ for (int i = 0; i < 0x400000; i++)
+ {
+ ROM[i] = bitswap<8>(ROM[i], 6, 5, 7, 0, 2, 3, 1, 4);
+ }
+}
+
+CONS( 2007, tvbg6a, 0, 0, elan_ep3a19a, elan_ep3a19a, elan_ep3a19a_state, init_tvbg, "NSI International / Mammoth Toys (Licensed by Hasbro)", "TV Board Games 6-in-1: Silly 6 Pins, Candy Land, Hungry Hungry Hippos, Match 'em, Mixin' Pics, Checkers", MACHINE_IMPERFECT_GRAPHICS | MACHINE_IMPERFECT_SOUND ) // https://www.youtube.com/watch?v=zajzQo47YYA
+CONS( 2007, tvbg6b, 0, 0, elan_ep3a19a, elan_ep3a19a, elan_ep3a19a_state, init_tvbg, "NSI International / Mammoth Toys (Licensed by Hasbro)", "TV Board Games 6-in-1: Simon, Battleship, Mouse Trap, Checkers, Link-a-Line, Roll Over", MACHINE_IMPERFECT_GRAPHICS | MACHINE_IMPERFECT_SOUND ) // https://www.youtube.com/watch?v=JbrR67kY8MI
+
+// TV Board Games 3-in-1: Silly 6 Pins, Hungry Hungry Hippos, Match 'em
+// TV Board Games 3-in-1: Simon, Battleship, Checkers https://www.youtube.com/watch?v=Q7nwKJfVavU
+// TV Board Games 3-in-1: Boggle, Connect 4, Roll Over https://www.youtube.com/watch?v=SoKKIKSDGhY
+
+// The back of the Silly 6 Pins 3-in-1 packaging suggests a Monopoly TV Board Game device was planned, but this does not appear to have been released.
diff --git a/src/mame/machine/elan_ep3a19asys.cpp b/src/mame/machine/elan_ep3a19asys.cpp
new file mode 100644
index 00000000000..dbe6f3f3017
--- /dev/null
+++ b/src/mame/machine/elan_ep3a19asys.cpp
@@ -0,0 +1,117 @@
+// license:BSD-3-Clause
+// copyright-holders:David Haywood
+
+#include "emu.h"
+#include "elan_ep3a19asys.h"
+
+// like EU3A05 but with the DMA at a lower address where the code bank register would usually be, and a single byte for bank register rather than 2 - any other changes?
+
+DEFINE_DEVICE_TYPE(ELAN_EP3A19A_SYS, elan_ep3a19asys_device, "elan_ep3a19asys", "Elan EP3A19A System")
+
+elan_ep3a19asys_device::elan_ep3a19asys_device(const machine_config &mconfig, const char *tag, device_t *owner, uint32_t clock) :
+ elan_eu3a05commonsys_device(mconfig, ELAN_EP3A19A_SYS, tag, owner, clock),
+ device_memory_interface(mconfig, *this),
+ m_space_config("regs", ENDIANNESS_NATIVE, 8, 5, 0, address_map_constructor(FUNC(elan_ep3a19asys_device::map), this))
+{
+}
+
+device_memory_interface::space_config_vector elan_ep3a19asys_device::memory_space_config() const
+{
+ return space_config_vector {
+ std::make_pair(0, &m_space_config)
+ };
+}
+
+
+void elan_ep3a19asys_device::rombank_w(offs_t offset, uint8_t data)
+{
+ m_rombank_lo = data;
+ m_bank->set_bank(m_rombank_lo);
+}
+
+uint8_t elan_ep3a19asys_device::rombank_r(offs_t offset)
+{
+ return m_rombank_lo;
+}
+
+
+void elan_ep3a19asys_device::map(address_map& map)
+{
+// elan_eu3a05commonsys_device::map(map); // 00 - 0e
+
+ map(0x0c, 0x0c).rw(FUNC(elan_ep3a19asys_device::rombank_r), FUNC(elan_ep3a19asys_device::rombank_w));
+
+ map(0x0d, 0x13).rw(FUNC(elan_ep3a19asys_device::dma_param_r), FUNC(elan_ep3a19asys_device::dma_param_w));
+ map(0x14, 0x14).rw(FUNC(elan_ep3a19asys_device::elan_eu3a05_dmatrg_r), FUNC(elan_ep3a19asys_device::elan_eu3a05_dmatrg_w));
+}
+
+void elan_ep3a19asys_device::device_start()
+{
+ elan_eu3a05commonsys_device::device_start();
+
+ save_item(NAME(m_dmaparams));
+}
+
+void elan_ep3a19asys_device::device_reset()
+{
+ elan_eu3a05commonsys_device::device_reset();
+
+ for (int i = 0; i < 7; i++)
+ m_dmaparams[i] = 0x00;
+}
+
+uint8_t elan_ep3a19asys_device::dma_param_r(offs_t offset)
+{
+ return m_dmaparams[offset];
+}
+
+void elan_ep3a19asys_device::dma_param_w(offs_t offset, uint8_t data)
+{
+ m_dmaparams[offset] = data;
+}
+
+
+uint8_t elan_ep3a19asys_device::elan_eu3a05_dmatrg_r()
+{
+ logerror("%s: elan_eu3a05_dmatrg_r (DMA operation state?)\n", machine().describe_context());
+ return 0x00;//m_dmatrg_data;
+}
+
+
+void elan_ep3a19asys_device::elan_eu3a05_dmatrg_w(uint8_t data)
+{
+ logerror("%s: elan_eu3a05_dmatrg_w (trigger DMA operation) %02x\n", machine().describe_context(), data);
+ //m_dmatrg_data = data;
+
+ address_space& fullbankspace = m_bank->space(AS_PROGRAM);
+ address_space& destspace = m_cpu->space(AS_PROGRAM);
+
+ if (data)
+ {
+ int src = (m_dmaparams[0]) | (m_dmaparams[1] << 8) | (m_dmaparams[2] << 16);
+ uint16_t dest = m_dmaparams[3] | (m_dmaparams[4] << 8);
+ uint16_t size = m_dmaparams[5] | (m_dmaparams[6] << 8);
+
+ logerror(" Doing %02x DMA %06x to %04x size %04x\n", data, src, dest, size);
+
+ for (int i = 0; i < size; i++)
+ {
+ uint8_t dat = fullbankspace.read_byte(src);
+ src++;
+ destspace.write_byte(dest, dat);
+ dest++;
+ }
+
+ m_dmaparams[0] = src & 0xff;
+ m_dmaparams[1] = (src >> 8) & 0xff;
+ m_dmaparams[2] = (src >> 16) & 0xff;
+ m_dmaparams[3] = dest & 0xff;
+ m_dmaparams[4] = (dest >> 8) & 0xff;
+
+ m_dmaparams[5] = 0;
+ m_dmaparams[6] = 0;
+ }
+}
+
+
+
diff --git a/src/mame/machine/elan_ep3a19asys.h b/src/mame/machine/elan_ep3a19asys.h
new file mode 100644
index 00000000000..25789370ec2
--- /dev/null
+++ b/src/mame/machine/elan_ep3a19asys.h
@@ -0,0 +1,38 @@
+// license:BSD-3-Clause
+// copyright-holders:David Haywood
+
+#ifndef MAME_MACHINE_ELAN_EP3A19ASYS_H
+#define MAME_MACHINE_ELAN_EP3A19ASYS_H
+
+#include "elan_eu3a05commonsys.h"
+
+class elan_ep3a19asys_device : public elan_eu3a05commonsys_device, public device_memory_interface
+{
+public:
+ elan_ep3a19asys_device(const machine_config &mconfig, const char *tag, device_t *owner, uint32_t clock);
+
+ uint8_t elan_eu3a05_dmatrg_r();
+ void elan_eu3a05_dmatrg_w(uint8_t data);
+
+ uint8_t dma_param_r(offs_t offset);
+ void dma_param_w(offs_t offset, uint8_t data);
+
+ virtual void map(address_map& map) override;
+
+protected:
+ // device-level overrides
+ virtual void device_start() override;
+ virtual void device_reset() override;
+ virtual space_config_vector memory_space_config() const override;
+
+ void rombank_w(offs_t offset, uint8_t data);
+ uint8_t rombank_r(offs_t offset);
+
+private:
+ const address_space_config m_space_config;
+ uint8_t m_dmaparams[7];
+};
+
+DECLARE_DEVICE_TYPE(ELAN_EP3A19A_SYS, elan_ep3a19asys_device)
+
+#endif // MAME_MACHINE_ELAN_EP3A19ASYS_H
diff --git a/src/mame/mame.lst b/src/mame/mame.lst
index 198d0f83574..3f2f709294f 100644
--- a/src/mame/mame.lst
+++ b/src/mame/mame.lst
@@ -13105,6 +13105,10 @@ egghunt // (c) 1995 Invi Image
einst256 //
einstein //
+@source:elan_ep3a19a.cpp
+tvbg6a
+tvbg6b
+
@source:elan_eu3a14.cpp
rad_gtg
rad_rsg
diff --git a/src/mame/mess.flt b/src/mame/mess.flt
index 2a869da53e9..d1c75fa1305 100644
--- a/src/mame/mess.flt
+++ b/src/mame/mess.flt
@@ -259,6 +259,7 @@ ec65.cpp
ec7915.cpp
einstein.cpp
eispc.cpp
+elan_ep3a19a.cpp
elan_eu3a05.cpp
elan_eu3a14.cpp
electron.cpp
diff --git a/src/mame/video/elan_eu3a05vid.cpp b/src/mame/video/elan_eu3a05vid.cpp
index 5ea11e30bd9..057df0f9937 100644
--- a/src/mame/video/elan_eu3a05vid.cpp
+++ b/src/mame/video/elan_eu3a05vid.cpp
@@ -17,7 +17,9 @@ elan_eu3a05vid_device::elan_eu3a05vid_device(const machine_config &mconfig, cons
m_bytes_per_tile_entry(4),
m_vrambase(0x600),
m_spritebase(0x3e00),
- m_use_spritepages(false)
+ m_use_spritepages(false),
+ m_force_transpen_ff(false),
+ m_force_basic_scroll(false)
{
}
@@ -126,7 +128,7 @@ uint8_t elan_eu3a05vid_device::read_vram(int offset)
that space (Tetris seems to rely on mirroring? as it sets all addresses up for the lower 1MB instead)
*/
-void elan_eu3a05vid_device::draw_sprites(screen_device &screen, bitmap_ind16 &bitmap, const rectangle &cliprect)
+void elan_eu3a05vid_device::draw_sprites(screen_device &screen, bitmap_ind16 &bitmap, bitmap_ind8 &priority_bitmap, const rectangle &cliprect)
{
address_space& fullbankspace = m_bank->space(AS_PROGRAM);
@@ -139,11 +141,11 @@ void elan_eu3a05vid_device::draw_sprites(screen_device &screen, bitmap_ind16 &bi
XX = texture x start
YY = texture y start
bb = sometimes set in invaders
- AA = same as attr on tiles (colour / priority?)
+ AA = same as attr on tiles (cccc pppp) (c = colour / p = priority?)
aa = same as unk2 on tiles? ( --pp ---- )
- p = page
+ p = page (some hardware types only? or selectable meaning)
FF = flags ( e-dD fFsS )
e = enable
@@ -156,7 +158,10 @@ void elan_eu3a05vid_device::draw_sprites(screen_device &screen, bitmap_ind16 &bi
*/
- for (int i = 0; i < 512; i += 8)
+// later in list with AA == 0f aa == 07 takes priority over earlier in the list with AA == 0f and aa == 07
+// later in the list with AA == 0e and aa == 17 is under AA == 0f aa == and 07
+
+ for (int i = 512-8; i >=0; i -= 8)
{
uint8_t x = read_spriteram(i + 2);
uint8_t y = read_spriteram(i + 1);
@@ -188,7 +193,8 @@ void elan_eu3a05vid_device::draw_sprites(screen_device &screen, bitmap_ind16 &bi
const int doubleX = (flags & 0x10)>>4;
const int doubleY = (flags & 0x20)>>5;
- //int priority = attr & 0x0f;
+ int priority = (attr & 0x0f)^0xf;
+
int colour = attr & 0xf0;
// ? game select has this set to 0xff, but clearly doesn't want the palette to change!
@@ -204,7 +210,7 @@ void elan_eu3a05vid_device::draw_sprites(screen_device &screen, bitmap_ind16 &bi
where the transpen needs to be 0x00 and Space Invaders has it set to 0x04
it could be a global register rather than something in the spritelist?
*/
- if ((attr == 0xff) && (unk2 == 0xff))
+ if (((attr == 0xff) && (unk2 == 0xff)) || m_force_transpen_ff)
transpen = 0xff;
@@ -242,14 +248,19 @@ void elan_eu3a05vid_device::draw_sprites(screen_device &screen, bitmap_ind16 &bi
for (int yy = 0; yy < sizey; yy++)
{
uint16_t* row;
+ uint8_t* rowpri;
if (flags & 0x08) // guess flipy
{
- row = &bitmap.pix((y + (sizey - 1 - yy)) & 0xff);
+ int drawypos = (y + (sizey - 1 - yy)) & 0xff;
+ row = &bitmap.pix(drawypos);
+ rowpri = &priority_bitmap.pix(drawypos);
}
else
{
- row = &bitmap.pix((y + yy) & 0xff);
+ int drawypos = (y + yy) & 0xff;
+ row = &bitmap.pix(drawypos);
+ rowpri = &priority_bitmap.pix(drawypos);
}
for (int xx = 0; xx < sizex; xx++)
@@ -272,11 +283,23 @@ void elan_eu3a05vid_device::draw_sprites(screen_device &screen, bitmap_ind16 &bi
{
if (flags & 0x04) // flipx
{
- row[(x + (sizex - 1 - xx)) & 0xff] = (pix + ((colour & 0x70) << 1)) & 0xff;
+ int xdrawpos = (x + (sizex - 1 - xx)) & 0xff;
+
+ if (rowpri[xdrawpos] > priority)
+ {
+ rowpri[xdrawpos] = priority;
+ row[xdrawpos] = (pix + ((colour & 0x70) << 1)) & 0xff;
+ }
}
else
{
- row[(x + xx) & 0xff] = (pix + ((colour & 0x70) << 1)) & 0xff;
+ int xdrawpos = (x + xx) & 0xff;
+
+ if (rowpri[xdrawpos] > priority)
+ {
+ rowpri[xdrawpos] = priority;
+ row[xdrawpos] = (pix + ((colour & 0x70) << 1)) & 0xff;
+ }
}
}
}
@@ -317,183 +340,269 @@ bool elan_eu3a05vid_device::get_tile_data(int base, int drawpri, int& tile, int
return true;
}
-void elan_eu3a05vid_device::draw_tilemaps(screen_device& screen, bitmap_ind16& bitmap, const rectangle& cliprect, int drawpri)
+
+
+void elan_eu3a05vid_device::draw_tilemaps_tileline(int drawpri, int tile, int attr, int unk2, int tilexsize, int i, int xpos, uint16_t* row)
{
- /*
- this doesn't handle 8x8 4bpp (not used by anything yet)
+ address_space& fullbankspace = m_bank->space(AS_PROGRAM);
+ int colour = attr & 0xf0;
+
+ /* 'tiles' are organized / extracted from 'texture' lines that form a 'page' the length of the rom
+ each texture line in 8bpp mode is 256 bytes
+ each texture line in 4bpp mode is 128 bytes
+ in 8x8 mode these pages are 32 tiles wide
+ in 16x16 mode these pages are 16 tiles wide
+ tiles can start on any line
+
+ it is unclear what the behavior is if the tile starts at the far edge of a line (wrap around on line?)
+
+ this is eu3a05 specific, eu3a14 uses a more traditional approach
*/
- int scroll = get_scroll(1);
- address_space& fullbankspace = m_bank->space(AS_PROGRAM);
+ const int tilespersrcline = 256 / tilexsize;
+ const int tilespersrcline_mask = tilespersrcline - 1;
+
+ tile = (tile & tilespersrcline_mask) + ((tile & ~tilespersrcline_mask) * tilexsize);
- // Phoenix scrolling actually skips a pixel, jumping from 0x001 to 0x1bf, scroll 0x000 isn't used, maybe it has other meanings?
+ if (!(m_vidctrl & 0x20)) // 8bpp
+ tile <<= 1;
- int totalyrow;
- int totalxcol;
- int mapyrowsbase;
- int tileysize;
- int tilexsize;
- int startrow;
+ if (!(m_vidctrl & 0x40)) // 8*8 tiles
+ tile >>= 1;
- if (m_vidctrl & 0x40) // 16x16 tiles
+ tile += ((m_tile_gfxbase_lo_data | m_tile_gfxbase_hi_data << 8) << 5);
+
+
+ if (m_vidctrl & 0x20) // 4bpp
{
- totalyrow = 16;
- totalxcol = 16;
- mapyrowsbase = 14;
- tileysize = 16;
- tilexsize = 16;
- startrow = (scroll >> 4) & 0x1f;
+ for (int xx = 0; xx < tilexsize; xx += 2)
+ {
+ int realaddr = ((tile + i * 16) << 3) + (xx >> 1);
+ uint8_t pix = fullbankspace.read_byte(realaddr);
+
+ int drawxpos;
+
+ drawxpos = xpos + xx + 0;
+ if ((drawxpos >= 0) && (drawxpos < 256))
+ row[drawxpos] = ((pix & 0xf0) >> 4) + colour;
+
+ drawxpos = xpos + xx + 1;
+ if ((drawxpos >= 0) && (drawxpos < 256))
+ row[drawxpos] = ((pix & 0x0f) >> 0) + colour;
+ }
}
- else
+ else // 8bpp
+ {
+ for (int xx = 0; xx < tilexsize; xx++)
+ {
+ int realaddr = ((tile + i * 32) << 3) + xx;
+ uint8_t pix = fullbankspace.read_byte(realaddr);
+
+ int drawxpos = xpos + xx;
+ if ((drawxpos >= 0) && (drawxpos < 256))
+ row[drawxpos] = (pix + ((colour & 0x70) << 1)) & 0xff;
+ }
+ }
+}
+
+uint16_t elan_eu3a05vid_device::get_tilemapindex_from_xy(uint16_t x, uint16_t y)
+{
+ // for mousetrap and candyland the pages in RAM (16x16 tile mode, 4 pages) are
+ // top left
+ // top right
+ // bottom left
+ // bottom right
+
+ // for airblaster joystick 3d stagess the pages in RAM (8x8 tile mode, 2 pages) are
+ // left
+ // right
+
+ // for airblaster joystick scrolling stages (8x8 tile mode, 2 pages)
+ // top
+ // bottom
+
+ uint16_t tilemapsizey;
+ uint16_t tilemapsizex;
+ uint16_t pagesizey, pagesizex;
+
+ pagesizey = 14; pagesizex = 16;
+
+ switch (m_vidctrl & 0x03)
{
- totalyrow = 32;
- totalxcol = 32;
- mapyrowsbase = 28;
- tileysize = 8;
- tilexsize = 8;
- startrow = (scroll >> 3) & 0x3f;
+ case 0x00: tilemapsizey = 14 * 2; tilemapsizex = 16 * 2; break; // double height & double width
+ case 0x02: tilemapsizey = 14 * 2; tilemapsizex = 16; break; // double height
+ case 0x01: tilemapsizey = 14; tilemapsizex = 16 * 2; break; // double width
+ case 0x03: tilemapsizey = 14; tilemapsizex = 16; break; // normal
}
- for (int y = 0; y < totalyrow; y++)
+ if (!(m_vidctrl & 0x40)) // 16x16 tiles
{
- for (int x = 0; x < totalxcol * 2; x++)
- {
- int realstartrow = (startrow + y);
+ pagesizey <<= 1;
+ pagesizex <<= 1;
+ tilemapsizey <<= 1;
+ tilemapsizex <<= 1;
+ }
- int yrows;
+ while (y >= tilemapsizey)
+ y -= tilemapsizey;
- if (m_vidctrl & 0x01)
- yrows = mapyrowsbase;
- else
- yrows = mapyrowsbase * 2;
+ while (x >= tilemapsizex)
+ x -= tilemapsizex;
- if (realstartrow >= yrows)
- realstartrow -= yrows;
+ int index = 0;
+ int page = 0;
- // in double width & double height mode the page addressing needs adjusting
- if (!(m_vidctrl & 0x02))
+ switch (m_vidctrl & 0x03)
+ {
+ case 0x00: // double height & double width
+ if (y < pagesizey)
+ {
+ if (x < pagesizex)
{
- if (!(m_vidctrl & 0x01))
- {
- if (realstartrow >= (yrows / 2))
- {
- realstartrow += yrows / 2;
- }
- }
+ page = 0;
}
-
- for (int i = 0; i < tileysize; i++)
+ else
{
- int drawline = (y * tileysize) + i;
- drawline -= scroll & (tileysize - 1);
+ page = 1;
+ }
+ }
+ else
+ {
+ if (x < pagesizex)
+ {
+ page = 2;
+ }
+ else
+ {
+ page = 3;
+ }
+ }
+ break;
- if ((drawline >= 0) && (drawline < 256))
- {
- int scrollx;
+ case 0x02: // double height
+ if (y < pagesizey)
+ {
+ page = 0;
+ }
+ else
+ {
+ page = 1;
+ }
+ break;
- // split can be probably configured in more ways than this
- // exact enable conditions unclear
- if (drawline < m_splitpos[0])
- {
- scrollx = get_scroll(0);
- }
- else if (drawline < m_splitpos[1])
- {
- scrollx = get_scroll(2);
- }
- else
- {
- scrollx = get_scroll(3);
- }
+ case 0x01: // double width
+ if (x < pagesizex)
+ {
+ page = 0;
+ }
+ else
+ {
+ page = 1;
+ }
+ break;
- int base;
+ case 0x03:
+ page = 0;
+ break;
+ }
- if (m_vidctrl & 0x40) // 16x16 tiles
- {
- base = (((realstartrow + y) & 0x3f) * 8) + x;
- }
- else
- {
- base = (((realstartrow) & 0x7f) * totalxcol) + (x & (totalxcol - 1));
- }
+ while (y >= pagesizey)
+ y -= pagesizey;
- if (!(m_vidctrl & 0x02))
- {
- if (x & totalxcol)
- {
- base += totalxcol * mapyrowsbase;
- }
- }
+ while (x >= pagesizex)
+ x -= pagesizex;
- int tile, attr, unk2;
+ index = x + y * pagesizex;
+ index += page * pagesizey * pagesizex;
- if (!get_tile_data(base, drawpri, tile, attr, unk2))
- continue;
+ return index;
+}
- int colour = attr & 0xf0;
+void elan_eu3a05vid_device::draw_tilemaps(screen_device& screen, bitmap_ind16& bitmap, const rectangle& cliprect, int drawpri)
+{
+ /*
+ this doesn't handle 8x8 4bpp (not used by anything yet)
+ */
+ //popmessage("%02x: %04x %04x %04x %04x", m_vidctrl, get_scroll(0), get_scroll(1), get_scroll(2), get_scroll(3));
- /* 'tiles' are organized / extracted from 'texture' lines that form a 'page' the length of the rom
- each texture line in 8bpp mode is 256 bytes
- each texture line in 4bpp mode is 128 bytes
- in 8x8 mode these pages are 32 tiles wide
- in 16x16 mode these pages are 16 tiles wide
- tiles can start on any line
+ int scrolly = get_scroll(1);
- it is unclear what the behavior is if the tile starts at the far edge of a line (wrap around on line?)
+ for (int screenline = 0; screenline < 224; screenline++)
+ {
+ int scrollx;
+ int coursescrollx;
+ int finescrollx;
+ int realline = screenline + scrolly;
+
+ // split can be probably configured in more ways than this
+ // exact enable conditions unclear
+ // this logic is needed for Air Blaster Joystick
+ if (screenline < m_splitpos[0])
+ {
+ scrollx = get_scroll(0);
+ }
+ else if (screenline < m_splitpos[1])
+ {
+ scrollx = get_scroll(2);
+ }
+ else
+ {
+ scrollx = get_scroll(3);
+ }
- this is eu3a05 specific, eu3a14 uses a more traditional approach
- */
+ // Candy Land and Mouse Trap in the TV Board Games units don't like the above logic, so force them to just use the
+ // first scroll register for now, there must be more complex enable conditions for the above
+ if (m_force_basic_scroll)
+ scrollx = get_scroll(0);
- const int tilespersrcline = 256 / tilexsize;
- const int tilespersrcline_mask = tilespersrcline - 1;
+ uint16_t* row = &bitmap.pix(screenline);
- tile = (tile & tilespersrcline_mask) + ((tile & ~tilespersrcline_mask) * tilexsize);
+ int xtiles;
+ int xtilesize;
+ if (m_vidctrl & 0x40) // 16x16 tiles
+ {
+ xtiles = 16; // number of tilemap entries per row
+ xtilesize = 16; // width of tile
+ coursescrollx = scrollx >> 4;
+ finescrollx = scrollx & 0xf;
+ }
+ else
+ {
+ xtiles = 32;
+ xtilesize = 8;
+ coursescrollx = scrollx >> 3;
+ finescrollx = scrollx & 0x7;
+ }
- if (!(m_vidctrl & 0x20)) // 8bpp
- tile <<= 1;
+ for (int xtile = 0; xtile <= xtiles; xtile++)
+ {
- if (!(m_vidctrl & 0x40)) // 8*8 tiles
- tile >>= 1;
+ int realxtile = xtile + coursescrollx;
- tile += ((m_tile_gfxbase_lo_data | m_tile_gfxbase_hi_data << 8) << 5);
+ int tilemaprow;
+ int tileline;
- uint16_t *const row = &bitmap.pix(drawline);
+ if (m_vidctrl & 0x40) // 16x16 tiles
+ {
+ tilemaprow = realline >> 4;
+ tileline = realline & 0xf;
+ }
+ else
+ {
+ tilemaprow = realline >> 3;
+ tileline = realline & 0x7;
+ }
- if (m_vidctrl & 0x20) // 4bpp
- {
- for (int xx = 0; xx < tilexsize; xx += 2)
- {
- int realaddr = ((tile + i * 16) << 3) + (xx >> 1);
- uint8_t pix = fullbankspace.read_byte(realaddr);
+ int tilemap_entry_index = get_tilemapindex_from_xy(realxtile, tilemaprow);
- int drawxpos;
+ int tile, attr, unk2;
- drawxpos = x * tilexsize + xx + 0 - scrollx;
- drawxpos &= 0x1ff;
- if ((drawxpos >= 0) && (drawxpos < 256))
- row[drawxpos] = ((pix & 0xf0) >> 4) + colour;
+ if (!get_tile_data(tilemap_entry_index, drawpri, tile, attr, unk2))
+ continue;
- drawxpos = x * tilexsize + xx + 1 - scrollx;
- drawxpos &= 0x1ff;
- if ((drawxpos >= 0) && (drawxpos < 256))
- row[drawxpos] = ((pix & 0x0f) >> 0) + colour;
- }
- }
- else // 8bpp
- {
- for (int xx = 0; xx < tilexsize; xx++)
- {
- int realaddr = ((tile + i * 32) << 3) + xx;
- uint8_t pix = fullbankspace.read_byte(realaddr);
+ int xpos = xtile * xtilesize - finescrollx;
+ draw_tilemaps_tileline(drawpri, tile, attr, unk2, xtilesize, tileline, xpos, row);
- int drawxpos = x * tilexsize + xx - scrollx;
- drawxpos &= 0x1ff;
- if ((drawxpos >= 0) && (drawxpos < 256))
- row[drawxpos] = (pix + ((colour & 0x70) << 1)) & 0xff;
- }
- }
- }
- }
}
}
}
@@ -501,10 +610,11 @@ void elan_eu3a05vid_device::draw_tilemaps(screen_device& screen, bitmap_ind16& b
uint32_t elan_eu3a05vid_device::screen_update(screen_device &screen, bitmap_ind16 &bitmap, const rectangle &cliprect)
{
bitmap.fill(0, cliprect);
+ screen.priority().fill(0xff, cliprect);
- draw_tilemaps(screen,bitmap,cliprect,0);
- draw_sprites(screen,bitmap,cliprect);
- draw_tilemaps(screen,bitmap,cliprect,1);
+ draw_tilemaps(screen,bitmap,cliprect,0); // 'low priority'
+ draw_sprites(screen,bitmap,screen.priority(),cliprect);
+ draw_tilemaps(screen,bitmap,cliprect,1); // 'high priority'
return 0;
}
@@ -572,6 +682,7 @@ uint8_t elan_eu3a05vid_device::tile_scroll_r(offs_t offset)
void elan_eu3a05vid_device::tile_scroll_w(offs_t offset, uint8_t data)
{
+ //logerror("tile_scroll_w %02x %02x\n", offset, data);
m_tile_scroll[offset] = data;
}
diff --git a/src/mame/video/elan_eu3a05vid.h b/src/mame/video/elan_eu3a05vid.h
index 08ccd121cb4..56028158bb6 100644
--- a/src/mame/video/elan_eu3a05vid.h
+++ b/src/mame/video/elan_eu3a05vid.h
@@ -7,6 +7,7 @@
#include "elan_eu3a05commonvid.h"
#include "cpu/m6502/m6502.h"
#include "machine/bankdev.h"
+#include "screen.h"
class elan_eu3a05vid_device : public elan_eu3a05commonvid_device, public device_memory_interface
{
@@ -23,6 +24,8 @@ public:
void set_is_sudoku();
void set_is_pvmilfin();
void set_use_spritepages() { m_use_spritepages = true; };
+ void set_force_transpen_ff() { m_force_transpen_ff = true; };
+ void set_force_basic_scroll() { m_force_basic_scroll = true; };
protected:
// device-level overrides
@@ -51,7 +54,9 @@ private:
bool get_tile_data(int base, int drawpri, int& tile, int &attr, int &unk2);
void draw_tilemaps(screen_device &screen, bitmap_ind16 &bitmap, const rectangle &cliprect, int drawpri);
- void draw_sprites(screen_device &screen, bitmap_ind16 &bitmap, const rectangle &cliprect);
+ void draw_sprites(screen_device &screen, bitmap_ind16 &bitmap, bitmap_ind8 &priority_bitmap, const rectangle &cliprect);
+ void draw_tilemaps_tileline(int drawpri, int tile, int attr, int unk2, int tilexsize, int tileline, int xpos, uint16_t *row);
+ uint16_t get_tilemapindex_from_xy(uint16_t x, uint16_t y);
uint8_t read_spriteram(int offset);
uint8_t read_vram(int offset);
@@ -84,6 +89,8 @@ private:
int m_vrambase;
int m_spritebase;
bool m_use_spritepages;
+ bool m_force_transpen_ff;
+ bool m_force_basic_scroll;
};
DECLARE_DEVICE_TYPE(ELAN_EU3A05_VID, elan_eu3a05vid_device)