summaryrefslogtreecommitdiffstatshomepage
path: root/src/mame/konami/jackal.cpp
diff options
context:
space:
mode:
Diffstat (limited to 'src/mame/konami/jackal.cpp')
-rw-r--r--src/mame/konami/jackal.cpp781
1 files changed, 781 insertions, 0 deletions
diff --git a/src/mame/konami/jackal.cpp b/src/mame/konami/jackal.cpp
new file mode 100644
index 00000000000..21e5525dcd9
--- /dev/null
+++ b/src/mame/konami/jackal.cpp
@@ -0,0 +1,781 @@
+// license:BSD-3-Clause
+// copyright-holders: Curt Coder
+// thanks-to: Kenneth Lin (original driver author)
+
+/***************************************************************************
+
+ jackal.cpp
+ Konami GX631 PCB
+
+Notes:
+- This game uses two 005885 gfx chip in parallel. The unique thing about it is
+ that the two 4bpp tilemaps from the two chips are merged to form a single
+ 8bpp tilemap.
+- topgunbl is derived from a completely different version, which supports gun
+ turret rotation. The copyright year is also different, but this doesn't
+ necessarily mean anything.
+
+TODO:
+- create a K005885 device shared with other drivers.
+
+
+Memory Map
+----------
+
+MAIN CPU:
+
+Address range 00xxxxxxxxxx---- is handled by the 007343 custom so layout is
+inferred by program behaviour. Note that address lines A8 and A9 are ORed
+together and go to the single A8.9 input of the 007343.
+
+Address Dir Data Description
+---------------- --- -------- -----------------------
+00000000000000xx R/W xxxxxxxx 005885 registers
+0000000000000100 R/W xxxxxxxx 005885 registers
+0000000000010000 R xxxxxxxx DIPSW1
+0000000000010001 R xxxxxxxx P1 inputs + DIPSW3.4
+0000000000010010 R xxxxxxxx P2 inputs
+0000000000010011 R xxxxxxxx Coin inputs + DIPSW3.1-3
+00000000000101-0 R xxxxxxxx P1 extra inputs (only used by the bootleg for the rotary control)
+00000000000101-1 R xxxxxxxx P2 extra inputs (only used by the bootleg for the rotary control)
+00000000000110-0 R xxxxxxxx DIPSW2
+00000000000111-0 W -------x Coin Counter 1 (to 005924 OUT1 input)
+ W ------x- Coin Counter 2 (to 005924 OUT2 input)
+ W -----x-- unknown ("END", to connector SVCN4P pin 4)
+ W ----x--- sprite RAM bank (to 007343 OBJB input)
+ W ---x---- 005885 select (to 007343 GATEB input)
+ W --x----- ROM bank
+00000000000111-1 R/W -------- Watchdog reset (to 005924 AFR input)
+00000000001xxxxx R/W xxxxxxxx scroll RAM (005885)
+00000000010xxxxx R/W xxxxxxxx Z RAM (005885)
+000xxxxxxxxxxxxx R/W xxxxxxxx RAM (shared with sound CPU--note that addresses 0000-005F are handled above so they are excluded)
+0010xxxxxxxxxxxx R/W xxxxxxxx video RAM (005885)
+0011xxxxxxxxxxxx R/W xxxxxxxx sprite RAM (005885)
+01xxxxxxxxxxxxxx R xxxxxxxx ROM (banked)
+10xxxxxxxxxxxxxx R xxxxxxxx ROM (banked)
+11xxxxxxxxxxxxxx R xxxxxxxx ROM
+
+
+SOUND CPU:
+
+Address Dir Data Description
+---------------- --- -------- -----------------------
+000------------- n.c.
+001------------x R/W xxxxxxxx YM2151
+010-xxxxxxxxxxxx R/W xxxxxxxx 007327 (palette)
+011xxxxxxxxxxxxx R/W xxxxxxxx RAM (shared with main CPU)
+1xxxxxxxxxxxxxxx R xxxxxxxx ROM
+
+***************************************************************************/
+
+#include "emu.h"
+
+#include "konamipt.h"
+
+#include "cpu/m6809/m6809.h"
+#include "machine/watchdog.h"
+#include "sound/ymopm.h"
+
+#include "emupal.h"
+#include "screen.h"
+#include "speaker.h"
+#include "tilemap.h"
+
+
+// configurable logging
+#define LOG_RAMBANK (1U << 1)
+
+//#define VERBOSE (LOG_GENERAL | LOG_RAMBANK)
+
+#include "logmacro.h"
+
+#define LOGRAMBANK(...) LOGMASKED(LOG_RAMBANK, __VA_ARGS__)
+
+
+namespace {
+
+class jackal_state : public driver_device
+{
+public:
+ jackal_state(const machine_config &mconfig, device_type type, const char *tag) :
+ driver_device(mconfig, type, tag),
+ m_videoctrl(*this, "videoctrl"),
+ m_videoram(*this, "videoram%u", 0U),
+ m_scrollram(*this, "scrollram%u", 0U, 0x40U, ENDIANNESS_BIG),
+ m_mainbank(*this, "mainbank"),
+ m_videoview(*this, "videoview"),
+ m_spritebank(*this, "spritebank"),
+ m_spriteram(*this, "spriteram%u", 0U, 0x1000U, ENDIANNESS_BIG),
+ m_scrollbank(*this, "scrollbank"),
+ m_dials(*this, "DIAL%u", 0U),
+ m_maincpu(*this, "maincpu"),
+ m_slavecpu(*this, "slave"),
+ m_gfxdecode(*this, "gfxdecode"),
+ m_palette(*this, "palette")
+ { }
+
+ void jackal(machine_config &config);
+
+protected:
+ virtual void machine_start() override ATTR_COLD;
+ virtual void machine_reset() override ATTR_COLD;
+ virtual void video_start() override ATTR_COLD;
+
+private:
+ // memory pointers
+ required_shared_ptr<uint8_t> m_videoctrl;
+ required_shared_ptr_array<uint8_t, 2> m_videoram;
+ memory_share_array_creator<uint8_t, 2> m_scrollram;
+ required_memory_bank m_mainbank;
+ memory_view m_videoview;
+ required_memory_bank m_spritebank;
+ memory_share_array_creator<uint8_t, 2> m_spriteram;
+ required_memory_bank m_scrollbank;
+
+ // video-related
+ tilemap_t *m_bg_tilemap = nullptr;
+
+ // misc
+ uint8_t m_irq_enable = 0;
+ optional_ioport_array<2> m_dials;
+
+ // devices
+ required_device<cpu_device> m_maincpu;
+ required_device<cpu_device> m_slavecpu;
+ required_device<gfxdecode_device> m_gfxdecode;
+ required_device<palette_device> m_palette;
+
+ uint8_t rotary_r(offs_t offset);
+ void flipscreen_w(uint8_t data);
+ void rambank_w(uint8_t data);
+ template <uint8_t Which> void voram_w(offs_t offset, uint8_t data);
+ TILE_GET_INFO_MEMBER(get_bg_tile_info);
+ void palette(palette_device &palette) const;
+ uint32_t screen_update(screen_device &screen, bitmap_ind16 &bitmap, const rectangle &cliprect);
+ void vblank_irq(int state);
+ void draw_background(screen_device &screen, bitmap_ind16 &bitmap, const rectangle &cliprect);
+ void draw_sprites_region(bitmap_ind16 &bitmap, const rectangle &cliprect, const uint8_t *sram, int length, int bank);
+ void draw_sprites(bitmap_ind16 &bitmap, const rectangle &cliprect);
+ void main_map(address_map &map) ATTR_COLD;
+ void slave_map(address_map &map) ATTR_COLD;
+};
+
+
+void jackal_state::palette(palette_device &palette) const
+{
+ uint8_t const *const color_prom = memregion("proms")->base();
+
+ for (int i = 0; i < 0x100; i++)
+ {
+ uint16_t const ctabentry = i | 0x100;
+ palette.set_pen_indirect(i, ctabentry);
+ }
+
+ for (int i = 0x100; i < 0x200; i++)
+ {
+ uint16_t const ctabentry = color_prom[i - 0x100] & 0x0f;
+ palette.set_pen_indirect(i, ctabentry);
+ }
+
+ for (int i = 0x200; i < 0x300; i++)
+ {
+ uint16_t const ctabentry = (color_prom[i - 0x100] & 0x0f) | 0x10;
+ palette.set_pen_indirect(i, ctabentry);
+ }
+}
+
+TILE_GET_INFO_MEMBER(jackal_state::get_bg_tile_info)
+{
+ int const attr = m_videoram[0][tile_index];
+ int const code = m_videoram[0][0x400 + tile_index] + ((attr & 0xc0) << 2) + ((attr & 0x30) << 6);
+ int const color = 0; //attr & 0x0f;
+ int const flags = ((attr & 0x10) ? TILE_FLIPX : 0) | ((attr & 0x20) ? TILE_FLIPY : 0);
+
+ tileinfo.set(0, code, color, flags);
+}
+
+void jackal_state::video_start()
+{
+ m_bg_tilemap = &machine().tilemap().create(*m_gfxdecode, tilemap_get_info_delegate(*this, FUNC(jackal_state::get_bg_tile_info)), TILEMAP_SCAN_ROWS, 8, 8, 32, 32);
+
+ m_spritebank->configure_entry(0, m_spriteram[0]);
+ m_spritebank->configure_entry(1, m_spriteram[1]);
+
+ m_scrollbank->configure_entry(0, m_scrollram[0]);
+ m_scrollbank->configure_entry(1, m_scrollram[1]);
+}
+
+void jackal_state::draw_background(screen_device &screen, bitmap_ind16 &bitmap, const rectangle &cliprect)
+{
+ m_bg_tilemap->set_scroll_rows(1);
+ m_bg_tilemap->set_scroll_cols(1);
+
+ m_bg_tilemap->set_scrolly(0, m_videoctrl[0]);
+ m_bg_tilemap->set_scrollx(0, m_videoctrl[1]);
+
+ if (m_videoctrl[2] & 0x02)
+ {
+ if (m_videoctrl[2] & 0x08)
+ {
+ m_bg_tilemap->set_scroll_rows(32);
+
+ for (int i = 0; i < 32; i++)
+ m_bg_tilemap->set_scrollx(i, m_scrollram[0][i]);
+ }
+
+ if (m_videoctrl[2] & 0x04)
+ {
+ m_bg_tilemap->set_scroll_cols(32);
+
+ for (int i = 0; i < 32; i++)
+ m_bg_tilemap->set_scrolly(i, m_scrollram[0][i]);
+ }
+ }
+
+ m_bg_tilemap->draw(screen, bitmap, cliprect, 0, 0);
+}
+
+#define DRAW_SPRITE(bank, code, sx, sy) m_gfxdecode->gfx(bank)->transpen(bitmap, cliprect, code, color, flipx, flipy, sx, sy, 0);
+
+void jackal_state::draw_sprites_region(bitmap_ind16 &bitmap, const rectangle &cliprect, const uint8_t *sram, int length, int bank)
+{
+ for (int offs = 0; offs < length; offs += 5)
+ {
+ int const sn1 = sram[offs];
+ int const sn2 = sram[offs + 1];
+ int sy = sram[offs + 2];
+ int sx = sram[offs + 3];
+ int const attr = sram[offs + 4];
+ int flipx = attr & 0x20;
+ int flipy = attr & 0x40;
+ int const color = ((sn2 & 0xf0) >> 4);
+
+ if (attr & 0x01)
+ sx = sx - 256;
+ if (sy > 0xf0)
+ sy = sy - 256;
+
+ if (flip_screen())
+ {
+ sx = 240 - sx;
+ sy = 240 - sy;
+ flipx = !flipx;
+ flipy = !flipy;
+ }
+
+ if (attr & 0xc) // half-size sprite
+ {
+ int const spritenum = sn1 * 4 + ((sn2 & (8 + 4)) >> 2) + ((sn2 & (2 + 1)) << 10);
+ int mod = -8;
+
+ if (flip_screen())
+ {
+ sx += 8;
+ sy -= 8;
+ mod = 8;
+ }
+
+ if ((attr & 0x0c) == 0x0c)
+ {
+ if (flip_screen()) sy += 16;
+ DRAW_SPRITE(bank + 1, spritenum, sx, sy)
+ }
+
+ if ((attr & 0x0c) == 0x08)
+ {
+ sy += 8;
+ DRAW_SPRITE(bank + 1, spritenum, sx, sy)
+ DRAW_SPRITE(bank + 1, spritenum - 2, sx, sy + mod)
+ }
+
+ if ((attr & 0x0c) == 0x04)
+ {
+ DRAW_SPRITE(bank + 1, spritenum, sx, sy)
+ DRAW_SPRITE(bank + 1, spritenum + 1, sx + mod, sy)
+ }
+ }
+ else
+ {
+ int const spritenum = sn1 + ((sn2 & 0x03) << 8);
+
+ if (attr & 0x10)
+ {
+ if (flip_screen())
+ {
+ sx -= 16;
+ sy -= 16;
+ }
+
+ DRAW_SPRITE(bank, spritenum, flipx ? sx + 16 : sx, flipy ? sy + 16 : sy)
+ DRAW_SPRITE(bank, spritenum + 1, flipx ? sx : sx + 16, flipy ? sy + 16 : sy)
+ DRAW_SPRITE(bank, spritenum + 2, flipx ? sx + 16 : sx, flipy ? sy : sy + 16)
+ DRAW_SPRITE(bank, spritenum + 3, flipx ? sx : sx + 16, flipy ? sy : sy + 16)
+ }
+ else
+ {
+ DRAW_SPRITE(bank, spritenum, sx, sy)
+ }
+ }
+ }
+}
+
+void jackal_state::draw_sprites(bitmap_ind16 &bitmap, const rectangle &cliprect)
+{
+ draw_sprites_region(bitmap, cliprect, &m_spriteram[1][BIT(m_videoctrl[0x03], 3) * 0x800], 0x0f5, 3);
+ draw_sprites_region(bitmap, cliprect, &m_spriteram[0][BIT(m_videoctrl[0x03], 3) * 0x800], 0x500, 1);
+}
+
+uint32_t jackal_state::screen_update(screen_device &screen, bitmap_ind16 &bitmap, const rectangle &cliprect)
+{
+ draw_background(screen, bitmap, cliprect);
+ draw_sprites(bitmap, cliprect);
+ return 0;
+}
+
+
+/*************************************
+ *
+ * Memory handlers
+ *
+ *************************************/
+
+uint8_t jackal_state::rotary_r(offs_t offset)
+{
+ return (1 << m_dials[offset].read_safe(0x00)) ^ 0xff;
+}
+
+void jackal_state::flipscreen_w(uint8_t data)
+{
+ m_irq_enable = BIT(data, 1);
+ flip_screen_set(BIT(data, 3));
+}
+
+void jackal_state::rambank_w(uint8_t data)
+{
+ if (data & 0x04)
+ LOGRAMBANK("rambank_w %02x", data);
+
+ // all revisions flips the coin counter bit between 1 -> 0 five times, causing the bookkeeping to report 5 coins inserted.
+ // most likely solution in HW is a f/f that disables coin counters when any of the other bits are enabled.
+ if ((data & 0xfc) == 0)
+ {
+ machine().bookkeeping().coin_counter_w(0, data & 0x01);
+ machine().bookkeeping().coin_counter_w(1, data & 0x02);
+ }
+
+ m_spritebank->set_entry(BIT(data, 3));
+ m_scrollbank->set_entry(BIT(data, 4));
+ m_videoview.select(BIT(data, 4));
+ m_mainbank->set_entry(BIT(data, 5));
+}
+
+template <uint8_t Which>
+void jackal_state::voram_w(offs_t offset, uint8_t data)
+{
+ if ((offset & 0xf800) == 0)
+ m_bg_tilemap->mark_tile_dirty(offset & 0x3ff);
+
+ m_videoram[Which][offset] = data;
+}
+
+
+/*************************************
+ *
+ * Address maps
+ *
+ *************************************/
+
+void jackal_state::main_map(address_map &map)
+{
+ map(0x0000, 0x0003).ram().share(m_videoctrl); // scroll + other things
+ map(0x0004, 0x0004).w(FUNC(jackal_state::flipscreen_w));
+ map(0x0010, 0x0010).portr("DSW1");
+ map(0x0011, 0x0011).portr("IN1");
+ map(0x0012, 0x0012).portr("IN2");
+ map(0x0013, 0x0013).portr("IN0");
+ map(0x0014, 0x0015).r(FUNC(jackal_state::rotary_r));
+ map(0x0018, 0x0018).portr("DSW2");
+ map(0x0019, 0x0019).w("watchdog", FUNC(watchdog_timer_device::reset_w));
+ map(0x001c, 0x001c).w(FUNC(jackal_state::rambank_w));
+ map(0x0020, 0x005f).bankrw(m_scrollbank); // MAIN Z RAM,SUB Z RAM
+ map(0x0060, 0x1fff).ram().share("mainsub"); // M COMMON RAM,S COMMON RAM
+ map(0x2000, 0x2fff).view(m_videoview);
+ m_videoview[0](0x2000, 0x2fff).ram().share(m_videoram[0]).w(FUNC(jackal_state::voram_w<0>)); // MAIN V O RAM,SUB V O RAM
+ m_videoview[1](0x2000, 0x2fff).ram().share(m_videoram[1]).w(FUNC(jackal_state::voram_w<1>)); // MAIN V O RAM,SUB V O RAM
+ map(0x3000, 0x3fff).bankrw(m_spritebank); // MAIN V O RAM,SUB V O RAM
+ map(0x4000, 0xbfff).bankr(m_mainbank);
+ map(0xc000, 0xffff).rom().region("maincpu", 0);
+}
+
+void jackal_state::slave_map(address_map &map)
+{
+ map(0x2000, 0x2001).rw("ymsnd", FUNC(ym2151_device::read), FUNC(ym2151_device::write));
+ map(0x4000, 0x43ff).ram().w(m_palette, FUNC(palette_device::write_indirect)).share("palette"); // self test only checks 0x4000-0x423f, 007327 should actually go up to 4fff
+ map(0x6000, 0x605f).ram(); // SOUND RAM (Self test check 0x6000-605f, 0x7c00-0x7fff)
+ map(0x6060, 0x7fff).ram().share("mainsub");
+ map(0x8000, 0xffff).rom().region("slave", 0);
+}
+
+/*************************************
+ *
+ * Input ports
+ *
+ *************************************/
+
+static INPUT_PORTS_START( jackal )
+ PORT_START("DSW1")
+ KONAMI_COINAGE_LOC(DEF_STR( Free_Play ), "No Coin B", SW1)
+ // "No Coin B" = coins produce sound, but no effect on coin counter
+
+ PORT_START("DSW2")
+ PORT_DIPNAME( 0x03, 0x02, DEF_STR( Lives ) ) PORT_DIPLOCATION( "SW2:1,2" )
+ PORT_DIPSETTING( 0x03, "2" )
+ PORT_DIPSETTING( 0x02, "3" )
+ PORT_DIPSETTING( 0x01, "4" )
+ PORT_DIPSETTING( 0x00, "7" )
+ PORT_DIPNAME( 0x04, 0x04, DEF_STR( Unused ) ) PORT_DIPLOCATION( "SW2:3" )
+ PORT_DIPSETTING( 0x04, DEF_STR( Off ) )
+ PORT_DIPSETTING( 0x00, DEF_STR( On ) )
+ PORT_DIPNAME( 0x18, 0x18, DEF_STR( Bonus_Life ) ) PORT_DIPLOCATION( "SW2:4,5" )
+ PORT_DIPSETTING( 0x18, "30K 150K" )
+ PORT_DIPSETTING( 0x10, "50K 200K" )
+ PORT_DIPSETTING( 0x08, "30K" )
+ PORT_DIPSETTING( 0x00, "50K" )
+ PORT_DIPNAME( 0x60, 0x40, DEF_STR( Difficulty ) ) PORT_DIPLOCATION( "SW2:6,7" )
+ PORT_DIPSETTING( 0x60, DEF_STR( Easy ) )
+ PORT_DIPSETTING( 0x40, DEF_STR( Normal ) )
+ PORT_DIPSETTING( 0x20, DEF_STR( Difficult ) )
+ PORT_DIPSETTING( 0x00, DEF_STR( Very_Difficult ) )
+ PORT_DIPNAME( 0x80, 0x00, DEF_STR( Demo_Sounds ) ) PORT_DIPLOCATION( "SW2:8" )
+ PORT_DIPSETTING( 0x80, DEF_STR( Off ) )
+ PORT_DIPSETTING( 0x00, DEF_STR( On ) )
+
+ PORT_START("IN0")
+ KONAMI8_SYSTEM_10
+ PORT_DIPNAME( 0x20, 0x20, DEF_STR( Flip_Screen ) ) PORT_DIPLOCATION( "SW3:1" )
+ PORT_DIPSETTING( 0x20, DEF_STR( Off ) )
+ PORT_DIPSETTING( 0x00, DEF_STR( On ) )
+ PORT_DIPNAME( 0x40, 0x00, "Sound Adjustment" ) PORT_DIPLOCATION( "SW3:2" )
+ PORT_DIPSETTING( 0x00, DEF_STR( Upright ) )
+ PORT_DIPSETTING( 0x40, DEF_STR( Cocktail ) )
+ PORT_DIPNAME( 0x80, 0x00, "Sound Mode" ) PORT_DIPLOCATION( "SW3:3" )
+ PORT_DIPSETTING( 0x80, DEF_STR( Mono ) )
+ PORT_DIPSETTING( 0x00, DEF_STR( Stereo ) )
+
+ PORT_START("IN1")
+ KONAMI8_B12(1)
+ PORT_DIPNAME( 0x80, 0x80, DEF_STR( Unused ) ) PORT_DIPLOCATION( "SW3:4" )
+ PORT_DIPSETTING( 0x80, DEF_STR( Off ) )
+ PORT_DIPSETTING( 0x00, DEF_STR( On ) )
+
+ PORT_START("IN2")
+ KONAMI8_B12_UNK(2)
+INPUT_PORTS_END
+
+static INPUT_PORTS_START( jackalr )
+ PORT_INCLUDE(jackal)
+
+ PORT_MODIFY("IN0")
+ PORT_BIT( 0xc0, IP_ACTIVE_LOW, IPT_UNUSED )
+
+ PORT_START("DIAL0") // player 1 8-way rotary control - converted in rotary_r()
+ PORT_BIT( 0xff, 0x00, IPT_POSITIONAL ) PORT_POSITIONS(8) PORT_WRAPS PORT_SENSITIVITY(15) PORT_KEYDELTA(1) PORT_CODE_DEC(KEYCODE_Z) PORT_CODE_INC(KEYCODE_X) PORT_FULL_TURN_COUNT(8)
+
+ PORT_START("DIAL1") // player 2 8-way rotary control - converted in rotary_r()
+ PORT_BIT( 0xff, 0x00, IPT_POSITIONAL ) PORT_POSITIONS(8) PORT_WRAPS PORT_SENSITIVITY(15) PORT_KEYDELTA(1) PORT_CODE_DEC(KEYCODE_N) PORT_CODE_INC(KEYCODE_M) PORT_PLAYER(2) PORT_FULL_TURN_COUNT(8)
+INPUT_PORTS_END
+
+
+/*************************************
+ *
+ * Graphics definitions
+ *
+ *************************************/
+
+static const gfx_layout charlayout =
+{
+ 8, 8,
+ RGN_FRAC(1,4),
+ 8, // 8 bits per pixel (!)
+ { 0, 1, 2, 3, RGN_FRAC(1,2)+0, RGN_FRAC(1,2)+1, RGN_FRAC(1,2)+2, RGN_FRAC(1,2)+3 },
+ { 0*4, 1*4, 2*4, 3*4, 4*4, 5*4, 6*4, 7*4 },
+ { 0*32, 1*32, 2*32, 3*32, 4*32, 5*32, 6*32, 7*32 },
+ 32*8
+};
+
+static const gfx_layout spritelayout =
+{
+ 16, 16,
+ RGN_FRAC(1,4),
+ 4,
+ { 0, 1, 2, 3 },
+ { 0*4, 1*4, 2*4, 3*4, 4*4, 5*4, 6*4, 7*4,
+ 32*8+0*4, 32*8+1*4, 32*8+2*4, 32*8+3*4, 32*8+4*4, 32*8+5*4, 32*8+6*4, 32*8+7*4 },
+ { 0*32, 1*32, 2*32, 3*32, 4*32, 5*32, 6*32, 7*32,
+ 16*32, 17*32, 18*32, 19*32, 20*32, 21*32, 22*32, 23*32 },
+ 32*32
+};
+
+static const gfx_layout spritelayout8 =
+{
+ 8, 8,
+ RGN_FRAC(1,4),
+ 4,
+ { 0, 1, 2, 3 },
+ { 0*4, 1*4, 2*4, 3*4, 4*4, 5*4, 6*4, 7*4 },
+ { 0*32, 1*32, 2*32, 3*32, 4*32, 5*32, 6*32, 7*32 },
+ 32*8
+};
+
+static GFXDECODE_START( gfx_jackal )
+ GFXDECODE_ENTRY( "gfx", 0x00000, charlayout, 0, 1 ) // colors 256-511 without lookup
+ GFXDECODE_ENTRY( "gfx", 0x20000, spritelayout, 0x100, 16 ) // colors 0- 15 with lookup
+ GFXDECODE_ENTRY( "gfx", 0x20000, spritelayout8, 0x100, 16 ) // to handle 8x8 sprites
+ GFXDECODE_ENTRY( "gfx", 0x60000, spritelayout, 0x200, 16 ) // colors 16- 31 with lookup
+ GFXDECODE_ENTRY( "gfx", 0x60000, spritelayout8, 0x200, 16 ) // to handle 8x8 sprites
+GFXDECODE_END
+
+/*************************************
+ *
+ * Interrupt generator
+ *
+ *************************************/
+
+void jackal_state::vblank_irq(int state)
+{
+ if (state && m_irq_enable)
+ {
+ m_maincpu->set_input_line(0, HOLD_LINE);
+ m_slavecpu->pulse_input_line(INPUT_LINE_NMI, attotime::zero);
+ }
+}
+
+
+/*************************************
+ *
+ * Machine driver
+ *
+ *************************************/
+
+void jackal_state::machine_start()
+{
+ m_mainbank->configure_entries(0, 2, memregion("maincpu")->base() + 0x4000, 0x8000);
+ m_mainbank->set_entry(0);
+
+ save_item(NAME(m_irq_enable));
+}
+
+void jackal_state::machine_reset()
+{
+ m_irq_enable = 0;
+}
+
+void jackal_state::jackal(machine_config &config)
+{
+ // basic machine hardware
+ MC6809E(config, m_maincpu, 18.432_MHz_XTAL / 12); // verified on PCB
+ m_maincpu->set_addrmap(AS_PROGRAM, &jackal_state::main_map);
+
+ MC6809E(config, m_slavecpu, 18.432_MHz_XTAL / 12); // verified on PCB
+ m_slavecpu->set_addrmap(AS_PROGRAM, &jackal_state::slave_map);
+
+ config.set_maximum_quantum(attotime::from_hz(6000));
+
+ WATCHDOG_TIMER(config, "watchdog");
+
+ // 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(32*8, 32*8);
+ screen.set_visarea(1*8, 31*8-1, 2*8, 30*8-1);
+ screen.set_screen_update(FUNC(jackal_state::screen_update));
+ screen.set_palette(m_palette);
+ screen.screen_vblank().set(FUNC(jackal_state::vblank_irq));
+
+ GFXDECODE(config, m_gfxdecode, m_palette, gfx_jackal);
+ PALETTE(config, m_palette, FUNC(jackal_state::palette));
+ m_palette->set_format(palette_device::xBGR_555, 0x300, 0x200);
+ m_palette->set_endianness(ENDIANNESS_LITTLE);
+
+ // sound hardware
+ SPEAKER(config, "speaker", 2).front();
+
+ YM2151(config, "ymsnd", 3.579545_MHz_XTAL).add_route(0, "speaker", 0.50, 0).add_route(1, "speaker", 0.50, 1); // verified on PCB
+}
+
+/*************************************
+ *
+ * ROM definition(s)
+ *
+ *************************************/
+
+ROM_START( jackal ) // 8-Way Joystick: You can only shoot in one direction regardless of travel - up the screen
+ ROM_REGION( 0x14000, "maincpu", 0 ) // Banked 64k for 1st CPU
+ ROM_LOAD( "631_v03.16d", 0x00000, 0x04000, CRC(3e0dfb83) SHA1(5ba7073751eee33180e51143b348256597909516) )
+ ROM_LOAD( "631_v02.15d", 0x04000, 0x10000, CRC(0b7e0584) SHA1(e4019463345a4c020d5a004c9a400aca4bdae07b) )
+
+ ROM_REGION( 0x8000, "slave", 0 ) // 64k for 2nd cpu (Graphics & Sound)
+ ROM_LOAD( "631_t01.11d", 0x0000, 0x8000, CRC(b189af6a) SHA1(f7df996c394fdd6f2ce128a8df38d7838f7ec6d6) )
+
+ ROM_REGION( 0x80000, "gfx", 0 )
+ ROM_LOAD16_BYTE( "631t04.7h", 0x00000, 0x20000, CRC(457f42f0) SHA1(08413a13d128875dddcf4f6ad302363096bf1d41) ) // Silkscreened MASK1M
+ ROM_LOAD16_BYTE( "631t05.8h", 0x00001, 0x20000, CRC(732b3fc1) SHA1(7e89650b9e5e2b7ae82f8c55ac9995740f6fdfe1) ) // Silkscreened MASK1M
+ ROM_LOAD16_BYTE( "631t06.12h", 0x40000, 0x20000, CRC(2d10e56e) SHA1(447b464ea725fb9ef87da067a41bcf463b427cce) ) // Silkscreened MASK1M
+ ROM_LOAD16_BYTE( "631t07.13h", 0x40001, 0x20000, CRC(4961c397) SHA1(b430df58fc3bb722d6fb23bed7d04afdb7e5d9c1) ) // Silkscreened MASK1M
+
+ ROM_REGION( 0x0200, "proms", 0 ) // color lookup tables
+ ROM_LOAD( "631r08.9h", 0x0000, 0x0100, CRC(7553a172) SHA1(eadf1b4157f62c3af4602da764268df954aa0018) ) // MMI 63S141AN or compatible (silkscreened 6301)
+ ROM_LOAD( "631r09.14h", 0x0100, 0x0100, CRC(a74dd86c) SHA1(571f606f8fc0fd3d98d26761de79ccb4cc9ab044) ) // MMI 63S141AN or compatible (silkscreened 6301)
+ROM_END
+
+ROM_START( jackalr ) // Rotary Joystick: Shot direction is controlled via the rotary function of the joystick
+ ROM_REGION( 0x14000, "maincpu", 0 ) // Banked 64k for 1st CPU
+ ROM_LOAD( "631_q03.16d", 0x00000, 0x04000, CRC(b9d34836) SHA1(af23a0c844fb9e60a757511ca898d73eef4c2e51) )
+ ROM_LOAD( "631_q02.15d", 0x04000, 0x10000, CRC(ed2a7d66) SHA1(3d9b31fa8b31e509880d617feb0dd4bd9790d2d5) )
+
+ ROM_REGION( 0x8000, "slave", 0 ) // 64k for 2nd cpu (Graphics & Sound)
+ ROM_LOAD( "631_q01.11d", 0x0000, 0x8000, CRC(54aa2d29) SHA1(ebc6b3a5db5120cc33d62e3213d0e881f658282d) )
+
+ ROM_REGION( 0x80000, "gfx", 0 ) // Paired ROMs are on tiny riser boards instead of larger single MASK1M type ROMs per socket
+ ROM_LOAD16_BYTE( "631_q05.7h", 0x00000, 0x10000, CRC(bcf5d0a8) SHA1(c406d6b3eaf251d9505b809b9ef927ecd6d672c0) ) // ROM located over socket on riser for 7H socket == 631t04 1/2
+ ROM_LOAD16_BYTE( "631_q06.8h", 0x00001, 0x10000, CRC(4cb5df22) SHA1(f4f6346459f4ddf6ddb34d143d77836d10710769) ) // ROM located over socket on riser for 8H socket == 631t05 1/2
+ ROM_LOAD16_BYTE( "631_q04.7h", 0x20000, 0x10000, CRC(e1e9aa42) SHA1(5b12537b7263663ee7ab52f98328f2334066216e) ) // ROM located left edge of riser for 7H socket == 631t04 2/2
+ ROM_LOAD16_BYTE( "631_q07.8h", 0x20001, 0x10000, CRC(cc68c5b8) SHA1(2fa475bd261532ded42240db14dcda4359bb94a3) ) // ROM located right edge of riser for 8H socket == 631t05 2/2
+ ROM_LOAD16_BYTE( "631_q09.12h", 0x40000, 0x10000, CRC(55ea6852) SHA1(2027ff887ecc6b7a96f24b14bd6ac89197fd963f) ) // ROM located over socket on riser for 12H socket == 631t06 1/2
+ ROM_LOAD16_BYTE( "631_q10.13h", 0x40001, 0x10000, CRC(fe93e217) SHA1(7b43ec09dd819fe9a9bdaffed0211e0359d17980) ) // ROM located over socket on riser for 13H socket == 631t07 1/2
+ ROM_LOAD16_BYTE( "631_q08.12h", 0x60000, 0x10000, CRC(d2492b8b) SHA1(a2563d73f7e03b144367354a5c207303fd91f670) ) // ROM located left edge of riser for 12H socket == 621t06 2/2
+ ROM_LOAD16_BYTE( "631_q11.13h", 0x60001, 0x10000, CRC(563ae24c) SHA1(224435bcbc543fe735521ec5a5a8bbd124d0a88a) ) // ROM located right edge of riser for 13H socket == 631t07 2/2
+
+ ROM_REGION( 0x0200, "proms", 0 ) // color lookup tables
+ ROM_LOAD( "631r08.9h", 0x0000, 0x0100, CRC(7553a172) SHA1(eadf1b4157f62c3af4602da764268df954aa0018) ) // MMI 63S141AN or compatible (silkscreened 6301)
+ ROM_LOAD( "631r09.14h", 0x0100, 0x0100, CRC(a74dd86c) SHA1(571f606f8fc0fd3d98d26761de79ccb4cc9ab044) ) // MMI 63S141AN or compatible (silkscreened 6301)
+ROM_END
+
+ROM_START( topgunr ) // 8-Way Joystick: You can only shoot in one direction regardless of travel - up the screen
+ ROM_REGION( 0x14000, "maincpu", 0 ) // Banked 64k for 1st CPU
+ ROM_LOAD( "631_u03.16d", 0x00000, 0x04000, CRC(c086844e) SHA1(4d6f27ac3aabb4b2d673aa619e407e417ad89337) )
+ ROM_LOAD( "631_u02.15d", 0x04000, 0x10000, CRC(f7e28426) SHA1(db2d5f252a574b8aa4d8406a8e93b423fd2a7fef) )
+
+ ROM_REGION( 0x8000, "slave", 0 ) // 64k for 2nd cpu (Graphics & Sound)
+ ROM_LOAD( "631_t01.11d", 0x0000, 0x8000, CRC(b189af6a) SHA1(f7df996c394fdd6f2ce128a8df38d7838f7ec6d6) )
+
+ ROM_REGION( 0x80000, "gfx", 0 )
+ ROM_LOAD16_BYTE( "631u04.7h", 0x00000, 0x20000, CRC(50122a12) SHA1(c9e0132a3a40d9d28685c867c70231947d8a9cb7) ) // Silkscreened MASK1M
+ ROM_LOAD16_BYTE( "631u05.8h", 0x00001, 0x20000, CRC(6943b1a4) SHA1(40de2b434600ea4c8fb42e6b21be2c3705a55d67) ) // Silkscreened MASK1M
+ ROM_LOAD16_BYTE( "631u06.12h", 0x40000, 0x20000, CRC(37dbbdb0) SHA1(f94db780d69e7dd40231a75629af79469d957378) ) // Silkscreened MASK1M
+ ROM_LOAD16_BYTE( "631u07.13h", 0x40001, 0x20000, CRC(22effcc8) SHA1(4d174b0ce64def32050f87343c4b1424e0fef6f7) ) // Silkscreened MASK1M
+
+ ROM_REGION( 0x0200, "proms", 0 ) // color lookup tables
+ ROM_LOAD( "631r08.9h", 0x0000, 0x0100, CRC(7553a172) SHA1(eadf1b4157f62c3af4602da764268df954aa0018) ) // MMI 63S141AN or compatible (silkscreened 6301)
+ ROM_LOAD( "631r09.14h", 0x0100, 0x0100, CRC(a74dd86c) SHA1(571f606f8fc0fd3d98d26761de79ccb4cc9ab044) ) // MMI 63S141AN or compatible (silkscreened 6301)
+ROM_END
+
+ROM_START( jackalj ) // 8-Way Joystick: You can only shoot in the direction you're traveling
+ ROM_REGION( 0x14000, "maincpu", 0 ) // Banked 64k for 1st CPU
+ ROM_LOAD( "631_t03.16d", 0x00000, 0x04000, CRC(fd5f9624) SHA1(2520c1ff54410ef498ecbf52877f011900baed4c) )
+ ROM_LOAD( "631_t02.15d", 0x04000, 0x10000, CRC(14db6b1a) SHA1(b469ea50aa94a2bda3bd0442300aa1272e5f30c4) )
+
+ ROM_REGION( 0x8000, "slave", 0 ) // 64k for 2nd cpu (Graphics & Sound)
+ ROM_LOAD( "631_t01.11d", 0x0000, 0x8000, CRC(b189af6a) SHA1(f7df996c394fdd6f2ce128a8df38d7838f7ec6d6) )
+
+ ROM_REGION( 0x80000, "gfx", 0 )
+ ROM_LOAD16_BYTE( "631t04.7h", 0x00000, 0x20000, CRC(457f42f0) SHA1(08413a13d128875dddcf4f6ad302363096bf1d41) ) // Silkscreened MASK1M
+ ROM_LOAD16_BYTE( "631t05.8h", 0x00001, 0x20000, CRC(732b3fc1) SHA1(7e89650b9e5e2b7ae82f8c55ac9995740f6fdfe1) ) // Silkscreened MASK1M
+ ROM_LOAD16_BYTE( "631t06.12h", 0x40000, 0x20000, CRC(2d10e56e) SHA1(447b464ea725fb9ef87da067a41bcf463b427cce) ) // Silkscreened MASK1M
+ ROM_LOAD16_BYTE( "631t07.13h", 0x40001, 0x20000, CRC(4961c397) SHA1(b430df58fc3bb722d6fb23bed7d04afdb7e5d9c1) ) // Silkscreened MASK1M
+
+ ROM_REGION( 0x0200, "proms", 0 ) // color lookup tables
+ ROM_LOAD( "631r08.9h", 0x0000, 0x0100, CRC(7553a172) SHA1(eadf1b4157f62c3af4602da764268df954aa0018) ) // MMI 63S141AN or compatible (silkscreened 6301)
+ ROM_LOAD( "631r09.14h", 0x0100, 0x0100, CRC(a74dd86c) SHA1(571f606f8fc0fd3d98d26761de79ccb4cc9ab044) ) // MMI 63S141AN or compatible (silkscreened 6301)
+ROM_END
+
+ROM_START( jackalbl ) // This is based on jackalr. Was dumped from 2 different PCBs.
+ ROM_REGION( 0x14000, "maincpu", 0 ) // Banked 64k for 1st CPU
+ ROM_LOAD( "epr-a-2.bin", 0x00000, 0x04000, CRC(ae2a290a) SHA1(e9bee75a02aef5cf330dccb9e7a45b0171a8c1d7) ) // also found labeled "2.20"
+ ROM_LOAD( "epr-a-3.bin", 0x04000, 0x08000, CRC(5fffee27) SHA1(224d5fd26dd1e0f15a3c99fd2fffbb76f641416e) ) // also found labeled "3.17"
+ ROM_LOAD( "epr-a-4.bin", 0x0c000, 0x08000, CRC(976c8431) SHA1(c199f57c25380d741aec85b0e0bfb6acf383e6a6) ) // also found labeled "4.18"
+
+ ROM_REGION( 0x8000, "slave", 0 ) // 64k for 2nd cpu (Graphics & Sound)
+ ROM_LOAD( "epr-a-1.bin", 0x0000, 0x8000, CRC(54aa2d29) SHA1(ebc6b3a5db5120cc33d62e3213d0e881f658282d) ) // also found labeled "1.19"
+
+ ROM_REGION( 0x80000, "gfx", 0 ) // same data, different layout
+ ROM_LOAD16_WORD_SWAP( "epr-a-17.bin", 0x00000, 0x08000, CRC(a96720b6) SHA1(d3c2a1848fa9d9d1232e58e412bdd69032fe2c83) ) // also found labeled "17.5"
+ ROM_LOAD16_WORD_SWAP( "epr-a-18.bin", 0x08000, 0x08000, CRC(932d0ecb) SHA1(20bf789f45c5b3ba90012e1a945523236578a014) ) // also found labeled "18.6"
+ ROM_LOAD16_WORD_SWAP( "epr-a-19.bin", 0x10000, 0x08000, CRC(1e3412e7) SHA1(dc0be23d6c89b7b131c3bd5cd117123e5f9d971c) ) // also found labeled "19.7"
+ ROM_LOAD16_WORD_SWAP( "epr-a-20.bin", 0x18000, 0x08000, CRC(4b0d15be) SHA1(657c861357b5881e4ff356b1f27345b11e6c0696) ) // also found labeled "20.8"
+ ROM_LOAD16_WORD_SWAP( "epr-a-6.bin", 0x20000, 0x08000, CRC(ec7141ad) SHA1(eb631ca58364827659fba1cb3dca326c2e5bf5b7) ) // also found labeled "6.9"
+ ROM_LOAD16_WORD_SWAP( "epr-a-5.bin", 0x28000, 0x08000, CRC(c6375c74) SHA1(55090485307c6581556632fadbf704431734b145) ) // also found labeled "5.10"
+ ROM_LOAD16_WORD_SWAP( "epr-a-7.bin", 0x30000, 0x08000, CRC(03e1de04) SHA1(c5f17633f4d5907310effb490488053861a55f6c) ) // also found labeled "7.11"
+ ROM_LOAD16_WORD_SWAP( "epr-a-8.bin", 0x38000, 0x08000, CRC(f946ada7) SHA1(fd9a0786436cbdb4c844f71342232e4e6645d98f) ) // also found labeled "8.12"
+ ROM_LOAD16_WORD_SWAP( "epr-a-13.bin", 0x40000, 0x08000, CRC(7c29c59e) SHA1(c2764f99ab4b39e7c0e43f58f69d6c353d0357aa) ) // also found labeled "13.1"
+ ROM_LOAD16_WORD_SWAP( "epr-a-14.bin", 0x48000, 0x08000, CRC(f2bbff39) SHA1(f39dfdb3301f9b01d58071ffee41c467757d99d9) ) // also found labeled "14.2"
+ ROM_LOAD16_WORD_SWAP( "epr-a-15.bin", 0x50000, 0x08000, CRC(594dbaaf) SHA1(e3f05acbdba8e8644dbabb065832476c1cb20569) ) // also found labeled "15.3"
+ ROM_LOAD16_WORD_SWAP( "epr-a-16.bin", 0x58000, 0x08000, CRC(069bf945) SHA1(93ecc7dd779d16d825680bbc4986a312758db52f) ) // also found labeled "16.4"
+ ROM_LOAD16_WORD_SWAP( "epr-a-9.bin", 0x60000, 0x08000, CRC(c00cef79) SHA1(94af2f4a67d1425fbb64b58ed7e618c8b38df203) ) // also found labeled "9.13"
+ ROM_LOAD16_WORD_SWAP( "epr-a-10.bin", 0x68000, 0x08000, CRC(0aed6cd7) SHA1(88f81be5d8b2679349bf5cf2d4e02aff25c5118b) ) // also found labeled "10.14"
+ ROM_LOAD16_WORD_SWAP( "epr-a-11.bin", 0x70000, 0x08000, CRC(a48e9f60) SHA1(6d5af16c16b40fb092fdba6dce852b94ac4767f4) ) // also found labeled "11.15"
+ ROM_LOAD16_WORD_SWAP( "epr-a-12.bin", 0x78000, 0x08000, CRC(79b7c71c) SHA1(8510226114ab9098ec48e02840465fc8b69b5262) ) // also found labeled "12.16"
+
+ ROM_REGION( 0x0200, "proms", 0 ) // color lookup tables
+ ROM_LOAD( "n82s129n.prom2", 0x0000, 0x0100, CRC(7553a172) SHA1(eadf1b4157f62c3af4602da764268df954aa0018) )
+ ROM_LOAD( "n82s129n.prom1", 0x0100, 0x0100, CRC(a74dd86c) SHA1(571f606f8fc0fd3d98d26761de79ccb4cc9ab044) )
+
+ ROM_REGION( 0x1000, "pals", 0 ) // currently not used by the emulation
+ ROM_LOAD( "pal16r6cn.pal1", 0x0000, 0x0104, CRC(9bba948f) SHA1(5f42568489f16f8b3719eb2ec178e7c61d7ce25f) )
+ ROM_LOAD( "ampal16l8pc.pal2", 0x0200, 0x0104, CRC(17c9de2f) SHA1(2db42618f9ca1174bdcdbf92ea91ebc1a79bc6d2) )
+ ROM_LOAD( "ampal16r4pc.pal3", 0x0400, 0x0104, CRC(e54cd288) SHA1(5b8ae5a2a4a9ec3fab603b063fd18c96dd1fd0cf) )
+ ROM_LOAD( "pal16r8acn.pal4", 0x0600, 0x0104, CRC(5cc45e00) SHA1(cbd871addbac6310c8593fe8e8d5a962c2b45b2c) )
+ ROM_LOAD( "pal20l8a-2cns.pal5", 0x0800, 0x0144, NO_DUMP ) // read protected
+ ROM_LOAD( "pal20l8acns.pal6", 0x0a00, 0x0144, NO_DUMP ) // read protected
+ ROM_LOAD( "pal16l8pc.pal7", 0x0c00, 0x0104, CRC(e8cdc259) SHA1(6917ef8f4f09aa099a48b8ae2d10bcd10961fb43) )
+ ROM_LOAD( "d5c121.ep1200", 0x0e00, 0x0200, NO_DUMP ) // not dumped yet
+ROM_END
+
+ROM_START( topgunbl ) // Rotary Joystick: Shot direction is controlled via the Rotary function of the joystick
+ ROM_REGION( 0x14000, "maincpu", 0 ) // Banked 64k for 1st CPU
+ ROM_LOAD( "t-2.c6", 0x00000, 0x04000, CRC(d53172e5) SHA1(44b7f180c17f9a121a2f06f2d3471920a8989e21) )
+ ROM_LOAD( "t-3.c5", 0x04000, 0x08000, CRC(7826ad38) SHA1(875e87867924905b9b83bc203eb7ffe81cf72233) )
+ ROM_LOAD( "t-4.c4", 0x0c000, 0x08000, CRC(976c8431) SHA1(c199f57c25380d741aec85b0e0bfb6acf383e6a6) ) // == 2nd half of 631_q02.15d
+
+ ROM_REGION( 0x8000, "slave", 0 ) // 64k for 2nd cpu (Graphics & Sound)
+ ROM_LOAD( "t-1.c14", 0x0000, 0x8000, CRC(54aa2d29) SHA1(ebc6b3a5db5120cc33d62e3213d0e881f658282d) ) // == 631_q01.11d
+
+ ROM_REGION( 0x80000, "gfx", 0 ) // same data, different layout
+ ROM_LOAD16_WORD_SWAP( "t-17.n12", 0x00000, 0x08000, CRC(e8875110) SHA1(73f4c47ab039dce8c285bf222253084c860c95bf) )
+ ROM_LOAD16_WORD_SWAP( "t-18.n13", 0x08000, 0x08000, CRC(cf14471d) SHA1(896aa8d7c93f837f6661d30bd0d6e19d16669107) )
+ ROM_LOAD16_WORD_SWAP( "t-19.n14", 0x10000, 0x08000, CRC(46ee5dd2) SHA1(1a910984a197af341f13b4683babee857aafb245) )
+ ROM_LOAD16_WORD_SWAP( "t-20.n15", 0x18000, 0x08000, CRC(3f472344) SHA1(49b9da8741b8e474d25726a706cf3008096ab2dc) )
+ ROM_LOAD16_WORD_SWAP( "t-6.n1", 0x20000, 0x08000, CRC(539cc48c) SHA1(476ff5fe239e5acb61ede4d745d327f6bc3709f3) )
+ ROM_LOAD16_WORD_SWAP( "t-5.m1", 0x28000, 0x08000, CRC(dbc26afe) SHA1(faab1feae91a9c22c008555955596c55d77b70c7) )
+ ROM_LOAD16_WORD_SWAP( "t-7.n2", 0x30000, 0x08000, CRC(0ecd31b1) SHA1(06d77159ed55c1e288f2a194cdb09d29542e06d6) )
+ ROM_LOAD16_WORD_SWAP( "t-8.n3", 0x38000, 0x08000, CRC(f946ada7) SHA1(fd9a0786436cbdb4c844f71342232e4e6645d98f) )
+ ROM_LOAD16_WORD_SWAP( "t-13.n8", 0x40000, 0x08000, CRC(5d669abb) SHA1(faba6d7b47caae2ecdf15fb3527824bdb22e3d6b) )
+ ROM_LOAD16_WORD_SWAP( "t-14.n9", 0x48000, 0x08000, CRC(f349369b) SHA1(f19238ef5feb1c89ef58c17a2506cc96ed8054e1) )
+ ROM_LOAD16_WORD_SWAP( "t-15.n10", 0x50000, 0x08000, CRC(7c5a91dd) SHA1(85a1d76efc385e8e971a65e225de7f5d100bfbc7) )
+ ROM_LOAD16_WORD_SWAP( "t-16.n11", 0x58000, 0x08000, CRC(5ec46d8e) SHA1(350e983b56a9f7d95e98429ee9a5fa6d3af36db4) )
+ ROM_LOAD16_WORD_SWAP( "t-9.n4", 0x60000, 0x08000, CRC(8269caca) SHA1(8b80b7bad966d5b61a5c22d2ced625b5645f2ce2) )
+ ROM_LOAD16_WORD_SWAP( "t-10.n5", 0x68000, 0x08000, CRC(25393e4f) SHA1(f6d7995b51d5bbbc3e325d6949dbc435446b5cf9) )
+ ROM_LOAD16_WORD_SWAP( "t-11.n6", 0x70000, 0x08000, CRC(7895c22d) SHA1(c81ae51116fb32ac99d37eb7c2000c990d089b8d) )
+ ROM_LOAD16_WORD_SWAP( "t-12.n7", 0x78000, 0x08000, CRC(15606dfc) SHA1(829492da49dbe70f81d15237803c5203aa011957) )
+
+ ROM_REGION( 0x0200, "proms", 0 ) // color lookup tables
+ ROM_LOAD( "631r08.bpr", 0x0000, 0x0100, CRC(7553a172) SHA1(eadf1b4157f62c3af4602da764268df954aa0018) )
+ ROM_LOAD( "631r09.bpr", 0x0100, 0x0100, CRC(a74dd86c) SHA1(571f606f8fc0fd3d98d26761de79ccb4cc9ab044) )
+ROM_END
+
+} // anonymous namespace
+
+
+/*************************************
+ *
+ * Game driver(s)
+ *
+ *************************************/
+
+GAME( 1986, jackal, 0, jackal, jackal, jackal_state, empty_init, ROT90, "Konami", "Jackal (World, 8-way Joystick)", MACHINE_SUPPORTS_SAVE )
+GAME( 1986, jackalr, jackal, jackal, jackalr, jackal_state, empty_init, ROT90, "Konami", "Jackal (World, Rotary Joystick)", MACHINE_SUPPORTS_SAVE )
+GAME( 1986, topgunr, jackal, jackal, jackal, jackal_state, empty_init, ROT90, "Konami", "Top Gunner (US, 8-way Joystick)", MACHINE_SUPPORTS_SAVE )
+GAME( 1986, jackalj, jackal, jackal, jackal, jackal_state, empty_init, ROT90, "Konami", "Tokushu Butai Jackal (Japan, 8-way Joystick)", MACHINE_SUPPORTS_SAVE )
+GAME( 1986, jackalbl, jackal, jackal, jackalr, jackal_state, empty_init, ROT90, "bootleg", "Jackal (bootleg, Rotary Joystick)", MACHINE_SUPPORTS_SAVE )
+GAME( 1986, topgunbl, jackal, jackal, jackalr, jackal_state, empty_init, ROT90, "bootleg", "Top Gunner (bootleg, Rotary Joystick)", MACHINE_SUPPORTS_SAVE )