summaryrefslogtreecommitdiffstatshomepage
diff options
context:
space:
mode:
author mooglyguy <therealmogminer@gmail.com>2018-06-01 11:41:52 +0200
committer mooglyguy <therealmogminer@gmail.com>2018-06-01 11:41:52 +0200
commit2cdb153103fa94d13a53dd747985ef56ec723e7a (patch)
treebbb19eca10de61e842c95e84fc823d17a6c68f23
parentd96189dfc9b49a6031d24000d31b9479a73c4e9e (diff)
svis_snd cleanups, nw
-rw-r--r--src/emu/diexec.cpp14
-rw-r--r--src/emu/diexec.h6
-rw-r--r--src/emu/screen.cpp33
-rw-r--r--src/emu/screen.h7
-rw-r--r--src/mame/audio/svis_snd.cpp24
-rw-r--r--src/mame/audio/svis_snd.h22
-rw-r--r--src/mame/drivers/svision.cpp290
-rw-r--r--src/mame/includes/svision.h76
8 files changed, 222 insertions, 250 deletions
diff --git a/src/emu/diexec.cpp b/src/emu/diexec.cpp
index f77f58fa83f..972c3ecdf96 100644
--- a/src/emu/diexec.cpp
+++ b/src/emu/diexec.cpp
@@ -46,7 +46,7 @@ device_execute_interface::device_execute_interface(const machine_config &mconfig
: device_interface(device, "execute")
, m_scheduler(nullptr)
, m_disabled(false)
- , m_vblank_interrupt_screen(nullptr)
+ , m_vblank_interrupt_screen(*this, finder_base::DUMMY_TAG)
, m_timed_interrupt_period(attotime::zero)
, m_nextexec(nullptr)
, m_timedint_timer(nullptr)
@@ -350,8 +350,8 @@ void device_execute_interface::interface_validity_check(validity_checker &valid)
screen_device_iterator iter(device().mconfig().root_device());
if (iter.first() == nullptr)
osd_printf_error("VBLANK interrupt specified, but the driver is screenless\n");
- else if (m_vblank_interrupt_screen != nullptr && device().siblingdevice(m_vblank_interrupt_screen) == nullptr)
- osd_printf_error("VBLANK interrupt references a non-existant screen tag '%s'\n", m_vblank_interrupt_screen);
+ else if (m_vblank_interrupt_screen == nullptr)
+ osd_printf_error("VBLANK interrupt references a non-existant screen tag\n");
}
if (!m_timed_interrupt.isnull() && m_timed_interrupt_period == attotime::zero)
@@ -443,13 +443,9 @@ void device_execute_interface::interface_post_reset()
elem.reset();
// reconfingure VBLANK interrupts
- if (m_vblank_interrupt_screen != nullptr)
+ if (m_vblank_interrupt_screen)
{
- // get the screen that will trigger the VBLANK
- screen_device *screen = device().siblingdevice<screen_device>(m_vblank_interrupt_screen);
-
- assert(screen != nullptr);
- screen->register_vblank_callback(vblank_state_delegate(&device_execute_interface::on_vblank, this));
+ m_vblank_interrupt_screen->register_vblank_callback(vblank_state_delegate(&device_execute_interface::on_vblank, this));
}
// reconfigure periodic interrupts
diff --git a/src/emu/diexec.h b/src/emu/diexec.h
index 3c9d754434e..3c1e17bd156 100644
--- a/src/emu/diexec.h
+++ b/src/emu/diexec.h
@@ -140,10 +140,10 @@ public:
// inline configuration helpers
void set_disable() { m_disabled = true; }
- template <typename Object> void set_vblank_int(Object &&cb, const char *tag, int rate = 0)
+ template <typename Object, typename T> void set_vblank_int(Object &&cb, T &&tag, int rate = 0)
{
m_vblank_interrupt = std::forward<Object>(cb);
- m_vblank_interrupt_screen = tag;
+ m_vblank_interrupt_screen.set_tag(std::forward<T>(tag));
}
template <typename Object> void set_periodic_int(Object &&cb, const attotime &rate)
{
@@ -290,7 +290,7 @@ private:
// configuration
bool m_disabled; // disabled from executing?
device_interrupt_delegate m_vblank_interrupt; // for interrupts tied to VBLANK
- const char * m_vblank_interrupt_screen; // the screen that causes the VBLANK interrupt
+ optional_device<screen_device> m_vblank_interrupt_screen; // the screen that causes the VBLANK interrupt
device_interrupt_delegate m_timed_interrupt; // for interrupts not tied to VBLANK
attotime m_timed_interrupt_period; // period for periodic interrupts
diff --git a/src/emu/screen.cpp b/src/emu/screen.cpp
index b4bdce1f45a..6434419c761 100644
--- a/src/emu/screen.cpp
+++ b/src/emu/screen.cpp
@@ -556,8 +556,7 @@ screen_device::screen_device(const machine_config &mconfig, const char *tag, dev
m_xscale(1.0f),
m_yscale(1.0f),
m_screen_vblank(*this),
- m_palette(nullptr),
- m_palette_tag(nullptr),
+ m_palette(*this, finder_base::DUMMY_TAG),
m_video_attributes(0),
m_svg_region(nullptr),
m_container(nullptr),
@@ -631,23 +630,17 @@ void screen_device::device_validity_check(validity_checker &valid) const
osd_printf_error("Invalid (zero) refresh rate\n");
texture_format texformat = !m_screen_update_ind16.isnull() ? TEXFORMAT_PALETTE16 : TEXFORMAT_RGB32;
- if (m_palette_tag != nullptr)
+ if (m_palette != nullptr)
{
if (texformat == TEXFORMAT_RGB32)
- osd_printf_warning("Screen does not need palette defined\n");
-
- device_t *paldev = owner()->subdevice(m_palette_tag);
- if (paldev == nullptr)
- osd_printf_error("Nonexistent device '%s' specified as palette\n", m_palette_tag);
- else
{
- device_palette_interface *palintf;
- if (!paldev->interface(palintf))
- osd_printf_error("Device '%s' specified as palette, but it has no palette interface\n", m_palette_tag);
+ osd_printf_warning("Screen does not need palette defined\n");
}
}
else if (texformat == TEXFORMAT_PALETTE16)
+ {
osd_printf_error("Screen does not have palette defined\n");
+ }
}
@@ -664,21 +657,9 @@ void screen_device::device_resolve_objects()
m_screen_update_rgb32.bind_relative_to(*owner());
m_screen_vblank.resolve_safe();
- // find the specified palette
- if (m_palette_tag != nullptr && m_palette == nullptr)
+ // assign our format to the palette before it starts
+ if (m_palette)
{
- // find our palette as a sibling device
- device_t *palette = owner()->subdevice(m_palette_tag);
- if (palette == nullptr)
- fatalerror("Screen '%s' specifies nonexistent device '%s' as palette\n",
- tag(),
- m_palette_tag);
- if (!palette->interface(m_palette))
- fatalerror("Screen '%s' specifies device '%s' as palette, but it has no palette interface\n",
- tag(),
- m_palette_tag);
-
- // assign our format to the palette before it starts
m_palette->m_format = format();
}
}
diff --git a/src/emu/screen.h b/src/emu/screen.h
index 2bfbc8af963..508c0756e37 100644
--- a/src/emu/screen.h
+++ b/src/emu/screen.h
@@ -219,7 +219,7 @@ public:
m_screen_update_rgb32 = callback;
}
template<class Object> devcb_base &set_screen_vblank(Object &&object) { return m_screen_vblank.set_callback(std::forward<Object>(object)); }
- void set_palette(const char *tag) { m_palette_tag = tag; }
+ template<typename T> void set_palette(T &&tag) { m_palette.set_tag(std::forward<T>(tag)); }
void set_video_attributes(u32 flags) { m_video_attributes = flags; }
void set_color(rgb_t color) { m_color = color; }
void set_svg_region(const char *region) { m_svg_region = region; }
@@ -309,8 +309,7 @@ private:
screen_update_ind16_delegate m_screen_update_ind16; // screen update callback (16-bit palette)
screen_update_rgb32_delegate m_screen_update_rgb32; // screen update callback (32-bit RGB)
devcb_write_line m_screen_vblank; // screen vblank line callback
- device_palette_interface *m_palette; // our palette
- const char * m_palette_tag; // configured tag for palette device
+ optional_device<palette_device> m_palette; // our palette
u32 m_video_attributes; // flags describing the video system
const char * m_svg_region; // the region in which the svg data is in
@@ -515,7 +514,7 @@ typedef device_type_iterator<screen_device> screen_device_iterator;
#define MCFG_SCREEN_PALETTE(_palette_tag) \
downcast<screen_device &>(*device).set_palette(_palette_tag);
#define MCFG_SCREEN_NO_PALETTE \
- downcast<screen_device &>(*device).set_palette(nullptr);
+ downcast<screen_device &>(*device).set_palette(finder_base::DUMMY_TAG);
#define MCFG_SCREEN_VIDEO_ATTRIBUTES(_flags) \
downcast<screen_device &>(*device).set_video_attributes(_flags);
#define MCFG_SCREEN_COLOR(_color) \
diff --git a/src/mame/audio/svis_snd.cpp b/src/mame/audio/svis_snd.cpp
index 2f881e9db95..60b98a9c7ad 100644
--- a/src/mame/audio/svis_snd.cpp
+++ b/src/mame/audio/svis_snd.cpp
@@ -25,6 +25,9 @@ DEFINE_DEVICE_TYPE(SVISION_SND, svision_sound_device, "svision_sound", "Super Vi
svision_sound_device::svision_sound_device(const machine_config &mconfig, const char *tag, device_t *owner, uint32_t clock)
: device_t(mconfig, SVISION_SND, tag, owner, clock)
, device_sound_interface(mconfig, *this)
+ , m_irq_cb(*this)
+ , m_maincpu(*this, finder_base::DUMMY_TAG)
+ , m_cartrom(*this, finder_base::DUMMY_TAG)
, m_mixer_channel(nullptr)
{
}
@@ -36,8 +39,7 @@ svision_sound_device::svision_sound_device(const machine_config &mconfig, const
void svision_sound_device::device_start()
{
- // bind callbacks
- m_irq_cb.bind_relative_to(*owner());
+ m_irq_cb.resolve_safe();
memset(&m_dma, 0, sizeof(m_dma));
memset(&m_noise, 0, sizeof(m_noise));
@@ -132,11 +134,11 @@ void svision_sound_device::sound_stream_update(sound_stream &stream, stream_samp
uint16_t addr = m_dma.start + (unsigned) m_dma.pos / 2;
if (addr >= 0x8000 && addr < 0xc000)
{
- sample = machine().root_device().memregion("user1")->base()[(addr & 0x3fff) | m_dma.ca14to16];
+ sample = ((uint8_t*)m_cartrom->base())[(addr & 0x3fff) | m_dma.ca14to16];
}
else
{
- sample = machine().device("maincpu")->memory().space(AS_PROGRAM).read_byte(addr);
+ sample = m_maincpu->space(AS_PROGRAM).read_byte(addr);
}
if (((unsigned)m_dma.pos) & 1)
s = (sample & 0xf);
@@ -152,7 +154,7 @@ void svision_sound_device::sound_stream_update(sound_stream &stream, stream_samp
{
m_dma.finished = true;
m_dma.on = false;
- m_irq_cb();
+ m_irq_cb(1);
}
}
}
@@ -173,7 +175,7 @@ WRITE8_MEMBER( svision_sound_device::sounddma_w )
m_dma.size = (data ? data : 0x100) * 32;
break;
case 3:
- m_dma.step = machine().device("maincpu")->unscaled_clock() / (256.0 * machine().sample_rate() * (1 + (data & 3)));
+ m_dma.step = unscaled_clock() / (256.0 * machine().sample_rate() * (1 + (data & 3)));
m_dma.right = data & 4;
m_dma.left = data & 8;
m_dma.ca14to16 = ((data & 0x70) >> 4) << 14;
@@ -197,7 +199,7 @@ WRITE8_MEMBER( svision_sound_device::noise_w )
{
case 0:
m_noise.volume=data&0xf;
- m_noise.step= machine().device("maincpu")->unscaled_clock() / (256.0*machine().sample_rate()*(1+(data>>4)));
+ m_noise.step= unscaled_clock() / (256.0*machine().sample_rate()*(1+(data>>4)));
break;
case 1:
m_noise.count = data + 1;
@@ -215,12 +217,6 @@ WRITE8_MEMBER( svision_sound_device::noise_w )
}
-int *svision_sound_device::dma_finished()
-{
- return &m_dma.finished;
-}
-
-
void svision_sound_device::sound_decrement()
{
if (m_channel[0].count > 0)
@@ -248,7 +244,7 @@ void svision_sound_device::soundport_w(int which, int offset, int data)
if (size)
{
// channel.size=(int)(device->machine().sample_rate()*(size<<5)/4e6);
- channel.size= (int) (machine().sample_rate() * (size << 5) / machine().device("maincpu")->unscaled_clock());
+ channel.size = (int) (machine().sample_rate() * (size << 5) / unscaled_clock());
}
else
{
diff --git a/src/mame/audio/svis_snd.h b/src/mame/audio/svis_snd.h
index e53b908f75e..44a40e5de86 100644
--- a/src/mame/audio/svis_snd.h
+++ b/src/mame/audio/svis_snd.h
@@ -16,27 +16,30 @@
// TYPE DEFINITIONS
//**************************************************************************
-#define SVISION_SND_IRQ_MEMBER(_name) void _name(void)
-
-#define SVISION_SND_IRQ_CB(_class, _method) \
- downcast<svision_sound_device &>(*device).set_irq_callback(svision_sound_device::irq_delegate(&_class::_method, #_class "::" #_method, this));
+#define MCFG_SVISION_SOUND_IRQ_CALLBACK(_devcb) \
+ devcb = &downcast<svision_sound_device&>(*device).set_irq_cb(DEVCB_##_devcb);
// ======================> svision_sound_device
class svision_sound_device : public device_t, public device_sound_interface
{
public:
- typedef device_delegate<void ()> irq_delegate;
+ template <typename T, typename U>
+ svision_sound_device(const machine_config &mconfig, const char *tag, device_t *owner, uint32_t clock, T &&cpu_tag, U &&region_tag)
+ : svision_sound_device(mconfig, tag, owner, clock)
+ {
+ m_maincpu.set_tag(std::forward<T>(cpu_tag));
+ m_cartrom.set_tag(std::forward<U>(region_tag));
+ }
svision_sound_device(const machine_config &mconfig, const char *tag, device_t *owner, uint32_t clock);
// configuration
- template<typename Object> void set_irq_callback(Object &&callback) { m_irq_cb = std::forward<Object>(callback); }
+ template <class Object> devcb_base &set_irq_cb(Object &&cb) { return m_irq_cb.set_callback(std::forward<Object>(cb)); }
DECLARE_WRITE8_MEMBER( sounddma_w );
DECLARE_WRITE8_MEMBER( noise_w );
- int *dma_finished();
void sound_decrement();
void soundport_w(int which, int offset, int data);
@@ -92,7 +95,10 @@ private:
int count = 0;
};
- irq_delegate m_irq_cb;
+ devcb_write_line m_irq_cb;
+
+ required_device<cpu_device> m_maincpu;
+ required_memory_bank m_cartrom;
sound_stream *m_mixer_channel;
DMA m_dma;
diff --git a/src/mame/drivers/svision.cpp b/src/mame/drivers/svision.cpp
index 5cd168ab6ff..a8b15a0a3f5 100644
--- a/src/mame/drivers/svision.cpp
+++ b/src/mame/drivers/svision.cpp
@@ -21,32 +21,26 @@
#define MAKE24_RGB32(red8, green8, blue8) ( (((red8)&0xf8)<<16) | (((green8)&0xf8)<<8) | (((blue8)&0xf8)) )
-// in pixel
-#define XSIZE (m_reg[0]&~3)
-#define XPOS m_reg[2]
-#define YPOS m_reg[3]
-#define BANK m_reg[0x26]
-
TIMER_CALLBACK_MEMBER(svision_state::svision_pet_timer)
{
switch (m_pet.state)
{
- case 0:
+ case 0x00:
if (m_joy2.found())
{
m_pet.input = m_joy2->read();
}
/* fall through */
- case 2: case 4: case 6: case 8:
- case 10: case 12: case 14:
+ case 0x02: case 0x04: case 0x06: case 0x08:
+ case 0x0a: case 0x0c: case 0x0e:
m_pet.clock = m_pet.state & 2;
m_pet.data = m_pet.input & 1;
m_pet.input >>= 1;
m_pet.state++;
break;
- case 16+15:
+ case 0x1f:
m_pet.state = 0;
break;
@@ -61,10 +55,16 @@ TIMER_DEVICE_CALLBACK_MEMBER(svision_state::svision_pet_timer_dev)
svision_pet_timer(ptr,param);
}
-void svision_state::svision_irq()
+WRITE_LINE_MEMBER(svision_state::sound_irq_w)
+{
+ m_dma_finished = true;
+ check_irq();
+}
+
+void svision_state::check_irq()
{
- int irq = m_svision.timer_shot && (BANK & 2);
- irq = irq || (*m_dma_finished && (BANK & 4));
+ bool irq = m_svision.timer_shot && BIT(m_reg[BANK], 1);
+ irq = irq || (m_dma_finished && BIT(m_reg[BANK], 2));
m_maincpu->set_input_line(M65C02_IRQ_LINE, irq ? ASSERT_LINE : CLEAR_LINE);
}
@@ -73,7 +73,7 @@ TIMER_CALLBACK_MEMBER(svision_state::svision_timer)
{
m_svision.timer_shot = true;
m_svision.timer1->enable(false);
- svision_irq();
+ check_irq();
}
READ8_MEMBER(svision_state::svision_r)
@@ -82,8 +82,7 @@ READ8_MEMBER(svision_state::svision_r)
switch (offset)
{
case 0x20:
- data = m_joy->read();
- break;
+ return m_joy->read();
case 0x21:
data &= ~0xf;
@@ -105,22 +104,22 @@ READ8_MEMBER(svision_state::svision_r)
data &= ~3;
if (m_svision.timer_shot)
{
- data|=1;
+ data |= 1;
}
- if (*m_dma_finished)
+ if (m_dma_finished)
{
- data|=2;
+ data |= 2;
}
break;
case 0x24:
m_svision.timer_shot = false;
- svision_irq();
+ check_irq();
break;
case 0x25:
- *m_dma_finished = false;
- svision_irq();
+ m_dma_finished = false;
+ check_irq();
break;
default:
@@ -133,39 +132,29 @@ READ8_MEMBER(svision_state::svision_r)
WRITE8_MEMBER(svision_state::svision_w)
{
- int value, delay, bank;
-
m_reg[offset] = data;
switch (offset)
{
- case 2:
- case 3:
+ case 0x02:
+ case 0x03:
break;
case 0x26: /* bits 5,6 memory management for a000? */
+ {
logerror("%.6f svision write %04x %02x\n", machine().time().as_double(), offset, data);
- bank = ((m_reg[0x26] & 0xe0) >> 5) % (m_cart_rom->bytes() / 0x4000);
+ int bank = ((m_reg[0x26] & 0xe0) >> 5) % (m_cart_rom->bytes() / 0x4000);
m_bank1->set_base(m_cart_rom->base() + (bank * 0x4000));
- svision_irq();
+ check_irq();
break;
+ }
case 0x23: /* delta hero irq routine write */
- value = data;
- if (!data)
- {
- value = 0x100;
- }
- if (BANK & 0x10)
- {
- delay = 16384;
- }
- else
- {
- delay = 256;
- }
m_svision.timer1->enable(true);
- m_svision.timer1->reset(m_maincpu->cycles_to_attotime(value * delay));
+ if (BIT(m_reg[BANK], 4))
+ m_svision.timer1->reset(m_maincpu->cycles_to_attotime(0x100 * 0x4000));
+ else
+ m_svision.timer1->reset(m_maincpu->cycles_to_attotime(0x100 * 0x100));
break;
case 0x10: case 0x11: case 0x12: case 0x13:
@@ -235,16 +224,15 @@ WRITE8_MEMBER(svision_state::tvlink_w)
svision_w(space, offset,data);
if (offset >= 0x800 && offset < 0x840)
{
- uint16_t c;
if (offset == 0x803 && data == 0x07)
{
/* tron hack */
- m_reg[0x0804]=0x00;
- m_reg[0x0805]=0x01;
- m_reg[0x0806]=0x00;
- m_reg[0x0807]=0x00;
+ m_reg[0x0804] = 0x00;
+ m_reg[0x0805] = 0x01;
+ m_reg[0x0806] = 0x00;
+ m_reg[0x0807] = 0x00;
}
- c = m_reg[0x800] | (m_reg[0x804] << 8);
+ uint16_t c = m_reg[0x800] | (m_reg[0x804] << 8);
m_tvlink.palette[0] = MAKE9_RGB32( (c>>0)&7, (c>>3)&7, (c>>6)&7);
c = m_reg[0x801] | (m_reg[0x805] << 8);
m_tvlink.palette[1] = MAKE9_RGB32( (c>>0)&7, (c>>3)&7, (c>>6)&7);
@@ -262,21 +250,21 @@ WRITE8_MEMBER(svision_state::tvlink_w)
void svision_state::svision_mem(address_map &map)
{
map(0x0000, 0x1fff).ram();
- map(0x2000, 0x3fff).rw(this, FUNC(svision_state::svision_r), FUNC(svision_state::svision_w)).share("reg");
- map(0x4000, 0x5fff).ram().share("videoram");
+ map(0x2000, 0x3fff).rw(this, FUNC(svision_state::svision_r), FUNC(svision_state::svision_w)).share(m_reg);
+ map(0x4000, 0x5fff).ram().share(m_videoram);
map(0x6000, 0x7fff).noprw();
- map(0x8000, 0xbfff).bankr("bank1");
- map(0xc000, 0xffff).bankr("bank2");
+ map(0x8000, 0xbfff).bankr(m_bank1);
+ map(0xc000, 0xffff).bankr(m_bank2);
}
void svision_state::tvlink_mem(address_map &map)
{
map(0x0000, 0x1fff).ram();
- map(0x2000, 0x3fff).rw(this, FUNC(svision_state::tvlink_r), FUNC(svision_state::tvlink_w)).share("reg");
- map(0x4000, 0x5fff).ram().share("videoram");
+ map(0x2000, 0x3fff).rw(this, FUNC(svision_state::tvlink_r), FUNC(svision_state::tvlink_w)).share(m_reg);
+ map(0x4000, 0x5fff).ram().share(m_videoram);
map(0x6000, 0x7fff).noprw();
- map(0x8000, 0xbfff).bankr("bank1");
- map(0xc000, 0xffff).bankr("bank2");
+ map(0x8000, 0xbfff).bankr(m_bank1);
+ map(0xc000, 0xffff).bankr(m_bank2);
}
static INPUT_PORTS_START( svision )
@@ -315,8 +303,6 @@ INPUT_PORTS_END
/* most games contain their graphics in roms, and have hardware to
draw complete rectangular objects */
-#define PALETTE_START 0
-
/* palette in red, green, blue triples */
static const unsigned char svision_palette[] =
{
@@ -337,7 +323,7 @@ static const unsigned char svision_palette[] =
#endif
};
-/* palette in red, green, blue tribles */
+/* palette in RGB triplets */
static const unsigned char svisionp_palette[] =
{
// pal
@@ -347,7 +333,7 @@ static const unsigned char svisionp_palette[] =
190, 190, 190
};
-/* palette in red, green, blue tribles */
+/* palette in RGB triplets */
static const unsigned char svisionn_palette[] =
{
0, 0, 0,
@@ -374,69 +360,71 @@ PALETTE_INIT_MEMBER(svision_state,svisionp)
uint32_t svision_state::screen_update_svision(screen_device &screen, bitmap_ind16 &bitmap, const rectangle &cliprect)
{
- int x, y, i, j=XPOS/4+YPOS*0x30;
- uint8_t *videoram = m_videoram;
-
- if (BANK&8)
+ if (BIT(m_reg[BANK], 3))
{
- for (y=0; y<160; y++)
+ int j = m_reg[XPOS] / 4 + m_reg[YPOS] * 0x30;
+ for (int y = 0; y < 160; y++)
{
- uint16_t *line = &bitmap.pix16(y, 3 - (XPOS & 3));
- for (x=3-(XPOS&3),i=0; x<160+3 && x<XSIZE+3; x+=4,i++)
+ const int start_x = 3 - (m_reg[XPOS] & 3);
+ const int end_x = std::min(163, m_reg[XSIZE] | 3);
+ uint16_t *line = &bitmap.pix16(y, start_x);
+ for (int x = start_x, i = 0; x < end_x; x+=4, i++)
{
- uint8_t b=videoram[j+i];
- line[3]=((b>>6)&3)+PALETTE_START;
- line[2]=((b>>4)&3)+PALETTE_START;
- line[1]=((b>>2)&3)+PALETTE_START;
- line[0]=((b>>0)&3)+PALETTE_START;
- line+=4;
+ uint8_t b = m_videoram[j+i];
+ for (int pix = 0; pix < 4; pix++)
+ {
+ *line = b & 3;
+ b >>= 2;
+ line++;
+ }
}
j += 0x30;
- if (j >= 8160)
+ if (j >= 0x1fe0)
j = 0; //sssnake
}
}
else
{
- bitmap.plot_box(3, 0, 162, 159, PALETTE_START);
+ bitmap.plot_box(3, 0, 162, 159, 0);
}
return 0;
}
uint32_t svision_state::screen_update_tvlink(screen_device &screen, bitmap_rgb32 &bitmap, const rectangle &cliprect)
{
- int x, y, i, j = XPOS/4+YPOS*0x30;
- uint8_t *videoram = m_videoram;
-
- if (BANK & 8)
+ if (BIT(m_reg[BANK], 3))
{
- for (y = 0; y < 160; y++)
+ int j = m_reg[XPOS] / 4 + m_reg[YPOS] * 0x30;
+ for (int y = 0; y < 160; y++)
{
- uint32_t *line = &bitmap.pix32(y, 3 - (XPOS & 3));
- for (x = 3 - (XPOS & 3), i = 0; x < 160 + 3 && x < XSIZE + 3; x += 4, i++)
+ const int start_x = 3 - (m_reg[XPOS] & 3);
+ const int end_x = std::min(163, m_reg[XSIZE] | 3);
+ uint32_t *line = &bitmap.pix32(y, start_x);
+ for (int x = start_x, i = 0; x < end_x; x += 4, i++)
{
- uint8_t b=videoram[j+i];
- line[3]=m_tvlink.palette[(b>>6)&3];
- line[2]=m_tvlink.palette[(b>>4)&3];
- line[1]=m_tvlink.palette[(b>>2)&3];
- line[0]=m_tvlink.palette[(b>>0)&3];
- line+=4;
+ uint8_t b = m_videoram[j + i];
+ for (int pix = 0; pix < 4; pix++)
+ {
+ *line = m_tvlink.palette[b & 3];
+ b >>= 2;
+ line++;
+ }
}
j += 0x30;
- if (j >= 8160)
+ if (j >= 0x1fe0)
j = 0; //sssnake
}
}
else
{
- bitmap.plot_box(3, 0, 162, 159, m_palette->pen(PALETTE_START));
+ bitmap.plot_box(3, 0, 162, 159, m_palette->pen(0));
}
return 0;
}
INTERRUPT_GEN_MEMBER(svision_state::svision_frame_int)
{
- if (BANK & 1)
+ if (BIT(m_reg[BANK], 0))
device.execute().pulse_input_line(INPUT_LINE_NMI, attotime::zero);
m_sound->sound_decrement();
@@ -445,14 +433,14 @@ INTERRUPT_GEN_MEMBER(svision_state::svision_frame_int)
void svision_state::init_svision()
{
m_svision.timer1 = machine().scheduler().timer_alloc(timer_expired_delegate(FUNC(svision_state::svision_timer),this));
- m_dma_finished = m_sound->dma_finished();
+ m_dma_finished = false;
m_pet.on = false;
}
void svision_state::init_svisions()
{
m_svision.timer1 = machine().scheduler().timer_alloc(timer_expired_delegate(FUNC(svision_state::svision_timer),this));
- m_dma_finished = m_sound->dma_finished();
+ m_dma_finished = false;
m_pet.on = true;
m_pet.timer = machine().scheduler().timer_alloc(timer_expired_delegate(FUNC(svision_state::svision_pet_timer),this));
}
@@ -475,28 +463,22 @@ DEVICE_IMAGE_LOAD_MEMBER( svision_state, svision_cart )
void svision_state::machine_start()
{
- int num_banks = 0;
- std::string region_tag;
- m_cart_rom = memregion(region_tag.assign(m_cart->tag()).append(GENERIC_ROM_REGION_TAG).c_str());
- if (m_cart_rom)
- num_banks = m_cart_rom->bytes() / 0x4000;
+ std::string region_tag(m_cart->tag());
+ region_tag.append(GENERIC_ROM_REGION_TAG);
+ m_cart_rom = memregion(region_tag.c_str());
- m_bank1 = membank("bank1");
- m_bank2 = membank("bank2");
- // bank1 is set to the first bank
- // do not crash if no cart
- if (num_banks)
+ if (m_cart_rom)
{
+ int num_banks = m_cart_rom->bytes() / 0x4000;
m_bank1->set_base(m_cart_rom->base());
- // bank2 is set to the last bank
- m_bank2->set_base(m_cart_rom->base() + (num_banks - 1) * 0x4000);
+ m_bank2->set_base(m_cart_rom->base() + (num_banks - 1) * 0x4000); // bank2 is set to the last bank
}
}
void svision_state::machine_reset()
{
m_svision.timer_shot = false;
- *m_dma_finished = false;
+ m_dma_finished = false;
}
@@ -508,49 +490,48 @@ MACHINE_RESET_MEMBER(svision_state,tvlink)
memset(m_reg + 0x800, 0xff, 0x40); // normally done from m_tvlink microcontroller
m_reg[0x82a] = 0xdf;
- m_tvlink.palette[0] = MAKE24_RGB32(svisionp_palette[(PALETTE_START+0)*3+0], svisionp_palette[(PALETTE_START+0)*3+1], svisionp_palette[(PALETTE_START+0)*3+2]);
- m_tvlink.palette[1] = MAKE24_RGB32(svisionp_palette[(PALETTE_START+1)*3+0], svisionp_palette[(PALETTE_START+1)*3+1], svisionp_palette[(PALETTE_START+1)*3+2]);
- m_tvlink.palette[2] = MAKE24_RGB32(svisionp_palette[(PALETTE_START+2)*3+0], svisionp_palette[(PALETTE_START+2)*3+1], svisionp_palette[(PALETTE_START+2)*3+2]);
- m_tvlink.palette[3] = MAKE24_RGB32(svisionp_palette[(PALETTE_START+3)*3+0], svisionp_palette[(PALETTE_START+3)*3+1], svisionp_palette[(PALETTE_START+3)*3+2]);
+ m_tvlink.palette[0] = MAKE24_RGB32(svisionp_palette[ 0], svisionp_palette[ 1], svisionp_palette[ 2]);
+ m_tvlink.palette[1] = MAKE24_RGB32(svisionp_palette[ 3], svisionp_palette[ 4], svisionp_palette[ 5]);
+ m_tvlink.palette[2] = MAKE24_RGB32(svisionp_palette[ 6], svisionp_palette[ 7], svisionp_palette[ 8]);
+ m_tvlink.palette[3] = MAKE24_RGB32(svisionp_palette[ 9], svisionp_palette[10], svisionp_palette[11]);
}
-MACHINE_CONFIG_START(svision_state::svision)
- /* basic machine hardware */
- MCFG_DEVICE_ADD("maincpu", M65C02, 4000000) /* ? stz used! speed? */
- MCFG_DEVICE_PROGRAM_MAP(svision_mem)
- MCFG_DEVICE_VBLANK_INT_DRIVER("screen", svision_state, svision_frame_int)
-
- /* video hardware */
- MCFG_SCREEN_ADD("screen", LCD)
- MCFG_SCREEN_REFRESH_RATE(61)
- MCFG_SCREEN_SIZE(3+160+3, 160)
- MCFG_SCREEN_VISIBLE_AREA(3+0, 3+160-1, 0, 160-1)
- MCFG_SCREEN_UPDATE_DRIVER(svision_state, screen_update_svision)
- MCFG_SCREEN_PALETTE("palette")
-
- MCFG_PALETTE_ADD("palette", ARRAY_LENGTH(svision_palette) * 3)
- MCFG_PALETTE_INIT_OWNER(svision_state, svision )
-
+MACHINE_CONFIG_START(svision_state::svision_base)
MCFG_DEFAULT_LAYOUT(layout_svision)
- /* sound hardware */
SPEAKER(config, "lspeaker").front_left();
SPEAKER(config, "rspeaker").front_right();
- MCFG_DEVICE_ADD("custom", SVISION_SND, 0)
+ MCFG_DEVICE_ADD(m_sound, SVISION_SND, 4000000, m_maincpu, m_bank1)
MCFG_SOUND_ROUTE(0, "lspeaker", 0.50)
MCFG_SOUND_ROUTE(1, "rspeaker", 0.50)
- SVISION_SND_IRQ_CB(svision_state, svision_irq)
+ MCFG_SVISION_SOUND_IRQ_CALLBACK(WRITELINE(*this, svision_state, sound_irq_w));
- /* cartridge */
- MCFG_GENERIC_CARTSLOT_ADD("cartslot", generic_plain_slot, "svision_cart")
+ MCFG_GENERIC_CARTSLOT_ADD(m_cart, generic_plain_slot, "svision_cart")
MCFG_GENERIC_EXTENSIONS("bin,ws,sv")
MCFG_GENERIC_MANDATORY
MCFG_GENERIC_LOAD(svision_state, svision_cart)
- /* Software lists */
MCFG_SOFTWARE_LIST_ADD("cart_list", "svision")
MACHINE_CONFIG_END
+MACHINE_CONFIG_START(svision_state::svision)
+ svision_base(config);
+
+ MCFG_DEVICE_ADD(m_maincpu, M65C02, 4000000)
+ MCFG_DEVICE_PROGRAM_MAP(svision_mem)
+ MCFG_DEVICE_VBLANK_INT_DRIVER(m_screen, svision_state, svision_frame_int)
+
+ MCFG_SCREEN_ADD(m_screen, LCD)
+ MCFG_SCREEN_REFRESH_RATE(61)
+ MCFG_SCREEN_SIZE(3+160+3, 160)
+ MCFG_SCREEN_VISIBLE_AREA(3+0, 3+160-1, 0, 160-1)
+ MCFG_SCREEN_UPDATE_DRIVER(svision_state, screen_update_svision)
+ MCFG_SCREEN_PALETTE(m_palette)
+
+ MCFG_PALETTE_ADD(m_palette, ARRAY_LENGTH(svision_palette) * 3)
+ MCFG_PALETTE_INIT_OWNER(svision_state, svision )
+MACHINE_CONFIG_END
+
MACHINE_CONFIG_START(svision_state::svisions)
svision(config);
MCFG_TIMER_DRIVER_ADD_PERIODIC("pet_timer", svision_state, svision_pet_timer_dev, attotime::from_seconds(8))
@@ -558,54 +539,45 @@ MACHINE_CONFIG_END
MACHINE_CONFIG_START(svision_state::svisionp)
svision(config);
- MCFG_DEVICE_MODIFY("maincpu")
- MCFG_DEVICE_CLOCK(4430000)
- MCFG_SCREEN_MODIFY("screen")
- MCFG_SCREEN_REFRESH_RATE(50)
- MCFG_PALETTE_MODIFY("palette")
- MCFG_PALETTE_INIT_OWNER(svision_state, svisionp)
+
+ m_maincpu->set_clock(4430000);
+ m_screen->set_refresh(HZ_TO_ATTOSECONDS(50));
+ m_palette->set_init(palette_init_delegate(&svision_state::palette_init_svisionp, "svision_state::palette_init_svisionp", this));
MACHINE_CONFIG_END
MACHINE_CONFIG_START(svision_state::svisionn)
svision(config);
- MCFG_DEVICE_MODIFY("maincpu")
- MCFG_DEVICE_CLOCK(3560000/*?*/)
- MCFG_SCREEN_MODIFY("screen")
- MCFG_SCREEN_REFRESH_RATE(60)
- MCFG_PALETTE_MODIFY("palette")
- MCFG_PALETTE_INIT_OWNER(svision_state, svisionn)
+ m_maincpu->set_clock(3560000/*?*/);
+ m_screen->set_refresh(HZ_TO_ATTOSECONDS(60));
+ m_palette->set_init(palette_init_delegate(&svision_state::palette_init_svisionn, "svision_state::palette_init_svisionn", this));
MACHINE_CONFIG_END
MACHINE_CONFIG_START(svision_state::tvlinkp)
svisionp(config);
- MCFG_DEVICE_MODIFY("maincpu")
- MCFG_DEVICE_PROGRAM_MAP(tvlink_mem)
-
- MCFG_MACHINE_RESET_OVERRIDE(svision_state, tvlink)
+ m_maincpu->set_addrmap(AS_PROGRAM, address_map_constructor(&std::remove_pointer_t<decltype(this)>::tvlink_mem, tag(), this));
- MCFG_SCREEN_MODIFY("screen")
- MCFG_SCREEN_NO_PALETTE
- MCFG_SCREEN_UPDATE_DRIVER(svision_state, screen_update_tvlink)
+ m_screen->set_palette(finder_base::DUMMY_TAG);
+ m_screen->set_screen_update(screen_update_delegate_smart(&svision_state::screen_update_tvlink, "svision_state::screen_update_tvlink", nullptr));
+ MCFG_MACHINE_RESET_OVERRIDE(svision_state, tvlink)
MACHINE_CONFIG_END
ROM_START(svision)
ROM_REGION(0x80000, "maincpu", ROMREGION_ERASE00)
ROM_END
-
-#define rom_svisions rom_svision
-#define rom_svisionn rom_svision
-#define rom_svisionp rom_svision
-#define rom_tvlinkp rom_svision
-
/***************************************************************************
Game driver(s)
***************************************************************************/
-// YEAR NAME PARENT COMPAT MACHINE INPUT STATE INIT COMPANY FULLNAME FLAGS
+#define rom_svisions rom_svision
+#define rom_svisionn rom_svision
+#define rom_svisionp rom_svision
+#define rom_tvlinkp rom_svision
+
+// YEAR NAME PARENT COMPAT MACHINE INPUT STATE INIT COMPANY FULLNAME FLAGS
// marketed under a ton of firms and names
CONS(1992, svision, 0, 0, svision, svision, svision_state, init_svision, "Watara", "Super Vision", 0 )
// svdual 2 connected via communication port
diff --git a/src/mame/includes/svision.h b/src/mame/includes/svision.h
index 147dd4cc63e..386ac2ff71d 100644
--- a/src/mame/includes/svision.h
+++ b/src/mame/includes/svision.h
@@ -39,40 +39,30 @@ class svision_state : public driver_device
{
public:
svision_state(const machine_config &mconfig, device_type type, const char *tag)
- : driver_device(mconfig, type, tag),
- m_maincpu(*this, "maincpu"),
- m_sound(*this, "custom"),
- m_cart(*this, "cartslot"),
- m_reg(*this, "reg"),
- m_videoram(*this, "videoram"),
- m_joy(*this, "JOY"),
- m_joy2(*this, "JOY2"),
- m_palette(*this, "palette") { }
-
- int *m_dma_finished;
- svision_t m_svision;
- svision_pet_t m_pet;
- tvlink_t m_tvlink;
+ : driver_device(mconfig, type, tag)
+ , m_maincpu(*this, "maincpu")
+ , m_sound(*this, "custom")
+ , m_cart(*this, "cartslot")
+ , m_reg(*this, "reg")
+ , m_videoram(*this, "videoram")
+ , m_screen(*this, "screen")
+ , m_joy(*this, "JOY")
+ , m_joy2(*this, "JOY2")
+ , m_palette(*this, "palette")
+ , m_bank1(*this, "bank1")
+ , m_bank2(*this, "bank2")
+ { }
+ DECLARE_WRITE_LINE_MEMBER(sound_irq_w);
DECLARE_READ8_MEMBER(svision_r);
DECLARE_WRITE8_MEMBER(svision_w);
DECLARE_READ8_MEMBER(tvlink_r);
DECLARE_WRITE8_MEMBER(tvlink_w);
void init_svisions();
void init_svision();
- virtual void machine_start() override;
- virtual void machine_reset() override;
- DECLARE_PALETTE_INIT(svision);
- DECLARE_PALETTE_INIT(svisionp);
- DECLARE_PALETTE_INIT(svisionn);
- DECLARE_MACHINE_RESET(tvlink);
uint32_t screen_update_svision(screen_device &screen, bitmap_ind16 &bitmap, const rectangle &cliprect);
uint32_t screen_update_tvlink(screen_device &screen, bitmap_rgb32 &bitmap, const rectangle &cliprect);
INTERRUPT_GEN_MEMBER(svision_frame_int);
- TIMER_CALLBACK_MEMBER(svision_pet_timer);
- TIMER_CALLBACK_MEMBER(svision_timer);
- TIMER_DEVICE_CALLBACK_MEMBER(svision_pet_timer_dev);
- void svision_irq();
DECLARE_DEVICE_IMAGE_LOAD_MEMBER(svision_cart);
void svisionp(machine_config &config);
@@ -80,21 +70,53 @@ public:
void tvlinkp(machine_config &config);
void svision(machine_config &config);
void svisionn(machine_config &config);
+ void svision_base(machine_config &config);
+
+protected:
+ virtual void machine_start() override;
+ virtual void machine_reset() override;
+
+ DECLARE_PALETTE_INIT(svision);
+ DECLARE_PALETTE_INIT(svisionp);
+ DECLARE_PALETTE_INIT(svisionn);
+ DECLARE_MACHINE_RESET(tvlink);
+
+ enum
+ {
+ XSIZE = 0x00,
+ XPOS = 0x02,
+ YPOS = 0x03,
+ BANK = 0x26,
+ };
+
+ void check_irq();
+
+ TIMER_CALLBACK_MEMBER(svision_pet_timer);
+ TIMER_CALLBACK_MEMBER(svision_timer);
+ TIMER_DEVICE_CALLBACK_MEMBER(svision_pet_timer_dev);
+
void svision_mem(address_map &map);
void tvlink_mem(address_map &map);
-protected:
+
required_device<cpu_device> m_maincpu;
required_device<svision_sound_device> m_sound;
required_device<generic_slot_device> m_cart;
required_shared_ptr<uint8_t> m_reg;
required_shared_ptr<uint8_t> m_videoram;
+ required_device<screen_device> m_screen;
required_ioport m_joy;
optional_ioport m_joy2;
required_device<palette_device> m_palette;
+ required_memory_bank m_bank1;
+ required_memory_bank m_bank2;
+
memory_region *m_cart_rom;
- memory_bank *m_bank1;
- memory_bank *m_bank2;
+
+ svision_t m_svision;
+ svision_pet_t m_pet;
+ tvlink_t m_tvlink;
+ bool m_dma_finished;
};
#endif // MAME_INCLUDES_SVISION_H