From 10f91147ebc24c9c3f22f0b84c249b9b751be467 Mon Sep 17 00:00:00 2001 From: AJR Date: Sun, 2 Jul 2023 21:00:00 -0400 Subject: avengers: Replace protection simulation with hookup of emulated MCU; add wait states to main CPU to keep it in sync while downloading the palette from the MCU [AJR, David Haywood] * lwings.cpp: Merge driver files; avoid runtime memory bank tag lookups --- src/mame/capcom/lwings.cpp | 718 +++++++++++++++++++++++++++++++------------ src/mame/capcom/lwings.h | 122 -------- src/mame/capcom/lwings_v.cpp | 278 ----------------- 3 files changed, 518 insertions(+), 600 deletions(-) delete mode 100644 src/mame/capcom/lwings.h delete mode 100644 src/mame/capcom/lwings_v.cpp diff --git a/src/mame/capcom/lwings.cpp b/src/mame/capcom/lwings.cpp index 8cee9c9324b..73ffbd85084 100644 --- a/src/mame/capcom/lwings.cpp +++ b/src/mame/capcom/lwings.cpp @@ -12,11 +12,6 @@ To Do: - sectionz does "false contacts" on the coin counters, causing them to increment twice per coin. -- clean up Avengers protection; it currently checks against hard-coded program - counter rather than behaving as a memory-mapped black box. -- Avengers had a protection chip underneath the sound module. Needs to be hooked up. - The protection is extensive: palette data, calculates player movement, - even a hand in the sound. The angle/movement stuff isn't 100% accurate either. - accurate music tempo (audiocpu irq freq) - accurate video timing, raw params @@ -33,6 +28,10 @@ FEB-2003 (AT) Notes: + Avengers has a protection chip underneath the sound module. + The protection is extensive: palette data, calculates player movement, + even a hand in the sound. + avengers061gre2: corrupted graphics in Avengers' ending not fixed. This bug is not in the Japanese set "Buraiken". It might just be a bug in the original: the tiles for the character @@ -58,14 +57,149 @@ Notes: ***************************************************************************/ #include "emu.h" -#include "lwings.h" +#include "cpu/mcs51/mcs51.h" #include "cpu/z80/z80.h" +#include "machine/gen_latch.h" #include "machine/watchdog.h" +#include "sound/msm5205.h" #include "sound/okim6295.h" #include "sound/ymopn.h" +#include "video/bufsprite.h" + +#include "emupal.h" #include "screen.h" #include "speaker.h" +#include "tilemap.h" + +namespace { + +class lwings_state : public driver_device +{ +public: + lwings_state(const machine_config &mconfig, device_type type, const char *tag) : + driver_device(mconfig, type, tag), + m_maincpu(*this, "maincpu"), + m_soundcpu(*this, "soundcpu"), + m_adpcmcpu(*this, "adpcmcpu"), + m_mcu(*this, "mcu"), + m_mculatch(*this, "mculatch%u", 0U), + m_msm(*this, "5205"), + m_gfxdecode(*this, "gfxdecode"), + m_palette(*this, "palette"), + m_screen(*this, "screen"), + m_soundlatch(*this, "soundlatch"), + m_spriteram(*this, "spriteram"), + m_fgvideoram(*this, "fgvideoram"), + m_bg1videoram(*this, "bg1videoram"), + m_soundlatch2(*this, "soundlatch_2"), + m_bank1(*this, "bank1"), + m_bank2(*this, "bank2"), + m_samplebank(*this, "samplebank") + { } + + void lwings(machine_config &config); + void sectionz(machine_config &config); + void trojan(machine_config &config); + void fball(machine_config &config); + void avengers(machine_config &config); + void buraikenb(machine_config &config); + +protected: + virtual void machine_start() override; + virtual void machine_reset() override; + virtual void video_start() override; + +private: + // devices + required_device m_maincpu; + required_device m_soundcpu; + optional_device m_adpcmcpu; + optional_device m_mcu; + optional_device_array m_mculatch; + optional_device m_msm; + required_device m_gfxdecode; + required_device m_palette; + required_device m_screen; + required_device m_soundlatch; + + // memory pointers + required_device m_spriteram; + required_shared_ptr m_fgvideoram; + required_shared_ptr m_bg1videoram; + optional_shared_ptr m_soundlatch2; + required_memory_bank m_bank1; + optional_memory_bank m_bank2; + optional_memory_bank m_samplebank; + + // video-related + tilemap_t *m_fg_tilemap = nullptr; + tilemap_t *m_bg1_tilemap = nullptr; + tilemap_t *m_bg2_tilemap = nullptr; + uint8_t m_bg2_image = 0U; + int m_spr_avenger_hw = 0; + uint8_t m_scroll_x[2]{}; + uint8_t m_scroll_y[2]{}; + + // misc + uint8_t m_soundstate = 0U; + uint8_t m_adpcm = 0U; + uint8_t m_nmi_mask = 0U; + int m_sprbank = 0; + + // MCU-related (avengers) + uint8_t m_mcu_data[2]{}; + uint8_t m_mcu_control = 0xff; + + void avengers_adpcm_w(uint8_t data); + uint8_t avengers_adpcm_r(); + void lwings_bankswitch_w(uint8_t data); + uint8_t avengers_m1_r(offs_t offset); + uint8_t avengers_soundlatch2_r(); + void lwings_fgvideoram_w(offs_t offset, uint8_t data); + void lwings_bg1videoram_w(offs_t offset, uint8_t data); + void lwings_bg1_scrollx_w(offs_t offset, uint8_t data); + void lwings_bg1_scrolly_w(offs_t offset, uint8_t data); + void trojan_bg2_scrollx_w(uint8_t data); + void trojan_bg2_image_w(uint8_t data); + void msm5205_w(uint8_t data); + void fball_oki_bank_w(uint8_t data); + + uint8_t mcu_p0_r(); + uint8_t mcu_p1_r(); + uint8_t mcu_p2_r(); + void mcu_p0_w(uint8_t data); + void mcu_p2_w(uint8_t data); + void mcu_control_w(uint8_t data); + + TILEMAP_MAPPER_MEMBER(get_bg2_memory_offset); + TILE_GET_INFO_MEMBER(get_fg_tile_info); + TILE_GET_INFO_MEMBER(lwings_get_bg1_tile_info); + TILE_GET_INFO_MEMBER(trojan_get_bg1_tile_info); + TILE_GET_INFO_MEMBER(get_bg2_tile_info); + DECLARE_VIDEO_START(trojan); + DECLARE_VIDEO_START(avengers); + uint32_t screen_update_lwings(screen_device &screen, bitmap_ind16 &bitmap, const rectangle &cliprect); + uint32_t screen_update_trojan(screen_device &screen, bitmap_ind16 &bitmap, const rectangle &cliprect); + void lwings_interrupt(int state); + void avengers_interrupt(int state); + inline int is_sprite_on( uint8_t *buffered_spriteram, int offs ); + void lwings_draw_sprites( bitmap_ind16 &bitmap, const rectangle &cliprect ); + void trojan_draw_sprites( bitmap_ind16 &bitmap, const rectangle &cliprect ); + + void avengers_adpcm_io_map(address_map &map); + void avengers_map(address_map &map); + void avengers_m1_map(address_map &map); + void buraikenb_map(address_map &map); + void fball_map(address_map &map); + void fball_oki_map(address_map &map); + void fball_sound_map(address_map &map); + void lwings_map(address_map &map); + void lwings_sound_map(address_map &map); + void trojan_adpcm_io_map(address_map &map); + void trojan_adpcm_map(address_map &map); + void trojan_map(address_map &map); +}; /* Avengers runs on hardware almost identical to Trojan, but with a protection * device and some small changes to the memory map and video hardware. @@ -96,7 +230,7 @@ void lwings_state::lwings_bankswitch_w(uint8_t data) flip_screen_set(~data & 0x01); /* bits 1 and 2 select ROM bank */ - membank("bank1")->set_entry((data & 0x06) >> 1); + m_bank1->set_entry((data & 0x06) >> 1); /* bit 3 enables NMI */ m_nmi_mask = data & 8; @@ -119,163 +253,61 @@ void lwings_state::avengers_interrupt(int state) } -void lwings_state::avengers_protection_w(uint8_t data) +uint8_t lwings_state::mcu_p0_r() { - int pc = m_maincpu->pc(); - - if (pc == 0x2eeb) - { - m_param[0] = data; - } - else if (pc == 0x2f09) - { - m_param[1] = data; - } - else if(pc == 0x2f26) - { - m_param[2] = data; - } - else if (pc == 0x2f43) - { - m_param[3] = data; - } - else if (pc == 0x0445) - { - m_soundstate = 0x80; - m_soundlatch->write(data); - } + if (!BIT(m_mcu_control, 7)) + return m_mculatch[0]->read(); + else + return 0xff; } -void lwings_state::avengers_prot_bank_w(uint8_t data) +uint8_t lwings_state::mcu_p1_r() { - m_palette_pen = data * 64; + // this is used to decide if we're sending angle params or a sound write? compares against 0xf0, vpos like 1943? + return m_screen->vpos(); } -int lwings_state::avengers_fetch_paldata( ) +uint8_t lwings_state::mcu_p2_r() { - static const char pal_data[] = - /* page 1: 0x03,0x02,0x01,0x00 */ - "0000000000000000" "A65486A6364676D6" "C764C777676778A7" "A574E5E5C5756AE5" - "0000000000000000" "F51785D505159405" "A637B6A636269636" "F45744E424348824" - "0000000000000000" "A33263B303330203" "4454848454440454" "A27242C232523632" - "0000000000000000" "1253327202421102" "3386437373631373" "41A331A161715461" - "0000000000000000" "1341715000711203" "4442635191622293" "5143D48383D37186" - "0000000000000000" "2432423000412305" "6633343302333305" "7234A565A5A4A2A8" - "0000000000000000" "46232422A02234A7" "88241624A21454A7" "A3256747A665D3AA" - "0000000000000000" "070406020003050B" "0A05090504050508" "05060A090806040C" - - /* page2: 0x07,0x06,0x05,0x04 */ - "0000000000000000" "2472030503230534" "6392633B23433B53" "0392846454346423" - "0000000000000000" "1313052405050423" "3223754805354832" "323346A38686A332" - "0000000000000000" "72190723070723D2" "81394776070776D1" "A15929F25959F2F1" - "0000000000000000" "650706411A2A1168" "770737C43A3A3466" "87071F013C0C3175" - "0000000000000000" "2001402727302020" "4403048F4A484344" "4A050B074E0E4440" - "0000000000000000" "3003800C35683130" "5304035C587C5453" "5607080C5B265550" - "0000000000000000" "4801D00043854245" "6C020038669A6569" "6604050A69446764" - "0000000000000000" "0504000001030504" "0A05090504060307" "04090D0507010403" - - /* page3: 0x0b,0x0a,0x09,0x08 */ - "0000000000000000" "685A586937F777F7" "988A797A67A7A7A7" "B8CA898DC737F787" - "0000000000000000" "4738A61705150505" "8797672835250535" "7777072A25350525" - "0000000000000000" "3525642404340404" "6554453554440454" "5544053634540434" - "0000000000000000" "2301923203430303" "4333834383630373" "3324034473730363" - "0000000000000000" "3130304000762005" "5352525291614193" "6463635483D06581" - "0000000000000000" "4241415100483107" "6463631302335304" "76757415A5A077A3" - "0000000000000000" "53525282A02A43AA" "76747424A31565A5" "88888536A66089A4" - "0000000000000000" "05040304000D050C" "0806050604070707" "0A0A060808000C06" - - /* page4: 0x0f,0x0e,0x0d,0x0c */ - "0000000000000000" "3470365956342935" "5590578997554958" "73C078A8C573687A" - "0000000000000000" "5355650685030604" "2427362686042607" "010A070584010508" - "0000000000000000" "0208432454022403" "737A243455733406" "000D050353000307" - "0000000000000000" "000A023233003202" "424C134234424204" "000F241132001105" - "0000000000000000" "3031113030300030" "5152215252512051" "7273337374723272" - "0000000000000000" "4141214041411041" "6263326363623162" "8385448585834383" - "0000000000000000" "5153225152512051" "7375437475734273" "9598559697946495" - "0000000000000000" "0205020303020102" "0407040606040304" "060A060809060506" - - /* page5: 0x13,0x12,0x11,0x10 */ - "0000000000000000" "4151D141D3D177F7" "5454C44482C4A7A7" "0404D45491D4F787" - "0000000000000000" "0303032374230505" "9696962673560535" "0505054502850525" - "0000000000000000" "0303030355030404" "7777770754470454" "0606060603760434" - "0000000000000000" "0505053547050303" "4949492945390373" "0808083804580363" - "0000000000000000" "0B0C444023442005" "3D3F333433334193" "0000043504046581" - "0000000000000000" "0809565085863107" "0B6A352374455304" "00700644050677A3" - "0000000000000000" "06073879C8C843AA" "09492739A58765A5" "0050084A060889A4" - "0000000000000000" "05060B070B0B050C" "0707090707090707" "00000B08070B0C06" - - /* page6: 0x17,0x16,0x15,0x14 */ - "0000000000000000" "0034308021620053" "0034417042512542" "0034526064502E31" - "0000000000000000" "0106412032733060" "11A6522053628350" "22A6632072620D42" - "0000000000000000" "1308223052242080" "2478233071235170" "3578243090230960" - "0000000000000000" "2111334333331404" "3353324232324807" "45B5314131310837" - "0000000000000000" "3232445444445302" "445443534343B725" "567642524242B745" - "0000000000000000" "4343556555550201" "5575546454540524" "6787536353537554" - "0000000000000000" "6474667676660100" "7696657575650423" "88A8647474645473" - "0000000000000000" "0001070701050004" "0003060603040303" "0005050505040302"; - - int bank = m_palette_pen / 64; - int offs = m_palette_pen % 64; - int page = bank / 4; /* 0..7 */ - int base = (3 - (bank & 3)); /* 0..3 */ - int row = offs & 0xf; /* 0..15 */ - int col = offs / 16 + base * 4; /* 0..15 */ - int digit0 = pal_data[page * 256 * 2 + (31 - row * 2) * 16 + col]; - int digit1 = pal_data[page * 256 * 2 + (30 - row * 2) * 16 + col]; - int result; - - if (digit0 >= 'A') - digit0 += 10 - 'A'; + if (!BIT(m_mcu_control, 7)) + return m_mculatch[1]->read(); else - digit0 -= '0'; - - if (digit1 >= 'A') - digit1 += 10 - 'A'; - else - digit1 -= '0'; - - result = digit0 * 16 + digit1; + return 0xff; +} - if ((m_palette_pen & 0x3f) != 0x3f) - m_palette_pen++; +void lwings_state::mcu_p0_w(uint8_t data) +{ + m_mcu_data[0] = data; +} - return result; +void lwings_state::mcu_p2_w(uint8_t data) +{ + m_mcu_data[1] = data; } -uint8_t lwings_state::avengers_protection_r() +void lwings_state::mcu_control_w(uint8_t data) { - static const int xpos[8] = { 10, 7, 0, -7, -10, -7, 0, 7 }; - static const int ypos[8] = { 0, 7, 10, 7, 0, -7, -10, -7 }; - int best_dist = 0; - int best_dir = 0; - int x, y; - int dx, dy, dist, dir; - - if (m_maincpu->pc() == 0x7c7) + if (!BIT(m_mcu_control, 6) && BIT(data, 6)) { - /* palette data */ - return avengers_fetch_paldata(); + //logerror("%s: MCU writes %02X back to main CPU\n", machine().time().to_string(), m_mcu_data[0]); + m_mculatch[2]->write(m_mcu_data[0]); + m_soundlatch->write(m_mcu_data[1]); + m_soundstate = 0x80; + machine().scheduler().perfect_quantum(attotime::from_usec(60)); } - /* Point to Angle Function + if (BIT(m_mcu_control, 7) != BIT(data, 7)) + m_mculatch[0]->acknowledge_w(); - Input: two cartesian points - Output: direction code (north, northeast, east, ...) - */ - x = m_param[0] - m_param[2]; - y = m_param[1] - m_param[3]; - for (dir = 0; dir < 8; dir++) - { - dx = xpos[dir] - x; - dy = ypos[dir] - y; - dist = dx * dx + dy * dy; - if (dist < best_dist || dir == 0) - { - best_dir = dir; - best_dist = dist; - } - } - return best_dir << 5; + m_mcu_control = data; +} + +uint8_t lwings_state::avengers_m1_r(offs_t offset) +{ + // 2 wait states on each M1 access (needed to keep in sync with MCU) + if (!machine().side_effects_disabled()) + m_maincpu->adjust_icount(-2); + return m_maincpu->space(AS_PROGRAM).read_byte(offset); } uint8_t lwings_state::avengers_soundlatch2_r() @@ -322,9 +354,14 @@ void lwings_state::avengers_map(address_map &map) { buraikenb_map(map); - map(0xf809, 0xf809).w(FUNC(lwings_state::avengers_protection_w)); - map(0xf80c, 0xf80c).w(FUNC(lwings_state::avengers_prot_bank_w)); - map(0xf80d, 0xf80d).r(FUNC(lwings_state::avengers_protection_r)); + map(0xf809, 0xf809).w(m_mculatch[0], FUNC(generic_latch_8_device::write)); + map(0xf80c, 0xf80c).w(m_mculatch[1], FUNC(generic_latch_8_device::write)); + map(0xf80d, 0xf80d).r(m_mculatch[2], FUNC(generic_latch_8_device::read)); +} + +void lwings_state::avengers_m1_map(address_map &map) +{ + map(0x0000, 0xffff).r(FUNC(lwings_state::avengers_m1_r)); } void lwings_state::lwings_map(address_map &map) @@ -414,7 +451,7 @@ void lwings_state::fball_map(address_map &map) void lwings_state::fball_oki_bank_w(uint8_t data) { //printf("fball_oki_bank_w %02x\n", data); - membank("samplebank")->set_entry((data >> 1) & 0x7); + m_samplebank->set_entry((data >> 1) & 0x7); } void lwings_state::fball_oki_map(address_map &map) @@ -454,6 +491,265 @@ void lwings_state::trojan_adpcm_io_map(address_map &map) } +/*************************************************************************** + + Callbacks for the TileMap code + +***************************************************************************/ + +TILEMAP_MAPPER_MEMBER(lwings_state::get_bg2_memory_offset) +{ + return (row * 0x800) | (col * 2); +} + +TILE_GET_INFO_MEMBER(lwings_state::get_fg_tile_info) +{ + int code = m_fgvideoram[tile_index]; + int color = m_fgvideoram[tile_index + 0x400]; + tileinfo.set(0, + code + ((color & 0xc0) << 2), + color & 0x0f, + TILE_FLIPYX((color & 0x30) >> 4)); +} + +TILE_GET_INFO_MEMBER(lwings_state::lwings_get_bg1_tile_info) +{ + int code = m_bg1videoram[tile_index]; + int color = m_bg1videoram[tile_index + 0x400]; + tileinfo.set(1, + code + ((color & 0xe0) << 3), + color & 0x07, + TILE_FLIPYX((color & 0x18) >> 3)); +} + +TILE_GET_INFO_MEMBER(lwings_state::trojan_get_bg1_tile_info) +{ + int code = m_bg1videoram[tile_index]; + int color = m_bg1videoram[tile_index + 0x400]; + code += (color & 0xe0)<<3; + tileinfo.set(1, + code, + (color & 7), + ((color & 0x10) ? TILE_FLIPX : 0)); + + tileinfo.group = (color & 0x08) >> 3; +} + +TILE_GET_INFO_MEMBER(lwings_state::get_bg2_tile_info) +{ + int code, color; + uint8_t *rom = memregion("gfx5")->base(); + int mask = memregion("gfx5")->bytes() - 1; + + tile_index = (tile_index + m_bg2_image * 0x20) & mask; + code = rom[tile_index]; + color = rom[tile_index + 1]; + tileinfo.set(3, + code + ((color & 0x80) << 1), + color & 0x07, + TILE_FLIPYX((color & 0x30) >> 4)); +} + + +/*************************************************************************** + + Start the video hardware emulation. + +***************************************************************************/ + +void lwings_state::video_start() +{ + m_fg_tilemap = &machine().tilemap().create(*m_gfxdecode, tilemap_get_info_delegate(*this, FUNC(lwings_state::get_fg_tile_info)), TILEMAP_SCAN_ROWS, 8, 8, 32, 32); + m_bg1_tilemap = &machine().tilemap().create(*m_gfxdecode, tilemap_get_info_delegate(*this, FUNC(lwings_state::lwings_get_bg1_tile_info)), TILEMAP_SCAN_COLS, 16, 16, 32, 32); + + m_fg_tilemap->set_transparent_pen(3); +} + +VIDEO_START_MEMBER(lwings_state,trojan) +{ + m_fg_tilemap = &machine().tilemap().create(*m_gfxdecode, tilemap_get_info_delegate(*this, FUNC(lwings_state::get_fg_tile_info)), TILEMAP_SCAN_ROWS, 8, 8, 32, 32); + m_bg1_tilemap = &machine().tilemap().create(*m_gfxdecode, tilemap_get_info_delegate(*this, FUNC(lwings_state::trojan_get_bg1_tile_info)),TILEMAP_SCAN_COLS, 16, 16, 32, 32); + m_bg2_tilemap = &machine().tilemap().create(*m_gfxdecode, tilemap_get_info_delegate(*this, FUNC(lwings_state::get_bg2_tile_info)), tilemap_mapper_delegate(*this, FUNC(lwings_state::get_bg2_memory_offset)), 16, 16, 32, 16); + + m_fg_tilemap->set_transparent_pen(3); + m_bg1_tilemap->set_transmask(0, 0xffff, 0x0001); // split type 0 is totally transparent in front half + m_bg1_tilemap->set_transmask(1, 0xf07f, 0x0f81); // split type 1 has pens 7-11 opaque in front half + + m_spr_avenger_hw = 0; +} + +VIDEO_START_MEMBER(lwings_state,avengers) +{ + VIDEO_START_CALL_MEMBER(trojan); + m_spr_avenger_hw = 1; +} + + +/*************************************************************************** + + Memory handlers + +***************************************************************************/ + +void lwings_state::lwings_fgvideoram_w(offs_t offset, uint8_t data) +{ + m_fgvideoram[offset] = data; + m_fg_tilemap->mark_tile_dirty(offset & 0x3ff); +} + +void lwings_state::lwings_bg1videoram_w(offs_t offset, uint8_t data) +{ + m_bg1videoram[offset] = data; + m_bg1_tilemap->mark_tile_dirty(offset & 0x3ff); +} + + +void lwings_state::lwings_bg1_scrollx_w(offs_t offset, uint8_t data) +{ + m_scroll_x[offset] = data; + m_bg1_tilemap->set_scrollx(0, m_scroll_x[0] | (m_scroll_x[1] << 8)); +} + +void lwings_state::lwings_bg1_scrolly_w(offs_t offset, uint8_t data) +{ + m_scroll_y[offset] = data; + m_bg1_tilemap->set_scrolly(0, m_scroll_y[0] | (m_scroll_y[1] << 8)); +} + +void lwings_state::trojan_bg2_scrollx_w(uint8_t data) +{ + m_bg2_tilemap->set_scrollx(0, data); +} + +void lwings_state::trojan_bg2_image_w(uint8_t data) +{ + if (m_bg2_image != data) + { + m_bg2_image = data; + m_bg2_tilemap->mark_all_dirty(); + } +} + + +/*************************************************************************** + + Display refresh + +***************************************************************************/ + +inline int lwings_state::is_sprite_on( uint8_t *buffered_spriteram, int offs ) +{ + int sx, sy; + + sx = buffered_spriteram[offs + 3] - 0x100 * (buffered_spriteram[offs + 1] & 0x01); + sy = buffered_spriteram[offs + 2]; + + return sx || sy; +} + +void lwings_state::lwings_draw_sprites( bitmap_ind16 &bitmap, const rectangle &cliprect ) +{ + uint8_t *buffered_spriteram = m_spriteram->buffer(); + int offs; + + for (offs = m_spriteram->bytes() - 4; offs >= 0; offs -= 4) + { + if (is_sprite_on(buffered_spriteram, offs)) + { + int code, color, sx, sy, flipx, flipy; + + sx = buffered_spriteram[offs + 3] - 0x100 * (buffered_spriteram[offs + 1] & 0x01); + sy = buffered_spriteram[offs + 2]; + if (sy > 0xf8) + sy -= 0x100; + code = buffered_spriteram[offs] | (buffered_spriteram[offs + 1] & 0xc0) << 2; + color = (buffered_spriteram[offs + 1] & 0x38) >> 3; + flipx = buffered_spriteram[offs + 1] & 0x02; + flipy = buffered_spriteram[offs + 1] & 0x04; + + if (flip_screen()) + { + sx = 240 - sx; + sy = 240 - sy; + flipx = !flipx; + flipy = !flipy; + } + + m_gfxdecode->gfx(2)->transpen(bitmap,cliprect, + code+(m_sprbank*0x400),color, + flipx,flipy, + sx,sy,15); + } + } +} + +void lwings_state::trojan_draw_sprites( bitmap_ind16 &bitmap, const rectangle &cliprect ) +{ + uint8_t *buffered_spriteram = m_spriteram->buffer(); + int offs; + + for (offs = m_spriteram->bytes() - 4; offs >= 0; offs -= 4) + { + if (is_sprite_on(buffered_spriteram, offs)) + { + int code, color, sx, sy, flipx, flipy; + + sx = buffered_spriteram[offs + 3] - 0x100 * (buffered_spriteram[offs + 1] & 0x01); + sy = buffered_spriteram[offs + 2]; + if (sy > 0xf8) + sy -= 0x100; + code = buffered_spriteram[offs] | + ((buffered_spriteram[offs + 1] & 0x20) << 4) | + ((buffered_spriteram[offs + 1] & 0x40) << 2) | + ((buffered_spriteram[offs + 1] & 0x80) << 3); + color = (buffered_spriteram[offs + 1] & 0x0e) >> 1; + + if (m_spr_avenger_hw) + { + flipx = 0; /* Avengers */ + flipy = ~buffered_spriteram[offs + 1] & 0x10; + } + else + { + flipx = buffered_spriteram[offs + 1] & 0x10; /* Trojan */ + flipy = 1; + } + + if (flip_screen()) + { + sx = 240 - sx; + sy = 240 - sy; + flipx = !flipx; + flipy = !flipy; + } + + m_gfxdecode->gfx(2)->transpen(bitmap,cliprect, + code,color, + flipx,flipy, + sx,sy,15); + } + } +} + +uint32_t lwings_state::screen_update_lwings(screen_device &screen, bitmap_ind16 &bitmap, const rectangle &cliprect) +{ + m_bg1_tilemap->draw(screen, bitmap, cliprect, 0, 0); + lwings_draw_sprites(bitmap, cliprect); + m_fg_tilemap->draw(screen, bitmap, cliprect, 0, 0); + return 0; +} + +uint32_t lwings_state::screen_update_trojan(screen_device &screen, bitmap_ind16 &bitmap, const rectangle &cliprect) +{ + m_bg2_tilemap->draw(screen, bitmap, cliprect, 0, 0); + m_bg1_tilemap->draw(screen, bitmap, cliprect, TILEMAP_DRAW_LAYER1, 0); + trojan_draw_sprites(bitmap, cliprect); + m_bg1_tilemap->draw(screen, bitmap, cliprect, TILEMAP_DRAW_LAYER0, 0); + m_fg_tilemap->draw(screen, bitmap, cliprect, 0, 0); + return 0; +} + + /************************************* * * Generic port definitions @@ -869,13 +1165,11 @@ void lwings_state::machine_start() { uint8_t *ROM = memregion("maincpu")->base(); - membank("bank1")->configure_entries(0, 4, &ROM[0x10000], 0x4000); + m_bank1->configure_entries(0, 4, &ROM[0x10000], 0x4000); save_item(NAME(m_bg2_image)); save_item(NAME(m_scroll_x)); save_item(NAME(m_scroll_y)); - save_item(NAME(m_param)); - save_item(NAME(m_palette_pen)); save_item(NAME(m_soundstate)); save_item(NAME(m_adpcm)); save_item(NAME(m_nmi_mask)); @@ -909,18 +1203,23 @@ void lwings_state::machine_start() */ - if (membank("bank2")) + if (m_bank2.found()) { - membank("bank2")->configure_entries(0, 2, &ROM[0x0000], 0x8000); - membank("bank2")->set_entry(0); + m_bank2->configure_entries(0, 2, &ROM[0x0000], 0x8000); + m_bank2->set_entry(0); } - if (membank("samplebank")) + if (m_samplebank.found()) { uint8_t *OKIROM = memregion("oki")->base(); - membank("samplebank")->configure_entries(0, 8, OKIROM, 0x20000); + m_samplebank->configure_entries(0, 8, OKIROM, 0x20000); } + if (m_mcu.found()) + { + save_item(NAME(m_mcu_data)); + save_item(NAME(m_mcu_control)); + } } void lwings_state::machine_reset() @@ -930,11 +1229,6 @@ void lwings_state::machine_reset() m_scroll_x[1] = 0; m_scroll_y[0] = 0; m_scroll_y[1] = 0; - m_param[0] = 0; - m_param[1] = 0; - m_param[2] = 0; - m_param[3] = 0; - m_palette_pen = 0; m_soundstate = 0; m_adpcm = 0; } @@ -955,15 +1249,15 @@ void lwings_state::lwings(machine_config &config) // video hardware BUFFERED_SPRITERAM8(config, m_spriteram); - screen_device &screen(SCREEN(config, "screen", SCREEN_TYPE_RASTER)); - screen.set_refresh_hz(60); - screen.set_vblank_time(ATTOSECONDS_IN_USEC(0)); - screen.set_size(32*8, 32*8); - screen.set_visarea(0*8, 32*8-1, 1*8, 31*8-1); - screen.set_screen_update(FUNC(lwings_state::screen_update_lwings)); - screen.screen_vblank().set(m_spriteram, FUNC(buffered_spriteram8_device::vblank_copy_rising)); - screen.screen_vblank().append(FUNC(lwings_state::lwings_interrupt)); - screen.set_palette(m_palette); + SCREEN(config, m_screen, SCREEN_TYPE_RASTER); + m_screen->set_refresh_hz(60); + m_screen->set_vblank_time(ATTOSECONDS_IN_USEC(0)); + m_screen->set_size(32*8, 32*8); + m_screen->set_visarea(0*8, 32*8-1, 1*8, 31*8-1); + m_screen->set_screen_update(FUNC(lwings_state::screen_update_lwings)); + m_screen->screen_vblank().set(m_spriteram, FUNC(buffered_spriteram8_device::vblank_copy_rising)); + m_screen->screen_vblank().append(FUNC(lwings_state::lwings_interrupt)); + m_screen->set_palette(m_palette); GFXDECODE(config, m_gfxdecode, m_palette, gfx_lwings); PALETTE(config, m_palette).set_format(palette_device::RGBx_444, 1024); @@ -992,7 +1286,7 @@ void lwings_state::sectionz(machine_config &config) m_maincpu->set_clock(12_MHz_XTAL/4); // XTAL and clock verified on an original PCB and on a bootleg with ROMs matching those of sectionza - subdevice("screen")->set_refresh_hz(55.37); // verified on an original PCB + m_screen->set_refresh_hz(55.37); // verified on an original PCB } void lwings_state::fball(machine_config &config) @@ -1010,15 +1304,15 @@ void lwings_state::fball(machine_config &config) // video hardware BUFFERED_SPRITERAM8(config, m_spriteram); - screen_device &screen(SCREEN(config, "screen", SCREEN_TYPE_RASTER)); - screen.set_refresh_hz(60); - screen.set_vblank_time(ATTOSECONDS_IN_USEC(0)); - screen.set_size(32*8, 32*8); - screen.set_visarea(0*8, 32*8-1, 1*8, 31*8-1); // the 16-pixel black border on left edge is correct, test mode actually uses that area - screen.set_screen_update(FUNC(lwings_state::screen_update_lwings)); - screen.screen_vblank().set(m_spriteram, FUNC(buffered_spriteram8_device::vblank_copy_rising)); - screen.screen_vblank().append(FUNC(lwings_state::avengers_interrupt)); - screen.set_palette(m_palette); + SCREEN(config, m_screen, SCREEN_TYPE_RASTER); + m_screen->set_refresh_hz(60); + m_screen->set_vblank_time(ATTOSECONDS_IN_USEC(0)); + m_screen->set_size(32*8, 32*8); + m_screen->set_visarea(0*8, 32*8-1, 1*8, 31*8-1); // the 16-pixel black border on left edge is correct, test mode actually uses that area + m_screen->set_screen_update(FUNC(lwings_state::screen_update_lwings)); + m_screen->screen_vblank().set(m_spriteram, FUNC(buffered_spriteram8_device::vblank_copy_rising)); + m_screen->screen_vblank().append(FUNC(lwings_state::avengers_interrupt)); + m_screen->set_palette(m_palette); GFXDECODE(config, m_gfxdecode, m_palette, gfx_lwings); PALETTE(config, m_palette).set_format(palette_device::RGBx_444, 1024); @@ -1052,7 +1346,7 @@ void lwings_state::trojan(machine_config &config) m_gfxdecode->set_info(gfx_trojan); MCFG_VIDEO_START_OVERRIDE(lwings_state,trojan) - subdevice("screen")->set_screen_update(FUNC(lwings_state::screen_update_trojan)); + m_screen->set_screen_update(FUNC(lwings_state::screen_update_trojan)); // sound hardware GENERIC_LATCH_8(config, "soundlatch2"); @@ -1067,13 +1361,28 @@ void lwings_state::avengers(machine_config &config) trojan(config); // basic machine hardware + m_maincpu->set_clock(12_MHz_XTAL/2); m_maincpu->set_addrmap(AS_PROGRAM, &lwings_state::avengers_map); + m_maincpu->set_addrmap(AS_OPCODES, &lwings_state::avengers_m1_map); I8751(config, m_mcu, 12_MHz_XTAL/2); + m_mcu->port_in_cb<0>().set(FUNC(lwings_state::mcu_p0_r)); + m_mcu->port_out_cb<0>().set(FUNC(lwings_state::mcu_p0_w)); + m_mcu->port_in_cb<1>().set(FUNC(lwings_state::mcu_p1_r)); + m_mcu->port_in_cb<2>().set(FUNC(lwings_state::mcu_p2_r)); + m_mcu->port_out_cb<2>().set(FUNC(lwings_state::mcu_p2_w)); + m_mcu->port_out_cb<3>().set(FUNC(lwings_state::mcu_control_w)); + + GENERIC_LATCH_8(config, m_mculatch[0]); + m_mculatch[0]->data_pending_callback().set_inputline(m_mcu, MCS51_INT0_LINE); + m_mculatch[0]->data_pending_callback().append([this] (int state) { if (state) machine().scheduler().perfect_quantum(attotime::from_usec(192)); }); + m_mculatch[0]->set_separate_acknowledge(true); - screen_device &screen(*subdevice("screen")); - screen.screen_vblank().set(m_spriteram, FUNC(buffered_spriteram8_device::vblank_copy_rising)); - screen.screen_vblank().append(FUNC(lwings_state::avengers_interrupt)); // RST 38h triggered by software + GENERIC_LATCH_8(config, m_mculatch[1]); + GENERIC_LATCH_8(config, m_mculatch[2]); + + m_screen->screen_vblank().set(m_spriteram, FUNC(buffered_spriteram8_device::vblank_copy_rising)); + m_screen->screen_vblank().append(FUNC(lwings_state::avengers_interrupt)); // RST 38h triggered by software m_adpcmcpu->set_addrmap(AS_IO, &lwings_state::avengers_adpcm_io_map); @@ -1088,9 +1397,9 @@ void lwings_state::buraikenb(machine_config &config) // basic machine hardware m_maincpu->set_addrmap(AS_PROGRAM, &lwings_state::buraikenb_map); config.device_remove("mcu"); - - // video hardware - MCFG_VIDEO_START_OVERRIDE(lwings_state,buraikenb) + config.device_remove("mculatch0"); + config.device_remove("mculatch1"); + config.device_remove("mculatch2"); } @@ -1656,6 +1965,18 @@ It was common for Capcom to use the same ROM label across regional sets but add with and without the "U" being stamped. */ + +// there is definitely at least one bad opcode in this dump, there could be others affecting enemy movement +#define AVENGERS_MCU \ + ROM_REGION( 0x1000, "mcu", 0 ) /* Intel C8751H - 88 */ \ + ROM_LOAD( "av.13k", 0x0000, 0x1000, BAD_DUMP CRC(505a0987) SHA1(ea1d855a9870d79d0e00eaa88a23038355a1203a) ) \ + ROM_FILL(0x0b84, 0x01, 0x02) /* bad code! bit 0x80 was flipped */ \ + /* these palette entries look wrong, but the low bit is unused, so could just be like that */ \ + ROM_FILL(0x0481, 0x01, 0x00) \ + ROM_FILL(0x04e0, 0x01, 0x00) \ + ROM_FILL(0x0483, 0x01, 0xa0) \ + ROM_FILL(0x04c3, 0x01, 0x30) + ROM_START( avengers ) ROM_REGION( 0x20000, "maincpu", 0 ) /* 64k for code + 3*16k for the banked ROMs images */ ROM_LOAD( "avu_04c.10n", 0x00000, 0x8000, CRC(4555b925) SHA1(49829272b23a39798bcaeb6d847a4091031b3dec) ) /* Red stripe across label for US region */ @@ -1668,8 +1989,7 @@ ROM_START( avengers ) ROM_REGION( 0x10000, "adpcmcpu", 0 ) /* ADPCM CPU */ ROM_LOAD( "av_01.6d", 0x0000, 0x8000, CRC(c1e5d258) SHA1(88ed978e6df72ce22f9371930360aa9cde73abe9) ) /* adpcm player - "Talker" ROM */ - ROM_REGION( 0x1000, "mcu", 0 ) // Intel C8751H-88 - ROM_LOAD( "av.13k", 0x0000, 0x1000, CRC(505a0987) SHA1(ea1d855a9870d79d0e00eaa88a23038355a1203a) ) + AVENGERS_MCU ROM_REGION( 0x08000, "gfx1", 0 ) ROM_LOAD( "av_03.8k", 0x00000, 0x8000, CRC(efb5883e) SHA1(08aebf579f2c5ff472db66597cde1c6871d7d757) ) /* characters */ @@ -1718,8 +2038,7 @@ ROM_START( avengersa ) ROM_REGION( 0x10000, "adpcmcpu", 0 ) /* ADPCM CPU */ ROM_LOAD( "av_01.6d", 0x0000, 0x8000, CRC(c1e5d258) SHA1(88ed978e6df72ce22f9371930360aa9cde73abe9) ) /* adpcm player - "Talker" ROM */ - ROM_REGION( 0x1000, "mcu", 0 ) // Intel C8751H-88 - ROM_LOAD( "av.13k", 0x0000, 0x1000, CRC(505a0987) SHA1(ea1d855a9870d79d0e00eaa88a23038355a1203a) ) + AVENGERS_MCU ROM_REGION( 0x08000, "gfx1", 0 ) ROM_LOAD( "av_03.8k", 0x00000, 0x8000, CRC(efb5883e) SHA1(08aebf579f2c5ff472db66597cde1c6871d7d757) ) /* characters */ @@ -1768,8 +2087,7 @@ ROM_START( avengersb ) ROM_REGION( 0x10000, "adpcmcpu", 0 ) /* ADPCM CPU */ ROM_LOAD( "av_01.6d", 0x0000, 0x8000, CRC(c1e5d258) SHA1(88ed978e6df72ce22f9371930360aa9cde73abe9) ) /* adpcm player - "Talker" ROM */ - ROM_REGION( 0x1000, "mcu", 0 ) // Intel C8751H-88 - ROM_LOAD( "av.13k", 0x0000, 0x1000, CRC(505a0987) SHA1(ea1d855a9870d79d0e00eaa88a23038355a1203a) ) + AVENGERS_MCU ROM_REGION( 0x08000, "gfx1", 0 ) ROM_LOAD( "av_03.8k", 0x00000, 0x8000, CRC(efb5883e) SHA1(08aebf579f2c5ff472db66597cde1c6871d7d757) ) /* characters */ @@ -1818,8 +2136,7 @@ ROM_START( avengersc ) ROM_REGION( 0x10000, "adpcmcpu", 0 ) /* ADPCM CPU */ ROM_LOAD( "av_01.6d", 0x0000, 0x8000, CRC(c1e5d258) SHA1(88ed978e6df72ce22f9371930360aa9cde73abe9) ) /* adpcm player - "Talker" ROM */ - ROM_REGION( 0x1000, "mcu", 0 ) // Intel C8751H-88 - ROM_LOAD( "av.13k", 0x0000, 0x1000, CRC(505a0987) SHA1(ea1d855a9870d79d0e00eaa88a23038355a1203a) ) + AVENGERS_MCU ROM_REGION( 0x08000, "gfx1", 0 ) ROM_LOAD( "av_03.8k", 0x00000, 0x8000, CRC(efb5883e) SHA1(08aebf579f2c5ff472db66597cde1c6871d7d757) ) /* characters */ @@ -1868,8 +2185,7 @@ ROM_START( buraiken ) ROM_REGION( 0x10000, "adpcmcpu", 0 ) /* ADPCM CPU */ ROM_LOAD( "av_01.6d", 0x0000, 0x8000, CRC(c1e5d258) SHA1(88ed978e6df72ce22f9371930360aa9cde73abe9) ) /* adpcm player - "Talker" ROM */ - ROM_REGION( 0x1000, "mcu", 0 ) // Intel C8751H-88 - ROM_LOAD( "av.13k", 0x0000, 0x1000, CRC(505a0987) SHA1(ea1d855a9870d79d0e00eaa88a23038355a1203a) ) + AVENGERS_MCU ROM_REGION( 0x08000, "gfx1", 0 ) ROM_LOAD( "av_03.8k", 0x00000, 0x8000, CRC(efb5883e) SHA1(08aebf579f2c5ff472db66597cde1c6871d7d757) ) /* characters */ @@ -1953,6 +2269,8 @@ ROM_START( buraikenb ) ROM_LOAD( "tbb_1bpr.1e", 0x0100, 0x0100, CRC(5052fa9d) SHA1(8cd240f4795a7ae76499573c09069dba37182be2) ) /* priority (not used) */ ROM_END +} // anonymous namespace + /************************************* * diff --git a/src/mame/capcom/lwings.h b/src/mame/capcom/lwings.h deleted file mode 100644 index 9133d6cf28e..00000000000 --- a/src/mame/capcom/lwings.h +++ /dev/null @@ -1,122 +0,0 @@ -// license:BSD-3-Clause -// copyright-holders:Paul Leaman - -#include "cpu/mcs51/mcs51.h" -#include "video/bufsprite.h" -#include "machine/gen_latch.h" -#include "sound/msm5205.h" - -#include "emupal.h" -#include "tilemap.h" - -class lwings_state : public driver_device -{ -public: - lwings_state(const machine_config &mconfig, device_type type, const char *tag) : - driver_device(mconfig, type, tag), - m_maincpu(*this, "maincpu"), - m_soundcpu(*this, "soundcpu"), - m_adpcmcpu(*this, "adpcmcpu"), - m_mcu(*this, "mcu"), - m_msm(*this, "5205"), - m_gfxdecode(*this, "gfxdecode"), - m_palette(*this, "palette"), - m_soundlatch(*this, "soundlatch"), - m_spriteram(*this, "spriteram"), - m_fgvideoram(*this, "fgvideoram"), - m_bg1videoram(*this, "bg1videoram"), - m_soundlatch2(*this, "soundlatch_2") - { } - - void lwings(machine_config &config); - void sectionz(machine_config &config); - void trojan(machine_config &config); - void fball(machine_config &config); - void avengers(machine_config &config); - void buraikenb(machine_config &config); - -protected: - virtual void machine_start() override; - virtual void machine_reset() override; - virtual void video_start() override; - -private: - // devices - required_device m_maincpu; - required_device m_soundcpu; - optional_device m_adpcmcpu; - optional_device m_mcu; - optional_device m_msm; - required_device m_gfxdecode; - required_device m_palette; - required_device m_soundlatch; - - // memory pointers - required_device m_spriteram; - required_shared_ptr m_fgvideoram; - required_shared_ptr m_bg1videoram; - optional_shared_ptr m_soundlatch2; - - // video-related - tilemap_t *m_fg_tilemap = nullptr; - tilemap_t *m_bg1_tilemap = nullptr; - tilemap_t *m_bg2_tilemap = nullptr; - uint8_t m_bg2_image = 0U; - int m_bg2_avenger_hw = 0; - int m_spr_avenger_hw = 0; - uint8_t m_scroll_x[2]{}; - uint8_t m_scroll_y[2]{}; - - // misc - uint8_t m_param[4]{}; - int m_palette_pen = 0; - uint8_t m_soundstate = 0U; - uint8_t m_adpcm = 0U; - uint8_t m_nmi_mask = 0U; - int m_sprbank = 0; - - void avengers_adpcm_w(uint8_t data); - uint8_t avengers_adpcm_r(); - void lwings_bankswitch_w(uint8_t data); - void avengers_protection_w(uint8_t data); - void avengers_prot_bank_w(uint8_t data); - uint8_t avengers_protection_r(); - uint8_t avengers_soundlatch2_r(); - void lwings_fgvideoram_w(offs_t offset, uint8_t data); - void lwings_bg1videoram_w(offs_t offset, uint8_t data); - void lwings_bg1_scrollx_w(offs_t offset, uint8_t data); - void lwings_bg1_scrolly_w(offs_t offset, uint8_t data); - void trojan_bg2_scrollx_w(uint8_t data); - void trojan_bg2_image_w(uint8_t data); - void msm5205_w(uint8_t data); - void fball_oki_bank_w(uint8_t data); - - TILEMAP_MAPPER_MEMBER(get_bg2_memory_offset); - TILE_GET_INFO_MEMBER(get_fg_tile_info); - TILE_GET_INFO_MEMBER(lwings_get_bg1_tile_info); - TILE_GET_INFO_MEMBER(trojan_get_bg1_tile_info); - TILE_GET_INFO_MEMBER(get_bg2_tile_info); - DECLARE_VIDEO_START(trojan); - DECLARE_VIDEO_START(avengers); - DECLARE_VIDEO_START(buraikenb); - uint32_t screen_update_lwings(screen_device &screen, bitmap_ind16 &bitmap, const rectangle &cliprect); - uint32_t screen_update_trojan(screen_device &screen, bitmap_ind16 &bitmap, const rectangle &cliprect); - void lwings_interrupt(int state); - void avengers_interrupt(int state); - inline int is_sprite_on( uint8_t *buffered_spriteram, int offs ); - void lwings_draw_sprites( bitmap_ind16 &bitmap, const rectangle &cliprect ); - void trojan_draw_sprites( bitmap_ind16 &bitmap, const rectangle &cliprect ); - int avengers_fetch_paldata(); - - void avengers_adpcm_io_map(address_map &map); - void avengers_map(address_map &map); - void buraikenb_map(address_map &map); - void fball_map(address_map &map); - void fball_oki_map(address_map &map); - void fball_sound_map(address_map &map); - void lwings_map(address_map &map); - void lwings_sound_map(address_map &map); - void trojan_adpcm_io_map(address_map &map); - void trojan_adpcm_map(address_map &map); - void trojan_map(address_map &map); -}; diff --git a/src/mame/capcom/lwings_v.cpp b/src/mame/capcom/lwings_v.cpp deleted file mode 100644 index 63d81c185f9..00000000000 --- a/src/mame/capcom/lwings_v.cpp +++ /dev/null @@ -1,278 +0,0 @@ -// license:BSD-3-Clause -// copyright-holders:Paul Leaman -/*************************************************************************** - - video.c - - Functions to emulate the video hardware of the machine. - -***************************************************************************/ - -#include "emu.h" -#include "lwings.h" - -/*************************************************************************** - - Callbacks for the TileMap code - -***************************************************************************/ - -TILEMAP_MAPPER_MEMBER(lwings_state::get_bg2_memory_offset) -{ - return (row * 0x800) | (col * 2); -} - -TILE_GET_INFO_MEMBER(lwings_state::get_fg_tile_info) -{ - int code = m_fgvideoram[tile_index]; - int color = m_fgvideoram[tile_index + 0x400]; - tileinfo.set(0, - code + ((color & 0xc0) << 2), - color & 0x0f, - TILE_FLIPYX((color & 0x30) >> 4)); -} - -TILE_GET_INFO_MEMBER(lwings_state::lwings_get_bg1_tile_info) -{ - int code = m_bg1videoram[tile_index]; - int color = m_bg1videoram[tile_index + 0x400]; - tileinfo.set(1, - code + ((color & 0xe0) << 3), - color & 0x07, - TILE_FLIPYX((color & 0x18) >> 3)); -} - -TILE_GET_INFO_MEMBER(lwings_state::trojan_get_bg1_tile_info) -{ - int code = m_bg1videoram[tile_index]; - int color = m_bg1videoram[tile_index + 0x400]; - code += (color & 0xe0)<<3; - tileinfo.set(1, - code, - m_bg2_avenger_hw ? ((color & 7) ^ 6) : (color & 7), - ((color & 0x10) ? TILE_FLIPX : 0)); - - tileinfo.group = (color & 0x08) >> 3; -} - -TILE_GET_INFO_MEMBER(lwings_state::get_bg2_tile_info) -{ - int code, color; - uint8_t *rom = memregion("gfx5")->base(); - int mask = memregion("gfx5")->bytes() - 1; - - tile_index = (tile_index + m_bg2_image * 0x20) & mask; - code = rom[tile_index]; - color = rom[tile_index + 1]; - tileinfo.set(3, - code + ((color & 0x80) << 1), - color & 0x07, - TILE_FLIPYX((color & 0x30) >> 4)); -} - -/*************************************************************************** - - Start the video hardware emulation. - -***************************************************************************/ - -void lwings_state::video_start() -{ - m_fg_tilemap = &machine().tilemap().create(*m_gfxdecode, tilemap_get_info_delegate(*this, FUNC(lwings_state::get_fg_tile_info)), TILEMAP_SCAN_ROWS, 8, 8, 32, 32); - m_bg1_tilemap = &machine().tilemap().create(*m_gfxdecode, tilemap_get_info_delegate(*this, FUNC(lwings_state::lwings_get_bg1_tile_info)), TILEMAP_SCAN_COLS, 16, 16, 32, 32); - - m_fg_tilemap->set_transparent_pen(3); -} - -VIDEO_START_MEMBER(lwings_state,trojan) -{ - m_fg_tilemap = &machine().tilemap().create(*m_gfxdecode, tilemap_get_info_delegate(*this, FUNC(lwings_state::get_fg_tile_info)), TILEMAP_SCAN_ROWS, 8, 8, 32, 32); - m_bg1_tilemap = &machine().tilemap().create(*m_gfxdecode, tilemap_get_info_delegate(*this, FUNC(lwings_state::trojan_get_bg1_tile_info)),TILEMAP_SCAN_COLS, 16, 16, 32, 32); - m_bg2_tilemap = &machine().tilemap().create(*m_gfxdecode, tilemap_get_info_delegate(*this, FUNC(lwings_state::get_bg2_tile_info)), tilemap_mapper_delegate(*this, FUNC(lwings_state::get_bg2_memory_offset)), 16, 16, 32, 16); - - m_fg_tilemap->set_transparent_pen(3); - m_bg1_tilemap->set_transmask(0, 0xffff, 0x0001); // split type 0 is totally transparent in front half - m_bg1_tilemap->set_transmask(1, 0xf07f, 0x0f81); // split type 1 has pens 7-11 opaque in front half - - m_bg2_avenger_hw = 0; - m_spr_avenger_hw = 0; -} - -VIDEO_START_MEMBER(lwings_state,avengers) -{ - VIDEO_START_CALL_MEMBER(trojan); - m_bg2_avenger_hw = 1; - m_spr_avenger_hw = 1; -} - -VIDEO_START_MEMBER(lwings_state,buraikenb) -{ - VIDEO_START_CALL_MEMBER(trojan); - m_bg2_avenger_hw = 0; - m_spr_avenger_hw = 1; -} - - -/*************************************************************************** - - Memory handlers - -***************************************************************************/ - -void lwings_state::lwings_fgvideoram_w(offs_t offset, uint8_t data) -{ - m_fgvideoram[offset] = data; - m_fg_tilemap->mark_tile_dirty(offset & 0x3ff); -} - -void lwings_state::lwings_bg1videoram_w(offs_t offset, uint8_t data) -{ - m_bg1videoram[offset] = data; - m_bg1_tilemap->mark_tile_dirty(offset & 0x3ff); -} - - -void lwings_state::lwings_bg1_scrollx_w(offs_t offset, uint8_t data) -{ - m_scroll_x[offset] = data; - m_bg1_tilemap->set_scrollx(0, m_scroll_x[0] | (m_scroll_x[1] << 8)); -} - -void lwings_state::lwings_bg1_scrolly_w(offs_t offset, uint8_t data) -{ - m_scroll_y[offset] = data; - m_bg1_tilemap->set_scrolly(0, m_scroll_y[0] | (m_scroll_y[1] << 8)); -} - -void lwings_state::trojan_bg2_scrollx_w(uint8_t data) -{ - m_bg2_tilemap->set_scrollx(0, data); -} - -void lwings_state::trojan_bg2_image_w(uint8_t data) -{ - if (m_bg2_image != data) - { - m_bg2_image = data; - m_bg2_tilemap->mark_all_dirty(); - } -} - - -/*************************************************************************** - - Display refresh - -***************************************************************************/ - -inline int lwings_state::is_sprite_on( uint8_t *buffered_spriteram, int offs ) -{ - int sx, sy; - - sx = buffered_spriteram[offs + 3] - 0x100 * (buffered_spriteram[offs + 1] & 0x01); - sy = buffered_spriteram[offs + 2]; - - return sx || sy; -} - -void lwings_state::lwings_draw_sprites( bitmap_ind16 &bitmap, const rectangle &cliprect ) -{ - uint8_t *buffered_spriteram = m_spriteram->buffer(); - int offs; - - for (offs = m_spriteram->bytes() - 4; offs >= 0; offs -= 4) - { - if (is_sprite_on(buffered_spriteram, offs)) - { - int code, color, sx, sy, flipx, flipy; - - sx = buffered_spriteram[offs + 3] - 0x100 * (buffered_spriteram[offs + 1] & 0x01); - sy = buffered_spriteram[offs + 2]; - if (sy > 0xf8) - sy -= 0x100; - code = buffered_spriteram[offs] | (buffered_spriteram[offs + 1] & 0xc0) << 2; - color = (buffered_spriteram[offs + 1] & 0x38) >> 3; - flipx = buffered_spriteram[offs + 1] & 0x02; - flipy = buffered_spriteram[offs + 1] & 0x04; - - if (flip_screen()) - { - sx = 240 - sx; - sy = 240 - sy; - flipx = !flipx; - flipy = !flipy; - } - - m_gfxdecode->gfx(2)->transpen(bitmap,cliprect, - code+(m_sprbank*0x400),color, - flipx,flipy, - sx,sy,15); - } - } -} - -void lwings_state::trojan_draw_sprites( bitmap_ind16 &bitmap, const rectangle &cliprect ) -{ - uint8_t *buffered_spriteram = m_spriteram->buffer(); - int offs; - - for (offs = m_spriteram->bytes() - 4; offs >= 0; offs -= 4) - { - if (is_sprite_on(buffered_spriteram, offs)) - { - int code, color, sx, sy, flipx, flipy; - - sx = buffered_spriteram[offs + 3] - 0x100 * (buffered_spriteram[offs + 1] & 0x01); - sy = buffered_spriteram[offs + 2]; - if (sy > 0xf8) - sy -= 0x100; - code = buffered_spriteram[offs] | - ((buffered_spriteram[offs + 1] & 0x20) << 4) | - ((buffered_spriteram[offs + 1] & 0x40) << 2) | - ((buffered_spriteram[offs + 1] & 0x80) << 3); - color = (buffered_spriteram[offs + 1] & 0x0e) >> 1; - - if (m_spr_avenger_hw) - { - flipx = 0; /* Avengers */ - flipy = ~buffered_spriteram[offs + 1] & 0x10; - } - else - { - flipx = buffered_spriteram[offs + 1] & 0x10; /* Trojan */ - flipy = 1; - } - - if (flip_screen()) - { - sx = 240 - sx; - sy = 240 - sy; - flipx = !flipx; - flipy = !flipy; - } - - m_gfxdecode->gfx(2)->transpen(bitmap,cliprect, - code,color, - flipx,flipy, - sx,sy,15); - } - } -} - -uint32_t lwings_state::screen_update_lwings(screen_device &screen, bitmap_ind16 &bitmap, const rectangle &cliprect) -{ - m_bg1_tilemap->draw(screen, bitmap, cliprect, 0, 0); - lwings_draw_sprites(bitmap, cliprect); - m_fg_tilemap->draw(screen, bitmap, cliprect, 0, 0); - return 0; -} - -uint32_t lwings_state::screen_update_trojan(screen_device &screen, bitmap_ind16 &bitmap, const rectangle &cliprect) -{ - m_bg2_tilemap->draw(screen, bitmap, cliprect, 0, 0); - m_bg1_tilemap->draw(screen, bitmap, cliprect, TILEMAP_DRAW_LAYER1, 0); - trojan_draw_sprites(bitmap, cliprect); - m_bg1_tilemap->draw(screen, bitmap, cliprect, TILEMAP_DRAW_LAYER0, 0); - m_fg_tilemap->draw(screen, bitmap, cliprect, 0, 0); - return 0; -} -- cgit v1.2.3