svis_snd cleanups, nw

This commit is contained in:
mooglyguy 2018-06-01 11:41:52 +02:00
parent d96189dfc9
commit 2cdb153103
8 changed files with 222 additions and 250 deletions

View File

@ -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

View File

@ -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

View File

@ -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();
}
}

View File

@ -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) \

View File

@ -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
{

View File

@ -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;

View File

@ -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)
{
int irq = m_svision.timer_shot && (BANK & 2);
irq = irq || (*m_dma_finished && (BANK & 4));
m_dma_finished = true;
check_irq();
}
void svision_state::check_irq()
{
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)
m_maincpu->set_addrmap(AS_PROGRAM, address_map_constructor(&std::remove_pointer_t<decltype(this)>::tvlink_mem, tag(), this));
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)
MCFG_SCREEN_MODIFY("screen")
MCFG_SCREEN_NO_PALETTE
MCFG_SCREEN_UPDATE_DRIVER(svision_state, screen_update_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

View File

@ -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