- nmk/cultures.cpp: updated to use memory view instead of bankdev and other small cleanups

- wing/lucky37.cpp: put the driver in an anonymous namespace

- wing/superwng.cpp: used finder instead of tag lookup for memory bank and other small cleanups
This commit is contained in:
Ivan Vangelista 2022-12-28 19:03:40 +01:00
parent 0f188db315
commit ba44facc37
3 changed files with 267 additions and 305 deletions

View File

@ -1,5 +1,6 @@
// license:BSD-3-Clause
// copyright-holders:Pierpaolo Prazzoli
// copyright-holders: Pierpaolo Prazzoli
/*
Jibun wo Migaku Culture School Mahjong Hen
(c)1994 Face
@ -8,18 +9,21 @@
thanks to David Haywood for some precious advice
TODO: PCB has a 93C46 but it isn't hooked up in the driver. Is it unused?
*/
#include "emu.h"
#include "cpu/z80/z80.h"
#include "machine/bankdev.h"
#include "sound/okim6295.h"
#include "emupal.h"
#include "screen.h"
#include "speaker.h"
#include "tilemap.h"
#define MCLK 16000000
namespace {
class cultures_state : public driver_device
{
@ -28,46 +32,41 @@ public:
driver_device(mconfig, type, tag),
m_maincpu(*this, "maincpu"),
m_gfxdecode(*this, "gfxdecode"),
m_vrambank(*this, "vrambank"),
m_vramview(*this, "vramview"),
m_prgbank(*this, "prgbank"),
m_okibank(*this, "okibank"),
m_bg1_rom(*this, "bg1"),
m_bg2_rom(*this, "bg2"),
m_bg_rom(*this, "bg%u", 1U),
m_bg0_videoram(*this, "bg0_videoram"),
m_bg0_regs_x(*this, "bg0_regs_x"),
m_bg0_regs_y(*this, "bg0_regs_y"),
m_bg1_regs_x(*this, "bg1_regs_x"),
m_bg1_regs_y(*this, "bg1_regs_y"),
m_bg2_regs_x(*this, "bg2_regs_x"),
m_bg2_regs_y(*this, "bg2_regs_y")
m_bg_regs_x(*this, "bg%u_regs_x", 0U),
m_bg_regs_y(*this, "bg%u_regs_y", 0U)
{ }
/* devices */
void cultures(machine_config &config);
protected:
virtual void machine_start() override;
virtual void machine_reset() override;
virtual void video_start() override;
private:
// devices
required_device<cpu_device> m_maincpu;
required_device<gfxdecode_device> m_gfxdecode;
required_device<address_map_bank_device> m_vrambank;
// memory pointers
memory_view m_vramview;
required_memory_bank m_prgbank;
required_memory_bank m_okibank;
/* memory pointers */
required_region_ptr<uint16_t> m_bg1_rom;
required_region_ptr<uint16_t> m_bg2_rom;
required_region_ptr_array<uint16_t, 2> m_bg_rom;
required_shared_ptr<uint8_t> m_bg0_videoram;
required_shared_ptr<uint8_t> m_bg0_regs_x;
required_shared_ptr<uint8_t> m_bg0_regs_y;
required_shared_ptr<uint8_t> m_bg1_regs_x;
required_shared_ptr<uint8_t> m_bg1_regs_y;
required_shared_ptr<uint8_t> m_bg2_regs_x;
required_shared_ptr<uint8_t> m_bg2_regs_y;
required_shared_ptr_array<uint8_t, 3> m_bg_regs_x;
required_shared_ptr_array<uint8_t, 3> m_bg_regs_y;
// video-related
tilemap_t *m_bg_tilemap[3];
uint8_t m_irq_enable;
uint8_t m_bg_rombank[2];
/* video-related */
tilemap_t *m_bg0_tilemap;
tilemap_t *m_bg1_tilemap;
tilemap_t *m_bg2_tilemap;
int m_irq_enable;
int m_bg1_bank;
int m_bg2_bank;
void cpu_bankswitch_w(uint8_t data);
void bg0_videoram_w(offs_t offset, uint8_t data);
void misc_w(uint8_t data);
@ -75,29 +74,24 @@ public:
TILE_GET_INFO_MEMBER(get_bg1_tile_info);
TILE_GET_INFO_MEMBER(get_bg2_tile_info);
TILE_GET_INFO_MEMBER(get_bg0_tile_info);
virtual void machine_start() override;
virtual void machine_reset() override;
virtual void video_start() override;
uint32_t screen_update_cultures(screen_device &screen, bitmap_ind16 &bitmap, const rectangle &cliprect);
INTERRUPT_GEN_MEMBER(cultures_interrupt);
void cultures(machine_config &config);
void cultures_io_map(address_map &map);
void cultures_map(address_map &map);
uint32_t screen_update(screen_device &screen, bitmap_ind16 &bitmap, const rectangle &cliprect);
INTERRUPT_GEN_MEMBER(interrupt);
void io_map(address_map &map);
void program_map(address_map &map);
void oki_map(address_map &map);
void vrambank_map(address_map &map);
};
TILE_GET_INFO_MEMBER(cultures_state::get_bg1_tile_info)
{
int const code = m_bg1_rom[0x200000/2 + m_bg1_bank * 0x80000/2 + tile_index];
int const code = m_bg_rom[0][0x200000 / 2 + m_bg_rombank[0] * 0x80000 / 2 + tile_index];
tileinfo.set(1, code, code >> 12, 0);
}
TILE_GET_INFO_MEMBER(cultures_state::get_bg2_tile_info)
{
int const code = m_bg2_rom[0x200000/2 + m_bg2_bank * 0x80000/2 + tile_index];
int const code = m_bg_rom[1][0x200000 / 2 + m_bg_rombank[1] * 0x80000 / 2 + tile_index];
tileinfo.set(2, code, code >> 12, 0);
}
@ -109,47 +103,45 @@ TILE_GET_INFO_MEMBER(cultures_state::get_bg0_tile_info)
void cultures_state::video_start()
{
m_bg0_tilemap = &machine().tilemap().create(*m_gfxdecode, tilemap_get_info_delegate(*this, FUNC(cultures_state::get_bg0_tile_info)), TILEMAP_SCAN_ROWS, 8, 8, 64, 128);
m_bg1_tilemap = &machine().tilemap().create(*m_gfxdecode, tilemap_get_info_delegate(*this, FUNC(cultures_state::get_bg1_tile_info)), TILEMAP_SCAN_ROWS, 8, 8, 512, 512);
m_bg2_tilemap = &machine().tilemap().create(*m_gfxdecode, tilemap_get_info_delegate(*this, FUNC(cultures_state::get_bg2_tile_info)), TILEMAP_SCAN_ROWS, 8, 8, 512, 512);
m_bg_tilemap[0] = &machine().tilemap().create(*m_gfxdecode, tilemap_get_info_delegate(*this, FUNC(cultures_state::get_bg0_tile_info)), TILEMAP_SCAN_ROWS, 8, 8, 64, 128);
m_bg_tilemap[1] = &machine().tilemap().create(*m_gfxdecode, tilemap_get_info_delegate(*this, FUNC(cultures_state::get_bg1_tile_info)), TILEMAP_SCAN_ROWS, 8, 8, 512, 512);
m_bg_tilemap[2] = &machine().tilemap().create(*m_gfxdecode, tilemap_get_info_delegate(*this, FUNC(cultures_state::get_bg2_tile_info)), TILEMAP_SCAN_ROWS, 8, 8, 512, 512);
m_bg1_tilemap->set_transparent_pen(0);
m_bg0_tilemap->set_transparent_pen(0);
m_bg_tilemap[1]->set_transparent_pen(0);
m_bg_tilemap[0]->set_transparent_pen(0);
m_bg0_tilemap->set_scrolldx(502, -118);
m_bg1_tilemap->set_scrolldx(502, -118);
m_bg2_tilemap->set_scrolldx(502, -118);
m_bg_tilemap[0]->set_scrolldx(502, -118);
m_bg_tilemap[1]->set_scrolldx(502, -118);
m_bg_tilemap[2]->set_scrolldx(502, -118);
m_bg0_tilemap->set_scrolldy(255, -16);
m_bg1_tilemap->set_scrolldy(255, -16);
m_bg2_tilemap->set_scrolldy(255, -16);
m_bg_tilemap[0]->set_scrolldy(255, -16);
m_bg_tilemap[1]->set_scrolldy(255, -16);
m_bg_tilemap[2]->set_scrolldy(255, -16);
}
uint32_t cultures_state::screen_update_cultures(screen_device &screen, bitmap_ind16 &bitmap, const rectangle &cliprect)
uint32_t cultures_state::screen_update(screen_device &screen, bitmap_ind16 &bitmap, const rectangle &cliprect)
{
int attr;
// tilemaps attributes
attr = (m_bg0_regs_x[3] & 1 ? TILEMAP_FLIPX : 0) | (m_bg0_regs_y[3] & 1 ? TILEMAP_FLIPY : 0);
m_bg0_tilemap->set_flip(attr);
int attr = (m_bg_regs_x[0][3] & 1 ? TILEMAP_FLIPX : 0) | (m_bg_regs_y[0][3] & 1 ? TILEMAP_FLIPY : 0);
m_bg_tilemap[0]->set_flip(attr);
attr = (m_bg1_regs_x[3] & 1 ? TILEMAP_FLIPX : 0) | (m_bg1_regs_y[3] & 1 ? TILEMAP_FLIPY : 0);
m_bg1_tilemap->set_flip(attr);
attr = (m_bg_regs_x[1][3] & 1 ? TILEMAP_FLIPX : 0) | (m_bg_regs_y[1][3] & 1 ? TILEMAP_FLIPY : 0);
m_bg_tilemap[1]->set_flip(attr);
attr = (m_bg2_regs_x[3] & 1 ? TILEMAP_FLIPX : 0) | (m_bg2_regs_y[3] & 1 ? TILEMAP_FLIPY : 0);
m_bg2_tilemap->set_flip(attr);
attr = (m_bg_regs_x[2][3] & 1 ? TILEMAP_FLIPX : 0) | (m_bg_regs_y[2][3] & 1 ? TILEMAP_FLIPY : 0);
m_bg_tilemap[2]->set_flip(attr);
// tilemaps scrolls
m_bg0_tilemap->set_scrollx(0, (m_bg0_regs_x[2] << 8) + m_bg0_regs_x[0]);
m_bg1_tilemap->set_scrollx(0, (m_bg1_regs_x[2] << 8) + m_bg1_regs_x[0]);
m_bg2_tilemap->set_scrollx(0, (m_bg2_regs_x[2] << 8) + m_bg2_regs_x[0]);
m_bg0_tilemap->set_scrolly(0, (m_bg0_regs_y[2] << 8) + m_bg0_regs_y[0]);
m_bg1_tilemap->set_scrolly(0, (m_bg1_regs_y[2] << 8) + m_bg1_regs_y[0]);
m_bg2_tilemap->set_scrolly(0, (m_bg2_regs_y[2] << 8) + m_bg2_regs_y[0]);
m_bg_tilemap[0]->set_scrollx(0, (m_bg_regs_x[0][2] << 8) + m_bg_regs_x[0][0]);
m_bg_tilemap[1]->set_scrollx(0, (m_bg_regs_x[1][2] << 8) + m_bg_regs_x[1][0]);
m_bg_tilemap[2]->set_scrollx(0, (m_bg_regs_x[2][2] << 8) + m_bg_regs_x[2][0]);
m_bg_tilemap[0]->set_scrolly(0, (m_bg_regs_y[0][2] << 8) + m_bg_regs_y[0][0]);
m_bg_tilemap[1]->set_scrolly(0, (m_bg_regs_y[1][2] << 8) + m_bg_regs_y[1][0]);
m_bg_tilemap[2]->set_scrolly(0, (m_bg_regs_y[2][2] << 8) + m_bg_regs_y[2][0]);
m_bg2_tilemap->draw(screen, bitmap, cliprect, 0, 0);
m_bg0_tilemap->draw(screen, bitmap, cliprect, 0, 0);
m_bg1_tilemap->draw(screen, bitmap, cliprect, 0, 0);
m_bg_tilemap[2]->draw(screen, bitmap, cliprect, 0, 0);
m_bg_tilemap[0]->draw(screen, bitmap, cliprect, 0, 0);
m_bg_tilemap[1]->draw(screen, bitmap, cliprect, 0, 0);
return 0;
}
@ -157,34 +149,34 @@ uint32_t cultures_state::screen_update_cultures(screen_device &screen, bitmap_in
void cultures_state::cpu_bankswitch_w(uint8_t data)
{
m_prgbank->set_entry(data & 0x0f);
m_vrambank->set_bank((data & 0x20)>>5);
m_vramview.select((data & 0x20) >> 5);
}
void cultures_state::bg0_videoram_w(offs_t offset, uint8_t data)
{
m_bg0_videoram[offset] = data;
m_bg0_tilemap->mark_tile_dirty(offset >> 1);
m_bg_tilemap[0]->mark_tile_dirty(offset >> 1);
}
void cultures_state::misc_w(uint8_t data)
{
m_okibank->set_entry(data&0x0f);
m_okibank->set_entry(data & 0x0f);
m_irq_enable = data & 0x80;
}
void cultures_state::bg_bank_w(uint8_t data)
{
if (m_bg1_bank != (data & 3))
if (m_bg_rombank[0] != (data & 3))
{
m_bg1_bank = data & 3;
m_bg1_tilemap->mark_all_dirty();
m_bg_rombank[0] = data & 3;
m_bg_tilemap[1]->mark_all_dirty();
}
if (m_bg2_bank != ((data & 0xc) >> 2))
if (m_bg_rombank[1] != ((data & 0xc) >> 2))
{
m_bg2_bank = (data & 0xc) >> 2;
m_bg2_tilemap->mark_all_dirty();
m_bg_rombank[1] = (data & 0xc) >> 2;
m_bg_tilemap[2]->mark_all_dirty();
}
machine().bookkeeping().coin_counter_w(0, data & 0x10);
}
@ -193,35 +185,31 @@ void cultures_state::bg_bank_w(uint8_t data)
void cultures_state::oki_map(address_map &map)
{
map(0x00000, 0x1ffff).rom();
map(0x20000, 0x3ffff).bankr("okibank");
map(0x20000, 0x3ffff).bankr(m_okibank);
}
void cultures_state::vrambank_map(address_map &map)
{
map(0x0000, 0x3fff).ram().w(FUNC(cultures_state::bg0_videoram_w)).share("bg0_videoram");
map(0x4000, 0x6fff).ram().w("palette", FUNC(palette_device::write8)).share("palette");
}
void cultures_state::cultures_map(address_map &map)
void cultures_state::program_map(address_map &map)
{
map(0x0000, 0x3fff).rom();
map(0x4000, 0x7fff).bankr("prgbank");
map(0x8000, 0xbfff).m(m_vrambank, FUNC(address_map_bank_device::amap8));
map(0x4000, 0x7fff).bankr(m_prgbank);
map(0x8000, 0xbfff).view(m_vramview);
m_vramview[0](0x8000, 0xbfff).ram().w(FUNC(cultures_state::bg0_videoram_w)).share(m_bg0_videoram);
m_vramview[1](0x8000, 0xafff).ram().w("palette", FUNC(palette_device::write8)).share("palette");
map(0xc000, 0xdfff).ram();
map(0xf000, 0xffff).ram();
}
void cultures_state::cultures_io_map(address_map &map)
void cultures_state::io_map(address_map &map)
{
map.global_mask(0xff);
map(0x00, 0x03).ram();
map(0x10, 0x13).ram();
map(0x20, 0x23).ram().share("bg0_regs_x");
map(0x30, 0x33).ram().share("bg0_regs_y");
map(0x40, 0x43).ram().share("bg1_regs_x");
map(0x50, 0x53).ram().share("bg1_regs_y");
map(0x60, 0x63).ram().share("bg2_regs_x");
map(0x70, 0x73).ram().share("bg2_regs_y");
map(0x20, 0x23).ram().share(m_bg_regs_x[0]);
map(0x30, 0x33).ram().share(m_bg_regs_y[0]);
map(0x40, 0x43).ram().share(m_bg_regs_x[1]);
map(0x50, 0x53).ram().share(m_bg_regs_y[1]);
map(0x60, 0x63).ram().share(m_bg_regs_x[2]);
map(0x70, 0x73).ram().share(m_bg_regs_y[2]);
map(0x80, 0x80).w(FUNC(cultures_state::cpu_bankswitch_w));
map(0x90, 0x90).w(FUNC(cultures_state::misc_w));
map(0xa0, 0xa0).w(FUNC(cultures_state::bg_bank_w));
@ -357,8 +345,6 @@ static INPUT_PORTS_START( cultures )
PORT_BIT( 0x80, IP_ACTIVE_LOW, IPT_COIN1 )
INPUT_PORTS_END
/*** GFX Decode ***/
static const gfx_layout gfxlayout =
{
@ -377,7 +363,7 @@ static GFXDECODE_START( gfx_cultures )
GFXDECODE_ENTRY("bg2", 0, gfxlayout, 0x1000, 8 )
GFXDECODE_END
INTERRUPT_GEN_MEMBER(cultures_state::cultures_interrupt)
INTERRUPT_GEN_MEMBER(cultures_state::interrupt)
{
if (m_irq_enable)
device.execute().set_input_line(0, HOLD_LINE);
@ -390,47 +376,46 @@ void cultures_state::machine_start()
m_okibank->set_entry(0);
save_item(NAME(m_irq_enable));
save_item(NAME(m_bg1_bank));
save_item(NAME(m_bg2_bank));
save_item(NAME(m_bg_rombank));
}
void cultures_state::machine_reset()
{
m_okibank->set_entry(0);
m_vrambank->set_bank(1);
m_vramview.select(1);
m_irq_enable = 0;
m_bg1_bank = 0;
m_bg2_bank = 0;
m_bg_rombank[0] = 0;
m_bg_rombank[1] = 0;
}
void cultures_state::cultures(machine_config &config)
{
/* basic machine hardware */
Z80(config, m_maincpu, MCLK/2); /* 8.000 MHz */
m_maincpu->set_addrmap(AS_PROGRAM, &cultures_state::cultures_map);
m_maincpu->set_addrmap(AS_IO, &cultures_state::cultures_io_map);
m_maincpu->set_vblank_int("screen", FUNC(cultures_state::cultures_interrupt));
static constexpr XTAL MCLK = 16_MHz_XTAL;
ADDRESS_MAP_BANK(config, "vrambank").set_map(&cultures_state::vrambank_map).set_options(ENDIANNESS_LITTLE, 8, 15, 0x4000);
// basic machine hardware
Z80(config, m_maincpu, MCLK / 2); // 8.000 MHz
m_maincpu->set_addrmap(AS_PROGRAM, &cultures_state::program_map);
m_maincpu->set_addrmap(AS_IO, &cultures_state::io_map);
m_maincpu->set_vblank_int("screen", FUNC(cultures_state::interrupt));
/* video hardware */
// video hardware
screen_device &screen(SCREEN(config, "screen", SCREEN_TYPE_RASTER));
screen.set_refresh_hz(60);
screen.set_vblank_time(ATTOSECONDS_IN_USEC(0));
screen.set_size(64*8, 32*8);
screen.set_visarea(0*8, 48*8-1, 0*8, 30*8-1);
screen.set_screen_update(FUNC(cultures_state::screen_update_cultures));
screen.set_screen_update(FUNC(cultures_state::screen_update));
screen.set_palette("palette");
GFXDECODE(config, m_gfxdecode, "palette", gfx_cultures);
PALETTE(config, "palette").set_format(palette_device::xRGBRRRRGGGGBBBB_bit0, 0x3000/2);
/* sound hardware */
// sound hardware
SPEAKER(config, "mono").front_center();
okim6295_device &oki(OKIM6295(config, "oki", MCLK/8, okim6295_device::PIN7_HIGH)); // clock frequency & pin 7 not verified
okim6295_device &oki(OKIM6295(config, "oki", MCLK / 8, okim6295_device::PIN7_HIGH)); // clock frequency & pin 7 not verified
oki.add_route(ALL_OUTPUTS, "mono", 0.30);
oki.set_addrmap(0, &cultures_state::oki_map);
}
@ -482,21 +467,23 @@ ROM_START( cultures )
ROM_REGION( 0x400000, "bg0", ROMREGION_ERASE00 )
ROM_LOAD( "bg0c.u45", 0x000000, 0x200000, CRC(ad2e1263) SHA1(b28a3d82aaa0421a7b4df837814147b109e7d1a5) )
ROM_LOAD( "bg0c2.u46", 0x200000, 0x100000, CRC(97c71c09) SHA1(ffbcee1d9cb39d0824f3aa652c3a24579113cf2e) )
/* 0x300000 - 0x3fffff empty */
// 0x300000 - 0x3fffff empty
ROM_REGION16_LE( 0x400000, "bg1", ROMREGION_ERASE00 )
ROM_LOAD( "bg2c.u68", 0x000000, 0x200000, CRC(fa598644) SHA1(532249e456c34f18a787d5a028df82f2170f604d) )
ROM_LOAD( "bg1t.u67", 0x200000, 0x100000, CRC(d2e594ee) SHA1(a84b5ab62dec1867d433ccaeb1381e7593958cf0) )
/* 0x300000 - 0x3fffff empty */
// 0x300000 - 0x3fffff empty
ROM_REGION16_LE( 0x400000, "bg2", ROMREGION_ERASE00 )
ROM_LOAD( "bg1c.u80", 0x000000, 0x200000, CRC(9ab99bd9) SHA1(bce41b6f5d83c8262ba8d37b2dfcd5d7a5e7ace7) )
ROM_LOAD( "bg2t.u79", 0x200000, 0x100000, CRC(0610a79f) SHA1(9fc6b2e5c573ed682b2f7fa462c8f42ff99da5ba) )
/* 0x300000 - 0x3fffff empty */
// 0x300000 - 0x3fffff empty
ROM_REGION( 0x200000, "oki", 0 )
ROM_LOAD( "pcm.u87", 0x000000, 0x200000, CRC(84206475) SHA1(d1423bd5c7425e121fb4e7845cf57801e9afa7b3) )
ROM_END
} // anonymous namespace
GAME( 1994, cultures, 0, cultures, cultures, cultures_state, empty_init, ROT0, "Face", "Jibun wo Migaku Culture School Mahjong Hen", MACHINE_SUPPORTS_SAVE )

View File

@ -52,14 +52,18 @@
#include "emu.h"
#include "cpu/z80/z80.h"
#include "cpu/z180/hd647180x.h"
#include "cpu/z80/z80.h"
#include "machine/mb8421.h"
#include "machine/nvram.h"
#include "sound/okim6295.h"
#include "screen.h"
#include "speaker.h"
namespace {
class lucky37_state : public driver_device
{
public:
@ -249,6 +253,8 @@ ROM_START( bingo75 ) // runs on wing 8802-c board
ROM_LOAD( "82s129.5f", 0x0600, 0x0100, CRC(83c3ec8f) SHA1(4a6452ef73061a446e6a8ceb9d077bc71cc8e2b2) )
ROM_END
} // anonymous namespace
GAME( 199?, lucky21, 0, lucky37, lucky37, lucky37_state, empty_init, ROT0, "Wing Co., Ltd.", "Lucky 21", MACHINE_IS_SKELETON )
GAME( 199?, lucky21d, 0, lucky37, lucky37, lucky37_state, empty_init, ROT0, "Wing Co., Ltd.", "Lucky 21-D", MACHINE_IS_SKELETON )

View File

@ -1,5 +1,6 @@
// license:BSD-3-Clause
// copyright-holders:Tomasz Slanina
// copyright-holders: Tomasz Slanina
/****************************************************************************************
Super Wing - (c) 1985 Wing (UPL?)
@ -10,8 +11,8 @@ probably a sequel to flipjack
Hardware a bit (interrupts, sound) similar to mouser as well
TODO:
- unused rom 6.8s (located on the pcb near the gfx rom 7.8p, but contains
data (similar to the one in roms 4.5p and 5.5r)
- unused ROM 6.8s (located on the PCB near the gfx ROM 7.8p, but contains
data (similar to the one in ROMs 4.5p and 5.5r)
The game currently crashes after the bonus round rather than moving on to
the next level, it writes 01 to 0xa187 which is probably ROM bank, however
@ -23,7 +24,7 @@ TODO:
the ball into one of the portals at the top left)
- dump color prom
- dump color PROM
- some unknown DSW and inputs
- hopper
- unknown writes
@ -33,15 +34,28 @@ TODO:
*****************************************************************************************/
#include "emu.h"
#include "cpu/z80/z80.h"
#include "machine/gen_latch.h"
#include "sound/ay8910.h"
#include "emupal.h"
#include "screen.h"
#include "speaker.h"
#include "tilemap.h"
#define MASTER_CLOCK XTAL(18'432'000)
// configurable logging
#define LOG_UNKWRITE (1U << 1)
//#define VERBOSE (LOG_GENERAL | LOG_UNKWRITE)
#include "logmacro.h"
#define LOGUNKWRITE(...) LOGMASKED(LOG_UNKWRITE, __VA_ARGS__)
namespace {
class superwng_state : public driver_device
{
@ -50,12 +64,11 @@ public:
driver_device(mconfig, type, tag),
m_maincpu(*this, "maincpu"),
m_audiocpu(*this, "audiocpu"),
m_videoram_bg(*this, "videorabg"),
m_videoram_fg(*this, "videorafg"),
m_colorram_bg(*this, "colorrabg"),
m_colorram_fg(*this, "colorrafg"),
m_gfxdecode(*this, "gfxdecode"),
m_palette(*this, "palette")
m_palette(*this, "palette"),
m_videoram(*this, "videoram%u", 0U),
m_colorram(*this, "colorram%u", 0U),
m_mainbank(*this, "mainbank")
{ }
void superwng(machine_config &config);
@ -68,108 +81,87 @@ protected:
private:
required_device<cpu_device> m_maincpu;
required_device<cpu_device> m_audiocpu;
required_shared_ptr<uint8_t> m_videoram_bg;
required_shared_ptr<uint8_t> m_videoram_fg;
required_shared_ptr<uint8_t> m_colorram_bg;
required_shared_ptr<uint8_t> m_colorram_fg;
required_device<gfxdecode_device> m_gfxdecode;
required_device<palette_device> m_palette;
required_shared_ptr_array<uint8_t, 2> m_videoram; // 0 BG, 1 FG
required_shared_ptr_array<uint8_t, 2> m_colorram; // 0 BG, 1 FG
required_memory_bank m_mainbank;
uint8_t m_tile_bank = 0;
uint8_t m_sound_byte = 0;
uint8_t m_nmi_enable = 0;
tilemap_t * m_bg_tilemap = nullptr;
tilemap_t * m_fg_tilemap = nullptr;
tilemap_t *m_tilemap[2] {};
void superwng_nmi_enable_w(uint8_t data);
void superwng_sound_interrupt_w(uint8_t data);
void superwng_sound_nmi_clear_w(uint8_t data);
void superwng_bg_vram_w(offs_t offset, uint8_t data);
void superwng_bg_cram_w(offs_t offset, uint8_t data);
void superwng_fg_vram_w(offs_t offset, uint8_t data);
void superwng_fg_cram_w(offs_t offset, uint8_t data);
void superwng_tilebank_w(uint8_t data);
void superwng_flip_screen_w(uint8_t data);
void superwng_cointcnt1_w(uint8_t data);
void superwng_cointcnt2_w(uint8_t data);
void superwng_hopper_w(uint8_t data);
uint8_t superwng_sound_byte_r();
void superwng_unk_a187_w(uint8_t data);
void superwng_unk_a185_w(uint8_t data);
void nmi_enable_w(uint8_t data);
void sound_nmi_clear_w(uint8_t data);
template <uint8_t Which> void vram_w(offs_t offset, uint8_t data);
template <uint8_t Which> void cram_w(offs_t offset, uint8_t data);
void tilebank_w(uint8_t data);
void flip_screen_w(uint8_t data);
template <uint8_t Which> void cointcnt_w(uint8_t data);
void hopper_w(uint8_t data);
void unk_a187_w(uint8_t data);
void unk_a185_w(uint8_t data);
TILE_GET_INFO_MEMBER(get_bg_tile_info);
TILE_GET_INFO_MEMBER(get_fg_tile_info);
void superwng_palette(palette_device &palette) const;
uint32_t screen_update_superwng(screen_device &screen, bitmap_ind16 &bitmap, const rectangle &cliprect);
template <uint8_t Which> TILE_GET_INFO_MEMBER(get_tile_info);
void palette(palette_device &palette) const;
uint32_t screen_update(screen_device &screen, bitmap_ind16 &bitmap, const rectangle &cliprect);
DECLARE_WRITE_LINE_MEMBER(main_nmi_interrupt);
INTERRUPT_GEN_MEMBER(superwng_sound_nmi_assert);
INTERRUPT_GEN_MEMBER(sound_nmi_assert);
void superwng_map(address_map &map);
void superwng_sound_map(address_map &map);
void main_map(address_map &map);
void sound_map(address_map &map);
};
void superwng_state::superwng_unk_a187_w(uint8_t data)
void superwng_state::unk_a187_w(uint8_t data)
{
membank("bank1")->set_entry(data&1);
m_mainbank->set_entry(data & 1);
}
void superwng_state::superwng_unk_a185_w(uint8_t data)
void superwng_state::unk_a185_w(uint8_t data)
{
// printf("superwng_unk_a185_w %02x\n", data);
LOGUNKWRITE("unk_a185_w %02x\n", data);
}
TILE_GET_INFO_MEMBER(superwng_state::get_bg_tile_info)
template <uint8_t Which>
TILE_GET_INFO_MEMBER(superwng_state::get_tile_info)
{
int code = m_videoram_bg[tile_index];
int attr = m_colorram_bg[tile_index];
int code = m_videoram[Which][tile_index];
int const attr = m_colorram[Which][tile_index];
code= (code&0x7f) | ((attr&0x40)<<1) | ((code&0x80)<<1);
code|=m_tile_bank?0x200:0;
code = (code & 0x7f) | ((attr & 0x40) << 1) | ((code & 0x80) << 1);
code |= m_tile_bank ? 0x200 : 0;
int flipx=(attr&0x80) ? TILE_FLIPX : 0;
int flipy=(attr&0x80) ? TILE_FLIPY : 0;
int const flipx = (attr & 0x80) ? TILE_FLIPX : 0;
int const flipy = (attr & 0x80) ? TILE_FLIPY : 0;
tileinfo.set(0, code, attr & 0xf, flipx|flipy);
}
TILE_GET_INFO_MEMBER(superwng_state::get_fg_tile_info)
{
int code = m_videoram_fg[tile_index];
int attr = m_colorram_fg[tile_index];
code= (code&0x7f) | ((attr&0x40)<<1) | ((code&0x80)<<1);
code|=m_tile_bank?0x200:0;
int flipx=(attr&0x80) ? TILE_FLIPX : 0;
int flipy=(attr&0x80) ? TILE_FLIPY : 0;
tileinfo.set(0, code, attr & 0xf, flipx|flipy);
tileinfo.set(0, code, attr & 0xf, flipx | flipy);
}
void superwng_state::video_start()
{
m_bg_tilemap = &machine().tilemap().create(*m_gfxdecode, tilemap_get_info_delegate(*this, FUNC(superwng_state::get_bg_tile_info)), TILEMAP_SCAN_ROWS, 8, 8, 32, 32);
m_fg_tilemap = &machine().tilemap().create(*m_gfxdecode, tilemap_get_info_delegate(*this, FUNC(superwng_state::get_fg_tile_info)), TILEMAP_SCAN_ROWS, 8, 8, 32, 32);
m_tilemap[0] = &machine().tilemap().create(*m_gfxdecode, tilemap_get_info_delegate(*this, FUNC(superwng_state::get_tile_info<0>)), TILEMAP_SCAN_ROWS, 8, 8, 32, 32);
m_tilemap[1] = &machine().tilemap().create(*m_gfxdecode, tilemap_get_info_delegate(*this, FUNC(superwng_state::get_tile_info<1>)), TILEMAP_SCAN_ROWS, 8, 8, 32, 32);
m_bg_tilemap->set_scrollx(0, 64);
m_tilemap[0]->set_scrollx(0, 64);
}
uint32_t superwng_state::screen_update_superwng(screen_device &screen, bitmap_ind16 &bitmap, const rectangle &cliprect)
uint32_t superwng_state::screen_update(screen_device &screen, bitmap_ind16 &bitmap, const rectangle &cliprect)
{
m_bg_tilemap->draw(screen, bitmap, cliprect, 0, 0);
m_tilemap[0]->draw(screen, bitmap, cliprect, 0, 0);
rectangle tmp = cliprect;
if (flip_screen())
{
tmp.min_x += 32;
m_fg_tilemap->draw(screen, bitmap, tmp, 0, 0);
m_tilemap[1]->draw(screen, bitmap, tmp, 0, 0);
}
else
{
tmp.max_x -= 32;
m_fg_tilemap->draw(screen, bitmap, tmp, 0, 0);
m_tilemap[1]->draw(screen, bitmap, tmp, 0, 0);
}
//sprites
@ -185,16 +177,16 @@ uint32_t superwng_state::screen_update_superwng(screen_device &screen, bitmap_in
x ?
xxxx color
*/
if (~m_videoram_bg[i] & 1)
if (~m_videoram[0][i] & 1)
continue;
int code = (m_videoram_bg[i] >> 2) | 0x40;
int flip = ~m_videoram_bg[i] >> 1 & 1;
int sx = 240 - m_videoram_bg[i + 1];
int sy = m_colorram_bg[i];
int color = m_colorram_bg[i + 1] & 0xf;
int const code = (m_videoram[0][i] >> 2) | 0x40;
int const flip = ~m_videoram[0][i] >> 1 & 1;
int const sx = 240 - m_videoram[0][i + 1];
int const sy = m_colorram[0][i];
int const color = m_colorram[0][i + 1] & 0xf;
m_gfxdecode->gfx(1)->transpen(bitmap,cliprect,
m_gfxdecode->gfx(1)->transpen(bitmap, cliprect,
code,
color,
flip, flip,
@ -205,7 +197,7 @@ uint32_t superwng_state::screen_update_superwng(screen_device &screen, bitmap_in
}
static constexpr uint8_t superwng_colors[]= /* temporary */
static constexpr uint8_t colors[]= // temporary
{
0x00, 0xc4, 0xff, 0x87, 0x00, 0xb0, 0xff, 0x2f, 0x00, 0x07, 0xff, 0xe0, 0x00, 0x86, 0xff, 0xc6,
0x00, 0x07, 0x3f, 0xff, 0x00, 0xb0, 0x38, 0x27, 0x00, 0x20, 0xff, 0x27, 0x00, 0xa4, 0xff, 0x87,
@ -213,31 +205,31 @@ static constexpr uint8_t superwng_colors[]= /* temporary */
0x00, 0xc0, 0x07, 0x3f, 0x00, 0x1f, 0x3f, 0xff, 0x00, 0x86, 0x05, 0xff, 0x00, 0xc0, 0xe8, 0xff
};
void superwng_state::superwng_palette(palette_device &palette) const
void superwng_state::palette(palette_device &palette) const
{
for (int i = 0; i < palette.entries(); i++)
{
int bit0, bit1, bit2;
bit0 = BIT(superwng_colors[i], 0);
bit1 = BIT(superwng_colors[i], 1);
bit2 = BIT(superwng_colors[i], 2);
bit0 = BIT(colors[i], 0);
bit1 = BIT(colors[i], 1);
bit2 = BIT(colors[i], 2);
int const r = 0x21 * bit0 + 0x47 * bit1 + 0x97 * bit2;
bit0 = BIT(superwng_colors[i], 3);
bit1 = BIT(superwng_colors[i], 4);
bit2 = BIT(superwng_colors[i], 5);
bit0 = BIT(colors[i], 3);
bit1 = BIT(colors[i], 4);
bit2 = BIT(colors[i], 5);
int const g = 0x21 * bit0 + 0x47 * bit1 + 0x97 * bit2;
bit0 = BIT(superwng_colors[i], 6);
bit1 = BIT(superwng_colors[i], 7);
bit0 = BIT(colors[i], 6);
bit1 = BIT(colors[i], 7);
int const b = 0x4f * bit0 + 0xa8 * bit1;
palette.set_pen_color(i, rgb_t(r, g, b));
}
}
void superwng_state::superwng_nmi_enable_w(uint8_t data)
void superwng_state::nmi_enable_w(uint8_t data)
{
m_nmi_enable = data;
}
@ -248,112 +240,85 @@ WRITE_LINE_MEMBER(superwng_state::main_nmi_interrupt)
m_maincpu->pulse_input_line(INPUT_LINE_NMI, attotime::zero);
}
void superwng_state::superwng_sound_interrupt_w(uint8_t data)
{
m_sound_byte = data;
m_audiocpu->set_input_line(0, ASSERT_LINE);
}
uint8_t superwng_state::superwng_sound_byte_r()
{
m_audiocpu->set_input_line(0, CLEAR_LINE);
return m_sound_byte;
}
void superwng_state::superwng_sound_nmi_clear_w(uint8_t data)
void superwng_state::sound_nmi_clear_w(uint8_t data)
{
m_audiocpu->set_input_line(INPUT_LINE_NMI, CLEAR_LINE);
}
INTERRUPT_GEN_MEMBER(superwng_state::superwng_sound_nmi_assert)
INTERRUPT_GEN_MEMBER(superwng_state::sound_nmi_assert)
{
if (BIT(m_nmi_enable, 0))
device.execute().set_input_line(INPUT_LINE_NMI, ASSERT_LINE);
}
void superwng_state::superwng_bg_vram_w(offs_t offset, uint8_t data)
template <uint8_t Which>
void superwng_state::vram_w(offs_t offset, uint8_t data)
{
m_videoram_bg[offset] = data;
m_bg_tilemap->mark_tile_dirty(offset);
m_videoram[Which][offset] = data;
m_tilemap[Which]->mark_tile_dirty(offset);
}
void superwng_state::superwng_bg_cram_w(offs_t offset, uint8_t data)
template <uint8_t Which>
void superwng_state::cram_w(offs_t offset, uint8_t data)
{
m_colorram_bg[offset] = data;
m_bg_tilemap->mark_tile_dirty(offset);
m_colorram[Which][offset] = data;
m_tilemap[Which]->mark_tile_dirty(offset);
}
void superwng_state::superwng_fg_vram_w(offs_t offset, uint8_t data)
{
m_videoram_fg[offset] = data;
m_fg_tilemap->mark_tile_dirty(offset);
}
void superwng_state::superwng_fg_cram_w(offs_t offset, uint8_t data)
{
m_colorram_fg[offset] = data;
m_fg_tilemap->mark_tile_dirty(offset);
}
void superwng_state::superwng_tilebank_w(uint8_t data)
void superwng_state::tilebank_w(uint8_t data)
{
m_tile_bank = data;
m_bg_tilemap->mark_all_dirty();
m_fg_tilemap->mark_all_dirty();
m_tilemap[0]->mark_all_dirty();
m_tilemap[1]->mark_all_dirty();
}
void superwng_state::superwng_flip_screen_w(uint8_t data)
void superwng_state::flip_screen_w(uint8_t data)
{
flip_screen_set(~data & 0x01);
m_bg_tilemap->mark_all_dirty();
m_fg_tilemap->mark_all_dirty();
m_tilemap[0]->mark_all_dirty();
m_tilemap[1]->mark_all_dirty();
}
void superwng_state::superwng_cointcnt1_w(uint8_t data)
template <uint8_t Which>
void superwng_state::cointcnt_w(uint8_t data)
{
machine().bookkeeping().coin_counter_w(0, data);
machine().bookkeeping().coin_counter_w(Which, data);
}
void superwng_state::superwng_cointcnt2_w(uint8_t data)
{
machine().bookkeeping().coin_counter_w(1, data);
}
void superwng_state::superwng_hopper_w(uint8_t data)
void superwng_state::hopper_w(uint8_t data)
{
}
void superwng_state::superwng_map(address_map &map)
void superwng_state::main_map(address_map &map)
{
map(0x0000, 0x3fff).rom();
map(0x4000, 0x6fff).bankr("bank1");
map(0x4000, 0x6fff).bankr(m_mainbank);
map(0x7000, 0x7fff).ram();
map(0x8000, 0x83ff).ram().w(FUNC(superwng_state::superwng_bg_vram_w)).share("videorabg");
map(0x8400, 0x87ff).ram().w(FUNC(superwng_state::superwng_fg_vram_w)).share("videorafg");
map(0x8800, 0x8bff).ram().w(FUNC(superwng_state::superwng_bg_cram_w)).share("colorrabg");
map(0x8c00, 0x8fff).ram().w(FUNC(superwng_state::superwng_fg_cram_w)).share("colorrafg");
map(0x8000, 0x83ff).ram().w(FUNC(superwng_state::vram_w<0>)).share(m_videoram[0]);
map(0x8400, 0x87ff).ram().w(FUNC(superwng_state::vram_w<1>)).share(m_videoram[1]);
map(0x8800, 0x8bff).ram().w(FUNC(superwng_state::cram_w<0>)).share(m_colorram[0]);
map(0x8c00, 0x8fff).ram().w(FUNC(superwng_state::cram_w<1>)).share(m_colorram[1]);
map(0x9800, 0x99ff).ram();
map(0xa000, 0xa000).portr("P1");
map(0xa000, 0xa000).w(FUNC(superwng_state::superwng_hopper_w));
map(0xa000, 0xa000).portr("P1").w(FUNC(superwng_state::hopper_w));
map(0xa080, 0xa080).portr("P2");
map(0xa100, 0xa100).portr("DSW1");
map(0xa100, 0xa100).w(FUNC(superwng_state::superwng_sound_interrupt_w));
map(0xa100, 0xa100).portr("DSW1").w("soundlatch", FUNC(generic_latch_8_device::write));
map(0xa180, 0xa180).portr("DSW2");
// TODO: the following is almost certainly a LS259 or similar
map(0xa180, 0xa180).nopw(); // watchdog? int ack?
map(0xa181, 0xa181).w(FUNC(superwng_state::superwng_nmi_enable_w));
map(0xa182, 0xa182).w(FUNC(superwng_state::superwng_tilebank_w));
map(0xa183, 0xa183).w(FUNC(superwng_state::superwng_flip_screen_w));
map(0xa184, 0xa184).w(FUNC(superwng_state::superwng_cointcnt1_w));
map(0xa185, 0xa185).w(FUNC(superwng_state::superwng_unk_a185_w)); // unknown, always(?) 0
map(0xa186, 0xa186).w(FUNC(superwng_state::superwng_cointcnt2_w));
map(0xa187, 0xa187).w(FUNC(superwng_state::superwng_unk_a187_w)); // unknown, always(?) 0
map(0xa181, 0xa181).w(FUNC(superwng_state::nmi_enable_w));
map(0xa182, 0xa182).w(FUNC(superwng_state::tilebank_w));
map(0xa183, 0xa183).w(FUNC(superwng_state::flip_screen_w));
map(0xa184, 0xa184).w(FUNC(superwng_state::cointcnt_w<0>));
map(0xa185, 0xa185).w(FUNC(superwng_state::unk_a185_w)); // unknown, always(?) 0
map(0xa186, 0xa186).w(FUNC(superwng_state::cointcnt_w<1>));
map(0xa187, 0xa187).w(FUNC(superwng_state::unk_a187_w)); // unknown, always(?) 0
}
void superwng_state::superwng_sound_map(address_map &map)
void superwng_state::sound_map(address_map &map)
{
map(0x0000, 0x1fff).rom();
map(0x2000, 0x23ff).ram();
map(0x3000, 0x3000).w(FUNC(superwng_state::superwng_sound_nmi_clear_w));
map(0x3000, 0x3000).w(FUNC(superwng_state::sound_nmi_clear_w));
map(0x4000, 0x4000).rw("ay1", FUNC(ay8910_device::data_r), FUNC(ay8910_device::data_w));
map(0x5000, 0x5000).w("ay1", FUNC(ay8910_device::address_w));
map(0x6000, 0x6000).rw("ay2", FUNC(ay8910_device::data_r), FUNC(ay8910_device::data_w));
@ -460,74 +425,78 @@ static const gfx_layout spritelayout =
};
static GFXDECODE_START( gfx_superwng )
GFXDECODE_ENTRY( "gfx1", 0x0000, charlayout, 0, 16 )
GFXDECODE_ENTRY( "gfx1", 0x0000, spritelayout, 0, 16 )
GFXDECODE_ENTRY( "gfx", 0x0000, charlayout, 0, 16 )
GFXDECODE_ENTRY( "gfx", 0x0000, spritelayout, 0, 16 )
GFXDECODE_END
void superwng_state::machine_start()
{
save_item(NAME(m_tile_bank));
save_item(NAME(m_sound_byte));
save_item(NAME(m_nmi_enable));
membank("bank1")->configure_entries(0, 2, memregion("maincpu")->base()+0x4000, 0x4000);
m_mainbank->configure_entries(0, 2, memregion("maincpu")->base() + 0x4000, 0x4000);
}
void superwng_state::machine_reset()
{
m_sound_byte = 0;
m_nmi_enable = 0;
}
void superwng_state::superwng(machine_config &config)
{
/* basic machine hardware */
Z80(config, m_maincpu, MASTER_CLOCK/4);
m_maincpu->set_addrmap(AS_PROGRAM, &superwng_state::superwng_map);
static constexpr XTAL MASTER_CLOCK = 18.432_MHz_XTAL;
Z80(config, m_audiocpu, MASTER_CLOCK/4);
m_audiocpu->set_addrmap(AS_PROGRAM, &superwng_state::superwng_sound_map);
m_audiocpu->set_periodic_int(FUNC(superwng_state::superwng_sound_nmi_assert), attotime::from_hz(4*60));
// basic machine hardware
Z80(config, m_maincpu, MASTER_CLOCK / 4);
m_maincpu->set_addrmap(AS_PROGRAM, &superwng_state::main_map);
/* video hardware */
Z80(config, m_audiocpu, MASTER_CLOCK / 4);
m_audiocpu->set_addrmap(AS_PROGRAM, &superwng_state::sound_map);
m_audiocpu->set_periodic_int(FUNC(superwng_state::sound_nmi_assert), attotime::from_hz(4 * 60));
GENERIC_LATCH_8(config, "soundlatch").data_pending_callback().set_inputline(m_audiocpu, 0);
// video hardware
screen_device &screen(SCREEN(config, "screen", SCREEN_TYPE_RASTER));
screen.set_refresh_hz(60);
screen.set_vblank_time(ATTOSECONDS_IN_USEC(2500));
screen.set_size(32*8, 32*8);
screen.set_visarea(0*8, 32*8-1, 2*8, 30*8-1);
screen.set_screen_update(FUNC(superwng_state::screen_update_superwng));
screen.set_screen_update(FUNC(superwng_state::screen_update));
screen.set_palette(m_palette);
screen.screen_vblank().set(FUNC(superwng_state::main_nmi_interrupt));
GFXDECODE(config, m_gfxdecode, m_palette, gfx_superwng);
PALETTE(config, m_palette, FUNC(superwng_state::superwng_palette), 0x40);
PALETTE(config, m_palette, FUNC(superwng_state::palette), 0x40);
SPEAKER(config, "mono").front_center();
ay8910_device &ay1(AY8910(config, "ay1", MASTER_CLOCK/12));
ay1.port_a_read_callback().set(FUNC(superwng_state::superwng_sound_byte_r));
ay8910_device &ay1(AY8910(config, "ay1", MASTER_CLOCK / 12));
ay1.port_a_read_callback().set("soundlatch", FUNC(generic_latch_8_device::read));
ay1.add_route(ALL_OUTPUTS, "mono", 0.50);
AY8910(config, "ay2", MASTER_CLOCK/12).add_route(ALL_OUTPUTS, "mono", 0.50);
AY8910(config, "ay2", MASTER_CLOCK / 12).add_route(ALL_OUTPUTS, "mono", 0.50);
}
ROM_START( superwng )
ROM_REGION( 0x20000, "maincpu", 0 )
ROM_LOAD( "2.5l", 0x0000, 0x2000, CRC(8d102f8d) SHA1(ff6d994273a2e493a68637822cd0b1a2f69fd054) )
ROM_LOAD( "3.5m", 0x2000, 0x2000, CRC(3b08bd19) SHA1(2020e2835df86a6a279bbf9d013a489f0e32a4bd) )
ROM_LOAD( "4.5p", 0x4000, 0x2000, CRC(6a49746d) SHA1(f5cd5eb77f60972a3897243f9ee3d61aac0878fc) )
ROM_LOAD( "5.5r", 0x6000, 0x2000, CRC(ebd23487) SHA1(16e8faf989aa80dbf9934450ec4ba642a6f88c63) )
ROM_LOAD( "6.8s", 0x8000, 0x4000, BAD_DUMP CRC(774433e0) SHA1(82b10d797581c14914bcce320f2aa5d3fb1fba33) ) // banked but probably bad, bits at 0xxx39 offsets appear to be missing / corrupt.
ROM_REGION( 0xc000, "maincpu", 0 )
ROM_LOAD( "2.5l", 0x0000, 0x2000, CRC(8d102f8d) SHA1(ff6d994273a2e493a68637822cd0b1a2f69fd054) )
ROM_LOAD( "3.5m", 0x2000, 0x2000, CRC(3b08bd19) SHA1(2020e2835df86a6a279bbf9d013a489f0e32a4bd) )
ROM_LOAD( "4.5p", 0x4000, 0x2000, CRC(6a49746d) SHA1(f5cd5eb77f60972a3897243f9ee3d61aac0878fc) )
ROM_LOAD( "5.5r", 0x6000, 0x2000, CRC(ebd23487) SHA1(16e8faf989aa80dbf9934450ec4ba642a6f88c63) )
ROM_LOAD( "6.8s", 0x8000, 0x4000, BAD_DUMP CRC(774433e0) SHA1(82b10d797581c14914bcce320f2aa5d3fb1fba33) ) // banked but probably bad, bits at 0xxx39 offsets appear to be missing / corrupt.
ROM_REGION( 0x10000, "audiocpu", 0 )
ROM_LOAD( "1.1a", 0x0000, 0x2000, CRC(a70aa39e) SHA1(b03de65d7bd020eb77495997128dce5ccbdbefac) )
ROM_REGION( 0x2000, "audiocpu", 0 )
ROM_LOAD( "1.1a", 0x0000, 0x2000, CRC(a70aa39e) SHA1(b03de65d7bd020eb77495997128dce5ccbdbefac) )
ROM_REGION( 0x4000, "gfx1", 0 )
ROM_LOAD( "7.8p", 0x0000, 0x4000, CRC(b472603c) SHA1(96f477a47a5be3db1292fea4f5c91ab155013f74) )
ROM_REGION( 0x4000, "gfx", 0 )
ROM_LOAD( "7.8p", 0x0000, 0x4000, CRC(b472603c) SHA1(96f477a47a5be3db1292fea4f5c91ab155013f74) )
ROM_REGION( 0x0040, "proms", 0 )
ROM_LOAD( "bprom.bin", 0x0000, 0x0040, NO_DUMP)
ROM_LOAD( "bprom.bin", 0x0000, 0x0040, NO_DUMP )
ROM_END
} // anonymous namespace
GAME( 1985, superwng, 0, superwng, superwng, superwng_state, empty_init, ROT90, "Wing", "Super Wing", MACHINE_NOT_WORKING | MACHINE_WRONG_COLORS | MACHINE_SUPPORTS_SAVE ) // crashes after bonus stage, see notes, bad rom?
GAME( 1985, superwng, 0, superwng, superwng, superwng_state, empty_init, ROT90, "Wing", "Super Wing", MACHINE_NOT_WORKING | MACHINE_WRONG_COLORS | MACHINE_SUPPORTS_SAVE ) // crashes after bonus stage, see notes, bad ROM?