From 2cdb153103fa94d13a53dd747985ef56ec723e7a Mon Sep 17 00:00:00 2001 From: mooglyguy Date: Fri, 1 Jun 2018 11:41:52 +0200 Subject: svis_snd cleanups, nw --- src/emu/diexec.cpp | 14 +-- src/emu/diexec.h | 6 +- src/emu/screen.cpp | 33 ++--- src/emu/screen.h | 7 +- src/mame/audio/svis_snd.cpp | 24 ++-- src/mame/audio/svis_snd.h | 22 ++-- src/mame/drivers/svision.cpp | 290 +++++++++++++++++++------------------------ src/mame/includes/svision.h | 76 ++++++++---- 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(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 void set_vblank_int(Object &&cb, const char *tag, int rate = 0) + template void set_vblank_int(Object &&cb, T &&tag, int rate = 0) { m_vblank_interrupt = std::forward(cb); - m_vblank_interrupt_screen = tag; + m_vblank_interrupt_screen.set_tag(std::forward(tag)); } template 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 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 devcb_base &set_screen_vblank(Object &&object) { return m_screen_vblank.set_callback(std::forward(object)); } - void set_palette(const char *tag) { m_palette_tag = tag; } + template void set_palette(T &&tag) { m_palette.set_tag(std::forward(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 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_iterator; #define MCFG_SCREEN_PALETTE(_palette_tag) \ downcast(*device).set_palette(_palette_tag); #define MCFG_SCREEN_NO_PALETTE \ - downcast(*device).set_palette(nullptr); + downcast(*device).set_palette(finder_base::DUMMY_TAG); #define MCFG_SCREEN_VIDEO_ATTRIBUTES(_flags) \ downcast(*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(*device).set_irq_callback(svision_sound_device::irq_delegate(&_class::_method, #_class "::" #_method, this)); +#define MCFG_SVISION_SOUND_IRQ_CALLBACK(_devcb) \ + devcb = &downcast(*device).set_irq_cb(DEVCB_##_devcb); // ======================> svision_sound_device class svision_sound_device : public device_t, public device_sound_interface { public: - typedef device_delegate irq_delegate; + template + svision_sound_device(const machine_config &mconfig, const char *tag, device_t *owner, uint32_t clock, T &&cpu_tag, U &®ion_tag) + : svision_sound_device(mconfig, tag, owner, clock) + { + m_maincpu.set_tag(std::forward(cpu_tag)); + m_cartrom.set_tag(std::forward(region_tag)); + } svision_sound_device(const machine_config &mconfig, const char *tag, device_t *owner, uint32_t clock); // configuration - template void set_irq_callback(Object &&callback) { m_irq_cb = std::forward(callback); } + template devcb_base &set_irq_cb(Object &&cb) { return m_irq_cb.set_callback(std::forward(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 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>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::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 m_maincpu; required_device m_sound; required_device m_cart; required_shared_ptr m_reg; required_shared_ptr m_videoram; + required_device m_screen; required_ioport m_joy; optional_ioport m_joy2; required_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 -- cgit v1.2.3