summaryrefslogtreecommitdiffstatshomepage
diff options
context:
space:
mode:
author David Haywood <28625134+DavidHaywood@users.noreply.github.com>2019-11-08 14:55:59 +0000
committer R. Belmont <rb6502@users.noreply.github.com>2019-11-08 09:55:59 -0500
commitab39e40669dbd4303ddeccbe099b61d9752ab558 (patch)
treecf4db7f46863605fd00e7c018c2a47ed40eddf18
parent56a4a69a0a7dfb030958bd733bce36ce1df6e431 (diff)
start trying to identify more sound related features on the elan hw (nw) + Senario Poker SunPlus (not working) (#5874)
* elan sound stuff (nw) * move more audio bits into audio file (nw) * new NOT WORKING machines ----- Texas Hold'em TV Poker - 6 Player Edition (UK) [David Haywood, Morten Kirkegaard, Peter Wilhelmsen] need to emulate the controllers etc. (currently requires debug hack to boot past initial logo) * start moving some more elan stuff around (nw)
-rw-r--r--scripts/target/mame/mess.lua2
-rw-r--r--src/devices/machine/spg2xx_video.cpp52
-rw-r--r--src/devices/machine/spg2xx_video.h1
-rw-r--r--src/mame/audio/elan_eu3a05.cpp149
-rw-r--r--src/mame/audio/elan_eu3a05.h33
-rw-r--r--src/mame/drivers/elan_eu3a05.cpp43
-rw-r--r--src/mame/drivers/elan_eu3a14.cpp867
-rw-r--r--src/mame/drivers/vii.cpp190
-rw-r--r--src/mame/mame.lst1
-rw-r--r--src/mame/video/elan_eu3a14vid.cpp766
-rw-r--r--src/mame/video/elan_eu3a14vid.h90
11 files changed, 1343 insertions, 851 deletions
diff --git a/scripts/target/mame/mess.lua b/scripts/target/mame/mess.lua
index bbfef8126bd..75f4b36ca91 100644
--- a/scripts/target/mame/mess.lua
+++ b/scripts/target/mame/mess.lua
@@ -3711,6 +3711,8 @@ files {
MAME_DIR .. "src/mame/video/elan_eu3a05commonvid.h",
MAME_DIR .. "src/mame/video/elan_eu3a05vid.cpp",
MAME_DIR .. "src/mame/video/elan_eu3a05vid.h",
+ MAME_DIR .. "src/mame/video/elan_eu3a14vid.cpp",
+ MAME_DIR .. "src/mame/video/elan_eu3a14vid.h",
MAME_DIR .. "src/mame/drivers/trkfldch.cpp",
MAME_DIR .. "src/mame/drivers/tvgame.cpp",
MAME_DIR .. "src/mame/drivers/spg110.cpp",
diff --git a/src/devices/machine/spg2xx_video.cpp b/src/devices/machine/spg2xx_video.cpp
index daef752bc82..3fde969d344 100644
--- a/src/devices/machine/spg2xx_video.cpp
+++ b/src/devices/machine/spg2xx_video.cpp
@@ -209,6 +209,51 @@ void spg2xx_video_device::draw(const rectangle &cliprect, uint32_t line, uint32_
}
}
+void spg2xx_video_device::draw_bitmap(const rectangle& cliprect, uint32_t scanline, int priority, uint32_t bitmap_addr, uint16_t* regs)
+{
+ if ((scanline < 0) || (scanline >= 240))
+ return;
+
+ address_space& space = m_cpu->space(AS_PROGRAM);
+ const int linewidth = 320 / 2;
+ int sourcebase = 0x3f0000; // this is correct for Texas Hold'em - TODO: get from a register?
+
+ sourcebase++; // why is this needed?
+ int bitmapline = scanline - 20; // should be from scrolly?
+
+ // at least for Texas Hold'em there is only enough memory for this size bitmap, and other reads would be outside of memory and generate excessive logging
+ // maybe we just need to silence logging instead tho?
+ if ((bitmapline < 0) || (bitmapline >= 200))
+ return;
+
+ sourcebase += bitmapline * linewidth;
+
+ uint32_t* dest = &m_screenbuf[320 * scanline];
+
+ for (int i = 0; i < 320 / 2; i++)
+ {
+ uint8_t palette_entry;
+ uint16_t color;
+ const uint16_t data = space.read_word(sourcebase + i);
+
+ palette_entry = (data & 0x00ff);
+ color = m_paletteram[palette_entry];
+
+ if (!(color & 0x8000))
+ {
+ dest[(i * 2)+0] = m_rgb555_to_rgb888[color & 0x7fff];
+ }
+
+ palette_entry = (data & 0xff00) >> 8;
+ color = m_paletteram[palette_entry];
+
+ if (!(color & 0x8000))
+ {
+ dest[(i * 2)+1] = m_rgb555_to_rgb888[color & 0x7fff];
+ }
+ }
+}
+
void spg2xx_video_device::draw_page(const rectangle &cliprect, uint32_t scanline, int priority, uint32_t bitmap_addr, uint16_t *regs)
{
uint32_t xscroll = regs[0];
@@ -229,6 +274,13 @@ void spg2xx_video_device::draw_page(const rectangle &cliprect, uint32_t scanline
return;
}
+ if (ctrl & 0x0001) // Bitmap mode!
+ {
+ draw_bitmap(cliprect, scanline, priority, bitmap_addr, regs);
+ return;
+ }
+
+
uint32_t tile_h = 8 << ((attr & PAGE_TILE_HEIGHT_MASK) >> PAGE_TILE_HEIGHT_SHIFT);
uint32_t tile_w = 8 << ((attr & PAGE_TILE_WIDTH_MASK) >> PAGE_TILE_WIDTH_SHIFT);
diff --git a/src/devices/machine/spg2xx_video.h b/src/devices/machine/spg2xx_video.h
index df98a1a639d..95bdd22cafe 100644
--- a/src/devices/machine/spg2xx_video.h
+++ b/src/devices/machine/spg2xx_video.h
@@ -84,6 +84,7 @@ protected:
template<blend_enable_t Blend, rowscroll_enable_t RowScroll, flipx_t FlipX>
void draw(const rectangle &cliprect, uint32_t line, uint32_t xoff, uint32_t yoff, uint32_t bitmap_addr, uint16_t tile, int32_t h, int32_t w, uint8_t bpp, uint32_t yflipmask, uint32_t palette_offset);
+ void draw_bitmap(const rectangle& cliprect, uint32_t scanline, int priority, uint32_t bitmap_addr, uint16_t* regs);
void draw_page(const rectangle &cliprect, uint32_t scanline, int priority, uint32_t bitmap_addr, uint16_t *regs);
void draw_sprite(const rectangle &cliprect, uint32_t scanline, int priority, uint32_t base_addr);
void draw_sprites(const rectangle &cliprect, uint32_t scanline, int priority);
diff --git a/src/mame/audio/elan_eu3a05.cpp b/src/mame/audio/elan_eu3a05.cpp
index 814849e3a43..b80258f32f0 100644
--- a/src/mame/audio/elan_eu3a05.cpp
+++ b/src/mame/audio/elan_eu3a05.cpp
@@ -16,11 +16,12 @@ DEFINE_DEVICE_TYPE(ELAN_EU3A05_SOUND, elan_eu3a05_sound_device, "elan_eu3a05soun
#include "logmacro.h"
-elan_eu3a05_sound_device::elan_eu3a05_sound_device(const machine_config &mconfig, const char *tag, device_t *owner, uint32_t clock)
- : device_t(mconfig, ELAN_EU3A05_SOUND, tag, owner, clock)
- , device_sound_interface(mconfig, *this)
- , m_stream(nullptr)
- , m_space_read_cb(*this)
+elan_eu3a05_sound_device::elan_eu3a05_sound_device(const machine_config &mconfig, const char *tag, device_t *owner, uint32_t clock) :
+ device_t(mconfig, ELAN_EU3A05_SOUND, tag, owner, clock),
+ device_sound_interface(mconfig, *this),
+ m_stream(nullptr),
+ m_space_read_cb(*this),
+ m_sound_end_cb{ { *this }, { *this }, { *this }, { *this }, { *this }, { *this } }
{
}
@@ -28,6 +29,19 @@ void elan_eu3a05_sound_device::device_start()
{
m_space_read_cb.resolve_safe(0);
m_stream = stream_alloc(0, 1, 8000);
+
+ for (devcb_write_line &cb : m_sound_end_cb)
+ cb.resolve_safe();
+
+ save_item(NAME(m_sound_byte_address));
+ save_item(NAME(m_sound_byte_len));
+ save_item(NAME(m_sound_current_nib_pos));
+ save_item(NAME(m_isstopped));
+ save_item(NAME(m_sound_trigger));
+ save_item(NAME(m_sound_unk));
+ save_item(NAME(m_volumes));
+ save_item(NAME(m_5024));
+ save_item(NAME(m_50a9));
}
void elan_eu3a05_sound_device::device_reset()
@@ -40,6 +54,15 @@ void elan_eu3a05_sound_device::device_reset()
}
m_isstopped = 0x3f;
+
+ m_sound_trigger = 0x00;
+ m_sound_unk = 0x00;
+
+ m_volumes[0] = 0xff;
+ m_volumes[1] = 0x0f;
+
+ m_5024 = 0x00;
+ m_50a9 = 0x00;
}
//-------------------------------------------------
@@ -81,8 +104,7 @@ void elan_eu3a05_sound_device::sound_stream_update(sound_stream &stream, stream_
m_sound_current_nib_pos[channel] = 0;
m_isstopped |= (1 << channel);
- // maybe should generate an interrupt with vector
- // ffb8, ffbc, ffc0, ffc4, ffc8, or ffcc depending on which channel finished??
+ m_sound_end_cb[channel](1); // generate interrupt based on which channel just stopped?
}
}
else
@@ -95,6 +117,8 @@ void elan_eu3a05_sound_device::sound_stream_update(sound_stream &stream, stream_
}
+
+
void elan_eu3a05_sound_device::handle_sound_addr_w(int which, int offset, uint8_t data)
{
switch (offset)
@@ -260,8 +284,11 @@ void elan_eu3a05_sound_device::handle_sound_trigger(int which)
{
LOGMASKED( LOG_AUDIO, "Triggering operation on channel (%d) with params %08x %08x\n", which, m_sound_byte_address[which], m_sound_byte_len[which]);
- m_sound_current_nib_pos[which] = 0;
- m_isstopped &= ~(1 << which);
+ if (m_isstopped & (1 << which)) // golden tee will repeatedly try to start the music on the title screen (although could depend on a status read first?)
+ {
+ m_sound_current_nib_pos[which] = 0;
+ m_isstopped &= ~(1 << which);
+ }
}
@@ -272,3 +299,107 @@ READ8_MEMBER(elan_eu3a05_sound_device::elan_eu3a05_50a8_r)
LOGMASKED( LOG_AUDIO, "%s: elan_eu3a05_50a8_r\n", machine().describe_context());
return m_isstopped;
}
+
+READ8_MEMBER(elan_eu3a05_sound_device::elan_eu3a05_sound_volume_r)
+{
+ return m_volumes[offset];
+}
+
+WRITE8_MEMBER(elan_eu3a05_sound_device::elan_eu3a05_sound_volume_w)
+{
+ m_volumes[offset] = data;
+}
+
+WRITE8_MEMBER(elan_eu3a05_sound_device::write)
+{
+ switch (offset)
+ {
+ case 0x00: case 0x01: case 0x02: // channel 0 address
+ case 0x03: case 0x04: case 0x05: // channel 1 address
+ case 0x06: case 0x07: case 0x08: // channel 2 address
+ case 0x09: case 0x0a: case 0x0b: // channel 3 address
+ case 0x0c: case 0x0d: case 0x0e: // channel 4 address
+ case 0x0f: case 0x10: case 0x11: // channel 5 address
+ elan_eu3a05_sound_addr_w(space, offset, data);
+ break;
+
+ case 0x12: case 0x13: case 0x14: // channel 0 length
+ case 0x15: case 0x16: case 0x17: // channel 1 length
+ case 0x18: case 0x19: case 0x1a: // channel 2 length
+ case 0x1b: case 0x1c: case 0x1d: // channel 3 length
+ case 0x1e: case 0x1f: case 0x20: // channel 4 length
+ case 0x21: case 0x22: case 0x23: // channel 5 length
+ elan_eu3a05_sound_size_w(space, offset - 0x12, data);
+ break;
+
+ case 0x24: // unk
+ m_5024 = data;
+ break;
+
+ case 0x25: // trigger
+ elan_eu3a05_sound_trigger_w(space, offset - 0x25, data);
+ break;
+
+ case 0x26: // volume channels 0,1,2,3 ? (lunar rescue sets 0x03 here and 0x00 below and just uses a single channel)
+ case 0x27: // volume channels 5,6 ?
+ elan_eu3a05_sound_volume_w(space, offset - 0x26, data);
+ break;
+
+ case 0x28: // stopped status?
+ LOGMASKED( LOG_AUDIO, "%s: write to stop state register? %02x\n", machine().describe_context(), data);
+ break;
+
+ case 0x29: // interrupt enable? or looping?
+ m_50a9 = data;
+ break;
+ }
+}
+
+READ8_MEMBER(elan_eu3a05_sound_device::read)
+{
+ uint8_t ret = 0x00;
+
+ switch (offset)
+ {
+ case 0x00: case 0x01: case 0x02: // channel 0 address
+ case 0x03: case 0x04: case 0x05: // channel 1 address
+ case 0x06: case 0x07: case 0x08: // channel 2 address
+ case 0x09: case 0x0a: case 0x0b: // channel 3 address
+ case 0x0c: case 0x0d: case 0x0e: // channel 4 address
+ case 0x0f: case 0x10: case 0x11: // channel 5 address
+ ret = elan_eu3a05_sound_addr_r(space, offset);
+ break;
+
+ case 0x12: case 0x13: case 0x14: // channel 0 length
+ case 0x15: case 0x16: case 0x17: // channel 1 length
+ case 0x18: case 0x19: case 0x1a: // channel 2 length
+ case 0x1b: case 0x1c: case 0x1d: // channel 3 length
+ case 0x1e: case 0x1f: case 0x20: // channel 4 length
+ case 0x21: case 0x22: case 0x23: // channel 5 length
+ ret = elan_eu3a05_sound_size_r(space, offset - 0x12);
+ break;
+
+ case 0x24: // unk
+ ret = m_5024;
+ break;
+
+ case 0x25: // trigger
+ ret = elan_eu3a05_sound_trigger_r(space, offset - 0x25);
+ break;
+
+ case 0x26: // volume channels 0,1,2,3 ?
+ case 0x27: // volume channels 5,6 ?
+ ret = elan_eu3a05_sound_volume_r(space, offset - 0x26);
+ break;
+
+ case 0x28: // stopped status?
+ ret = elan_eu3a05_50a8_r(space, offset - 0x28);
+ break;
+
+ case 0x29: // interrupt enable? or looping?
+ ret = m_50a9;
+ break;
+ }
+
+ return ret;
+} \ No newline at end of file
diff --git a/src/mame/audio/elan_eu3a05.h b/src/mame/audio/elan_eu3a05.h
index e56f8cdc166..867998051be 100644
--- a/src/mame/audio/elan_eu3a05.h
+++ b/src/mame/audio/elan_eu3a05.h
@@ -18,16 +18,11 @@ public:
auto space_read_callback() { return m_space_read_cb.bind(); }
- DECLARE_WRITE8_MEMBER(elan_eu3a05_sound_addr_w);
- DECLARE_READ8_MEMBER(elan_eu3a05_sound_addr_r);
- DECLARE_WRITE8_MEMBER(elan_eu3a05_sound_size_w);
- DECLARE_READ8_MEMBER(elan_eu3a05_sound_size_r);
- DECLARE_READ8_MEMBER(elan_eu3a05_sound_trigger_r);
- DECLARE_WRITE8_MEMBER(elan_eu3a05_sound_trigger_w);
- DECLARE_READ8_MEMBER(elan_eu3a05_sound_unk_r);
- DECLARE_WRITE8_MEMBER(elan_eu3a05_sound_unk_w);
+ template <unsigned N> auto sound_end_cb() { return m_sound_end_cb[N].bind(); }
+
+ DECLARE_WRITE8_MEMBER(write);
+ DECLARE_READ8_MEMBER(read);
- DECLARE_READ8_MEMBER(elan_eu3a05_50a8_r);
protected:
// device-level overrides
virtual void device_start() override;
@@ -49,12 +44,32 @@ private:
uint8_t m_isstopped;
+ uint8_t m_volumes[2];
+ uint8_t m_5024;
+ uint8_t m_50a9;
+
void handle_sound_trigger(int which);
void handle_sound_addr_w(int which, int offset, uint8_t data);
uint8_t handle_sound_addr_r(int which, int offset);
void handle_sound_size_w(int which, int offset, uint8_t data);
uint8_t handle_sound_size_r(int which, int offset);
+
+ DECLARE_WRITE8_MEMBER(elan_eu3a05_sound_addr_w);
+ DECLARE_READ8_MEMBER(elan_eu3a05_sound_addr_r);
+ DECLARE_WRITE8_MEMBER(elan_eu3a05_sound_size_w);
+ DECLARE_READ8_MEMBER(elan_eu3a05_sound_size_r);
+ DECLARE_READ8_MEMBER(elan_eu3a05_sound_trigger_r);
+ DECLARE_WRITE8_MEMBER(elan_eu3a05_sound_trigger_w);
+ DECLARE_READ8_MEMBER(elan_eu3a05_sound_unk_r);
+ DECLARE_WRITE8_MEMBER(elan_eu3a05_sound_unk_w);
+
+ DECLARE_READ8_MEMBER(elan_eu3a05_50a8_r);
+
+ DECLARE_READ8_MEMBER(elan_eu3a05_sound_volume_r);
+ DECLARE_WRITE8_MEMBER(elan_eu3a05_sound_volume_w);
+
+ devcb_write_line m_sound_end_cb[6];
};
DECLARE_DEVICE_TYPE(ELAN_EU3A05_SOUND, elan_eu3a05_sound_device)
diff --git a/src/mame/drivers/elan_eu3a05.cpp b/src/mame/drivers/elan_eu3a05.cpp
index 903918779ff..06b077c0704 100644
--- a/src/mame/drivers/elan_eu3a05.cpp
+++ b/src/mame/drivers/elan_eu3a05.cpp
@@ -107,10 +107,6 @@ private:
DECLARE_READ8_MEMBER(elan_eu3a05_pal_ntsc_r);
DECLARE_WRITE8_MEMBER(elan_eu3a05_500b_unk_w);
- // more sound regs?
- DECLARE_READ8_MEMBER(elan_eu3a05_50a9_r);
- DECLARE_WRITE8_MEMBER(elan_eu3a05_50a9_w);
-
INTERRUPT_GEN_MEMBER(interrupt);
// for callback
@@ -137,7 +133,12 @@ private:
required_device<gfxdecode_device> m_gfxdecode;
required_device<palette_device> m_palette;
- uint8_t m_50a9_data;
+ 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); }
};
void elan_eu3a05_state::video_start()
@@ -180,19 +181,6 @@ READ8_MEMBER(elan_eu3a05_state::elan_eu3a05_5003_r)
-// probably also sound device, maybe for forcing channels to stop?
-READ8_MEMBER(elan_eu3a05_state::elan_eu3a05_50a9_r)
-{
- logerror("%s: elan_eu3a05_50a9_r\n", machine().describe_context());
- return m_50a9_data;
-}
-
-WRITE8_MEMBER(elan_eu3a05_state::elan_eu3a05_50a9_w)
-{
- logerror("%s: elan_eu3a05_50a9_w %02x\n", machine().describe_context(), data);
- m_50a9_data = data;
-}
-
WRITE8_MEMBER(elan_eu3a05_state::elan_eu3a05_500b_unk_w)
{
// this is the PAL / NTSC flag when read, so what are writes?
@@ -253,17 +241,10 @@ void elan_eu3a05_state::elan_eu3a05_map(address_map &map)
map(0x5048, 0x504a).w(m_gpio, FUNC(elan_eu3a05gpio_device::gpio_unk_w));
// 506x unknown
- map(0x5060, 0x506d).ram(); // read/written by tetris
+ map(0x5060, 0x506d).ram(); // read/written by tetris (ADC?)
// 508x sound
- map(0x5080, 0x5091).rw(m_sound, FUNC(elan_eu3a05_sound_device::elan_eu3a05_sound_addr_r), FUNC(elan_eu3a05_sound_device::elan_eu3a05_sound_addr_w));
- map(0x5092, 0x50a3).rw(m_sound, FUNC(elan_eu3a05_sound_device::elan_eu3a05_sound_size_r), FUNC(elan_eu3a05_sound_device::elan_eu3a05_sound_size_w));
- map(0x50a4, 0x50a4).rw(m_sound, FUNC(elan_eu3a05_sound_device::elan_eu3a05_sound_unk_r), FUNC(elan_eu3a05_sound_device::elan_eu3a05_sound_unk_w));
- map(0x50a5, 0x50a5).rw(m_sound, FUNC(elan_eu3a05_sound_device::elan_eu3a05_sound_trigger_r), FUNC(elan_eu3a05_sound_device::elan_eu3a05_sound_trigger_w));
- map(0x50a6, 0x50a6).ram();
- map(0x50a7, 0x50a7).ram();
- map(0x50a8, 0x50a8).r(m_sound, FUNC(elan_eu3a05_sound_device::elan_eu3a05_50a8_r)); // possible 'stopped' status of above channels, waits for it to be 0x3f in places
- map(0x50a9, 0x50a9).rw(FUNC(elan_eu3a05_state::elan_eu3a05_50a9_r), FUNC(elan_eu3a05_state::elan_eu3a05_50a9_w));
+ map(0x5080, 0x50a9).rw(m_sound, FUNC(elan_eu3a05_sound_device::read), FUNC(elan_eu3a05_sound_device::write));
//map(0x5000, 0x50ff).ram();
map(0x6000, 0xdfff).m(m_bank, FUNC(address_map_bank_device::amap8));
@@ -497,6 +478,14 @@ void elan_eu3a05_state::elan_eu3a05(machine_config &config)
ELAN_EU3A05_SOUND(config, m_sound, 8000);
m_sound->space_read_callback().set(FUNC(elan_eu3a05_state::read_full_space));
m_sound->add_route(ALL_OUTPUTS, "mono", 1.0);
+ /* just causes select sound to loop in Tetris for now!
+ m_sound->sound_end_cb<0>().set(FUNC(elan_eu3a05_state::sound_end0));
+ m_sound->sound_end_cb<1>().set(FUNC(elan_eu3a05_state::sound_end1));
+ m_sound->sound_end_cb<2>().set(FUNC(elan_eu3a05_state::sound_end2));
+ m_sound->sound_end_cb<3>().set(FUNC(elan_eu3a05_state::sound_end3));
+ m_sound->sound_end_cb<4>().set(FUNC(elan_eu3a05_state::sound_end4));
+ m_sound->sound_end_cb<5>().set(FUNC(elan_eu3a05_state::sound_end5));
+ */
}
void elan_eu3a05_state::airblsjs(machine_config& config)
diff --git a/src/mame/drivers/elan_eu3a14.cpp b/src/mame/drivers/elan_eu3a14.cpp
index bc324de3c05..f0519473c68 100644
--- a/src/mame/drivers/elan_eu3a14.cpp
+++ b/src/mame/drivers/elan_eu3a14.cpp
@@ -69,7 +69,7 @@
#include "audio/elan_eu3a05.h"
#include "machine/timer.h"
#include "machine/elan_eu3a14sys.h"
-#include "video/elan_eu3a05commonvid.h"
+#include "video/elan_eu3a14vid.h"
@@ -81,16 +81,8 @@ public:
m_maincpu(*this, "maincpu"),
m_sys(*this, "sys"),
m_sound(*this, "eu3a05sound"),
- m_commonvid(*this, "commonvid"),
+ m_vid(*this, "commonvid"),
m_mainregion(*this, "maincpu"),
- m_scrollregs(*this, "scrollregs"),
- m_tilecfg(*this, "tilecfg"),
- m_rowscrollregs(*this, "rowscrollregs"),
- m_rowscrollsplit(*this, "rowscrollsplit"),
- m_rowscrollcfg(*this, "rowscrollcfg"),
- m_ramtilecfg(*this, "ramtilecfg"),
- m_spriteaddr(*this, "spriteaddr"),
- m_spritebase(*this, "spritebase"),
m_mainram(*this, "mainram"),
m_bank(*this, "bank"),
m_palette(*this, "palette"),
@@ -101,12 +93,11 @@ public:
void radica_eu3a14(machine_config &config);
- void radica_eu3a14_adc(machine_config &config);
void radica_eu3a14p(machine_config &config);
- void init_rad_gtg();
- void init_rad_foot();
- void init_rad_hnt3();
+ void radica_eu3a14p_altrambase(machine_config &config);
+ void radica_eu3a14_altrambase(machine_config& config);
+ void radica_eu3a14_altrambase_adc(machine_config &config);
private:
// screen updates
@@ -116,7 +107,6 @@ private:
DECLARE_READ8_MEMBER(elan_eu3a05_pal_ntsc_r);
-
DECLARE_WRITE8_MEMBER(porta_dir_w);
DECLARE_WRITE8_MEMBER(portb_dir_w);
DECLARE_WRITE8_MEMBER(portc_dir_w);
@@ -125,11 +115,8 @@ private:
DECLARE_WRITE8_MEMBER(portb_dat_w);
DECLARE_WRITE8_MEMBER(portc_dat_w);
-
DECLARE_READ8_MEMBER(radica_5009_unk_r) { return machine().rand(); };
- DECLARE_READ8_MEMBER(random_r) { return machine().rand(); };
-
TIMER_DEVICE_CALLBACK_MEMBER(scanline_cb);
// for callback
@@ -147,16 +134,9 @@ private:
required_device<cpu_device> m_maincpu;
required_device<elan_eu3a14sys_device> m_sys;
required_device<elan_eu3a05_sound_device> m_sound;
- required_device<elan_eu3a05commonvid_device> m_commonvid;
+ required_device<elan_eu3a14vid_device> m_vid;
required_region_ptr<uint8_t> m_mainregion;
- required_shared_ptr<uint8_t> m_scrollregs;
- required_shared_ptr<uint8_t> m_tilecfg;
- required_shared_ptr<uint8_t> m_rowscrollregs;
- required_shared_ptr<uint8_t> m_rowscrollsplit;
- required_shared_ptr<uint8_t> m_rowscrollcfg;
- required_shared_ptr<uint8_t> m_ramtilecfg;
- required_shared_ptr<uint8_t> m_spriteaddr;
- required_shared_ptr<uint8_t> m_spritebase;
+
required_shared_ptr<uint8_t> m_mainram;
required_device<address_map_bank_device> m_bank;
required_device<palette_device> m_palette;
@@ -164,746 +144,26 @@ private:
required_device<screen_device> m_screen;
required_ioport m_tvtype;
- int m_tilerambase;
- int m_spriterambase;
-
- bitmap_ind8 m_prioritybitmap;
-
uint8_t m_portdir[3];
- void draw_background_ramlayer(screen_device& screen, bitmap_ind16& bitmap, const rectangle& cliprect);
- int get_xscroll_for_screenypos(int line);
- void draw_background_tile(bitmap_ind16 &bitmap, const rectangle &cliprect, int bpp, int tileno, int palette, int priority, int flipx, int flipy, int xpos, int ypos, int transpen, int size, int base, int drawfromram);
- void draw_background_page(screen_device &screen, bitmap_ind16 &bitmap, const rectangle &cliprect, int ramstart, int ramend, int xbase, int ybase, int size, int bpp, int base, int pagewidth,int pageheight, int bytespertile, int palettepri, int drawfromram);
- void draw_background(screen_device &screen, bitmap_ind16 &bitmap, const rectangle &cliprect);
- void draw_sprite_pix(const rectangle& cliprect, uint16_t* dst, uint8_t* pridst, int realx, int priority, uint8_t pix, uint8_t mask, uint8_t shift, int palette);
- void draw_sprite_line(screen_device &screen, bitmap_ind16 &bitmap, const rectangle &cliprect, int offset, int line, int pal, int flipx, int pri, int xpos, int ypos, int bpp);
- void draw_sprites(screen_device &screen, bitmap_ind16 &bitmap, const rectangle &cliprect);
+ 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); }
};
void elan_eu3a14_state::video_start()
{
- m_screen->register_screen_bitmap(m_prioritybitmap);
-}
-
-void elan_eu3a14_state::draw_background_tile(bitmap_ind16& bitmap, const rectangle& cliprect, int bpp, int tileno, int palette, int priority, int flipx, int flipy, int xpos, int ypos, int transpen, int size, int base, int drawfromram)
-{
- int baseaddr = base * 256;
-
- int xstride = 8;
-
- if (bpp == 8) // 8bpp selection
- {
- if (size == 8)
- {
- xstride = size / 1; baseaddr += tileno * 64; // 8x8 8bpp
- }
- else
- {
- xstride = size / 1; baseaddr += tileno * 256; // 16x16 8bpp
- }
-
- palette &= 0x100; // only top bit valid, as there are only 2 palettes?
- }
- else if (bpp == 4) // 4bpp selection
- {
- if (size == 8)
- {
- xstride = size / 2; baseaddr += tileno * 32; // 8x8 4bpp
- }
- else
- {
- xstride = size / 2; baseaddr += tileno * 128; // 16x16 4bpp
- }
- }
- else if (bpp == 2) // 2bpp?
- {
- xstride = size / 4; baseaddr += tileno * 64; // 16x16 2bpp
- }
- else
- {
- popmessage("draw_background_tile unsupported bpp %d\n", bpp);
- return;
- }
-
-
-
- uint8_t* gfxdata;
-
- if (drawfromram)
- {
- gfxdata = &m_mainram[baseaddr & 0x3fff];
- }
- else
- {
- gfxdata = &m_mainregion[baseaddr & 0x3fffff];
- }
-
-
- int count = 0;
- for (int y = 0; y < size; y++)
- {
- int realy = ypos + y;
- int xposwithscroll = 0;
-
- if (!drawfromram)
- {
- xposwithscroll = xpos - get_xscroll_for_screenypos(realy);
- }
- else
- {
- xposwithscroll = xpos;
- // RAM tile layer has no scrolling? (or we've never seen it used / enabled)
- }
-
- uint16_t* dst = &bitmap.pix16(ypos + y);
- uint8_t* pridst = &m_prioritybitmap.pix8(ypos + y);
-
- for (int x = 0; x < xstride; x++)
- {
- int pix = gfxdata[count];
-
- if (realy >= cliprect.min_y && realy <= cliprect.max_y)
- {
- if (bpp == 8) // 8bpp
- {
- int realx = x + xposwithscroll;
- if (realx >= cliprect.min_x && realx <= cliprect.max_x)
- {
- if (pix)
- {
- if (pridst[realx] <= priority)
- {
- dst[realx] = pix | palette;
- pridst[realx] = priority;
- }
-
- }
- }
- }
- else if (bpp == 7)
- {
- popmessage("draw_background_tile bpp == 7");
- }
- else if (bpp == 6)
- {
- popmessage("draw_background_tile bpp == 6");
- }
- else if (bpp == 5)
- {
- popmessage("draw_background_tile bpp == 5");
- }
- else if (bpp == 4) // 4bpp
- {
- int realx = (x * 2) + xposwithscroll;
- if (realx >= cliprect.min_x && realx <= cliprect.max_x)
- {
- if (pix & 0xf0)
- {
- if (pridst[realx] <= priority)
- {
- dst[realx] = ((pix & 0xf0) >> 4) | palette;
- pridst[realx] = priority;
- }
- }
- }
-
- realx++;
-
- if (realx >= cliprect.min_x && realx <= cliprect.max_x)
- {
- if (pix & 0x0f)
- {
- if (pridst[realx] <= priority)
- {
- dst[realx] = (pix & 0x0f) | palette;
- pridst[realx] = priority;
- }
- }
- }
- }
- else if (bpp == 3)
- {
- popmessage("draw_background_tile bpp == 3");
- }
- else if (bpp == 2) // 2bpp (hnt3 ram text)
- {
- int realx = (x * 4) + xposwithscroll;
- if (realx >= cliprect.min_x && realx <= cliprect.max_x)
- {
- if (pix & 0xc0)
- {
- if (pridst[realx] <= priority)
- {
- dst[realx] = ((pix & 0xc0) >> 6) | palette;
- pridst[realx] = priority;
- }
- }
- }
-
- realx++;
-
- if (realx >= cliprect.min_x && realx <= cliprect.max_x)
- {
- if (pix & 0x30)
- {
- if (pridst[realx] <= priority)
- {
- dst[realx] = ((pix & 0x30) >> 4) | palette;
- pridst[realx] = priority;
- }
- }
- }
-
- realx++;
-
- if (realx >= cliprect.min_x && realx <= cliprect.max_x)
- {
- if (pix & 0x0c)
- {
- if (pridst[realx] <= priority)
- {
- dst[realx] = ((pix & 0x0c) >> 2) | palette;
- pridst[realx] = priority;
- }
- }
- }
-
- realx++;
-
- if (realx >= cliprect.min_x && realx <= cliprect.max_x)
- {
- if (pix & 0x03)
- {
- if (pridst[realx] <= priority)
- {
- dst[realx] = ((pix & 0x03) >> 0) | palette;
- pridst[realx] = priority;
- }
- }
- }
- }
- else if (bpp == 1)
- {
- popmessage("draw_background_tile bpp == 1");
- }
- }
- count++;
- }
- }
-}
-
-int elan_eu3a14_state::get_xscroll_for_screenypos(int ydraw)
-{
- if ((ydraw < 0) || (ydraw >= 224))
- return 0;
-
- int xscroll = m_scrollregs[0] | (m_scrollregs[1] << 8);
-
- if (m_rowscrollcfg[1] == 0x01) // GUESS! could be anything, but this bit is set in Huntin'3
- {
- int split0 = m_rowscrollregs[0] | (m_rowscrollregs[1] << 8);
- int split1 = m_rowscrollregs[2] | (m_rowscrollregs[3] << 8);
- int split2 = m_rowscrollregs[4] | (m_rowscrollregs[5] << 8);
- int split3 = m_rowscrollregs[6] | (m_rowscrollregs[7] << 8);
-
- if (ydraw < m_rowscrollsplit[0])
- {
- return xscroll;
- }
- else if (ydraw < m_rowscrollsplit[1])
- {
- return split0;
- }
- else if (ydraw < m_rowscrollsplit[2])
- {
- return split1;
- }
- else if (ydraw < m_rowscrollsplit[3])
- {
- return split2;
- }
- else if (ydraw < m_rowscrollsplit[4])
- {
- return split3;
- }
- else
- {
- return 0;
- }
- }
- else
- {
- return xscroll;
- }
-}
-
-
-void elan_eu3a14_state::draw_background_page(screen_device& screen, bitmap_ind16& bitmap, const rectangle& cliprect, int ramstart, int ramend, int xbase, int ybase, int size, int bpp, int base, int pagewidth, int pageheight, int bytespertile, int palettepri, int drawfromram)
-{
-
- int palette = ((palettepri & 0xf0) >> 4) | ((palettepri & 0x08) << 1);
- palette = palette << 4;
- int priority = palettepri & 0x07;
-
- int xdraw = xbase;
- int ydraw = ybase;
- int count = 0;
-
- for (int i = ramstart; i < ramend; i += bytespertile)
- {
- int tile = 0;
- int realpalette = palette;
- int realpriority = priority;
- int realbpp = bpp;
-
- if (bytespertile == 2)
- {
- tile = m_mainram[i + 0] | (m_mainram[i + 1] << 8);
- }
- else if (bytespertile == 4) // rad_foot hidden test mode, rad_hnt3 "Target Range" (not yet correct)
- {
- tile = m_mainram[i + 0] | (m_mainram[i + 1] << 8);// | (m_mainram[i + 2] << 16) | | (m_mainram[i + 3] << 24);
-
- // m_mainram[i + 3] & 0x04 is set in both seen cases, maybe per-tile bpp?
- // this would match up with this mode being inline replacements for m_tilecfg[1] (palettepri) and m_tilecfg[2] (bpp);
-
- int newpalette = ((m_mainram[i + 2] & 0xf0) >> 4) | ((m_mainram[i + 2] & 0x08) << 1);
- newpalette = newpalette << 4;
- realpalette = newpalette;
- realpriority = m_mainram[i + 2] & 0x07;
- realbpp = m_mainram[i + 3] & 0x07;
- if (realbpp == 0)
- realbpp = 8;
-
- }
-
-
- draw_background_tile(bitmap, cliprect, realbpp, tile, realpalette, realpriority, 0, 0, xdraw, ydraw, 0, size, base, drawfromram);
-
- xdraw += size;
-
- count++;
- if (((count % pagewidth) == 0))
- {
- xdraw -= size * pagewidth;
- ydraw += size;
- }
- }
-}
-
-void elan_eu3a14_state::draw_background_ramlayer(screen_device& screen, bitmap_ind16& bitmap, const rectangle& cliprect)
-{
- // this register use is questionable
- if (m_ramtilecfg[0] & 0x80)
- {
- int rtm_size;;
- int rtm_pagewidth;
- int rtm_pageheight;
- int rtm_yscroll;
- int rtm_bpp;
- int rtm_bytespertile = 2;
- uint8_t palettepri = m_ramtilecfg[1];
-
- rtm_yscroll = 0;
-
- // this is the gfxbase in ram for all cases seen
- int rtm_base = (0x2000 - 0x200) / 256;
-
- // same as regular layer?
- if (m_ramtilecfg[0] & 0x10)
- {
- rtm_size = 8;
- rtm_pagewidth = 32;
- rtm_pageheight = 28;
- }
- else
- {
- rtm_size = 16;
- rtm_pagewidth = 32 / 2;
- rtm_pageheight = 28 / 2;
- }
-
- rtm_bpp = m_ramtilecfg[2] & 0x07;
- if (rtm_bpp == 0)
- rtm_bpp = 8;
-
- // this is in the same place even when the first tilemap is in 16x16 mode, probably a base register somewhere
- int ramstart = m_tilerambase + 0x700;
- int ramend = m_tilerambase + 0x700 + 0x700;
-
- // hack for "Target Range" mode
- if (m_ramtilecfg[5] == 0x06)
- {
- ramstart = 0x3980-0x200;
- ramend = 0x3980-0x200 + 0x700;
- }
-
- // normal
- draw_background_page(screen, bitmap, cliprect, ramstart, ramend, 0, 0 - rtm_yscroll, rtm_size, rtm_bpp, rtm_base, rtm_pagewidth, rtm_pageheight, rtm_bytespertile, palettepri, 1);
- // wrap x
- draw_background_page(screen, bitmap, cliprect, ramstart, ramend, (rtm_size * rtm_pagewidth), 0 - rtm_yscroll, rtm_size, rtm_bpp, rtm_base, rtm_pagewidth, rtm_pageheight, rtm_bytespertile, palettepri, 1);
- // wrap y
- draw_background_page(screen, bitmap, cliprect, ramstart, ramend, 0, (rtm_size * rtm_pageheight) + 0 - rtm_yscroll, rtm_size, rtm_bpp, rtm_base, rtm_pagewidth, rtm_pageheight, rtm_bytespertile, palettepri, 1);
- // wrap x+y
- draw_background_page(screen, bitmap, cliprect, ramstart, ramend, (rtm_size * rtm_pagewidth), (rtm_size * rtm_pageheight) + 0 - rtm_yscroll, rtm_size, rtm_bpp, rtm_base, rtm_pagewidth, rtm_pageheight, rtm_bytespertile, palettepri, 1);
- }
-}
-
-
-void elan_eu3a14_state::draw_background(screen_device &screen, bitmap_ind16 &bitmap, const rectangle &cliprect)
-{
- int yscroll = m_scrollregs[2] | (m_scrollregs[3] << 8);
-
- int base = (m_tilecfg[5] << 8) | m_tilecfg[4];
- uint8_t palettepri = m_tilecfg[1];
-
- int pagewidth = 1, pageheight = 1;
- int bytespertile = 2;
- int size;
-
- // m_tilecfg[0] b-as ?-hh b = bytes per tile s = tilesize / page size? a = always set when tilemaps are in use - check? h = related to page positions, when set uses 2x2 pages? ? = used
- // m_tilecfg[1] pppp x--? ? = used foot x = used, huntin3 summary (palette bank?) p = palette (used for different stages in huntin3 and the hidden test modes in others)
- // m_tilecfg[2] ---- bbbb b = bpp mode (0 = 8bpp)
- // m_tilecfg[3] ---- ---- (unused or more gfxbase?)
- // m_tilecfg[4] gggg gggg gfxbase (lower bits)
- // m_tilecfg[5] gggg gggg gfxbase (upper bits)
-
- // ramtilecfg appears to be a similar format, except for the other layer with ram base tiles
- // however 'a' in m_tilecfg[0] is NOT set
- // also m_tilecfg[0] has 0x80 set, which would be 4 bytes per tile, but it isn't?
- // the layer seems to be disabled by setting m_tilecfg[0] to 0?
-
- if (m_tilecfg[0] & 0x10)
- {
- size = 8;
- pagewidth = 32;
- pageheight = 28;
- }
- else
- {
- size = 16;
- pagewidth = 16;
- pageheight = 14;
- }
-
- if (m_tilecfg[0] & 0x80)
- {
- bytespertile = 4;
- }
- else
- {
- bytespertile = 2;
- }
-
- int bpp = (m_tilecfg[2] & 0x07);
- if (bpp == 0)
- bpp = 8;
-
- int ramstart = 0;
- int ramend = 0;
-
- int pagesize = pagewidth * pageheight * 2;
-
- if (bytespertile == 4)
- {
- pagesize <<= 1; // shift because we need twice as much ram for this mode
- }
-
- if ((m_tilecfg[0] & 0x03) == 0x00) // tilemaps arranged as 2x2 pages?
- {
- ramstart = m_tilerambase + pagesize * 0;
- ramend = m_tilerambase + pagesize * 1;
-
- draw_background_page(screen, bitmap, cliprect, ramstart,ramend, 0, 0 - yscroll, size, bpp, base, pagewidth,pageheight, bytespertile, palettepri, 0); // normal
- draw_background_page(screen, bitmap, cliprect, ramstart,ramend, (size * pagewidth * 2), 0 - yscroll, size, bpp, base, pagewidth,pageheight, bytespertile, palettepri, 0); // wrap x
- draw_background_page(screen, bitmap, cliprect, ramstart,ramend, 0, (size * pageheight * 2) + 0 - yscroll, size, bpp, base, pagewidth,pageheight, bytespertile, palettepri, 0); // wrap y
- draw_background_page(screen, bitmap, cliprect, ramstart,ramend, (size * pagewidth * 2), (size * pageheight * 2) + 0 - yscroll, size, bpp, base, pagewidth,pageheight, bytespertile, palettepri, 0); // wrap x+y
-
- ramstart = m_tilerambase + pagesize * 1;
- ramend = m_tilerambase + pagesize * 2;
-
- draw_background_page(screen, bitmap, cliprect, ramstart,ramend, (size * pagewidth), 0 - yscroll, size, bpp, base, pagewidth,pageheight, bytespertile, palettepri, 0); // normal
- draw_background_page(screen, bitmap, cliprect, ramstart,ramend, (size * pagewidth * 3), 0 - yscroll, size, bpp, base, pagewidth,pageheight, bytespertile, palettepri, 0); // wrap x
- draw_background_page(screen, bitmap, cliprect, ramstart,ramend, (size * pagewidth), (size * pageheight * 2) + 0 - yscroll, size, bpp, base, pagewidth,pageheight, bytespertile, palettepri, 0); // wrap y
- draw_background_page(screen, bitmap, cliprect, ramstart,ramend, (size * pagewidth * 3), (size * pageheight * 2) + 0 - yscroll, size, bpp, base, pagewidth,pageheight, bytespertile, palettepri, 0); // wrap x+y
-
- ramstart = m_tilerambase + pagesize * 2;
- ramend = m_tilerambase + pagesize * 3;
-
- draw_background_page(screen, bitmap, cliprect, ramstart,ramend, 0, (size * pageheight) - yscroll, size, bpp, base, pagewidth,pageheight, bytespertile, palettepri, 0); // normal
- draw_background_page(screen, bitmap, cliprect, ramstart,ramend, (size * pagewidth * 2), (size * pageheight) - yscroll, size, bpp, base, pagewidth,pageheight, bytespertile, palettepri, 0); // wrap x
- draw_background_page(screen, bitmap, cliprect, ramstart,ramend, 0, (size * pageheight * 3) - yscroll, size, bpp, base, pagewidth,pageheight, bytespertile, palettepri, 0); // wrap y
- draw_background_page(screen, bitmap, cliprect, ramstart,ramend, (size * pagewidth * 2), (size * pageheight * 3) - yscroll, size, bpp, base, pagewidth,pageheight, bytespertile, palettepri, 0); // wrap x+y
-
- ramstart = m_tilerambase + pagesize * 3;
- ramend = m_tilerambase + pagesize * 4;
-
- draw_background_page(screen, bitmap, cliprect, ramstart,ramend, (size * pagewidth), (size * pageheight) - yscroll, size, bpp, base, pagewidth,pageheight, bytespertile, palettepri, 0); // normal
- draw_background_page(screen, bitmap, cliprect, ramstart,ramend, (size * pagewidth * 3), (size * pageheight) - yscroll, size, bpp, base, pagewidth,pageheight, bytespertile, palettepri, 0); // wrap x
- draw_background_page(screen, bitmap, cliprect, ramstart,ramend, (size * pagewidth), (size * pageheight * 3) - yscroll, size, bpp, base, pagewidth,pageheight, bytespertile, palettepri, 0);// wrap y
- draw_background_page(screen, bitmap, cliprect, ramstart,ramend, (size * pagewidth * 3), (size * pageheight * 3) - yscroll, size, bpp, base, pagewidth,pageheight, bytespertile, palettepri, 0); // wrap x+y
- }
- else if ((m_tilecfg[0] & 0x03) == 0x03) // individual tilemaps? multiple layers?
- {
- // popmessage("m_tilecfg[0] & 0x03 multiple layers config %04x", base);
- ramstart = m_tilerambase + pagesize * 0;
- ramend = m_tilerambase + pagesize * 1;
-
- // normal
- draw_background_page(screen, bitmap, cliprect, ramstart, ramend, 0, 0 - yscroll, size, bpp, base, pagewidth,pageheight, bytespertile, palettepri, 0);
- // wrap x
- draw_background_page(screen, bitmap, cliprect, ramstart, ramend, (size * pagewidth), 0 - yscroll, size, bpp, base, pagewidth,pageheight, bytespertile, palettepri, 0);
- // wrap y
- draw_background_page(screen, bitmap, cliprect, ramstart, ramend, 0, (size * pageheight) + 0 - yscroll, size, bpp, base, pagewidth,pageheight, bytespertile, palettepri, 0);
- // wrap x+y
- draw_background_page(screen, bitmap, cliprect, ramstart, ramend, (size * pagewidth), (size * pageheight) + 0 - yscroll, size, bpp, base, pagewidth,pageheight, bytespertile, palettepri, 0);
-
- // RAM based tile layer
- draw_background_ramlayer(screen, bitmap, cliprect);
- }
- else
- {
- popmessage("m_tilecfg[0] & 0x03 unknown config");
- }
-
-}
-
-void elan_eu3a14_state::draw_sprite_pix(const rectangle& cliprect, uint16_t* dst, uint8_t* pridst, int realx, int priority, uint8_t pix, uint8_t mask, uint8_t shift, int palette)
-{
- if (realx >= cliprect.min_x && realx <= cliprect.max_x)
- {
- if (pridst[realx] <= priority)
- {
- if (pix & mask)
- {
- dst[realx] = ((pix & mask) >> shift) | palette;
- pridst[realx] = priority;
- }
- }
- }
+ m_vid->video_start();
}
-void elan_eu3a14_state::draw_sprite_line(screen_device &screen, bitmap_ind16 &bitmap, const rectangle &cliprect, int offset, int line, int palette, int flipx, int priority, int xpos, int ypos, int bpp)
-{
- offset = offset * 2;
-
- int bppdiv = 0;
- switch (bpp)
- {
- default:
- case 0x8:
- case 0x7:
- case 0x6:
- case 0x5:
- offset += line * 8;
- bppdiv = 1;
- break;
-
- case 0x4:
- case 0x3:
- offset += line * 4;
- bppdiv = 2;
- break;
-
- case 0x2:
- offset += line * 2;
- bppdiv = 4;
- break;
-
- case 0x1:
- offset += line * 1;
- bppdiv = 8;
- break;
- }
-
- uint8_t* gfxdata = &m_mainregion[offset & 0x3fffff];
-
- if (ypos >= cliprect.min_y && ypos <= cliprect.max_y)
- {
- uint16_t* dst = &bitmap.pix16(ypos);
- uint8_t* pridst = &m_prioritybitmap.pix8(ypos);
-
- int count = 0;
- for (int x = 0; x < 8/bppdiv;x++)
- {
- if (bpp == 8)
- {
- int pix,mask,shift;
- if (flipx) { pix = gfxdata[7 - count]; } else { pix = gfxdata[count]; }
- int realx = xpos + x * 1;
- if (flipx) { mask = 0xff; shift = 0; } else { mask = 0xff; shift = 0; }
- draw_sprite_pix(cliprect, dst, pridst, realx, priority, pix, mask, shift, palette);
- }
- else if (bpp == 7)
- {
- int pix,mask,shift;
- if (flipx) { pix = gfxdata[7 - count]; } else { pix = gfxdata[count]; }
- int realx = xpos + x * 1;
- // stride doesn't change, data isn't packed, just don't use top bit
- if (flipx) { mask = 0x7f; shift = 0; } else { mask = 0x7f; shift = 0; }
- draw_sprite_pix(cliprect, dst, pridst, realx, priority, pix, mask, shift, palette);
- }
- else if (bpp == 6)
- {
- popmessage("6bpp sprite\n");
- }
- else if (bpp == 5)
- {
- popmessage("5bpp sprite\n");
- }
- else if (bpp == 4)
- {
- int pix,mask,shift;
- if (flipx) { pix = gfxdata[3 - count]; } else { pix = gfxdata[count]; }
- int realx = xpos + x * 2;
- if (flipx) { mask = 0x0f; shift = 0; } else { mask = 0xf0; shift = 4; }
- draw_sprite_pix(cliprect, dst, pridst, realx, priority, pix, mask, shift, palette);
- realx++;
- if (flipx) { mask = 0xf0; shift = 4; } else { mask = 0x0f; shift = 0; }
- draw_sprite_pix(cliprect, dst, pridst, realx, priority, pix, mask, shift, palette);
- }
- else if (bpp == 3)
- {
- popmessage("3bpp sprite\n");
- }
- else if (bpp == 2)
- {
- int pix,mask,shift;
- if (flipx) { pix = gfxdata[1 - count]; } else { pix = gfxdata[count]; }
- int realx = xpos + x * 4;
- if (flipx) { mask = 0x03; shift = 0; } else { mask = 0xc0; shift = 6; }
- draw_sprite_pix(cliprect, dst, pridst, realx, priority, pix, mask, shift, palette);
- realx++;
- if (flipx) { mask = 0x0c; shift = 2; } else { mask = 0x30; shift = 4; }
- draw_sprite_pix(cliprect, dst, pridst, realx, priority, pix, mask, shift, palette);
- realx++;
- if (flipx) { mask = 0x30; shift = 4; } else { mask = 0x0c; shift = 2; }
- draw_sprite_pix(cliprect, dst, pridst, realx, priority, pix, mask, shift, palette);
- realx++;
- if (flipx) { mask = 0xc0; shift = 6; } else { mask = 0x03; shift = 0; }
- draw_sprite_pix(cliprect, dst, pridst, realx, priority, pix, mask, shift, palette);
- }
- else if (bpp == 1)
- {
- popmessage("1bpp sprite\n");
- }
-
- count++;
- }
- }
-
-}
-
-
-void elan_eu3a14_state::draw_sprites(screen_device &screen, bitmap_ind16 &bitmap, const rectangle &cliprect)
+uint32_t elan_eu3a14_state::screen_update(screen_device& screen, bitmap_ind16& bitmap, const rectangle& cliprect)
{
- // first 4 sprite entries seem to be garbage sprites, so we start at 0x20
- // likely we're just interpreting them wrong and they're used for blanking things or clipping?
- for (int i = m_spriterambase; i < m_spriterambase + 0x800; i += 8)
- {
- /*
- +0 e-ff hhww flip yx, enable, height, width
- +1 yyyy yyyy ypos
- +2 xxxx xxxx xpos
- +3 pppp Pzzz p = palette, P = upper palette bank, z = priority
- +4 tttt tttt tile bits
- +5 tttt tttt
- +6 --TT TPPP TTT = tile bank PPP = bpp select (+more?)
- +7 ---- ----
-
- */
-
- int attr = m_mainram[i + 0];
- int y = m_mainram[i + 1];
- int x = m_mainram[i + 2];
- int palettepri = m_mainram[i + 3];
-
- int h = attr & 0x0c;
- int w = attr & 0x03;
- int flipx = (attr & 0x10) >> 4;
- int flipy = (attr & 0x20) >> 5;
-
- int height = 0;
- int width = 0;
-
- int pri = palettepri & 0x07;
-
- int palette = ((palettepri & 0xf0) >> 4) | ((palettepri & 0x08) << 1);
- palette = palette << 4;
-
- switch (h)
- {
- case 0x0:height = 2; break;
- case 0x4:height = 4; break;
- case 0x8:height = 8; break;
- case 0xc:height = 16; break;
- }
-
- switch (w)
- {
- case 0x0:width = 1; break;
- case 0x1:width = 2; break;
- case 0x2:width = 4; break;
- case 0x3:width = 8; break;
- }
-
- y -= ((height * 2) - 4);
-
- x -= ((width * 4) - 4);
-
- height *= 4;
-
- x -= 6;
- y -= 4;
-
- int offset = ((m_mainram[i + 5] << 8) + (m_mainram[i + 4] << 0));
- int extra = m_mainram[i + 6];
-
- int spritebase = (m_spritebase[1] << 8) | m_spritebase[0];
-
- offset += (extra & 0xf8) << 13;
- offset += spritebase << 7;
-
- int bpp = extra & 0x07;
- if (bpp == 0)
- bpp = 8;
-
- if (attr & 0x80)
- {
- int count = 0;
- for (int yy = 0; yy < height; yy++)
- {
- int yoff = flipy ? height-1-yy : yy;
-
- for (int xx = 0; xx < width; xx++)
- {
- int xoff = flipx ? (((width - 1) * 8) - (xx * 8)) : (xx * 8);
-
- draw_sprite_line(screen, bitmap, cliprect, offset, count, palette, flipx, pri, x + xoff, y + yoff, bpp);
- count++;
- }
- }
- }
- }
-}
-
-
-
-uint32_t elan_eu3a14_state::screen_update(screen_device &screen, bitmap_ind16 &bitmap, const rectangle &cliprect)
-{
- m_spriterambase = (m_spriteaddr[0] * 0x200) - 0x200;
-
- bitmap.fill(0, cliprect);
- m_prioritybitmap.fill(0, cliprect);
-
- draw_background(screen, bitmap, cliprect);
-
- draw_sprites(screen, bitmap, cliprect);
-
- return 0;
+ return m_vid->screen_update(screen, bitmap, cliprect);
}
// sound callback
@@ -964,7 +224,7 @@ void elan_eu3a14_state::radica_eu3a14_map(address_map &map)
map(0x0000, 0x01ff).ram();
map(0x0200, 0x3fff).ram().share("mainram"); // 200-9ff is sprites? a00 - ??? is tilemap?
- map(0x4800, 0x4bff).rw(m_commonvid, FUNC(elan_eu3a05commonvid_device::palette_r), FUNC(elan_eu3a05commonvid_device::palette_w));
+ map(0x4800, 0x4bff).rw(m_vid, FUNC(elan_eu3a14vid_device::palette_r), FUNC(elan_eu3a14vid_device::palette_w));
// 5000 - 501f = SYSTEM AREA
@@ -999,14 +259,7 @@ void elan_eu3a14_state::radica_eu3a14_map(address_map &map)
// 5060 - 506e r/w during startup on foot
// sound appears to be the same as eu3a05
- map(0x5080, 0x5091).rw(m_sound, FUNC(elan_eu3a05_sound_device::elan_eu3a05_sound_addr_r), FUNC(elan_eu3a05_sound_device::elan_eu3a05_sound_addr_w));
- map(0x5092, 0x50a3).rw(m_sound, FUNC(elan_eu3a05_sound_device::elan_eu3a05_sound_size_r), FUNC(elan_eu3a05_sound_device::elan_eu3a05_sound_size_w));
- map(0x50a4, 0x50a4).rw(m_sound, FUNC(elan_eu3a05_sound_device::elan_eu3a05_sound_unk_r), FUNC(elan_eu3a05_sound_device::elan_eu3a05_sound_unk_w)); // read frequently on this
- map(0x50a5, 0x50a5).rw(m_sound, FUNC(elan_eu3a05_sound_device::elan_eu3a05_sound_trigger_r), FUNC(elan_eu3a05_sound_device::elan_eu3a05_sound_trigger_w));
- map(0x50a6, 0x50a6).nopw(); // startup
- map(0x50a7, 0x50a7).nopw(); // startup
- map(0x50a8, 0x50a8).r(m_sound, FUNC(elan_eu3a05_sound_device::elan_eu3a05_50a8_r));
- map(0x50a9, 0x50a9).nopw(); // startup, read foot
+ map(0x5080, 0x50a9).rw(m_sound, FUNC(elan_eu3a05_sound_device::read), FUNC(elan_eu3a05_sound_device::write));
// video regs are in the 51xx range
@@ -1030,10 +283,11 @@ void elan_eu3a14_state::radica_eu3a14_map(address_map &map)
map(0x5108, 0x5109).ram(); // hnt3, frequently rewrites same values, maybe something to do with raster irq?
// layer specific regs?
- map(0x5110, 0x5115).ram().share("tilecfg");
- map(0x5116, 0x5117).ram().share("rowscrollcfg"); // 00 01 in hnt3 (could just be extra tile config bits, purpose guessed) set to 00 05 in rad_gtg overhead part (no rowscroll)
+ map(0x5110, 0x5115).rw(m_vid, FUNC(elan_eu3a14vid_device::tilecfg_r), FUNC(elan_eu3a14vid_device::tilecfg_w));
+ map(0x5116, 0x5117).rw(m_vid, FUNC(elan_eu3a14vid_device::rowscrollcfg_r), FUNC(elan_eu3a14vid_device::rowscrollcfg_w)); // 00 01 in hnt3 (could just be extra tile config bits, purpose guessed) set to 00 05 in rad_gtg overhead part (no rowscroll)
// 0x5118, 0x5119 not used
- map(0x511a, 0x511e).ram().share("rowscrollsplit"); // hnt3 (60 68 78 90 b8 - rowscroll position list see note below
+ map(0x511a, 0x511e).rw(m_vid, FUNC(elan_eu3a14vid_device::rowscrollsplit_r), FUNC(elan_eu3a14vid_device::rowscrollsplit_w)); // hnt3 (60 68 78 90 b8 - rowscroll position list see note below
+
// register value notes for 511a-511e and how they relate to screen
// 00-6f normal scroll reg
@@ -1043,18 +297,20 @@ void elan_eu3a14_state::radica_eu3a14_map(address_map &map)
// 90-b7 is the 4th
// b8-ff no scroll?
- map(0x5121, 0x5124).ram().share("scrollregs");
- map(0x5125, 0x512c).ram().share("rowscrollregs"); // 4 extra x scroll regs
+ map(0x5121, 0x5124).rw(m_vid, FUNC(elan_eu3a14vid_device::scrollregs_r), FUNC(elan_eu3a14vid_device::scrollregs_w));
+ map(0x5125, 0x512c).rw(m_vid, FUNC(elan_eu3a14vid_device::rowscrollregs_r), FUNC(elan_eu3a14vid_device::rowscrollregs_w)); // 4 extra x scroll regs
// layer specific regs?
- map(0x5140, 0x5145).ram().share("ramtilecfg"); // hnt3
+ map(0x5140, 0x5145).rw(m_vid, FUNC(elan_eu3a14vid_device::ramtilecfg_r), FUNC(elan_eu3a14vid_device::ramtilecfg_w)); // hnt3
map(0x5148, 0x514b).ram(); // hnt3 (always 0 tho?)
// sprite specific regs?
- map(0x5150, 0x5150).ram().share("spriteaddr"); // startup 01 bb3,gtg,rsg, (na) foot 0c hnt3
- map(0x5151, 0x5152).ram().share("spritebase");
+ map(0x5150, 0x5150).rw(m_vid, FUNC(elan_eu3a14vid_device::spriteaddr_r), FUNC(elan_eu3a14vid_device::spriteaddr_w)); // startup 01 bb3,gtg,rsg, (na) foot 0c hnt3
+ map(0x5151, 0x5152).rw(m_vid, FUNC(elan_eu3a14vid_device::spritebase_r), FUNC(elan_eu3a14vid_device::spritebase_w));
map(0x5153, 0x5153).ram(); // startup
+
+
map(0x6000, 0xdfff).m(m_bank, FUNC(address_map_bank_device::amap8));
map(0xe000, 0xffff).rom().region("maincpu", 0x0000);
@@ -1526,8 +782,6 @@ void elan_eu3a14_state::machine_reset()
m_portdir[0] = 0x00;
m_portdir[1] = 0x00;
m_portdir[2] = 0x00;
-
- m_spriteaddr[0] = 0x14; // ?? rad_foot never writes, other games seem to use it to set sprite location
}
@@ -1639,9 +893,13 @@ void elan_eu3a14_state::radica_eu3a14(machine_config &config)
PALETTE(config, m_palette).set_entries(512);
- ELAN_EU3A05_COMMONVID(config, m_commonvid, 0);
- m_commonvid->set_palette("palette");
- m_commonvid->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_entries(512);
+ m_vid->set_tilerambase(0x0200 - 0x200);
/* sound hardware */
SPEAKER(config, "mono").front_center();
@@ -1649,11 +907,23 @@ void elan_eu3a14_state::radica_eu3a14(machine_config &config)
ELAN_EU3A05_SOUND(config, m_sound, 8000);
m_sound->space_read_callback().set(FUNC(elan_eu3a14_state::read_full_space));
m_sound->add_route(ALL_OUTPUTS, "mono", 1.0);
+ m_sound->sound_end_cb<0>().set(FUNC(elan_eu3a14_state::sound_end0));
+ m_sound->sound_end_cb<1>().set(FUNC(elan_eu3a14_state::sound_end1));
+ m_sound->sound_end_cb<2>().set(FUNC(elan_eu3a14_state::sound_end2));
+ m_sound->sound_end_cb<3>().set(FUNC(elan_eu3a14_state::sound_end3));
+ m_sound->sound_end_cb<4>().set(FUNC(elan_eu3a14_state::sound_end4));
+ m_sound->sound_end_cb<5>().set(FUNC(elan_eu3a14_state::sound_end5));
}
-void elan_eu3a14_state::radica_eu3a14_adc(machine_config &config)
+void elan_eu3a14_state::radica_eu3a14_altrambase(machine_config& config)
{
radica_eu3a14(config);
+ m_vid->set_tilerambase(0x0a00 - 0x200);
+}
+
+void elan_eu3a14_state::radica_eu3a14_altrambase_adc(machine_config &config)
+{
+ radica_eu3a14_altrambase(config);
TIMER(config, "scantimer").configure_scanline(FUNC(elan_eu3a14_state::scanline_cb), "screen", 0, 1);
}
@@ -1666,23 +936,10 @@ void elan_eu3a14_state::radica_eu3a14p(machine_config &config) // TODO, clocks d
subdevice<screen_device>("screen")->set_refresh_hz(50);
}
-
-void elan_eu3a14_state::init_rad_gtg()
-{
- // must be registers to control this
- m_tilerambase = 0x0a00 - 0x200;
-}
-
-void elan_eu3a14_state::init_rad_foot()
-{
- // must be registers to control this
- m_tilerambase = 0x0200 - 0x200;
-}
-
-void elan_eu3a14_state::init_rad_hnt3()
+void elan_eu3a14_state::radica_eu3a14p_altrambase(machine_config& config)
{
- // must be registers to control this
- m_tilerambase = 0x0200 - 0x200;
+ radica_eu3a14p(config);
+ m_vid->set_tilerambase(0x0a00 - 0x200);
}
@@ -1737,20 +994,20 @@ ROM_START( rad_baskp )
ROM_LOAD( "basketball.bin", 0x000000, 0x400000, CRC(7d6ff53c) SHA1(1c75261d55e0107a3b8e8d4c1eb2854750f2d0e8) )
ROM_END
-CONS( 2006, rad_gtg, 0, 0, radica_eu3a14_adc, rad_gtg, elan_eu3a14_state, init_rad_gtg, "Radica / FarSight Studios (licensed from Incredible Technologies)", "Golden Tee Golf: Home Edition", MACHINE_NOT_WORKING )
+CONS( 2006, rad_gtg, 0, 0, radica_eu3a14_altrambase_adc, rad_gtg, elan_eu3a14_state, empty_init, "Radica / FarSight Studios (licensed from Incredible Technologies)", "Golden Tee Golf: Home Edition", MACHINE_NOT_WORKING )
-CONS( 2005, rad_rsg, 0, 0, radica_eu3a14, rad_rsg, elan_eu3a14_state, init_rad_gtg, "Radica / FarSight Studios", "Play TV Real Swing Golf", MACHINE_NOT_WORKING )
+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, rad_rsgp, elan_eu3a14_state, init_rad_gtg, "Radica / FarSight Studios", "Connectv Real Swing Golf", MACHINE_NOT_WORKING )
+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 )
// 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, init_rad_foot, "Radica / Medialink", "Connectv Football", MACHINE_NOT_WORKING )
+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, radica_bb3, elan_eu3a14_state, init_rad_gtg, "Radica / FarSight Studios", "Play TV Baseball 3", MACHINE_NOT_WORKING )
-CONS( 2005, rad_bb3p, rad_bb3, 0, radica_eu3a14p, radica_bb3p, elan_eu3a14_state, init_rad_gtg, "Radica / FarSight Studios", "Connectv Baseball 3", 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_hnt3, 0, 0, radica_eu3a14, radica_hnt3, elan_eu3a14_state, init_rad_hnt3, "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, init_rad_hnt3, "Radica / V-Tac Technology Co Ltd.", "Connectv Huntin' 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_bask, 0, 0, radica_eu3a14, radica_bask, elan_eu3a14_state, init_rad_gtg, "Radica / FarSight Studios", "Play TV Basketball", MACHINE_NOT_WORKING )
-CONS( 2005, rad_baskp,rad_bask, 0, radica_eu3a14, radica_baskp, elan_eu3a14_state, init_rad_gtg, "Radica / FarSight Studios", "Connectv Basketball", 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 )
diff --git a/src/mame/drivers/vii.cpp b/src/mame/drivers/vii.cpp
index 1f3f7ab8ea8..4c833c2a3d6 100644
--- a/src/mame/drivers/vii.cpp
+++ b/src/mame/drivers/vii.cpp
@@ -193,6 +193,7 @@ public:
void non_spg_base(machine_config &config);
void lexizeus(machine_config &config);
void taikeegr(machine_config &config);
+ void sentx6p(machine_config &config);
void init_crc();
void init_zeus();
@@ -216,7 +217,7 @@ protected:
DECLARE_READ16_MEMBER(rad_porta_r);
DECLARE_READ16_MEMBER(rad_portb_r);
DECLARE_READ16_MEMBER(rad_portc_r);
-
+
DECLARE_WRITE16_MEMBER(jakks_porta_w);
DECLARE_WRITE16_MEMBER(jakks_portb_w);
@@ -231,6 +232,9 @@ protected:
virtual void mem_map_2m(address_map &map);
virtual void mem_map_1m(address_map &map);
+ void mem_map_2m_texas(address_map &map);
+
+
uint32_t m_current_bank;
std::unique_ptr<uint8_t[]> m_serial_eeprom;
@@ -773,6 +777,12 @@ void spg2xx_game_state::mem_map_2m(address_map &map)
map(0x000000, 0x1fffff).mirror(0x200000).bankr("cartbank");
}
+void spg2xx_game_state::mem_map_2m_texas(address_map &map)
+{
+ map(0x000000, 0x1fffff).bankr("cartbank");
+ map(0x3f0000, 0x3f7fff).ram();
+}
+
void spg2xx_game_state::mem_map_1m(address_map &map)
{
map(0x000000, 0x0fffff).mirror(0x300000).bankr("cartbank");
@@ -1885,6 +1895,158 @@ static INPUT_PORTS_START( taikeegr )
PORT_BIT( 0xffff, IP_ACTIVE_LOW, IPT_UNKNOWN )
INPUT_PORTS_END
+
+static INPUT_PORTS_START( sentx6p )
+ PORT_START("P1")
+ PORT_DIPNAME( 0x0001, 0x0001, "Port 1" )
+ 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_DIPNAME( 0x0100, 0x0100, DEF_STR( Unknown ) )
+ PORT_DIPSETTING( 0x0100, DEF_STR( Off ) )
+ PORT_DIPSETTING( 0x0000, DEF_STR( On ) )
+ PORT_DIPNAME( 0x0200, 0x0200, DEF_STR( Unknown ) )
+ PORT_DIPSETTING( 0x0200, DEF_STR( Off ) )
+ PORT_DIPSETTING( 0x0000, DEF_STR( On ) )
+ PORT_DIPNAME( 0x0400, 0x0400, DEF_STR( Unknown ) )
+ PORT_DIPSETTING( 0x0400, DEF_STR( Off ) )
+ PORT_DIPSETTING( 0x0000, DEF_STR( On ) )
+ PORT_DIPNAME( 0x0800, 0x0800, DEF_STR( Unknown ) )
+ PORT_DIPSETTING( 0x0800, DEF_STR( Off ) )
+ PORT_DIPSETTING( 0x0000, DEF_STR( On ) )
+ PORT_DIPNAME( 0x1000, 0x1000, DEF_STR( Unknown ) )
+ PORT_DIPSETTING( 0x1000, DEF_STR( Off ) )
+ PORT_DIPSETTING( 0x0000, DEF_STR( On ) )
+ PORT_DIPNAME( 0x2000, 0x2000, DEF_STR( Unknown ) )
+ PORT_DIPSETTING( 0x2000, DEF_STR( Off ) )
+ PORT_DIPSETTING( 0x0000, DEF_STR( On ) )
+ PORT_DIPNAME( 0x4000, 0x4000, DEF_STR( Unknown ) )
+ PORT_DIPSETTING( 0x4000, DEF_STR( Off ) )
+ PORT_DIPSETTING( 0x0000, DEF_STR( On ) )
+ PORT_DIPNAME( 0x8000, 0x8000, "Low Battery" )
+ PORT_DIPSETTING( 0x8000, DEF_STR( On ) )
+ PORT_DIPSETTING( 0x0000, DEF_STR( Off ) )
+
+ PORT_START("P2")
+ // these must be sense lines
+ PORT_DIPNAME( 0x0001, 0x0001, "Player 1 Connected" )
+ PORT_DIPSETTING( 0x0000, DEF_STR( No ) )
+ PORT_DIPSETTING( 0x0001, DEF_STR( Yes ) )
+ PORT_DIPNAME( 0x0002, 0x0002, "Player 2 Connected" )
+ PORT_DIPSETTING( 0x0000, DEF_STR( No ) )
+ PORT_DIPSETTING( 0x0002, DEF_STR( Yes ) )
+ PORT_DIPNAME( 0x0004, 0x0004, "Player 3 Connected" )
+ PORT_DIPSETTING( 0x0000, DEF_STR( No ) )
+ PORT_DIPSETTING( 0x0004, DEF_STR( Yes ) )
+ PORT_DIPNAME( 0x0008, 0x0008, "Player 4 Connected" )
+ PORT_DIPSETTING( 0x0000, DEF_STR( No ) )
+ PORT_DIPSETTING( 0x0008, DEF_STR( Yes ) )
+ PORT_DIPNAME( 0x0010, 0x0010, "Player 5 Connected" )
+ PORT_DIPSETTING( 0x0000, DEF_STR( No ) )
+ PORT_DIPSETTING( 0x0010, DEF_STR( Yes ) )
+ PORT_DIPNAME( 0x0020, 0x0020, "Player 6 Connected" )
+ PORT_DIPSETTING( 0x0000, DEF_STR( No ) )
+ PORT_DIPSETTING( 0x0020, DEF_STR( Yes ) )
+
+ PORT_DIPNAME( 0x0040, 0x0040, "Port 2" )
+ 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_DIPNAME( 0x0100, 0x0100, DEF_STR( Unknown ) )
+ PORT_DIPSETTING( 0x0100, DEF_STR( Off ) )
+ PORT_DIPSETTING( 0x0000, DEF_STR( On ) )
+ PORT_DIPNAME( 0x0200, 0x0200, DEF_STR( Unknown ) )
+ PORT_DIPSETTING( 0x0200, DEF_STR( Off ) )
+ PORT_DIPSETTING( 0x0000, DEF_STR( On ) )
+ PORT_DIPNAME( 0x0400, 0x0400, DEF_STR( Unknown ) )
+ PORT_DIPSETTING( 0x0400, DEF_STR( Off ) )
+ PORT_DIPSETTING( 0x0000, DEF_STR( On ) )
+ PORT_DIPNAME( 0x0800, 0x0800, DEF_STR( Unknown ) )
+ PORT_DIPSETTING( 0x0800, DEF_STR( Off ) )
+ PORT_DIPSETTING( 0x0000, DEF_STR( On ) )
+ PORT_DIPNAME( 0x1000, 0x1000, DEF_STR( Unknown ) )
+ PORT_DIPSETTING( 0x1000, DEF_STR( Off ) )
+ PORT_DIPSETTING( 0x0000, DEF_STR( On ) )
+ PORT_DIPNAME( 0x2000, 0x2000, DEF_STR( Unknown ) )
+ PORT_DIPSETTING( 0x2000, DEF_STR( Off ) )
+ PORT_DIPSETTING( 0x0000, DEF_STR( On ) )
+ PORT_DIPNAME( 0x4000, 0x4000, DEF_STR( Unknown ) )
+ PORT_DIPSETTING( 0x4000, DEF_STR( Off ) )
+ PORT_DIPSETTING( 0x0000, DEF_STR( On ) )
+ PORT_DIPNAME( 0x8000, 0x8000, DEF_STR( Unknown ) )
+ PORT_DIPSETTING( 0x8000, DEF_STR( Off ) )
+ PORT_DIPSETTING( 0x0000, DEF_STR( On ) )
+
+ PORT_START("P3")
+ PORT_DIPNAME( 0x0001, 0x0001, "Port 3" )
+ 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_BIT( 0x0080, IP_ACTIVE_LOW, IPT_BUTTON1 ) PORT_NAME("Console Select")
+ PORT_BIT( 0x0100, IP_ACTIVE_LOW, IPT_BUTTON2 ) PORT_NAME("Console Ok")
+ PORT_DIPNAME( 0x0200, 0x0200, DEF_STR( Unknown ) )
+ PORT_DIPSETTING( 0x0200, DEF_STR( Off ) )
+ PORT_DIPSETTING( 0x0000, DEF_STR( On ) )
+ PORT_DIPNAME( 0x0400, 0x0400, DEF_STR( Unknown ) )
+ PORT_DIPSETTING( 0x0400, DEF_STR( Off ) )
+ PORT_DIPSETTING( 0x0000, DEF_STR( On ) )
+ PORT_DIPNAME( 0x0800, 0x0800, DEF_STR( Unknown ) )
+ PORT_DIPSETTING( 0x0800, DEF_STR( Off ) )
+ PORT_DIPSETTING( 0x0000, DEF_STR( On ) )
+ PORT_DIPNAME( 0x1000, 0x1000, DEF_STR( Unknown ) )
+ PORT_DIPSETTING( 0x1000, DEF_STR( Off ) )
+ PORT_DIPSETTING( 0x0000, DEF_STR( On ) )
+ PORT_DIPNAME( 0x2000, 0x2000, DEF_STR( Unknown ) )
+ PORT_DIPSETTING( 0x2000, DEF_STR( Off ) )
+ PORT_DIPSETTING( 0x0000, DEF_STR( On ) )
+ PORT_DIPNAME( 0x4000, 0x4000, DEF_STR( Unknown ) )
+ PORT_DIPSETTING( 0x4000, DEF_STR( Off ) )
+ PORT_DIPSETTING( 0x0000, DEF_STR( On ) )
+ PORT_DIPNAME( 0x8000, 0x8000, DEF_STR( Unknown ) )
+ PORT_DIPSETTING( 0x8000, DEF_STR( Off ) )
+ PORT_DIPSETTING( 0x0000, DEF_STR( On ) )
+INPUT_PORTS_END
+
+
READ16_MEMBER(dreamlif_state::portb_r)
{
uint16_t ret = 0x0000;
@@ -2623,6 +2785,23 @@ void spg2xx_game_state::taikeegr(machine_config &config)
NVRAM(config, m_nvram, nvram_device::DEFAULT_ALL_1);
}
+
+void spg2xx_game_state::sentx6p(machine_config &config)
+{
+ SPG24X(config, m_maincpu, XTAL(27'000'000), m_screen);
+ m_maincpu->set_addrmap(AS_PROGRAM, &spg2xx_game_state::mem_map_2m_texas);
+ m_maincpu->set_pal(true);
+
+ spg2xx_base(config);
+
+ m_screen->set_refresh_hz(50);
+
+ m_maincpu->porta_in().set_ioport("P1");
+ m_maincpu->portb_in().set_ioport("P2");
+ m_maincpu->portc_in().set_ioport("P3");
+}
+
+
ROM_START( vii )
ROM_REGION( 0x2000000, "maincpu", ROMREGION_ERASE00 )
ROM_LOAD16_WORD_SWAP( "vii.bin", 0x0000, 0x2000000, CRC(04627639) SHA1(f883a92d31b53c9a5b0cdb112d07cd793c95fc43))
@@ -2833,6 +3012,11 @@ ROM_START( taikeegr )
ROM_END
+ROM_START( sentx6p )
+ ROM_REGION( 0x400000, "maincpu", ROMREGION_ERASE00 )
+ ROM_LOAD16_WORD_SWAP( "senario texas holdem.bin", 0x000000, 0x400000, CRC(7c7d2d33) SHA1(71631074ba66e3b0cdeb86ebca3931599f3a911c) )
+ROM_END
+
void spg2xx_game_state::init_crc()
{
// several games have a byte sum checksum listed at the start of ROM, this little helper function logs what it should match.
@@ -2999,3 +3183,7 @@ CONS( 2006, pvmil, 0, 0, pvmil, pvmil, pvmil_state, e
// for the UK version the title screen always shows "Guitar Rock", however there are multiple boxes with different titles and song selections.
// ROM is glued on the underside and soldered to the PCB, very difficult to remove without damaging.
CONS( 2007, taikeegr, 0, 0, taikeegr, taikeegr, spg2xx_game_state, init_taikeegr, "TaiKee", "Rockstar Guitar / Guitar Rock (PAL)", MACHINE_NOT_WORKING | MACHINE_IMPERFECT_SOUND | MACHINE_IMPERFECT_GRAPHICS ) // bad music timings (too slow)
+
+// "go 02d1d0" "do r1 = ff" to get past initial screen
+// a 'deluxe' version of this also exists with extra game modes
+CONS( 2004, sentx6p, 0, 0, sentx6p, sentx6p, spg2xx_game_state, empty_init, "Senario / Play Vision", "Texas Hold'em TV Poker - 6 Player Edition (UK)", MACHINE_NOT_WORKING | MACHINE_IMPERFECT_SOUND | MACHINE_IMPERFECT_GRAPHICS ) // from a UK Play Vision branded box, values in GBP
diff --git a/src/mame/mame.lst b/src/mame/mame.lst
index a63306aefde..52ce2ccfc36 100644
--- a/src/mame/mame.lst
+++ b/src/mame/mame.lst
@@ -39510,6 +39510,7 @@ icanpian //
tvgogo //
pvmil //
taikeegr //
+sentx6p //
@source:vsmile.cpp
vsmile //
diff --git a/src/mame/video/elan_eu3a14vid.cpp b/src/mame/video/elan_eu3a14vid.cpp
new file mode 100644
index 00000000000..79b2f4a97d0
--- /dev/null
+++ b/src/mame/video/elan_eu3a14vid.cpp
@@ -0,0 +1,766 @@
+// license:BSD-3-Clause
+// copyright-holders:David Haywood
+
+#include "emu.h"
+#include "elan_eu3a14vid.h"
+
+DEFINE_DEVICE_TYPE(ELAN_EU3A14_VID, elan_eu3a14vid_device, "elan_eu3a14vid", "Elan EU3A14 Video")
+
+elan_eu3a14vid_device::elan_eu3a14vid_device(const machine_config &mconfig, const char *tag, device_t *owner, uint32_t clock)
+ : elan_eu3a05commonvid_device(mconfig, ELAN_EU3A14_VID, tag, owner, clock),
+ m_cpu(*this, finder_base::DUMMY_TAG),
+ m_bank(*this, finder_base::DUMMY_TAG),
+ m_screen(*this, finder_base::DUMMY_TAG)
+{
+}
+
+void elan_eu3a14vid_device::device_start()
+{
+ elan_eu3a05commonvid_device::device_start();
+}
+
+void elan_eu3a14vid_device::device_reset()
+{
+ elan_eu3a05commonvid_device::device_reset();
+
+ m_spriteaddr = 0x14; // ?? rad_foot never writes, other games seem to use it to set sprite location
+}
+
+
+
+uint8_t elan_eu3a14vid_device::read_vram(int offset)
+{
+ address_space& cpuspace = m_cpu->space(AS_PROGRAM);
+ int realoffset = offset + 0x200;
+ if (realoffset < 0x4000)
+ {
+ return cpuspace.read_byte(realoffset);
+ }
+ else
+ return 0x00;
+}
+
+uint32_t elan_eu3a14vid_device::screen_update(screen_device &screen, bitmap_ind16 &bitmap, const rectangle &cliprect)
+{
+ m_spriterambase = (m_spriteaddr * 0x200) - 0x200;
+
+ bitmap.fill(0, cliprect);
+ m_prioritybitmap.fill(0, cliprect);
+
+ draw_background(screen, bitmap, cliprect);
+
+ draw_sprites(screen, bitmap, cliprect);
+ return 0;
+}
+
+void elan_eu3a14vid_device::video_start()
+{
+ m_screen->register_screen_bitmap(m_prioritybitmap);
+}
+
+
+uint8_t elan_eu3a14vid_device::read_gfxdata(int offset, int x)
+{
+ address_space& fullbankspace = m_bank->space(AS_PROGRAM);
+ return fullbankspace.read_byte((offset+x) & 0x3fffff);
+}
+
+void elan_eu3a14vid_device::draw_background_tile(bitmap_ind16& bitmap, const rectangle& cliprect, int bpp, int tileno, int palette, int priority, int flipx, int flipy, int xpos, int ypos, int transpen, int size, int base, int drawfromram)
+{
+ int baseaddr = base * 256;
+
+ int xstride = 8;
+
+ if (bpp == 8) // 8bpp selection
+ {
+ if (size == 8)
+ {
+ xstride = size / 1; baseaddr += tileno * 64; // 8x8 8bpp
+ }
+ else
+ {
+ xstride = size / 1; baseaddr += tileno * 256; // 16x16 8bpp
+ }
+
+ palette &= 0x100; // only top bit valid, as there are only 2 palettes?
+ }
+ else if (bpp == 4) // 4bpp selection
+ {
+ if (size == 8)
+ {
+ xstride = size / 2; baseaddr += tileno * 32; // 8x8 4bpp
+ }
+ else
+ {
+ xstride = size / 2; baseaddr += tileno * 128; // 16x16 4bpp
+ }
+ }
+ else if (bpp == 2) // 2bpp?
+ {
+ xstride = size / 4; baseaddr += tileno * 64; // 16x16 2bpp
+ }
+ else
+ {
+ popmessage("draw_background_tile unsupported bpp %d\n", bpp);
+ return;
+ }
+
+
+ int count = 0;
+ for (int y = 0; y < size; y++)
+ {
+ int realy = ypos + y;
+ int xposwithscroll = 0;
+
+ if (!drawfromram)
+ {
+ xposwithscroll = xpos - get_xscroll_for_screenypos(realy);
+ }
+ else
+ {
+ xposwithscroll = xpos;
+ // RAM tile layer has no scrolling? (or we've never seen it used / enabled)
+ }
+
+ uint16_t* dst = &bitmap.pix16(ypos + y);
+ uint8_t* pridst = &m_prioritybitmap.pix8(ypos + y);
+
+ for (int x = 0; x < xstride; x++)
+ {
+ int pix;
+
+ if (drawfromram)
+ {
+ pix = read_vram((baseaddr + count) & 0x3fff);
+ }
+ else
+ {
+ address_space& fullbankspace = m_bank->space(AS_PROGRAM);
+ pix = fullbankspace.read_byte((baseaddr+count) & 0x3fffff);
+ }
+
+ if (realy >= cliprect.min_y && realy <= cliprect.max_y)
+ {
+ if (bpp == 8) // 8bpp
+ {
+ int realx = x + xposwithscroll;
+ if (realx >= cliprect.min_x && realx <= cliprect.max_x)
+ {
+ if (pix)
+ {
+ if (pridst[realx] <= priority)
+ {
+ dst[realx] = pix | palette;
+ pridst[realx] = priority;
+ }
+
+ }
+ }
+ }
+ else if (bpp == 7)
+ {
+ popmessage("draw_background_tile bpp == 7");
+ }
+ else if (bpp == 6)
+ {
+ popmessage("draw_background_tile bpp == 6");
+ }
+ else if (bpp == 5)
+ {
+ popmessage("draw_background_tile bpp == 5");
+ }
+ else if (bpp == 4) // 4bpp
+ {
+ int realx = (x * 2) + xposwithscroll;
+ if (realx >= cliprect.min_x && realx <= cliprect.max_x)
+ {
+ if (pix & 0xf0)
+ {
+ if (pridst[realx] <= priority)
+ {
+ dst[realx] = ((pix & 0xf0) >> 4) | palette;
+ pridst[realx] = priority;
+ }
+ }
+ }
+
+ realx++;
+
+ if (realx >= cliprect.min_x && realx <= cliprect.max_x)
+ {
+ if (pix & 0x0f)
+ {
+ if (pridst[realx] <= priority)
+ {
+ dst[realx] = (pix & 0x0f) | palette;
+ pridst[realx] = priority;
+ }
+ }
+ }
+ }
+ else if (bpp == 3)
+ {
+ popmessage("draw_background_tile bpp == 3");
+ }
+ else if (bpp == 2) // 2bpp (hnt3 ram text)
+ {
+ int realx = (x * 4) + xposwithscroll;
+ if (realx >= cliprect.min_x && realx <= cliprect.max_x)
+ {
+ if (pix & 0xc0)
+ {
+ if (pridst[realx] <= priority)
+ {
+ dst[realx] = ((pix & 0xc0) >> 6) | palette;
+ pridst[realx] = priority;
+ }
+ }
+ }
+
+ realx++;
+
+ if (realx >= cliprect.min_x && realx <= cliprect.max_x)
+ {
+ if (pix & 0x30)
+ {
+ if (pridst[realx] <= priority)
+ {
+ dst[realx] = ((pix & 0x30) >> 4) | palette;
+ pridst[realx] = priority;
+ }
+ }
+ }
+
+ realx++;
+
+ if (realx >= cliprect.min_x && realx <= cliprect.max_x)
+ {
+ if (pix & 0x0c)
+ {
+ if (pridst[realx] <= priority)
+ {
+ dst[realx] = ((pix & 0x0c) >> 2) | palette;
+ pridst[realx] = priority;
+ }
+ }
+ }
+
+ realx++;
+
+ if (realx >= cliprect.min_x && realx <= cliprect.max_x)
+ {
+ if (pix & 0x03)
+ {
+ if (pridst[realx] <= priority)
+ {
+ dst[realx] = ((pix & 0x03) >> 0) | palette;
+ pridst[realx] = priority;
+ }
+ }
+ }
+ }
+ else if (bpp == 1)
+ {
+ popmessage("draw_background_tile bpp == 1");
+ }
+ }
+ count++;
+ }
+ }
+}
+
+int elan_eu3a14vid_device::get_xscroll_for_screenypos(int ydraw)
+{
+ if ((ydraw < 0) || (ydraw >= 224))
+ return 0;
+
+ int xscroll = m_scrollregs[0] | (m_scrollregs[1] << 8);
+
+ if (m_rowscrollcfg[1] == 0x01) // GUESS! could be anything, but this bit is set in Huntin'3
+ {
+ int split0 = m_rowscrollregs[0] | (m_rowscrollregs[1] << 8);
+ int split1 = m_rowscrollregs[2] | (m_rowscrollregs[3] << 8);
+ int split2 = m_rowscrollregs[4] | (m_rowscrollregs[5] << 8);
+ int split3 = m_rowscrollregs[6] | (m_rowscrollregs[7] << 8);
+
+ if (ydraw < m_rowscrollsplit[0])
+ {
+ return xscroll;
+ }
+ else if (ydraw < m_rowscrollsplit[1])
+ {
+ return split0;
+ }
+ else if (ydraw < m_rowscrollsplit[2])
+ {
+ return split1;
+ }
+ else if (ydraw < m_rowscrollsplit[3])
+ {
+ return split2;
+ }
+ else if (ydraw < m_rowscrollsplit[4])
+ {
+ return split3;
+ }
+ else
+ {
+ return 0;
+ }
+ }
+ else
+ {
+ return xscroll;
+ }
+}
+
+
+void elan_eu3a14vid_device::draw_background_page(screen_device& screen, bitmap_ind16& bitmap, const rectangle& cliprect, int ramstart, int ramend, int xbase, int ybase, int size, int bpp, int base, int pagewidth, int pageheight, int bytespertile, int palettepri, int drawfromram)
+{
+
+ int palette = ((palettepri & 0xf0) >> 4) | ((palettepri & 0x08) << 1);
+ palette = palette << 4;
+ int priority = palettepri & 0x07;
+
+ int xdraw = xbase;
+ int ydraw = ybase;
+ int count = 0;
+
+ for (int i = ramstart; i < ramend; i += bytespertile)
+ {
+ int tile = 0;
+ int realpalette = palette;
+ int realpriority = priority;
+ int realbpp = bpp;
+
+ if (bytespertile == 2)
+ {
+ tile = read_vram(i + 0) | (read_vram(i + 1) << 8);
+ }
+ else if (bytespertile == 4) // rad_foot hidden test mode, rad_hnt3 "Target Range" (not yet correct)
+ {
+ tile = read_vram(i + 0) | (read_vram(i + 1) << 8);// | (read_vram(i + 2) << 16) | | (read_vram(i + 3) << 24);
+
+ // read_vram(i + 3) & 0x04 is set in both seen cases, maybe per-tile bpp?
+ // this would match up with this mode being inline replacements for m_tilecfg[1] (palettepri) and m_tilecfg[2] (bpp);
+
+ int newpalette = ((read_vram(i + 2) & 0xf0) >> 4) | ((read_vram(i + 2) & 0x08) << 1);
+ newpalette = newpalette << 4;
+ realpalette = newpalette;
+ realpriority = read_vram(i + 2) & 0x07;
+ realbpp = read_vram(i + 3) & 0x07;
+ if (realbpp == 0)
+ realbpp = 8;
+
+ }
+
+
+ draw_background_tile(bitmap, cliprect, realbpp, tile, realpalette, realpriority, 0, 0, xdraw, ydraw, 0, size, base, drawfromram);
+
+ xdraw += size;
+
+ count++;
+ if (((count % pagewidth) == 0))
+ {
+ xdraw -= size * pagewidth;
+ ydraw += size;
+ }
+ }
+}
+
+void elan_eu3a14vid_device::draw_background_ramlayer(screen_device& screen, bitmap_ind16& bitmap, const rectangle& cliprect)
+{
+ // this register use is questionable
+ if (m_ramtilecfg[0] & 0x80)
+ {
+ int rtm_size;;
+ int rtm_pagewidth;
+ int rtm_pageheight;
+ int rtm_yscroll;
+ int rtm_bpp;
+ int rtm_bytespertile = 2;
+ uint8_t palettepri = m_ramtilecfg[1];
+
+ rtm_yscroll = 0;
+
+ // this is the gfxbase in ram for all cases seen
+ int rtm_base = (0x2000 - 0x200) / 256;
+
+ // same as regular layer?
+ if (m_ramtilecfg[0] & 0x10)
+ {
+ rtm_size = 8;
+ rtm_pagewidth = 32;
+ rtm_pageheight = 28;
+ }
+ else
+ {
+ rtm_size = 16;
+ rtm_pagewidth = 32 / 2;
+ rtm_pageheight = 28 / 2;
+ }
+
+ rtm_bpp = m_ramtilecfg[2] & 0x07;
+ if (rtm_bpp == 0)
+ rtm_bpp = 8;
+
+ // this is in the same place even when the first tilemap is in 16x16 mode, probably a base register somewhere
+ int ramstart = m_tilerambase + 0x700;
+ int ramend = m_tilerambase + 0x700 + 0x700;
+
+ // hack for "Target Range" mode
+ if (m_ramtilecfg[5] == 0x06)
+ {
+ ramstart = 0x3980-0x200;
+ ramend = 0x3980-0x200 + 0x700;
+ }
+
+ // normal
+ draw_background_page(screen, bitmap, cliprect, ramstart, ramend, 0, 0 - rtm_yscroll, rtm_size, rtm_bpp, rtm_base, rtm_pagewidth, rtm_pageheight, rtm_bytespertile, palettepri, 1);
+ // wrap x
+ draw_background_page(screen, bitmap, cliprect, ramstart, ramend, (rtm_size * rtm_pagewidth), 0 - rtm_yscroll, rtm_size, rtm_bpp, rtm_base, rtm_pagewidth, rtm_pageheight, rtm_bytespertile, palettepri, 1);
+ // wrap y
+ draw_background_page(screen, bitmap, cliprect, ramstart, ramend, 0, (rtm_size * rtm_pageheight) + 0 - rtm_yscroll, rtm_size, rtm_bpp, rtm_base, rtm_pagewidth, rtm_pageheight, rtm_bytespertile, palettepri, 1);
+ // wrap x+y
+ draw_background_page(screen, bitmap, cliprect, ramstart, ramend, (rtm_size * rtm_pagewidth), (rtm_size * rtm_pageheight) + 0 - rtm_yscroll, rtm_size, rtm_bpp, rtm_base, rtm_pagewidth, rtm_pageheight, rtm_bytespertile, palettepri, 1);
+ }
+}
+
+
+void elan_eu3a14vid_device::draw_background(screen_device &screen, bitmap_ind16 &bitmap, const rectangle &cliprect)
+{
+ int yscroll = m_scrollregs[2] | (m_scrollregs[3] << 8);
+
+ int base = (m_tilecfg[5] << 8) | m_tilecfg[4];
+ uint8_t palettepri = m_tilecfg[1];
+
+ int pagewidth = 1, pageheight = 1;
+ int bytespertile = 2;
+ int size;
+
+ // m_tilecfg[0] b-as ?-hh b = bytes per tile s = tilesize / page size? a = always set when tilemaps are in use - check? h = related to page positions, when set uses 2x2 pages? ? = used
+ // m_tilecfg[1] pppp x--? ? = used foot x = used, huntin3 summary (palette bank?) p = palette (used for different stages in huntin3 and the hidden test modes in others)
+ // m_tilecfg[2] ---- bbbb b = bpp mode (0 = 8bpp)
+ // m_tilecfg[3] ---- ---- (unused or more gfxbase?)
+ // m_tilecfg[4] gggg gggg gfxbase (lower bits)
+ // m_tilecfg[5] gggg gggg gfxbase (upper bits)
+
+ // ramtilecfg appears to be a similar format, except for the other layer with ram base tiles
+ // however 'a' in m_tilecfg[0] is NOT set
+ // also m_tilecfg[0] has 0x80 set, which would be 4 bytes per tile, but it isn't?
+ // the layer seems to be disabled by setting m_tilecfg[0] to 0?
+
+ if (m_tilecfg[0] & 0x10)
+ {
+ size = 8;
+ pagewidth = 32;
+ pageheight = 28;
+ }
+ else
+ {
+ size = 16;
+ pagewidth = 16;
+ pageheight = 14;
+ }
+
+ if (m_tilecfg[0] & 0x80)
+ {
+ bytespertile = 4;
+ }
+ else
+ {
+ bytespertile = 2;
+ }
+
+ int bpp = (m_tilecfg[2] & 0x07);
+ if (bpp == 0)
+ bpp = 8;
+
+ int ramstart = 0;
+ int ramend = 0;
+
+ int pagesize = pagewidth * pageheight * 2;
+
+ if (bytespertile == 4)
+ {
+ pagesize <<= 1; // shift because we need twice as much ram for this mode
+ }
+
+ if ((m_tilecfg[0] & 0x03) == 0x00) // tilemaps arranged as 2x2 pages?
+ {
+ ramstart = m_tilerambase + pagesize * 0;
+ ramend = m_tilerambase + pagesize * 1;
+
+ draw_background_page(screen, bitmap, cliprect, ramstart,ramend, 0, 0 - yscroll, size, bpp, base, pagewidth,pageheight, bytespertile, palettepri, 0); // normal
+ draw_background_page(screen, bitmap, cliprect, ramstart,ramend, (size * pagewidth * 2), 0 - yscroll, size, bpp, base, pagewidth,pageheight, bytespertile, palettepri, 0); // wrap x
+ draw_background_page(screen, bitmap, cliprect, ramstart,ramend, 0, (size * pageheight * 2) + 0 - yscroll, size, bpp, base, pagewidth,pageheight, bytespertile, palettepri, 0); // wrap y
+ draw_background_page(screen, bitmap, cliprect, ramstart,ramend, (size * pagewidth * 2), (size * pageheight * 2) + 0 - yscroll, size, bpp, base, pagewidth,pageheight, bytespertile, palettepri, 0); // wrap x+y
+
+ ramstart = m_tilerambase + pagesize * 1;
+ ramend = m_tilerambase + pagesize * 2;
+
+ draw_background_page(screen, bitmap, cliprect, ramstart,ramend, (size * pagewidth), 0 - yscroll, size, bpp, base, pagewidth,pageheight, bytespertile, palettepri, 0); // normal
+ draw_background_page(screen, bitmap, cliprect, ramstart,ramend, (size * pagewidth * 3), 0 - yscroll, size, bpp, base, pagewidth,pageheight, bytespertile, palettepri, 0); // wrap x
+ draw_background_page(screen, bitmap, cliprect, ramstart,ramend, (size * pagewidth), (size * pageheight * 2) + 0 - yscroll, size, bpp, base, pagewidth,pageheight, bytespertile, palettepri, 0); // wrap y
+ draw_background_page(screen, bitmap, cliprect, ramstart,ramend, (size * pagewidth * 3), (size * pageheight * 2) + 0 - yscroll, size, bpp, base, pagewidth,pageheight, bytespertile, palettepri, 0); // wrap x+y
+
+ ramstart = m_tilerambase + pagesize * 2;
+ ramend = m_tilerambase + pagesize * 3;
+
+ draw_background_page(screen, bitmap, cliprect, ramstart,ramend, 0, (size * pageheight) - yscroll, size, bpp, base, pagewidth,pageheight, bytespertile, palettepri, 0); // normal
+ draw_background_page(screen, bitmap, cliprect, ramstart,ramend, (size * pagewidth * 2), (size * pageheight) - yscroll, size, bpp, base, pagewidth,pageheight, bytespertile, palettepri, 0); // wrap x
+ draw_background_page(screen, bitmap, cliprect, ramstart,ramend, 0, (size * pageheight * 3) - yscroll, size, bpp, base, pagewidth,pageheight, bytespertile, palettepri, 0); // wrap y
+ draw_background_page(screen, bitmap, cliprect, ramstart,ramend, (size * pagewidth * 2), (size * pageheight * 3) - yscroll, size, bpp, base, pagewidth,pageheight, bytespertile, palettepri, 0); // wrap x+y
+
+ ramstart = m_tilerambase + pagesize * 3;
+ ramend = m_tilerambase + pagesize * 4;
+
+ draw_background_page(screen, bitmap, cliprect, ramstart,ramend, (size * pagewidth), (size * pageheight) - yscroll, size, bpp, base, pagewidth,pageheight, bytespertile, palettepri, 0); // normal
+ draw_background_page(screen, bitmap, cliprect, ramstart,ramend, (size * pagewidth * 3), (size * pageheight) - yscroll, size, bpp, base, pagewidth,pageheight, bytespertile, palettepri, 0); // wrap x
+ draw_background_page(screen, bitmap, cliprect, ramstart,ramend, (size * pagewidth), (size * pageheight * 3) - yscroll, size, bpp, base, pagewidth,pageheight, bytespertile, palettepri, 0);// wrap y
+ draw_background_page(screen, bitmap, cliprect, ramstart,ramend, (size * pagewidth * 3), (size * pageheight * 3) - yscroll, size, bpp, base, pagewidth,pageheight, bytespertile, palettepri, 0); // wrap x+y
+ }
+ else if ((m_tilecfg[0] & 0x03) == 0x03) // individual tilemaps? multiple layers?
+ {
+ // popmessage("m_tilecfg[0] & 0x03 multiple layers config %04x", base);
+ ramstart = m_tilerambase + pagesize * 0;
+ ramend = m_tilerambase + pagesize * 1;
+
+ // normal
+ draw_background_page(screen, bitmap, cliprect, ramstart, ramend, 0, 0 - yscroll, size, bpp, base, pagewidth,pageheight, bytespertile, palettepri, 0);
+ // wrap x
+ draw_background_page(screen, bitmap, cliprect, ramstart, ramend, (size * pagewidth), 0 - yscroll, size, bpp, base, pagewidth,pageheight, bytespertile, palettepri, 0);
+ // wrap y
+ draw_background_page(screen, bitmap, cliprect, ramstart, ramend, 0, (size * pageheight) + 0 - yscroll, size, bpp, base, pagewidth,pageheight, bytespertile, palettepri, 0);
+ // wrap x+y
+ draw_background_page(screen, bitmap, cliprect, ramstart, ramend, (size * pagewidth), (size * pageheight) + 0 - yscroll, size, bpp, base, pagewidth,pageheight, bytespertile, palettepri, 0);
+
+ // RAM based tile layer
+ draw_background_ramlayer(screen, bitmap, cliprect);
+ }
+ else
+ {
+ popmessage("m_tilecfg[0] & 0x03 unknown config");
+ }
+
+}
+
+void elan_eu3a14vid_device::draw_sprite_pix(const rectangle& cliprect, uint16_t* dst, uint8_t* pridst, int realx, int priority, uint8_t pix, uint8_t mask, uint8_t shift, int palette)
+{
+ if (realx >= cliprect.min_x && realx <= cliprect.max_x)
+ {
+ if (pridst[realx] <= priority)
+ {
+ if (pix & mask)
+ {
+ dst[realx] = ((pix & mask) >> shift) | palette;
+ pridst[realx] = priority;
+ }
+ }
+ }
+}
+
+void elan_eu3a14vid_device::draw_sprite_line(screen_device &screen, bitmap_ind16 &bitmap, const rectangle &cliprect, int offset, int line, int palette, int flipx, int priority, int xpos, int ypos, int bpp)
+{
+ offset = offset * 2;
+
+ int bppdiv = 0;
+
+ switch (bpp)
+ {
+ default:
+ case 0x8:
+ case 0x7:
+ case 0x6:
+ case 0x5:
+ offset += line * 8;
+ bppdiv = 1;
+ break;
+
+ case 0x4:
+ case 0x3:
+ offset += line * 4;
+ bppdiv = 2;
+ break;
+
+ case 0x2:
+ offset += line * 2;
+ bppdiv = 4;
+ break;
+
+ case 0x1:
+ offset += line * 1;
+ bppdiv = 8;
+ break;
+ }
+
+
+ if (ypos >= cliprect.min_y && ypos <= cliprect.max_y)
+ {
+ uint16_t* dst = &bitmap.pix16(ypos);
+ uint8_t* pridst = &m_prioritybitmap.pix8(ypos);
+
+ int count = 0;
+ for (int x = 0; x < 8/bppdiv;x++)
+ {
+ if (bpp == 8)
+ {
+ int pix,mask,shift;
+ if (flipx) { pix = read_gfxdata(offset, 7 - count); } else { pix = read_gfxdata(offset, count); }
+ int realx = xpos + x * 1;
+ if (flipx) { mask = 0xff; shift = 0; } else { mask = 0xff; shift = 0; }
+ draw_sprite_pix(cliprect, dst, pridst, realx, priority, pix, mask, shift, palette);
+ }
+ else if (bpp == 7)
+ {
+ int pix,mask,shift;
+ if (flipx) { pix = read_gfxdata(offset, 7 - count); } else { pix = read_gfxdata(offset, count); }
+ int realx = xpos + x * 1;
+ // stride doesn't change, data isn't packed, just don't use top bit
+ if (flipx) { mask = 0x7f; shift = 0; } else { mask = 0x7f; shift = 0; }
+ draw_sprite_pix(cliprect, dst, pridst, realx, priority, pix, mask, shift, palette);
+ }
+ else if (bpp == 6)
+ {
+ popmessage("6bpp sprite\n");
+ }
+ else if (bpp == 5)
+ {
+ popmessage("5bpp sprite\n");
+ }
+ else if (bpp == 4)
+ {
+ int pix,mask,shift;
+ if (flipx) { pix = read_gfxdata(offset, 3 - count); } else { pix = read_gfxdata(offset, count); }
+ int realx = xpos + x * 2;
+ if (flipx) { mask = 0x0f; shift = 0; } else { mask = 0xf0; shift = 4; }
+ draw_sprite_pix(cliprect, dst, pridst, realx, priority, pix, mask, shift, palette);
+ realx++;
+ if (flipx) { mask = 0xf0; shift = 4; } else { mask = 0x0f; shift = 0; }
+ draw_sprite_pix(cliprect, dst, pridst, realx, priority, pix, mask, shift, palette);
+ }
+ else if (bpp == 3)
+ {
+ popmessage("3bpp sprite\n");
+ }
+ else if (bpp == 2)
+ {
+ int pix,mask,shift;
+ if (flipx) { pix = read_gfxdata(offset, 1 - count); } else { pix = read_gfxdata(offset, count); }
+ int realx = xpos + x * 4;
+ if (flipx) { mask = 0x03; shift = 0; } else { mask = 0xc0; shift = 6; }
+ draw_sprite_pix(cliprect, dst, pridst, realx, priority, pix, mask, shift, palette);
+ realx++;
+ if (flipx) { mask = 0x0c; shift = 2; } else { mask = 0x30; shift = 4; }
+ draw_sprite_pix(cliprect, dst, pridst, realx, priority, pix, mask, shift, palette);
+ realx++;
+ if (flipx) { mask = 0x30; shift = 4; } else { mask = 0x0c; shift = 2; }
+ draw_sprite_pix(cliprect, dst, pridst, realx, priority, pix, mask, shift, palette);
+ realx++;
+ if (flipx) { mask = 0xc0; shift = 6; } else { mask = 0x03; shift = 0; }
+ draw_sprite_pix(cliprect, dst, pridst, realx, priority, pix, mask, shift, palette);
+ }
+ else if (bpp == 1)
+ {
+ popmessage("1bpp sprite\n");
+ }
+
+ count++;
+ }
+ }
+
+}
+
+
+void elan_eu3a14vid_device::draw_sprites(screen_device &screen, bitmap_ind16 &bitmap, const rectangle &cliprect)
+{
+ // first 4 sprite entries seem to be garbage sprites, so we start at 0x20
+ // likely we're just interpreting them wrong and they're used for blanking things or clipping?
+ for (int i = m_spriterambase; i < m_spriterambase + 0x800; i += 8)
+ {
+ /*
+ +0 e-ff hhww flip yx, enable, height, width
+ +1 yyyy yyyy ypos
+ +2 xxxx xxxx xpos
+ +3 pppp Pzzz p = palette, P = upper palette bank, z = priority
+ +4 tttt tttt tile bits
+ +5 tttt tttt
+ +6 --TT TPPP TTT = tile bank PPP = bpp select (+more?)
+ +7 ---- ----
+
+ */
+
+ int attr = read_vram(i + 0);
+ int y = read_vram(i + 1);
+ int x = read_vram(i + 2);
+ int palettepri = read_vram(i + 3);
+
+ int h = attr & 0x0c;
+ int w = attr & 0x03;
+ int flipx = (attr & 0x10) >> 4;
+ int flipy = (attr & 0x20) >> 5;
+
+ int height = 0;
+ int width = 0;
+
+ int pri = palettepri & 0x07;
+
+ int palette = ((palettepri & 0xf0) >> 4) | ((palettepri & 0x08) << 1);
+ palette = palette << 4;
+
+ switch (h)
+ {
+ case 0x0:height = 2; break;
+ case 0x4:height = 4; break;
+ case 0x8:height = 8; break;
+ case 0xc:height = 16; break;
+ }
+
+ switch (w)
+ {
+ case 0x0:width = 1; break;
+ case 0x1:width = 2; break;
+ case 0x2:width = 4; break;
+ case 0x3:width = 8; break;
+ }
+
+ y -= ((height * 2) - 4);
+
+ x -= ((width * 4) - 4);
+
+ height *= 4;
+
+ x -= 6;
+ y -= 4;
+
+ int offset = ((read_vram(i + 5) << 8) + (read_vram(i + 4) << 0));
+ int extra = read_vram(i + 6);
+
+ int spritebase = (m_spritebase[1] << 8) | m_spritebase[0];
+
+ offset += (extra & 0xf8) << 13;
+ offset += spritebase << 7;
+
+ int bpp = extra & 0x07;
+ if (bpp == 0)
+ bpp = 8;
+
+ if (attr & 0x80)
+ {
+ int count = 0;
+ for (int yy = 0; yy < height; yy++)
+ {
+ int yoff = flipy ? height-1-yy : yy;
+
+ for (int xx = 0; xx < width; xx++)
+ {
+ int xoff = flipx ? (((width - 1) * 8) - (xx * 8)) : (xx * 8);
+
+ draw_sprite_line(screen, bitmap, cliprect, offset, count, palette, flipx, pri, x + xoff, y + yoff, bpp);
+ count++;
+ }
+ }
+ }
+ }
+}
+
diff --git a/src/mame/video/elan_eu3a14vid.h b/src/mame/video/elan_eu3a14vid.h
new file mode 100644
index 00000000000..71f91a6aae0
--- /dev/null
+++ b/src/mame/video/elan_eu3a14vid.h
@@ -0,0 +1,90 @@
+// license:BSD-3-Clause
+// copyright-holders:David Haywood
+
+#ifndef MAME_VIDEO_ELAN_EU3A14VID_H
+#define MAME_VIDEO_ELAN_EU3A14VID_H
+
+#include "elan_eu3a05commonvid.h"
+#include "cpu/m6502/m6502.h"
+#include "machine/bankdev.h"
+#include "screen.h"
+
+class elan_eu3a14vid_device : public elan_eu3a05commonvid_device
+{
+public:
+ elan_eu3a14vid_device(const machine_config &mconfig, const char *tag, device_t *owner, uint32_t clock);
+
+ 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)); }
+ template <typename T> void set_screen(T &&tag) { m_screen.set_tag(std::forward<T>(tag)); }
+
+ void set_tilerambase(int tilerambase) { m_tilerambase = tilerambase; }
+
+ void video_start();
+ uint32_t screen_update(screen_device &screen, bitmap_ind16 &bitmap, const rectangle &cliprect);
+
+ DECLARE_READ8_MEMBER(tilecfg_r) { return m_tilecfg[offset]; }
+ DECLARE_WRITE8_MEMBER(tilecfg_w) { m_tilecfg[offset] = data; }
+ DECLARE_READ8_MEMBER(ramtilecfg_r) { return m_ramtilecfg[offset]; }
+ DECLARE_WRITE8_MEMBER(ramtilecfg_w) { m_ramtilecfg[offset] = data; }
+ DECLARE_READ8_MEMBER(rowscrollcfg_r) { return m_rowscrollcfg[offset]; }
+ DECLARE_WRITE8_MEMBER(rowscrollcfg_w) { m_rowscrollcfg[offset] = data; }
+ DECLARE_READ8_MEMBER(scrollregs_r) { return m_scrollregs[offset]; }
+ DECLARE_WRITE8_MEMBER(scrollregs_w) { m_scrollregs[offset] = data; }
+ DECLARE_READ8_MEMBER(rowscrollregs_r) { return m_rowscrollregs[offset]; }
+ DECLARE_WRITE8_MEMBER(rowscrollregs_w) { m_rowscrollregs[offset] = data; }
+
+ DECLARE_READ8_MEMBER(spriteaddr_r) { return m_spriteaddr; }
+ DECLARE_WRITE8_MEMBER(spriteaddr_w) { m_spriteaddr = data; }
+
+ DECLARE_READ8_MEMBER(spritebase_r) { return m_spritebase[offset]; }
+ DECLARE_WRITE8_MEMBER(spritebase_w) { m_spritebase[offset] = data; }
+
+ DECLARE_READ8_MEMBER(rowscrollsplit_r) { return m_rowscrollsplit[offset]; }
+ DECLARE_WRITE8_MEMBER(rowscrollsplit_w) { m_rowscrollsplit[offset] = data; }
+
+
+ int m_tilerambase;
+ int m_spriterambase;
+
+ bitmap_ind8 m_prioritybitmap;
+
+
+ void draw_background_ramlayer(screen_device& screen, bitmap_ind16& bitmap, const rectangle& cliprect);
+ int get_xscroll_for_screenypos(int line);
+ void draw_background_tile(bitmap_ind16 &bitmap, const rectangle &cliprect, int bpp, int tileno, int palette, int priority, int flipx, int flipy, int xpos, int ypos, int transpen, int size, int base, int drawfromram);
+ void draw_background_page(screen_device &screen, bitmap_ind16 &bitmap, const rectangle &cliprect, int ramstart, int ramend, int xbase, int ybase, int size, int bpp, int base, int pagewidth,int pageheight, int bytespertile, int palettepri, int drawfromram);
+ void draw_background(screen_device &screen, bitmap_ind16 &bitmap, const rectangle &cliprect);
+ void draw_sprite_pix(const rectangle& cliprect, uint16_t* dst, uint8_t* pridst, int realx, int priority, uint8_t pix, uint8_t mask, uint8_t shift, int palette);
+ void draw_sprite_line(screen_device &screen, bitmap_ind16 &bitmap, const rectangle &cliprect, int offset, int line, int pal, int flipx, int pri, int xpos, int ypos, int bpp);
+ void draw_sprites(screen_device &screen, bitmap_ind16 &bitmap, const rectangle &cliprect);
+
+
+protected:
+ // device-level overrides
+ virtual void device_start() override;
+ virtual void device_reset() override;
+
+private:
+ required_device<m6502_device> m_cpu;
+ required_device<address_map_bank_device> m_bank;
+ required_device<screen_device> m_screen;
+
+ uint8_t read_gfxdata(int offset, int x);
+
+ uint8_t read_vram(int offset);
+
+ uint8_t m_scrollregs[4];
+ uint8_t m_tilecfg[6];
+ uint8_t m_rowscrollregs[8];
+ uint8_t m_rowscrollsplit[5];
+ uint8_t m_rowscrollcfg[2];
+ uint8_t m_ramtilecfg[6];
+ uint8_t m_spriteaddr;
+ uint8_t m_spritebase[2];
+
+};
+
+DECLARE_DEVICE_TYPE(ELAN_EU3A14_VID, elan_eu3a14vid_device)
+
+#endif // MAME_VIDEO_ELAN_EU3A14VID_H