summaryrefslogtreecommitdiffstatshomepage
path: root/src/mame/konami/twin16.cpp
diff options
context:
space:
mode:
Diffstat (limited to 'src/mame/konami/twin16.cpp')
-rw-r--r--src/mame/konami/twin16.cpp448
1 files changed, 321 insertions, 127 deletions
diff --git a/src/mame/konami/twin16.cpp b/src/mame/konami/twin16.cpp
index a4a37881777..3a401eaa0e1 100644
--- a/src/mame/konami/twin16.cpp
+++ b/src/mame/konami/twin16.cpp
@@ -14,11 +14,11 @@ Sounds are generated by a Z80, a Yamaha 2151 and 3012, a Konami custom IC and a
Dark Adventure / Devil World / Majuu no Ohkoku
Vulcan Venture / Gradius II
- Cuebrick
+ Cuebrick (Japan)
MIA (Japan)
Final Round / Hard Puncher (Japan)
-68000 Memory Map for Konami Twin System
+68000 Memory Map for Konami Twin16 System
CPUA CPUB
0x000000..0x03ffff ROM 0x000000..0x03ffff
@@ -35,39 +35,203 @@ Sounds are generated by a Z80, a Yamaha 2151 and 3012, a Konami custom IC and a
0x100000..0x103fff FIXRAM (text layer)
0x120000..0x123fff VIDRAM (tilemaps) 0x480000..0x483fff (shared)
0x140000..0x143fff OBJRAM (sprites) 0x400000..0x403fff (shared)
- ZIP RAM (tiles) 0x500000..0x53ffff
+ ZIP RAM (tile gfx) 0x500000..0x53ffff
gfx ROM (banked) 0x600000..0x77ffff
sprite gfx RAM 0x780000..0x79ffff
Known Issues:
- repeated uPD7759C samples in fround, disconnecting reset helps but doesn't fix it
-- see video/twin16.c for graphics related issues
+- see konami/twin16_v.cpp for graphics related issues
*/
#include "emu.h"
-#include "twin16.h"
#include "konamipt.h"
+#include "twin16_v.h"
#include "cpu/m68000/m68000.h"
#include "cpu/z80/z80.h"
#include "machine/gen_latch.h"
#include "machine/nvram.h"
#include "machine/watchdog.h"
+#include "sound/k007232.h"
+#include "sound/upd7759.h"
#include "sound/ymopm.h"
+
+#include "emupal.h"
+#include "screen.h"
#include "speaker.h"
+#include "tilemap.h"
+
+namespace {
+
+class twin16_state : public driver_device
+{
+public:
+ twin16_state(const machine_config &mconfig, device_type type, const char *tag) :
+ driver_device(mconfig, type, tag),
+ m_maincpu(*this, "maincpu"),
+ m_subcpu(*this, "sub"),
+ m_audiocpu(*this, "audiocpu"),
+ m_video(*this, "video"),
+ m_k007232(*this, "k007232"),
+ m_upd7759(*this, "upd"),
+ m_screen(*this, "screen"),
+ m_palette(*this, "palette"),
+ m_gfxrombank(*this, "gfxrombank"),
+ m_zipram(*this, "zipram"),
+ m_sprite_gfx_ram(*this, "sprite_gfx_ram"),
+ m_gfxrom(*this, "gfxrom")
+ { }
+
+ void devilw(machine_config &config) ATTR_COLD;
+ void miaj(machine_config &config) ATTR_COLD;
+ void twin16(machine_config &config) ATTR_COLD;
+
+protected:
+ virtual void machine_start() override ATTR_COLD;
+ virtual void machine_reset() override ATTR_COLD;
+ virtual void video_start() override ATTR_COLD;
+
+ required_device<cpu_device> m_maincpu;
+ optional_device<cpu_device> m_subcpu;
+ required_device<cpu_device> m_audiocpu;
+ required_device<konami_twin16_video_device> m_video;
+ required_device<k007232_device> m_k007232;
+ required_device<upd7759_device> m_upd7759;
+ required_device<screen_device> m_screen;
+ required_device<palette_device> m_palette;
+ optional_memory_bank m_gfxrombank;
+ optional_shared_ptr<uint16_t> m_zipram;
+ optional_shared_ptr<uint16_t> m_sprite_gfx_ram;
+ required_region_ptr<uint16_t> m_gfxrom;
+
+ uint16_t m_cpua_register = 0;
+ uint16_t m_cpub_register = 0;
+
+ void cpua_register_w(offs_t offset, uint16_t data, uint16_t mem_mask = ~0);
+ void cpub_register_w(offs_t offset, uint16_t data, uint16_t mem_mask = ~0);
+
+ void zipram_w(offs_t offset, uint16_t data, uint16_t mem_mask = ~0);
+
+ uint8_t upd_busy_r();
+ void upd_reset_w(uint8_t data);
+ void upd_start_w(uint8_t data);
+
+ void virq_callback(int state);
+ uint16_t sprite_callback(int addr);
+
+ void volume_callback(uint8_t data);
+
+ void main_map(address_map &map) ATTR_COLD;
+ void sound_map(address_map &map) ATTR_COLD;
+ void sub_map(address_map &map) ATTR_COLD;
+};
+
+class fround_state : public twin16_state
+{
+public:
+ fround_state(const machine_config &mconfig, device_type type, const char *tag) :
+ twin16_state(mconfig, type, tag)
+ { }
+
+ void fround(machine_config &config);
+
+protected:
+ virtual void machine_start() override ATTR_COLD;
+
+private:
+ uint8_t m_gfx_bank[4] = { };
+
+ void fround_cpu_register_w(offs_t offset, uint16_t data, uint16_t mem_mask = ~0);
+ void gfx_bank_w(offs_t offset, uint16_t data, uint16_t mem_mask = ~0);
+
+ uint16_t fround_sprite_callback(int addr);
+ uint32_t tile_callback(uint16_t data);
+
+ void fround_map(address_map &map) ATTR_COLD;
+};
+
+class cuebrickj_state : public twin16_state
+{
+public:
+ cuebrickj_state(const machine_config &mconfig, device_type type, const char *tag) :
+ twin16_state(mconfig, type, tag),
+ m_nvram_bank(*this, "nvram_bank")
+ { }
+
+ void cuebrickj(machine_config &config);
+
+protected:
+ virtual void machine_start() override ATTR_COLD;
+
+private:
+ required_memory_bank m_nvram_bank;
+
+ uint16_t m_nvram[0x400 * 0x20 / 2]{};
+
+ void nvram_bank_w(uint8_t data);
+ void cuebrickj_main_map(address_map &map) ATTR_COLD;
+};
-int twin16_state::spriteram_process_enable()
+
+void twin16_state::virq_callback(int state)
{
- return (m_CPUA_register & 0x40) == 0;
+ if (state)
+ {
+ if (BIT(m_cpua_register, 5))
+ m_maincpu->set_input_line(5, HOLD_LINE);
+ if (m_subcpu.found() && BIT(m_cpub_register, 1))
+ m_subcpu->set_input_line(5, HOLD_LINE);
+ }
}
+
+uint16_t twin16_state::sprite_callback(int addr)
+{
+ switch ((addr >> 18) & 0x3)
+ {
+ case 0:
+ case 1:
+ return m_gfxrom[addr & 0x7ffff];
+ case 2:
+ return m_gfxrom[0x80000 + (addr & 0x3ffff) + (BIT(addr, 20) ? 0x40000 : 0)];
+ case 3:
+ return m_sprite_gfx_ram[addr & 0xffff];
+ }
+ return 0;
+}
+
+
+uint16_t fround_state::fround_sprite_callback(int addr)
+{
+ return m_gfxrom[addr & 0x7ffff];
+}
+
+
+uint32_t fround_state::tile_callback(uint16_t data)
+{
+ /* fedcba9876543210
+ xxx------------- color; high bit is also priority over sprites
+ ---xx----------- tile bank
+ -----xxxxxxxxxxx tile number
+ */
+ const uint8_t bank = (data >> 11) & 3;
+ return (m_gfx_bank[bank] << 11) | (data & 0x7ff);
+}
+
+void twin16_state::video_start()
+{
+ m_palette->set_shadow_factor(0.4); // screenshots estimate
+}
+
+
/******************************************************************************************/
/* Read/Write Handlers */
-void twin16_state::CPUA_register_w(offs_t offset, uint16_t data, uint16_t mem_mask)
+void twin16_state::cpua_register_w(offs_t offset, uint16_t data, uint16_t mem_mask)
{
/*
7 6 5 4 3 2 1 0
@@ -77,30 +241,28 @@ void twin16_state::CPUA_register_w(offs_t offset, uint16_t data, uint16_t mem_ma
X 0->1 trigger IRQ on sound CPU
x x x coin counters
*/
- int old = m_CPUA_register;
- COMBINE_DATA(&m_CPUA_register);
+ const int old = m_cpua_register;
+ COMBINE_DATA(&m_cpua_register);
- if (m_CPUA_register != old)
+ if (m_cpua_register != old)
{
- int rising_edge = ~old & m_CPUA_register;
- int falling_edge = old & ~m_CPUA_register;
+ const int rising_edge = ~old & m_cpua_register;
- if (rising_edge & 0x08)
+ if (BIT(rising_edge, 3))
m_audiocpu->set_input_line_and_vector(0, HOLD_LINE, 0xff); // Z80
- if (falling_edge & 0x40)
- spriteram_process();
+ m_video->sprite_process_enable_w(BIT(~m_cpua_register, 6));
- if (rising_edge & 0x10)
+ if (BIT(rising_edge, 4))
m_subcpu->set_input_line(M68K_IRQ_6, HOLD_LINE);
- machine().bookkeeping().coin_counter_w(0, m_CPUA_register & 0x01);
- machine().bookkeeping().coin_counter_w(1, m_CPUA_register & 0x02);
- machine().bookkeeping().coin_counter_w(2, m_CPUA_register & 0x04);
+ machine().bookkeeping().coin_counter_w(0, BIT(m_cpua_register, 0));
+ machine().bookkeeping().coin_counter_w(1, BIT(m_cpua_register, 1));
+ machine().bookkeeping().coin_counter_w(2, BIT(m_cpua_register, 2));
}
}
-void twin16_state::CPUB_register_w(offs_t offset, uint16_t data, uint16_t mem_mask)
+void twin16_state::cpub_register_w(offs_t offset, uint16_t data, uint16_t mem_mask)
{
/*
7 6 5 4 3 2 1 0
@@ -108,20 +270,20 @@ void twin16_state::CPUB_register_w(offs_t offset, uint16_t data, uint16_t mem_ma
X IRQ5 enable
X 0->1 trigger IRQ6 on CPUA
*/
- int old = m_CPUB_register;
- COMBINE_DATA(&m_CPUB_register);
+ const int old = m_cpub_register;
+ COMBINE_DATA(&m_cpub_register);
- if (m_CPUB_register != old)
+ if (m_cpub_register != old)
{
- int rising_edge = ~old & m_CPUB_register;
- if (rising_edge & 0x01)
+ const int rising_edge = ~old & m_cpub_register;
+ if (BIT(rising_edge, 0))
m_maincpu->set_input_line(M68K_IRQ_6, HOLD_LINE);
- m_gfxrombank->set_entry(BIT(m_CPUB_register, 2));
+ m_gfxrombank->set_entry(BIT(m_cpub_register, 2));
}
}
-void fround_state::fround_CPU_register_w(offs_t offset, uint16_t data, uint16_t mem_mask)
+void fround_state::fround_cpu_register_w(offs_t offset, uint16_t data, uint16_t mem_mask)
{
/*
7 6 5 4 3 2 1 0
@@ -129,19 +291,58 @@ void fround_state::fround_CPU_register_w(offs_t offset, uint16_t data, uint16_t
X 0->1 trigger IRQ on sound CPU
x x coin counters
*/
- uint16_t old = m_CPUA_register;
- COMBINE_DATA(&m_CPUA_register);
+ const uint16_t old = m_cpua_register;
+ COMBINE_DATA(&m_cpua_register);
- if (m_CPUA_register != old)
+ if (m_cpua_register != old)
{
- if ((old & 0x08) == 0 && (m_CPUA_register & 0x08))
+ if (BIT(~old, 3) && BIT(m_cpua_register, 3))
m_audiocpu->set_input_line_and_vector(0, HOLD_LINE, 0xff); // Z80
- machine().bookkeeping().coin_counter_w(0, m_CPUA_register & 0x01);
- machine().bookkeeping().coin_counter_w(1, m_CPUA_register & 0x02);
+ m_video->sprite_process_enable_w(BIT(~m_cpua_register, 6));
+
+ machine().bookkeeping().coin_counter_w(0, BIT(m_cpua_register, 0));
+ machine().bookkeeping().coin_counter_w(1, BIT(m_cpua_register, 1));
}
}
+void cuebrickj_state::nvram_bank_w(uint8_t data)
+{
+ m_nvram_bank->set_entry(data);
+}
+
+void twin16_state::zipram_w(offs_t offset, uint16_t data, uint16_t mem_mask)
+{
+ const uint16_t old = m_zipram[offset];
+ COMBINE_DATA(&m_zipram[offset]);
+ if (m_zipram[offset] != old)
+ m_video->gfx(1)->mark_dirty(offset / 16);
+}
+
+void fround_state::gfx_bank_w(offs_t offset, uint16_t data, uint16_t mem_mask)
+{
+ int changed = 0;
+
+ if (ACCESSING_BITS_0_7)
+ {
+ const int oldbank0 = m_gfx_bank[0];
+ const int oldbank1 = m_gfx_bank[1];
+ m_gfx_bank[0] = (data >> 0) & 0xf;
+ m_gfx_bank[1] = (data >> 4) & 0xf;
+ changed |= (oldbank0 ^ m_gfx_bank[0]) | (oldbank1 ^ m_gfx_bank[1]);
+ }
+ if (ACCESSING_BITS_8_15)
+ {
+ const int oldbank2 = m_gfx_bank[2];
+ const int oldbank3 = m_gfx_bank[3];
+ m_gfx_bank[2] = (data >> 8) & 0xf;
+ m_gfx_bank[3] = (data >> 12) & 0xf;
+ changed |= (oldbank2 ^ m_gfx_bank[2]) | (oldbank3 ^ m_gfx_bank[3]);
+ }
+ if (changed)
+ m_video->mark_scroll_dirty();
+}
+
uint8_t twin16_state::upd_busy_r()
{
return m_upd7759->busy_r();
@@ -180,7 +381,7 @@ void twin16_state::main_map(address_map &map)
map(0x060000, 0x063fff).ram();
map(0x080000, 0x080fff).rw(m_palette, FUNC(palette_device::read8), FUNC(palette_device::write8)).umask16(0x00ff).share("palette");
map(0x081000, 0x081fff).nopw();
- map(0x0a0000, 0x0a0001).portr("SYSTEM").w(FUNC(twin16_state::CPUA_register_w));
+ map(0x0a0000, 0x0a0001).portr("SYSTEM").w(FUNC(twin16_state::cpua_register_w));
map(0x0a0002, 0x0a0003).portr("P1");
map(0x0a0004, 0x0a0005).portr("P2");
map(0x0a0006, 0x0a0007).portr("P3");
@@ -188,19 +389,19 @@ void twin16_state::main_map(address_map &map)
map(0x0a0010, 0x0a0011).portr("DSW2").w("watchdog", FUNC(watchdog_timer_device::reset16_w));
map(0x0a0012, 0x0a0013).portr("DSW1");
map(0x0a0018, 0x0a0019).portr("DSW3");
- map(0x0c0000, 0x0c000f).w(FUNC(twin16_state::video_register_w));
- map(0x0c000e, 0x0c000f).r(FUNC(twin16_state::sprite_status_r));
- map(0x100000, 0x103fff).ram().w(FUNC(twin16_state::fixram_w)).share("fixram");
+ map(0x0c0000, 0x0c000f).w(m_video, FUNC(konami_twin16_video_device::video_register_w));
+ map(0x0c000e, 0x0c000f).r(m_video, FUNC(konami_twin16_video_device::sprite_status_r));
+ map(0x100000, 0x103fff).rw(m_video, FUNC(konami_twin16_video_device::fixram_r), FUNC(konami_twin16_video_device::fixram_w));
// map(0x104000, 0x105fff).noprw(); // miaj
- map(0x120000, 0x121fff).ram().w(FUNC(twin16_state::videoram0_w)).share("videoram.0");
- map(0x122000, 0x123fff).ram().w(FUNC(twin16_state::videoram1_w)).share("videoram.1");
- map(0x140000, 0x143fff).ram().share("spriteram");
+ map(0x120000, 0x121fff).rw(m_video, FUNC(konami_twin16_video_device::videoram_r<0>), FUNC(konami_twin16_video_device::videoram_w<0>));
+ map(0x122000, 0x123fff).rw(m_video, FUNC(konami_twin16_video_device::videoram_r<1>), FUNC(konami_twin16_video_device::videoram_w<1>));
+ map(0x140000, 0x143fff).rw(m_video, FUNC(konami_twin16_video_device::spriteram_r), FUNC(konami_twin16_video_device::spriteram_w));
}
void cuebrickj_state::cuebrickj_main_map(address_map &map)
{
main_map(map);
- map(0x0b0000, 0x0b03ff).bankrw("nvrambank");
+ map(0x0b0000, 0x0b03ff).bankrw(m_nvram_bank);
map(0x0b0400, 0x0b0400).w(FUNC(cuebrickj_state::nvram_bank_w));
}
@@ -211,14 +412,14 @@ void twin16_state::sub_map(address_map &map)
// map(0x044000, 0x04ffff).noprw(); // miaj
map(0x060000, 0x063fff).ram();
map(0x080000, 0x09ffff).rom().region("data", 0);
- map(0x0a0000, 0x0a0001).w(FUNC(twin16_state::CPUB_register_w));
- map(0x400000, 0x403fff).ram().share("spriteram");
- map(0x480000, 0x481fff).ram().w(FUNC(twin16_state::videoram0_w)).share("videoram.0");
- map(0x482000, 0x483fff).ram().w(FUNC(twin16_state::videoram1_w)).share("videoram.1");
- map(0x500000, 0x53ffff).ram().w(FUNC(twin16_state::zipram_w)).share("zipram");
+ map(0x0a0000, 0x0a0001).w(FUNC(twin16_state::cpub_register_w));
+ map(0x400000, 0x403fff).rw(m_video, FUNC(konami_twin16_video_device::spriteram_r), FUNC(konami_twin16_video_device::spriteram_w));
+ map(0x480000, 0x481fff).rw(m_video, FUNC(konami_twin16_video_device::videoram_r<0>), FUNC(konami_twin16_video_device::videoram_w<0>));
+ map(0x482000, 0x483fff).rw(m_video, FUNC(konami_twin16_video_device::videoram_r<1>), FUNC(konami_twin16_video_device::videoram_w<1>));
+ map(0x500000, 0x53ffff).ram().w(FUNC(twin16_state::zipram_w)).share(m_zipram);
map(0x600000, 0x6fffff).rom().region("gfxrom", 0);
- map(0x700000, 0x77ffff).bankr("gfxrombank");
- map(0x780000, 0x79ffff).ram().share("sprite_gfx_ram");
+ map(0x700000, 0x77ffff).bankr(m_gfxrombank);
+ map(0x780000, 0x79ffff).ram().share(m_sprite_gfx_ram);
}
void fround_state::fround_map(address_map &map)
@@ -227,20 +428,20 @@ void fround_state::fround_map(address_map &map)
map(0x040000, 0x043fff).ram().share("comram");
map(0x060000, 0x063fff).ram();
map(0x080000, 0x080fff).rw(m_palette, FUNC(palette_device::read8), FUNC(palette_device::write8)).umask16(0x00ff).share("palette");
- map(0x0a0000, 0x0a0001).portr("SYSTEM").w(FUNC(fround_state::fround_CPU_register_w));
+ map(0x0a0000, 0x0a0001).portr("SYSTEM").w(FUNC(fround_state::fround_cpu_register_w));
map(0x0a0002, 0x0a0003).portr("P1");
map(0x0a0004, 0x0a0005).portr("P2");
map(0x0a0009, 0x0a0009).w("soundlatch", FUNC(generic_latch_8_device::write));
map(0x0a0010, 0x0a0011).portr("DSW2").w("watchdog", FUNC(watchdog_timer_device::reset16_w));
map(0x0a0012, 0x0a0013).portr("DSW1");
map(0x0a0018, 0x0a0019).portr("DSW3");
- map(0x0c0000, 0x0c000f).w(FUNC(fround_state::video_register_w));
- map(0x0c000e, 0x0c000f).r(FUNC(fround_state::sprite_status_r));
+ map(0x0c0000, 0x0c000f).w(m_video, FUNC(konami_twin16_video_device::video_register_w));
+ map(0x0c000e, 0x0c000f).r(m_video, FUNC(konami_twin16_video_device::sprite_status_r));
map(0x0e0000, 0x0e0001).w(FUNC(fround_state::gfx_bank_w));
- map(0x100000, 0x103fff).ram().w(FUNC(fround_state::fixram_w)).share("fixram");
- map(0x120000, 0x121fff).ram().w(FUNC(fround_state::videoram0_w)).share("videoram.0");
- map(0x122000, 0x123fff).ram().w(FUNC(fround_state::videoram1_w)).share("videoram.1");
- map(0x140000, 0x143fff).ram().share("spriteram");
+ map(0x100000, 0x103fff).rw(m_video, FUNC(konami_twin16_video_device::fixram_r), FUNC(konami_twin16_video_device::fixram_w));
+ map(0x120000, 0x121fff).rw(m_video, FUNC(konami_twin16_video_device::videoram_r<0>), FUNC(konami_twin16_video_device::videoram_w<0>));
+ map(0x122000, 0x123fff).rw(m_video, FUNC(konami_twin16_video_device::videoram_r<1>), FUNC(konami_twin16_video_device::videoram_w<1>));
+ map(0x140000, 0x143fff).rw(m_video, FUNC(konami_twin16_video_device::spriteram_r), FUNC(konami_twin16_video_device::spriteram_w));
map(0x500000, 0x5fffff).rom().region("tiles", 0);
map(0x600000, 0x6fffff).rom().region("gfxrom", 0);
}
@@ -623,16 +824,16 @@ GFXDECODE_END
void twin16_state::volume_callback(uint8_t data)
{
- m_k007232->set_volume(0,(data >> 4) * 0x11,0);
- m_k007232->set_volume(1,0,(data & 0x0f) * 0x11);
+ m_k007232->set_volume(0, (data >> 4) * 0x11, 0);
+ m_k007232->set_volume(1, 0, (data & 0x0f) * 0x11);
}
/* Machine Drivers */
void twin16_state::machine_reset()
{
- m_CPUA_register = 0;
- m_CPUB_register = 0;
+ m_cpua_register = 0;
+ m_cpub_register = 0;
m_upd7759->reset_w(0);
m_upd7759->start_w(1);
@@ -640,9 +841,32 @@ void twin16_state::machine_reset()
void twin16_state::machine_start()
{
+ if (m_gfxrombank.found())
+ {
+ m_gfxrombank->configure_entries(0, 2, memregion("gfxrom")->base() + 0x100000, 0x80000);
+ m_gfxrombank->set_entry(0);
+ }
+
/* register for savestates */
- save_item(NAME(m_CPUA_register));
- save_item(NAME(m_CPUB_register));
+ save_item(NAME(m_cpua_register));
+ save_item(NAME(m_cpub_register));
+}
+
+void fround_state::machine_start()
+{
+ twin16_state::machine_start();
+ save_item(NAME(m_gfx_bank));
+}
+
+void cuebrickj_state::machine_start()
+{
+ twin16_state::machine_start();
+
+ m_nvram_bank->configure_entries(0, 0x20, m_nvram, 0x400);
+
+ subdevice<nvram_device>("nvram")->set_base(m_nvram, sizeof(m_nvram));
+
+ save_item(NAME(m_nvram));
}
void twin16_state::twin16(machine_config &config)
@@ -662,16 +886,17 @@ void twin16_state::twin16(machine_config &config)
WATCHDOG_TIMER(config, "watchdog");
// video hardware
- BUFFERED_SPRITERAM16(config, m_spriteram);
+ KONAMI_TWIN16_VIDEO(config, m_video, XTAL(18'432'000), m_palette, gfx_twin16);
+ m_video->set_screen(m_screen);
+ m_video->virq_callback().set(FUNC(twin16_state::virq_callback));
+ m_video->set_sprite_callback(FUNC(twin16_state::sprite_callback));
SCREEN(config, m_screen, SCREEN_TYPE_RASTER);
m_screen->set_raw(XTAL(18'432'000)/3, 384, 0, 40*8, 264, 2*8, 30*8);
- m_screen->set_screen_update(FUNC(twin16_state::screen_update_twin16));
- m_screen->screen_vblank().set(FUNC(twin16_state::screen_vblank_twin16));
+ m_screen->set_screen_update(m_video, FUNC(konami_twin16_video_device::screen_update));
+ m_screen->screen_vblank().set(m_video, FUNC(konami_twin16_video_device::screen_vblank));
m_screen->set_palette(m_palette);
- GFXDECODE(config, m_gfxdecode, m_palette, gfx_twin16);
-
PALETTE(config, m_palette).set_format(palette_device::xBGR_555, 1024);
m_palette->set_membits(8);
m_palette->enable_shadows();
@@ -685,10 +910,8 @@ void twin16_state::twin16(machine_config &config)
K007232(config, m_k007232, XTAL(3'579'545));
m_k007232->port_write().set(FUNC(twin16_state::volume_callback));
- m_k007232->add_route(0, "speaker", 0.12, 0); // estimated with gradius2 OST
- m_k007232->add_route(0, "speaker", 0.12, 1);
- m_k007232->add_route(1, "speaker", 0.12, 0);
- m_k007232->add_route(1, "speaker", 0.12, 1);
+ m_k007232->add_route(ALL_OUTPUTS, "speaker", 0.12, 0); // estimated with gradius2 OST
+ m_k007232->add_route(ALL_OUTPUTS, "speaker", 0.12, 1);
UPD7759(config, m_upd7759);
m_upd7759->add_route(ALL_OUTPUTS, "speaker", 0.20, 0);
@@ -715,16 +938,18 @@ void fround_state::fround(machine_config &config)
WATCHDOG_TIMER(config, "watchdog");
/* video hardware */
- BUFFERED_SPRITERAM16(config, m_spriteram);
+ KONAMI_TWIN16_VIDEO(config, m_video, XTAL(18'432'000), m_palette, gfx_fround);
+ m_video->set_screen(m_screen);
+ m_video->virq_callback().set(FUNC(fround_state::virq_callback));
+ m_video->set_sprite_callback(FUNC(fround_state::fround_sprite_callback));
+ m_video->set_tile_callback(FUNC(fround_state::tile_callback));
SCREEN(config, m_screen, SCREEN_TYPE_RASTER);
m_screen->set_raw(XTAL(18'432'000)/3, 384, 0, 40*8, 264, 2*8, 30*8);
- m_screen->set_screen_update(FUNC(twin16_state::screen_update_twin16));
- m_screen->screen_vblank().set(FUNC(twin16_state::screen_vblank_twin16));
+ m_screen->set_screen_update(m_video, FUNC(konami_twin16_video_device::screen_update));
+ m_screen->screen_vblank().set(m_video, FUNC(konami_twin16_video_device::screen_vblank));
m_screen->set_palette(m_palette);
- GFXDECODE(config, m_gfxdecode, m_palette, gfx_fround);
-
PALETTE(config, m_palette).set_format(palette_device::xBGR_555, 1024);
m_palette->set_membits(8);
m_palette->enable_shadows();
@@ -737,11 +962,9 @@ void fround_state::fround(machine_config &config)
YM2151(config, "ymsnd", XTAL(3'579'545)).add_route(0, "speaker", 1.0, 0).add_route(1, "speaker", 1.0, 1);
K007232(config, m_k007232, XTAL(3'579'545));
- m_k007232->port_write().set(FUNC(twin16_state::volume_callback));
- m_k007232->add_route(0, "speaker", 0.12, 0);
- m_k007232->add_route(0, "speaker", 0.12, 1);
- m_k007232->add_route(1, "speaker", 0.12, 0);
- m_k007232->add_route(1, "speaker", 0.12, 1);
+ m_k007232->port_write().set(FUNC(fround_state::volume_callback));
+ m_k007232->add_route(ALL_OUTPUTS, "speaker", 0.12, 0);
+ m_k007232->add_route(ALL_OUTPUTS, "speaker", 0.12, 1);
UPD7759(config, m_upd7759);
m_upd7759->add_route(ALL_OUTPUTS, "speaker", 0.20, 0);
@@ -756,9 +979,8 @@ void twin16_state::miaj(machine_config &config)
void cuebrickj_state::cuebrickj(machine_config &config)
{
- twin16(config);
+ miaj(config);
m_maincpu->set_addrmap(AS_PROGRAM, &cuebrickj_state::cuebrickj_main_map);
- m_screen->set_raw(XTAL(18'432'000)/3, 384, 1*8, 39*8, 264, 2*8, 30*8);
NVRAM(config, "nvram", nvram_device::DEFAULT_ALL_0);
}
@@ -1233,54 +1455,26 @@ ROM_START( cuebrickj )
// unpopulated
ROM_END
-/* Driver Initialization */
-
-void twin16_state::init_twin16()
-{
- m_is_fround = false;
- m_gfxrombank->configure_entries(0, 2, memregion("gfxrom")->base() + 0x100000, 0x80000);
- m_gfxrombank->set_entry(0);
-}
-
-void fround_state::init_fround()
-{
- m_is_fround = true;
-}
-
-void cuebrickj_state::nvram_bank_w(uint8_t data)
-{
- membank("nvrambank")->set_entry(data);
-}
-
-void cuebrickj_state::init_cuebrickj()
-{
- init_twin16();
-
- membank("nvrambank")->configure_entries(0, 0x20, m_nvram, 0x400);
-
- subdevice<nvram_device>("nvram")->set_base(m_nvram, sizeof(m_nvram));
-
- save_item(NAME(m_nvram));
-}
+} // anonymous namespace
/* Game Drivers */
-// YEAR, NAME, PARENT, MACHINE, INPUT, STATE, INIT, MONITOR,COMPANY, FULLNAME,FLAGS
-GAME( 1987, devilw, 0, devilw, devilw, twin16_state, init_twin16, ROT0, "Konami", "Devil World", MACHINE_SUPPORTS_SAVE )
-GAME( 1987, majuu, devilw, devilw, devilw, twin16_state, init_twin16, ROT0, "Konami", "Majuu no Ohkoku", MACHINE_SUPPORTS_SAVE )
-GAME( 1987, darkadv, devilw, devilw, darkadv, twin16_state, init_twin16, ROT0, "Konami", "Dark Adventure", MACHINE_SUPPORTS_SAVE )
+// YEAR, NAME, PARENT, MACHINE, INPUT, STATE, INIT, MONITOR,COMPANY, FULLNAME, FLAGS
+GAME( 1987, devilw, 0, devilw, devilw, twin16_state, empty_init, ROT0, "Konami", "Devil World", MACHINE_SUPPORTS_SAVE )
+GAME( 1987, majuu, devilw, devilw, devilw, twin16_state, empty_init, ROT0, "Konami", "Majuu no Ohkoku (Japan)", MACHINE_SUPPORTS_SAVE )
+GAME( 1987, darkadv, devilw, devilw, darkadv, twin16_state, empty_init, ROT0, "Konami", "Dark Adventure", MACHINE_SUPPORTS_SAVE )
-GAME( 1988, vulcan, 0, twin16, vulcan, twin16_state, init_twin16, ROT0, "Konami", "Vulcan Venture (new)", MACHINE_SUPPORTS_SAVE )
-GAME( 1988, vulcana, vulcan, twin16, vulcan, twin16_state, init_twin16, ROT0, "Konami", "Vulcan Venture (old)", MACHINE_SUPPORTS_SAVE )
-GAME( 1988, vulcanb, vulcan, twin16, vulcan, twin16_state, init_twin16, ROT0, "Konami", "Vulcan Venture (older)", MACHINE_SUPPORTS_SAVE )
-GAME( 1988, gradius2, vulcan, twin16, gradius2, twin16_state, init_twin16, ROT0, "Konami", "Gradius II: GOFER no Yabou (Japan, new)", MACHINE_SUPPORTS_SAVE )
-GAME( 1988, gradius2a, vulcan, twin16, vulcan, twin16_state, init_twin16, ROT0, "Konami", "Gradius II: GOFER no Yabou (Japan, old)", MACHINE_SUPPORTS_SAVE )
-GAME( 1988, gradius2b, vulcan, twin16, vulcan, twin16_state, init_twin16, ROT0, "Konami", "Gradius II: GOFER no Yabou (Japan, older)", MACHINE_SUPPORTS_SAVE )
+GAME( 1988, vulcan, 0, twin16, vulcan, twin16_state, empty_init, ROT0, "Konami", "Vulcan Venture (new)", MACHINE_SUPPORTS_SAVE )
+GAME( 1988, vulcana, vulcan, twin16, vulcan, twin16_state, empty_init, ROT0, "Konami", "Vulcan Venture (old)", MACHINE_SUPPORTS_SAVE )
+GAME( 1988, vulcanb, vulcan, twin16, vulcan, twin16_state, empty_init, ROT0, "Konami", "Vulcan Venture (older)", MACHINE_SUPPORTS_SAVE )
+GAME( 1988, gradius2, vulcan, twin16, gradius2, twin16_state, empty_init, ROT0, "Konami", "Gradius II: GOFER no Yabou (Japan, new)", MACHINE_SUPPORTS_SAVE )
+GAME( 1988, gradius2a, vulcan, twin16, vulcan, twin16_state, empty_init, ROT0, "Konami", "Gradius II: GOFER no Yabou (Japan, old)", MACHINE_SUPPORTS_SAVE )
+GAME( 1988, gradius2b, vulcan, twin16, vulcan, twin16_state, empty_init, ROT0, "Konami", "Gradius II: GOFER no Yabou (Japan, older)", MACHINE_SUPPORTS_SAVE )
-GAME( 1988, fround, 0, fround, fround, fround_state, init_fround, ROT0, "Konami", "The Final Round (version M)", MACHINE_SUPPORTS_SAVE )
-GAME( 1988, froundl, fround, fround, fround, fround_state, init_fround, ROT0, "Konami", "The Final Round (version L)", MACHINE_SUPPORTS_SAVE )
-GAME( 1988, hpuncher, fround, twin16, fround, twin16_state, init_twin16, ROT0, "Konami", "Hard Puncher (Japan)", MACHINE_SUPPORTS_SAVE )
+GAME( 1988, fround, 0, fround, fround, fround_state, empty_init, ROT0, "Konami", "The Final Round (version M)", MACHINE_SUPPORTS_SAVE )
+GAME( 1988, froundl, fround, fround, fround, fround_state, empty_init, ROT0, "Konami", "The Final Round (version L)", MACHINE_SUPPORTS_SAVE )
+GAME( 1988, hpuncher, fround, twin16, fround, twin16_state, empty_init, ROT0, "Konami", "Hard Puncher (Japan)", MACHINE_SUPPORTS_SAVE )
-GAME( 1989, miaj, mia, miaj, miaj, twin16_state, init_twin16, ROT0, "Konami", "M.I.A.: Missing in Action (Japan, version R)", MACHINE_SUPPORTS_SAVE )
+GAME( 1989, miaj, mia, miaj, miaj, twin16_state, empty_init, ROT0, "Konami", "M.I.A.: Missing in Action (Japan, version R)", MACHINE_SUPPORTS_SAVE )
-GAME( 1989, cuebrickj, cuebrick, cuebrickj, cuebrickj, cuebrickj_state, init_cuebrickj, ROT0, "Konami", "Cue Brick (Japan)", MACHINE_SUPPORTS_SAVE )
+GAME( 1989, cuebrickj, cuebrick, cuebrickj, cuebrickj, cuebrickj_state, empty_init, ROT0, "Konami", "Cue Brick (Japan)", MACHINE_SUPPORTS_SAVE )