mirror of
https://github.com/holub/mame
synced 2025-04-16 21:44:32 +03:00
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]
This commit is contained in:
parent
323250bbee
commit
2746058dcf
@ -4066,6 +4066,7 @@ files {
|
||||
|
||||
createMESSProjects(_target, _subtarget, "tvgames")
|
||||
files {
|
||||
MAME_DIR .. "src/mame/drivers/elan_ep3a19a.cpp",
|
||||
MAME_DIR .. "src/mame/drivers/elan_eu3a14.cpp",
|
||||
MAME_DIR .. "src/mame/drivers/elan_eu3a05.cpp",
|
||||
MAME_DIR .. "src/mame/audio/elan_eu3a05.cpp",
|
||||
@ -4074,6 +4075,8 @@ files {
|
||||
MAME_DIR .. "src/mame/machine/elan_eu3a05gpio.h",
|
||||
MAME_DIR .. "src/mame/machine/elan_eu3a05commonsys.cpp",
|
||||
MAME_DIR .. "src/mame/machine/elan_eu3a05commonsys.h",
|
||||
MAME_DIR .. "src/mame/machine/elan_ep3a19asys.cpp",
|
||||
MAME_DIR .. "src/mame/machine/elan_ep3a19asys.h",
|
||||
MAME_DIR .. "src/mame/machine/elan_eu3a05sys.cpp",
|
||||
MAME_DIR .. "src/mame/machine/elan_eu3a05sys.h",
|
||||
MAME_DIR .. "src/mame/machine/elan_eu3a14sys.cpp",
|
||||
|
372
src/mame/drivers/elan_ep3a19a.cpp
Normal file
372
src/mame/drivers/elan_ep3a19a.cpp
Normal file
@ -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.
|
117
src/mame/machine/elan_ep3a19asys.cpp
Normal file
117
src/mame/machine/elan_ep3a19asys.cpp
Normal file
@ -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;
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
|
38
src/mame/machine/elan_ep3a19asys.h
Normal file
38
src/mame/machine/elan_ep3a19asys.h
Normal file
@ -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
|
@ -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
|
||||
|
@ -259,6 +259,7 @@ ec65.cpp
|
||||
ec7915.cpp
|
||||
einstein.cpp
|
||||
eispc.cpp
|
||||
elan_ep3a19a.cpp
|
||||
elan_eu3a05.cpp
|
||||
elan_eu3a14.cpp
|
||||
electron.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,119 +340,11 @@ 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)
|
||||
{
|
||||
/*
|
||||
this doesn't handle 8x8 4bpp (not used by anything yet)
|
||||
*/
|
||||
|
||||
int scroll = get_scroll(1);
|
||||
|
||||
void elan_eu3a05vid_device::draw_tilemaps_tileline(int drawpri, int tile, int attr, int unk2, int tilexsize, int i, int xpos, uint16_t* row)
|
||||
{
|
||||
address_space& fullbankspace = m_bank->space(AS_PROGRAM);
|
||||
|
||||
// Phoenix scrolling actually skips a pixel, jumping from 0x001 to 0x1bf, scroll 0x000 isn't used, maybe it has other meanings?
|
||||
|
||||
int totalyrow;
|
||||
int totalxcol;
|
||||
int mapyrowsbase;
|
||||
int tileysize;
|
||||
int tilexsize;
|
||||
int startrow;
|
||||
|
||||
if (m_vidctrl & 0x40) // 16x16 tiles
|
||||
{
|
||||
totalyrow = 16;
|
||||
totalxcol = 16;
|
||||
mapyrowsbase = 14;
|
||||
tileysize = 16;
|
||||
tilexsize = 16;
|
||||
startrow = (scroll >> 4) & 0x1f;
|
||||
}
|
||||
else
|
||||
{
|
||||
totalyrow = 32;
|
||||
totalxcol = 32;
|
||||
mapyrowsbase = 28;
|
||||
tileysize = 8;
|
||||
tilexsize = 8;
|
||||
startrow = (scroll >> 3) & 0x3f;
|
||||
}
|
||||
|
||||
for (int y = 0; y < totalyrow; y++)
|
||||
{
|
||||
for (int x = 0; x < totalxcol * 2; x++)
|
||||
{
|
||||
int realstartrow = (startrow + y);
|
||||
|
||||
int yrows;
|
||||
|
||||
if (m_vidctrl & 0x01)
|
||||
yrows = mapyrowsbase;
|
||||
else
|
||||
yrows = mapyrowsbase * 2;
|
||||
|
||||
if (realstartrow >= yrows)
|
||||
realstartrow -= yrows;
|
||||
|
||||
// in double width & double height mode the page addressing needs adjusting
|
||||
if (!(m_vidctrl & 0x02))
|
||||
{
|
||||
if (!(m_vidctrl & 0x01))
|
||||
{
|
||||
if (realstartrow >= (yrows / 2))
|
||||
{
|
||||
realstartrow += yrows / 2;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
for (int i = 0; i < tileysize; i++)
|
||||
{
|
||||
int drawline = (y * tileysize) + i;
|
||||
drawline -= scroll & (tileysize - 1);
|
||||
|
||||
if ((drawline >= 0) && (drawline < 256))
|
||||
{
|
||||
int scrollx;
|
||||
|
||||
// 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);
|
||||
}
|
||||
|
||||
int base;
|
||||
|
||||
if (m_vidctrl & 0x40) // 16x16 tiles
|
||||
{
|
||||
base = (((realstartrow + y) & 0x3f) * 8) + x;
|
||||
}
|
||||
else
|
||||
{
|
||||
base = (((realstartrow) & 0x7f) * totalxcol) + (x & (totalxcol - 1));
|
||||
}
|
||||
|
||||
if (!(m_vidctrl & 0x02))
|
||||
{
|
||||
if (x & totalxcol)
|
||||
{
|
||||
base += totalxcol * mapyrowsbase;
|
||||
}
|
||||
}
|
||||
|
||||
int tile, attr, unk2;
|
||||
|
||||
if (!get_tile_data(base, drawpri, tile, attr, unk2))
|
||||
continue;
|
||||
|
||||
int colour = attr & 0xf0;
|
||||
|
||||
/* 'tiles' are organized / extracted from 'texture' lines that form a 'page' the length of the rom
|
||||
@ -457,7 +372,6 @@ void elan_eu3a05vid_device::draw_tilemaps(screen_device& screen, bitmap_ind16& b
|
||||
|
||||
tile += ((m_tile_gfxbase_lo_data | m_tile_gfxbase_hi_data << 8) << 5);
|
||||
|
||||
uint16_t *const row = &bitmap.pix(drawline);
|
||||
|
||||
if (m_vidctrl & 0x20) // 4bpp
|
||||
{
|
||||
@ -468,13 +382,11 @@ void elan_eu3a05vid_device::draw_tilemaps(screen_device& screen, bitmap_ind16& b
|
||||
|
||||
int drawxpos;
|
||||
|
||||
drawxpos = x * tilexsize + xx + 0 - scrollx;
|
||||
drawxpos &= 0x1ff;
|
||||
drawxpos = xpos + xx + 0;
|
||||
if ((drawxpos >= 0) && (drawxpos < 256))
|
||||
row[drawxpos] = ((pix & 0xf0) >> 4) + colour;
|
||||
|
||||
drawxpos = x * tilexsize + xx + 1 - scrollx;
|
||||
drawxpos &= 0x1ff;
|
||||
drawxpos = xpos + xx + 1;
|
||||
if ((drawxpos >= 0) && (drawxpos < 256))
|
||||
row[drawxpos] = ((pix & 0x0f) >> 0) + colour;
|
||||
}
|
||||
@ -486,14 +398,211 @@ void elan_eu3a05vid_device::draw_tilemaps(screen_device& screen, bitmap_ind16& b
|
||||
int realaddr = ((tile + i * 32) << 3) + xx;
|
||||
uint8_t pix = fullbankspace.read_byte(realaddr);
|
||||
|
||||
int drawxpos = x * tilexsize + xx - scrollx;
|
||||
drawxpos &= 0x1ff;
|
||||
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)
|
||||
{
|
||||
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
|
||||
}
|
||||
|
||||
if (!(m_vidctrl & 0x40)) // 16x16 tiles
|
||||
{
|
||||
pagesizey <<= 1;
|
||||
pagesizex <<= 1;
|
||||
tilemapsizey <<= 1;
|
||||
tilemapsizex <<= 1;
|
||||
}
|
||||
|
||||
while (y >= tilemapsizey)
|
||||
y -= tilemapsizey;
|
||||
|
||||
while (x >= tilemapsizex)
|
||||
x -= tilemapsizex;
|
||||
|
||||
int index = 0;
|
||||
int page = 0;
|
||||
|
||||
switch (m_vidctrl & 0x03)
|
||||
{
|
||||
case 0x00: // double height & double width
|
||||
if (y < pagesizey)
|
||||
{
|
||||
if (x < pagesizex)
|
||||
{
|
||||
page = 0;
|
||||
}
|
||||
else
|
||||
{
|
||||
page = 1;
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
if (x < pagesizex)
|
||||
{
|
||||
page = 2;
|
||||
}
|
||||
else
|
||||
{
|
||||
page = 3;
|
||||
}
|
||||
}
|
||||
break;
|
||||
|
||||
case 0x02: // double height
|
||||
if (y < pagesizey)
|
||||
{
|
||||
page = 0;
|
||||
}
|
||||
else
|
||||
{
|
||||
page = 1;
|
||||
}
|
||||
break;
|
||||
|
||||
case 0x01: // double width
|
||||
if (x < pagesizex)
|
||||
{
|
||||
page = 0;
|
||||
}
|
||||
else
|
||||
{
|
||||
page = 1;
|
||||
}
|
||||
break;
|
||||
|
||||
case 0x03:
|
||||
page = 0;
|
||||
break;
|
||||
}
|
||||
|
||||
while (y >= pagesizey)
|
||||
y -= pagesizey;
|
||||
|
||||
while (x >= pagesizex)
|
||||
x -= pagesizex;
|
||||
|
||||
index = x + y * pagesizex;
|
||||
index += page * pagesizey * pagesizex;
|
||||
|
||||
return index;
|
||||
}
|
||||
|
||||
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));
|
||||
|
||||
int scrolly = get_scroll(1);
|
||||
|
||||
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);
|
||||
}
|
||||
|
||||
// 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);
|
||||
|
||||
uint16_t* row = &bitmap.pix(screenline);
|
||||
|
||||
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;
|
||||
}
|
||||
|
||||
for (int xtile = 0; xtile <= xtiles; xtile++)
|
||||
{
|
||||
|
||||
int realxtile = xtile + coursescrollx;
|
||||
|
||||
int tilemaprow;
|
||||
int tileline;
|
||||
|
||||
if (m_vidctrl & 0x40) // 16x16 tiles
|
||||
{
|
||||
tilemaprow = realline >> 4;
|
||||
tileline = realline & 0xf;
|
||||
}
|
||||
else
|
||||
{
|
||||
tilemaprow = realline >> 3;
|
||||
tileline = realline & 0x7;
|
||||
}
|
||||
|
||||
int tilemap_entry_index = get_tilemapindex_from_xy(realxtile, tilemaprow);
|
||||
|
||||
int tile, attr, unk2;
|
||||
|
||||
if (!get_tile_data(tilemap_entry_index, drawpri, tile, attr, unk2))
|
||||
continue;
|
||||
|
||||
int xpos = xtile * xtilesize - finescrollx;
|
||||
draw_tilemaps_tileline(drawpri, tile, attr, unk2, xtilesize, tileline, xpos, row);
|
||||
|
||||
}
|
||||
}
|
||||
}
|
||||
@ -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;
|
||||
}
|
||||
|
||||
|
@ -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)
|
||||
|
Loading…
Reference in New Issue
Block a user