diff --git a/src/mame/mame.lst b/src/mame/mame.lst index afe8753bcd3..9ed7bc5aef0 100644 --- a/src/mame/mame.lst +++ b/src/mame/mame.lst @@ -42630,6 +42630,7 @@ lgpalt // (c) 1983 Taito @source:taito/lkage.cpp bygone // A53 (c) 1985 Taito Corporation - prototype ? lkage // A54 (c) 1984 Taito Corporation +lkage5232 // lkageb // bootleg lkageb2 // bootleg lkageb3 // bootleg diff --git a/src/mame/taito/lkage.cpp b/src/mame/taito/lkage.cpp index 7a00f0050e1..7b4407cc91a 100644 --- a/src/mame/taito/lkage.cpp +++ b/src/mame/taito/lkage.cpp @@ -1,5 +1,6 @@ // license:BSD-3-Clause -// copyright-holders:Phil Stroffolino +// copyright-holders: Phil Stroffolino, Takahiro Nogi + /*************************************************************************** Legend of Kage @@ -29,7 +30,7 @@ Stephh's notes (based on the games Z80 code and some tests) : Flame length/color (and perhaps some other stuff) is also affected by DSW3 bit 3. - DSW3 bit 7 is supposed to determine how many coin slots there are (again, check - the coingae display routine and code at 0x1295), but if you look at coinage insertion + the coinage display routine and code at 0x1295), but if you look at coinage insertion routines (0x091b for COIN1 and 0x0991 for COIN2), you'll notice that DSW3 bit 7 is NOT tested ! @@ -67,7 +68,7 @@ Stephh's notes (based on the games Z80 code and some tests) : TODO: - - The high score display uses a video attribute flag whose pupose isn't known. + - The high score display uses a video attribute flag whose purpose isn't known. - purpose of the 0x200 byte prom, "a54-10.2" is unknown. It contains values in range 0x0..0xf. @@ -76,8 +77,8 @@ TODO: - Note that all the bootlegs are derived from a different version of the original which hasn't been found yet. - - lkage is verfied to be an original set, but it seems to work regardless of what - the mcu does. Moreover, the mcu returns a checksum which is different from what + - lkage is verified to be an original set, but it seems to work regardless of what + the MCU does. Moreover, the MCU returns a checksum which is different from what is expected - the MCU computes 0x89, but the main CPU expects 0x5d. The game works anyway, it never gives the usual Taito "BAD HW" message (because there is no test at 0x033b after call at routine at 0xde1d). @@ -86,28 +87,357 @@ TODO: ***************************************************************************/ #include "emu.h" -#include "lkage.h" + +#include "taito68705.h" #include "cpu/m6805/m6805.h" #include "cpu/z80/z80.h" +#include "machine/gen_latch.h" +#include "machine/input_merger.h" +#include "sound/ay8910.h" +#include "sound/dac.h" +#include "sound/msm5232.h" #include "sound/ymopn.h" +#include "emupal.h" #include "screen.h" #include "speaker.h" +#include "tilemap.h" -#define MAIN_CPU_CLOCK (XTAL(12'000'000)/2) -#define SOUND_CPU_CLOCK (XTAL(8'000'000)/2) -#define AUDIO_CLOCK (XTAL(8'000'000)/2) -#define MCU_CLOCK (XTAL(12'000'000)/4) +namespace { + +class lkage_state : public driver_device +{ +public: + lkage_state(const machine_config &mconfig, device_type type, const char *tag) : + driver_device(mconfig, type, tag), + m_vreg(*this, "vreg"), + m_scroll(*this, "scroll"), + m_spriteram(*this, "spriteram"), + m_videoram(*this, "videoram"), + m_maincpu(*this, "maincpu"), + m_audiocpu(*this, "audiocpu"), + m_bmcu(*this, "bmcu"), + m_gfxdecode(*this, "gfxdecode"), + m_palette(*this, "palette"), + m_soundlatch(*this, "soundlatch"), + m_soundnmi(*this, "soundnmi") + { } + + void lkageb(machine_config &config); + void lkage(machine_config &config); + + void init_bygone(); + void init_lkage(); + +protected: + virtual void machine_start() override; + virtual void machine_reset() override; + virtual void video_start() override; + + void sh_nmi_disable_w(uint8_t data); + void sh_nmi_enable_w(uint8_t data); + uint8_t sound_status_r(); + uint8_t mcu_status_r(); + uint8_t fake_mcu_r(); + void fake_mcu_w(uint8_t data); + uint8_t fake_status_r(); + + void videoram_w(offs_t offset, uint8_t data); + TILE_GET_INFO_MEMBER(get_bg_tile_info); + TILE_GET_INFO_MEMBER(get_fg_tile_info); + TILE_GET_INFO_MEMBER(get_tx_tile_info); + uint32_t screen_update(screen_device &screen, bitmap_ind16 &bitmap, const rectangle &cliprect); + void draw_sprites(screen_device &screen, bitmap_ind16 &bitmap, const rectangle &cliprect); + + void io_map(address_map &map); + void base_program_map(address_map &map); + void program_map(address_map &map); + void bootleg_program_map(address_map &map); + void mcu_map(address_map &map); + void sound_map(address_map &map); + + required_shared_ptr m_vreg; + required_shared_ptr m_scroll; + required_shared_ptr m_spriteram; + required_shared_ptr m_videoram; + + // devices + required_device m_maincpu; + required_device m_audiocpu; + optional_device m_bmcu; + required_device m_gfxdecode; + required_device m_palette; + required_device m_soundlatch; + required_device m_soundnmi; + + // video-related + tilemap_t *m_bg_tilemap = nullptr; + tilemap_t *m_fg_tilemap = nullptr; + tilemap_t *m_tx_tilemap = nullptr; + uint8_t m_bg_tile_bank = 0U; + uint8_t m_fg_tile_bank = 0U; + uint8_t m_tx_tile_bank = 0U; + + uint8_t m_sprite_dx = 0U; + uint8_t m_sprite_offset = 0U; + + // lkageb fake MCU + uint8_t m_mcu_val = 0U; + uint8_t m_mcu_ready = 0; // CPU data/MCU ready status +}; + +class lkage5232_state : public lkage_state +{ +public: + lkage5232_state(const machine_config &mconfig, device_type type, const char *tag) : + lkage_state(mconfig, type, tag), + m_exrom(*this, "data") + { } + + void lkage5232(machine_config &config); + + void init_lkage5232(); + +protected: + virtual void machine_start() override; + +private: + uint8_t unk_f0e1_r(offs_t offset); + uint8_t exrom_data_r(offs_t offset); + void exrom_offset_w(offs_t offset, uint8_t data); + uint8_t sound_unk_e000_r(offs_t offset); + + void program_map(address_map &map); + void sound_map(address_map &map); + + required_region_ptr m_exrom; + + uint8_t m_exrom_offs[2] = { 0x00, 0x00 }; +}; -void lkage_state::lkage_sh_nmi_disable_w(uint8_t data) +// video + +/*************************************************************************** + + lkage_scroll[0x00]: text layer horizontal scroll + lkage_scroll[0x01]: text layer vertical scroll + lkage_scroll[0x02]: foreground layer horizontal scroll + lkage_scroll[0x03]: foreground layer vertical scroll + lkage_scroll[0x04]: background layer horizontal scroll + lkage_scroll[0x05]: background layer vertical scroll + + lkage_vreg[0]: 0x00,0x04 + 0x02: tx tile bank select (bygone only?) + 0x04: fg tile bank select + 0x08: ? + + lkage_vreg[1]: 0x7d + 0xf0: background/foreground palette select + 0x08: bg tile bank select + 0x07: priority config? + + lkage_vreg[2]: 0xf3 + 0x03: flip screen x/y + 0xf0: normally 1111, but 1001 and 0001 inbetween stages (while the + backgrounds are are being redrawn). These bits are probably used to enable + individual layers, but we have no way of knowing the mapping. + + lkage_vreg: + 04 7d f3 : title screen 101 + 0c 7d f3 : high score 101 + 04 06 f3 : attract#1 110 + 04 1e f3 : attract#2 110 + 04 1e f3 : attract#3 110 + 00 4e f3 : attract#4 110 + + +***************************************************************************/ + + +void lkage_state::videoram_w(offs_t offset, uint8_t data) +{ + m_videoram[offset] = data; + + switch (offset / 0x400) + { + case 0: + m_tx_tilemap->mark_tile_dirty(offset & 0x3ff); + break; + + case 1: + m_fg_tilemap->mark_tile_dirty(offset & 0x3ff); + break; + + case 2: + m_bg_tilemap->mark_tile_dirty(offset & 0x3ff); + break; + + default: + break; + } +} + +TILE_GET_INFO_MEMBER(lkage_state::get_bg_tile_info) +{ + int const code = m_videoram[tile_index + 0x800] + 256 * (m_bg_tile_bank ? 5 : 1); + tileinfo.set(0, code, 0, 0); +} + +TILE_GET_INFO_MEMBER(lkage_state::get_fg_tile_info) +{ + int const code = m_videoram[tile_index + 0x400] + 256 * (m_fg_tile_bank ? 1 : 0); + tileinfo.set(0, code, 0, 0); +} + +TILE_GET_INFO_MEMBER(lkage_state::get_tx_tile_info) +{ + int const code = m_videoram[tile_index] + 256 * (m_tx_tile_bank ? 4 : 0); + tileinfo.set(0, code, 0, 0); +} + +void lkage_state::video_start() +{ + m_bg_tilemap = &machine().tilemap().create(*m_gfxdecode, tilemap_get_info_delegate(*this, FUNC(lkage_state::get_bg_tile_info)), TILEMAP_SCAN_ROWS, 8, 8, 32, 32); + m_fg_tilemap = &machine().tilemap().create(*m_gfxdecode, tilemap_get_info_delegate(*this, FUNC(lkage_state::get_fg_tile_info)), TILEMAP_SCAN_ROWS, 8, 8, 32, 32); + m_tx_tilemap = &machine().tilemap().create(*m_gfxdecode, tilemap_get_info_delegate(*this, FUNC(lkage_state::get_tx_tile_info)), TILEMAP_SCAN_ROWS, 8, 8, 32, 32); + + m_fg_tilemap->set_transparent_pen(0); + m_tx_tilemap->set_transparent_pen(0); + + m_bg_tilemap->set_scrolldx(-5, -5 + 24); + m_fg_tilemap->set_scrolldx(-3, -3 + 24); + m_tx_tilemap->set_scrolldx(-1, -1 + 24); +} + + +void lkage_state::draw_sprites(screen_device &screen, bitmap_ind16 &bitmap, const rectangle &cliprect) +{ + uint8_t const *source = m_spriteram; + uint8_t const *const finish = source + std::min(m_spriteram.bytes(), 0x80); + + for ( ; source < finish; source += 4) + { + int const attributes = source[2]; + /* 0x01: horizontal flip + * 0x02: vertical flip + * 0x04: bank select + * 0x08: sprite size + * 0x70: color + * 0x80: priority + */ + int const color = (attributes >> 4) & 7; + int flipx = attributes & 0x01; + int flipy = attributes & 0x02; + int const height = (attributes & 0x08) ? 2 : 1; + int sx = source[0] - 15 + m_sprite_dx; + int sy = 256 - (16 * height) - source[1]; + int sprite_number = source[3] + ((attributes & 0x04) << 6); + + int const priority_mask = (attributes & 0x80) ? (0xf0 | 0xcc) : 0xf0; + + if (flip_screen_x()) + { + sx = 239 - sx - 24; + flipx = !flipx; + } + else + { + sx += m_sprite_offset; + } + + if (flip_screen_y()) + { + sy = 254 - (16 * height) - sy; + flipy = !flipy; + } + if (height == 2 && !flipy) + { + sprite_number ^= 1; + } + + for (int y = 0; y < height; y++) + { + m_gfxdecode->gfx(1)->prio_transpen( + bitmap, + cliprect, + sprite_number ^ y, + color, + flipx, flipy, + sx & 0xff, + sy + 16 * y, + screen.priority(), + priority_mask, 0); + } + } +} + +uint32_t lkage_state::screen_update(screen_device &screen, bitmap_ind16 &bitmap, const rectangle &cliprect) +{ + flip_screen_x_set(~m_vreg[2] & 0x01); + flip_screen_y_set(~m_vreg[2] & 0x02); + + int const bg_bank = m_vreg[1] & 0x08; + if (m_bg_tile_bank != bg_bank) + { + m_bg_tile_bank = bg_bank; + m_bg_tilemap->mark_all_dirty(); + } + + int const fg_bank = m_vreg[0] & 0x04; + if (m_fg_tile_bank != fg_bank) + { + m_fg_tile_bank = fg_bank; + m_fg_tilemap->mark_all_dirty(); + } + + int const tx_bank = m_vreg[0] & 0x02; + if (m_tx_tile_bank != tx_bank) + { + m_tx_tile_bank = tx_bank; + m_tx_tilemap->mark_all_dirty(); + } + + m_bg_tilemap->set_palette_offset(0x300 + (m_vreg[1] & 0xf0)); + m_fg_tilemap->set_palette_offset(0x200 + (m_vreg[1] & 0xf0)); + m_tx_tilemap->set_palette_offset(0x110); + + m_tx_tilemap->set_scrollx(0, m_scroll[0]); + m_tx_tilemap->set_scrolly(0, m_scroll[1]); + + m_fg_tilemap->set_scrollx(0, m_scroll[2]); + m_fg_tilemap->set_scrolly(0, m_scroll[3]); + + m_bg_tilemap->set_scrollx(0, m_scroll[4]); + m_bg_tilemap->set_scrolly(0, m_scroll[5]); + + screen.priority().fill(0, cliprect); + if ((m_vreg[2] & 0xf0) == 0xf0) + { + m_bg_tilemap->draw(screen, bitmap, cliprect, 0, 1); + m_fg_tilemap->draw(screen, bitmap, cliprect, 0, (m_vreg[1] & 2) ? 2 : 4); + m_tx_tilemap->draw(screen, bitmap, cliprect, 0, 4); + draw_sprites(screen, bitmap, cliprect); + } + else + { + m_tx_tilemap->draw(screen, bitmap, cliprect, TILEMAP_DRAW_OPAQUE, 0); + } + + return 0; +} + + +// machine + +void lkage_state::sh_nmi_disable_w(uint8_t data) { m_soundnmi->in_w<1>(0); } -void lkage_state::lkage_sh_nmi_enable_w(uint8_t data) +void lkage_state::sh_nmi_enable_w(uint8_t data) { m_soundnmi->in_w<1>(1); } @@ -117,77 +447,131 @@ uint8_t lkage_state::sound_status_r() return 0xff; } -void lkage_state::lkage_map(address_map &map) +uint8_t lkage5232_state::unk_f0e1_r(offs_t offset) +{ + // Protection? + return 0xff; +} + +uint8_t lkage5232_state::exrom_data_r(offs_t offset) +{ + uint16_t const offs = ((m_exrom_offs[1] & 0x3f) << 8) + (m_exrom_offs[0] & 0xff); + uint8_t const data = m_exrom[offs]; + + if (offset != 0) + return 0xff; + else + return data; +} + +void lkage5232_state::exrom_offset_w(offs_t offset, uint8_t data) +{ + m_exrom_offs[offset] = data; +} + +uint8_t lkage5232_state::sound_unk_e000_r(offs_t offset) +{ + return 0xff; +} + + +void lkage_state::base_program_map(address_map &map) { map(0x0000, 0xdfff).rom(); - map(0xe000, 0xe7ff).ram(); /* work ram */ + map(0xe000, 0xe7ff).ram(); // work RAM map(0xe800, 0xefff).ram().w(m_palette, FUNC(palette_device::write8)).share("palette"); - map(0xf000, 0xf003).ram().share("vreg"); /* video registers */ + map(0xf000, 0xf003).ram().share(m_vreg); map(0xf060, 0xf060).w(m_soundlatch, FUNC(generic_latch_8_device::write)); map(0xf061, 0xf061).nopw().r(FUNC(lkage_state::sound_status_r)); - map(0xf063, 0xf063).nopw(); /* pulsed; nmi on sound cpu? */ + map(0xf063, 0xf063).nopw(); // pulsed; NMI on sound CPU? map(0xf080, 0xf080).portr("DSW1"); map(0xf081, 0xf081).portr("DSW2"); map(0xf082, 0xf082).portr("DSW3"); map(0xf083, 0xf083).portr("SYSTEM"); map(0xf084, 0xf084).portr("P1"); map(0xf086, 0xf086).portr("P2"); - map(0xf0a0, 0xf0a3).ram(); /* unknown */ - map(0xf0c0, 0xf0c5).ram().share("scroll"); - map(0xf0e1, 0xf0e1).nopw(); /* pulsed */ - map(0xf100, 0xf15f).ram().share("spriteram"); - map(0xf160, 0xf1ff).ram(); /* unknown - no valid sprite data */ - map(0xf400, 0xffff).ram().w(FUNC(lkage_state::lkage_videoram_w)).share("videoram"); + map(0xf0a0, 0xf0a3).ram(); // unknown + map(0xf0c0, 0xf0c5).ram().share(m_scroll); + map(0xf0e1, 0xf0e1).nopw(); // pulsed + map(0xf400, 0xffff).ram().w(FUNC(lkage_state::videoram_w)).share(m_videoram); } -void lkage_state::lkage_map_mcu(address_map &map) +void lkage_state::program_map(address_map &map) { - lkage_map(map); + base_program_map(map); + map(0xf100, 0xf15f).ram().share(m_spriteram); + map(0xf160, 0xf1ff).ram(); // unknown - no valid sprite data +} + +void lkage5232_state::program_map(address_map &map) +{ + base_program_map(map); + //map(0xf060, 0xf060).w(m_soundlatch, FUNC(generic_latch_8_device::write)); + map(0xf0a0, 0xf0a1).r(FUNC(lkage5232_state::exrom_data_r)).w(FUNC(lkage5232_state::exrom_offset_w)); // extend ROM read + map(0xf0a2, 0xf0a3).noprw(); // unknown + map(0xf0e1, 0xf0e1).r(FUNC(lkage5232_state::unk_f0e1_r)).nopw(); // unknown + map(0xf100, 0xf1ff).ram().share(m_spriteram); +} + +void lkage_state::mcu_map(address_map &map) +{ + program_map(map); map(0xf062, 0xf062).rw(m_bmcu, FUNC(taito68705_mcu_device::data_r), FUNC(taito68705_mcu_device::data_w)); map(0xf087, 0xf087).r(FUNC(lkage_state::mcu_status_r)); } -void lkage_state::lkage_map_boot(address_map &map) +void lkage_state::bootleg_program_map(address_map &map) { - lkage_map(map); + program_map(map); map(0xf062, 0xf062).rw(FUNC(lkage_state::fake_mcu_r), FUNC(lkage_state::fake_mcu_w)); map(0xf087, 0xf087).r(FUNC(lkage_state::fake_status_r)); } -uint8_t lkage_state::port_fetch_r(offs_t offset) +void lkage_state::io_map(address_map &map) { - return memregion("user1")->base()[offset]; -} - -void lkage_state::lkage_io_map(address_map &map) -{ - map(0x4000, 0x7fff).r(FUNC(lkage_state::port_fetch_r)); + map(0x4000, 0x7fff).rom().region("data", 0); } /***************************************************************************/ -/* sound section is almost identical to Bubble Bobble, YM2203 instead of YM3526 */ +// sound section is almost identical to Bubble Bobble, YM2203 instead of YM3526 -void lkage_state::lkage_sound_map(address_map &map) +void lkage_state::sound_map(address_map &map) { map(0x0000, 0x7fff).rom(); map(0x8000, 0x87ff).ram(); map(0x9000, 0x9001).rw("ym1", FUNC(ym2203_device::read), FUNC(ym2203_device::write)); map(0xa000, 0xa001).rw("ym2", FUNC(ym2203_device::read), FUNC(ym2203_device::write)); - map(0xb000, 0xb000).r(m_soundlatch, FUNC(generic_latch_8_device::read)).nopw(); /* ??? */ - map(0xb001, 0xb001).nopr() /* ??? */ .w(FUNC(lkage_state::lkage_sh_nmi_enable_w)); - map(0xb002, 0xb002).w(FUNC(lkage_state::lkage_sh_nmi_disable_w)); + map(0xb000, 0xb000).r(m_soundlatch, FUNC(generic_latch_8_device::read)).nopw(); // ??? + map(0xb001, 0xb001).nopr().w(FUNC(lkage_state::sh_nmi_enable_w)); // read ??? + map(0xb002, 0xb002).w(FUNC(lkage_state::sh_nmi_disable_w)); map(0xb003, 0xb003).nopw(); - map(0xe000, 0xefff).rom(); /* space for diagnostic ROM? */ + map(0xe000, 0xefff).rom(); // space for diagnostic ROM? +} + +void lkage5232_state::sound_map(address_map &map) +{ + map(0x0000, 0x3fff).rom(); + map(0x4000, 0x47ff).ram(); + map(0x8000, 0x8001).w("ay1", FUNC(ym2149_device::address_data_w)); + map(0x8002, 0x8003).w("ay2", FUNC(ym2149_device::address_data_w)); + map(0x8010, 0x801d).w("msm", FUNC(msm5232_device::write)); + map(0x8020, 0x8020).nopw(); // ? + map(0xc000, 0xc000).r(m_soundlatch, FUNC(generic_latch_8_device::read)); + map(0xc001, 0xc001).nopr().w(FUNC(lkage5232_state::sh_nmi_enable_w)); + map(0xc002, 0xc002).w(FUNC(lkage5232_state::sh_nmi_disable_w)); +// map(0xc003, 0xc003).w("dac", FUNC(dac_byte_interface::data_w)); + map(0xc003, 0xc003).nopw(); + map(0xe000, 0xe000).r(FUNC(lkage5232_state::sound_unk_e000_r)); } /***************************************************************************/ static INPUT_PORTS_START( lkage ) PORT_START("DSW1") - PORT_DIPNAME( 0x03, 0x03, DEF_STR( Bonus_Life ) ) /* table at 0x04b8 */ + PORT_DIPNAME( 0x03, 0x03, DEF_STR( Bonus_Life ) ) // table at 0x04b8 PORT_DIPSETTING( 0x03, "200k 700k 500k+" ) PORT_DIPSETTING( 0x02, "200k 900k 700k+" ) PORT_DIPSETTING( 0x01, "300k 1000k 700k+" ) @@ -248,17 +632,17 @@ static INPUT_PORTS_START( lkage ) PORT_DIPUNUSED( 0x01, IP_ACTIVE_LOW ) PORT_DIPNAME( 0x02, 0x02, "Initial Season" ) PORT_DIPSETTING( 0x02, "Spring" ) - PORT_DIPSETTING( 0x00, "Winter" ) /* same as if you saved the princess twice ("HOWEVER ...") */ + PORT_DIPSETTING( 0x00, "Winter" ) // same as if you saved the princess twice ("HOWEVER ...") PORT_DIPUNUSED( 0x04, IP_ACTIVE_LOW ) - PORT_DIPNAME( 0x08, 0x08, DEF_STR( Difficulty ) ) /* see notes */ + PORT_DIPNAME( 0x08, 0x08, DEF_STR( Difficulty ) ) // see notes PORT_DIPSETTING( 0x08, DEF_STR( Easy ) ) PORT_DIPSETTING( 0x00, DEF_STR( Normal ) ) - PORT_DIPNAME( 0x10, 0x10, "Coinage Display" ) /* see notes */ + PORT_DIPNAME( 0x10, 0x10, "Coinage Display" ) // see notes PORT_DIPSETTING( 0x00, DEF_STR( No ) ) PORT_DIPSETTING( 0x10, DEF_STR( Yes ) ) PORT_DIPNAME( 0x20, 0x20, "Year Display" ) PORT_DIPSETTING( 0x00, "1985" ) - PORT_DIPSETTING( 0x20, "MCMLXXXIV" ) /* 1984(!) */ + PORT_DIPSETTING( 0x20, "MCMLXXXIV" ) // 1984(!) PORT_DIPNAME( 0x40, 0x40, "Invulnerability (Cheat)") PORT_DIPSETTING( 0x40, DEF_STR( Off ) ) PORT_DIPSETTING( 0x00, DEF_STR( On ) ) @@ -301,14 +685,14 @@ static INPUT_PORTS_START( lkageb ) PORT_INCLUDE( lkage ) PORT_MODIFY("DSW1") - PORT_DIPNAME( 0x03, 0x03, DEF_STR( Bonus_Life ) ) /* table at 0x04b8 */ + PORT_DIPNAME( 0x03, 0x03, DEF_STR( Bonus_Life ) ) // table at 0x04b8 PORT_DIPSETTING( 0x03, "20k 70k 50k+" ) PORT_DIPSETTING( 0x02, "20k 90k 70k+" ) PORT_DIPSETTING( 0x01, "30k 100k 70k+" ) PORT_DIPSETTING( 0x00, "30k 130k 100k+" ) PORT_MODIFY("DSW3") - PORT_DIPNAME( 0x0c, 0x0c, DEF_STR( Difficulty ) ) /* see notes */ + PORT_DIPNAME( 0x0c, 0x0c, DEF_STR( Difficulty ) ) // see notes PORT_DIPSETTING( 0x0c, DEF_STR( Easy ) ) PORT_DIPSETTING( 0x08, DEF_STR( Normal ) ) PORT_DIPSETTING( 0x04, DEF_STR( Hard ) ) @@ -461,8 +845,8 @@ static const gfx_layout sprite_layout = }; static GFXDECODE_START( gfx_lkage ) - GFXDECODE_ENTRY( "gfx1", 0x0000, tile_layout, /*128*/0, 64 ) - GFXDECODE_ENTRY( "gfx1", 0x0000, sprite_layout, 0, 16 ) + GFXDECODE_ENTRY( "gfx", 0x0000, tile_layout, /*128*/0, 64 ) + GFXDECODE_ENTRY( "gfx", 0x0000, sprite_layout, 0, 16 ) GFXDECODE_END @@ -472,12 +856,18 @@ void lkage_state::machine_start() save_item(NAME(m_fg_tile_bank)); save_item(NAME(m_tx_tile_bank)); - save_item(NAME(m_sprite_dx)); - - save_item(NAME(m_mcu_ready)); save_item(NAME(m_mcu_val)); } +void lkage5232_state::machine_start() +{ + save_item(NAME(m_bg_tile_bank)); + save_item(NAME(m_fg_tile_bank)); + save_item(NAME(m_tx_tile_bank)); + + save_item(NAME(m_exrom_offs)); +} + void lkage_state::machine_reset() { m_bg_tile_bank = m_fg_tile_bank = m_tx_tile_bank =0; @@ -488,46 +878,47 @@ void lkage_state::machine_reset() m_soundnmi->in_w<1>(0); } + void lkage_state::lkage(machine_config &config) { - /* basic machine hardware */ - Z80(config, m_maincpu, MAIN_CPU_CLOCK); - m_maincpu->set_addrmap(AS_PROGRAM, &lkage_state::lkage_map_mcu); - m_maincpu->set_addrmap(AS_IO, &lkage_state::lkage_io_map); + // basic machine hardware + Z80(config, m_maincpu, 12_MHz_XTAL / 2); + m_maincpu->set_addrmap(AS_PROGRAM, &lkage_state::mcu_map); + m_maincpu->set_addrmap(AS_IO, &lkage_state::io_map); m_maincpu->set_vblank_int("screen", FUNC(lkage_state::irq0_line_hold)); - Z80(config, m_audiocpu, SOUND_CPU_CLOCK); - m_audiocpu->set_addrmap(AS_PROGRAM, &lkage_state::lkage_sound_map); /* IRQs are triggered by the YM2203 */ + Z80(config, m_audiocpu, 8_MHz_XTAL / 2); + m_audiocpu->set_addrmap(AS_PROGRAM, &lkage_state::sound_map); // IRQs are triggered by the YM2203 - TAITO68705_MCU(config, m_bmcu, MCU_CLOCK); + TAITO68705_MCU(config, m_bmcu, 12_MHz_XTAL / 4); - /* video hardware */ + // video hardware screen_device &screen(SCREEN(config, "screen", SCREEN_TYPE_RASTER)); screen.set_refresh_hz(60); - screen.set_vblank_time(ATTOSECONDS_IN_USEC(2500)); /* not accurate */ + screen.set_vblank_time(ATTOSECONDS_IN_USEC(2500)); // not accurate screen.set_size(32*8, 32*8); screen.set_visarea(2*8, 32*8-1, 2*8, 30*8-1); - screen.set_screen_update(FUNC(lkage_state::screen_update_lkage)); + screen.set_screen_update(FUNC(lkage_state::screen_update)); screen.set_palette(m_palette); GFXDECODE(config, m_gfxdecode, m_palette, gfx_lkage); PALETTE(config, m_palette).set_format(palette_device::xRGB_444, 1024); - /* sound hardware */ + // sound hardware SPEAKER(config, "mono").front_center(); GENERIC_LATCH_8(config, m_soundlatch).data_pending_callback().set(m_soundnmi, FUNC(input_merger_device::in_w<0>)); INPUT_MERGER_ALL_HIGH(config, m_soundnmi).output_handler().set_inputline(m_audiocpu, INPUT_LINE_NMI); - ym2203_device &ym1(YM2203(config, "ym1", AUDIO_CLOCK)); + ym2203_device &ym1(YM2203(config, "ym1", 8_MHz_XTAL / 2)); ym1.irq_handler().set_inputline(m_audiocpu, 0); ym1.add_route(0, "mono", 0.15); ym1.add_route(1, "mono", 0.15); ym1.add_route(2, "mono", 0.15); ym1.add_route(3, "mono", 0.40); - ym2203_device &ym2(YM2203(config, "ym2", AUDIO_CLOCK)); + ym2203_device &ym2(YM2203(config, "ym2", 8_MHz_XTAL / 2)); ym2.add_route(0, "mono", 0.15); ym2.add_route(1, "mono", 0.15); ym2.add_route(2, "mono", 0.15); @@ -536,70 +927,70 @@ void lkage_state::lkage(machine_config &config) void lkage_state::lkageb(machine_config &config) { - /* basic machine hardware */ - Z80(config, m_maincpu, MAIN_CPU_CLOCK); - m_maincpu->set_addrmap(AS_PROGRAM, &lkage_state::lkage_map_boot); - m_maincpu->set_addrmap(AS_IO, &lkage_state::lkage_io_map); - m_maincpu->set_vblank_int("screen", FUNC(lkage_state::irq0_line_hold)); + lkage(config); - Z80(config, m_audiocpu, SOUND_CPU_CLOCK); - m_audiocpu->set_addrmap(AS_PROGRAM, &lkage_state::lkage_sound_map); /* IRQs are triggered by the YM2203 */ + m_maincpu->set_addrmap(AS_PROGRAM, &lkage_state::bootleg_program_map); - /* video hardware */ - screen_device &screen(SCREEN(config, "screen", SCREEN_TYPE_RASTER)); - screen.set_refresh_hz(60); - screen.set_vblank_time(ATTOSECONDS_IN_USEC(2500)); /* not accurate */ - screen.set_size(32*8, 32*8); - screen.set_visarea(2*8, 32*8-1, 2*8, 30*8-1); - screen.set_screen_update(FUNC(lkage_state::screen_update_lkage)); - screen.set_palette(m_palette); - - GFXDECODE(config, m_gfxdecode, m_palette, gfx_lkage); - PALETTE(config, m_palette).set_format(palette_device::xRGB_444, 1024); - - /* sound hardware */ - SPEAKER(config, "mono").front_center(); - - GENERIC_LATCH_8(config, m_soundlatch).data_pending_callback().set(m_soundnmi, FUNC(input_merger_device::in_w<0>)); - - INPUT_MERGER_ALL_HIGH(config, m_soundnmi).output_handler().set_inputline(m_audiocpu, INPUT_LINE_NMI); - - ym2203_device &ym1(YM2203(config, "ym1", AUDIO_CLOCK)); - ym1.irq_handler().set_inputline("audiocpu", 0); - ym1.add_route(0, "mono", 0.15); - ym1.add_route(1, "mono", 0.15); - ym1.add_route(2, "mono", 0.15); - ym1.add_route(3, "mono", 0.40); - - ym2203_device &ym2(YM2203(config, "ym2", AUDIO_CLOCK)); - ym2.add_route(0, "mono", 0.15); - ym2.add_route(1, "mono", 0.15); - ym2.add_route(2, "mono", 0.15); - ym2.add_route(3, "mono", 0.40); + config.device_remove("bmcu"); } +void lkage5232_state::lkage5232(machine_config &config) +{ + lkageb(config); + + m_maincpu->set_addrmap(AS_PROGRAM, &lkage5232_state::program_map); + + m_audiocpu->set_addrmap(AS_PROGRAM, &lkage5232_state::sound_map); + m_audiocpu->set_periodic_int(FUNC(lkage5232_state::irq0_line_hold), attotime::from_hz(60)); + + // 100 CPU slices per frame - a high value to ensure proper synchronization of the CPUs + config.set_maximum_quantum(attotime::from_hz(6000)); + + subdevice("screen")->set_screen_update(FUNC(lkage5232_state::screen_update)); + + config.device_remove("ym1"); + config.device_remove("ym2"); + + YM2149(config, "ay1", 2_MHz_XTAL).add_route(ALL_OUTPUTS, "mono", 0.18); + YM2149(config, "ay2", 2_MHz_XTAL).add_route(ALL_OUTPUTS, "mono", 0.18); + + msm5232_device &msm(MSM5232(config, "msm", 2_MHz_XTAL)); + msm.set_capacitors(0.39e-6, 0.39e-6, 0.39e-6, 0.39e-6, 0.39e-6, 0.39e-6, 0.39e-6, 0.39e-6); + msm.add_route(0, "mono", 1.35); + msm.add_route(1, "mono", 1.35); + msm.add_route(2, "mono", 1.35); + msm.add_route(3, "mono", 1.35); + msm.add_route(4, "mono", 1.35); + msm.add_route(5, "mono", 1.35); + msm.add_route(6, "mono", 1.35); + msm.add_route(7, "mono", 1.35); + + DAC_8BIT_R2R(config, "dac", 0).add_route(ALL_OUTPUTS, "mono", 0.25); +} + + ROM_START( lkage ) - ROM_REGION( 0x14000, "maincpu", 0 ) /* Z80 code (main CPU) */ + ROM_REGION( 0x14000, "maincpu", 0 ) // Z80 code ROM_LOAD( "a54-01-2.37", 0x0000, 0x8000, CRC(60fd9734) SHA1(33b444b887d80acb3a63ca4534db65c4d8147712) ) ROM_LOAD( "a54-02-2.38", 0x8000, 0x8000, CRC(878a25ce) SHA1(6228a12774e116e333c3563ee6e20c0c70db514b) ) - ROM_REGION( 0x10000, "audiocpu", 0 ) /* Z80 code (sound CPU) */ + ROM_REGION( 0x10000, "audiocpu", 0 ) // Z80 code ROM_LOAD( "a54-04.54", 0x0000, 0x8000, CRC(541faf9a) SHA1(b142ff3bd198f700697ec06ea92db3109ab5818e) ) - ROM_REGION( 0x00800, "bmcu:mcu", 0 ) /* 68705 MCU code */ + ROM_REGION( 0x00800, "bmcu:mcu", 0 ) // 68705 code ROM_LOAD( "a54-09.53", 0x0000, 0x0800, CRC(0e8b8846) SHA1(a4a105462b0127229bb7edfadd2e581c7e40f1cc) ) - ROM_REGION( 0x4000, "user1", 0 ) /* data */ + ROM_REGION( 0x4000, "data", 0 ) ROM_LOAD( "a54-03.51", 0x0000, 0x4000, CRC(493e76d8) SHA1(13c6160edd94ba2801fd89bb33bcae3a1e3454ff) ) - ROM_REGION( 0x10000, "gfx1", 0 ) + ROM_REGION( 0x10000, "gfx", 0 ) ROM_LOAD( "a54-05-1.84", 0x0000, 0x4000, CRC(0033c06a) SHA1(89964503fc338817c6511fd15942741996b7037a) ) ROM_LOAD( "a54-06-1.85", 0x4000, 0x4000, CRC(9f04d9ad) SHA1(3b9a4d30348fd02e5c8ae94655548bd4a02dd65d) ) ROM_LOAD( "a54-07-1.86", 0x8000, 0x4000, CRC(b20561a4) SHA1(0d6d83dfae79ea133e37704ca47426b4c978fb36) ) ROM_LOAD( "a54-08-1.87", 0xc000, 0x4000, CRC(3ff3b230) SHA1(ffcd964efb0af32b5d7a70305dfda615ea95acbe) ) ROM_REGION( 0x0200, "proms", 0 ) - ROM_LOAD( "a54-10.2", 0x0000, 0x0200, CRC(17dfbd14) SHA1(f8f0b6dfedd4ba108dad43ccc7697ef4ab9cbf86) ) /* unknown */ + ROM_LOAD( "a54-10.2", 0x0000, 0x0200, CRC(17dfbd14) SHA1(f8f0b6dfedd4ba108dad43ccc7697ef4ab9cbf86) ) // unknown ROM_REGION( 0x0800, "plds", 0 ) ROM_LOAD( "pal16l8-a54-11.34", 0x0000, 0x0104, CRC(56232113) SHA1(4cdc6732aa3e7fbe8df51966a1295253711ecc8f) ) @@ -609,27 +1000,27 @@ ROM_START( lkage ) ROM_END ROM_START( lkageo ) - ROM_REGION( 0x14000, "maincpu", 0 ) /* Z80 code (main CPU) */ + ROM_REGION( 0x14000, "maincpu", 0 ) // Z80 code ROM_LOAD( "a54-01-1.37", 0x0000, 0x8000, CRC(973da9c5) SHA1(ad3b5d6a329b784e47be563c6f8dc628f32ba0a5) ) ROM_LOAD( "a54-02-1.38", 0x8000, 0x8000, CRC(27b509da) SHA1(c623950bd7dd2b5699ca948e3731455964106b89) ) - ROM_REGION( 0x10000, "audiocpu", 0 ) /* Z80 code (sound CPU) */ + ROM_REGION( 0x10000, "audiocpu", 0 ) // Z80 code ROM_LOAD( "a54-04.54", 0x0000, 0x8000, CRC(541faf9a) SHA1(b142ff3bd198f700697ec06ea92db3109ab5818e) ) - ROM_REGION( 0x00800, "bmcu:mcu", 0 ) /* 68705 MCU code */ + ROM_REGION( 0x00800, "bmcu:mcu", 0 ) // 68705 code ROM_LOAD( "a54-09.53", 0x0000, 0x0800, CRC(0e8b8846) SHA1(a4a105462b0127229bb7edfadd2e581c7e40f1cc) ) - ROM_REGION( 0x4000, "user1", 0 ) /* data */ + ROM_REGION( 0x4000, "data", 0 ) ROM_LOAD( "a54-03.51", 0x0000, 0x4000, CRC(493e76d8) SHA1(13c6160edd94ba2801fd89bb33bcae3a1e3454ff) ) - ROM_REGION( 0x10000, "gfx1", 0 ) + ROM_REGION( 0x10000, "gfx", 0 ) ROM_LOAD( "a54-05-1.84", 0x0000, 0x4000, CRC(0033c06a) SHA1(89964503fc338817c6511fd15942741996b7037a) ) ROM_LOAD( "a54-06-1.85", 0x4000, 0x4000, CRC(9f04d9ad) SHA1(3b9a4d30348fd02e5c8ae94655548bd4a02dd65d) ) ROM_LOAD( "a54-07-1.86", 0x8000, 0x4000, CRC(b20561a4) SHA1(0d6d83dfae79ea133e37704ca47426b4c978fb36) ) ROM_LOAD( "a54-08-1.87", 0xc000, 0x4000, CRC(3ff3b230) SHA1(ffcd964efb0af32b5d7a70305dfda615ea95acbe) ) ROM_REGION( 0x0200, "proms", 0 ) - ROM_LOAD( "a54-10.2", 0x0000, 0x0200, CRC(17dfbd14) SHA1(f8f0b6dfedd4ba108dad43ccc7697ef4ab9cbf86) ) /* unknown */ + ROM_LOAD( "a54-10.2", 0x0000, 0x0200, CRC(17dfbd14) SHA1(f8f0b6dfedd4ba108dad43ccc7697ef4ab9cbf86) ) // unknown ROM_REGION( 0x0800, "plds", 0 ) ROM_LOAD( "pal16l8-a54-11.34", 0x0000, 0x0104, CRC(56232113) SHA1(4cdc6732aa3e7fbe8df51966a1295253711ecc8f) ) @@ -639,27 +1030,27 @@ ROM_START( lkageo ) ROM_END ROM_START( lkageoo ) - ROM_REGION( 0x14000, "maincpu", 0 ) /* Z80 code (main CPU) */ + ROM_REGION( 0x14000, "maincpu", 0 ) // Z80 code ROM_LOAD( "a54-01.37", 0x0000, 0x8000, CRC(34eab2c5) SHA1(25bf2dc80d21aa68c3af5debf10b24c75d83a738) ) ROM_LOAD( "a54-02.38", 0x8000, 0x8000, CRC(ea471d8a) SHA1(1ffc7f78e3e983e16a23e97019f7030f9846569b) ) - ROM_REGION( 0x10000, "audiocpu", 0 ) /* Z80 code (sound CPU) */ + ROM_REGION( 0x10000, "audiocpu", 0 ) // Z80 code ROM_LOAD( "a54-04.54", 0x0000, 0x8000, CRC(541faf9a) SHA1(b142ff3bd198f700697ec06ea92db3109ab5818e) ) - ROM_REGION( 0x00800, "bmcu:mcu", 0 ) /* 68705 MCU code */ + ROM_REGION( 0x00800, "bmcu:mcu", 0 ) // 68705 code ROM_LOAD( "a54-09.53", 0x0000, 0x0800, CRC(0e8b8846) SHA1(a4a105462b0127229bb7edfadd2e581c7e40f1cc) ) - ROM_REGION( 0x4000, "user1", 0 ) /* data */ + ROM_REGION( 0x4000, "data", 0 ) ROM_LOAD( "a54-03.51", 0x0000, 0x4000, CRC(493e76d8) SHA1(13c6160edd94ba2801fd89bb33bcae3a1e3454ff) ) - ROM_REGION( 0x10000, "gfx1", 0 ) + ROM_REGION( 0x10000, "gfx", 0 ) ROM_LOAD( "a54-05.84", 0x0000, 0x4000, CRC(76753e52) SHA1(13f61969d59b055a5ab40237148e091d7cabe190) ) ROM_LOAD( "a54-06.85", 0x4000, 0x4000, CRC(f33c015c) SHA1(756326daab255d3a36d97e51ee141b9f7157f12e) ) ROM_LOAD( "a54-07.86", 0x8000, 0x4000, CRC(0e02c2e8) SHA1(1d8a817ba66cf26a4fe51ae00874c0fe6e7cebe3) ) ROM_LOAD( "a54-08.87", 0xc000, 0x4000, CRC(4ef5f073) SHA1(dfd234542b28cff74692a1c381772da01e8bb4a7) ) ROM_REGION( 0x0200, "proms", 0 ) - ROM_LOAD( "a54-10.2", 0x0000, 0x0200, CRC(17dfbd14) SHA1(f8f0b6dfedd4ba108dad43ccc7697ef4ab9cbf86) ) /* unknown */ + ROM_LOAD( "a54-10.2", 0x0000, 0x0200, CRC(17dfbd14) SHA1(f8f0b6dfedd4ba108dad43ccc7697ef4ab9cbf86) ) // unknown ROM_REGION( 0x0800, "plds", 0 ) ROM_LOAD( "pal16l8-a54-11.34", 0x0000, 0x0104, CRC(56232113) SHA1(4cdc6732aa3e7fbe8df51966a1295253711ecc8f) ) @@ -669,66 +1060,66 @@ ROM_START( lkageoo ) ROM_END ROM_START( lkageb ) - ROM_REGION( 0x10000, "maincpu", 0 ) /* Z80 code (main CPU) */ + ROM_REGION( 0x10000, "maincpu", 0 ) // Z80 code ROM_LOAD( "ic37_1", 0x0000, 0x8000, CRC(05694f7b) SHA1(08a3796d6cf04d64db52ed8208a51084c420e10a) ) ROM_LOAD( "ic38_2", 0x8000, 0x8000, CRC(22efe29e) SHA1(f7a29d54081ca7509e822ad8823ec977bccc4a40) ) - ROM_REGION( 0x10000, "audiocpu", 0 ) /* Z80 code (sound CPU) */ + ROM_REGION( 0x10000, "audiocpu", 0 ) // Z80 code ROM_LOAD( "a54-04.54", 0x0000, 0x8000, CRC(541faf9a) SHA1(b142ff3bd198f700697ec06ea92db3109ab5818e) ) - ROM_REGION( 0x4000, "user1", 0 ) /* data */ + ROM_REGION( 0x4000, "data", 0 ) ROM_LOAD( "a54-03.51", 0x0000, 0x4000, CRC(493e76d8) SHA1(13c6160edd94ba2801fd89bb33bcae3a1e3454ff) ) - ROM_REGION( 0x10000, "gfx1", 0 ) + ROM_REGION( 0x10000, "gfx", 0 ) ROM_LOAD( "ic93_5", 0x0000, 0x4000, CRC(76753e52) SHA1(13f61969d59b055a5ab40237148e091d7cabe190) ) ROM_LOAD( "ic94_6", 0x4000, 0x4000, CRC(f33c015c) SHA1(756326daab255d3a36d97e51ee141b9f7157f12e) ) ROM_LOAD( "ic95_7", 0x8000, 0x4000, CRC(0e02c2e8) SHA1(1d8a817ba66cf26a4fe51ae00874c0fe6e7cebe3) ) ROM_LOAD( "ic96_8", 0xc000, 0x4000, CRC(4ef5f073) SHA1(dfd234542b28cff74692a1c381772da01e8bb4a7) ) ROM_REGION( 0x0200, "proms", 0 ) - ROM_LOAD( "a54-10.2", 0x0000, 0x0200, CRC(17dfbd14) SHA1(f8f0b6dfedd4ba108dad43ccc7697ef4ab9cbf86) ) /* unknown */ + ROM_LOAD( "a54-10.2", 0x0000, 0x0200, CRC(17dfbd14) SHA1(f8f0b6dfedd4ba108dad43ccc7697ef4ab9cbf86) ) // unknown ROM_END ROM_START( lkageb2 ) - ROM_REGION( 0x10000, "maincpu", 0 ) /* Z80 code (main CPU) */ + ROM_REGION( 0x10000, "maincpu", 0 ) // Z80 code ROM_LOAD( "lok.a", 0x0000, 0x8000, CRC(866df793) SHA1(44a9a773d7bbfc5f9d53f56682438ef8b23ecbd6) ) ROM_LOAD( "lok.b", 0x8000, 0x8000, CRC(fba9400f) SHA1(fedcb9b717feaeec31afda098f0ac2744df6c7be) ) - ROM_REGION( 0x10000, "audiocpu", 0 ) /* Z80 code (sound CPU) */ + ROM_REGION( 0x10000, "audiocpu", 0 ) // Z80 code ROM_LOAD( "a54-04.54", 0x0000, 0x8000, CRC(541faf9a) SHA1(b142ff3bd198f700697ec06ea92db3109ab5818e) ) - ROM_REGION( 0x4000, "user1", 0 ) /* data */ + ROM_REGION( 0x4000, "data", 0 ) ROM_LOAD( "a54-03.51", 0x0000, 0x4000, CRC(493e76d8) SHA1(13c6160edd94ba2801fd89bb33bcae3a1e3454ff) ) - ROM_REGION( 0x10000, "gfx1", 0 ) + ROM_REGION( 0x10000, "gfx", 0 ) ROM_LOAD( "ic93_5", 0x0000, 0x4000, CRC(76753e52) SHA1(13f61969d59b055a5ab40237148e091d7cabe190) ) ROM_LOAD( "ic94_6", 0x4000, 0x4000, CRC(f33c015c) SHA1(756326daab255d3a36d97e51ee141b9f7157f12e) ) ROM_LOAD( "ic95_7", 0x8000, 0x4000, CRC(0e02c2e8) SHA1(1d8a817ba66cf26a4fe51ae00874c0fe6e7cebe3) ) ROM_LOAD( "ic96_8", 0xc000, 0x4000, CRC(4ef5f073) SHA1(dfd234542b28cff74692a1c381772da01e8bb4a7) ) ROM_REGION( 0x0200, "proms", 0 ) - ROM_LOAD( "a54-10.2", 0x0000, 0x0200, CRC(17dfbd14) SHA1(f8f0b6dfedd4ba108dad43ccc7697ef4ab9cbf86) ) /* unknown */ + ROM_LOAD( "a54-10.2", 0x0000, 0x0200, CRC(17dfbd14) SHA1(f8f0b6dfedd4ba108dad43ccc7697ef4ab9cbf86) ) // unknown ROM_END ROM_START( lkageb3 ) - ROM_REGION( 0x10000, "maincpu", 0 ) /* Z80 code (main CPU) */ + ROM_REGION( 0x10000, "maincpu", 0 ) // Z80 code ROM_LOAD( "z1.bin", 0x0000, 0x8000, CRC(60cac488) SHA1(b61df14159f37143b1faed22d77fc7be31602022) ) ROM_LOAD( "z2.bin", 0x8000, 0x8000, CRC(22c95f17) SHA1(8ca438d508a36918778651adf599cf45a7c4a5d7) ) - ROM_REGION( 0x10000, "audiocpu", 0 ) /* Z80 code (sound CPU) */ + ROM_REGION( 0x10000, "audiocpu", 0 ) // Z80 code ROM_LOAD( "a54-04.54", 0x0000, 0x8000, CRC(541faf9a) SHA1(b142ff3bd198f700697ec06ea92db3109ab5818e) ) - ROM_REGION( 0x4000, "user1", 0 ) /* data */ + ROM_REGION( 0x4000, "data", 0 ) ROM_LOAD( "a54-03.51", 0x0000, 0x4000, CRC(493e76d8) SHA1(13c6160edd94ba2801fd89bb33bcae3a1e3454ff) ) - ROM_REGION( 0x10000, "gfx1", 0 ) + ROM_REGION( 0x10000, "gfx", 0 ) ROM_LOAD( "ic93_5", 0x0000, 0x4000, CRC(76753e52) SHA1(13f61969d59b055a5ab40237148e091d7cabe190) ) ROM_LOAD( "ic94_6", 0x4000, 0x4000, CRC(f33c015c) SHA1(756326daab255d3a36d97e51ee141b9f7157f12e) ) ROM_LOAD( "ic95_7", 0x8000, 0x4000, CRC(0e02c2e8) SHA1(1d8a817ba66cf26a4fe51ae00874c0fe6e7cebe3) ) ROM_LOAD( "ic96_8", 0xc000, 0x4000, CRC(4ef5f073) SHA1(dfd234542b28cff74692a1c381772da01e8bb4a7) ) ROM_REGION( 0x0200, "proms", 0 ) - ROM_LOAD( "a54-10.2", 0x0000, 0x0200, CRC(17dfbd14) SHA1(f8f0b6dfedd4ba108dad43ccc7697ef4ab9cbf86) ) /* unknown */ + ROM_LOAD( "a54-10.2", 0x0000, 0x0200, CRC(17dfbd14) SHA1(f8f0b6dfedd4ba108dad43ccc7697ef4ab9cbf86) ) // unknown ROM_END ROM_START( lkageb4 ) @@ -739,16 +1130,42 @@ ROM_START( lkageb4 ) ROM_REGION( 0x10000, "audiocpu", 0 ) ROM_LOAD( "4.ic54", 0x0000, 0x8000, CRC(541faf9a) SHA1(b142ff3bd198f700697ec06ea92db3109ab5818e) ) - ROM_REGION( 0x4000, "user1", 0 ) + ROM_REGION( 0x4000, "data", 0 ) ROM_LOAD( "a54-03.51", 0x0000, 0x4000, CRC(493e76d8) SHA1(13c6160edd94ba2801fd89bb33bcae3a1e3454ff) ) - ROM_REGION( 0x10000, "gfx1", 0 ) + ROM_REGION( 0x10000, "gfx", 0 ) ROM_LOAD( "5.ic84", 0x0000, 0x4000, CRC(0033c06a) SHA1(89964503fc338817c6511fd15942741996b7037a) ) ROM_LOAD( "6.ic85", 0x4000, 0x4000, CRC(9f04d9ad) SHA1(3b9a4d30348fd02e5c8ae94655548bd4a02dd65d) ) ROM_LOAD( "7.ic86", 0x8000, 0x4000, CRC(b20561a4) SHA1(0d6d83dfae79ea133e37704ca47426b4c978fb36) ) ROM_LOAD( "8.ic87", 0xc000, 0x4000, CRC(3ff3b230) SHA1(ffcd964efb0af32b5d7a70305dfda615ea95acbe) ) ROM_END + +ROM_START( lkage5232 ) + ROM_REGION( 0x10000, "maincpu", ROMREGION_ERASEFF ) // Z80 code + ROM_LOAD( "a51_11-2.ic", 0x0000, 0x4000, CRC(540fdb1f) SHA1(11d2a5b56d6d72458816aaf7687e490126b468cc) ) + ROM_LOAD( "a51_12-2.ic", 0x4000, 0x4000, CRC(a625a4b8) SHA1(417e7590f98eadc71cbed749350d6d3a1c1fd413) ) + ROM_LOAD( "a51_13-2.ic", 0x8000, 0x4000, CRC(aba8c6a3) SHA1(6723138f54a06d3e4719a43e8e3f11b3cabfb6f7) ) + ROM_LOAD( "a51_10-2.ic", 0xc000, 0x2000, CRC(f6243d5c) SHA1(7b2810afe9c128a290f15c6ea1a6a1c2757ddf55) ) + + ROM_REGION( 0x10000, "audiocpu", 0 ) // Z80 code + ROM_LOAD( "a51_01-1.ic", 0x0000, 0x4000, CRC(03c818ba) SHA1(80604726c647495ab76870806cd1fb448cffe34d) ) + ROM_FILL( 0xe000, 0x2000, 0xff ) // diagnostics ROM + + ROM_REGION( 0x10000, "gfx", 0 ) + ROM_LOAD( "a51_03-1.ic", 0x0000, 0x2000, CRC(99847f0a) SHA1(34ea492e82845d0366bd755ddf1cad7f574d867a) ) // tile + ROM_LOAD( "a51_07-1.ic", 0x2000, 0x2000, CRC(c9d01e5b) SHA1(16d689ccc9c3cb16e6b4d85f8e50386c78c439e5) ) // spr + ROM_LOAD( "a51_02-1.ic", 0x4000, 0x2000, CRC(28bbf964) SHA1(67fb767549d7326133c630f424703abe2b14273d) ) // tile + ROM_LOAD( "a51_06-1.ic", 0x6000, 0x2000, CRC(d16c7c95) SHA1(f3cfc995cc072311b3bd831b69ccb229e2734f53) ) // spr + ROM_LOAD( "a51_05-1.ic", 0x8000, 0x2000, CRC(38bb3ad0) SHA1(9c24d705e55acaaa99fbb39e06486ca932bda796) ) // tile + ROM_LOAD( "a51_09-1.ic", 0xa000, 0x2000, CRC(40fd3d86) SHA1(f92156e5e44483b2683457166cb5b9cfc7fbbf14) ) // spr + ROM_LOAD( "a51_04-1.ic", 0xc000, 0x2000, CRC(8e132cc6) SHA1(c7b196e6b8c3b6841a1f4ca0904597085a53cc25) ) // tile + ROM_LOAD( "a51_08-1.ic", 0xe000, 0x2000, CRC(2ab68af8) SHA1(6dd91311f2344936590577440898da5f26e35880) ) // spr + + ROM_REGION( 0x4000, "data", 0 ) + ROM_LOAD( "a51_14.ic", 0x0000, 0x4000, CRC(493e76d8) SHA1(13c6160edd94ba2801fd89bb33bcae3a1e3454ff) ) +ROM_END + /* Bygone Taito, 1985? @@ -840,27 +1257,27 @@ Notes: */ ROM_START( bygone ) - ROM_REGION( 0x14000, "maincpu", 0 ) /* Z80 code (main CPU) */ + ROM_REGION( 0x14000, "maincpu", 0 ) // Z80 code ROM_LOAD( "a53_05.ic37", 0x0000, 0x8000, CRC(63a3f08b) SHA1(781539077cb1d3b8eecc8bd3717330c0f281833d) ) ROM_LOAD( "a53_06.ic38", 0x8000, 0x8000, CRC(cb0dcb08) SHA1(6b12b018b983b8225b5f33fb9fcd8004a00fd8ff) ) - ROM_REGION( 0x10000, "audiocpu", 0 ) /* Z80 code (sound CPU) */ + ROM_REGION( 0x10000, "audiocpu", 0 ) // Z80 code ROM_LOAD( "a53_07.ic54", 0x0000, 0x8000, CRC(72f69a77) SHA1(dfc1050a4123b3c83ae733ece1b6fe2836beb901) ) - ROM_REGION( 0x00800, "bmcu:mcu", 0 ) /* 68705 MCU code */ - ROM_LOAD( "a51_09.ic53", 0x0000, 0x0800, CRC(0e8b8846) SHA1(a4a105462b0127229bb7edfadd2e581c7e40f1cc) ) /* the same as lkage */ + ROM_REGION( 0x00800, "bmcu:mcu", 0 ) // 68705 code + ROM_LOAD( "a51_09.ic53", 0x0000, 0x0800, CRC(0e8b8846) SHA1(a4a105462b0127229bb7edfadd2e581c7e40f1cc) ) // the same as lkage - ROM_REGION( 0x4000, "user1", 0 ) /* data */ + ROM_REGION( 0x4000, "data", 0 ) ROM_LOAD( "a53_08.ic51", 0x0000, 0x4000, CRC(f85139f9) SHA1(7e089d1dd5c5fa8abb396b44aa15aabcf8677940) ) - ROM_REGION( 0x10000, "gfx1", 0 ) + ROM_REGION( 0x10000, "gfx", 0 ) ROM_LOAD( "a53_01.ic84", 0x0000, 0x4000, CRC(38cf7fb2) SHA1(424efabe2386fa5f1c22444a53952d85c05c2d64) ) ROM_LOAD( "a53_02.ic85", 0x4000, 0x4000, CRC(dca7adfe) SHA1(83b159e92dab96d9e20fa3a9d1ce7a7d2e83b313) ) ROM_LOAD( "a53_03.ic86", 0x8000, 0x4000, CRC(af3eb997) SHA1(ba66ffb9d83f91c98446ac38bb0e712ec0800625) ) ROM_LOAD( "a53_04.ic87", 0xc000, 0x4000, CRC(65af72d3) SHA1(759a1dd7548075630ddb9c692bdb32ad4712c579) ) ROM_REGION( 0x0400, "proms", 0 ) - ROM_LOAD( "a54-10.ic2", 0x0000, 0x0400, CRC(369722d9) SHA1(2df9932ad8ce87c0a9d2c89222a4cec12c29046d) ) /* unknown */ + ROM_LOAD( "a54-10.ic2", 0x0000, 0x0400, CRC(369722d9) SHA1(2df9932ad8ce87c0a9d2c89222a4cec12c29046d) ) // unknown ROM_END @@ -881,7 +1298,7 @@ uint8_t lkage_state::fake_mcu_r() switch (m_mcu_val) { - /*These are for the attract mode*/ + // These are for the attract mode case 0x01: result = m_mcu_val - 1; break; @@ -890,7 +1307,7 @@ uint8_t lkage_state::fake_mcu_r() result = m_mcu_val + 0x43; break; - /*Gameplay Protection,checked in this order at a start of a play*/ + // Gameplay Protection, checked in this order at a start of a play case 0xa6: result = m_mcu_val + 0x27; break; @@ -923,19 +1340,33 @@ uint8_t lkage_state::fake_status_r() void lkage_state::init_lkage() { m_sprite_dx = 0; + + m_sprite_offset = 0; } +void lkage5232_state::init_lkage5232() +{ + init_lkage(); + + m_sprite_offset = 24; +} void lkage_state::init_bygone() { m_sprite_dx = 1; + + m_sprite_offset = 0; } -GAME( 1984, lkage, 0, lkage, lkage, lkage_state, init_lkage, ROT0, "Taito Corporation", "The Legend of Kage", MACHINE_NO_COCKTAIL | MACHINE_SUPPORTS_SAVE ) -GAME( 1984, lkageo, lkage, lkage, lkage, lkage_state, init_lkage, ROT0, "Taito Corporation", "The Legend of Kage (older)", MACHINE_NO_COCKTAIL | MACHINE_SUPPORTS_SAVE ) -GAME( 1984, lkageoo, lkage, lkage, lkage, lkage_state, init_lkage, ROT0, "Taito Corporation", "The Legend of Kage (oldest)", MACHINE_NO_COCKTAIL | MACHINE_SUPPORTS_SAVE ) -GAME( 1984, lkageb, lkage, lkageb, lkageb, lkage_state, init_lkage, ROT0, "bootleg", "The Legend of Kage (bootleg set 1)", MACHINE_NO_COCKTAIL | MACHINE_SUPPORTS_SAVE ) -GAME( 1984, lkageb2, lkage, lkageb, lkageb, lkage_state, init_lkage, ROT0, "bootleg", "The Legend of Kage (bootleg set 2)", MACHINE_NO_COCKTAIL | MACHINE_SUPPORTS_SAVE ) -GAME( 1984, lkageb3, lkage, lkageb, lkageb, lkage_state, init_lkage, ROT0, "bootleg", "The Legend of Kage (bootleg set 3)", MACHINE_NO_COCKTAIL | MACHINE_SUPPORTS_SAVE ) -GAME( 1984, lkageb4, lkage, lkageb, lkageb, lkage_state, init_lkage, ROT0, "bootleg", "The Legend of Kage (bootleg set 4)", MACHINE_NO_COCKTAIL | MACHINE_SUPPORTS_SAVE ) -GAME( 1985, bygone, 0, lkage, bygone, lkage_state, init_bygone, ROT0, "Taito Corporation", "Bygone (prototype)", MACHINE_IMPERFECT_SOUND | MACHINE_IMPERFECT_GRAPHICS | MACHINE_NO_COCKTAIL | MACHINE_SUPPORTS_SAVE ) +} // anonymous namespace + + +GAME( 1984, lkage, 0, lkage, lkage, lkage_state, init_lkage, ROT0, "Taito Corporation", "The Legend of Kage", MACHINE_NO_COCKTAIL | MACHINE_SUPPORTS_SAVE ) +GAME( 1984, lkageo, lkage, lkage, lkage, lkage_state, init_lkage, ROT0, "Taito Corporation", "The Legend of Kage (older)", MACHINE_NO_COCKTAIL | MACHINE_SUPPORTS_SAVE ) +GAME( 1984, lkageoo, lkage, lkage, lkage, lkage_state, init_lkage, ROT0, "Taito Corporation", "The Legend of Kage (oldest)", MACHINE_NO_COCKTAIL | MACHINE_SUPPORTS_SAVE ) +GAME( 1984, lkageb, lkage, lkageb, lkageb, lkage_state, init_lkage, ROT0, "bootleg", "The Legend of Kage (bootleg set 1)", MACHINE_NO_COCKTAIL | MACHINE_SUPPORTS_SAVE ) +GAME( 1984, lkageb2, lkage, lkageb, lkageb, lkage_state, init_lkage, ROT0, "bootleg", "The Legend of Kage (bootleg set 2)", MACHINE_NO_COCKTAIL | MACHINE_SUPPORTS_SAVE ) +GAME( 1984, lkageb3, lkage, lkageb, lkageb, lkage_state, init_lkage, ROT0, "bootleg", "The Legend of Kage (bootleg set 3)", MACHINE_NO_COCKTAIL | MACHINE_SUPPORTS_SAVE ) +GAME( 1984, lkageb4, lkage, lkageb, lkageb, lkage_state, init_lkage, ROT0, "bootleg", "The Legend of Kage (bootleg set 4)", MACHINE_NO_COCKTAIL | MACHINE_SUPPORTS_SAVE ) +GAME( 1984, lkage5232, lkage, lkage5232, lkage, lkage5232_state, init_lkage5232, ROT0, "Taito Corporation", "The Legend of Kage (MSM5232 version)", MACHINE_NOT_WORKING | MACHINE_NO_COCKTAIL | MACHINE_SUPPORTS_SAVE ) // attract is broken, reads and writes from/to MCU addresses +GAME( 1985, bygone, 0, lkage, bygone, lkage_state, init_bygone, ROT0, "Taito Corporation", "Bygone (prototype)", MACHINE_IMPERFECT_SOUND | MACHINE_IMPERFECT_GRAPHICS | MACHINE_NO_COCKTAIL | MACHINE_SUPPORTS_SAVE ) diff --git a/src/mame/taito/lkage.h b/src/mame/taito/lkage.h deleted file mode 100644 index 13d0551d386..00000000000 --- a/src/mame/taito/lkage.h +++ /dev/null @@ -1,95 +0,0 @@ -// license:BSD-3-Clause -// copyright-holders:Phil Stroffolino -#ifndef MAME_TAITO_LKAGE_H -#define MAME_TAITO_LKAGE_H - -#pragma once - -#include "taito68705.h" - -#include "machine/gen_latch.h" -#include "machine/input_merger.h" -#include "emupal.h" -#include "tilemap.h" - -class lkage_state : public driver_device -{ -public: - lkage_state(const machine_config &mconfig, device_type type, const char *tag) : - driver_device(mconfig, type, tag), - m_vreg(*this, "vreg"), - m_scroll(*this, "scroll"), - m_spriteram(*this, "spriteram"), - m_videoram(*this, "videoram"), - m_maincpu(*this, "maincpu"), - m_audiocpu(*this, "audiocpu"), - m_bmcu(*this, "bmcu"), - m_gfxdecode(*this, "gfxdecode"), - m_palette(*this, "palette"), - m_soundlatch(*this, "soundlatch"), - m_soundnmi(*this, "soundnmi") - { } - - void lkageb(machine_config &config); - void lkage(machine_config &config); - - void init_bygone(); - void init_lkage(); - -protected: - virtual void machine_start() override; - virtual void machine_reset() override; - virtual void video_start() override; - -private: - required_shared_ptr m_vreg; - required_shared_ptr m_scroll; - required_shared_ptr m_spriteram; - required_shared_ptr m_videoram; - - /* video-related */ - tilemap_t *m_bg_tilemap = nullptr; - tilemap_t *m_fg_tilemap = nullptr; - tilemap_t *m_tx_tilemap = nullptr; - uint8_t m_bg_tile_bank = 0U; - uint8_t m_fg_tile_bank = 0U; - uint8_t m_tx_tile_bank = 0U; - - int m_sprite_dx = 0; - - /* lkageb fake mcu */ - uint8_t m_mcu_val = 0U; - int m_mcu_ready = 0; /* cpu data/mcu ready status */ - - /* devices */ - required_device m_maincpu; - required_device m_audiocpu; - optional_device m_bmcu; - required_device m_gfxdecode; - required_device m_palette; - required_device m_soundlatch; - required_device m_soundnmi; - - void lkage_sh_nmi_disable_w(uint8_t data); - void lkage_sh_nmi_enable_w(uint8_t data); - uint8_t sound_status_r(); - uint8_t port_fetch_r(offs_t offset); - uint8_t mcu_status_r(); - uint8_t fake_mcu_r(); - void fake_mcu_w(uint8_t data); - uint8_t fake_status_r(); - - void lkage_videoram_w(offs_t offset, uint8_t data); - TILE_GET_INFO_MEMBER(get_bg_tile_info); - TILE_GET_INFO_MEMBER(get_fg_tile_info); - TILE_GET_INFO_MEMBER(get_tx_tile_info); - uint32_t screen_update_lkage(screen_device &screen, bitmap_ind16 &bitmap, const rectangle &cliprect); - void draw_sprites( screen_device &screen, bitmap_ind16 &bitmap, const rectangle &cliprect ); - void lkage_io_map(address_map &map); - void lkage_map(address_map &map); - void lkage_map_boot(address_map &map); - void lkage_map_mcu(address_map &map); - void lkage_sound_map(address_map &map); -}; - -#endif // MAME_TAITO_LKAGE_H diff --git a/src/mame/taito/lkage_v.cpp b/src/mame/taito/lkage_v.cpp deleted file mode 100644 index 45d065c9a3a..00000000000 --- a/src/mame/taito/lkage_v.cpp +++ /dev/null @@ -1,225 +0,0 @@ -// license:BSD-3-Clause -// copyright-holders:Phil Stroffolino -/*************************************************************************** - - video/lkage.c - - - lkage_scroll[0x00]: text layer horizontal scroll - lkage_scroll[0x01]: text layer vertical scroll - lkage_scroll[0x02]: foreground layer horizontal scroll - lkage_scroll[0x03]: foreground layer vertical scroll - lkage_scroll[0x04]: background layer horizontal scroll - lkage_scroll[0x05]: background layer vertical scroll - - lkage_vreg[0]: 0x00,0x04 - 0x02: tx tile bank select (bygone only?) - 0x04: fg tile bank select - 0x08: ? - - lkage_vreg[1]: 0x7d - 0xf0: background/foreground palette select - 0x08: bg tile bank select - 0x07: priority config? - - lkage_vreg[2]: 0xf3 - 0x03: flip screen x/y - 0xf0: normally 1111, but 1001 and 0001 inbetween stages (while the - backgrounds are are being redrawn). These bits are probably used to enable - individual layers, but we have no way of knowing the mapping. - - lkage_vreg: - 04 7d f3 : title screen 101 - 0c 7d f3 : high score 101 - 04 06 f3 : attract#1 110 - 04 1e f3 : attract#2 110 - 04 1e f3 : attract#3 110 - 00 4e f3 : attract#4 110 - - -***************************************************************************/ - -#include "emu.h" -#include "lkage.h" -#include "screen.h" - - -void lkage_state::lkage_videoram_w(offs_t offset, uint8_t data) -{ - m_videoram[offset] = data; - - switch (offset / 0x400) - { - case 0: - m_tx_tilemap->mark_tile_dirty(offset & 0x3ff); - break; - - case 1: - m_fg_tilemap->mark_tile_dirty(offset & 0x3ff); - break; - - case 2: - m_bg_tilemap->mark_tile_dirty(offset & 0x3ff); - break; - - default: - break; - } -} - -TILE_GET_INFO_MEMBER(lkage_state::get_bg_tile_info) -{ - int code = m_videoram[tile_index + 0x800] + 256 * (m_bg_tile_bank ? 5 : 1); - tileinfo.set(0/*gfx*/, code, 0/*color*/, 0/*flags*/ ); -} - -TILE_GET_INFO_MEMBER(lkage_state::get_fg_tile_info) -{ - int code = m_videoram[tile_index + 0x400] + 256 * (m_fg_tile_bank ? 1 : 0); - tileinfo.set(0/*gfx*/, code, 0/*color*/, 0/*flags*/); -} - -TILE_GET_INFO_MEMBER(lkage_state::get_tx_tile_info) -{ - int code = m_videoram[tile_index] + 256 * (m_tx_tile_bank ? 4 : 0); - tileinfo.set(0/*gfx*/, code, 0/*color*/, 0/*flags*/); -} - -void lkage_state::video_start() -{ - m_bg_tilemap = &machine().tilemap().create(*m_gfxdecode, tilemap_get_info_delegate(*this, FUNC(lkage_state::get_bg_tile_info)), TILEMAP_SCAN_ROWS, 8, 8, 32, 32); - m_fg_tilemap = &machine().tilemap().create(*m_gfxdecode, tilemap_get_info_delegate(*this, FUNC(lkage_state::get_fg_tile_info)), TILEMAP_SCAN_ROWS, 8, 8, 32, 32); - m_tx_tilemap = &machine().tilemap().create(*m_gfxdecode, tilemap_get_info_delegate(*this, FUNC(lkage_state::get_tx_tile_info)), TILEMAP_SCAN_ROWS, 8, 8, 32, 32); - - m_fg_tilemap->set_transparent_pen(0); - m_tx_tilemap->set_transparent_pen(0); - - m_bg_tilemap->set_scrolldx(-5, -5 + 24); - m_fg_tilemap->set_scrolldx(-3, -3 + 24); - m_tx_tilemap->set_scrolldx(-1, -1 + 24); -} - - -void lkage_state::draw_sprites( screen_device &screen, bitmap_ind16 &bitmap, const rectangle &cliprect ) -{ - const uint8_t *source = m_spriteram; - const uint8_t *finish = source + 0x60; - - while (source < finish) - { - int attributes = source[2]; - /* 0x01: horizontal flip - * 0x02: vertical flip - * 0x04: bank select - * 0x08: sprite size - * 0x70: color - * 0x80: priority - */ - int priority_mask = 0; - int color = (attributes >> 4) & 7; - int flipx = attributes & 0x01; - int flipy = attributes & 0x02; - int height = (attributes & 0x08) ? 2 : 1; - int sx = source[0] - 15 + m_sprite_dx; - int sy = 256 - 16 * height - source[1]; - int sprite_number = source[3] + ((attributes & 0x04) << 6); - int y; - - if (attributes & 0x80) - { - priority_mask = (0xf0 | 0xcc); - } - else - { - priority_mask = 0xf0; - } - - if (flip_screen_x()) - { - sx = 239 - sx - 24; - flipx = !flipx; - } - if (flip_screen_y()) - { - sy = 254 - 16 * height - sy; - flipy = !flipy; - } - if (height == 2 && !flipy) - { - sprite_number ^= 1; - } - - for (y = 0; y < height; y++) - { - m_gfxdecode->gfx(1)->prio_transpen( - bitmap, - cliprect, - sprite_number ^ y, - color, - flipx,flipy, - sx&0xff, - sy + 16*y, - screen.priority(), - priority_mask,0 ); - } - source += 4; - } -} - -uint32_t lkage_state::screen_update_lkage(screen_device &screen, bitmap_ind16 &bitmap, const rectangle &cliprect) -{ - int bank; - - flip_screen_x_set(~m_vreg[2] & 0x01); - flip_screen_y_set(~m_vreg[2] & 0x02); - - bank = m_vreg[1] & 0x08; - - if (m_bg_tile_bank != bank) - { - m_bg_tile_bank = bank; - m_bg_tilemap->mark_all_dirty(); - } - - bank = m_vreg[0]&0x04; - if (m_fg_tile_bank != bank) - { - m_fg_tile_bank = bank; - m_fg_tilemap->mark_all_dirty(); - } - - bank = m_vreg[0]&0x02; - if (m_tx_tile_bank != bank) - { - m_tx_tile_bank = bank; - m_tx_tilemap->mark_all_dirty(); - } - - m_bg_tilemap->set_palette_offset(0x300 + (m_vreg[1] & 0xf0)); - m_fg_tilemap->set_palette_offset(0x200 + (m_vreg[1] & 0xf0)); - m_tx_tilemap->set_palette_offset(0x110); - - m_tx_tilemap->set_scrollx(0, m_scroll[0]); - m_tx_tilemap->set_scrolly(0, m_scroll[1]); - - m_fg_tilemap->set_scrollx(0, m_scroll[2]); - m_fg_tilemap->set_scrolly(0, m_scroll[3]); - - m_bg_tilemap->set_scrollx(0, m_scroll[4]); - m_bg_tilemap->set_scrolly(0, m_scroll[5]); - - screen.priority().fill(0, cliprect); - if ((m_vreg[2] & 0xf0) == 0xf0) - { - m_bg_tilemap->draw(screen, bitmap, cliprect, 0, 1); - m_fg_tilemap->draw(screen, bitmap, cliprect, 0, (m_vreg[1] & 2) ? 2 : 4); - m_tx_tilemap->draw(screen, bitmap, cliprect, 0, 4); - draw_sprites(screen, bitmap, cliprect); - } - else - { - m_tx_tilemap->draw(screen, bitmap, cliprect, TILEMAP_DRAW_OPAQUE, 0); - } - - return 0; -}