From 75de98d1f9024fed13c8936fa259b7220e68989c Mon Sep 17 00:00:00 2001 From: David Haywood Date: Wed, 26 Nov 2025 19:37:53 +0000 Subject: [PATCH 1/8] added VJ Starz Dance Mat --- src/mame/mame.lst | 1 + src/mame/tvgames/elan_eu3a05.cpp | 21 +++++++++++++++++++++ src/mame/tvgames/elan_eu3a05commonsys.cpp | 13 +++++++++++-- src/mame/tvgames/elan_eu3a05commonsys.h | 3 ++- 4 files changed, 35 insertions(+), 3 deletions(-) diff --git a/src/mame/mame.lst b/src/mame/mame.lst index 5263fc2432547..a02bf8fcee3b3 100644 --- a/src/mame/mame.lst +++ b/src/mame/mame.lst @@ -47128,6 +47128,7 @@ rad_tetr sudelan sudelan3 sudoku2p +vjstarzd @source:tvgames/elan_eu3a14.cpp batvgc diff --git a/src/mame/tvgames/elan_eu3a05.cpp b/src/mame/tvgames/elan_eu3a05.cpp index 960428587edc3..b917b345bd1e8 100644 --- a/src/mame/tvgames/elan_eu3a05.cpp +++ b/src/mame/tvgames/elan_eu3a05.cpp @@ -524,6 +524,16 @@ static INPUT_PORTS_START( rad_tetr ) INPUT_PORTS_END +static INPUT_PORTS_START( vjstarzd ) + PORT_START("IN0") + PORT_BIT( 0xff, IP_ACTIVE_LOW, IPT_UNUSED ) + + PORT_START("IN1") + PORT_BIT( 0xff, IP_ACTIVE_LOW, IPT_UNUSED ) + + PORT_START("IN2") + PORT_BIT( 0xff, IP_ACTIVE_LOW, IPT_UNUSED ) +INPUT_PORTS_END static INPUT_PORTS_START( airblsjs ) PORT_START("IN0") @@ -869,6 +879,7 @@ void elan_eu3a13_state::elan_eu3a13(machine_config& config) m_vid->set_is_sudoku(); m_vid->set_use_spritepages(); m_sys->set_alt_timer(); // for Carl Edwards' + m_sys->set_bank_on_low_writes(); // for rad_ftet } void elan_eu3a13_state::elan_eu3a13_pal(machine_config& config) @@ -967,6 +978,12 @@ ROM_START( sudelan3 ) ROM_RELOAD(0x300000,0x100000) ROM_END +ROM_START( vjstarzd ) + ROM_REGION( 0x400000, "maincpu", ROMREGION_ERASE00 ) + ROM_LOAD( "ep1206a.u2", 0x00000, 0x80000, CRC(e5f39fa5) SHA1(5ac45bde6f4323998f2387cb62e1841ebe60e781) ) + ROM_RELOAD(0x380000,0x80000) // for boot vectors +ROM_END + ROM_START( sudelan ) ROM_REGION( 0x400000, "maincpu", ROMREGION_ERASE00 ) ROM_LOAD( "klaussudoku.bin", 0x00000, 0x200000, CRC(afd2b06a) SHA1(21db956fb40b2e3d61fc2bac89000cf7f61fe99e) ) @@ -1066,6 +1083,10 @@ CONS( 2004, rad_sinv, 0, 0, elan_eu3a05, rad_sinv, elan_eu3a05_state, empty_init CONS( 2004, rad_tetr, 0, 0, elan_eu3a05, rad_tetr, elan_eu3a05_state, empty_init, "Radica (licensed from Elorg / The Tetris Company)", "Tetris (Radica, Arcade Legends TV Game)", MACHINE_NOT_WORKING ) // "5 Tetris games in 1" +// it isn't clear if the ELAN is generating the music on this, or if one of the other globs is an audio MCU +// VJ Starz Dance Mat on box, VJ Starz Dancing Mat on screen +CONS( 2003, vjstarzd, 0, 0, elan_eu3a05, vjstarzd, elan_eu3a05_state, empty_init, "Kidz Biz / Jakks Pacific", "VJ Starz Dance Mat", MACHINE_NOT_WORKING ) + // ROM contains the string "Credit:XiAn Hummer Software Studio(CHINA) Tel:86-29-84270600 Email:HummerSoft@126.com" PCB has datecode of "050423" (23rd April 2005) CONS( 2005, airblsjs, 0, 0, elan_eu3a05_pal, airblsjs, elan_eu3a05_state, empty_init, "Advance Bright Ltd", "Air-Blaster Joystick (AB1500, PAL)", MACHINE_NOT_WORKING ) diff --git a/src/mame/tvgames/elan_eu3a05commonsys.cpp b/src/mame/tvgames/elan_eu3a05commonsys.cpp index ce4346a286ada..3acbc32717b13 100644 --- a/src/mame/tvgames/elan_eu3a05commonsys.cpp +++ b/src/mame/tvgames/elan_eu3a05commonsys.cpp @@ -175,6 +175,7 @@ elan_eu3a05commonsys_device::elan_eu3a05commonsys_device(const machine_config &m m_bank(*this, finder_base::DUMMY_TAG), m_is_pal(false), m_allow_timer_irq(true), + m_bank_on_low_bank_writes(false), m_whichtimer(0) { } @@ -355,15 +356,23 @@ void elan_eu3a05commonsys_device::elan_eu3a05_rombank_w(offs_t offset, uint8_t d { //logerror("%s: elan_eu3a05_rombank_hi_w (set ROM bank) %02x\n", machine().describe_context(), data); m_rombank_hi = data; + + m_bank->set_bank(m_rombank_lo | (m_rombank_hi << 8)); } else { //logerror("%s: elan_eu3a05_rombank_lo_w (select ROM bank) %02x\n", machine().describe_context(), data); m_rombank_lo = data; + + if (m_bank_on_low_bank_writes) + { + // rad_ftet writes only the low and expects bank to change + // however qix in rad_sinv disagrees. could this be an + // eu3a05 / eu3a13 difference? + m_bank->set_bank(m_rombank_lo | (m_rombank_hi << 8)); + } } - // rad_ftet writes only the low and expects bank to change - m_bank->set_bank(m_rombank_lo | (m_rombank_hi << 8)); } uint8_t elan_eu3a05commonsys_device::elan_eu3a05_rombank_r(offs_t offset) diff --git a/src/mame/tvgames/elan_eu3a05commonsys.h b/src/mame/tvgames/elan_eu3a05commonsys.h index 089b77c49ffe4..ff8ea15100f21 100644 --- a/src/mame/tvgames/elan_eu3a05commonsys.h +++ b/src/mame/tvgames/elan_eu3a05commonsys.h @@ -26,7 +26,7 @@ class elan_eu3a05commonsys_device : public device_t uint8_t irq_vector_r(offs_t offset); void set_alt_timer() { m_whichtimer = 1; } - + void set_bank_on_low_writes() { m_bank_on_low_bank_writes = true; } protected: // device-level overrides virtual void device_start() override ATTR_COLD; @@ -49,6 +49,7 @@ class elan_eu3a05commonsys_device : public device_t bool m_is_pal; // this is usually a jumper connected to the chip that the software can read (clocks also differ on PAL units) bool m_allow_timer_irq; + bool m_bank_on_low_bank_writes; private: uint8_t intmask_r(offs_t offset); void intmask_w(offs_t offset, uint8_t data); From 5fdb2607746e39b0b1946c67fd2023875f511590 Mon Sep 17 00:00:00 2001 From: David Haywood Date: Thu, 27 Nov 2025 16:19:56 +0000 Subject: [PATCH 2/8] do ELAN_EU3A13 video as a subclass, as there seem to be subtle differences to ELAN_EU3A05 --- src/mame/tvgames/elan_ep3a19a.cpp | 4 +- src/mame/tvgames/elan_eu3a05.cpp | 16 +++--- src/mame/tvgames/elan_eu3a05vid.cpp | 76 +++++++++++++++++++---------- src/mame/tvgames/elan_eu3a05vid.h | 26 +++++++--- 4 files changed, 77 insertions(+), 45 deletions(-) diff --git a/src/mame/tvgames/elan_ep3a19a.cpp b/src/mame/tvgames/elan_ep3a19a.cpp index 4ad8aa8b973cf..f3189d8d6fb1d 100644 --- a/src/mame/tvgames/elan_ep3a19a.cpp +++ b/src/mame/tvgames/elan_ep3a19a.cpp @@ -275,13 +275,11 @@ void elan_ep3a19a_state::elan_ep3a19a(machine_config &config) m_sys->set_cpu("maincpu"); m_sys->set_addrbank("bank"); - ELAN_EU3A05_VID(config, m_vid, 0); + ELAN_EU3A13_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_basic_scroll(); /* sound hardware */ diff --git a/src/mame/tvgames/elan_eu3a05.cpp b/src/mame/tvgames/elan_eu3a05.cpp index b917b345bd1e8..90466159b6c74 100644 --- a/src/mame/tvgames/elan_eu3a05.cpp +++ b/src/mame/tvgames/elan_eu3a05.cpp @@ -846,7 +846,7 @@ void elan_eu3a05_state::elan_eu3a05(machine_config &config) m_vid->set_cpu("maincpu"); m_vid->set_addrbank("bank"); m_vid->set_palette("palette"); - m_vid->set_entries(256); + m_vid->set_entries(256); /* sound hardware */ SPEAKER(config, "mono").front_center(); @@ -875,9 +875,14 @@ void elan_eu3a05_state::elan_eu3a05_pal(machine_config& config) void elan_eu3a13_state::elan_eu3a13(machine_config& config) { elan_eu3a05(config); + + ELAN_EU3A13_VID(config.replace(), m_vid, 0); + m_vid->set_cpu("maincpu"); + m_vid->set_addrbank("bank"); + m_vid->set_palette("palette"); + m_vid->set_entries(256); + m_maincpu->set_addrmap(AS_PROGRAM, &elan_eu3a13_state::elan_eu3a13_map); - m_vid->set_is_sudoku(); - m_vid->set_use_spritepages(); m_sys->set_alt_timer(); // for Carl Edwards' m_sys->set_bank_on_low_writes(); // for rad_ftet } @@ -891,12 +896,9 @@ void elan_eu3a13_state::elan_eu3a13_pal(machine_config& config) void elan_eu3a13_state::elan_eu3a13_pvmil8(machine_config& config) { - elan_eu3a05(config); + elan_eu3a13_pal(config); m_maincpu->set_addrmap(AS_PROGRAM, &elan_eu3a13_state::elan_eu3a13_map); - m_vid->set_is_pvmilfin(); m_sys->set_alt_timer(); - m_sys->set_pal(); // TODO: also set PAL clocks - m_screen->set_refresh_hz(50); } diff --git a/src/mame/tvgames/elan_eu3a05vid.cpp b/src/mame/tvgames/elan_eu3a05vid.cpp index 08c0a7558b50c..b08899d26a9b8 100644 --- a/src/mame/tvgames/elan_eu3a05vid.cpp +++ b/src/mame/tvgames/elan_eu3a05vid.cpp @@ -1,27 +1,46 @@ // license:BSD-3-Clause // copyright-holders:David Haywood +// ELAN EU3A05 / EU3A13 video implementation +// also currently used for EP3A19A, which assumes EU3A13 type +// although m_force_basic_scroll might be a hardware difference there + #include "emu.h" #include "elan_eu3a05vid.h" DEFINE_DEVICE_TYPE(ELAN_EU3A05_VID, elan_eu3a05vid_device, "elan_eu3a05vid", "Elan EU3A05 Video") +DEFINE_DEVICE_TYPE(ELAN_EU3A13_VID, elan_eu3a13vid_device, "elan_eu3a13vid", "Elan EU3A13 Video") -// tilemaps start at 0x0600 in mainram, sprites at 0x3e00, unlike eu3a14 these could be fixed addresses -elan_eu3a05vid_device::elan_eu3a05vid_device(const machine_config &mconfig, const char *tag, device_t *owner, uint32_t clock) : - elan_eu3a05commonvid_device(mconfig, ELAN_EU3A05_VID, tag, owner, clock), +elan_eu3a05vid_device::elan_eu3a05vid_device(const machine_config& mconfig, device_type type, const char *tag, device_t *owner, uint32_t clock) : + elan_eu3a05commonvid_device(mconfig, type, tag, owner, clock), device_memory_interface(mconfig, *this), m_cpu(*this, finder_base::DUMMY_TAG), m_bank(*this, finder_base::DUMMY_TAG), m_space_config("regs", ENDIANNESS_NATIVE, 8, 5, 0, address_map_constructor(FUNC(elan_eu3a05vid_device::map), this)), - m_bytes_per_tile_entry(4), - m_vrambase(0x600), - m_spritebase(0x3e00), - m_use_spritepages(false), m_force_basic_scroll(false) { } +elan_eu3a05vid_device::elan_eu3a05vid_device(const machine_config &mconfig, const char *tag, device_t *owner, uint32_t clock) : + elan_eu3a05vid_device(mconfig, ELAN_EU3A05_VID, tag, owner, clock) +{ + // tilemaps start at 0x0600 in mainram, sprites at 0x3e00, unlike EU3A14 these could be fixed addresses + m_vrambase = 0x600; + m_spritebase = 0x3e00; + m_use_spritepages = false; +} + +elan_eu3a13vid_device::elan_eu3a13vid_device(const machine_config &mconfig, const char *tag, device_t *owner, uint32_t clock) : + elan_eu3a05vid_device(mconfig, ELAN_EU3A13_VID, tag, owner, clock) +{ + // these seem to be different to EU3A05 (but still hardcoded?) for EU3A13 based devices + m_vrambase = 0x200; + m_spritebase = 0x1000; + m_use_spritepages = true; +} + + device_memory_interface::space_config_vector elan_eu3a05vid_device::memory_space_config() const { return space_config_vector { @@ -80,20 +99,6 @@ void elan_eu3a05vid_device::device_reset() } -void elan_eu3a05vid_device::set_is_sudoku() -{ - m_bytes_per_tile_entry = 2; - m_vrambase = 0x200; - m_spritebase = 0x1000; -} - -void elan_eu3a05vid_device::set_is_pvmilfin() -{ - m_bytes_per_tile_entry = 4; - m_vrambase = 0x200; - m_spritebase = 0x1000; // not verified -} - uint8_t elan_eu3a05vid_device::read_spriteram(int offset) { address_space& cpuspace = m_cpu->space(AS_PROGRAM); @@ -294,18 +299,35 @@ void elan_eu3a05vid_device::draw_sprites(screen_device &screen, bitmap_ind16 &bi } } +int elan_eu3a05vid_device::get_bytes_per_tile_entry() +{ + // always 4 on EU3A05? + return 4; +} + +int elan_eu3a13vid_device::get_bytes_per_tile_entry() +{ + // can be selected on EU3A13? + // (some EU3A05 games flip this bit, either unused or has another purpose there?) + if (m_vidctrl & 0x80) + return 4; + else + return 2; +} // a hacky mess for now bool elan_eu3a05vid_device::get_tile_data(int base, int drawpri, int& tile, int &attr, int &unk2) { - tile = read_vram(base * m_bytes_per_tile_entry) + (read_vram((base * m_bytes_per_tile_entry) + 1) << 8); + int bytes_per_tile_entry = get_bytes_per_tile_entry(); + + tile = read_vram(base * bytes_per_tile_entry) + (read_vram((base * bytes_per_tile_entry) + 1) << 8); // these seem to be the basically the same as attr/unk2 in the sprites, which also make // very little sense. - if (m_bytes_per_tile_entry == 4) + if (bytes_per_tile_entry == 4) { - attr = read_vram((base * m_bytes_per_tile_entry) + 2); - unk2 = read_vram((base * m_bytes_per_tile_entry) + 3); + attr = read_vram((base * bytes_per_tile_entry) + 2); + unk2 = read_vram((base * bytes_per_tile_entry) + 3); } else { @@ -724,9 +746,9 @@ void elan_eu3a05vid_device::elan_eu3a05_vidctrl_w(uint8_t data) 03 8bpp 8x8 0000 0011 air blaster 2d bosses 00 0000 0000 air blaster 3d stages - ?tb- --wh + Btb- --wh - ? = unknown + B = unknown on EU3A05, bytes per tile on EU3A13? t = tile size (1 = 16x16, 0 = 8x8) b = bpp (0 = 8bpp, 1 = 4bpp) - = haven't seen used diff --git a/src/mame/tvgames/elan_eu3a05vid.h b/src/mame/tvgames/elan_eu3a05vid.h index 41008832093e4..d4f6e44704602 100644 --- a/src/mame/tvgames/elan_eu3a05vid.h +++ b/src/mame/tvgames/elan_eu3a05vid.h @@ -21,23 +21,27 @@ class elan_eu3a05vid_device : public elan_eu3a05commonvid_device, public device_ uint32_t screen_update(screen_device &screen, bitmap_ind16 &bitmap, const rectangle &cliprect); - void set_is_sudoku(); - void set_is_pvmilfin(); - void set_use_spritepages() { m_use_spritepages = true; } void set_force_basic_scroll() { m_force_basic_scroll = true; } protected: + elan_eu3a05vid_device(const machine_config& mconfig, device_type type, const char* tag, device_t* owner, uint32_t clock); + // device-level overrides virtual void device_start() override ATTR_COLD; virtual void device_reset() override ATTR_COLD; virtual space_config_vector memory_space_config() const override; + virtual int get_bytes_per_tile_entry(); + + int m_vrambase; + int m_spritebase; + bool m_use_spritepages; + uint8_t m_vidctrl = 0; private: required_device m_cpu; required_device m_bank; const address_space_config m_space_config; - uint8_t m_vidctrl = 0; uint8_t m_tile_gfxbase_lo_data = 0; uint8_t m_tile_gfxbase_hi_data = 0; @@ -88,13 +92,19 @@ class elan_eu3a05vid_device : public elan_eu3a05commonvid_device, public device_ uint8_t read_unmapped(offs_t offset); void write_unmapped(offs_t offset, uint8_t data); - int m_bytes_per_tile_entry; - int m_vrambase; - int m_spritebase; - bool m_use_spritepages; bool m_force_basic_scroll; }; +class elan_eu3a13vid_device : public elan_eu3a05vid_device +{ +public: + elan_eu3a13vid_device(const machine_config &mconfig, const char *tag, device_t *owner, uint32_t clock); + +protected: + virtual int get_bytes_per_tile_entry() override; +}; + DECLARE_DEVICE_TYPE(ELAN_EU3A05_VID, elan_eu3a05vid_device) +DECLARE_DEVICE_TYPE(ELAN_EU3A13_VID, elan_eu3a13vid_device) #endif // MAME_TVGAMES_ELAN_EU3A05VID_H From 191b53ebe9fa80a9aae51499e6c019203e864fa4 Mon Sep 17 00:00:00 2001 From: David Haywood Date: Thu, 27 Nov 2025 16:41:17 +0000 Subject: [PATCH 3/8] subclass EP3A19A video too, as there also seem to be differences here --- src/mame/tvgames/elan_ep3a19a.cpp | 3 +-- src/mame/tvgames/elan_eu3a05vid.cpp | 21 ++++++++++++++++----- src/mame/tvgames/elan_eu3a05vid.h | 16 +++++++++++----- 3 files changed, 28 insertions(+), 12 deletions(-) diff --git a/src/mame/tvgames/elan_ep3a19a.cpp b/src/mame/tvgames/elan_ep3a19a.cpp index f3189d8d6fb1d..adf20f431cc51 100644 --- a/src/mame/tvgames/elan_ep3a19a.cpp +++ b/src/mame/tvgames/elan_ep3a19a.cpp @@ -275,12 +275,11 @@ void elan_ep3a19a_state::elan_ep3a19a(machine_config &config) m_sys->set_cpu("maincpu"); m_sys->set_addrbank("bank"); - ELAN_EU3A13_VID(config, m_vid, 0); + ELAN_EP3A19A_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_force_basic_scroll(); /* sound hardware */ SPEAKER(config, "mono").front_center(); diff --git a/src/mame/tvgames/elan_eu3a05vid.cpp b/src/mame/tvgames/elan_eu3a05vid.cpp index b08899d26a9b8..8544534128452 100644 --- a/src/mame/tvgames/elan_eu3a05vid.cpp +++ b/src/mame/tvgames/elan_eu3a05vid.cpp @@ -10,16 +10,16 @@ DEFINE_DEVICE_TYPE(ELAN_EU3A05_VID, elan_eu3a05vid_device, "elan_eu3a05vid", "Elan EU3A05 Video") DEFINE_DEVICE_TYPE(ELAN_EU3A13_VID, elan_eu3a13vid_device, "elan_eu3a13vid", "Elan EU3A13 Video") - +DEFINE_DEVICE_TYPE(ELAN_EP3A19A_VID, elan_ep3a19avid_device, "elan_ep3a19avid", "Elan EP3A19A Video") elan_eu3a05vid_device::elan_eu3a05vid_device(const machine_config& mconfig, device_type type, const char *tag, device_t *owner, uint32_t clock) : elan_eu3a05commonvid_device(mconfig, type, tag, owner, clock), device_memory_interface(mconfig, *this), m_cpu(*this, finder_base::DUMMY_TAG), m_bank(*this, finder_base::DUMMY_TAG), - m_space_config("regs", ENDIANNESS_NATIVE, 8, 5, 0, address_map_constructor(FUNC(elan_eu3a05vid_device::map), this)), - m_force_basic_scroll(false) + m_space_config("regs", ENDIANNESS_NATIVE, 8, 5, 0, address_map_constructor(FUNC(elan_eu3a05vid_device::map), this)) { + m_force_basic_scroll = false; } elan_eu3a05vid_device::elan_eu3a05vid_device(const machine_config &mconfig, const char *tag, device_t *owner, uint32_t clock) : @@ -31,8 +31,8 @@ elan_eu3a05vid_device::elan_eu3a05vid_device(const machine_config &mconfig, cons m_use_spritepages = false; } -elan_eu3a13vid_device::elan_eu3a13vid_device(const machine_config &mconfig, const char *tag, device_t *owner, uint32_t clock) : - elan_eu3a05vid_device(mconfig, ELAN_EU3A13_VID, tag, owner, clock) +elan_eu3a13vid_device::elan_eu3a13vid_device(const machine_config &mconfig, device_type type, const char *tag, device_t *owner, uint32_t clock) : + elan_eu3a05vid_device(mconfig, type, tag, owner, clock) { // these seem to be different to EU3A05 (but still hardcoded?) for EU3A13 based devices m_vrambase = 0x200; @@ -40,6 +40,17 @@ elan_eu3a13vid_device::elan_eu3a13vid_device(const machine_config &mconfig, cons m_use_spritepages = true; } +elan_eu3a13vid_device::elan_eu3a13vid_device(const machine_config &mconfig, const char *tag, device_t *owner, uint32_t clock) : + elan_eu3a13vid_device(mconfig, ELAN_EU3A13_VID, tag, owner, clock) +{ +} + +elan_ep3a19avid_device::elan_ep3a19avid_device(const machine_config &mconfig, const char *tag, device_t *owner, uint32_t clock) : + elan_eu3a13vid_device(mconfig, ELAN_EP3A19A_VID, tag, owner, clock) +{ + // this could be a EP3A19A specific behavior + m_force_basic_scroll = true; +} device_memory_interface::space_config_vector elan_eu3a05vid_device::memory_space_config() const { diff --git a/src/mame/tvgames/elan_eu3a05vid.h b/src/mame/tvgames/elan_eu3a05vid.h index d4f6e44704602..6f64c57a7ece6 100644 --- a/src/mame/tvgames/elan_eu3a05vid.h +++ b/src/mame/tvgames/elan_eu3a05vid.h @@ -21,10 +21,8 @@ class elan_eu3a05vid_device : public elan_eu3a05commonvid_device, public device_ uint32_t screen_update(screen_device &screen, bitmap_ind16 &bitmap, const rectangle &cliprect); - void set_force_basic_scroll() { m_force_basic_scroll = true; } - protected: - elan_eu3a05vid_device(const machine_config& mconfig, device_type type, const char* tag, device_t* owner, uint32_t clock); + elan_eu3a05vid_device(const machine_config &mconfig, device_type type, const char *tag, device_t *owner, uint32_t clock); // device-level overrides virtual void device_start() override ATTR_COLD; @@ -36,6 +34,7 @@ class elan_eu3a05vid_device : public elan_eu3a05commonvid_device, public device_ int m_vrambase; int m_spritebase; bool m_use_spritepages; + bool m_force_basic_scroll; uint8_t m_vidctrl = 0; private: required_device m_cpu; @@ -91,8 +90,6 @@ class elan_eu3a05vid_device : public elan_eu3a05commonvid_device, public device_ uint8_t read_unmapped(offs_t offset); void write_unmapped(offs_t offset, uint8_t data); - - bool m_force_basic_scroll; }; class elan_eu3a13vid_device : public elan_eu3a05vid_device @@ -101,10 +98,19 @@ class elan_eu3a13vid_device : public elan_eu3a05vid_device elan_eu3a13vid_device(const machine_config &mconfig, const char *tag, device_t *owner, uint32_t clock); protected: + elan_eu3a13vid_device(const machine_config &mconfig, device_type type, const char *tag, device_t *owner, uint32_t clock); + virtual int get_bytes_per_tile_entry() override; }; +class elan_ep3a19avid_device : public elan_eu3a13vid_device +{ +public: + elan_ep3a19avid_device(const machine_config &mconfig, const char *tag, device_t *owner, uint32_t clock); +}; + DECLARE_DEVICE_TYPE(ELAN_EU3A05_VID, elan_eu3a05vid_device) DECLARE_DEVICE_TYPE(ELAN_EU3A13_VID, elan_eu3a13vid_device) +DECLARE_DEVICE_TYPE(ELAN_EP3A19A_VID, elan_ep3a19avid_device) #endif // MAME_TVGAMES_ELAN_EU3A05VID_H From eff7b577cc253c41d32dfdcabba1c869c7908f11 Mon Sep 17 00:00:00 2001 From: David Haywood Date: Thu, 27 Nov 2025 20:01:40 +0000 Subject: [PATCH 4/8] treat banking behavior as a potential difference between SoC types --- src/mame/tvgames/elan_eu3a05.cpp | 6 ++++-- src/mame/tvgames/elan_eu3a05commonsys.h | 1 - src/mame/tvgames/elan_eu3a05sys.cpp | 18 ++++++++++++++++-- src/mame/tvgames/elan_eu3a05sys.h | 10 ++++++++++ 4 files changed, 30 insertions(+), 5 deletions(-) diff --git a/src/mame/tvgames/elan_eu3a05.cpp b/src/mame/tvgames/elan_eu3a05.cpp index 90466159b6c74..adacdec2f61fc 100644 --- a/src/mame/tvgames/elan_eu3a05.cpp +++ b/src/mame/tvgames/elan_eu3a05.cpp @@ -875,6 +875,7 @@ void elan_eu3a05_state::elan_eu3a05_pal(machine_config& config) void elan_eu3a13_state::elan_eu3a13(machine_config& config) { elan_eu3a05(config); + m_maincpu->set_addrmap(AS_PROGRAM, &elan_eu3a13_state::elan_eu3a13_map); ELAN_EU3A13_VID(config.replace(), m_vid, 0); m_vid->set_cpu("maincpu"); @@ -882,9 +883,10 @@ void elan_eu3a13_state::elan_eu3a13(machine_config& config) m_vid->set_palette("palette"); m_vid->set_entries(256); - m_maincpu->set_addrmap(AS_PROGRAM, &elan_eu3a13_state::elan_eu3a13_map); + ELAN_EU3A13_SYS(config.replace(), m_sys, 0); + m_sys->set_cpu("maincpu"); + m_sys->set_addrbank("bank"); m_sys->set_alt_timer(); // for Carl Edwards' - m_sys->set_bank_on_low_writes(); // for rad_ftet } void elan_eu3a13_state::elan_eu3a13_pal(machine_config& config) diff --git a/src/mame/tvgames/elan_eu3a05commonsys.h b/src/mame/tvgames/elan_eu3a05commonsys.h index ff8ea15100f21..32fdacae1e715 100644 --- a/src/mame/tvgames/elan_eu3a05commonsys.h +++ b/src/mame/tvgames/elan_eu3a05commonsys.h @@ -26,7 +26,6 @@ class elan_eu3a05commonsys_device : public device_t uint8_t irq_vector_r(offs_t offset); void set_alt_timer() { m_whichtimer = 1; } - void set_bank_on_low_writes() { m_bank_on_low_bank_writes = true; } protected: // device-level overrides virtual void device_start() override ATTR_COLD; diff --git a/src/mame/tvgames/elan_eu3a05sys.cpp b/src/mame/tvgames/elan_eu3a05sys.cpp index 681beb0340426..98fc5a517a69c 100644 --- a/src/mame/tvgames/elan_eu3a05sys.cpp +++ b/src/mame/tvgames/elan_eu3a05sys.cpp @@ -7,14 +7,28 @@ // DMA size and destination are 16-bit here, they're 24-bit on EU3A14 DEFINE_DEVICE_TYPE(ELAN_EU3A05_SYS, elan_eu3a05sys_device, "elan_eu3a05sys", "Elan EU3A05 System") +DEFINE_DEVICE_TYPE(ELAN_EU3A13_SYS, elan_eu3a13sys_device, "elan_eu3a13sys", "Elan EU3A13 System") -elan_eu3a05sys_device::elan_eu3a05sys_device(const machine_config &mconfig, const char *tag, device_t *owner, uint32_t clock) : - elan_eu3a05commonsys_device(mconfig, ELAN_EU3A05_SYS, tag, owner, clock), +elan_eu3a05sys_device::elan_eu3a05sys_device(const machine_config &mconfig, device_type type, const char *tag, device_t *owner, uint32_t clock) : + elan_eu3a05commonsys_device(mconfig, type, tag, owner, clock), device_memory_interface(mconfig, *this), m_space_config("regs", ENDIANNESS_NATIVE, 8, 5, 0, address_map_constructor(FUNC(elan_eu3a05sys_device::map), this)) { } +elan_eu3a05sys_device::elan_eu3a05sys_device(const machine_config &mconfig, const char *tag, device_t *owner, uint32_t clock) : + elan_eu3a05sys_device(mconfig, ELAN_EU3A05_SYS, tag, owner, clock) +{ +} + +elan_eu3a13sys_device::elan_eu3a13sys_device(const machine_config &mconfig, const char *tag, device_t *owner, uint32_t clock) : + elan_eu3a05sys_device(mconfig, ELAN_EU3A13_SYS, tag, owner, clock) +{ + // might be a difference on this hardware type, as rad_ftet (EU3A13) needs it, but rad_sinv (EU3A05) does not + m_bank_on_low_bank_writes = true; +} + + device_memory_interface::space_config_vector elan_eu3a05sys_device::memory_space_config() const { return space_config_vector { diff --git a/src/mame/tvgames/elan_eu3a05sys.h b/src/mame/tvgames/elan_eu3a05sys.h index 54073bac65eac..f1f045c58ded5 100644 --- a/src/mame/tvgames/elan_eu3a05sys.h +++ b/src/mame/tvgames/elan_eu3a05sys.h @@ -20,6 +20,8 @@ class elan_eu3a05sys_device : public elan_eu3a05commonsys_device, public device_ virtual void map(address_map &map) override ATTR_COLD; protected: + elan_eu3a05sys_device(const machine_config &mconfig, device_type type, const char *tag, device_t *owner, uint32_t clock); + // device-level overrides virtual void device_start() override ATTR_COLD; virtual void device_reset() override ATTR_COLD; @@ -30,6 +32,14 @@ class elan_eu3a05sys_device : public elan_eu3a05commonsys_device, public device_ uint8_t m_dmaparams[7]; }; + +class elan_eu3a13sys_device : public elan_eu3a05sys_device +{ +public: + elan_eu3a13sys_device(const machine_config &mconfig, const char *tag, device_t *owner, uint32_t clock); +}; + DECLARE_DEVICE_TYPE(ELAN_EU3A05_SYS, elan_eu3a05sys_device) +DECLARE_DEVICE_TYPE(ELAN_EU3A13_SYS, elan_eu3a13sys_device) #endif // MAME_TVGAMES_ELAN_EU3A05SYS_H From 3f7998c27485d2ea667be68cdf58a2bc732aa0db Mon Sep 17 00:00:00 2001 From: David Haywood Date: Thu, 27 Nov 2025 20:06:39 +0000 Subject: [PATCH 5/8] srcclean --- src/mame/tvgames/elan_eu3a05.cpp | 2 +- src/mame/tvgames/elan_eu3a05vid.cpp | 7 ++++--- 2 files changed, 5 insertions(+), 4 deletions(-) diff --git a/src/mame/tvgames/elan_eu3a05.cpp b/src/mame/tvgames/elan_eu3a05.cpp index adacdec2f61fc..ff2638dc398bc 100644 --- a/src/mame/tvgames/elan_eu3a05.cpp +++ b/src/mame/tvgames/elan_eu3a05.cpp @@ -846,7 +846,7 @@ void elan_eu3a05_state::elan_eu3a05(machine_config &config) m_vid->set_cpu("maincpu"); m_vid->set_addrbank("bank"); m_vid->set_palette("palette"); - m_vid->set_entries(256); + m_vid->set_entries(256); /* sound hardware */ SPEAKER(config, "mono").front_center(); diff --git a/src/mame/tvgames/elan_eu3a05vid.cpp b/src/mame/tvgames/elan_eu3a05vid.cpp index 8544534128452..9b308d9e2aa8e 100644 --- a/src/mame/tvgames/elan_eu3a05vid.cpp +++ b/src/mame/tvgames/elan_eu3a05vid.cpp @@ -1,9 +1,10 @@ // license:BSD-3-Clause // copyright-holders:David Haywood -// ELAN EU3A05 / EU3A13 video implementation -// also currently used for EP3A19A, which assumes EU3A13 type -// although m_force_basic_scroll might be a hardware difference there +// ELAN EU3A05 / EU3A13 / EP3A19A video implementations +// There seem to be slight differences between which modes/features are available in each +// chip, so using the correct hardware type is important. As these are 'glob top' chips +// they can't be fully identified without decapping. #include "emu.h" #include "elan_eu3a05vid.h" From 0f9e360ad68c63461df9d6fa0ddab7d26b1c31b3 Mon Sep 17 00:00:00 2001 From: David Haywood Date: Thu, 27 Nov 2025 21:42:06 +0000 Subject: [PATCH 6/8] a few cleanups --- src/mame/tvgames/elan_ep3a19a.cpp | 12 ++++++------ src/mame/tvgames/elan_eu3a05.cpp | 22 +++++++++++----------- src/mame/tvgames/elan_eu3a14.cpp | 14 +++++++------- 3 files changed, 24 insertions(+), 24 deletions(-) diff --git a/src/mame/tvgames/elan_ep3a19a.cpp b/src/mame/tvgames/elan_ep3a19a.cpp index adf20f431cc51..496c8e787c4bd 100644 --- a/src/mame/tvgames/elan_ep3a19a.cpp +++ b/src/mame/tvgames/elan_ep3a19a.cpp @@ -252,7 +252,7 @@ void elan_ep3a19a_state::elan_ep3a19a(machine_config &config) 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); + ADDRESS_MAP_BANK(config, m_bank).set_map(&elan_ep3a19a_state::elan_ep3a19a_bank_map).set_options(ENDIANNESS_LITTLE, 8, 24, 0x8000); PALETTE(config, m_palette).set_entries(256); @@ -272,13 +272,13 @@ void elan_ep3a19a_state::elan_ep3a19a(machine_config &config) 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"); + m_sys->set_cpu(m_maincpu); + m_sys->set_addrbank(m_bank); ELAN_EP3A19A_VID(config, m_vid, 0); - m_vid->set_cpu("maincpu"); - m_vid->set_addrbank("bank"); - m_vid->set_palette("palette"); + m_vid->set_cpu(m_maincpu); + m_vid->set_addrbank(m_bank); + m_vid->set_palette(m_palette); m_vid->set_entries(256); /* sound hardware */ diff --git a/src/mame/tvgames/elan_eu3a05.cpp b/src/mame/tvgames/elan_eu3a05.cpp index ff2638dc398bc..d22c99bd1eea9 100644 --- a/src/mame/tvgames/elan_eu3a05.cpp +++ b/src/mame/tvgames/elan_eu3a05.cpp @@ -819,7 +819,7 @@ void elan_eu3a05_state::elan_eu3a05(machine_config &config) m_maincpu->set_addrmap(AS_PROGRAM, &elan_eu3a05_state::elan_eu3a05_map); m_maincpu->set_vblank_int("screen", FUNC(elan_eu3a05_state::interrupt)); - ADDRESS_MAP_BANK(config, "bank").set_map(&elan_eu3a05_state::elan_eu3a05_bank_map).set_options(ENDIANNESS_LITTLE, 8, 24, 0x8000); + ADDRESS_MAP_BANK(config, m_bank).set_map(&elan_eu3a05_state::elan_eu3a05_bank_map).set_options(ENDIANNESS_LITTLE, 8, 24, 0x8000); PALETTE(config, m_palette).set_entries(256); @@ -839,13 +839,13 @@ void elan_eu3a05_state::elan_eu3a05(machine_config &config) m_gpio->read_2_callback().set_ioport("IN2"); ELAN_EU3A05_SYS(config, m_sys, 0); - m_sys->set_cpu("maincpu"); - m_sys->set_addrbank("bank"); + m_sys->set_cpu(m_maincpu); + m_sys->set_addrbank(m_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_cpu(m_maincpu); + m_vid->set_addrbank(m_bank); + m_vid->set_palette(m_palette); m_vid->set_entries(256); /* sound hardware */ @@ -878,14 +878,14 @@ void elan_eu3a13_state::elan_eu3a13(machine_config& config) m_maincpu->set_addrmap(AS_PROGRAM, &elan_eu3a13_state::elan_eu3a13_map); ELAN_EU3A13_VID(config.replace(), m_vid, 0); - m_vid->set_cpu("maincpu"); - m_vid->set_addrbank("bank"); - m_vid->set_palette("palette"); + m_vid->set_cpu(m_maincpu); + m_vid->set_addrbank(m_bank); + m_vid->set_palette(m_palette); m_vid->set_entries(256); ELAN_EU3A13_SYS(config.replace(), m_sys, 0); - m_sys->set_cpu("maincpu"); - m_sys->set_addrbank("bank"); + m_sys->set_cpu(m_maincpu); + m_sys->set_addrbank(m_bank); m_sys->set_alt_timer(); // for Carl Edwards' } diff --git a/src/mame/tvgames/elan_eu3a14.cpp b/src/mame/tvgames/elan_eu3a14.cpp index a2b8e800c7693..2ffe5d03ccd2d 100644 --- a/src/mame/tvgames/elan_eu3a14.cpp +++ b/src/mame/tvgames/elan_eu3a14.cpp @@ -783,11 +783,11 @@ void elan_eu3a14_state::radica_eu3a14(machine_config &config) m_maincpu->set_addrmap(AS_PROGRAM, &elan_eu3a14_state::radica_eu3a14_map); m_maincpu->set_vblank_int("screen", FUNC(elan_eu3a14_state::interrupt)); - ADDRESS_MAP_BANK(config, "bank").set_map(&elan_eu3a14_state::bank_map).set_options(ENDIANNESS_LITTLE, 8, 24, 0x8000); + ADDRESS_MAP_BANK(config, m_bank).set_map(&elan_eu3a14_state::bank_map).set_options(ENDIANNESS_LITTLE, 8, 24, 0x8000); ELAN_EU3A14_SYS(config, m_sys, 0); - m_sys->set_cpu("maincpu"); - m_sys->set_addrbank("bank"); + m_sys->set_cpu(m_maincpu); + m_sys->set_addrbank(m_bank); GFXDECODE(config, m_gfxdecode, m_palette, gfx_helper); @@ -803,10 +803,10 @@ void elan_eu3a14_state::radica_eu3a14(machine_config &config) PALETTE(config, m_palette).set_entries(512); ELAN_EU3A14_VID(config, m_vid, 0); - m_vid->set_cpu("maincpu"); - m_vid->set_addrbank("bank"); - m_vid->set_palette("palette"); - m_vid->set_screen("screen"); + m_vid->set_cpu(m_maincpu); + m_vid->set_addrbank(m_bank); + m_vid->set_palette(m_palette); + m_vid->set_screen(m_screen); m_vid->set_entries(512); m_vid->set_tilerambase(0x0200 - 0x200); From 7c1724e357853edf249bb2a45fb76fcc61412a4e Mon Sep 17 00:00:00 2001 From: David Haywood Date: Thu, 27 Nov 2025 23:22:15 +0000 Subject: [PATCH 7/8] map vjstarzd inputs, although it needs the other timer running which we don't currently know how to enable --- src/mame/tvgames/elan_eu3a05.cpp | 24 +++++++++++++++++++----- 1 file changed, 19 insertions(+), 5 deletions(-) diff --git a/src/mame/tvgames/elan_eu3a05.cpp b/src/mame/tvgames/elan_eu3a05.cpp index d22c99bd1eea9..9fc1490da4f82 100644 --- a/src/mame/tvgames/elan_eu3a05.cpp +++ b/src/mame/tvgames/elan_eu3a05.cpp @@ -525,14 +525,28 @@ static INPUT_PORTS_START( rad_tetr ) INPUT_PORTS_END static INPUT_PORTS_START( vjstarzd ) + // star shaped dance pad, with 5 points and a start/select button on each pad + // can't easily be mapped to directions, so just using buttons PORT_START("IN0") - PORT_BIT( 0xff, IP_ACTIVE_LOW, IPT_UNUSED ) - - PORT_START("IN1") - PORT_BIT( 0xff, IP_ACTIVE_LOW, IPT_UNUSED ) + PORT_BIT( 0x01, IP_ACTIVE_LOW, IPT_BUTTON1 ) PORT_PLAYER(1) PORT_NAME("P1 Right / Green") // moves right in menu + PORT_BIT( 0x02, IP_ACTIVE_LOW, IPT_BUTTON2 ) PORT_PLAYER(1) PORT_NAME("P1 Top / Red") + PORT_BIT( 0x04, IP_ACTIVE_LOW, IPT_BUTTON3 ) PORT_PLAYER(1) PORT_NAME("P1 Bottom Right / Pink") + PORT_BIT( 0x08, IP_ACTIVE_LOW, IPT_BUTTON4 ) PORT_PLAYER(1) PORT_NAME("P1 Bottom Left / Yellow") + PORT_BIT( 0x10, IP_ACTIVE_LOW, IPT_BUTTON5 ) PORT_PLAYER(1) PORT_NAME("P1 Left / Blue") // moves left in menu + PORT_BIT( 0x20, IP_ACTIVE_LOW, IPT_START1 ) // connected to both start inputs? + PORT_BIT( 0x40, IP_ACTIVE_LOW, IPT_UNUSED ) // makes a sound, but is not connected? + PORT_BIT( 0x80, IP_ACTIVE_LOW, IPT_SELECT ) // connected to both select inputs? + + PORT_START("IN1") // these don't make a sound in menu, but do in game + PORT_BIT( 0x01, IP_ACTIVE_LOW, IPT_BUTTON1 ) PORT_PLAYER(2) PORT_NAME("P2 Right / Green") + PORT_BIT( 0x02, IP_ACTIVE_LOW, IPT_BUTTON2 ) PORT_PLAYER(2) PORT_NAME("P2 Top / Red") + PORT_BIT( 0x04, IP_ACTIVE_LOW, IPT_BUTTON3 ) PORT_PLAYER(2) PORT_NAME("P2 Bottom Right / Pink") + PORT_BIT( 0x08, IP_ACTIVE_LOW, IPT_BUTTON4 ) PORT_PLAYER(2) PORT_NAME("P2 Bottom Left / Yellow") + PORT_BIT( 0x10, IP_ACTIVE_LOW, IPT_BUTTON5 ) PORT_PLAYER(2) PORT_NAME("P2 Left / Blue") + PORT_BIT( 0xe0, IP_ACTIVE_LOW, IPT_UNUSED ) PORT_START("IN2") - PORT_BIT( 0xff, IP_ACTIVE_LOW, IPT_UNUSED ) + PORT_BIT( 0xe0, IP_ACTIVE_LOW, IPT_UNUSED ) INPUT_PORTS_END static INPUT_PORTS_START( airblsjs ) From 81046d64ad1814b5b146319fd82803c31fe25613 Mon Sep 17 00:00:00 2001 From: David Haywood Date: Thu, 27 Nov 2025 23:23:02 +0000 Subject: [PATCH 8/8] typo --- src/mame/tvgames/elan_eu3a05.cpp | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/mame/tvgames/elan_eu3a05.cpp b/src/mame/tvgames/elan_eu3a05.cpp index 9fc1490da4f82..2564973c10951 100644 --- a/src/mame/tvgames/elan_eu3a05.cpp +++ b/src/mame/tvgames/elan_eu3a05.cpp @@ -546,7 +546,7 @@ static INPUT_PORTS_START( vjstarzd ) PORT_BIT( 0xe0, IP_ACTIVE_LOW, IPT_UNUSED ) PORT_START("IN2") - PORT_BIT( 0xe0, IP_ACTIVE_LOW, IPT_UNUSED ) + PORT_BIT( 0xff, IP_ACTIVE_LOW, IPT_UNUSED ) INPUT_PORTS_END static INPUT_PORTS_START( airblsjs )