summaryrefslogtreecommitdiffstatshomepage
path: root/src/mame
diff options
context:
space:
mode:
author David Haywood <28625134+DavidHaywood@users.noreply.github.com>2019-11-12 16:44:24 +0000
committer R. Belmont <rb6502@users.noreply.github.com>2019-11-12 11:44:24 -0500
commitd093c549295c721fd0c6f507b9d17804f24fafe1 (patch)
treeeab0f639d4e5cd8cb55ae391b5c98fac1e318269 /src/mame
parent1e02669173965f37d144f9db982e497b37f24f3a (diff)
continued elan refactoring (nw) (#5892)
* cointinued elan refactoring (nw) * fake a timer interrupt to force Air Blaster Joystick 3D stages forward (nw) * notes on bugs present on Air Blaster original hw (nw) * lower frequency (nw) * improve split scroll mode for air blaster joystick 3d stage bosses (nw) * change wording (nw)
Diffstat (limited to 'src/mame')
-rw-r--r--src/mame/drivers/elan_eu3a05.cpp102
-rw-r--r--src/mame/drivers/elan_eu3a14.cpp105
-rw-r--r--src/mame/machine/elan_eu3a05commonsys.cpp74
-rw-r--r--src/mame/machine/elan_eu3a05commonsys.h30
-rw-r--r--src/mame/machine/elan_eu3a05sys.cpp18
-rw-r--r--src/mame/machine/elan_eu3a05sys.h6
-rw-r--r--src/mame/machine/elan_eu3a14sys.cpp20
-rw-r--r--src/mame/machine/elan_eu3a14sys.h6
-rw-r--r--src/mame/video/elan_eu3a05vid.cpp15
9 files changed, 203 insertions, 173 deletions
diff --git a/src/mame/drivers/elan_eu3a05.cpp b/src/mame/drivers/elan_eu3a05.cpp
index 441398120d1..51f074a5916 100644
--- a/src/mame/drivers/elan_eu3a05.cpp
+++ b/src/mame/drivers/elan_eu3a05.cpp
@@ -37,10 +37,11 @@
Space Invaders - hold P1 Down + P1 Button 1 on boot
ABL Air-Blaster - none?
- ----
-
+ -----------------------------------------------------
Flaws (NOT emulation bugs, happen on hardware):
- --
+ -----------------------------------------------------
+
+ rad_sinv:
In QIX the sprites lag behind the line drawing, so you see the line infront of your player until you stop moving
@@ -56,12 +57,39 @@
The 200pt right facing bird on the Phoenix score table is corrupt
- Uncertain (to check)
-
Space Invaders seems to be using a darker than expected palette, there are lighter colours in the palette but
they don't seem to be used. It's difficult to judge from hardware videos, although it definitely isn't as
- white as the menu, so this might also be a non-bug.
+ white as the menu, so this might also be a non-bug. (Uncertain - to check)
+
+ -------------------------
+
+ airblasjs:
+
+ This game is very buggy.
+
+ The 3D stages are prone to softlocking when the refuel jet is meant to appear.
+ 2D stages will zap you of your lives and then continues one by one if you die on a boss meaning if you have
+ 2 continues left you'll be offered the continue screen twice while it drains you of your lives before
+ actually presenting you with the Game Over screen. The manual claims you can't continue on a boss however
+ this isn't true for the 3D stages, where the continue feature works as expected. Either way, this is a very
+ crude way of implementing a 'no continue' feature on bosses if it isn't simply a bug in the game code that
+ was explained away as a feature.
+
+ Sprites clip on / off the top of the screen in parts - if you move your the player helipcopter to the top
+ of the screen the top 8 pixels clip off too (not currently happening in MAME, probably need to take out
+ sprite wrapping on y)
+
+ Sprites wrap around on X too, if you move to the left edge you can see your shadow on the right etc.
+
+ Sound sometimes stops working properly / shot changes for no reason.
+
+ There's no indication of damage most of the time on bosses, some parts won't take damage until other parts
+ have been destroyed, not always obvious.
+
+ Very heavy sprite flicker (not emulated)
+
+ Very heavy slowdown (MAME speed is approximate)
*/
@@ -102,11 +130,6 @@ private:
// screen updates
uint32_t screen_update(screen_device &screen, bitmap_ind16 &bitmap, const rectangle &cliprect);
- // system
- DECLARE_READ8_MEMBER(elan_eu3a05_5003_r);
- DECLARE_READ8_MEMBER(elan_eu3a05_pal_ntsc_r);
- DECLARE_WRITE8_MEMBER(elan_eu3a05_500b_unk_w);
-
INTERRUPT_GEN_MEMBER(interrupt);
// for callback
@@ -151,42 +174,6 @@ uint32_t elan_eu3a05_state::screen_update(screen_device& screen, bitmap_ind16& b
return m_vid->screen_update(screen, bitmap, cliprect);
}
-// System control
-
-READ8_MEMBER(elan_eu3a05_state::elan_eu3a05_pal_ntsc_r)
-{
- // how best to handle this, we probably need to run the PAL machine at 50hz
- // the text under the radica logo differs between regions
- logerror("%s: elan_eu3a05_pal_ntsc_r (region + more?)\n", machine().describe_context());
- return 0xff; // NTSC
- //return 0x00; // PAL
-}
-
-READ8_MEMBER(elan_eu3a05_state::elan_eu3a05_5003_r)
-{
- /* masked with 0x0f, 0x01 or 0x03 depending on situation..
-
- I think it might just be an RNG because if you return 0x00
- your shots can never hit the stage 3 enemies in Phoenix and
- if you return 0xff they always hit. On the real hardware it
- seems to be random. Could also just be a crude frame counter
- used for the same purpose.
-
- */
-
- logerror("%s: elan_eu3a05_5003_r (RNG?)\n", machine().describe_context());
-
- return machine().rand();
-}
-
-
-
-WRITE8_MEMBER(elan_eu3a05_state::elan_eu3a05_500b_unk_w)
-{
- // this is the PAL / NTSC flag when read, so what are writes?
- logerror("%s: elan_eu3a05_500b_unk_w %02x\n", machine().describe_context(), data);
-}
-
// sound callback
READ8_MEMBER(elan_eu3a05_state::read_full_space)
{
@@ -204,25 +191,7 @@ void elan_eu3a05_state::elan_eu3a05_map(address_map &map)
map(0x0000, 0x3fff).ram().share("ram");
map(0x4800, 0x49ff).rw(m_vid, FUNC(elan_eu3a05commonvid_device::palette_r), FUNC(elan_eu3a05commonvid_device::palette_w));
- // 500x system regs?
- map(0x5000, 0x5000).ram();
- map(0x5001, 0x5001).ram();
- // 5002
- map(0x5003, 0x5003).r(FUNC(elan_eu3a05_state::elan_eu3a05_5003_r));
- map(0x5004, 0x5004).ram();
- // 5005
- map(0x5006, 0x5006).ram();
- map(0x5007, 0x5008).rw(m_sys, FUNC(elan_eu3a05commonsys_device::intmask_r), FUNC(elan_eu3a05commonsys_device::intmask_w));
- map(0x5009, 0x5009).ram();
- map(0x500a, 0x500a).ram();
- map(0x500b, 0x500b).rw(FUNC(elan_eu3a05_state::elan_eu3a05_pal_ntsc_r), FUNC(elan_eu3a05_state::elan_eu3a05_500b_unk_w)); // PAL / NTSC flag at least
- map(0x500c, 0x500d).rw(m_sys, FUNC(elan_eu3a05commonsys_device::elan_eu3a05_rombank_r), FUNC(elan_eu3a05commonsys_device::elan_eu3a05_rombank_w));
-
- // 501x DMA controller
- map(0x500f, 0x5015).rw(m_sys, FUNC(elan_eu3a05sys_device::dma_param_r), FUNC(elan_eu3a05sys_device::dma_param_w));
- map(0x5016, 0x5016).rw(m_sys, FUNC(elan_eu3a05sys_device::elan_eu3a05_dmatrg_r), FUNC(elan_eu3a05sys_device::elan_eu3a05_dmatrg_w));
-
- // 502x - 503x video regs area?
+ map(0x5000, 0x501f).m(m_sys, FUNC(elan_eu3a05sys_device::map)); // including DMA controller
map(0x5020, 0x503f).m(m_vid, FUNC(elan_eu3a05vid_device::map));
// 504x GPIO area?
@@ -482,6 +451,7 @@ void elan_eu3a05_state::airblsjs(machine_config& config)
{
elan_eu3a05(config);
m_screen->set_refresh_hz(50);
+ m_sys->set_pal(); // TODO: also set PAL clocks
}
diff --git a/src/mame/drivers/elan_eu3a14.cpp b/src/mame/drivers/elan_eu3a14.cpp
index 312f3bcf910..4437f551ed5 100644
--- a/src/mame/drivers/elan_eu3a14.cpp
+++ b/src/mame/drivers/elan_eu3a14.cpp
@@ -87,8 +87,7 @@ public:
m_bank(*this, "bank"),
m_palette(*this, "palette"),
m_gfxdecode(*this, "gfxdecode"),
- m_screen(*this, "screen"),
- m_tvtype(*this, "TV")
+ m_screen(*this, "screen")
{ }
@@ -105,7 +104,6 @@ private:
INTERRUPT_GEN_MEMBER(interrupt);
- DECLARE_READ8_MEMBER(elan_eu3a05_pal_ntsc_r);
DECLARE_WRITE8_MEMBER(porta_dir_w);
DECLARE_WRITE8_MEMBER(portb_dir_w);
@@ -115,7 +113,6 @@ private:
DECLARE_WRITE8_MEMBER(portb_dat_w);
DECLARE_WRITE8_MEMBER(portc_dat_w);
- DECLARE_READ8_MEMBER(radica_5009_unk_r) { return machine().rand(); };
TIMER_DEVICE_CALLBACK_MEMBER(scanline_cb);
@@ -142,7 +139,6 @@ private:
required_device<palette_device> m_palette;
required_device<gfxdecode_device> m_gfxdecode;
required_device<screen_device> m_screen;
- required_ioport m_tvtype;
uint8_t m_portdir[3];
@@ -173,15 +169,6 @@ READ8_MEMBER(elan_eu3a14_state::read_full_space)
return fullbankspace.read_byte(offset);
}
-
-READ8_MEMBER(elan_eu3a14_state::elan_eu3a05_pal_ntsc_r)
-{
- // how best to handle this, we probably need to run the PAL machine at 50hz
- // the text under the radica logo differs between regions
- logerror("%s: elan_eu3a05_pal_ntsc_r (region + more?)\n", machine().describe_context());
- return m_tvtype->read();
-}
-
WRITE8_MEMBER(elan_eu3a14_state::porta_dir_w)
{
m_portdir[0] = data;
@@ -226,22 +213,7 @@ void elan_eu3a14_state::radica_eu3a14_map(address_map& map)
map(0x4800, 0x4bff).rw(m_vid, FUNC(elan_eu3a14vid_device::palette_r), FUNC(elan_eu3a14vid_device::palette_w));
- // 5000 - 501f = SYSTEM AREA
-
- // similar to eu3a05, at least for pal flags and rom banking
- // 5001 write
- // 5004 write
- // 5006 write
- map(0x5007, 0x5008).rw(m_sys, FUNC(elan_eu3a05commonsys_device::intmask_r), FUNC(elan_eu3a05commonsys_device::intmask_w));
- map(0x5009, 0x5009).r(FUNC(elan_eu3a14_state::radica_5009_unk_r)); // rad_hnt3 polls this on startup
- map(0x500a, 0x500a).nopw(); // startup
- map(0x500b, 0x500b).r(FUNC(elan_eu3a14_state::elan_eu3a05_pal_ntsc_r)).nopw(); // PAL / NTSC flag at least
- map(0x500c, 0x500d).rw(m_sys, FUNC(elan_eu3a05commonsys_device::elan_eu3a05_rombank_r), FUNC(elan_eu3a05commonsys_device::elan_eu3a05_rombank_w));
- // DMA is similar to, but not the same as eu3a05
- map(0x500f, 0x5017).rw(m_sys, FUNC(elan_eu3a14sys_device::dma_param_r), FUNC(elan_eu3a14sys_device::dma_param_w));
- map(0x5018, 0x5018).rw(m_sys, FUNC(elan_eu3a14sys_device::dma_trigger_r), FUNC(elan_eu3a14sys_device::dma_trigger_w));
- // 5019 - 46 on startup (hnt3) 22 (bb3, foot) na (gtg) 09 (rsg)
- // 501a - 01 on startup (hnt3) 03 (bb3, foot) na (gtg) 02,01 (rsg)
+ map(0x5000, 0x501f).m(m_sys, FUNC(elan_eu3a14sys_device::map)); // including DMA controller
// probably GPIO like eu3a05, although it access 47/48 as unknown instead of 48/49/4a
map(0x5040, 0x5040).w(FUNC(elan_eu3a14_state::porta_dir_w));
@@ -323,9 +295,6 @@ static INPUT_PORTS_START( rad_gtg )
PORT_DIPSETTING( 0x20, DEF_STR( Off ) )
PORT_DIPSETTING( 0x00, DEF_STR( On ) )
PORT_BIT( 0xc0, IP_ACTIVE_LOW, IPT_UNUSED )
-
- PORT_START("TV")
- PORT_BIT( 0xff, IP_ACTIVE_LOW, IPT_UNUSED )
INPUT_PORTS_END
@@ -397,16 +366,6 @@ static INPUT_PORTS_START( rad_rsg ) // base unit just has 4 directions + enter a
PORT_DIPNAME( 0x80, 0x80, DEF_STR( Unknown ) )
PORT_DIPSETTING( 0x80, DEF_STR( Off ) )
PORT_DIPSETTING( 0x00, DEF_STR( On ) )
-
- PORT_START("TV")
- PORT_BIT( 0xff, IP_ACTIVE_LOW, IPT_UNUSED )
-INPUT_PORTS_END
-
-static INPUT_PORTS_START( rad_rsgp )
- PORT_INCLUDE(rad_rsg)
-
- PORT_MODIFY("TV")
- PORT_BIT( 0xff, IP_ACTIVE_HIGH, IPT_UNUSED )
INPUT_PORTS_END
@@ -482,9 +441,6 @@ static INPUT_PORTS_START( radica_foot )
PORT_DIPNAME( 0x80, 0x80, DEF_STR( Unknown ) )
PORT_DIPSETTING( 0x80, DEF_STR( Off ) )
PORT_DIPSETTING( 0x00, DEF_STR( On ) )
-
- PORT_START("TV")
- PORT_BIT( 0xff, IP_ACTIVE_HIGH, IPT_UNUSED )
INPUT_PORTS_END
static INPUT_PORTS_START( radica_hnt3 )
@@ -543,19 +499,8 @@ static INPUT_PORTS_START( radica_hnt3 )
PORT_DIPNAME( 0x80, 0x80, DEF_STR( Unknown ) )
PORT_DIPSETTING( 0x80, DEF_STR( Off ) )
PORT_DIPSETTING( 0x00, DEF_STR( On ) )
-
- PORT_START("TV")
- PORT_BIT( 0xff, IP_ACTIVE_LOW, IPT_UNUSED )
-INPUT_PORTS_END
-
-static INPUT_PORTS_START( radica_hnt3p )
- PORT_INCLUDE(radica_hnt3)
-
- PORT_MODIFY("TV")
- PORT_BIT( 0xff, IP_ACTIVE_HIGH, IPT_UNUSED )
INPUT_PORTS_END
-
static INPUT_PORTS_START( radica_bask )
PORT_START("IN0")
PORT_BIT( 0x01, IP_ACTIVE_LOW, IPT_JOYSTICK_RIGHT )
@@ -628,16 +573,6 @@ static INPUT_PORTS_START( radica_bask )
PORT_DIPNAME( 0x80, 0x80, DEF_STR( Unknown ) )
PORT_DIPSETTING( 0x80, DEF_STR( Off ) )
PORT_DIPSETTING( 0x00, DEF_STR( On ) )
-
- PORT_START("TV")
- PORT_BIT( 0xff, IP_ACTIVE_LOW, IPT_UNUSED )
-INPUT_PORTS_END
-
-static INPUT_PORTS_START( radica_baskp )
- PORT_INCLUDE(radica_bask)
-
- PORT_MODIFY("TV")
- PORT_BIT( 0xff, IP_ACTIVE_HIGH, IPT_UNUSED )
INPUT_PORTS_END
static INPUT_PORTS_START( radica_bb3 )
@@ -708,17 +643,8 @@ static INPUT_PORTS_START( radica_bb3 )
PORT_DIPNAME( 0x80, 0x80, DEF_STR( Unknown ) )
PORT_DIPSETTING( 0x80, DEF_STR( Off ) )
PORT_DIPSETTING( 0x00, DEF_STR( On ) )
-
- PORT_START("TV")
- PORT_BIT( 0xff, IP_ACTIVE_LOW, IPT_UNUSED )
INPUT_PORTS_END
-static INPUT_PORTS_START( radica_bb3p )
- PORT_INCLUDE(radica_bb3)
-
- PORT_MODIFY("TV")
- PORT_BIT( 0xff, IP_ACTIVE_HIGH, IPT_UNUSED )
-INPUT_PORTS_END
void elan_eu3a14_state::machine_start()
{
@@ -835,13 +761,13 @@ void elan_eu3a14_state::radica_eu3a14(machine_config &config)
GFXDECODE(config, m_gfxdecode, m_palette, gfx_helper);
/* video hardware */
- screen_device &screen(SCREEN(config, "screen", SCREEN_TYPE_RASTER));
- screen.set_refresh_hz(60);
- screen.set_vblank_time(ATTOSECONDS_IN_USEC(2500));
- screen.set_screen_update(FUNC(elan_eu3a14_state::screen_update));
- screen.set_size(32*8, 32*8);
- screen.set_visarea(0*8, 32*8-1, 0*8, 28*8-1);
- screen.set_palette(m_palette);
+ 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_eu3a14_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);
PALETTE(config, m_palette).set_entries(512);
@@ -884,13 +810,14 @@ void elan_eu3a14_state::radica_eu3a14_altrambase_adc(machine_config &config)
void elan_eu3a14_state::radica_eu3a14p(machine_config &config) // TODO, clocks differ too, what are they on PAL?
{
radica_eu3a14(config);
-
- subdevice<screen_device>("screen")->set_refresh_hz(50);
+ m_sys->set_pal(); // TODO: also set PAL clocks
+ m_screen->set_refresh_hz(50);
}
void elan_eu3a14_state::radica_eu3a14p_altrambase(machine_config& config)
{
radica_eu3a14p(config);
+
m_vid->set_tilerambase(0x0a00 - 0x200);
}
@@ -950,16 +877,16 @@ CONS( 2006, rad_gtg, 0, 0, radica_eu3a14_altrambase_adc, rad_gtg,
CONS( 2005, rad_rsg, 0, 0, radica_eu3a14_altrambase, rad_rsg, elan_eu3a14_state, empty_init, "Radica / FarSight Studios", "Play TV Real Swing Golf", MACHINE_NOT_WORKING )
// some Connectv branded Real Swing Golf units have a language selection (checksum in test mode confirmed as different on said units)
-CONS( 2005, rad_rsgp, rad_rsg, 0, radica_eu3a14p_altrambase, rad_rsgp, elan_eu3a14_state, empty_init, "Radica / FarSight Studios", "Connectv Real Swing Golf", MACHINE_NOT_WORKING )
+CONS( 2005, rad_rsgp, rad_rsg, 0, radica_eu3a14p_altrambase, rad_rsg, elan_eu3a14_state, empty_init, "Radica / FarSight Studios", "Connectv Real Swing Golf", MACHINE_NOT_WORKING )
// also has a Connectv Real Soccer logo in the roms, apparently unused, maybe that was to be the US title (without the logo being changed to Play TV) but Play TV Soccer ended up being a different game licensed from Epoch instead.
CONS( 2006, rad_foot, 0, 0, radica_eu3a14p, radica_foot, elan_eu3a14_state, empty_init, "Radica / Medialink", "Connectv Football", MACHINE_NOT_WORKING )
CONS( 2005, rad_bb3, 0, 0, radica_eu3a14_altrambase, radica_bb3, elan_eu3a14_state, empty_init, "Radica / FarSight Studios", "Play TV Baseball 3", MACHINE_NOT_WORKING )
-CONS( 2005, rad_bb3p, rad_bb3, 0, radica_eu3a14p_altrambase, radica_bb3p, elan_eu3a14_state, empty_init, "Radica / FarSight Studios", "Connectv Baseball 3", MACHINE_NOT_WORKING )
+CONS( 2005, rad_bb3p, rad_bb3, 0, radica_eu3a14p_altrambase, radica_bb3, elan_eu3a14_state, empty_init, "Radica / FarSight Studios", "Connectv Baseball 3", MACHINE_NOT_WORKING )
CONS( 2005, rad_hnt3, 0, 0, radica_eu3a14, radica_hnt3, elan_eu3a14_state, empty_init, "Radica / V-Tac Technology Co Ltd.", "Play TV Huntin' 3", MACHINE_NOT_WORKING )
-CONS( 2005, rad_hnt3p,rad_hnt3, 0, radica_eu3a14p, radica_hnt3p, elan_eu3a14_state, empty_init, "Radica / V-Tac Technology Co Ltd.", "Connectv Huntin' 3", MACHINE_NOT_WORKING )
+CONS( 2005, rad_hnt3p,rad_hnt3, 0, radica_eu3a14p, radica_hnt3, elan_eu3a14_state, empty_init, "Radica / V-Tac Technology Co Ltd.", "Connectv Huntin' 3", MACHINE_NOT_WORKING )
CONS( 2005, rad_bask, 0, 0, radica_eu3a14_altrambase, radica_bask, elan_eu3a14_state, empty_init, "Radica / FarSight Studios", "Play TV Basketball", MACHINE_NOT_WORKING )
-CONS( 2005, rad_baskp,rad_bask, 0, radica_eu3a14p_altrambase, radica_baskp, elan_eu3a14_state, empty_init, "Radica / FarSight Studios", "Connectv Basketball", MACHINE_NOT_WORKING )
+CONS( 2005, rad_baskp,rad_bask, 0, radica_eu3a14p_altrambase, radica_bask, elan_eu3a14_state, empty_init, "Radica / FarSight Studios", "Connectv Basketball", MACHINE_NOT_WORKING )
diff --git a/src/mame/machine/elan_eu3a05commonsys.cpp b/src/mame/machine/elan_eu3a05commonsys.cpp
index 7b1b5f09e5f..a655ae2be1e 100644
--- a/src/mame/machine/elan_eu3a05commonsys.cpp
+++ b/src/mame/machine/elan_eu3a05commonsys.cpp
@@ -172,7 +172,8 @@ DEFINE_DEVICE_TYPE(ELAN_EU3A05_COMMONSYS, elan_eu3a05commonsys_device, "elan_eu3
elan_eu3a05commonsys_device::elan_eu3a05commonsys_device(const machine_config &mconfig, device_type type, const char *tag, device_t *owner, uint32_t clock) :
device_t(mconfig, type, tag, owner, clock),
m_cpu(*this, finder_base::DUMMY_TAG),
- m_bank(*this, finder_base::DUMMY_TAG)
+ m_bank(*this, finder_base::DUMMY_TAG),
+ m_is_pal(false)
{
}
@@ -181,6 +182,38 @@ elan_eu3a05commonsys_device::elan_eu3a05commonsys_device(const machine_config &m
{
}
+
+void elan_eu3a05commonsys_device::map(address_map &map)
+{
+ map(0x00, 0x00).ram();
+ map(0x01, 0x01).ram();
+ // 5002
+ map(0x03, 0x03).r(FUNC(elan_eu3a05commonsys_device::elan_eu3a05_5003_r));
+ map(0x04, 0x04).ram();
+ // 5005
+ map(0x06, 0x06).ram();
+ map(0x07, 0x08).rw(FUNC(elan_eu3a05commonsys_device::intmask_r), FUNC(elan_eu3a05commonsys_device::intmask_w));
+ map(0x09, 0x09).r(FUNC(elan_eu3a05commonsys_device::radica_5009_unk_r)); // rad_hnt3 polls this on startup
+ map(0x0a, 0x0a).ram();
+ map(0x0b, 0x0b).rw(FUNC(elan_eu3a05commonsys_device::elan_eu3a05_pal_ntsc_r), FUNC(elan_eu3a05commonsys_device::elan_eu3a05_500b_unk_w)); // PAL / NTSC flag at least
+ map(0x0c, 0x0d).rw(FUNC(elan_eu3a05commonsys_device::elan_eu3a05_rombank_r), FUNC(elan_eu3a05commonsys_device::elan_eu3a05_rombank_w));
+ // 0e
+}
+
+
+void elan_eu3a05commonsys_device::device_timer(emu_timer &timer, device_timer_id id, int param, void *ptr)
+{
+ switch (id)
+ {
+ case TIMER_UNK:
+ {
+ generate_custom_interrupt(0);
+ break;
+ }
+ }
+}
+
+
void elan_eu3a05commonsys_device::device_start()
{
save_item(NAME(m_rombank_lo));
@@ -190,6 +223,9 @@ void elan_eu3a05commonsys_device::device_start()
save_item(NAME(m_custom_nmi));
save_item(NAME(m_custom_irq_vector));
save_item(NAME(m_custom_nmi_vector));
+
+ m_unk_timer = timer_alloc(TIMER_UNK);
+ m_unk_timer->adjust(attotime::never);
}
void elan_eu3a05commonsys_device::device_reset()
@@ -208,6 +244,8 @@ void elan_eu3a05commonsys_device::device_reset()
m_rombank_hi = 0x00;
m_bank->set_bank(0x7f);
+ // generate at a fixed frequency for now, but can probably be configured. drives 3D stages in Air Blaster Joystick
+ m_unk_timer->adjust(attotime::from_hz(4096), 0, attotime::from_hz(2048));
}
READ8_MEMBER(elan_eu3a05commonsys_device::intmask_r)
@@ -305,3 +343,37 @@ READ8_MEMBER(elan_eu3a05commonsys_device::elan_eu3a05_rombank_r)
return m_rombank_lo;
}
}
+
+
+READ8_MEMBER(elan_eu3a05commonsys_device::elan_eu3a05_pal_ntsc_r)
+{
+ // the text under the radica logo differs between regions, sometimes the titles too
+ logerror("%s: elan_eu3a05_pal_ntsc_r (region + more?)\n", machine().describe_context());
+ if (!m_is_pal) return 0xff; // NTSC
+ else return 0x00; // PAL
+}
+
+READ8_MEMBER(elan_eu3a05commonsys_device::elan_eu3a05_5003_r)
+{
+ /* masked with 0x0f, 0x01 or 0x03 depending on situation..
+
+ I think it might just be an RNG because if you return 0x00
+ your shots can never hit the stage 3 enemies in Phoenix and
+ if you return 0xff they always hit. On the real hardware it
+ seems to be random. Could also just be a crude frame counter
+ used for the same purpose.
+
+ */
+
+ logerror("%s: elan_eu3a05_5003_r (RNG?)\n", machine().describe_context());
+
+ return machine().rand();
+}
+
+
+
+WRITE8_MEMBER(elan_eu3a05commonsys_device::elan_eu3a05_500b_unk_w)
+{
+ // this is the PAL / NTSC flag when read, so what are writes?
+ logerror("%s: elan_eu3a05_500b_unk_w %02x\n", machine().describe_context(), data);
+}
diff --git a/src/mame/machine/elan_eu3a05commonsys.h b/src/mame/machine/elan_eu3a05commonsys.h
index ec7f7cd482e..c7a1fec12dd 100644
--- a/src/mame/machine/elan_eu3a05commonsys.h
+++ b/src/mame/machine/elan_eu3a05commonsys.h
@@ -15,25 +15,24 @@ public:
template <typename T> void set_cpu(T &&tag) { m_cpu.set_tag(std::forward<T>(tag)); }
template <typename T> void set_addrbank(T &&tag) { m_bank.set_tag(std::forward<T>(tag)); }
+ void set_pal(void) { m_is_pal = true; }
void generate_custom_interrupt(int level);
- DECLARE_READ8_MEMBER(intmask_r);
- DECLARE_WRITE8_MEMBER(intmask_w);
+ virtual void map(address_map& map);
DECLARE_READ8_MEMBER(nmi_vector_r);
DECLARE_READ8_MEMBER(irq_vector_r);
- DECLARE_WRITE8_MEMBER(elan_eu3a05_rombank_w);
- DECLARE_READ8_MEMBER(elan_eu3a05_rombank_r);
-
protected:
// device-level overrides
virtual void device_start() override;
virtual void device_reset() override;
+ virtual void device_timer(emu_timer &timer, device_timer_id id, int param, void *ptr) override;
required_device<m6502_device> m_cpu;
required_device<address_map_bank_device> m_bank;
+
uint8_t m_intmask[2];
int m_custom_irq;
@@ -43,6 +42,27 @@ protected:
uint8_t m_rombank_hi;
uint8_t m_rombank_lo;
+
+ bool m_is_pal; // this is usually a jumper connected to the chip that the software can read (clocks also differ on PAL units)
+
+private:
+ DECLARE_READ8_MEMBER(intmask_r);
+ DECLARE_WRITE8_MEMBER(intmask_w);
+
+
+ DECLARE_WRITE8_MEMBER(elan_eu3a05_rombank_w);
+ DECLARE_READ8_MEMBER(elan_eu3a05_rombank_r);
+
+ DECLARE_READ8_MEMBER(elan_eu3a05_5003_r);
+ DECLARE_READ8_MEMBER(elan_eu3a05_pal_ntsc_r);
+ DECLARE_WRITE8_MEMBER(elan_eu3a05_500b_unk_w);
+
+ DECLARE_READ8_MEMBER(radica_5009_unk_r) { return machine().rand(); };
+
+ emu_timer *m_unk_timer;
+ static const device_timer_id TIMER_UNK = 0;
+
+
};
DECLARE_DEVICE_TYPE(ELAN_EU3A05_COMMONSYS, elan_eu3a05commonsys_device)
diff --git a/src/mame/machine/elan_eu3a05sys.cpp b/src/mame/machine/elan_eu3a05sys.cpp
index 462457010fb..94c214ff903 100644
--- a/src/mame/machine/elan_eu3a05sys.cpp
+++ b/src/mame/machine/elan_eu3a05sys.cpp
@@ -9,10 +9,26 @@
DEFINE_DEVICE_TYPE(ELAN_EU3A05_SYS, elan_eu3a05sys_device, "elan_eu3a05sys", "Elan EU3A05 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_eu3a05commonsys_device(mconfig, ELAN_EU3A05_SYS, 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))
{
}
+device_memory_interface::space_config_vector elan_eu3a05sys_device::memory_space_config() const
+{
+ return space_config_vector {
+ std::make_pair(0, &m_space_config)
+ };
+}
+
+void elan_eu3a05sys_device::map(address_map& map)
+{
+ elan_eu3a05commonsys_device::map(map); // 00 - 0e
+ map(0x0f, 0x15).rw(FUNC(elan_eu3a05sys_device::dma_param_r), FUNC(elan_eu3a05sys_device::dma_param_w));
+ map(0x16, 0x16).rw(FUNC(elan_eu3a05sys_device::elan_eu3a05_dmatrg_r), FUNC(elan_eu3a05sys_device::elan_eu3a05_dmatrg_w));
+}
+
void elan_eu3a05sys_device::device_start()
{
elan_eu3a05commonsys_device::device_start();
diff --git a/src/mame/machine/elan_eu3a05sys.h b/src/mame/machine/elan_eu3a05sys.h
index 72e971a7556..8905eb570e2 100644
--- a/src/mame/machine/elan_eu3a05sys.h
+++ b/src/mame/machine/elan_eu3a05sys.h
@@ -6,7 +6,7 @@
#include "elan_eu3a05commonsys.h"
-class elan_eu3a05sys_device : public elan_eu3a05commonsys_device
+class elan_eu3a05sys_device : public elan_eu3a05commonsys_device, public device_memory_interface
{
public:
elan_eu3a05sys_device(const machine_config &mconfig, const char *tag, device_t *owner, uint32_t clock);
@@ -17,12 +17,16 @@ public:
DECLARE_READ8_MEMBER(dma_param_r);
DECLARE_WRITE8_MEMBER(dma_param_w);
+ 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;
private:
+ const address_space_config m_space_config;
uint8_t m_dmaparams[7];
};
diff --git a/src/mame/machine/elan_eu3a14sys.cpp b/src/mame/machine/elan_eu3a14sys.cpp
index 2c9871fc5f1..ea0c955fba8 100644
--- a/src/mame/machine/elan_eu3a14sys.cpp
+++ b/src/mame/machine/elan_eu3a14sys.cpp
@@ -9,10 +9,28 @@
DEFINE_DEVICE_TYPE(ELAN_EU3A14_SYS, elan_eu3a14sys_device, "elan_eu3a14sys", "Elan EU3A14 System")
elan_eu3a14sys_device::elan_eu3a14sys_device(const machine_config &mconfig, const char *tag, device_t *owner, uint32_t clock) :
- elan_eu3a05commonsys_device(mconfig, ELAN_EU3A14_SYS, tag, owner, clock)
+ elan_eu3a05commonsys_device(mconfig, ELAN_EU3A14_SYS, tag, owner, clock),
+ device_memory_interface(mconfig, *this),
+ m_space_config("regs", ENDIANNESS_NATIVE, 8, 5, 0, address_map_constructor(FUNC(elan_eu3a14sys_device::map), this))
{
}
+device_memory_interface::space_config_vector elan_eu3a14sys_device::memory_space_config() const
+{
+ return space_config_vector {
+ std::make_pair(0, &m_space_config)
+ };
+}
+
+void elan_eu3a14sys_device::map(address_map& map)
+{
+ elan_eu3a05commonsys_device::map(map); // 00 - 0e
+ map(0x0f, 0x17).rw(FUNC(elan_eu3a14sys_device::dma_param_r), FUNC(elan_eu3a14sys_device::dma_param_w));
+ map(0x18, 0x18).rw(FUNC(elan_eu3a14sys_device::dma_trigger_r), FUNC(elan_eu3a14sys_device::dma_trigger_w));
+ // 5019 - 46 on startup (hnt3) 22 (bb3, foot) na (gtg) 09 (rsg)
+ // 501a - 01 on startup (hnt3) 03 (bb3, foot) na (gtg) 02,01 (rsg)
+}
+
void elan_eu3a14sys_device::device_start()
{
elan_eu3a05commonsys_device::device_start();
diff --git a/src/mame/machine/elan_eu3a14sys.h b/src/mame/machine/elan_eu3a14sys.h
index 02162af7541..47eed32e8f3 100644
--- a/src/mame/machine/elan_eu3a14sys.h
+++ b/src/mame/machine/elan_eu3a14sys.h
@@ -6,7 +6,7 @@
#include "elan_eu3a05commonsys.h"
-class elan_eu3a14sys_device : public elan_eu3a05commonsys_device
+class elan_eu3a14sys_device : public elan_eu3a05commonsys_device, public device_memory_interface
{
public:
elan_eu3a14sys_device(const machine_config &mconfig, const char *tag, device_t *owner, uint32_t clock);
@@ -17,12 +17,16 @@ public:
DECLARE_READ8_MEMBER(dma_param_r);
DECLARE_WRITE8_MEMBER(dma_param_w);
+ 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;
private:
+ const address_space_config m_space_config;
uint8_t m_dmaparams[9];
};
diff --git a/src/mame/video/elan_eu3a05vid.cpp b/src/mame/video/elan_eu3a05vid.cpp
index faf9419729a..cd846531ec9 100644
--- a/src/mame/video/elan_eu3a05vid.cpp
+++ b/src/mame/video/elan_eu3a05vid.cpp
@@ -356,18 +356,17 @@ void elan_eu3a05vid_device::draw_tilemaps(screen_device& screen, bitmap_ind16& b
// split can be probably configured in more ways than this
// exact enable conditions unclear
- int splitpos = (m_splitpos[0] << 8) | m_splitpos[1];
-
- if (splitpos != 0xffff)
+ if (drawline < m_splitpos[0])
{
- if (drawline > splitpos)
- scrollx = get_scroll(3);
- else
- scrollx = get_scroll(2);
+ scrollx = get_scroll(0);
+ }
+ else if (drawline < m_splitpos[1])
+ {
+ scrollx = get_scroll(2);
}
else
{
- scrollx = get_scroll(0);
+ scrollx = get_scroll(3);
}
int base;