From 196a342ae44ce98c8823d4872b8e331e567dfd17 Mon Sep 17 00:00:00 2001 From: David Haywood <28625134+DavidHaywood@users.noreply.github.com> Date: Tue, 30 Mar 2021 14:13:02 +0100 Subject: [PATCH] Refactoring and bug fixes for bbusters and mechatt: (#7902) * Moved sprite handling to a device. * Adjusted audio balance on mechatt (channel 0 was overpowering everything). * Adjusted priority handing on mechatt (planes now correctly rise from underground hanger on stage 3, train carts in later level). * Split driver in two, general refactoring etc. * Removed player 2 inputs from mechattu1 - it doesn't respond to them at all. --- scripts/target/mame/arcade.lua | 5 +- src/mame/arcade.flt | 1 + src/mame/drivers/bbusters.cpp | 829 +++++++++------------------- src/mame/drivers/mechatt.cpp | 731 ++++++++++++++++++++++++ src/mame/includes/bbusters.h | 115 ---- src/mame/mame.lst | 10 +- src/mame/video/bbusters.cpp | 297 ---------- src/mame/video/snk_bbusters_spr.cpp | 222 ++++++++ src/mame/video/snk_bbusters_spr.h | 42 ++ 9 files changed, 1253 insertions(+), 999 deletions(-) create mode 100644 src/mame/drivers/mechatt.cpp delete mode 100644 src/mame/includes/bbusters.h delete mode 100644 src/mame/video/bbusters.cpp create mode 100644 src/mame/video/snk_bbusters_spr.cpp create mode 100644 src/mame/video/snk_bbusters_spr.h diff --git a/scripts/target/mame/arcade.lua b/scripts/target/mame/arcade.lua index 78e0f077993..ad97618dced 100644 --- a/scripts/target/mame/arcade.lua +++ b/scripts/target/mame/arcade.lua @@ -3860,8 +3860,9 @@ files { createMAMEProjects(_target, _subtarget, "snk") files { MAME_DIR .. "src/mame/drivers/bbusters.cpp", - MAME_DIR .. "src/mame/includes/bbusters.h", - MAME_DIR .. "src/mame/video/bbusters.cpp", + MAME_DIR .. "src/mame/drivers/mechatt.cpp", + MAME_DIR .. "src/mame/video/snk_bbusters_spr.cpp", + MAME_DIR .. "src/mame/video/snk_bbusters_spr.h", MAME_DIR .. "src/mame/drivers/dmndrby.cpp", MAME_DIR .. "src/mame/drivers/hng64.cpp", MAME_DIR .. "src/mame/includes/hng64.h", diff --git a/src/mame/arcade.flt b/src/mame/arcade.flt index 868d838a6b0..cdc69cb9317 100644 --- a/src/mame/arcade.flt +++ b/src/mame/arcade.flt @@ -751,6 +751,7 @@ mcr3.cpp mcr68.cpp meadows.cpp meadwttl.cpp +mechatt.cpp mediagx.cpp megadriv_acbl.cpp megaphx.cpp diff --git a/src/mame/drivers/bbusters.cpp b/src/mame/drivers/bbusters.cpp index bc61630c89d..c6ed0e40d12 100644 --- a/src/mame/drivers/bbusters.cpp +++ b/src/mame/drivers/bbusters.cpp @@ -3,25 +3,19 @@ /*************************************************************************** Beast Busters A9003 (c) 1989 SNK Corporation - Mechanized Attack A8002 (c) 1989 SNK Corporation Beast Busters is a large dedicated (non-jamma) triple machine gun game, the gun positions values are read in an interrupt routine that must be called for each position (X and Y for 3 guns, so at least 6 times a frame). - Mechanized Attack (A8002) is an earlier design, it only has one sprite - chip, no eeprom, and only 2 machine guns, but the tilemaps are twice - the size. + ---------------------------------------------------------------------------------------- - Emulation by Bryan McPhail, mish@tendril.co.uk + Stephh's notes (based on the games M68000 code and some tests) : + 1) 'bbusters' -Stephh's notes (based on the games M68000 code and some tests) : - -1) 'bbusters' - - - Country/version is stored at 0x003954.w and the possible values are + - Country/version is stored at 0x003954.w and the possible values are 0x0000, 0x0004 and 0x0008 (0x000c being the same as 0x0008), 0x0008 being the value stored in ROM in the current set. I haven't noticed any major effect (copyright/logo, language, coinage), @@ -32,155 +26,52 @@ Stephh's notes (based on the games M68000 code and some tests) : Anyway, here is my guess to determine the versions (by using some infos from 'mechatt' : - Value Country - 0x0000 Japan - 0x0004 US? - 0x0008 World? (value stored in the current set) - 0x000c World? (same as 0x0008 - impossible choice ?) + Value Country + 0x0000 Japan + 0x0004 US? + 0x0008 World? (value stored in the current set) + 0x000c World? (same as 0x0008 - impossible choice ?) - - Coin buttons act differently depending on the "Coin Slots" Dip Switch : + - Coin buttons act differently depending on the "Coin Slots" Dip Switch : - * "Coin Slots" Dip Switch set to "Common" : + * "Coin Slots" Dip Switch set to "Common" : - . COIN1 : adds coin(s)/credit(s) depending on "Coin A" Dip Switch - . COIN2 : adds coin(s)/credit(s) depending on "Coin B" Dip Switch - . COIN3 : NO EFFECT ! - . COIN4 : NO EFFECT ! - . COIN5 : NO EFFECT ! - . COIN6 : NO EFFECT ! - . SERVICE1 : adds coin(s)/credit(s) depending on "Coin A" Dip Switch + . COIN1 : adds coin(s)/credit(s) depending on "Coin A" Dip Switch + . COIN2 : adds coin(s)/credit(s) depending on "Coin B" Dip Switch + . COIN3 : NO EFFECT ! + . COIN4 : NO EFFECT ! + . COIN5 : NO EFFECT ! + . COIN6 : NO EFFECT ! + . SERVICE1 : adds coin(s)/credit(s) depending on "Coin A" Dip Switch - * "Coin Slots" Dip Switch set to "Individual" : + * "Coin Slots" Dip Switch set to "Individual" : - . COIN1 : adds coin(s)/credit(s) for player 1 depending on "Coin A" Dip Switch - . COIN2 : adds coin(s)/credit(s) for player 1 depending on "Coin B" Dip Switch - . COIN3 : adds coin(s)/credit(s) for player 2 depending on "Coin A" Dip Switch - . COIN4 : adds coin(s)/credit(s) for player 2 depending on "Coin B" Dip Switch - . COIN5 : adds coin(s)/credit(s) for player 3 depending on "Coin A" Dip Switch - . COIN6 : adds coin(s)/credit(s) for player 3 depending on "Coin B" Dip Switch - . SERVICE1 : adds coin(s)/credit(s) for all players depending on "Coin A" Dip Switch + . COIN1 : adds coin(s)/credit(s) for player 1 depending on "Coin A" Dip Switch + . COIN2 : adds coin(s)/credit(s) for player 1 depending on "Coin B" Dip Switch + . COIN3 : adds coin(s)/credit(s) for player 2 depending on "Coin A" Dip Switch + . COIN4 : adds coin(s)/credit(s) for player 2 depending on "Coin B" Dip Switch + . COIN5 : adds coin(s)/credit(s) for player 3 depending on "Coin A" Dip Switch + . COIN6 : adds coin(s)/credit(s) for player 3 depending on "Coin B" Dip Switch + . SERVICE1 : adds coin(s)/credit(s) for all players depending on "Coin A" Dip Switch Note that I had to map COIN5 and COIN6 to SERVICE2 and SERVICE3 to be able to use the default parametrable keys. Let me know if there is a another (better ?) way to do so. + ---------------------------------------------------------------------------------------- -2) 'mechatt' + RansAckeR's notes: - - Country/version is stored at 0x06a000.w and the possible values are : + bbusters: - Value Country - 0x0000 Japan - 0x1111 World (value stored in the current set) - 0x2222 US - 0x3333 Asia? (it looks like Japanese text but some "symbols" are missing) + If you only calibrate the P1 gun or do not hit the correct spots for all guns + you will get either garbage or a black screen when rebooting. + According to the manual this happens when the eprom contains invalid gun aim data. -2a) Japan version - - - All texts are in Japanese. - - "(c) 1989 (Corp) S-N-K". - - "Coin Slots" Dip Switch has no effect. - - "Coin A" and "Coin B" Dip Switches are the same as in the World version. - - Coin buttons effect : - - * "Coin Slots" are ALWAYS considered as "Common" : - - . COIN1 : adds coin(s)/credit(s) depending on "Coin A" Dip Switch - . COIN2 : adds coin(s)/credit(s) depending on "Coin B" Dip Switch - . COIN3 : NO EFFECT ! - . COIN4 : NO EFFECT ! - . SERVICE1 : adds coin(s)/credit(s) depending on "Coin A" Dip Switch - -2b) World version - - - All texts are in English. - - "(c) 1989 SNK Corporation". - - Coin buttons effect : - - * "Coin Slots" Dip Switch set to "Common" : - - . COIN1 : adds coin(s)/credit(s) depending on "Coin A" Dip Switch - . COIN2 : adds coin(s)/credit(s) depending on "Coin B" Dip Switch - . COIN3 : NO EFFECT ! - . COIN4 : NO EFFECT ! - . SERVICE1 : adds coin(s)/credit(s) depending on "Coin A" Dip Switch - - * "Coin Slots" Dip Switch set to "Individual" : - - . COIN1 : adds coin(s)/credit(s) for player 1 depending on "Coin A" Dip Switch - . COIN2 : adds coin(s)/credit(s) for player 1 depending on "Coin B" Dip Switch - . COIN3 : adds coin(s)/credit(s) for player 2 depending on "Coin A" Dip Switch - . COIN4 : adds coin(s)/credit(s) for player 2 depending on "Coin B" Dip Switch - . SERVICE1 : adds coin(s)/credit(s) for all players depending on "Coin A" Dip Switch - -2c) US version - - - All texts are in English. - - "(c) 1989 SNK Corp. of America". - - Additional FBI logo as first screen as well as small FBI notice at the bottom left - of the screens until a coin is inserted. - - "Coin Slots" Dip Switch has no effect. - - "Coin A" Dip Switch is different from the World version : - - World US - 4C_1C "Free Play" - 3C_1C special (see below) - 2C_1C "2 Coins to Start, 1 to Continue" - 1C_1C 1C_1C - - It's a bit hard to explain the "special" coinage, so here are some infos : - - * when you insert a coin before starting a game, you are awarded 2 credits - if credits == 0, else you are awarded 1 credit - * when you insert a coin to continue, you are ALWAYS awarded 1 credit - - - "Coin B" Dip Switch has no effect. - - - Coin buttons effect : - - * "Coin Slots" are ALWAYS considered as "Individual" : - - . COIN1 : adds coin(s)/credit(s) for player 1 depending on "Coin A" Dip Switch - . COIN2 : adds coin(s)/credit(s) for player 2 depending on "Coin A" Dip Switch - . COIN3 : NO EFFECT ! - . COIN4 : NO EFFECT ! - . SERVICE1 : adds coin(s)/credit(s) for all players depending on "Coin A" Dip Switch - -2d) Asia? version - - - All texts are in Japanese ? (to be confirmed) - - "(c) 1989 SNK Corporation". - - "Coin Slots" Dip Switch has no effect. - - "Coin A" and "Coin B" Dip Switches are the same as in the World version. - - Coin buttons effect : - - * "Coin Slots" are ALWAYS considered as "Common" : - - . COIN1 : adds coin(s)/credit(s) depending on "Coin A" Dip Switch - . COIN2 : adds coin(s)/credit(s) depending on "Coin B" Dip Switch - . COIN3 : NO EFFECT ! - . COIN4 : NO EFFECT ! - . SERVICE1 : adds coin(s)/credit(s) depending on "Coin A" Dip Switch - - - -HIGHWAYMAN's notes: - -after adding the mechanized attack u.s. roms I suspect that there is more than just a few bytes changed ;-) - - -RansAckeR's notes: - -bbusters: - -If you only calibrate the P1 gun or do not hit the correct spots for all guns -you will get either garbage or a black screen when rebooting. -According to the manual this happens when the eprom contains invalid gun aim data. - -If you calibrate the guns correctly the game runs as expected: -1) Using P1 controls fire at the indicated spots. -2) Using P2 controls fire at the indicated spots. -3) Using P3 controls fire at the indicated spots. + If you calibrate the guns correctly the game runs as expected: + 1) Using P1 controls fire at the indicated spots. + 2) Using P2 controls fire at the indicated spots. + 3) Using P3 controls fire at the indicated spots. The locations of the shots fired in attract mode are defined by a table starting at $65000. The value taken from there is combined with data from @@ -192,66 +83,116 @@ If you calibrate the guns correctly the game runs as expected: in the order: Minimum axis 0, middle axis 0, maximum axis 0 (repeat for the other 5 axes). + ---------------------------------------------------------------------------------------- + + Beast Busters Region code works as follows + + ROM[0x003954/2] = data * 4; + + Country/Version : + + - 0x0000 : Japan? + - 0x0004 : US? + - 0x0008 : World? (default) + - 0x000c : World? (same as 0x0008) + ***************************************************************************/ #include "emu.h" -#include "includes/bbusters.h" -#include "cpu/z80/z80.h" +// src/mame +#include "video/snk_bbusters_spr.h" +// src/devices #include "cpu/m68000/m68000.h" +#include "cpu/z80/z80.h" +#include "machine/gen_latch.h" #include "machine/nvram.h" #include "machine/upd7004.h" -#include "sound/ym2608.h" #include "sound/ym2610.h" +#include "video/bufsprite.h" +// src/emu #include "emupal.h" #include "screen.h" #include "speaker.h" +#include "tilemap.h" +class bbusters_state : public driver_device +{ +public: + bbusters_state(const machine_config &mconfig, device_type type, const char *tag) : + driver_device(mconfig, type, tag), + m_maincpu(*this, "maincpu"), + m_audiocpu(*this, "audiocpu"), + m_screen(*this, "screen"), + m_gfxdecode(*this, "gfxdecode"), + m_sprites(*this, "sprites%u", 1U), + m_spriteram(*this, "spriteram%u", 1U), + m_soundlatch(*this, "soundlatch%u", 1U), + m_tx_videoram(*this, "tx_videoram"), + m_pf_data(*this, "pf%u_data", 1U), + m_pf_scroll_data(*this, "pf%u_scroll_data", 1U), + m_gun_recoil(*this, "Player%u_Gun_Recoil", 1U), + m_eprom_data(*this, "eeprom") + { } -/******************************************************************************/ + void bbusters(machine_config &config); +protected: + virtual void machine_start() override; + virtual void video_start() override; -/* Beast Busters Region code works as follows +private: + required_device m_maincpu; + required_device m_audiocpu; + required_device m_screen; + required_device m_gfxdecode; + required_device_array m_sprites; + required_device_array m_spriteram; + required_device_array m_soundlatch; -ROM[0x003954/2] = data * 4; + required_shared_ptr m_tx_videoram; + required_shared_ptr_array m_pf_data; + required_shared_ptr_array m_pf_scroll_data; -Country/Version : + output_finder<3> m_gun_recoil; + required_shared_ptr m_eprom_data; - - 0x0000 : Japan? - - 0x0004 : US? - - 0x0008 : World? (default) - - 0x000c : World? (same as 0x0008) + tilemap_t *m_fix_tilemap; + tilemap_t *m_pf_tilemap[2]; -*/ + TILE_GET_INFO_MEMBER(get_tile_info); + template TILE_GET_INFO_MEMBER(get_pf_tile_info); -/* Mech Attack Region code works as follows + void sound_cpu_w(uint8_t data); + void video_w(offs_t offset, uint16_t data, uint16_t mem_mask = ~0); + template void pf_w(offs_t offset, uint16_t data, uint16_t mem_mask = ~0); + void coin_counter_w(uint8_t data); -ROM[0x06a000/2] = (data << 12) | (data << 8) | (data << 4) | (data << 0); + void bbusters_map(address_map &map); + void sound_map(address_map &map); + void sound_portmap(address_map &map); -Country : -- 0x0000 : Japan -- 0x1111 : World (default) -- 0x2222 : US -- 0x3333 : Asia? + uint16_t eprom_r(offs_t offset); + void three_gun_output_w(uint16_t data); -*/ + void mixlow(bitmap_ind16 &bitmap, bitmap_ind16 &srcbitmap, const rectangle &cliprect); + void mix(bitmap_ind16 &bitmap, bitmap_ind16 &srcbitmap, const rectangle &cliprect); + template + void mix_sprites(bitmap_ind16 &bitmap, bitmap_ind16 &srcbitmap, const rectangle &cliprect, Proc MIX); -/******************************************************************************/ + bitmap_ind16 m_bitmap_sprites[2]; + uint32_t screen_update(screen_device &screen, bitmap_ind16 &bitmap, const rectangle &cliprect); +}; -void bbusters_state_base::machine_start() +void bbusters_state::machine_start() { m_gun_recoil.resolve(); } -void bbusters_state::machine_start() +void bbusters_state::sound_cpu_w(uint8_t data) { - bbusters_state_base::machine_start(); -} - -void bbusters_state_base::sound_cpu_w(uint8_t data) -{ - m_soundlatch[0]->write(data&0xff); + m_soundlatch[0]->write(data); m_audiocpu->pulse_input_line(INPUT_LINE_NMI, attotime::zero); } @@ -268,25 +209,113 @@ void bbusters_state::three_gun_output_w(uint16_t data) } template -void bbusters_state_base::pf_w(offs_t offset, uint16_t data, uint16_t mem_mask) +void bbusters_state::pf_w(offs_t offset, uint16_t data, uint16_t mem_mask) { COMBINE_DATA(&m_pf_data[Layer][offset]); m_pf_tilemap[Layer]->mark_tile_dirty(offset); } -void bbusters_state_base::coin_counter_w(uint8_t data) +void bbusters_state::coin_counter_w(uint8_t data) { machine().bookkeeping().coin_counter_w(0, BIT(data, 0)); machine().bookkeeping().coin_counter_w(1, BIT(data, 1)); } + +TILE_GET_INFO_MEMBER(bbusters_state::get_tile_info) +{ + uint16_t tile = m_tx_videoram[tile_index]; + + tileinfo.set(0,tile&0xfff,tile>>12,0); +} + +template +TILE_GET_INFO_MEMBER(bbusters_state::get_pf_tile_info) +{ + uint16_t tile = m_pf_data[Layer][tile_index]; + + tileinfo.set(Gfx,tile&0xfff,tile>>12,0); +} + +void bbusters_state::video_w(offs_t offset, uint16_t data, uint16_t mem_mask) +{ + COMBINE_DATA(&m_tx_videoram[offset]); + m_fix_tilemap->mark_tile_dirty(offset); +} + +/******************************************************************************/ + + +void bbusters_state::video_start() +{ + m_fix_tilemap = &machine().tilemap().create(*m_gfxdecode, tilemap_get_info_delegate(*this, FUNC(bbusters_state::get_tile_info)), TILEMAP_SCAN_ROWS, 8, 8, 32, 32); + m_fix_tilemap->set_transparent_pen(15); + + m_pf_tilemap[0] = &machine().tilemap().create(*m_gfxdecode, tilemap_get_info_delegate(*this, NAME((&bbusters_state::get_pf_tile_info<0, 1>))), TILEMAP_SCAN_COLS, 16, 16, 128, 32); + m_pf_tilemap[1] = &machine().tilemap().create(*m_gfxdecode, tilemap_get_info_delegate(*this, NAME((&bbusters_state::get_pf_tile_info<1, 2>))), TILEMAP_SCAN_COLS, 16, 16, 128, 32); + + m_pf_tilemap[0]->set_transparent_pen(15); + + for (int i = 0; i < 2; i++) + { + m_screen->register_screen_bitmap(m_bitmap_sprites[i]); + m_bitmap_sprites[i].fill(0xffff); + } + +} + +/******************************************************************************/ + +/******************************************************************************/ + +template +void bbusters_state::mix_sprites(bitmap_ind16 &bitmap, bitmap_ind16 &srcbitmap, const rectangle &cliprect, Proc MIX) +{ + for (int y = cliprect.min_y; y <= cliprect.max_y; y++) + { + uint16_t* srcbuf = &srcbitmap.pix(y); + uint16_t* dstbuf = &bitmap.pix(y); + for (int x = cliprect.min_x; x <= cliprect.max_x; x++) + { + uint16_t srcdat = srcbuf[x]; + if ((srcdat & 0xf) != 0xf) + MIX(srcdat, x, dstbuf); + } + } +} + +uint32_t bbusters_state::screen_update(screen_device &screen, bitmap_ind16 &bitmap, const rectangle &cliprect) +{ + m_bitmap_sprites[0].fill(0xffff); + m_bitmap_sprites[1].fill(0xffff); + m_sprites[1]->draw_sprites(m_bitmap_sprites[1], cliprect); + m_sprites[0]->draw_sprites(m_bitmap_sprites[0], cliprect); + + m_pf_tilemap[0]->set_scrollx(0, m_pf_scroll_data[0][0]); + m_pf_tilemap[0]->set_scrolly(0, m_pf_scroll_data[0][1]); + m_pf_tilemap[1]->set_scrollx(0, m_pf_scroll_data[1][0]); + m_pf_tilemap[1]->set_scrolly(0, m_pf_scroll_data[1][1]); + + m_pf_tilemap[1]->draw(screen, bitmap, cliprect, 0, 0); + + // Palettes 0xc-0xf confirmed to be behind tilemap on Beast Busters for 2nd sprite chip (elevator stage) + mix_sprites(bitmap, m_bitmap_sprites[1], cliprect, [](uint16_t srcdat, uint16_t x, uint16_t* dstbuf) { if ((srcdat & 0xc0) == 0xc0) dstbuf[x] = srcdat + 512; } ); + m_pf_tilemap[0]->draw(screen, bitmap, cliprect, 0, 2); + mix_sprites(bitmap, m_bitmap_sprites[1], cliprect, [](uint16_t srcdat, uint16_t x, uint16_t* dstbuf) { if ((srcdat & 0xc0) != 0xc0) dstbuf[x] = srcdat + 512; } ); + mix_sprites(bitmap, m_bitmap_sprites[0], cliprect, [](uint16_t srcdat, uint16_t x, uint16_t* dstbuf) { dstbuf[x] = srcdat + 256; } ); + + m_fix_tilemap->draw(screen, bitmap, cliprect, 0, 0); + + return 0; +} + /*******************************************************************************/ void bbusters_state::bbusters_map(address_map &map) { map(0x000000, 0x07ffff).rom(); map(0x080000, 0x08ffff).ram().share("ram"); - map(0x090000, 0x090fff).ram().w(FUNC(bbusters_state::video_w)).share("videoram"); + map(0x090000, 0x090fff).ram().w(FUNC(bbusters_state::video_w)).share("tx_videoram"); map(0x0a0000, 0x0a0fff).ram().share("spriteram1"); map(0x0a1000, 0x0a7fff).ram(); /* service mode */ map(0x0a8000, 0x0a8fff).ram().share("spriteram2"); @@ -312,50 +341,7 @@ void bbusters_state::bbusters_map(address_map &map) /*******************************************************************************/ -void mechatt_state::two_gun_output_w(uint16_t data) -{ - for (int i = 0; i < 2; i++) - m_gun_recoil[i] = BIT(data, i); -} - -uint16_t mechatt_state::mechatt_gun_r(offs_t offset) -{ - int x, y; - - x = m_gun_io[offset ? 2 : 0]->read(); - y = m_gun_io[offset ? 3 : 1]->read(); - - /* Todo - does the hardware really clamp like this? */ - x += 0x18; - if (x > 0xff) x = 0xff; - if (y > 0xef) y = 0xef; - - return x | (y<<8); -} - -void mechatt_state::mechatt_map(address_map &map) -{ - map(0x000000, 0x06ffff).rom(); - map(0x070000, 0x07ffff).ram().share("ram"); - map(0x090000, 0x090fff).ram().w(FUNC(mechatt_state::video_w)).share("videoram"); - map(0x0a0000, 0x0a0fff).ram().share("spriteram1"); - map(0x0a1000, 0x0a7fff).nopw(); - map(0x0b0000, 0x0b3fff).ram().w(FUNC(mechatt_state::pf_w<0>)).share("pf1_data"); - map(0x0b8000, 0x0b8003).writeonly().share("pf1_scroll_data"); - map(0x0c0000, 0x0c3fff).ram().w(FUNC(mechatt_state::pf_w<1>)).share("pf2_data"); - map(0x0c8000, 0x0c8003).writeonly().share("pf2_scroll_data"); - map(0x0d0000, 0x0d07ff).ram().w("palette", FUNC(palette_device::write16)).share("palette"); - map(0x0e0000, 0x0e0001).portr("IN0"); - map(0x0e0002, 0x0e0003).portr("DSW1"); - map(0x0e0004, 0x0e0007).r(FUNC(mechatt_state::mechatt_gun_r)); - map(0x0e4000, 0x0e4001).w(FUNC(mechatt_state::coin_counter_w)); - map(0x0e4002, 0x0e4003).w(FUNC(mechatt_state::two_gun_output_w)); - map(0x0e8001, 0x0e8001).r(m_soundlatch[1], FUNC(generic_latch_8_device::read)).w(FUNC(mechatt_state::sound_cpu_w)); -} - -/******************************************************************************/ - -void bbusters_state_base::sound_map(address_map &map) +void bbusters_state::sound_map(address_map &map) { map(0x0000, 0xefff).rom(); map(0xf000, 0xf7ff).ram(); @@ -369,13 +355,6 @@ void bbusters_state::sound_portmap(address_map &map) map(0xc0, 0xc1).nopw(); /* -> Main CPU */ } -void mechatt_state::sounda_portmap(address_map &map) -{ - map.global_mask(0xff); - map(0x00, 0x03).rw("ymsnd", FUNC(ym2608_device::read), FUNC(ym2608_device::write)); - map(0xc0, 0xc1).nopw(); /* -> Main CPU */ -} - /******************************************************************************/ static INPUT_PORTS_START( bbusters ) @@ -480,94 +459,6 @@ static INPUT_PORTS_START( bbusters ) PORT_BIT(0x3ff, 0x212, IPT_LIGHTGUN_X) PORT_CROSSHAIR(X, 1.0, 0.0, 0) PORT_MINMAX(0x14e, 0x33e) PORT_SENSITIVITY(100) PORT_KEYDELTA(10) PORT_PLAYER(3) INPUT_PORTS_END -static INPUT_PORTS_START( mechatt ) - PORT_START("IN0") - PORT_BIT( 0x0001, IP_ACTIVE_LOW, IPT_COIN1 ) - PORT_BIT( 0x0002, IP_ACTIVE_LOW, IPT_COIN2 ) - PORT_BIT( 0x0004, IP_ACTIVE_LOW, IPT_SERVICE1 ) // See notes - PORT_BIT( 0x0008, IP_ACTIVE_LOW, IPT_UNUSED ) - PORT_BIT( 0x0010, IP_ACTIVE_LOW, IPT_COIN3 ) - PORT_BIT( 0x0020, IP_ACTIVE_LOW, IPT_COIN4 ) - PORT_BIT( 0x0040, IP_ACTIVE_LOW, IPT_UNUSED ) - PORT_BIT( 0x0080, IP_ACTIVE_LOW, IPT_UNUSED ) - PORT_BIT( 0x0100, IP_ACTIVE_LOW, IPT_START1 ) - PORT_BIT( 0x0200, IP_ACTIVE_LOW, IPT_BUTTON1 ) PORT_PLAYER(1) PORT_NAME("P1 Fire") // "Fire" - PORT_BIT( 0x0400, IP_ACTIVE_LOW, IPT_BUTTON2 ) PORT_PLAYER(1) PORT_NAME("P1 Grenade") // "Grenade" - PORT_BIT( 0x0800, IP_ACTIVE_LOW, IPT_UNUSED ) - PORT_BIT( 0x1000, IP_ACTIVE_LOW, IPT_START2 ) - PORT_BIT( 0x2000, IP_ACTIVE_LOW, IPT_BUTTON1 ) PORT_PLAYER(2) PORT_NAME("P2 Fire") // "Fire" - PORT_BIT( 0x4000, IP_ACTIVE_LOW, IPT_BUTTON2 ) PORT_PLAYER(2) PORT_NAME("P2 Grenade") // "Grenade" - PORT_BIT( 0x8000, IP_ACTIVE_LOW, IPT_UNUSED ) - - PORT_START("DSW1") - PORT_DIPNAME( 0x0001, 0x0001, "Coin Slots" ) PORT_DIPLOCATION("SW1:1") // Listed as "Unused" (manual from different revision/region?), See notes - PORT_DIPSETTING( 0x0001, "Common" ) - PORT_DIPSETTING( 0x0000, "Individual" ) - PORT_DIPNAME( 0x0002, 0x0002, DEF_STR( Allow_Continue ) ) PORT_DIPLOCATION("SW1:2") - PORT_DIPSETTING( 0x0000, DEF_STR( No ) ) - PORT_DIPSETTING( 0x0002, DEF_STR( Yes ) ) - PORT_DIPNAME( 0x000c, 0x000c, "Magazine / Grenade" ) PORT_DIPLOCATION("SW1:3,4") - PORT_DIPSETTING( 0x0008, "5 / 2" ) - PORT_DIPSETTING( 0x000c, "6 / 3" ) - PORT_DIPSETTING( 0x0004, "7 / 4" ) - PORT_DIPSETTING( 0x0000, "8 / 5" ) - PORT_DIPNAME( 0x0030, 0x0030, DEF_STR( Coin_A ) ) PORT_DIPLOCATION("SW1:5,6") // See notes - PORT_DIPSETTING( 0x0000, DEF_STR( 4C_1C ) ) - PORT_DIPSETTING( 0x0010, DEF_STR( 3C_1C ) ) - PORT_DIPSETTING( 0x0020, DEF_STR( 2C_1C ) ) - PORT_DIPSETTING( 0x0030, DEF_STR( 1C_1C ) ) - PORT_DIPNAME( 0x00c0, 0x00c0, DEF_STR( Coin_B ) ) PORT_DIPLOCATION("SW1:7,8") // Listed as "Unused" (manual from different revision/region?), See notes - PORT_DIPSETTING( 0x00c0, DEF_STR( 1C_1C ) ) - PORT_DIPSETTING( 0x0080, DEF_STR( 1C_2C ) ) - PORT_DIPSETTING( 0x0040, DEF_STR( 1C_3C ) ) - PORT_DIPSETTING( 0x0000, DEF_STR( 1C_4C ) ) - PORT_DIPNAME( 0x0300, 0x0300, DEF_STR( Difficulty ) ) PORT_DIPLOCATION("SW2:1,2") - PORT_DIPSETTING( 0x0200, DEF_STR( Easy ) ) - PORT_DIPSETTING( 0x0300, DEF_STR( Normal ) ) - PORT_DIPSETTING( 0x0100, DEF_STR( Hard ) ) - PORT_DIPSETTING( 0x0000, DEF_STR( Hardest ) ) - PORT_DIPNAME( 0x0c00, 0x0c00, "Game Mode" ) PORT_DIPLOCATION("SW2:3,4") - PORT_DIPSETTING( 0x0800, "Demo Sounds Off" ) - PORT_DIPSETTING( 0x0c00, "Demo Sounds On" ) - PORT_DIPSETTING( 0x0400, "Infinite Energy (Cheat)") - PORT_DIPSETTING( 0x0000, "Freeze" ) - PORT_DIPUNUSED_DIPLOC(0x1000, 0x1000, "SW2:5" ) /* Listed as "Unused" */ - PORT_DIPUNUSED_DIPLOC(0x2000, 0x2000, "SW2:6" ) /* Listed as "Unused" */ - PORT_DIPUNUSED_DIPLOC(0x4000, 0x4000, "SW2:7" ) /* Listed as "Unused" */ - PORT_SERVICE_DIPLOC( 0x8000, IP_ACTIVE_LOW, "SW2:8" ) - - PORT_START("GUNX1") - PORT_BIT( 0xff, 0x80, IPT_LIGHTGUN_X ) PORT_CROSSHAIR(X, 1.0, 0.0, 0) PORT_SENSITIVITY(25) PORT_KEYDELTA(10) PORT_PLAYER(1) - PORT_START("GUNY1") - PORT_BIT( 0xff, 0x80, IPT_LIGHTGUN_Y ) PORT_CROSSHAIR(Y, 1.0, 0.0, 0) PORT_SENSITIVITY(25) PORT_KEYDELTA(10) PORT_PLAYER(1) - - PORT_START("GUNX2") - PORT_BIT( 0xff, 0x80, IPT_LIGHTGUN_X ) PORT_CROSSHAIR(X, 1.0, 0.0, 0) PORT_SENSITIVITY(25) PORT_KEYDELTA(10) PORT_PLAYER(2) - PORT_START("GUNY2") - PORT_BIT( 0xff, 0x80, IPT_LIGHTGUN_Y ) PORT_CROSSHAIR(Y, 1.0, 0.0, 0) PORT_SENSITIVITY(25) PORT_KEYDELTA(10) PORT_PLAYER(2) -INPUT_PORTS_END - -static INPUT_PORTS_START( mechattj ) - PORT_INCLUDE( mechatt ) - - PORT_MODIFY("DSW1") - PORT_DIPUNUSED_DIPLOC( 0x0001, 0x0001, "SW1:1" ) -INPUT_PORTS_END - -static INPUT_PORTS_START( mechattu ) - PORT_INCLUDE( mechatt ) - - PORT_MODIFY("DSW1") - PORT_DIPUNUSED_DIPLOC( 0x0001, 0x0001, "SW1:1" ) - PORT_DIPNAME( 0x0030, 0x0030, DEF_STR( Coinage ) ) PORT_DIPLOCATION("SW1:5,6") - PORT_DIPSETTING( 0x0000, DEF_STR( Free_Play ) ) - PORT_DIPSETTING( 0x0010, "1 Coin/2 Credits first, then 1 Coin/1 Credit" ) - PORT_DIPSETTING( 0x0020, "2 Coins/1 Credit first, then 1 Coin/1 Credit" ) - PORT_DIPSETTING( 0x0030, DEF_STR( 1C_1C ) ) - PORT_DIPUNUSED_DIPLOC( 0x00c0, 0x00c0, "SW1:7,8" ) -INPUT_PORTS_END - - /******************************************************************************/ static const gfx_layout charlayout = @@ -581,19 +472,6 @@ static const gfx_layout charlayout = 32*8 }; -static const gfx_layout spritelayout = -{ - 16,16, - RGN_FRAC(1,1), - 4, - { STEP4(0,4) }, - { - STEP4(0,1), STEP4(4*4,1), - STEP4(4*4*2*8,1), STEP4(4*4+4*4*2*8,1) - }, - { STEP8(0,4*4*2), STEP8(16*32,4*8) }, - 128*8 -}; static const gfx_layout tilelayout = { @@ -607,21 +485,11 @@ static const gfx_layout tilelayout = }; static GFXDECODE_START( gfx_bbusters ) - GFXDECODE_ENTRY( "gfx1", 0, charlayout, 0, 16 ) - GFXDECODE_ENTRY( "gfx2", 0, spritelayout, 256, 16 ) - GFXDECODE_ENTRY( "gfx3", 0, spritelayout, 512, 16 ) + GFXDECODE_ENTRY( "tx_tiles", 0, charlayout, 0, 16 ) GFXDECODE_ENTRY( "gfx4", 0, tilelayout, 768, 16 ) GFXDECODE_ENTRY( "gfx5", 0, tilelayout, 1024+256, 16 ) GFXDECODE_END -static GFXDECODE_START( gfx_mechatt ) - GFXDECODE_ENTRY( "gfx1", 0, charlayout, 0, 16 ) - GFXDECODE_ENTRY( "gfx2", 0, spritelayout, 256, 16 ) - GFXDECODE_ENTRY( "gfx3", 0, tilelayout, 512, 16 ) - GFXDECODE_ENTRY( "gfx4", 0, tilelayout, 768, 16 ) -GFXDECODE_END - - /******************************************************************************/ void bbusters_state::bbusters(machine_config &config) @@ -659,6 +527,16 @@ void bbusters_state::bbusters(machine_config &config) GFXDECODE(config, m_gfxdecode, "palette", gfx_bbusters); PALETTE(config, "palette").set_format(palette_device::RGBx_444, 2048); + SNK_BBUSTERS_SPR(config, m_sprites[0], 0); + m_sprites[0]->set_scaletable_tag("sprites1:scale_table"); + m_sprites[0]->set_palette("palette"); + m_sprites[0]->set_spriteram_tag("spriteram1"); + + SNK_BBUSTERS_SPR(config, m_sprites[1], 0); + m_sprites[1]->set_scaletable_tag("sprites2:scale_table"); + m_sprites[1]->set_palette("palette"); + m_sprites[1]->set_spriteram_tag("spriteram2"); + BUFFERED_SPRITERAM16(config, m_spriteram[0]); BUFFERED_SPRITERAM16(config, m_spriteram[1]); @@ -677,46 +555,6 @@ void bbusters_state::bbusters(machine_config &config) ymsnd.add_route(2, "rspeaker", 1.0); } -void mechatt_state::mechatt(machine_config &config) -{ - /* basic machine hardware */ - M68000(config, m_maincpu, 12000000); - m_maincpu->set_addrmap(AS_PROGRAM, &mechatt_state::mechatt_map); - m_maincpu->set_vblank_int("screen", FUNC(mechatt_state::irq4_line_hold)); - - Z80(config, m_audiocpu, 4000000); /* Accurate */ - m_audiocpu->set_addrmap(AS_PROGRAM, &mechatt_state::sound_map); - m_audiocpu->set_addrmap(AS_IO, &mechatt_state::sounda_portmap); - - /* video hardware */ - screen_device &screen(SCREEN(config, "screen", SCREEN_TYPE_RASTER)); - screen.set_refresh_hz(60); - screen.set_size(64*8, 32*8); - screen.set_visarea(0*8, 32*8-1, 2*8, 30*8-1); - screen.set_screen_update(FUNC(mechatt_state::screen_update)); - screen.screen_vblank().set(m_spriteram[0], FUNC(buffered_spriteram16_device::vblank_copy_rising)); - screen.set_palette("palette"); - - GFXDECODE(config, m_gfxdecode, "palette", gfx_mechatt); - PALETTE(config, "palette").set_format(palette_device::RGBx_444, 1024); - - BUFFERED_SPRITERAM16(config, m_spriteram[0]); - - /* sound hardware */ - SPEAKER(config, "lspeaker").front_left(); - SPEAKER(config, "rspeaker").front_right(); - - GENERIC_LATCH_8(config, m_soundlatch[0]); - GENERIC_LATCH_8(config, m_soundlatch[1]); - - ym2608_device &ymsnd(YM2608(config, "ymsnd", 8000000)); - ymsnd.irq_handler().set_inputline("audiocpu", 0); - ymsnd.add_route(0, "lspeaker", 0.50); - ymsnd.add_route(0, "rspeaker", 0.50); - ymsnd.add_route(1, "lspeaker", 1.0); - ymsnd.add_route(2, "rspeaker", 1.0); -} - /******************************************************************************/ ROM_START( bbusters ) @@ -729,16 +567,16 @@ ROM_START( bbusters ) ROM_REGION( 0x10000, "audiocpu", 0 ) ROM_LOAD( "bb-1.e6", 0x000000, 0x10000, CRC(4360f2ee) SHA1(4c6b212f59389bdf4388893d2030493b110ac087) ) - ROM_REGION( 0x020000, "gfx1", 0 ) + ROM_REGION( 0x020000, "tx_tiles", 0 ) ROM_LOAD( "bb-10.l9", 0x000000, 0x20000, CRC(490c0d9b) SHA1(567c25a6d96407259c64061d674305e4117d9fa4) ) - ROM_REGION( 0x200000, "gfx2", 0 ) + ROM_REGION( 0x200000, "sprites1", 0 ) ROM_LOAD16_WORD_SWAP( "bb-f11.m16", 0x000000, 0x80000, CRC(39fdf9c0) SHA1(80392947e3a1831c3ee80139f6f3bdc3bafa4f0d) ) ROM_LOAD16_WORD_SWAP( "bb-f12.m13", 0x080000, 0x80000, CRC(69ee046b) SHA1(5c0435f1ce76b584fa8d154d7617d73c7ab5f62f) ) ROM_LOAD16_WORD_SWAP( "bb-f13.m12", 0x100000, 0x80000, CRC(f5ef840e) SHA1(dd0f630c52076e0d330f47931e68a3ae9a401078) ) ROM_LOAD16_WORD_SWAP( "bb-f14.m11", 0x180000, 0x80000, CRC(1a7df3bb) SHA1(1f27a528e6f89fe56a7342c4f1ff733da0a09327) ) - ROM_REGION( 0x200000, "gfx3", 0 ) + ROM_REGION( 0x200000, "sprites2", 0 ) ROM_LOAD16_WORD_SWAP( "bb-f21.l10", 0x000000, 0x80000, CRC(530f595b) SHA1(820898693b878c4423de9c244f943d39ea69515e) ) ROM_LOAD16_WORD_SWAP( "bb-f22.l12", 0x080000, 0x80000, CRC(889c562e) SHA1(d19172d6515ab9793c98de75d6e41687e61a408d) ) ROM_LOAD16_WORD_SWAP( "bb-f23.l13", 0x100000, 0x80000, CRC(c89fe0da) SHA1(92be860a7191e7473c42aa2da981eda873219d3d) ) @@ -750,10 +588,11 @@ ROM_START( bbusters ) ROM_REGION( 0x80000, "gfx5", 0 ) ROM_LOAD( "bb-back2.m6", 0x000000, 0x80000, CRC(8be996f6) SHA1(1e2c56f4c24793f806d7b366b92edc03145ae94c) ) - ROM_REGION( 0x10000, "scale_table", 0 ) /* Zoom table */ - /* same rom exists in 4 different locations on the board */ + ROM_REGION( 0x10000, "sprites1:scale_table", 0 ) /* Zoom table - same rom exists in 4 different locations on the board */ ROM_LOAD( "bb-6.e7", 0x000000, 0x10000, CRC(61f3de03) SHA1(736f9634fe054ea68a2aa90a743bd0dc320f23c9) ) ROM_LOAD( "bb-7.h7", 0x000000, 0x10000, CRC(61f3de03) SHA1(736f9634fe054ea68a2aa90a743bd0dc320f23c9) ) + + ROM_REGION( 0x10000, "sprites2:scale_table", 0 ) /* Zoom table - same rom exists in 4 different locations on the board */ ROM_LOAD( "bb-8.a14", 0x000000, 0x10000, CRC(61f3de03) SHA1(736f9634fe054ea68a2aa90a743bd0dc320f23c9) ) ROM_LOAD( "bb-9.c14", 0x000000, 0x10000, CRC(61f3de03) SHA1(736f9634fe054ea68a2aa90a743bd0dc320f23c9) ) @@ -774,16 +613,16 @@ ROM_START( bbustersu ) ROM_REGION( 0x10000, "audiocpu", 0 ) ROM_LOAD( "bb-1.e6", 0x000000, 0x10000, CRC(4360f2ee) SHA1(4c6b212f59389bdf4388893d2030493b110ac087) ) - ROM_REGION( 0x020000, "gfx1", 0 ) + ROM_REGION( 0x020000, "tx_tiles", 0 ) ROM_LOAD( "bb-10.l9", 0x000000, 0x20000, CRC(490c0d9b) SHA1(567c25a6d96407259c64061d674305e4117d9fa4) ) - ROM_REGION( 0x200000, "gfx2", 0 ) + ROM_REGION( 0x200000, "sprites1", 0 ) ROM_LOAD16_WORD_SWAP( "bb-f11.m16", 0x000000, 0x80000, CRC(39fdf9c0) SHA1(80392947e3a1831c3ee80139f6f3bdc3bafa4f0d) ) ROM_LOAD16_WORD_SWAP( "bb-f12.m13", 0x080000, 0x80000, CRC(69ee046b) SHA1(5c0435f1ce76b584fa8d154d7617d73c7ab5f62f) ) ROM_LOAD16_WORD_SWAP( "bb-f13.m12", 0x100000, 0x80000, CRC(f5ef840e) SHA1(dd0f630c52076e0d330f47931e68a3ae9a401078) ) ROM_LOAD16_WORD_SWAP( "bb-f14.m11", 0x180000, 0x80000, CRC(1a7df3bb) SHA1(1f27a528e6f89fe56a7342c4f1ff733da0a09327) ) - ROM_REGION( 0x200000, "gfx3", 0 ) + ROM_REGION( 0x200000, "sprites2", 0 ) ROM_LOAD16_WORD_SWAP( "bb-f21.l10", 0x000000, 0x80000, CRC(530f595b) SHA1(820898693b878c4423de9c244f943d39ea69515e) ) ROM_LOAD16_WORD_SWAP( "bb-f22.l12", 0x080000, 0x80000, CRC(889c562e) SHA1(d19172d6515ab9793c98de75d6e41687e61a408d) ) ROM_LOAD16_WORD_SWAP( "bb-f23.l13", 0x100000, 0x80000, CRC(c89fe0da) SHA1(92be860a7191e7473c42aa2da981eda873219d3d) ) @@ -795,10 +634,11 @@ ROM_START( bbustersu ) ROM_REGION( 0x80000, "gfx5", 0 ) ROM_LOAD( "bb-back2.m6", 0x000000, 0x80000, CRC(8be996f6) SHA1(1e2c56f4c24793f806d7b366b92edc03145ae94c) ) - ROM_REGION( 0x10000, "scale_table", 0 ) /* Zoom table */ - /* same rom exists in 4 different locations on the board */ + ROM_REGION( 0x10000, "sprites1:scale_table", 0 ) /* Zoom table - same rom exists in 4 different locations on the board */ ROM_LOAD( "bb-6.e7", 0x000000, 0x10000, CRC(61f3de03) SHA1(736f9634fe054ea68a2aa90a743bd0dc320f23c9) ) ROM_LOAD( "bb-7.h7", 0x000000, 0x10000, CRC(61f3de03) SHA1(736f9634fe054ea68a2aa90a743bd0dc320f23c9) ) + + ROM_REGION( 0x10000, "sprites2:scale_table", 0 ) /* Zoom table - same rom exists in 4 different locations on the board */ ROM_LOAD( "bb-8.a14", 0x000000, 0x10000, CRC(61f3de03) SHA1(736f9634fe054ea68a2aa90a743bd0dc320f23c9) ) ROM_LOAD( "bb-9.c14", 0x000000, 0x10000, CRC(61f3de03) SHA1(736f9634fe054ea68a2aa90a743bd0dc320f23c9) ) @@ -819,16 +659,16 @@ ROM_START( bbustersua ) ROM_REGION( 0x10000, "audiocpu", 0 ) ROM_LOAD( "bb-1.e6", 0x000000, 0x10000, CRC(4360f2ee) SHA1(4c6b212f59389bdf4388893d2030493b110ac087) ) - ROM_REGION( 0x020000, "gfx1", 0 ) + ROM_REGION( 0x020000, "tx_tiles", 0 ) ROM_LOAD( "bb-10.l9", 0x000000, 0x20000, CRC(490c0d9b) SHA1(567c25a6d96407259c64061d674305e4117d9fa4) ) - ROM_REGION( 0x200000, "gfx2", 0 ) + ROM_REGION( 0x200000, "sprites1", 0 ) ROM_LOAD16_WORD_SWAP( "bb-f11.m16", 0x000000, 0x80000, CRC(39fdf9c0) SHA1(80392947e3a1831c3ee80139f6f3bdc3bafa4f0d) ) ROM_LOAD16_WORD_SWAP( "bb-f12.m13", 0x080000, 0x80000, CRC(69ee046b) SHA1(5c0435f1ce76b584fa8d154d7617d73c7ab5f62f) ) ROM_LOAD16_WORD_SWAP( "bb-f13.m12", 0x100000, 0x80000, CRC(f5ef840e) SHA1(dd0f630c52076e0d330f47931e68a3ae9a401078) ) ROM_LOAD16_WORD_SWAP( "bb-f14.m11", 0x180000, 0x80000, CRC(1a7df3bb) SHA1(1f27a528e6f89fe56a7342c4f1ff733da0a09327) ) - ROM_REGION( 0x200000, "gfx3", 0 ) + ROM_REGION( 0x200000, "sprites2", 0 ) ROM_LOAD16_WORD_SWAP( "bb-f21.l10", 0x000000, 0x80000, CRC(530f595b) SHA1(820898693b878c4423de9c244f943d39ea69515e) ) ROM_LOAD16_WORD_SWAP( "bb-f22.l12", 0x080000, 0x80000, CRC(889c562e) SHA1(d19172d6515ab9793c98de75d6e41687e61a408d) ) ROM_LOAD16_WORD_SWAP( "bb-f23.l13", 0x100000, 0x80000, CRC(c89fe0da) SHA1(92be860a7191e7473c42aa2da981eda873219d3d) ) @@ -840,10 +680,11 @@ ROM_START( bbustersua ) ROM_REGION( 0x80000, "gfx5", 0 ) ROM_LOAD( "bb-back2.m6", 0x000000, 0x80000, CRC(8be996f6) SHA1(1e2c56f4c24793f806d7b366b92edc03145ae94c) ) - ROM_REGION( 0x10000, "scale_table", 0 ) /* Zoom table */ - /* same rom exists in 4 different locations on the board */ + ROM_REGION( 0x10000, "sprites1:scale_table", 0 ) /* Zoom table - same rom exists in 4 different locations on the board */ ROM_LOAD( "bb-6.e7", 0x000000, 0x10000, CRC(61f3de03) SHA1(736f9634fe054ea68a2aa90a743bd0dc320f23c9) ) ROM_LOAD( "bb-7.h7", 0x000000, 0x10000, CRC(61f3de03) SHA1(736f9634fe054ea68a2aa90a743bd0dc320f23c9) ) + + ROM_REGION( 0x10000, "sprites2:scale_table", 0 ) /* Zoom table - same rom exists in 4 different locations on the board */ ROM_LOAD( "bb-8.a14", 0x000000, 0x10000, CRC(61f3de03) SHA1(736f9634fe054ea68a2aa90a743bd0dc320f23c9) ) ROM_LOAD( "bb-9.c14", 0x000000, 0x10000, CRC(61f3de03) SHA1(736f9634fe054ea68a2aa90a743bd0dc320f23c9) ) @@ -864,16 +705,16 @@ ROM_START( bbustersj ) ROM_REGION( 0x10000, "audiocpu", 0 ) ROM_LOAD( "bb-1.e6", 0x000000, 0x10000, CRC(4360f2ee) SHA1(4c6b212f59389bdf4388893d2030493b110ac087) ) - ROM_REGION( 0x020000, "gfx1", 0 ) + ROM_REGION( 0x020000, "tx_tiles", 0 ) ROM_LOAD( "bb-10.l9", 0x000000, 0x20000, CRC(490c0d9b) SHA1(567c25a6d96407259c64061d674305e4117d9fa4) ) - ROM_REGION( 0x200000, "gfx2", 0 ) + ROM_REGION( 0x200000, "sprites1", 0 ) ROM_LOAD16_WORD_SWAP( "bb-f11.m16", 0x000000, 0x80000, CRC(39fdf9c0) SHA1(80392947e3a1831c3ee80139f6f3bdc3bafa4f0d) ) ROM_LOAD16_WORD_SWAP( "bb-f12.m13", 0x080000, 0x80000, CRC(69ee046b) SHA1(5c0435f1ce76b584fa8d154d7617d73c7ab5f62f) ) ROM_LOAD16_WORD_SWAP( "bb-f13.m12", 0x100000, 0x80000, CRC(f5ef840e) SHA1(dd0f630c52076e0d330f47931e68a3ae9a401078) ) ROM_LOAD16_WORD_SWAP( "bb-f14.m11", 0x180000, 0x80000, CRC(1a7df3bb) SHA1(1f27a528e6f89fe56a7342c4f1ff733da0a09327) ) - ROM_REGION( 0x200000, "gfx3", 0 ) + ROM_REGION( 0x200000, "sprites2", 0 ) ROM_LOAD16_WORD_SWAP( "bb-f21.l10", 0x000000, 0x80000, CRC(530f595b) SHA1(820898693b878c4423de9c244f943d39ea69515e) ) ROM_LOAD16_WORD_SWAP( "bb-f22.l12", 0x080000, 0x80000, CRC(889c562e) SHA1(d19172d6515ab9793c98de75d6e41687e61a408d) ) ROM_LOAD16_WORD_SWAP( "bb-f23.l13", 0x100000, 0x80000, CRC(c89fe0da) SHA1(92be860a7191e7473c42aa2da981eda873219d3d) ) @@ -885,10 +726,11 @@ ROM_START( bbustersj ) ROM_REGION( 0x80000, "gfx5", 0 ) ROM_LOAD( "bb-back2.m6", 0x000000, 0x80000, CRC(8be996f6) SHA1(1e2c56f4c24793f806d7b366b92edc03145ae94c) ) - ROM_REGION( 0x10000, "scale_table", 0 ) /* Zoom table */ - /* same rom exists in 4 different locations on the board */ + ROM_REGION( 0x10000, "sprites1:scale_table", 0 ) /* Zoom table - same rom exists in 4 different locations on the board */ ROM_LOAD( "bb-6.e7", 0x000000, 0x10000, CRC(61f3de03) SHA1(736f9634fe054ea68a2aa90a743bd0dc320f23c9) ) ROM_LOAD( "bb-7.h7", 0x000000, 0x10000, CRC(61f3de03) SHA1(736f9634fe054ea68a2aa90a743bd0dc320f23c9) ) + + ROM_REGION( 0x10000, "sprites2:scale_table", 0 ) /* Zoom table - same rom exists in 4 different locations on the board */ ROM_LOAD( "bb-8.a14", 0x000000, 0x10000, CRC(61f3de03) SHA1(736f9634fe054ea68a2aa90a743bd0dc320f23c9) ) ROM_LOAD( "bb-9.c14", 0x000000, 0x10000, CRC(61f3de03) SHA1(736f9634fe054ea68a2aa90a743bd0dc320f23c9) ) @@ -909,16 +751,16 @@ ROM_START( bbustersja ) ROM_REGION( 0x10000, "audiocpu", 0 ) ROM_LOAD( "bb-1.e6", 0x000000, 0x10000, CRC(4360f2ee) SHA1(4c6b212f59389bdf4388893d2030493b110ac087) ) - ROM_REGION( 0x020000, "gfx1", 0 ) + ROM_REGION( 0x020000, "tx_tiles", 0 ) ROM_LOAD( "bb-10.l9", 0x000000, 0x20000, CRC(490c0d9b) SHA1(567c25a6d96407259c64061d674305e4117d9fa4) ) - ROM_REGION( 0x200000, "gfx2", 0 ) + ROM_REGION( 0x200000, "sprites1", 0 ) ROM_LOAD16_WORD_SWAP( "bb-f11.m16", 0x000000, 0x80000, CRC(39fdf9c0) SHA1(80392947e3a1831c3ee80139f6f3bdc3bafa4f0d) ) ROM_LOAD16_WORD_SWAP( "bb-f12.m13", 0x080000, 0x80000, CRC(69ee046b) SHA1(5c0435f1ce76b584fa8d154d7617d73c7ab5f62f) ) ROM_LOAD16_WORD_SWAP( "bb-f13.m12", 0x100000, 0x80000, CRC(f5ef840e) SHA1(dd0f630c52076e0d330f47931e68a3ae9a401078) ) ROM_LOAD16_WORD_SWAP( "bb-f14.m11", 0x180000, 0x80000, CRC(1a7df3bb) SHA1(1f27a528e6f89fe56a7342c4f1ff733da0a09327) ) - ROM_REGION( 0x200000, "gfx3", 0 ) + ROM_REGION( 0x200000, "sprites2", 0 ) ROM_LOAD16_WORD_SWAP( "bb-f21.l10", 0x000000, 0x80000, CRC(530f595b) SHA1(820898693b878c4423de9c244f943d39ea69515e) ) ROM_LOAD16_WORD_SWAP( "bb-f22.l12", 0x080000, 0x80000, CRC(889c562e) SHA1(d19172d6515ab9793c98de75d6e41687e61a408d) ) ROM_LOAD16_WORD_SWAP( "bb-f23.l13", 0x100000, 0x80000, CRC(c89fe0da) SHA1(92be860a7191e7473c42aa2da981eda873219d3d) ) @@ -930,10 +772,11 @@ ROM_START( bbustersja ) ROM_REGION( 0x80000, "gfx5", 0 ) ROM_LOAD( "bb-back2.m6", 0x000000, 0x80000, CRC(8be996f6) SHA1(1e2c56f4c24793f806d7b366b92edc03145ae94c) ) - ROM_REGION( 0x10000, "scale_table", 0 ) /* Zoom table */ - /* same rom exists in 4 different locations on the board */ + ROM_REGION( 0x10000, "sprites1:scale_table", 0 ) /* Zoom table - same rom exists in 4 different locations on the board */ ROM_LOAD( "bb-6.e7", 0x000000, 0x10000, CRC(61f3de03) SHA1(736f9634fe054ea68a2aa90a743bd0dc320f23c9) ) ROM_LOAD( "bb-7.h7", 0x000000, 0x10000, CRC(61f3de03) SHA1(736f9634fe054ea68a2aa90a743bd0dc320f23c9) ) + + ROM_REGION( 0x10000, "sprites2:scale_table", 0 ) /* Zoom table - same rom exists in 4 different locations on the board */ ROM_LOAD( "bb-8.a14", 0x000000, 0x10000, CRC(61f3de03) SHA1(736f9634fe054ea68a2aa90a743bd0dc320f23c9) ) ROM_LOAD( "bb-9.c14", 0x000000, 0x10000, CRC(61f3de03) SHA1(736f9634fe054ea68a2aa90a743bd0dc320f23c9) ) @@ -944,177 +787,6 @@ ROM_START( bbustersja ) ROM_LOAD( "bb-pcmb.l3", 0x000000, 0x80000, CRC(c8d5dd53) SHA1(0f7e94532cc14852ca12c1b792e5479667af899e) ) ROM_END - -ROM_START( mechatt ) - ROM_REGION( 0x80000, "maincpu", 0 ) // Located on the A8002-1 main board - ROM_LOAD16_BYTE( "ma5-e.n12", 0x000000, 0x20000, CRC(9bbb852a) SHA1(34b696bf79cf53cac1c384a3143c0f3f243a71f3) ) - ROM_LOAD16_BYTE( "ma4.l12", 0x000001, 0x20000, CRC(0d414918) SHA1(0d51b893d37ba124b983beebb691e65bdc52d300) ) - ROM_LOAD16_BYTE( "ma7.n13", 0x040000, 0x20000, CRC(61d85e1b) SHA1(46234d48ac21c481a5e70c6a654a341ebdd4cd3a) ) - ROM_LOAD16_BYTE( "ma6-f.l13", 0x040001, 0x20000, CRC(4055fe8d) SHA1(b4d8bd5f73805ce1c332eff657dddbb88ff45b37) ) - - ROM_REGION( 0x10000, "audiocpu", 0 ) // Located on the A8002-1 main board - ROM_LOAD( "ma_3.e13", 0x000000, 0x10000, CRC(c06cc8e1) SHA1(65f5f1901120d633f7c3ba07432a188fd7fd7272) ) - - ROM_REGION( 0x020000, "gfx1", 0 ) // Located on the A8002-2 board - ROM_LOAD( "ma_1.l2", 0x000000, 0x10000, CRC(24766917) SHA1(9082a8ae849605ce65b5a0493ae69cfe282f7e7b) ) - - ROM_REGION( 0x200000, "gfx2", 0 ) // Located on the A8002-2 board - ROM_LOAD16_WORD_SWAP( "mao89p13.bin", 0x000000, 0x80000, CRC(8bcb16cf) SHA1(409ee1944188d9ce39adce29b1df029b560dd5b0) ) - ROM_LOAD16_WORD_SWAP( "ma189p15.bin", 0x080000, 0x80000, CRC(b84d9658) SHA1(448adecb0067d8f5b219ec2f94a8dec84187a554) ) - ROM_LOAD16_WORD_SWAP( "ma289p17.bin", 0x100000, 0x80000, CRC(6cbe08ac) SHA1(8f81f6e92b84ab6867452011d52f3e7689c62a1a) ) - ROM_LOAD16_WORD_SWAP( "ma389m15.bin", 0x180000, 0x80000, CRC(34d4585e) SHA1(38d9fd5d775e4b3c8b8b487a6ba9b8bdcb3274b0) ) - - ROM_REGION( 0x80000, "gfx3", 0 ) // Located on the A8002-2 board - ROM_LOAD( "mab189a2.bin", 0x000000, 0x80000, CRC(e1c8b4d0) SHA1(2f8a1839cca892f8380c7cffe7a12e615d38fd55) ) - - ROM_REGION( 0x80000, "gfx4", 0 ) // Located on the A8002-2 board - ROM_LOAD( "mab289c2.bin", 0x000000, 0x80000, CRC(14f97ceb) SHA1(a22033532ea616dc3a3db8b66ad6ccc6172ed7cc) ) - - ROM_REGION( 0x20000, "ymsnd", 0 ) // Located on the A8002-1 main board - ROM_LOAD( "ma_2.d10", 0x000000, 0x20000, CRC(ea4cc30d) SHA1(d8f089fc0ce76309411706a8110ad907f93dc97e) ) - - ROM_REGION( 0x20000, "scale_table", 0 ) // Zoom table - Located on the A8002-2 board - ROM_LOAD( "ma_8.f10", 0x000000, 0x10000, CRC(61f3de03) SHA1(736f9634fe054ea68a2aa90a743bd0dc320f23c9) ) - ROM_LOAD( "ma_9.f12", 0x000000, 0x10000, CRC(61f3de03) SHA1(736f9634fe054ea68a2aa90a743bd0dc320f23c9) ) // identical to ma_8.f10 -ROM_END - -ROM_START( mechattj ) // Uses EPROMs on official SNK A8002-5 & A8002-6 sub boards instead of MaskROMs - ROM_REGION( 0x80000, "maincpu", 0 ) // Located on the A8002-1 main board - ROM_LOAD16_BYTE( "ma5j.n12", 0x000000, 0x20000, CRC(e6bb5952) SHA1(3b01eccc20d99fd33ff8e303afa902abb66e1036) ) - ROM_LOAD16_BYTE( "ma4j.l12", 0x000001, 0x20000, CRC(c78baa62) SHA1(c3554698fbc94e3625269c5cb1fc664364f3fb3f) ) - ROM_LOAD16_BYTE( "ma7j.n13", 0x040000, 0x20000, CRC(12a68fc2) SHA1(c935788723d8ea3bfe99244b8c7b2aff85579912) ) - ROM_LOAD16_BYTE( "ma6j.l13", 0x040001, 0x20000, CRC(332b2f54) SHA1(c768f5437a20ea406523d3de9e1ea807b39e1622) ) - - ROM_REGION( 0x10000, "audiocpu", 0 ) // Located on the A8002-1 main board - ROM_LOAD( "ma_3.e13", 0x000000, 0x10000, CRC(c06cc8e1) SHA1(65f5f1901120d633f7c3ba07432a188fd7fd7272) ) - - ROM_REGION( 0x020000, "gfx1", 0 ) // Located on the A8002-2 board - ROM_LOAD( "ma_1.l2", 0x000000, 0x10000, CRC(24766917) SHA1(9082a8ae849605ce65b5a0493ae69cfe282f7e7b) ) - - ROM_REGION( 0x200000, "gfx2", 0 ) // Located on the A8002-6 sub board - ROM_LOAD16_BYTE( "s_9.a1", 0x000001, 0x20000, CRC(6e8e194c) SHA1(02bbd573a322a3f7f8e92ccceebffdd598b5489e) ) // these 4 == mao89p13.bin - ROM_LOAD16_BYTE( "s_1.b1", 0x000000, 0x20000, CRC(fd9161ed) SHA1(b3e2434dd9cb1cafe1022774b863b5f1a008a9d2) ) - ROM_LOAD16_BYTE( "s_10.a2", 0x040001, 0x20000, CRC(fad6a1ab) SHA1(5347b4493c8004dc8cedc0b37aba494f203142b8) ) - ROM_LOAD16_BYTE( "s_2.b2", 0x040000, 0x20000, CRC(549056f0) SHA1(f515aa98ab25f3735dbfdefcb8d55ba3b2075b70) ) - ROM_LOAD16_BYTE( "s_11.a3", 0x080001, 0x20000, CRC(3887a382) SHA1(b40861fc1414b2fa299772e76a78cb8dc00b71b7) ) // these 4 == ma189p15.bin - ROM_LOAD16_BYTE( "s_3.b3", 0x080000, 0x20000, CRC(cb99f565) SHA1(9ed1b21f4a33b9a614bca38610378857560cdaba) ) - ROM_LOAD16_BYTE( "s_12.a4", 0x0c0001, 0x20000, CRC(63417b49) SHA1(786249fa7e8770de5b5882debdc2913d58e9170e) ) - ROM_LOAD16_BYTE( "s_4.b4", 0x0c0000, 0x20000, CRC(d739d48a) SHA1(04d2ecea72b6e651b815865946c9c9cfae4e5c4d) ) - ROM_LOAD16_BYTE( "s_13.a5", 0x100001, 0x20000, CRC(eccd47b6) SHA1(6b9c63fee97a7568114f227a89a1effd6b04806a) ) // these 4 == ma289p17.bin - ROM_LOAD16_BYTE( "s_5.b5", 0x100000, 0x20000, CRC(e15244da) SHA1(ebf3072565c53d0098d373b5093ba6918c4eddae) ) - ROM_LOAD16_BYTE( "s_14.a6", 0x140001, 0x20000, CRC(bbbf0461) SHA1(c5299ab1d45f685a5d160492247cf1303ef6937a) ) - ROM_LOAD16_BYTE( "s_6.b6", 0x140000, 0x20000, CRC(4ee89f75) SHA1(bda0e9095da2d424faac341fd934000a621796eb) ) - ROM_LOAD16_BYTE( "s_15.a7", 0x180001, 0x20000, CRC(cde29bad) SHA1(24c1b43c6d717eaaf7c01ec7de89837947334224) ) // these 4 == ma389m15.bin - ROM_LOAD16_BYTE( "s_7.b7", 0x180000, 0x20000, CRC(065ed221) SHA1(c03ca5b4d1198939a57b5fccf6a79d70afe1faaf) ) - ROM_LOAD16_BYTE( "s_16.a8", 0x1c0001, 0x20000, CRC(70f28040) SHA1(91012728953563fcc576725337e6ba7e1b49d1ba) ) - ROM_LOAD16_BYTE( "s_8.b8", 0x1c0000, 0x20000, CRC(a6f8574f) SHA1(87c041669b2eaec495ae10a6f45b6668accb92bf) ) - - ROM_REGION( 0x80000, "gfx3", 0 ) // these 4 == mab189a2.bin - Located on the A8002-5 sub board - ROM_LOAD( "s_21.b3", 0x000000, 0x20000, CRC(701a0072) SHA1(b03b6fa18e0cfcd5c7c541025fa2d3632d2f8387) ) - ROM_LOAD( "s_22.b4", 0x020000, 0x20000, CRC(34e6225c) SHA1(f6335084f4f4c7a4b6528e6ad74962b88f81e3bc) ) - ROM_LOAD( "s_23.b5", 0x040000, 0x20000, CRC(9a7399d3) SHA1(04e0327b0da75f621b51e1831cbdc4537082e32b) ) - ROM_LOAD( "s_24.b6", 0x060000, 0x20000, CRC(f097459d) SHA1(466364677f048519eb2894ddecf76f5c52f6afe9) ) - - ROM_REGION( 0x80000, "gfx4", 0 ) // these 4 == mab289c2.bin - Located on the A8002-5 sub board - ROM_LOAD( "s_17.a3", 0x000000, 0x20000, CRC(cc47c4a3) SHA1(140f53b671b4eaed6fcc516c4018f07a6d7c2290) ) - ROM_LOAD( "s_18.a4", 0x020000, 0x20000, CRC(a04377e8) SHA1(841c6c3073b137f6a5c875db32039186c014f785) ) - ROM_LOAD( "s_19.a5", 0x040000, 0x20000, CRC(b07f5289) SHA1(8817bd225edf9b0fa439b220617f925365e39253) ) - ROM_LOAD( "s_20.a6", 0x060000, 0x20000, CRC(a9bb4fa9) SHA1(ccede784671a864667b92a8101d686c26c78d76f) ) - - ROM_REGION( 0x20000, "ymsnd", 0 ) // Located on the A8002-1 main board - ROM_LOAD( "ma_2.d10", 0x000000, 0x20000, CRC(ea4cc30d) SHA1(d8f089fc0ce76309411706a8110ad907f93dc97e) ) - - ROM_REGION( 0x20000, "scale_table", 0 ) // Zoom table - Located on the A8002-2 board - ROM_LOAD( "ma_8.f10", 0x000000, 0x10000, CRC(61f3de03) SHA1(736f9634fe054ea68a2aa90a743bd0dc320f23c9) ) - ROM_LOAD( "ma_9.f12", 0x000000, 0x10000, CRC(61f3de03) SHA1(736f9634fe054ea68a2aa90a743bd0dc320f23c9) ) // identical to ma_8.f10 -ROM_END - -ROM_START( mechattu ) - ROM_REGION( 0x80000, "maincpu", 0 ) // Located on the A8002-1 main board - ROM_LOAD16_BYTE( "ma5u.n12", 0x000000, 0x20000, CRC(485ea606) SHA1(0c499f08d7c6d861ba7c50a8f577823613a7923c) ) - ROM_LOAD16_BYTE( "ma4u.l12", 0x000001, 0x20000, CRC(09fa31ec) SHA1(008abb2e09f83614c277471e534f20cba3e354d7) ) - ROM_LOAD16_BYTE( "ma7u.n13", 0x040000, 0x20000, CRC(f45b2c70) SHA1(65523d202d378bab890f1f7bffdde152dd246d4a) ) - ROM_LOAD16_BYTE( "ma6u.l13", 0x040001, 0x20000, CRC(d5d68ce6) SHA1(16057d882781015f6d1c7bb659e0812a8459c3f0) ) - - ROM_REGION( 0x10000, "audiocpu", 0 ) // Located on the A8002-1 main board - ROM_LOAD( "ma_3.e13", 0x000000, 0x10000, CRC(c06cc8e1) SHA1(65f5f1901120d633f7c3ba07432a188fd7fd7272) ) - - ROM_REGION( 0x020000, "gfx1", 0 ) // Located on the A8002-2 board - ROM_LOAD( "ma_1.l2", 0x000000, 0x10000, CRC(24766917) SHA1(9082a8ae849605ce65b5a0493ae69cfe282f7e7b) ) - - ROM_REGION( 0x200000, "gfx2", 0 ) // Located on the A8002-2 board - ROM_LOAD16_WORD_SWAP( "mao89p13.bin", 0x000000, 0x80000, CRC(8bcb16cf) SHA1(409ee1944188d9ce39adce29b1df029b560dd5b0) ) - ROM_LOAD16_WORD_SWAP( "ma189p15.bin", 0x080000, 0x80000, CRC(b84d9658) SHA1(448adecb0067d8f5b219ec2f94a8dec84187a554) ) - ROM_LOAD16_WORD_SWAP( "ma289p17.bin", 0x100000, 0x80000, CRC(6cbe08ac) SHA1(8f81f6e92b84ab6867452011d52f3e7689c62a1a) ) - ROM_LOAD16_WORD_SWAP( "ma389m15.bin", 0x180000, 0x80000, CRC(34d4585e) SHA1(38d9fd5d775e4b3c8b8b487a6ba9b8bdcb3274b0) ) - - ROM_REGION( 0x80000, "gfx3", 0 ) // Located on the A8002-2 board - ROM_LOAD( "mab189a2.bin", 0x000000, 0x80000, CRC(e1c8b4d0) SHA1(2f8a1839cca892f8380c7cffe7a12e615d38fd55) ) - - ROM_REGION( 0x80000, "gfx4", 0 ) // Located on the A8002-2 board - ROM_LOAD( "mab289c2.bin", 0x000000, 0x80000, CRC(14f97ceb) SHA1(a22033532ea616dc3a3db8b66ad6ccc6172ed7cc) ) - - ROM_REGION( 0x20000, "ymsnd", 0 ) // Located on the A8002-1 main board - ROM_LOAD( "ma_2.d10", 0x000000, 0x20000, CRC(ea4cc30d) SHA1(d8f089fc0ce76309411706a8110ad907f93dc97e) ) - - ROM_REGION( 0x20000, "scale_table", 0 ) // Zoom table - Located on the A8002-2 board - ROM_LOAD( "ma_8.f10", 0x000000, 0x10000, CRC(61f3de03) SHA1(736f9634fe054ea68a2aa90a743bd0dc320f23c9) ) - ROM_LOAD( "ma_9.f12", 0x000000, 0x10000, CRC(61f3de03) SHA1(736f9634fe054ea68a2aa90a743bd0dc320f23c9) ) // identical to ma_8.f10 -ROM_END - -/* does Ver1 on the roms mean it's a revision, the first version, or used because it's the single player version? */ -ROM_START( mechattu1 ) // Uses EPROMs on official SNK A8002-5 & A8002-6 sub boards instead of MaskROMs - ROM_REGION( 0x80000, "maincpu", 0 ) // Located on the A8002-1 main board - ROM_LOAD16_BYTE( "ma_ver1_5u.n12", 0x000000, 0x20000, CRC(dcd2e971) SHA1(e292b251c429b6990e97233e86360e5d43f573f2) ) - ROM_LOAD16_BYTE( "ma_ver1_4u.l12", 0x000001, 0x20000, CRC(69c8a85b) SHA1(07c6d395772a5e096e3ac42c5248eadccc146ad1) ) - ROM_LOAD16_BYTE( "ma7u.n13", 0x040000, 0x20000, CRC(f45b2c70) SHA1(65523d202d378bab890f1f7bffdde152dd246d4a) ) - ROM_LOAD16_BYTE( "ma6u.l13", 0x040001, 0x20000, CRC(d5d68ce6) SHA1(16057d882781015f6d1c7bb659e0812a8459c3f0) ) - - ROM_REGION( 0x10000, "audiocpu", 0 ) // Located on the A8002-1 main board - ROM_LOAD( "ma_3.e13", 0x000000, 0x10000, CRC(c06cc8e1) SHA1(65f5f1901120d633f7c3ba07432a188fd7fd7272) ) - - ROM_REGION( 0x020000, "gfx1", 0 ) // Located on the A8002-2 board - ROM_LOAD( "ma_1.l2", 0x000000, 0x10000, CRC(24766917) SHA1(9082a8ae849605ce65b5a0493ae69cfe282f7e7b) ) - - ROM_REGION( 0x200000, "gfx2", 0 ) // Located on the A8002-6 sub board - ROM_LOAD16_BYTE( "s_9.a1", 0x000001, 0x20000, CRC(6e8e194c) SHA1(02bbd573a322a3f7f8e92ccceebffdd598b5489e) ) // these 4 == mao89p13.bin - ROM_LOAD16_BYTE( "s_1.b1", 0x000000, 0x20000, CRC(fd9161ed) SHA1(b3e2434dd9cb1cafe1022774b863b5f1a008a9d2) ) - ROM_LOAD16_BYTE( "s_10.a2", 0x040001, 0x20000, CRC(fad6a1ab) SHA1(5347b4493c8004dc8cedc0b37aba494f203142b8) ) - ROM_LOAD16_BYTE( "s_2.b2", 0x040000, 0x20000, CRC(549056f0) SHA1(f515aa98ab25f3735dbfdefcb8d55ba3b2075b70) ) - ROM_LOAD16_BYTE( "s_11.a3", 0x080001, 0x20000, CRC(3887a382) SHA1(b40861fc1414b2fa299772e76a78cb8dc00b71b7) ) // these 4 == ma189p15.bin - ROM_LOAD16_BYTE( "s_3.b3", 0x080000, 0x20000, CRC(cb99f565) SHA1(9ed1b21f4a33b9a614bca38610378857560cdaba) ) - ROM_LOAD16_BYTE( "s_12.a4", 0x0c0001, 0x20000, CRC(63417b49) SHA1(786249fa7e8770de5b5882debdc2913d58e9170e) ) - ROM_LOAD16_BYTE( "s_4.b4", 0x0c0000, 0x20000, CRC(d739d48a) SHA1(04d2ecea72b6e651b815865946c9c9cfae4e5c4d) ) - ROM_LOAD16_BYTE( "s_13.a5", 0x100001, 0x20000, CRC(eccd47b6) SHA1(6b9c63fee97a7568114f227a89a1effd6b04806a) ) // these 4 == ma289p17.bin - ROM_LOAD16_BYTE( "s_5.b5", 0x100000, 0x20000, CRC(e15244da) SHA1(ebf3072565c53d0098d373b5093ba6918c4eddae) ) - ROM_LOAD16_BYTE( "s_14.a6", 0x140001, 0x20000, CRC(bbbf0461) SHA1(c5299ab1d45f685a5d160492247cf1303ef6937a) ) - ROM_LOAD16_BYTE( "s_6.b6", 0x140000, 0x20000, CRC(4ee89f75) SHA1(bda0e9095da2d424faac341fd934000a621796eb) ) - ROM_LOAD16_BYTE( "s_15.a7", 0x180001, 0x20000, CRC(cde29bad) SHA1(24c1b43c6d717eaaf7c01ec7de89837947334224) ) // these 4 == ma389m15.bin - ROM_LOAD16_BYTE( "s_7.b7", 0x180000, 0x20000, CRC(065ed221) SHA1(c03ca5b4d1198939a57b5fccf6a79d70afe1faaf) ) - ROM_LOAD16_BYTE( "s_16.a8", 0x1c0001, 0x20000, CRC(70f28040) SHA1(91012728953563fcc576725337e6ba7e1b49d1ba) ) - ROM_LOAD16_BYTE( "s_8.b8", 0x1c0000, 0x20000, CRC(a6f8574f) SHA1(87c041669b2eaec495ae10a6f45b6668accb92bf) ) - - ROM_REGION( 0x80000, "gfx3", 0 ) // these 4 == mab189a2.bin - Located on the A8002-5 sub board - ROM_LOAD( "s_21.b3", 0x000000, 0x20000, CRC(701a0072) SHA1(b03b6fa18e0cfcd5c7c541025fa2d3632d2f8387) ) - ROM_LOAD( "s_22.b4", 0x020000, 0x20000, CRC(34e6225c) SHA1(f6335084f4f4c7a4b6528e6ad74962b88f81e3bc) ) - ROM_LOAD( "s_23.b5", 0x040000, 0x20000, CRC(9a7399d3) SHA1(04e0327b0da75f621b51e1831cbdc4537082e32b) ) - ROM_LOAD( "s_24.b6", 0x060000, 0x20000, CRC(f097459d) SHA1(466364677f048519eb2894ddecf76f5c52f6afe9) ) - - ROM_REGION( 0x80000, "gfx4", 0 ) // these 4 == mab289c2.bin - Located on the A8002-5 sub board - ROM_LOAD( "s_17.a3", 0x000000, 0x20000, CRC(cc47c4a3) SHA1(140f53b671b4eaed6fcc516c4018f07a6d7c2290) ) - ROM_LOAD( "s_18.a4", 0x020000, 0x20000, CRC(a04377e8) SHA1(841c6c3073b137f6a5c875db32039186c014f785) ) - ROM_LOAD( "s_19.a5", 0x040000, 0x20000, CRC(b07f5289) SHA1(8817bd225edf9b0fa439b220617f925365e39253) ) - ROM_LOAD( "s_20.a6", 0x060000, 0x20000, CRC(a9bb4fa9) SHA1(ccede784671a864667b92a8101d686c26c78d76f) ) - - ROM_REGION( 0x20000, "ymsnd", 0 ) // Located on the A8002-1 main board - ROM_LOAD( "ma_2.d10", 0x000000, 0x20000, CRC(ea4cc30d) SHA1(d8f089fc0ce76309411706a8110ad907f93dc97e) ) - - ROM_REGION( 0x20000, "scale_table", 0 ) // Zoom table - Located on the A8002-2 board - ROM_LOAD( "ma_8.f10", 0x000000, 0x10000, CRC(61f3de03) SHA1(736f9634fe054ea68a2aa90a743bd0dc320f23c9) ) - ROM_LOAD( "ma_9.f12", 0x000000, 0x10000, CRC(61f3de03) SHA1(736f9634fe054ea68a2aa90a743bd0dc320f23c9) ) // identical to ma_8.f10 -ROM_END - - /******************************************************************************/ GAME( 1989, bbusters, 0, bbusters, bbusters, bbusters_state, empty_init, ROT0, "SNK", "Beast Busters (World)", MACHINE_SUPPORTS_SAVE ) @@ -1122,8 +794,3 @@ GAME( 1989, bbustersu, bbusters, bbusters, bbusters, bbusters_state, empty_init GAME( 1989, bbustersua, bbusters, bbusters, bbusters, bbusters_state, empty_init, ROT0, "SNK", "Beast Busters (US, Version 2)", MACHINE_SUPPORTS_SAVE ) GAME( 1989, bbustersj, bbusters, bbusters, bbusters, bbusters_state, empty_init, ROT0, "SNK", "Beast Busters (Japan, Version 2, 3 Player)", MACHINE_SUPPORTS_SAVE ) GAME( 1989, bbustersja, bbusters, bbusters, bbusters, bbusters_state, empty_init, ROT0, "SNK", "Beast Busters (Japan, Version 2, 2 Player)", MACHINE_SUPPORTS_SAVE ) - -GAME( 1989, mechatt, 0, mechatt, mechatt, mechatt_state, empty_init, ROT0, "SNK", "Mechanized Attack (World)", MACHINE_SUPPORTS_SAVE ) -GAME( 1989, mechattj, mechatt, mechatt, mechattj, mechatt_state, empty_init, ROT0, "SNK", "Mechanized Attack (Japan)", MACHINE_SUPPORTS_SAVE ) -GAME( 1989, mechattu, mechatt, mechatt, mechattu, mechatt_state, empty_init, ROT0, "SNK", "Mechanized Attack (US)", MACHINE_SUPPORTS_SAVE ) -GAME( 1989, mechattu1, mechatt, mechatt, mechattu, mechatt_state, empty_init, ROT0, "SNK", "Mechanized Attack (US, Version 1, Single Player)", MACHINE_SUPPORTS_SAVE ) diff --git a/src/mame/drivers/mechatt.cpp b/src/mame/drivers/mechatt.cpp new file mode 100644 index 00000000000..d046cd03ed4 --- /dev/null +++ b/src/mame/drivers/mechatt.cpp @@ -0,0 +1,731 @@ +// license:BSD-3-Clause +// copyright-holders:Bryan McPhail +/*************************************************************************** + + Mechanized Attack A8002 (c) 1989 SNK Corporation + + Compared to Beast Busters (A9003), Mechanized Attack (A8002) is an + earlier design, it only has one sprite chip, no eeprom, and only 2 + machine guns, but the tilemaps are twice the size. + + ---------------------------------------------------------------------------------------- + + Stephh's notes (based on the games M68000 code and some tests) : + + 2) 'mechatt' + + - Country/version is stored at 0x06a000.w and the possible values are : + + Value Country + 0x0000 Japan + 0x1111 World (value stored in the current set) + 0x2222 US + 0x3333 Asia? (it looks like Japanese text but some "symbols" are missing) + + 2a) Japan version + + - All texts are in Japanese. + - "(c) 1989 (Corp) S-N-K". + - "Coin Slots" Dip Switch has no effect. + - "Coin A" and "Coin B" Dip Switches are the same as in the World version. + - Coin buttons effect : + + * "Coin Slots" are ALWAYS considered as "Common" : + + . COIN1 : adds coin(s)/credit(s) depending on "Coin A" Dip Switch + . COIN2 : adds coin(s)/credit(s) depending on "Coin B" Dip Switch + . COIN3 : NO EFFECT ! + . COIN4 : NO EFFECT ! + . SERVICE1 : adds coin(s)/credit(s) depending on "Coin A" Dip Switch + + 2b) World version + + - All texts are in English. + - "(c) 1989 SNK Corporation". + - Coin buttons effect : + + * "Coin Slots" Dip Switch set to "Common" : + + . COIN1 : adds coin(s)/credit(s) depending on "Coin A" Dip Switch + . COIN2 : adds coin(s)/credit(s) depending on "Coin B" Dip Switch + . COIN3 : NO EFFECT ! + . COIN4 : NO EFFECT ! + . SERVICE1 : adds coin(s)/credit(s) depending on "Coin A" Dip Switch + + * "Coin Slots" Dip Switch set to "Individual" : + + . COIN1 : adds coin(s)/credit(s) for player 1 depending on "Coin A" Dip Switch + . COIN2 : adds coin(s)/credit(s) for player 1 depending on "Coin B" Dip Switch + . COIN3 : adds coin(s)/credit(s) for player 2 depending on "Coin A" Dip Switch + . COIN4 : adds coin(s)/credit(s) for player 2 depending on "Coin B" Dip Switch + . SERVICE1 : adds coin(s)/credit(s) for all players depending on "Coin A" Dip Switch + + 2c) US version + + - All texts are in English. + - "(c) 1989 SNK Corp. of America". + - Additional FBI logo as first screen as well as small FBI notice at the bottom left + of the screens until a coin is inserted. + - "Coin Slots" Dip Switch has no effect. + - "Coin A" Dip Switch is different from the World version : + + World US + 4C_1C "Free Play" + 3C_1C special (see below) + 2C_1C "2 Coins to Start, 1 to Continue" + 1C_1C 1C_1C + + It's a bit hard to explain the "special" coinage, so here are some infos : + + * when you insert a coin before starting a game, you are awarded 2 credits + if credits == 0, else you are awarded 1 credit + * when you insert a coin to continue, you are ALWAYS awarded 1 credit + + - "Coin B" Dip Switch has no effect. + + - Coin buttons effect : + + * "Coin Slots" are ALWAYS considered as "Individual" : + + . COIN1 : adds coin(s)/credit(s) for player 1 depending on "Coin A" Dip Switch + . COIN2 : adds coin(s)/credit(s) for player 2 depending on "Coin A" Dip Switch + . COIN3 : NO EFFECT ! + . COIN4 : NO EFFECT ! + . SERVICE1 : adds coin(s)/credit(s) for all players depending on "Coin A" Dip Switch + + 2d) Asia? version + + - All texts are in Japanese ? (to be confirmed) + - "(c) 1989 SNK Corporation". + - "Coin Slots" Dip Switch has no effect. + - "Coin A" and "Coin B" Dip Switches are the same as in the World version. + - Coin buttons effect : + + * "Coin Slots" are ALWAYS considered as "Common" : + + . COIN1 : adds coin(s)/credit(s) depending on "Coin A" Dip Switch + . COIN2 : adds coin(s)/credit(s) depending on "Coin B" Dip Switch + . COIN3 : NO EFFECT ! + . COIN4 : NO EFFECT ! + . SERVICE1 : adds coin(s)/credit(s) depending on "Coin A" Dip Switch + + ---------------------------------------------------------------------------------------- + + HIGHWAYMAN's notes: + + after adding the mechanized attack u.s. roms I suspect that there is more than just a few bytes changed ;-) + + ---------------------------------------------------------------------------------------- + + Mech Attack Region code works as follows + + ROM[0x06a000/2] = (data << 12) | (data << 8) | (data << 4) | (data << 0); + + Country : + - 0x0000 : Japan + - 0x1111 : World (default) + - 0x2222 : US + - 0x3333 : Asia? + +***************************************************************************/ + +#include "emu.h" + +// src/mame +#include "video/snk_bbusters_spr.h" +// src/devices +#include "cpu/z80/z80.h" +#include "cpu/m68000/m68000.h" +#include "machine/gen_latch.h" +#include "sound/ym2608.h" +#include "video/bufsprite.h" +// src/emu +#include "emupal.h" +#include "screen.h" +#include "speaker.h" +#include "tilemap.h" + +class mechatt_state : public driver_device +{ +public: + mechatt_state(const machine_config &mconfig, device_type type, const char *tag) : + driver_device(mconfig, type, tag), + m_maincpu(*this, "maincpu"), + m_audiocpu(*this, "audiocpu"), + m_screen(*this, "screen"), + m_gfxdecode(*this, "gfxdecode"), + m_sprites(*this, "sprites1"), + m_spriteram(*this, "spriteram1"), + m_soundlatch(*this, "soundlatch%u", 1U), + m_tx_videoram(*this, "tx_videoram"), + m_pf_data(*this, "pf%u_data", 1U), + m_pf_scroll_data(*this, "pf%u_scroll_data", 1U), + m_gun_io(*this, { "GUNX1", "GUNY1", "GUNX2", "GUNY2" }), + m_gun_recoil(*this, "Player%u_Gun_Recoil", 1U) + { } + + void mechatt(machine_config &config); + +protected: + virtual void machine_start() override; + virtual void video_start() override; + +private: + required_device m_maincpu; + required_device m_audiocpu; + required_device m_screen; + required_device m_gfxdecode; + required_device m_sprites; + required_device m_spriteram; + required_device_array m_soundlatch; + required_shared_ptr m_tx_videoram; + required_shared_ptr_array m_pf_data; + required_shared_ptr_array m_pf_scroll_data; + required_ioport_array<4> m_gun_io; + output_finder<2> m_gun_recoil; + + tilemap_t *m_fix_tilemap; + tilemap_t *m_pf_tilemap[2]; + + TILE_GET_INFO_MEMBER(get_tile_info); + template TILE_GET_INFO_MEMBER(get_pf_tile_info); + + void sound_cpu_w(uint8_t data); + void video_w(offs_t offset, uint16_t data, uint16_t mem_mask = ~0); + template void pf_w(offs_t offset, uint16_t data, uint16_t mem_mask = ~0); + void coin_counter_w(uint8_t data); + + void mechatt_map(address_map &map); + void sound_map(address_map &map); + void sounda_portmap(address_map &map); + + void two_gun_output_w(uint16_t data); + uint16_t mechatt_gun_r(offs_t offset); + + template + void mix_sprites(bitmap_ind16 &bitmap, bitmap_ind16 &srcbitmap, const rectangle &cliprect, Proc MIX); + + bitmap_ind16 m_bitmap_sprites; + uint32_t screen_update(screen_device &screen, bitmap_ind16 &bitmap, const rectangle &cliprect); +}; + +/******************************************************************************/ + +void mechatt_state::machine_start() +{ + m_gun_recoil.resolve(); +} + +void mechatt_state::sound_cpu_w(uint8_t data) +{ + m_soundlatch[0]->write(data); + m_audiocpu->pulse_input_line(INPUT_LINE_NMI, attotime::zero); +} + +template +void mechatt_state::pf_w(offs_t offset, uint16_t data, uint16_t mem_mask) +{ + COMBINE_DATA(&m_pf_data[Layer][offset]); + m_pf_tilemap[Layer]->mark_tile_dirty(offset); +} + +void mechatt_state::coin_counter_w(uint8_t data) +{ + machine().bookkeeping().coin_counter_w(0, BIT(data, 0)); + machine().bookkeeping().coin_counter_w(1, BIT(data, 1)); +} + + +TILE_GET_INFO_MEMBER(mechatt_state::get_tile_info) +{ + uint16_t tile = m_tx_videoram[tile_index]; + tileinfo.set(0,tile&0xfff,tile>>12,0); +} + +template +TILE_GET_INFO_MEMBER(mechatt_state::get_pf_tile_info) +{ + uint16_t tile = m_pf_data[Layer][tile_index]; + tileinfo.set(Gfx,tile&0xfff,tile>>12,0); +} + +void mechatt_state::video_w(offs_t offset, uint16_t data, uint16_t mem_mask) +{ + COMBINE_DATA(&m_tx_videoram[offset]); + m_fix_tilemap->mark_tile_dirty(offset); +} + +/******************************************************************************/ + +void mechatt_state::video_start() +{ + m_fix_tilemap = &machine().tilemap().create(*m_gfxdecode, tilemap_get_info_delegate(*this, FUNC(mechatt_state::get_tile_info)), TILEMAP_SCAN_ROWS, 8, 8, 32, 32); + m_fix_tilemap->set_transparent_pen(15); + + m_pf_tilemap[0] = &machine().tilemap().create(*m_gfxdecode, tilemap_get_info_delegate(*this, NAME((&mechatt_state::get_pf_tile_info<0,1>))), TILEMAP_SCAN_COLS, 16, 16, 256, 32); + m_pf_tilemap[1] = &machine().tilemap().create(*m_gfxdecode, tilemap_get_info_delegate(*this, NAME((&mechatt_state::get_pf_tile_info<1,2>))), TILEMAP_SCAN_COLS, 16, 16, 256, 32); + + m_pf_tilemap[0]->set_transparent_pen(15); + + m_screen->register_screen_bitmap(m_bitmap_sprites); + m_bitmap_sprites.fill(0xffff); +} + +template +void mechatt_state::mix_sprites(bitmap_ind16 &bitmap, bitmap_ind16 &srcbitmap, const rectangle &cliprect, Proc MIX) +{ + for (int y = cliprect.min_y; y <= cliprect.max_y; y++) + { + uint16_t* srcbuf = &srcbitmap.pix(y); + uint16_t* dstbuf = &bitmap.pix(y); + for (int x = cliprect.min_x; x <= cliprect.max_x; x++) + { + uint16_t srcdat = srcbuf[x]; + if ((srcdat & 0xf) != 0xf) + MIX(srcdat, x, dstbuf); + } + } +} + +uint32_t mechatt_state::screen_update(screen_device &screen, bitmap_ind16 &bitmap, const rectangle &cliprect) +{ + m_bitmap_sprites.fill(0xffff); + m_sprites->draw_sprites(m_bitmap_sprites, cliprect); + + m_pf_tilemap[0]->set_scrollx(0, m_pf_scroll_data[0][0]); + m_pf_tilemap[0]->set_scrolly(0, m_pf_scroll_data[0][1]); + m_pf_tilemap[1]->set_scrollx(0, m_pf_scroll_data[1][0]); + m_pf_tilemap[1]->set_scrolly(0, m_pf_scroll_data[1][1]); + + m_pf_tilemap[1]->draw(screen, bitmap, cliprect, 0, 0); + + // during level 3, plane sprites must rise from the underground, obscured by the fg tilemap + mix_sprites(bitmap, m_bitmap_sprites, cliprect, [](uint16_t srcdat, uint16_t x, uint16_t* dstbuf) { if ((srcdat & 0xc0) == 0xc0) dstbuf[x] = srcdat + 256; } ); + m_pf_tilemap[0]->draw(screen, bitmap, cliprect, 0, 0); + mix_sprites(bitmap, m_bitmap_sprites, cliprect, [](uint16_t srcdat, uint16_t x, uint16_t* dstbuf) { if ((srcdat & 0xc0) != 0xc0) dstbuf[x] = srcdat + 256; } ); + + m_fix_tilemap->draw(screen, bitmap, cliprect, 0, 0); + return 0; +} + +/*******************************************************************************/ + +void mechatt_state::two_gun_output_w(uint16_t data) +{ + for (int i = 0; i < 2; i++) + m_gun_recoil[i] = BIT(data, i); +} + +uint16_t mechatt_state::mechatt_gun_r(offs_t offset) +{ + int x, y; + + x = m_gun_io[offset ? 2 : 0]->read(); + y = m_gun_io[offset ? 3 : 1]->read(); + + /* Todo - does the hardware really clamp like this? */ + x += 0x18; + if (x > 0xff) x = 0xff; + if (y > 0xef) y = 0xef; + + return x | (y<<8); +} + +void mechatt_state::mechatt_map(address_map &map) +{ + map(0x000000, 0x06ffff).rom(); + map(0x070000, 0x07ffff).ram().share("ram"); + map(0x090000, 0x090fff).ram().w(FUNC(mechatt_state::video_w)).share("tx_videoram"); + map(0x0a0000, 0x0a0fff).ram().share("spriteram1"); + map(0x0a1000, 0x0a7fff).nopw(); + map(0x0b0000, 0x0b3fff).ram().w(FUNC(mechatt_state::pf_w<0>)).share("pf1_data"); + map(0x0b8000, 0x0b8003).writeonly().share("pf1_scroll_data"); + map(0x0c0000, 0x0c3fff).ram().w(FUNC(mechatt_state::pf_w<1>)).share("pf2_data"); + map(0x0c8000, 0x0c8003).writeonly().share("pf2_scroll_data"); + map(0x0d0000, 0x0d07ff).ram().w("palette", FUNC(palette_device::write16)).share("palette"); + map(0x0e0000, 0x0e0001).portr("IN0"); + map(0x0e0002, 0x0e0003).portr("DSW1"); + map(0x0e0004, 0x0e0007).r(FUNC(mechatt_state::mechatt_gun_r)); + map(0x0e4000, 0x0e4001).w(FUNC(mechatt_state::coin_counter_w)); + map(0x0e4002, 0x0e4003).w(FUNC(mechatt_state::two_gun_output_w)); + map(0x0e8001, 0x0e8001).r(m_soundlatch[1], FUNC(generic_latch_8_device::read)).w(FUNC(mechatt_state::sound_cpu_w)); +} + +/******************************************************************************/ + +void mechatt_state::sound_map(address_map &map) +{ + map(0x0000, 0xefff).rom(); + map(0xf000, 0xf7ff).ram(); + map(0xf800, 0xf800).r(m_soundlatch[0], FUNC(generic_latch_8_device::read)).w(m_soundlatch[1], FUNC(generic_latch_8_device::write)); +} + +void mechatt_state::sounda_portmap(address_map &map) +{ + map.global_mask(0xff); + map(0x00, 0x03).rw("ymsnd", FUNC(ym2608_device::read), FUNC(ym2608_device::write)); + map(0xc0, 0xc1).nopw(); /* -> Main CPU */ +} + +/******************************************************************************/ + +static INPUT_PORTS_START( mechatt ) + PORT_START("IN0") + PORT_BIT( 0x0001, IP_ACTIVE_LOW, IPT_COIN1 ) + PORT_BIT( 0x0002, IP_ACTIVE_LOW, IPT_COIN2 ) + PORT_BIT( 0x0004, IP_ACTIVE_LOW, IPT_SERVICE1 ) // See notes + PORT_BIT( 0x0008, IP_ACTIVE_LOW, IPT_UNUSED ) + PORT_BIT( 0x0010, IP_ACTIVE_LOW, IPT_COIN3 ) + PORT_BIT( 0x0020, IP_ACTIVE_LOW, IPT_COIN4 ) + PORT_BIT( 0x0040, IP_ACTIVE_LOW, IPT_UNUSED ) + PORT_BIT( 0x0080, IP_ACTIVE_LOW, IPT_UNUSED ) + PORT_BIT( 0x0100, IP_ACTIVE_LOW, IPT_START1 ) + PORT_BIT( 0x0200, IP_ACTIVE_LOW, IPT_BUTTON1 ) PORT_PLAYER(1) PORT_NAME("P1 Fire") // "Fire" + PORT_BIT( 0x0400, IP_ACTIVE_LOW, IPT_BUTTON2 ) PORT_PLAYER(1) PORT_NAME("P1 Grenade") // "Grenade" + PORT_BIT( 0x0800, IP_ACTIVE_LOW, IPT_UNUSED ) + PORT_BIT( 0x1000, IP_ACTIVE_LOW, IPT_START2 ) + PORT_BIT( 0x2000, IP_ACTIVE_LOW, IPT_BUTTON1 ) PORT_PLAYER(2) PORT_NAME("P2 Fire") // "Fire" + PORT_BIT( 0x4000, IP_ACTIVE_LOW, IPT_BUTTON2 ) PORT_PLAYER(2) PORT_NAME("P2 Grenade") // "Grenade" + PORT_BIT( 0x8000, IP_ACTIVE_LOW, IPT_UNUSED ) + + PORT_START("DSW1") + PORT_DIPNAME( 0x0001, 0x0001, "Coin Slots" ) PORT_DIPLOCATION("SW1:1") // Listed as "Unused" (manual from different revision/region?), See notes + PORT_DIPSETTING( 0x0001, "Common" ) + PORT_DIPSETTING( 0x0000, "Individual" ) + PORT_DIPNAME( 0x0002, 0x0002, DEF_STR( Allow_Continue ) ) PORT_DIPLOCATION("SW1:2") + PORT_DIPSETTING( 0x0000, DEF_STR( No ) ) + PORT_DIPSETTING( 0x0002, DEF_STR( Yes ) ) + PORT_DIPNAME( 0x000c, 0x000c, "Magazine / Grenade" ) PORT_DIPLOCATION("SW1:3,4") + PORT_DIPSETTING( 0x0008, "5 / 2" ) + PORT_DIPSETTING( 0x000c, "6 / 3" ) + PORT_DIPSETTING( 0x0004, "7 / 4" ) + PORT_DIPSETTING( 0x0000, "8 / 5" ) + PORT_DIPNAME( 0x0030, 0x0030, DEF_STR( Coin_A ) ) PORT_DIPLOCATION("SW1:5,6") // See notes + PORT_DIPSETTING( 0x0000, DEF_STR( 4C_1C ) ) + PORT_DIPSETTING( 0x0010, DEF_STR( 3C_1C ) ) + PORT_DIPSETTING( 0x0020, DEF_STR( 2C_1C ) ) + PORT_DIPSETTING( 0x0030, DEF_STR( 1C_1C ) ) + PORT_DIPNAME( 0x00c0, 0x00c0, DEF_STR( Coin_B ) ) PORT_DIPLOCATION("SW1:7,8") // Listed as "Unused" (manual from different revision/region?), See notes + PORT_DIPSETTING( 0x00c0, DEF_STR( 1C_1C ) ) + PORT_DIPSETTING( 0x0080, DEF_STR( 1C_2C ) ) + PORT_DIPSETTING( 0x0040, DEF_STR( 1C_3C ) ) + PORT_DIPSETTING( 0x0000, DEF_STR( 1C_4C ) ) + PORT_DIPNAME( 0x0300, 0x0300, DEF_STR( Difficulty ) ) PORT_DIPLOCATION("SW2:1,2") + PORT_DIPSETTING( 0x0200, DEF_STR( Easy ) ) + PORT_DIPSETTING( 0x0300, DEF_STR( Normal ) ) + PORT_DIPSETTING( 0x0100, DEF_STR( Hard ) ) + PORT_DIPSETTING( 0x0000, DEF_STR( Hardest ) ) + PORT_DIPNAME( 0x0c00, 0x0c00, "Game Mode" ) PORT_DIPLOCATION("SW2:3,4") + PORT_DIPSETTING( 0x0800, "Demo Sounds Off" ) + PORT_DIPSETTING( 0x0c00, "Demo Sounds On" ) + PORT_DIPSETTING( 0x0400, "Infinite Energy (Cheat)") + PORT_DIPSETTING( 0x0000, "Freeze" ) + PORT_DIPUNUSED_DIPLOC(0x1000, 0x1000, "SW2:5" ) /* Listed as "Unused" */ + PORT_DIPUNUSED_DIPLOC(0x2000, 0x2000, "SW2:6" ) /* Listed as "Unused" */ + PORT_DIPUNUSED_DIPLOC(0x4000, 0x4000, "SW2:7" ) /* Listed as "Unused" */ + PORT_SERVICE_DIPLOC( 0x8000, IP_ACTIVE_LOW, "SW2:8" ) + + PORT_START("GUNX1") + PORT_BIT( 0xff, 0x80, IPT_LIGHTGUN_X ) PORT_CROSSHAIR(X, 1.0, 0.0, 0) PORT_SENSITIVITY(25) PORT_KEYDELTA(10) PORT_PLAYER(1) + PORT_START("GUNY1") + PORT_BIT( 0xff, 0x80, IPT_LIGHTGUN_Y ) PORT_CROSSHAIR(Y, 1.0, 0.0, 0) PORT_SENSITIVITY(25) PORT_KEYDELTA(10) PORT_PLAYER(1) + + PORT_START("GUNX2") + PORT_BIT( 0xff, 0x80, IPT_LIGHTGUN_X ) PORT_CROSSHAIR(X, 1.0, 0.0, 0) PORT_SENSITIVITY(25) PORT_KEYDELTA(10) PORT_PLAYER(2) + PORT_START("GUNY2") + PORT_BIT( 0xff, 0x80, IPT_LIGHTGUN_Y ) PORT_CROSSHAIR(Y, 1.0, 0.0, 0) PORT_SENSITIVITY(25) PORT_KEYDELTA(10) PORT_PLAYER(2) +INPUT_PORTS_END + +static INPUT_PORTS_START( mechattj ) + PORT_INCLUDE( mechatt ) + + PORT_MODIFY("DSW1") + PORT_DIPUNUSED_DIPLOC( 0x0001, 0x0001, "SW1:1" ) +INPUT_PORTS_END + +static INPUT_PORTS_START( mechattu ) + PORT_INCLUDE( mechatt ) + + PORT_MODIFY("DSW1") + PORT_DIPUNUSED_DIPLOC( 0x0001, 0x0001, "SW1:1" ) + PORT_DIPNAME( 0x0030, 0x0030, DEF_STR( Coinage ) ) PORT_DIPLOCATION("SW1:5,6") + PORT_DIPSETTING( 0x0000, DEF_STR( Free_Play ) ) + PORT_DIPSETTING( 0x0010, "1 Coin/2 Credits first, then 1 Coin/1 Credit" ) + PORT_DIPSETTING( 0x0020, "2 Coins/1 Credit first, then 1 Coin/1 Credit" ) + PORT_DIPSETTING( 0x0030, DEF_STR( 1C_1C ) ) + PORT_DIPUNUSED_DIPLOC( 0x00c0, 0x00c0, "SW1:7,8" ) +INPUT_PORTS_END + +static INPUT_PORTS_START( mechattu1 ) + PORT_INCLUDE( mechattu ) + + PORT_MODIFY("IN0") + PORT_BIT( 0x0002, IP_ACTIVE_LOW, IPT_UNUSED ) + PORT_BIT( 0x0010, IP_ACTIVE_LOW, IPT_UNUSED ) + PORT_BIT( 0x0020, IP_ACTIVE_LOW, IPT_UNUSED ) + PORT_BIT( 0x1000, IP_ACTIVE_LOW, IPT_UNUSED ) + PORT_BIT( 0x2000, IP_ACTIVE_LOW, IPT_UNUSED ) + PORT_BIT( 0x4000, IP_ACTIVE_LOW, IPT_UNUSED ) + + PORT_MODIFY("GUNX2") + PORT_BIT( 0xff, IP_ACTIVE_LOW, IPT_UNUSED ) + PORT_MODIFY("GUNY2") + PORT_BIT( 0xff, IP_ACTIVE_LOW, IPT_UNUSED ) +INPUT_PORTS_END + +/******************************************************************************/ + +static const gfx_layout charlayout = +{ + 8,8, + RGN_FRAC(1,1), + 4, + { STEP4(0,1) }, + { STEP8(0,4) }, + { STEP8(0,4*8) }, + 32*8 +}; + +static const gfx_layout tilelayout = +{ + 16,16, /* 16*16 sprites */ + RGN_FRAC(1,1), + 4, /* 4 bits per pixel */ + { STEP4(0,1) }, + { STEP8(0,4), STEP8(4*8*16,4) }, + { STEP16(0,4*8) }, + 128*8 +}; + +static GFXDECODE_START( gfx_mechatt ) + GFXDECODE_ENTRY( "tx_tiles", 0, charlayout, 0, 16 ) + GFXDECODE_ENTRY( "gfx3", 0, tilelayout, 512, 16 ) + GFXDECODE_ENTRY( "gfx4", 0, tilelayout, 768, 16 ) +GFXDECODE_END + + +/******************************************************************************/ + +void mechatt_state::mechatt(machine_config &config) +{ + /* basic machine hardware */ + M68000(config, m_maincpu, 12000000); + m_maincpu->set_addrmap(AS_PROGRAM, &mechatt_state::mechatt_map); + m_maincpu->set_vblank_int("screen", FUNC(mechatt_state::irq4_line_hold)); + + Z80(config, m_audiocpu, 4000000); /* Accurate */ + m_audiocpu->set_addrmap(AS_PROGRAM, &mechatt_state::sound_map); + m_audiocpu->set_addrmap(AS_IO, &mechatt_state::sounda_portmap); + + /* video hardware */ + screen_device &screen(SCREEN(config, "screen", SCREEN_TYPE_RASTER)); + screen.set_refresh_hz(60); + screen.set_size(64*8, 32*8); + screen.set_visarea(0*8, 32*8-1, 2*8, 30*8-1); + screen.set_screen_update(FUNC(mechatt_state::screen_update)); + screen.screen_vblank().set(m_spriteram, FUNC(buffered_spriteram16_device::vblank_copy_rising)); + screen.set_palette("palette"); + + GFXDECODE(config, m_gfxdecode, "palette", gfx_mechatt); + PALETTE(config, "palette").set_format(palette_device::RGBx_444, 1024); + + BUFFERED_SPRITERAM16(config, m_spriteram); + + SNK_BBUSTERS_SPR(config, m_sprites, 0); + m_sprites->set_scaletable_tag("sprites1:scale_table"); + m_sprites->set_palette("palette"); + m_sprites->set_spriteram_tag("spriteram1"); + + /* sound hardware */ + SPEAKER(config, "lspeaker").front_left(); + SPEAKER(config, "rspeaker").front_right(); + + GENERIC_LATCH_8(config, m_soundlatch[0]); + GENERIC_LATCH_8(config, m_soundlatch[1]); + + ym2608_device &ymsnd(YM2608(config, "ymsnd", 8000000)); + ymsnd.irq_handler().set_inputline("audiocpu", 0); + ymsnd.add_route(0, "lspeaker", 0.15); + ymsnd.add_route(0, "rspeaker", 0.15); + ymsnd.add_route(1, "lspeaker", 0.80); + ymsnd.add_route(2, "rspeaker", 0.80); +} + +/******************************************************************************/ + +ROM_START( mechatt ) + ROM_REGION( 0x80000, "maincpu", 0 ) // Located on the A8002-1 main board + ROM_LOAD16_BYTE( "ma5-e.n12", 0x000000, 0x20000, CRC(9bbb852a) SHA1(34b696bf79cf53cac1c384a3143c0f3f243a71f3) ) + ROM_LOAD16_BYTE( "ma4.l12", 0x000001, 0x20000, CRC(0d414918) SHA1(0d51b893d37ba124b983beebb691e65bdc52d300) ) + ROM_LOAD16_BYTE( "ma7.n13", 0x040000, 0x20000, CRC(61d85e1b) SHA1(46234d48ac21c481a5e70c6a654a341ebdd4cd3a) ) + ROM_LOAD16_BYTE( "ma6-f.l13", 0x040001, 0x20000, CRC(4055fe8d) SHA1(b4d8bd5f73805ce1c332eff657dddbb88ff45b37) ) + + ROM_REGION( 0x10000, "audiocpu", 0 ) // Located on the A8002-1 main board + ROM_LOAD( "ma_3.e13", 0x000000, 0x10000, CRC(c06cc8e1) SHA1(65f5f1901120d633f7c3ba07432a188fd7fd7272) ) + + ROM_REGION( 0x020000, "tx_tiles", 0 ) // Located on the A8002-2 board + ROM_LOAD( "ma_1.l2", 0x000000, 0x10000, CRC(24766917) SHA1(9082a8ae849605ce65b5a0493ae69cfe282f7e7b) ) + + ROM_REGION( 0x200000, "sprites1", 0 ) // Located on the A8002-2 board + ROM_LOAD16_WORD_SWAP( "mao89p13.bin", 0x000000, 0x80000, CRC(8bcb16cf) SHA1(409ee1944188d9ce39adce29b1df029b560dd5b0) ) + ROM_LOAD16_WORD_SWAP( "ma189p15.bin", 0x080000, 0x80000, CRC(b84d9658) SHA1(448adecb0067d8f5b219ec2f94a8dec84187a554) ) + ROM_LOAD16_WORD_SWAP( "ma289p17.bin", 0x100000, 0x80000, CRC(6cbe08ac) SHA1(8f81f6e92b84ab6867452011d52f3e7689c62a1a) ) + ROM_LOAD16_WORD_SWAP( "ma389m15.bin", 0x180000, 0x80000, CRC(34d4585e) SHA1(38d9fd5d775e4b3c8b8b487a6ba9b8bdcb3274b0) ) + + ROM_REGION( 0x80000, "gfx3", 0 ) // Located on the A8002-2 board + ROM_LOAD( "mab189a2.bin", 0x000000, 0x80000, CRC(e1c8b4d0) SHA1(2f8a1839cca892f8380c7cffe7a12e615d38fd55) ) + + ROM_REGION( 0x80000, "gfx4", 0 ) // Located on the A8002-2 board + ROM_LOAD( "mab289c2.bin", 0x000000, 0x80000, CRC(14f97ceb) SHA1(a22033532ea616dc3a3db8b66ad6ccc6172ed7cc) ) + + ROM_REGION( 0x20000, "ymsnd", 0 ) // Located on the A8002-1 main board + ROM_LOAD( "ma_2.d10", 0x000000, 0x20000, CRC(ea4cc30d) SHA1(d8f089fc0ce76309411706a8110ad907f93dc97e) ) + + ROM_REGION( 0x20000, "sprites1:scale_table", 0 ) // Zoom table - Located on the A8002-2 board + ROM_LOAD( "ma_8.f10", 0x000000, 0x10000, CRC(61f3de03) SHA1(736f9634fe054ea68a2aa90a743bd0dc320f23c9) ) + ROM_LOAD( "ma_9.f12", 0x000000, 0x10000, CRC(61f3de03) SHA1(736f9634fe054ea68a2aa90a743bd0dc320f23c9) ) // identical to ma_8.f10 +ROM_END + +ROM_START( mechattj ) // Uses EPROMs on official SNK A8002-5 & A8002-6 sub boards instead of MaskROMs + ROM_REGION( 0x80000, "maincpu", 0 ) // Located on the A8002-1 main board + ROM_LOAD16_BYTE( "ma5j.n12", 0x000000, 0x20000, CRC(e6bb5952) SHA1(3b01eccc20d99fd33ff8e303afa902abb66e1036) ) + ROM_LOAD16_BYTE( "ma4j.l12", 0x000001, 0x20000, CRC(c78baa62) SHA1(c3554698fbc94e3625269c5cb1fc664364f3fb3f) ) + ROM_LOAD16_BYTE( "ma7j.n13", 0x040000, 0x20000, CRC(12a68fc2) SHA1(c935788723d8ea3bfe99244b8c7b2aff85579912) ) + ROM_LOAD16_BYTE( "ma6j.l13", 0x040001, 0x20000, CRC(332b2f54) SHA1(c768f5437a20ea406523d3de9e1ea807b39e1622) ) + + ROM_REGION( 0x10000, "audiocpu", 0 ) // Located on the A8002-1 main board + ROM_LOAD( "ma_3.e13", 0x000000, 0x10000, CRC(c06cc8e1) SHA1(65f5f1901120d633f7c3ba07432a188fd7fd7272) ) + + ROM_REGION( 0x020000, "tx_tiles", 0 ) // Located on the A8002-2 board + ROM_LOAD( "ma_1.l2", 0x000000, 0x10000, CRC(24766917) SHA1(9082a8ae849605ce65b5a0493ae69cfe282f7e7b) ) + + ROM_REGION( 0x200000, "sprites1", 0 ) // Located on the A8002-6 sub board + ROM_LOAD16_BYTE( "s_9.a1", 0x000001, 0x20000, CRC(6e8e194c) SHA1(02bbd573a322a3f7f8e92ccceebffdd598b5489e) ) // these 4 == mao89p13.bin + ROM_LOAD16_BYTE( "s_1.b1", 0x000000, 0x20000, CRC(fd9161ed) SHA1(b3e2434dd9cb1cafe1022774b863b5f1a008a9d2) ) + ROM_LOAD16_BYTE( "s_10.a2", 0x040001, 0x20000, CRC(fad6a1ab) SHA1(5347b4493c8004dc8cedc0b37aba494f203142b8) ) + ROM_LOAD16_BYTE( "s_2.b2", 0x040000, 0x20000, CRC(549056f0) SHA1(f515aa98ab25f3735dbfdefcb8d55ba3b2075b70) ) + ROM_LOAD16_BYTE( "s_11.a3", 0x080001, 0x20000, CRC(3887a382) SHA1(b40861fc1414b2fa299772e76a78cb8dc00b71b7) ) // these 4 == ma189p15.bin + ROM_LOAD16_BYTE( "s_3.b3", 0x080000, 0x20000, CRC(cb99f565) SHA1(9ed1b21f4a33b9a614bca38610378857560cdaba) ) + ROM_LOAD16_BYTE( "s_12.a4", 0x0c0001, 0x20000, CRC(63417b49) SHA1(786249fa7e8770de5b5882debdc2913d58e9170e) ) + ROM_LOAD16_BYTE( "s_4.b4", 0x0c0000, 0x20000, CRC(d739d48a) SHA1(04d2ecea72b6e651b815865946c9c9cfae4e5c4d) ) + ROM_LOAD16_BYTE( "s_13.a5", 0x100001, 0x20000, CRC(eccd47b6) SHA1(6b9c63fee97a7568114f227a89a1effd6b04806a) ) // these 4 == ma289p17.bin + ROM_LOAD16_BYTE( "s_5.b5", 0x100000, 0x20000, CRC(e15244da) SHA1(ebf3072565c53d0098d373b5093ba6918c4eddae) ) + ROM_LOAD16_BYTE( "s_14.a6", 0x140001, 0x20000, CRC(bbbf0461) SHA1(c5299ab1d45f685a5d160492247cf1303ef6937a) ) + ROM_LOAD16_BYTE( "s_6.b6", 0x140000, 0x20000, CRC(4ee89f75) SHA1(bda0e9095da2d424faac341fd934000a621796eb) ) + ROM_LOAD16_BYTE( "s_15.a7", 0x180001, 0x20000, CRC(cde29bad) SHA1(24c1b43c6d717eaaf7c01ec7de89837947334224) ) // these 4 == ma389m15.bin + ROM_LOAD16_BYTE( "s_7.b7", 0x180000, 0x20000, CRC(065ed221) SHA1(c03ca5b4d1198939a57b5fccf6a79d70afe1faaf) ) + ROM_LOAD16_BYTE( "s_16.a8", 0x1c0001, 0x20000, CRC(70f28040) SHA1(91012728953563fcc576725337e6ba7e1b49d1ba) ) + ROM_LOAD16_BYTE( "s_8.b8", 0x1c0000, 0x20000, CRC(a6f8574f) SHA1(87c041669b2eaec495ae10a6f45b6668accb92bf) ) + + ROM_REGION( 0x80000, "gfx3", 0 ) // these 4 == mab189a2.bin - Located on the A8002-5 sub board + ROM_LOAD( "s_21.b3", 0x000000, 0x20000, CRC(701a0072) SHA1(b03b6fa18e0cfcd5c7c541025fa2d3632d2f8387) ) + ROM_LOAD( "s_22.b4", 0x020000, 0x20000, CRC(34e6225c) SHA1(f6335084f4f4c7a4b6528e6ad74962b88f81e3bc) ) + ROM_LOAD( "s_23.b5", 0x040000, 0x20000, CRC(9a7399d3) SHA1(04e0327b0da75f621b51e1831cbdc4537082e32b) ) + ROM_LOAD( "s_24.b6", 0x060000, 0x20000, CRC(f097459d) SHA1(466364677f048519eb2894ddecf76f5c52f6afe9) ) + + ROM_REGION( 0x80000, "gfx4", 0 ) // these 4 == mab289c2.bin - Located on the A8002-5 sub board + ROM_LOAD( "s_17.a3", 0x000000, 0x20000, CRC(cc47c4a3) SHA1(140f53b671b4eaed6fcc516c4018f07a6d7c2290) ) + ROM_LOAD( "s_18.a4", 0x020000, 0x20000, CRC(a04377e8) SHA1(841c6c3073b137f6a5c875db32039186c014f785) ) + ROM_LOAD( "s_19.a5", 0x040000, 0x20000, CRC(b07f5289) SHA1(8817bd225edf9b0fa439b220617f925365e39253) ) + ROM_LOAD( "s_20.a6", 0x060000, 0x20000, CRC(a9bb4fa9) SHA1(ccede784671a864667b92a8101d686c26c78d76f) ) + + ROM_REGION( 0x20000, "ymsnd", 0 ) // Located on the A8002-1 main board + ROM_LOAD( "ma_2.d10", 0x000000, 0x20000, CRC(ea4cc30d) SHA1(d8f089fc0ce76309411706a8110ad907f93dc97e) ) + + ROM_REGION( 0x20000, "sprites1:scale_table", 0 ) // Zoom table - Located on the A8002-2 board + ROM_LOAD( "ma_8.f10", 0x000000, 0x10000, CRC(61f3de03) SHA1(736f9634fe054ea68a2aa90a743bd0dc320f23c9) ) + ROM_LOAD( "ma_9.f12", 0x000000, 0x10000, CRC(61f3de03) SHA1(736f9634fe054ea68a2aa90a743bd0dc320f23c9) ) // identical to ma_8.f10 +ROM_END + +ROM_START( mechattu ) + ROM_REGION( 0x80000, "maincpu", 0 ) // Located on the A8002-1 main board + ROM_LOAD16_BYTE( "ma5u.n12", 0x000000, 0x20000, CRC(485ea606) SHA1(0c499f08d7c6d861ba7c50a8f577823613a7923c) ) + ROM_LOAD16_BYTE( "ma4u.l12", 0x000001, 0x20000, CRC(09fa31ec) SHA1(008abb2e09f83614c277471e534f20cba3e354d7) ) + ROM_LOAD16_BYTE( "ma7u.n13", 0x040000, 0x20000, CRC(f45b2c70) SHA1(65523d202d378bab890f1f7bffdde152dd246d4a) ) + ROM_LOAD16_BYTE( "ma6u.l13", 0x040001, 0x20000, CRC(d5d68ce6) SHA1(16057d882781015f6d1c7bb659e0812a8459c3f0) ) + + ROM_REGION( 0x10000, "audiocpu", 0 ) // Located on the A8002-1 main board + ROM_LOAD( "ma_3.e13", 0x000000, 0x10000, CRC(c06cc8e1) SHA1(65f5f1901120d633f7c3ba07432a188fd7fd7272) ) + + ROM_REGION( 0x020000, "tx_tiles", 0 ) // Located on the A8002-2 board + ROM_LOAD( "ma_1.l2", 0x000000, 0x10000, CRC(24766917) SHA1(9082a8ae849605ce65b5a0493ae69cfe282f7e7b) ) + + ROM_REGION( 0x200000, "sprites1", 0 ) // Located on the A8002-2 board + ROM_LOAD16_WORD_SWAP( "mao89p13.bin", 0x000000, 0x80000, CRC(8bcb16cf) SHA1(409ee1944188d9ce39adce29b1df029b560dd5b0) ) + ROM_LOAD16_WORD_SWAP( "ma189p15.bin", 0x080000, 0x80000, CRC(b84d9658) SHA1(448adecb0067d8f5b219ec2f94a8dec84187a554) ) + ROM_LOAD16_WORD_SWAP( "ma289p17.bin", 0x100000, 0x80000, CRC(6cbe08ac) SHA1(8f81f6e92b84ab6867452011d52f3e7689c62a1a) ) + ROM_LOAD16_WORD_SWAP( "ma389m15.bin", 0x180000, 0x80000, CRC(34d4585e) SHA1(38d9fd5d775e4b3c8b8b487a6ba9b8bdcb3274b0) ) + + ROM_REGION( 0x80000, "gfx3", 0 ) // Located on the A8002-2 board + ROM_LOAD( "mab189a2.bin", 0x000000, 0x80000, CRC(e1c8b4d0) SHA1(2f8a1839cca892f8380c7cffe7a12e615d38fd55) ) + + ROM_REGION( 0x80000, "gfx4", 0 ) // Located on the A8002-2 board + ROM_LOAD( "mab289c2.bin", 0x000000, 0x80000, CRC(14f97ceb) SHA1(a22033532ea616dc3a3db8b66ad6ccc6172ed7cc) ) + + ROM_REGION( 0x20000, "ymsnd", 0 ) // Located on the A8002-1 main board + ROM_LOAD( "ma_2.d10", 0x000000, 0x20000, CRC(ea4cc30d) SHA1(d8f089fc0ce76309411706a8110ad907f93dc97e) ) + + ROM_REGION( 0x20000, "sprites1:scale_table", 0 ) // Zoom table - Located on the A8002-2 board + ROM_LOAD( "ma_8.f10", 0x000000, 0x10000, CRC(61f3de03) SHA1(736f9634fe054ea68a2aa90a743bd0dc320f23c9) ) + ROM_LOAD( "ma_9.f12", 0x000000, 0x10000, CRC(61f3de03) SHA1(736f9634fe054ea68a2aa90a743bd0dc320f23c9) ) // identical to ma_8.f10 +ROM_END + +/* does Ver1 on the roms mean it's a revision, the first version, or used because it's the single player version? */ +ROM_START( mechattu1 ) // Uses EPROMs on official SNK A8002-5 & A8002-6 sub boards instead of MaskROMs + ROM_REGION( 0x80000, "maincpu", 0 ) // Located on the A8002-1 main board + ROM_LOAD16_BYTE( "ma_ver1_5u.n12", 0x000000, 0x20000, CRC(dcd2e971) SHA1(e292b251c429b6990e97233e86360e5d43f573f2) ) + ROM_LOAD16_BYTE( "ma_ver1_4u.l12", 0x000001, 0x20000, CRC(69c8a85b) SHA1(07c6d395772a5e096e3ac42c5248eadccc146ad1) ) + ROM_LOAD16_BYTE( "ma7u.n13", 0x040000, 0x20000, CRC(f45b2c70) SHA1(65523d202d378bab890f1f7bffdde152dd246d4a) ) + ROM_LOAD16_BYTE( "ma6u.l13", 0x040001, 0x20000, CRC(d5d68ce6) SHA1(16057d882781015f6d1c7bb659e0812a8459c3f0) ) + + ROM_REGION( 0x10000, "audiocpu", 0 ) // Located on the A8002-1 main board + ROM_LOAD( "ma_3.e13", 0x000000, 0x10000, CRC(c06cc8e1) SHA1(65f5f1901120d633f7c3ba07432a188fd7fd7272) ) + + ROM_REGION( 0x020000, "tx_tiles", 0 ) // Located on the A8002-2 board + ROM_LOAD( "ma_1.l2", 0x000000, 0x10000, CRC(24766917) SHA1(9082a8ae849605ce65b5a0493ae69cfe282f7e7b) ) + + ROM_REGION( 0x200000, "sprites1", 0 ) // Located on the A8002-6 sub board + ROM_LOAD16_BYTE( "s_9.a1", 0x000001, 0x20000, CRC(6e8e194c) SHA1(02bbd573a322a3f7f8e92ccceebffdd598b5489e) ) // these 4 == mao89p13.bin + ROM_LOAD16_BYTE( "s_1.b1", 0x000000, 0x20000, CRC(fd9161ed) SHA1(b3e2434dd9cb1cafe1022774b863b5f1a008a9d2) ) + ROM_LOAD16_BYTE( "s_10.a2", 0x040001, 0x20000, CRC(fad6a1ab) SHA1(5347b4493c8004dc8cedc0b37aba494f203142b8) ) + ROM_LOAD16_BYTE( "s_2.b2", 0x040000, 0x20000, CRC(549056f0) SHA1(f515aa98ab25f3735dbfdefcb8d55ba3b2075b70) ) + ROM_LOAD16_BYTE( "s_11.a3", 0x080001, 0x20000, CRC(3887a382) SHA1(b40861fc1414b2fa299772e76a78cb8dc00b71b7) ) // these 4 == ma189p15.bin + ROM_LOAD16_BYTE( "s_3.b3", 0x080000, 0x20000, CRC(cb99f565) SHA1(9ed1b21f4a33b9a614bca38610378857560cdaba) ) + ROM_LOAD16_BYTE( "s_12.a4", 0x0c0001, 0x20000, CRC(63417b49) SHA1(786249fa7e8770de5b5882debdc2913d58e9170e) ) + ROM_LOAD16_BYTE( "s_4.b4", 0x0c0000, 0x20000, CRC(d739d48a) SHA1(04d2ecea72b6e651b815865946c9c9cfae4e5c4d) ) + ROM_LOAD16_BYTE( "s_13.a5", 0x100001, 0x20000, CRC(eccd47b6) SHA1(6b9c63fee97a7568114f227a89a1effd6b04806a) ) // these 4 == ma289p17.bin + ROM_LOAD16_BYTE( "s_5.b5", 0x100000, 0x20000, CRC(e15244da) SHA1(ebf3072565c53d0098d373b5093ba6918c4eddae) ) + ROM_LOAD16_BYTE( "s_14.a6", 0x140001, 0x20000, CRC(bbbf0461) SHA1(c5299ab1d45f685a5d160492247cf1303ef6937a) ) + ROM_LOAD16_BYTE( "s_6.b6", 0x140000, 0x20000, CRC(4ee89f75) SHA1(bda0e9095da2d424faac341fd934000a621796eb) ) + ROM_LOAD16_BYTE( "s_15.a7", 0x180001, 0x20000, CRC(cde29bad) SHA1(24c1b43c6d717eaaf7c01ec7de89837947334224) ) // these 4 == ma389m15.bin + ROM_LOAD16_BYTE( "s_7.b7", 0x180000, 0x20000, CRC(065ed221) SHA1(c03ca5b4d1198939a57b5fccf6a79d70afe1faaf) ) + ROM_LOAD16_BYTE( "s_16.a8", 0x1c0001, 0x20000, CRC(70f28040) SHA1(91012728953563fcc576725337e6ba7e1b49d1ba) ) + ROM_LOAD16_BYTE( "s_8.b8", 0x1c0000, 0x20000, CRC(a6f8574f) SHA1(87c041669b2eaec495ae10a6f45b6668accb92bf) ) + + ROM_REGION( 0x80000, "gfx3", 0 ) // these 4 == mab189a2.bin - Located on the A8002-5 sub board + ROM_LOAD( "s_21.b3", 0x000000, 0x20000, CRC(701a0072) SHA1(b03b6fa18e0cfcd5c7c541025fa2d3632d2f8387) ) + ROM_LOAD( "s_22.b4", 0x020000, 0x20000, CRC(34e6225c) SHA1(f6335084f4f4c7a4b6528e6ad74962b88f81e3bc) ) + ROM_LOAD( "s_23.b5", 0x040000, 0x20000, CRC(9a7399d3) SHA1(04e0327b0da75f621b51e1831cbdc4537082e32b) ) + ROM_LOAD( "s_24.b6", 0x060000, 0x20000, CRC(f097459d) SHA1(466364677f048519eb2894ddecf76f5c52f6afe9) ) + + ROM_REGION( 0x80000, "gfx4", 0 ) // these 4 == mab289c2.bin - Located on the A8002-5 sub board + ROM_LOAD( "s_17.a3", 0x000000, 0x20000, CRC(cc47c4a3) SHA1(140f53b671b4eaed6fcc516c4018f07a6d7c2290) ) + ROM_LOAD( "s_18.a4", 0x020000, 0x20000, CRC(a04377e8) SHA1(841c6c3073b137f6a5c875db32039186c014f785) ) + ROM_LOAD( "s_19.a5", 0x040000, 0x20000, CRC(b07f5289) SHA1(8817bd225edf9b0fa439b220617f925365e39253) ) + ROM_LOAD( "s_20.a6", 0x060000, 0x20000, CRC(a9bb4fa9) SHA1(ccede784671a864667b92a8101d686c26c78d76f) ) + + ROM_REGION( 0x20000, "ymsnd", 0 ) // Located on the A8002-1 main board + ROM_LOAD( "ma_2.d10", 0x000000, 0x20000, CRC(ea4cc30d) SHA1(d8f089fc0ce76309411706a8110ad907f93dc97e) ) + + ROM_REGION( 0x20000, "sprites1:scale_table", 0 ) // Zoom table - Located on the A8002-2 board + ROM_LOAD( "ma_8.f10", 0x000000, 0x10000, CRC(61f3de03) SHA1(736f9634fe054ea68a2aa90a743bd0dc320f23c9) ) + ROM_LOAD( "ma_9.f12", 0x000000, 0x10000, CRC(61f3de03) SHA1(736f9634fe054ea68a2aa90a743bd0dc320f23c9) ) // identical to ma_8.f10 +ROM_END + + +/******************************************************************************/ + +GAME( 1989, mechatt, 0, mechatt, mechatt, mechatt_state, empty_init, ROT0, "SNK", "Mechanized Attack (World)", MACHINE_SUPPORTS_SAVE ) +GAME( 1989, mechattj, mechatt, mechatt, mechattj, mechatt_state, empty_init, ROT0, "SNK", "Mechanized Attack (Japan)", MACHINE_SUPPORTS_SAVE ) +GAME( 1989, mechattu, mechatt, mechatt, mechattu, mechatt_state, empty_init, ROT0, "SNK", "Mechanized Attack (US)", MACHINE_SUPPORTS_SAVE ) +GAME( 1989, mechattu1, mechatt, mechatt, mechattu1,mechatt_state, empty_init, ROT0, "SNK", "Mechanized Attack (US, Version 1, Single Player)", MACHINE_SUPPORTS_SAVE ) diff --git a/src/mame/includes/bbusters.h b/src/mame/includes/bbusters.h deleted file mode 100644 index 251888e4419..00000000000 --- a/src/mame/includes/bbusters.h +++ /dev/null @@ -1,115 +0,0 @@ -// license:BSD-3-Clause -// copyright-holders:Bryan McPhail -#ifndef MAME_INCLUDES_BBUSTERS_H -#define MAME_INCLUDES_BBUSTERS_H - -#pragma once - -#include "machine/gen_latch.h" -#include "video/bufsprite.h" -#include "screen.h" -#include "tilemap.h" - -class bbusters_state_base : public driver_device -{ -protected: - bbusters_state_base(const machine_config &mconfig, device_type type, const char *tag) : - driver_device(mconfig, type, tag), - m_maincpu(*this, "maincpu"), - m_audiocpu(*this, "audiocpu"), - m_gfxdecode(*this, "gfxdecode"), - m_spriteram(*this, "spriteram%u", 1U), - m_soundlatch(*this, "soundlatch%u", 1U), - m_videoram(*this, "videoram"), - m_pf_data(*this, "pf%u_data", 1U), - m_pf_scroll_data(*this, "pf%u_scroll_data", 1U), - m_scale_table(*this, "scale_table"), - m_gun_io(*this, { "GUNX1", "GUNY1", "GUNX2", "GUNY2", "GUNX3", "GUNY3" }), - m_gun_recoil(*this, "Player%u_Gun_Recoil", 1U) - { } - - required_device m_maincpu; - required_device m_audiocpu; - required_device m_gfxdecode; - optional_device_array m_spriteram; - required_device_array m_soundlatch; - - required_shared_ptr m_videoram; - required_shared_ptr_array m_pf_data; - required_shared_ptr_array m_pf_scroll_data; - - required_region_ptr m_scale_table; - - optional_ioport_array<6> m_gun_io; - output_finder<3> m_gun_recoil; - - tilemap_t *m_fix_tilemap; - tilemap_t *m_pf_tilemap[2]; - const uint8_t *m_scale_table_ptr; - uint8_t m_scale_line_count; - - virtual void machine_start() override; - virtual void video_start() override; - - TILE_GET_INFO_MEMBER(get_tile_info); - template TILE_GET_INFO_MEMBER(get_pf_tile_info); - - void sound_cpu_w(uint8_t data); - void video_w(offs_t offset, uint16_t data, uint16_t mem_mask = ~0); - template void pf_w(offs_t offset, uint16_t data, uint16_t mem_mask = ~0); - void coin_counter_w(uint8_t data); - - const uint8_t *get_source_ptr(gfx_element *gfx, uint32_t sprite, int dx, int dy, int block); - void draw_block(screen_device &screen, bitmap_ind16 &dest,int x,int y,int size,int flipx,int flipy,uint32_t sprite,int color,int bank,int block,int priority); - void draw_sprites(screen_device &screen, bitmap_ind16 &bitmap, const uint16_t *source, int bank); - - void sound_map(address_map &map); -}; - -class bbusters_state : public bbusters_state_base -{ -public: - bbusters_state(const machine_config &mconfig, device_type type, const char *tag) : - bbusters_state_base(mconfig, type, tag), - m_eprom_data(*this, "eeprom") - { } - - void bbusters(machine_config &config); - -protected: - virtual void machine_start() override; - virtual void video_start() override; - -private: - required_shared_ptr m_eprom_data; - - uint16_t eprom_r(offs_t offset); - void three_gun_output_w(uint16_t data); - - uint32_t screen_update(screen_device &screen, bitmap_ind16 &bitmap, const rectangle &cliprect); - void bbusters_map(address_map &map); - void sound_portmap(address_map &map); -}; - -class mechatt_state : public bbusters_state_base -{ -public: - mechatt_state(const machine_config &mconfig, device_type type, const char *tag) : - bbusters_state_base(mconfig, type, tag) - { } - - void mechatt(machine_config &config); - -protected: - virtual void video_start() override; - -private: - void two_gun_output_w(uint16_t data); - uint16_t mechatt_gun_r(offs_t offset); - - uint32_t screen_update(screen_device &screen, bitmap_ind16 &bitmap, const rectangle &cliprect); - void mechatt_map(address_map &map); - void sounda_portmap(address_map &map); -}; - -#endif // MAME_INCLUDES_BBUSTERS_H diff --git a/src/mame/mame.lst b/src/mame/mame.lst index 0523314d107..26b23dc3288 100644 --- a/src/mame/mame.lst +++ b/src/mame/mame.lst @@ -3330,10 +3330,6 @@ bbustersu // A9003 'BB' (c) 1989 bbustersua // A9003 'BB' (c) 1989 bbustersj // bbustersja // -mechatt // A8002 'MA' (c) 1989 -mechattj // A8002 'MA' (c) 1989 -mechattu // A8002 'MA' (c) 1989 -mechattu1 // A8002 'MA' (c) 1989 @source:bcs3.cpp bcs3 // @@ -22443,6 +22439,12 @@ cgunship // (c) 1976 Meadows ckidzo // (c) 1976 Meadows mead4in1 // (c) 197? Meadows +@source:mechatt.cpp +mechatt // A8002 'MA' (c) 1989 +mechattj // A8002 'MA' (c) 1989 +mechattu // A8002 'MA' (c) 1989 +mechattu1 // A8002 'MA' (c) 1989 + @source:mediagx.cpp a51site4 // ?? (c) 1998 a51site4a // Sept.11,1998 (c) 1998 diff --git a/src/mame/video/bbusters.cpp b/src/mame/video/bbusters.cpp deleted file mode 100644 index ffb748fab9a..00000000000 --- a/src/mame/video/bbusters.cpp +++ /dev/null @@ -1,297 +0,0 @@ -// license:BSD-3-Clause -// copyright-holders:Bryan McPhail -/*************************************************************************** - - Emulation by Bryan McPhail, mish@tendril.co.uk - - Like NeoGeo sprite scale Y line selection is from an external rom. - - For 16 high sprites scale data starts at 0x3800 (9 scale levels) - For 32 high sprites scale data starts at 0x7000 (17 scale levels) - For 64 high sprites scale data starts at 0xa000 (33 scale levels) - For 128 pixel high sprites scale data starts 0xc000 (65 scale levels) - - 0xe000 and up - possibly X scale data? unconfirmed - - Sprites are also double buffered, and this seems to be performed - by having two complete sprite chips that are toggled per frame, rather - than just ram. Beast Busters has 4 sprite chips as it has two sprite - banks. - -***************************************************************************/ - -#include "emu.h" -#include "includes/bbusters.h" - - -/******************************************************************************/ - -TILE_GET_INFO_MEMBER(bbusters_state_base::get_tile_info) -{ - uint16_t tile = m_videoram[tile_index]; - - tileinfo.set(0,tile&0xfff,tile>>12,0); -} - -template -TILE_GET_INFO_MEMBER(bbusters_state_base::get_pf_tile_info) -{ - uint16_t tile = m_pf_data[Layer][tile_index]; - - tileinfo.set(Gfx,tile&0xfff,tile>>12,0); -} - -void bbusters_state_base::video_w(offs_t offset, uint16_t data, uint16_t mem_mask) -{ - COMBINE_DATA(&m_videoram[offset]); - m_fix_tilemap->mark_tile_dirty(offset); -} - -/******************************************************************************/ - -void bbusters_state_base::video_start() -{ - m_fix_tilemap = &machine().tilemap().create(*m_gfxdecode, tilemap_get_info_delegate(*this, FUNC(bbusters_state_base::get_tile_info)), TILEMAP_SCAN_ROWS, 8, 8, 32, 32); - m_fix_tilemap->set_transparent_pen(15); - - save_item(NAME(m_scale_line_count)); -} - -void bbusters_state::video_start() -{ - bbusters_state_base::video_start(); - - m_pf_tilemap[0] = &machine().tilemap().create(*m_gfxdecode, tilemap_get_info_delegate(*this, NAME((&bbusters_state::get_pf_tile_info<0,3>))), TILEMAP_SCAN_COLS, 16, 16, 128, 32); - m_pf_tilemap[1] = &machine().tilemap().create(*m_gfxdecode, tilemap_get_info_delegate(*this, NAME((&bbusters_state::get_pf_tile_info<1,4>))), TILEMAP_SCAN_COLS, 16, 16, 128, 32); - - m_pf_tilemap[0]->set_transparent_pen(15); -} - -void mechatt_state::video_start() -{ - bbusters_state_base::video_start(); - - m_pf_tilemap[0] = &machine().tilemap().create(*m_gfxdecode, tilemap_get_info_delegate(*this, NAME((&mechatt_state::get_pf_tile_info<0,2>))), TILEMAP_SCAN_COLS, 16, 16, 256, 32); - m_pf_tilemap[1] = &machine().tilemap().create(*m_gfxdecode, tilemap_get_info_delegate(*this, NAME((&mechatt_state::get_pf_tile_info<1,3>))), TILEMAP_SCAN_COLS, 16, 16, 256, 32); - - m_pf_tilemap[0]->set_transparent_pen(15); -} - -/******************************************************************************/ - -#define ADJUST_4x4 \ - if ((dx&0x10) && (dy&0x10)) code+=3; \ - else if (dy&0x10) code+=2; \ - else if (dx&0x10) code+=1 - -#define ADJUST_8x8 \ - if ((dx&0x20) && (dy&0x20)) code+=12; \ - else if (dy&0x20) code+=8; \ - else if (dx&0x20) code+=4 - -#define ADJUST_16x16 \ - if ((dx&0x40) && (dy&0x40)) code+=48; \ - else if (dy&0x40) code+=32; \ - else if (dx&0x40) code+=16 - -inline const uint8_t *bbusters_state_base::get_source_ptr(gfx_element *gfx, uint32_t sprite, int dx, int dy, int block) -{ - int code=0; - - /* Get a tile index from the x,y position in the block */ - switch (block) - { - case 0: /* 16 x 16 sprite */ - break; - - case 1: /* 32 x 32 block - 0 1 - 2 3 - */ - ADJUST_4x4; - break; - - case 2: /* 64 by 64 block - 0 1 4 5 - 2 3 6 7 - - 8 9 12 13 - 10 11 14 15 - */ - ADJUST_4x4; - ADJUST_8x8; - break; - - case 3: /* 128 by 128 block */ - ADJUST_4x4; - ADJUST_8x8; - ADJUST_16x16; - break; - } - - return gfx->get_data((sprite+code) % gfx->elements()) + ((dy%16) * gfx->rowbytes()); -} - -void bbusters_state_base::draw_block(screen_device &screen, bitmap_ind16 &dest,int x,int y,int size,int flipx,int flipy,uint32_t sprite,int color,int bank,int block,int priority) -{ - gfx_element *gfx = m_gfxdecode->gfx(bank); - pen_t pen_base = gfx->colorbase() + gfx->granularity() * (color % gfx->colors()); - uint32_t xinc=(m_scale_line_count * 0x10000 ) / size; - int dy=y; - int ex = m_scale_line_count; - - while (m_scale_line_count) { - if (dy>=16 && dy<240) { - uint16_t *const destline = &dest.pix(dy); - uint8_t *const priorityline = &screen.priority().pix(dy); - uint8_t srcline=*m_scale_table_ptr; - const uint8_t *srcptr=nullptr; - - if (!flipy) - srcline=size-srcline-1; - - int x_index; - if (flipx) - x_index=(ex-1)*0x10000; - else - x_index=0; - - for (int sx=0; sx priorityline[(x+(x_index>>16)) & 0x1ff]) - { - priorityline[(x+(x_index>>16)) & 0x1ff] = priority; - destline[(x+(x_index>>16)) & 0x1ff]= pen_base + pixel; - } - - if (flipx) - x_index-=xinc; - else - x_index+=xinc; - } - } - - dy++; - m_scale_table_ptr--; - m_scale_line_count--; - } -} - -void bbusters_state_base::draw_sprites(screen_device &screen, bitmap_ind16 &bitmap, const uint16_t *source, int bank) -{ - int offs; - - // Sprites are stored in memory in back to front order. - // We draw them here front to back with a priority buffer in case any sprite - // with priority under a tilemap is later in the list than a sprite with - // above tilemap priority (which would cause a cut-out as only the top-most sprite - // in the line buffer goes to the priority mixer) - for (offs = 0x7fc;offs >=0 ;offs -= 4) { - int x,sprite,colour,fx,fy,scale; - int16_t y; - int block; - int priority; - - sprite=source[offs+1]; - colour=source[offs+0]; - - if ((colour==0xf7 || colour==0xffff || colour == 0x43f9) && (sprite==0x3fff || sprite==0xffff || sprite==0x0001)) - continue; // sprite 1, color 0x43f9 is the dead sprite in the top-right of the screen in Mechanized Attack's High Score table. - - y=source[offs+3]; - x=source[offs+2]; - if (x&0x200) x=-(0x100-(x&0xff)); - if (y > 320 || y < -256) y &= 0x1ff; // fix for bbusters ending & "Zing!" attract-mode fullscreen zombie & Helicopter on the 3rd rotation of the attractmode sequence - - /* - Source[0]: - 0xf000: Colour - 0x0800: FX - 0x0400: FY? - 0x0300: Block control - 0x0080: ? - 0x007f: scale - - Scale varies according to block size. - Block type 0: 0x70 = no scale, 0x7f == half size - 16 pixel sprite - Block type 1: 0x60 = no scale, 0x6f == half size - 32 pixel sprite - Block type 2: 0x40 = no scale, 0x5f == half size - 64 pixel sprite - Block type 3: 0x00 = no scale, 0x3f == half size - 128 pixel sprite - - */ - colour=colour>>12; - block=(source[offs+0]>>8)&0x3; - fy=source[offs+0]&0x400; - fx=source[offs+0]&0x800; - sprite=sprite&0x3fff; - - // Palettes 0xc-0xf confirmed to be behind tilemap on Beast Busters for 2nd sprite chip - priority = (bank==2) ? (((colour&0xc)==0xc) ? 1 : 4) : 8; - - switch ((source[offs+0]>>8)&0x3) { - case 0: - scale=source[offs+0]&0x7; - m_scale_table_ptr = m_scale_table+0x387f+(0x80*scale); - m_scale_line_count = 0x10-scale; - draw_block(screen,bitmap,x,y,16,fx,fy,sprite,colour,bank,block,priority); - break; - case 1: /* 2 x 2 */ - scale=source[offs+0]&0xf; - m_scale_table_ptr = m_scale_table+0x707f+(0x80*scale); - m_scale_line_count = 0x20-scale; - draw_block(screen,bitmap,x,y,32,fx,fy,sprite,colour,bank,block,priority); - break; - case 2: /* 64 by 64 block (2 x 2) x 2 */ - scale=source[offs+0]&0x1f; - m_scale_table_ptr = m_scale_table+0xa07f+(0x80*scale); - m_scale_line_count = 0x40-scale; - draw_block(screen,bitmap,x,y,64,fx,fy,sprite,colour,bank,block,priority); - break; - case 3: /* 2 x 2 x 2 x 2 */ - scale=source[offs+0]&0x3f; - m_scale_table_ptr = m_scale_table+0xc07f+(0x80*scale); - m_scale_line_count = 0x80-scale; - draw_block(screen,bitmap,x,y,128,fx,fy,sprite,colour,bank,block,priority); - break; - } - } -} - -/******************************************************************************/ - -uint32_t bbusters_state::screen_update(screen_device &screen, bitmap_ind16 &bitmap, const rectangle &cliprect) -{ - screen.priority().fill(0, cliprect); - - m_pf_tilemap[0]->set_scrollx(0, m_pf_scroll_data[0][0]); - m_pf_tilemap[0]->set_scrolly(0, m_pf_scroll_data[0][1]); - m_pf_tilemap[1]->set_scrollx(0, m_pf_scroll_data[1][0]); - m_pf_tilemap[1]->set_scrolly(0, m_pf_scroll_data[1][1]); - - m_pf_tilemap[1]->draw(screen, bitmap, cliprect, 0, 0); - m_pf_tilemap[0]->draw(screen, bitmap, cliprect, 0, 2); - draw_sprites(screen, bitmap, m_spriteram[1]->buffer(), 2); - draw_sprites(screen, bitmap, m_spriteram[0]->buffer(), 1); - m_fix_tilemap->draw(screen, bitmap, cliprect, 0, 0); - - return 0; -} - -uint32_t mechatt_state::screen_update(screen_device &screen, bitmap_ind16 &bitmap, const rectangle &cliprect) -{ - screen.priority().fill(0, cliprect); - - m_pf_tilemap[0]->set_scrollx(0, m_pf_scroll_data[0][0]); - m_pf_tilemap[0]->set_scrolly(0, m_pf_scroll_data[0][1]); - m_pf_tilemap[1]->set_scrollx(0, m_pf_scroll_data[1][0]); - m_pf_tilemap[1]->set_scrolly(0, m_pf_scroll_data[1][1]); - - m_pf_tilemap[1]->draw(screen, bitmap, cliprect, 0, 0); - m_pf_tilemap[0]->draw(screen, bitmap, cliprect, 0, 0); - draw_sprites(screen, bitmap, m_spriteram[0]->buffer(), 1); - m_fix_tilemap->draw(screen, bitmap, cliprect, 0, 0); - return 0; -} diff --git a/src/mame/video/snk_bbusters_spr.cpp b/src/mame/video/snk_bbusters_spr.cpp new file mode 100644 index 00000000000..abd94cc51f9 --- /dev/null +++ b/src/mame/video/snk_bbusters_spr.cpp @@ -0,0 +1,222 @@ +// license:BSD-3-Clause +// copyright-holders:Bryan McPhail +/*************************************************************************** + + Like NeoGeo sprite scale Y line selection is from an external rom. + + For 16 high sprites scale data starts at 0x3800 (9 scale levels) + For 32 high sprites scale data starts at 0x7000 (17 scale levels) + For 64 high sprites scale data starts at 0xa000 (33 scale levels) + For 128 pixel high sprites scale data starts 0xc000 (65 scale levels) + + 0xe000 and up - possibly X scale data? unconfirmed + + Sprites are also double buffered, and this seems to be performed + by having two complete sprite chips that are toggled per frame, rather + than just ram. Beast Busters has 4 sprite chips as it has two sprite + banks. + +***************************************************************************/ + +#include "emu.h" +#include "snk_bbusters_spr.h" + +DEFINE_DEVICE_TYPE(SNK_BBUSTERS_SPR, snk_bbusters_spr_device, "snk_bbusters_spr", "SNK Beast Busters Sprites") + +snk_bbusters_spr_device::snk_bbusters_spr_device(const machine_config &mconfig, const char *tag, device_t *owner, u32 clock) + : device_t(mconfig, SNK_BBUSTERS_SPR, tag, owner, clock) + , device_gfx_interface(mconfig, *this, gfxinfo) + , m_scale_table(*this, finder_base::DUMMY_TAG) + , m_spriteram(*this, finder_base::DUMMY_TAG) +{ +} + +static const gfx_layout spritelayout = +{ + 16,16, + RGN_FRAC(1,1), + 4, + { STEP4(0,4) }, + { + STEP4(0,1), STEP4(4*4,1), + STEP4(4*4*2*8,1), STEP4(4*4+4*4*2*8,1) + }, + { STEP8(0,4*4*2), STEP8(16*32,4*8) }, + 128*8 +}; + +GFXDECODE_MEMBER( snk_bbusters_spr_device::gfxinfo ) + GFXDECODE_DEVICE( DEVICE_SELF, 0, spritelayout, 0, 16*4 ) +GFXDECODE_END + + +void snk_bbusters_spr_device::device_start() +{ + save_item(NAME(m_scale_line_count)); +} + +template +int snk_bbusters_spr_device::adjust_spritecode(int dx, int dy, int code) +{ + if (dy & (0x10 << Size)) code += 2 << (Size * 2); + if (dx & (0x10 << Size)) code += 1 << (Size * 2); + return code; +} + +inline const uint8_t* snk_bbusters_spr_device::get_source_ptr(gfx_element* tilegfx, uint32_t sprite, int dx, int dy, int block) +{ + int code = 0; + + /* Get a tile index from the x,y position in the block */ + switch (block) + { + case 0: /* 16 x 16 sprite */ + break; + + case 1: /* 32 x 32 block + 0 1 + 2 3 + */ + code = adjust_spritecode<0>(dx, dy, code); // 4x4 + break; + + case 2: /* 64 by 64 block + 0 1 4 5 + 2 3 6 7 + + 8 9 12 13 + 10 11 14 15 + */ + code = adjust_spritecode<0>(dx, dy, code); // 4x4 + code = adjust_spritecode<1>(dx, dy, code); // 8x8 + break; + + case 3: /* 128 by 128 block */ + code = adjust_spritecode<0>(dx, dy, code); // 4x4 + code = adjust_spritecode<1>(dx, dy, code); // 8x8 + code = adjust_spritecode<2>(dx, dy, code); // 16x16 + break; + } + + return tilegfx->get_data((sprite + code) % tilegfx->elements()) + ((dy % 16) * tilegfx->rowbytes()); +} + +void snk_bbusters_spr_device::draw_block(bitmap_ind16 &dest, const rectangle &cliprect, int x, int y, int size, int flipx, int flipy, uint32_t sprite, int color, int block) +{ + // TODO: respect cliprect + + gfx_element* tilegfx = gfx(0); + pen_t pen_base = tilegfx->colorbase() + tilegfx->granularity() * (color % tilegfx->colors()); + uint32_t xinc = (m_scale_line_count * 0x10000) / size; + int dy = y; + int ex = m_scale_line_count; + + while (m_scale_line_count) + { + if (dy >= 16 && dy < 240) + { + uint16_t* const destline = &dest.pix(dy); + uint8_t srcline = *m_scale_table_ptr; + const uint8_t* srcptr = nullptr; + + if (!flipy) + srcline = size - srcline - 1; + + int x_index; + if (flipx) + x_index = (ex - 1) * 0x10000; + else + x_index = 0; + + for (int sx = 0; sx < size; sx++) + { + if ((sx % 16) == 0) + srcptr = get_source_ptr(tilegfx, sprite, sx, srcline, block); + + uint8_t pixel = *srcptr++; + if (pixel != 15) + destline[(x + (x_index >> 16)) & 0x1ff] = pen_base + pixel; + + if (flipx) + x_index -= xinc; + else + x_index += xinc; + } + } + + dy++; + m_scale_table_ptr--; + m_scale_line_count--; + } +} + +void snk_bbusters_spr_device::draw_sprites(bitmap_ind16& bitmap, const rectangle& cliprect) +{ + const uint16_t* sprram = m_spriteram->buffer(); + + for (int offs = 0; offs < 0x800; offs += 4) + { + int sprite = sprram[offs + 1]; + int colour = sprram[offs + 0]; + + // TODO: get rid of this abominable hack without breaking anything + if ((colour == 0xf7 || colour == 0xffff || colour == 0x43f9) && (sprite == 0x3fff || sprite == 0xffff || sprite == 0x0001)) + continue; // sprite 1, color 0x43f9 is the dead sprite in the top-right of the screen in Mechanized Attack's High Score table. + + int16_t y = sprram[offs + 3]; + int x = sprram[offs + 2]; + if (x & 0x200) x = -(0x100 - (x & 0xff)); + if (y > 320 || y < -256) y &= 0x1ff; // fix for bbusters ending & "Zing!" attract-mode fullscreen zombie & Helicopter on the 3rd rotation of the attractmode sequence + + /* + sprram[0]: + 0xf000: Colour + 0x0800: FX + 0x0400: FY? + 0x0300: Block control + 0x0080: ? + 0x007f: scale + + Scale varies according to block size. + Block type 0: 0x70 = no scale, 0x7f == half size - 16 pixel sprite + Block type 1: 0x60 = no scale, 0x6f == half size - 32 pixel sprite + Block type 2: 0x40 = no scale, 0x5f == half size - 64 pixel sprite + Block type 3: 0x00 = no scale, 0x3f == half size - 128 pixel sprite + + */ + colour = colour >> 12; + int block = (sprram[offs + 0] >> 8) & 0x3; + int fy = sprram[offs + 0] & 0x400; + int fx = sprram[offs + 0] & 0x800; + sprite = sprite & 0x3fff; + + int scale; + switch ((sprram[offs + 0] >> 8) & 0x3) + { + case 0: + scale = sprram[offs + 0] & 0x7; + m_scale_table_ptr = m_scale_table + 0x387f + (0x80 * scale); + m_scale_line_count = 0x10 - scale; + draw_block(bitmap, cliprect, x, y, 16, fx, fy, sprite, colour, block); + break; + case 1: /* 2 x 2 */ + scale = sprram[offs + 0] & 0xf; + m_scale_table_ptr = m_scale_table + 0x707f + (0x80 * scale); + m_scale_line_count = 0x20 - scale; + draw_block(bitmap, cliprect, x, y, 32, fx, fy, sprite, colour, block); + break; + case 2: /* 64 by 64 block (2 x 2) x 2 */ + scale = sprram[offs + 0] & 0x1f; + m_scale_table_ptr = m_scale_table + 0xa07f + (0x80 * scale); + m_scale_line_count = 0x40 - scale; + draw_block(bitmap, cliprect, x, y, 64, fx, fy, sprite, colour, block); + break; + case 3: /* 2 x 2 x 2 x 2 */ + scale = sprram[offs + 0] & 0x3f; + m_scale_table_ptr = m_scale_table + 0xc07f + (0x80 * scale); + m_scale_line_count = 0x80 - scale; + draw_block(bitmap, cliprect, x, y, 128, fx, fy, sprite, colour, block); + break; + } + } +} diff --git a/src/mame/video/snk_bbusters_spr.h b/src/mame/video/snk_bbusters_spr.h new file mode 100644 index 00000000000..c451040b11f --- /dev/null +++ b/src/mame/video/snk_bbusters_spr.h @@ -0,0 +1,42 @@ +// license:BSD-3-Clause +// copyright-holders:Bryan McPhail +#ifndef MAME_VIDEO_SNK_BBUSTERS_SPR_H +#define MAME_VIDEO_SNK_BBUSTERS_SPR_H + + +#include "video/bufsprite.h" + +class snk_bbusters_spr_device : public device_t, public device_gfx_interface +{ +public: + snk_bbusters_spr_device(const machine_config &mconfig, const char *tag, device_t *owner, uint32_t clock); + + // configuration + template void set_spriteram_tag(T &&tag) { m_spriteram.set_tag(std::forward(tag)); } + template void set_scaletable_tag(T &&tag) { m_scale_table.set_tag(std::forward(tag)); } + + void draw_sprites(bitmap_ind16 &bitmap, const rectangle &cliprect); + +protected: + virtual void device_start() override; + +private: + + DECLARE_GFXDECODE_MEMBER(gfxinfo); + + const uint8_t *m_scale_table_ptr; + uint8_t m_scale_line_count; + + template + int adjust_spritecode(int dx, int dy, int code); + + const uint8_t *get_source_ptr(gfx_element *tilegfx, uint32_t sprite, int dx, int dy, int block); + void draw_block(bitmap_ind16 &dest, const rectangle &cliprect, int x,int y,int size,int flipx,int flipy,uint32_t sprite,int color,int block); + + required_region_ptr m_scale_table; + required_device m_spriteram; +}; + +DECLARE_DEVICE_TYPE(SNK_BBUSTERS_SPR, snk_bbusters_spr_device) + +#endif // MAME_VIDEO_SNK_BBUSTERS_SPR_H