mcr68: Move zwackery to its own driver.

It doesn't have much in common with the other games in the driver. Also
clean up the implementation, make spriteram 8-bit, add some hardware
info and add button descriptions.
This commit is contained in:
Dirk Best 2016-12-17 19:43:07 +01:00
parent 9759695f10
commit 3cb2a973fd
7 changed files with 625 additions and 587 deletions

View File

@ -2513,6 +2513,7 @@ files {
MAME_DIR .. "src/mame/includes/mcr68.h",
MAME_DIR .. "src/mame/machine/mcr68.cpp",
MAME_DIR .. "src/mame/video/mcr68.cpp",
MAME_DIR .. "src/mame/drivers/zwackery.cpp",
MAME_DIR .. "src/mame/drivers/midqslvr.cpp",
MAME_DIR .. "src/mame/drivers/midtunit.cpp",
MAME_DIR .. "src/mame/includes/midtunit.h",

View File

@ -7,7 +7,6 @@
driver by Bryan McPhail, Aaron Giles
Games supported:
* Zwackery (Chip Squeak Deluxe)
* Xenopohobe (Sounds Good)
* Spy Hunter II (Sounds Good/Turbo Chip Squeak)
* Blasted (Sounds Good)
@ -62,37 +61,6 @@
/*************************************
*
* Zwackery-specific handlers
*
*************************************/
READ8_MEMBER(mcr68_state::zwackery_port_2_r)
{
int result = ioport("IN2")->read();
int wheel = ioport("IN5")->read();
return result | ((wheel >> 2) & 0x3e);
}
READ8_MEMBER(mcr68_state::zwackery_6840_r)
{
/* Zwackery does a timer test: */
/* It loads $1388 into one of the timers clocked by E */
/* Then it sits in a tight loop counting down from $4E4 */
/* BTST #$1,($2,A0) */
/* DBNE D1,*-6 */
/* It expects D1 to end up between 0 and 5; in order to */
/* make this happen, we must assume that reads from the */
/* 6840 take 14 additional cycles */
space.device().execute().adjust_icount(-14);
return m_ptm->read(space, offset);
}
/*************************************
*
* Xenophobe-specific handlers
@ -317,28 +285,6 @@ ADDRESS_MAP_END
/*************************************
*
* Zwackery main CPU memory handlers
*
*************************************/
static ADDRESS_MAP_START( zwackery_map, AS_PROGRAM, 16, mcr68_state )
ADDRESS_MAP_UNMAP_HIGH
AM_RANGE(0x000000, 0x037fff) AM_ROM
AM_RANGE(0x080000, 0x080fff) AM_RAM
AM_RANGE(0x084000, 0x084fff) AM_RAM
AM_RANGE(0x100000, 0x10000f) AM_READ8(zwackery_6840_r, 0xff00) AM_DEVWRITE8("ptm", ptm6840_device, write, 0xff00)
AM_RANGE(0x104000, 0x104007) AM_DEVREADWRITE8("pia0", pia6821_device, read, write, 0xff00)
AM_RANGE(0x108000, 0x108007) AM_DEVREADWRITE8("pia1", pia6821_device, read, write, 0x00ff)
AM_RANGE(0x10c000, 0x10c007) AM_DEVREADWRITE8("pia2", pia6821_device, read, write, 0x00ff)
AM_RANGE(0x800000, 0x800fff) AM_RAM_WRITE(zwackery_videoram_w) AM_SHARE("videoram")
AM_RANGE(0x802000, 0x803fff) AM_RAM_DEVWRITE("palette", palette_device, write) AM_SHARE("palette")
AM_RANGE(0xc00000, 0xc00fff) AM_RAM_WRITE(zwackery_spriteram_w) AM_SHARE("spriteram")
ADDRESS_MAP_END
/*************************************
*
* Pigskin CPU memory handlers
@ -394,62 +340,6 @@ ADDRESS_MAP_END
*
*************************************/
static INPUT_PORTS_START( zwackery )
PORT_START("IN0")
PORT_BIT( 0x01, IP_ACTIVE_LOW, IPT_START1 )
PORT_BIT( 0x02, IP_ACTIVE_LOW, IPT_START2 )
PORT_BIT( 0x04, IP_ACTIVE_LOW, IPT_COIN1 )
PORT_BIT( 0x08, IP_ACTIVE_LOW, IPT_COIN2 )
PORT_SERVICE( 0x0010, IP_ACTIVE_LOW )
PORT_BIT( 0x20, IP_ACTIVE_LOW, IPT_SERVICE1 )
PORT_BIT( 0x40, IP_ACTIVE_LOW, IPT_TILT )
PORT_BIT( 0x80, IP_ACTIVE_LOW, IPT_BUTTON1 ) /* sword */
PORT_START("IN1")
PORT_BIT( 0x01, IP_ACTIVE_LOW, IPT_JOYSTICK_LEFT ) PORT_8WAY
PORT_BIT( 0x02, IP_ACTIVE_LOW, IPT_JOYSTICK_RIGHT ) PORT_8WAY
PORT_BIT( 0x04, IP_ACTIVE_LOW, IPT_JOYSTICK_DOWN ) PORT_8WAY
PORT_BIT( 0x08, IP_ACTIVE_LOW, IPT_JOYSTICK_UP ) PORT_8WAY
PORT_BIT( 0xf0, IP_ACTIVE_LOW, IPT_SPECIAL ) /* sound communications */
PORT_START("IN2")
PORT_BIT( 0x01, IP_ACTIVE_LOW, IPT_BUTTON3 ) /* spell up */
PORT_BIT( 0x3e, IP_ACTIVE_HIGH, IPT_UNUSED ) /* encoder wheel */
PORT_BIT( 0x40, IP_ACTIVE_LOW, IPT_BUTTON2 ) /* shield */
PORT_BIT( 0x80, IP_ACTIVE_LOW, IPT_BUTTON4 ) /* spell down */
PORT_START("IN3")
PORT_BIT( 0xff, IP_ACTIVE_LOW, IPT_UNUSED )
PORT_START("DSW")
PORT_DIPNAME( 0x07, 0x00, DEF_STR( Coinage ) ) PORT_DIPLOCATION("SW1:1,2,3")
PORT_DIPSETTING( 0x05, DEF_STR( 6C_1C ) )
PORT_DIPSETTING( 0x04, DEF_STR( 5C_1C ) )
PORT_DIPSETTING( 0x03, DEF_STR( 4C_1C ) )
PORT_DIPSETTING( 0x02, DEF_STR( 3C_1C ) )
PORT_DIPSETTING( 0x01, DEF_STR( 2C_1C ) )
PORT_DIPSETTING( 0x00, DEF_STR( 1C_1C ) )
PORT_DIPSETTING( 0x06, DEF_STR( 1C_2C ) )
PORT_DIPSETTING( 0x07, DEF_STR( Free_Play ) )
PORT_DIPNAME( 0x38, 0x00, "Buy-in" ) PORT_DIPLOCATION("SW1:4,5,6")
PORT_DIPSETTING( 0x00, "1 coin" )
PORT_DIPSETTING( 0x08, "2 coins" )
PORT_DIPSETTING( 0x10, "3 coins" )
PORT_DIPSETTING( 0x18, "4 coins" )
PORT_DIPSETTING( 0x20, "5 coins" )
PORT_DIPSETTING( 0x28, "6 coins" )
PORT_DIPSETTING( 0x30, "7 coins" )
PORT_DIPSETTING( 0x38, DEF_STR( None ) )
PORT_DIPNAME( 0xc0, 0x00, DEF_STR( Difficulty ) ) PORT_DIPLOCATION("SW1:7,8")
PORT_DIPSETTING( 0xc0, DEF_STR( Easier ) )
PORT_DIPSETTING( 0x00, DEF_STR( Normal ) )
PORT_DIPSETTING( 0x40, DEF_STR( Harder ) )
PORT_DIPSETTING( 0x80, DEF_STR( Hardest ) )
PORT_START("IN5")
PORT_BIT( 0xff, 0x00, IPT_DIAL ) PORT_SENSITIVITY(50) PORT_KEYDELTA(10) PORT_CODE_DEC(KEYCODE_Z) PORT_CODE_INC(KEYCODE_X) PORT_REVERSE
INPUT_PORTS_END
static INPUT_PORTS_START( xenophob )
PORT_START("IN0")
@ -956,29 +846,11 @@ static const gfx_layout mcr68_sprite_layout =
32*32
};
static const gfx_layout zwackery_layout =
{
16,16,
RGN_FRAC(1,2),
8,
{ 0, 0, 0, 0, 0, 0, 0, 0 },
{ STEP4(3,-1), STEP4(11,-1), STEP4(19,-1), STEP4(27,-1) },
{ 4, RGN_FRAC(1,2)+4, 0, RGN_FRAC(1,2)+0, 36, RGN_FRAC(1,2)+36, 32, RGN_FRAC(1,2)+32,
68, RGN_FRAC(1,2)+68, 64, RGN_FRAC(1,2)+64, 100, RGN_FRAC(1,2)+100, 96, RGN_FRAC(1,2)+96 },
128
};
static GFXDECODE_START( mcr68 )
GFXDECODE_SCALE( "gfx1", 0, mcr68_bg_layout, 0, 4, 2, 2 )
GFXDECODE_ENTRY( "gfx2", 0, mcr68_sprite_layout, 0, 4 )
GFXDECODE_END
static GFXDECODE_START( zwackery )
GFXDECODE_ENTRY( "gfx1", 0, zwackery_layout, 0, 16 )
GFXDECODE_ENTRY( "gfx2", 0, mcr68_sprite_layout, 0x800, 32 )
GFXDECODE_ENTRY( "gfx1", 0, zwackery_layout, 0, 16 ) /* yes, an extra copy */
GFXDECODE_END
/*************************************
@ -1002,7 +874,6 @@ GFXDECODE_END
Ideal CPU timings, based on counter usage:
Zwackery: 7652400
Xenophobe: 7723800
Spy Hunter II:7723800
Blasted: 7798800
@ -1015,60 +886,6 @@ GFXDECODE_END
=================================================================*/
static MACHINE_CONFIG_START( zwackery, mcr68_state )
/* basic machine hardware */
MCFG_CPU_ADD("maincpu", M68000, 7652400) /* should be XTAL_16MHz/2 */
MCFG_CPU_PROGRAM_MAP(zwackery_map)
MCFG_WATCHDOG_ADD("watchdog")
// MCFG_WATCHDOG_VBLANK_INIT("screen", 8)
MCFG_MACHINE_START_OVERRIDE(mcr68_state,zwackery)
MCFG_MACHINE_RESET_OVERRIDE(mcr68_state,zwackery)
MCFG_DEVICE_ADD("ptm", PTM6840, 7652400 / 10)
MCFG_PTM6840_IRQ_CB(WRITELINE(mcr68_state, ptm_irq_w))
MCFG_DEVICE_ADD("pia0", PIA6821, 0)
MCFG_PIA_READPB_HANDLER(IOPORT("IN0"))
MCFG_PIA_WRITEPA_HANDLER(WRITE8(mcr68_state, zwackery_pia0_w))
MCFG_PIA_IRQA_HANDLER(WRITELINE(mcr68_state, zwackery_pia_irq))
MCFG_PIA_IRQB_HANDLER(WRITELINE(mcr68_state, zwackery_pia_irq))
MCFG_DEVICE_ADD("pia1", PIA6821, 0)
MCFG_PIA_READPA_HANDLER(READ8(mcr68_state,zwackery_port_1_r))
MCFG_PIA_READPB_HANDLER(READ8(mcr68_state, zwackery_port_2_r))
MCFG_PIA_WRITEPA_HANDLER(WRITE8(mcr68_state, zwackery_pia1_w))
MCFG_PIA_CA2_HANDLER(WRITELINE(mcr68_state, zwackery_ca2_w))
MCFG_DEVICE_ADD("pia2", PIA6821, 0)
MCFG_PIA_READPA_HANDLER(READ8(mcr68_state, zwackery_port_3_r))
MCFG_PIA_READPB_HANDLER(IOPORT("DSW"))
/* video hardware */
MCFG_SCREEN_ADD("screen", RASTER)
MCFG_SCREEN_REFRESH_RATE(30)
MCFG_SCREEN_VBLANK_TIME(ATTOSECONDS_IN_USEC(2500) /* not accurate */)
MCFG_SCREEN_SIZE(32*16, 30*16)
MCFG_SCREEN_VISIBLE_AREA(0, 32*16-1, 0, 30*16-1)
MCFG_SCREEN_UPDATE_DRIVER(mcr68_state, screen_update_zwackery)
MCFG_SCREEN_PALETTE("palette")
MCFG_TIMER_DRIVER_ADD_SCANLINE("scantimer", mcr68_state, scanline_cb, "screen", 0, 1)
MCFG_GFXDECODE_ADD("gfxdecode", "palette", zwackery)
MCFG_PALETTE_ADD("palette", 4096)
MCFG_PALETTE_FORMAT(xRRRRRBBBBBGGGGG_inverted)
MCFG_VIDEO_START_OVERRIDE(mcr68_state,zwackery)
/* sound hardware */
MCFG_SPEAKER_STANDARD_MONO("speaker")
MCFG_SOUND_ADD("csd", MIDWAY_CHIP_SQUEAK_DELUXE, 0)
MCFG_SOUND_ROUTE(ALL_OUTPUTS, "speaker", 1.0)
MACHINE_CONFIG_END
static MACHINE_CONFIG_START( mcr68, mcr68_state )
/* basic machine hardware */
@ -1081,7 +898,7 @@ static MACHINE_CONFIG_START( mcr68, mcr68_state )
MCFG_MACHINE_RESET_OVERRIDE(mcr68_state,mcr68)
MCFG_DEVICE_ADD("ptm", PTM6840, 7723800 / 10)
MCFG_PTM6840_IRQ_CB(WRITELINE(mcr68_state, ptm_irq_w))
MCFG_PTM6840_IRQ_CB(INPUTLINE("maincpu", 2))
/* video hardware */
MCFG_SCREEN_ADD("screen", RASTER)
@ -1172,67 +989,6 @@ MACHINE_CONFIG_END
*
*************************************/
ROM_START( zwackery )
ROM_REGION( 0x40000, "maincpu", 0 )
ROM_LOAD16_BYTE( "pro0.bin", 0x00000, 0x4000, CRC(6fb9731c) SHA1(ee5b297ef2b4cf20df5e776f1c585b51f174bfa7) )
ROM_LOAD16_BYTE( "pro1.bin", 0x00001, 0x4000, CRC(84b92555) SHA1(9b4af81374828c1742c1e13fc425eea2973b0867) )
ROM_LOAD16_BYTE( "pro2.bin", 0x08000, 0x4000, CRC(e6977a2a) SHA1(602bf3f7e0f4080cb5b72d8fd3ee9fd11f27c558) )
ROM_LOAD16_BYTE( "pro3.bin", 0x08001, 0x4000, CRC(f5d0a60e) SHA1(7e0e4936cb37ac16d6db5533ae4aecdfb07ead93) )
ROM_LOAD16_BYTE( "pro4.bin", 0x10000, 0x4000, CRC(ec5841d9) SHA1(4bafe614e8993994b0ea9aedc8dc2474361e4594) )
ROM_LOAD16_BYTE( "pro5.bin", 0x10001, 0x4000, CRC(d7d99ce0) SHA1(fdf428ab9c96dae555d49bac47495613ba265452) )
ROM_LOAD16_BYTE( "pro6.bin", 0x18000, 0x4000, CRC(b9fe7bf5) SHA1(a94f80f49b4520a2c1098eee8983560b4ecdf3d5) )
ROM_LOAD16_BYTE( "pro7.bin", 0x18001, 0x4000, CRC(5e261b3b) SHA1(dcf99f528c9e3b4f8b52d413c088559bfb37d733) )
ROM_LOAD16_BYTE( "pro8.bin", 0x20000, 0x4000, CRC(55e380a5) SHA1(e3fef8486858cd714086449327a93b4a70ae73ff) )
ROM_LOAD16_BYTE( "pro9.bin", 0x20001, 0x4000, CRC(12249dca) SHA1(154170286047ea78645d45dfdd895a597dad17da) )
ROM_LOAD16_BYTE( "pro10.bin", 0x28000, 0x4000, CRC(6a39a8ca) SHA1(8ac9c3e60dc6f1918bfb95acf3ee170cedfb20ea) )
ROM_LOAD16_BYTE( "pro11.bin", 0x28001, 0x4000, CRC(ad6b45bc) SHA1(118496e898654b028f008a3d493e693ba000ef38) )
ROM_LOAD16_BYTE( "pro12.bin", 0x30000, 0x4000, CRC(e2d25e1f) SHA1(5d8ff303441eccf431422b453a173983a4513630) )
ROM_LOAD16_BYTE( "pro13.bin", 0x30001, 0x4000, CRC(e131f9b8) SHA1(08b131f2acc84d4c2c931bfd24e7de3d92a8a817) )
ROM_REGION( 0x20000, "csd:cpu", 0 )
ROM_LOAD16_BYTE( "csd7.bin", 0x00000, 0x2000, CRC(5501f54b) SHA1(84c0851fb868e81400cfe3ebfd7b91fe98a47bac) )
ROM_LOAD16_BYTE( "csd17.bin", 0x00001, 0x2000, CRC(2e482580) SHA1(92bd3e64ff580800ee16579d97bcb8b3bd9f755c) )
ROM_LOAD16_BYTE( "csd8.bin", 0x04000, 0x2000, CRC(13366575) SHA1(bcf25a7d4c6b2ccd7cd9978edafc66ef0cadfe72) )
ROM_LOAD16_BYTE( "csd18.bin", 0x04001, 0x2000, CRC(bcfe5820) SHA1(ca32daa645851a2373b3cdb8a5e63ebda84aa762) )
ROM_REGION( 0x8000, "gfx1", ROMREGION_INVERT )
ROM_LOAD( "tileh.bin", 0x00000, 0x4000, CRC(a7237eb1) SHA1(197e5838ac2bc732ae9eb33a9257b9391d50abf8) )
ROM_LOAD( "tileg.bin", 0x04000, 0x4000, CRC(626cc69b) SHA1(86142bafa78f45d1a0bed0b83f3558b21384fa1a) )
ROM_REGION( 0x20000, "gfx2", 0 )
ROM_LOAD( "spr6h.bin", 0x00000, 0x4000, CRC(a51158dc) SHA1(8d3b0054950443fdf57f83dcb973d05f6c7ad9c8) )
ROM_LOAD( "spr7h.bin", 0x04000, 0x4000, CRC(941feecf) SHA1(8e88c956332e78dc7e55139879f2272116415714) )
ROM_LOAD( "spr6j.bin", 0x08000, 0x4000, CRC(f3eef316) SHA1(026e18bdfdda8cc9d0774e6d9d758686bf16992c) )
ROM_LOAD( "spr7j.bin", 0x0c000, 0x4000, CRC(a8a34033) SHA1(abd9fde84bb079c84126ad04d584ec03b44b60cd) )
ROM_LOAD( "spr10h.bin", 0x10000, 0x4000, CRC(a99daea6) SHA1(c323e05f398b7e9e04b75fd8ac5e8ab675236d66) )
ROM_LOAD( "spr11h.bin", 0x14000, 0x4000, CRC(c1a767fb) SHA1(c16e09b39b09d409b534ce4c53366e43237a3759) )
ROM_LOAD( "spr10j.bin", 0x18000, 0x4000, CRC(4dd04376) SHA1(069b64397e7a961c1fc246671472f759bd9f6c03) )
ROM_LOAD( "spr11j.bin", 0x1c000, 0x4000, CRC(e8c6a880) SHA1(dd3d52ddbc36e244b96cfb87e6a80adb94626407) )
ROM_REGION( 0x8000, "gfx3", 0 ) /* bg color maps */
ROM_LOAD16_BYTE( "tilef.bin", 0x0000, 0x4000, CRC(a0dfcd7e) SHA1(0fc6723eddef2a96de9bf1f48006dd067c148540) )
ROM_LOAD16_BYTE( "tilee.bin", 0x0001, 0x4000, CRC(ab504dc8) SHA1(4ebdcd42624e94c29ccdb8247bfff2d8e936ddd7) )
ROM_REGION( 0x000D, "plds", 0 )
/* According to the manual these pal's are located on the "Venus CPU" board */
ROM_LOAD( "pal.d5", 0x0000, 0x00001, NO_DUMP ) /* marked H-T in manual */
ROM_LOAD( "pal.d2", 0x0001, 0x00001, NO_DUMP ) /* marked V-T in manual */
ROM_LOAD( "pal.d4", 0x0002, 0x00001, NO_DUMP ) /* marked MISC V&H PAL in manual */
ROM_LOAD( "pal.d3", 0x0003, 0x00001, NO_DUMP ) /* marked MISC CUSTOM PAL in manual */
ROM_LOAD( "pal.e6", 0x0004, 0x00001, NO_DUMP ) /* marked CPU WTS PAL in manual*/
ROM_LOAD( "pal.f8", 0x0005, 0x00001, NO_DUMP ) /* marked CPU IOC PAL in manual*/
ROM_LOAD( "pal.a5", 0x0006, 0x00001, NO_DUMP ) /* marked CPU RMD PAL in manual*/
/* According to the manual these pal's are located on the "Venus VIDEO" board */
ROM_LOAD( "pal.1f", 0x0007, 0x00001, NO_DUMP ) /* marked PAL FGBDCD in manual*/
ROM_LOAD( "pal.1d", 0x0008, 0x00001, NO_DUMP ) /* marked PAL HCT in manual*/
/* According to the manual these pal's are located on the "Venus BACKGROUND" board */
ROM_LOAD( "pal.1c", 0x0009, 0x00001, NO_DUMP ) /* marked BGBPE PAL in manual*/
ROM_LOAD( "pal.5c", 0x000a, 0x00001, NO_DUMP ) /* marked HCT PAL in manual*/
ROM_LOAD( "pal.5j", 0x000b, 0x00001, NO_DUMP ) /* marked BGBDCD PAL in manual*/
/* According to the manual this pal is located on the "Artificial Artist" board */
ROM_LOAD( "pal20.u15", 0x000c, 0x00001, NO_DUMP ) /* marked CSD002R0 in manual, pal type not specified */
ROM_END
/*
Xenophobe
@ -1708,15 +1464,6 @@ void mcr68_state::mcr68_common_init(int clip, int xoffset)
}
DRIVER_INIT_MEMBER(mcr68_state,zwackery)
{
mcr68_common_init(0, 0);
/* Zwackery doesn't care too much about this value; currently taken from Blasted */
m_timing_factor = attotime::from_hz(m_maincpu->unscaled_clock() / 10) * (256 + 16);
}
DRIVER_INIT_MEMBER(mcr68_state,xenophob)
{
mcr68_common_init(0, -4);
@ -1843,8 +1590,6 @@ DRIVER_INIT_MEMBER(mcr68_state,trisport)
*
*************************************/
GAME( 1984, zwackery, 0, zwackery, zwackery, mcr68_state, zwackery, ROT0, "Bally Midway", "Zwackery", MACHINE_SUPPORTS_SAVE )
GAME( 1987, xenophob, 0, xenophob, xenophob, mcr68_state, xenophob, ROT0, "Bally Midway", "Xenophobe", MACHINE_SUPPORTS_SAVE )
GAME( 1987, spyhunt2, 0, spyhunt2, spyhunt2, mcr68_state, spyhunt2, ROT0, "Bally Midway", "Spy Hunter II (rev 2)", MACHINE_SUPPORTS_SAVE )

View File

@ -0,0 +1,618 @@
// license: BSD-3-Clause
// copyright-holders: Aaron Giles, Bryan McPhail
/***************************************************************************
Zwackery
© 1984 Midway
The hardware consists of the following boards:
- Venus CPU (B084-91668-A385)
- Venus Video (B084-91675-A385)
- Venus Background (B084-91672-A385)
- Artificial Artist (B084-91671-A385)
TODO:
- Accurate screen timings
***************************************************************************/
#include "emu.h"
#include "cpu/m68000/m68000.h"
#include "machine/6821pia.h"
#include "machine/6840ptm.h"
#include "machine/watchdog.h"
#include "audio/midway.h"
//**************************************************************************
// TYPE DEFINITIONS
//**************************************************************************
class zwackery_state : public driver_device
{
public:
zwackery_state(const machine_config &mconfig, device_type type, const char *tag)
: driver_device(mconfig, type, tag),
m_maincpu(*this, "maincpu"),
m_pia0(*this, "pia0"),
m_pia1(*this, "pia1"),
m_pia2(*this, "pia2"),
m_ptm(*this, "ptm"),
m_watchdog(*this, "watchdog"),
m_screen(*this, "screen"),
m_gfxdecode(*this, "gfxdecode"),
m_videoram(*this, "videoram"),
m_chip_squeak_deluxe(*this, "csd"),
m_bg_tilemap(nullptr),
m_fg_tilemap(nullptr),
m_sound_data(0)
{ }
DECLARE_VIDEO_START(zwackery);
TIMER_DEVICE_CALLBACK_MEMBER(scanline_cb);
DECLARE_WRITE16_MEMBER(videoram_w);
DECLARE_READ8_MEMBER(spriteram_r);
DECLARE_WRITE8_MEMBER(spriteram_w);
void update_sprites(screen_device &screen, bitmap_ind16 &bitmap, const rectangle &cliprect, int priority);
uint32_t screen_update(screen_device &screen, bitmap_ind16 &bitmap, const rectangle &cliprect);
TILE_GET_INFO_MEMBER(get_bg_tile_info);
TILE_GET_INFO_MEMBER(get_fg_tile_info);
DECLARE_WRITE8_MEMBER(pia0_porta_w);
DECLARE_WRITE_LINE_MEMBER(pia0_irq_w);
DECLARE_READ8_MEMBER(pia1_porta_r);
DECLARE_WRITE8_MEMBER(pia1_porta_w);
DECLARE_READ8_MEMBER(pia1_portb_r);
DECLARE_WRITE_LINE_MEMBER(pia1_ca2_w);
DECLARE_READ8_MEMBER(pia2_porta_r);
DECLARE_READ8_MEMBER(ptm_r);
protected:
virtual void machine_start() override;
private:
required_device<m68000_device> m_maincpu;
required_device<pia6821_device> m_pia0;
required_device<pia6821_device> m_pia1;
required_device<pia6821_device> m_pia2;
required_device<ptm6840_device> m_ptm;
required_device<watchdog_timer_device> m_watchdog;
required_device<screen_device> m_screen;
required_device<gfxdecode_device> m_gfxdecode;
required_shared_ptr<uint16_t> m_videoram;
required_device<midway_chip_squeak_deluxe_device> m_chip_squeak_deluxe;
tilemap_t *m_bg_tilemap;
tilemap_t *m_fg_tilemap;
std::unique_ptr<uint8_t[]> m_spriteram;
std::unique_ptr<uint8_t[]> m_srcdata0;
std::unique_ptr<uint8_t[]> m_srcdata2;
uint8_t m_sound_data;
};
//**************************************************************************
// ADDRESS MAPS
//**************************************************************************
static ADDRESS_MAP_START( zwackery_map, AS_PROGRAM, 16, zwackery_state )
ADDRESS_MAP_UNMAP_HIGH
AM_RANGE(0x000000, 0x037fff) AM_ROM
AM_RANGE(0x080000, 0x080fff) AM_RAM
AM_RANGE(0x084000, 0x084fff) AM_RAM
AM_RANGE(0x100000, 0x10000f) AM_READ8(ptm_r, 0xff00) AM_DEVWRITE8("ptm", ptm6840_device, write, 0xff00)
AM_RANGE(0x104000, 0x104007) AM_DEVREADWRITE8("pia0", pia6821_device, read, write, 0xff00)
AM_RANGE(0x108000, 0x108007) AM_DEVREADWRITE8("pia1", pia6821_device, read, write, 0x00ff)
AM_RANGE(0x10c000, 0x10c007) AM_DEVREADWRITE8("pia2", pia6821_device, read, write, 0x00ff)
AM_RANGE(0x800000, 0x800fff) AM_RAM_WRITE(videoram_w) AM_SHARE("videoram")
AM_RANGE(0x802000, 0x803fff) AM_RAM_DEVWRITE("palette", palette_device, write) AM_SHARE("palette")
AM_RANGE(0xc00000, 0xc00fff) AM_READWRITE8(spriteram_r, spriteram_w, 0x00ff)
ADDRESS_MAP_END
//**************************************************************************
// INPUTS
//**************************************************************************
static INPUT_PORTS_START( zwackery )
PORT_START("IN0")
PORT_BIT( 0x01, IP_ACTIVE_LOW, IPT_START1 )
PORT_BIT( 0x02, IP_ACTIVE_LOW, IPT_START2 )
PORT_BIT( 0x04, IP_ACTIVE_LOW, IPT_COIN1 )
PORT_BIT( 0x08, IP_ACTIVE_LOW, IPT_COIN2 )
PORT_SERVICE( 0x0010, IP_ACTIVE_LOW )
PORT_BIT( 0x20, IP_ACTIVE_LOW, IPT_SERVICE1 )
PORT_BIT( 0x40, IP_ACTIVE_LOW, IPT_TILT )
PORT_BIT( 0x80, IP_ACTIVE_LOW, IPT_BUTTON1 ) PORT_NAME("Sword")
PORT_START("IN1")
PORT_BIT( 0x01, IP_ACTIVE_LOW, IPT_JOYSTICK_LEFT ) PORT_8WAY
PORT_BIT( 0x02, IP_ACTIVE_LOW, IPT_JOYSTICK_RIGHT ) PORT_8WAY
PORT_BIT( 0x04, IP_ACTIVE_LOW, IPT_JOYSTICK_DOWN ) PORT_8WAY
PORT_BIT( 0x08, IP_ACTIVE_LOW, IPT_JOYSTICK_UP ) PORT_8WAY
PORT_BIT( 0xf0, IP_ACTIVE_LOW, IPT_SPECIAL ) // sound communications
PORT_START("IN2")
PORT_BIT( 0x01, IP_ACTIVE_LOW, IPT_BUTTON3 ) PORT_NAME("Spell Up")
PORT_BIT( 0x3e, IP_ACTIVE_HIGH, IPT_UNUSED ) // encoder wheel
PORT_BIT( 0x40, IP_ACTIVE_LOW, IPT_BUTTON2 ) PORT_NAME("Shield")
PORT_BIT( 0x80, IP_ACTIVE_LOW, IPT_BUTTON4 ) PORT_NAME("Spell Down")
PORT_START("IN3")
PORT_BIT( 0xff, IP_ACTIVE_LOW, IPT_UNUSED )
PORT_START("DSW")
PORT_DIPNAME( 0x07, 0x00, DEF_STR( Coinage ) ) PORT_DIPLOCATION("SW1:1,2,3")
PORT_DIPSETTING( 0x05, DEF_STR( 6C_1C ) )
PORT_DIPSETTING( 0x04, DEF_STR( 5C_1C ) )
PORT_DIPSETTING( 0x03, DEF_STR( 4C_1C ) )
PORT_DIPSETTING( 0x02, DEF_STR( 3C_1C ) )
PORT_DIPSETTING( 0x01, DEF_STR( 2C_1C ) )
PORT_DIPSETTING( 0x00, DEF_STR( 1C_1C ) )
PORT_DIPSETTING( 0x06, DEF_STR( 1C_2C ) )
PORT_DIPSETTING( 0x07, DEF_STR( Free_Play ) )
PORT_DIPNAME( 0x38, 0x00, "Buy-in" ) PORT_DIPLOCATION("SW1:4,5,6")
PORT_DIPSETTING( 0x00, "1 coin" )
PORT_DIPSETTING( 0x08, "2 coins" )
PORT_DIPSETTING( 0x10, "3 coins" )
PORT_DIPSETTING( 0x18, "4 coins" )
PORT_DIPSETTING( 0x20, "5 coins" )
PORT_DIPSETTING( 0x28, "6 coins" )
PORT_DIPSETTING( 0x30, "7 coins" )
PORT_DIPSETTING( 0x38, DEF_STR( None ) )
PORT_DIPNAME( 0xc0, 0x00, DEF_STR( Difficulty ) ) PORT_DIPLOCATION("SW1:7,8")
PORT_DIPSETTING( 0xc0, DEF_STR( Easier ) )
PORT_DIPSETTING( 0x00, DEF_STR( Normal ) )
PORT_DIPSETTING( 0x40, DEF_STR( Harder ) )
PORT_DIPSETTING( 0x80, DEF_STR( Hardest ) )
PORT_START("IN5")
PORT_BIT( 0xff, 0x00, IPT_DIAL ) PORT_SENSITIVITY(50) PORT_KEYDELTA(10) PORT_CODE_DEC(KEYCODE_Z) PORT_CODE_INC(KEYCODE_X) PORT_REVERSE
INPUT_PORTS_END
//**************************************************************************
// VIDEO EMULATION
//**************************************************************************
VIDEO_START_MEMBER( zwackery_state, zwackery )
{
const uint8_t *colordatabase = (const uint8_t *)memregion("bg_color")->base();
gfx_element *gfx0 = m_gfxdecode->gfx(0);
gfx_element *gfx2 = m_gfxdecode->gfx(2);
// initialize the background tilemap
m_bg_tilemap = &machine().tilemap().create(*m_gfxdecode, tilemap_get_info_delegate(FUNC(zwackery_state::get_bg_tile_info),this), TILEMAP_SCAN_ROWS, 16,16, 32,32);
// initialize the foreground tilemap
m_fg_tilemap = &machine().tilemap().create(*m_gfxdecode, tilemap_get_info_delegate(FUNC(zwackery_state::get_fg_tile_info),this), TILEMAP_SCAN_ROWS, 16,16, 32,32);
m_fg_tilemap->set_transparent_pen(0);
// allocate memory for the assembled gfx data
m_srcdata0 = std::make_unique<uint8_t[]>(gfx0->elements() * gfx0->width() * gfx0->height());
m_srcdata2 = std::make_unique<uint8_t[]>(gfx2->elements() * gfx2->width() * gfx2->height());
// "colorize" each code
uint8_t *dest0 = m_srcdata0.get();
uint8_t *dest2 = m_srcdata2.get();
for (int code = 0; code < gfx0->elements(); code++)
{
const uint8_t *coldata = colordatabase + code * 32;
const uint8_t *gfxdata0 = gfx0->get_data(code);
const uint8_t *gfxdata2 = gfx2->get_data(code);
// assume 16 rows
for (int y = 0; y < 16; y++)
{
const uint8_t *gd0 = gfxdata0;
const uint8_t *gd2 = gfxdata2;
// 16 columns
for (int x = 0; x < 16; x++, gd0++, gd2++)
{
int coloffs = (y & 0x0c) | ((x >> 2) & 0x03);
int pen0 = coldata[coloffs * 2 + 0];
int pen1 = coldata[coloffs * 2 + 1];
int tp0, tp1;
// every 4 pixels gets its own foreground/background colors
*dest0++ = *gd0 ? pen1 : pen0;
// for gfx 2, we convert all low-priority pens to 0
tp0 = (pen0 & 0x80) ? pen0 : 0;
tp1 = (pen1 & 0x80) ? pen1 : 0;
*dest2++ = *gd2 ? tp1 : tp0;
}
// advance
gfxdata0 += gfx0->rowbytes();
gfxdata2 += gfx2->rowbytes();
}
}
// make the assembled data our new source data
gfx0->set_raw_layout(m_srcdata0.get(), gfx0->width(), gfx0->height(), gfx0->elements(), 8 * gfx0->width(), 8 * gfx0->width() * gfx0->height());
gfx2->set_raw_layout(m_srcdata2.get(), gfx2->width(), gfx2->height(), gfx2->elements(), 8 * gfx2->width(), 8 * gfx2->width() * gfx2->height());
}
TIMER_DEVICE_CALLBACK_MEMBER( zwackery_state::scanline_cb )
{
switch (param)
{
case 0:
// VSYNC
m_ptm->set_c1(0);
m_ptm->set_c1(1);
break;
case 474:
// source of this signal is pal.d3 (current value taken from original driver)
m_pia0->ca1_w(1);
break;
case 475:
// turn it off again after one scanline
m_pia0->ca1_w(0);
break;
}
// HSYNC
m_ptm->set_c3(0);
m_ptm->set_c3(1);
}
WRITE16_MEMBER( zwackery_state::videoram_w )
{
COMBINE_DATA(&m_videoram[offset]);
m_bg_tilemap->mark_tile_dirty(offset);
m_fg_tilemap->mark_tile_dirty(offset);
}
READ8_MEMBER( zwackery_state::spriteram_r )
{
return m_spriteram[offset];
}
WRITE8_MEMBER( zwackery_state::spriteram_w )
{
m_spriteram[offset] = data;
}
void zwackery_state::update_sprites(screen_device &screen, bitmap_ind16 &bitmap, const rectangle &cliprect, int priority)
{
screen.priority().fill(1, cliprect);
// loop over sprite RAM
for (int offs = 0x800 - 4; offs >= 0; offs -= 4)
{
int code, color, flipx, flipy, x, y, flags;
// get the code and skip if zero
code = m_spriteram[offs + 2];
if (code == 0)
continue;
// extract the flag bits and determine the color
flags = m_spriteram[offs + 1];
color = ((~flags >> 2) & 0x0f) | ((flags & 0x02) << 3);
// for low priority, draw everything but color 7
if (!priority)
{
if (color == 7)
continue;
}
// for high priority, only draw color 7
else
{
if (color != 7)
continue;
}
// determine flipping and coordinates
flipx = ~flags & 0x40;
flipy = flags & 0x80;
x = (231 - m_spriteram[offs + 3]) * 2;
y = (241 - m_spriteram[offs]) * 2;
if (x <= -32) x += 512;
// sprites use color 0 for background pen and 8 for the 'under tile' pen.
// The color 8 is used to cover over other sprites.
// first draw the sprite, visible
m_gfxdecode->gfx(1)->prio_transmask(bitmap,cliprect, code, color, flipx, flipy, x, y,
screen.priority(), 0x00, 0x0101);
// then draw the mask, behind the background but obscuring following sprites
m_gfxdecode->gfx(1)->prio_transmask(bitmap,cliprect, code, color, flipx, flipy, x, y,
screen.priority(), 0x02, 0xfeff);
}
}
uint32_t zwackery_state::screen_update(screen_device &screen, bitmap_ind16 &bitmap, const rectangle &cliprect)
{
// draw the background
m_bg_tilemap->draw(screen, bitmap, cliprect, 0, 0);
// draw the low-priority sprites
update_sprites(screen, bitmap, cliprect, 0);
// redraw tiles with priority over sprites
m_fg_tilemap->draw(screen, bitmap, cliprect, 1, 0);
// draw the high-priority sprites
update_sprites(screen, bitmap, cliprect, 1);
return 0;
}
TILE_GET_INFO_MEMBER( zwackery_state::get_bg_tile_info )
{
uint16_t data = m_videoram[tile_index];
int color = (data >> 13) & 7;
SET_TILE_INFO_MEMBER(0, data & 0x3ff, color, TILE_FLIPYX(data >> 11));
}
TILE_GET_INFO_MEMBER( zwackery_state::get_fg_tile_info )
{
uint16_t data = m_videoram[tile_index];
int color = (data >> 13) & 7;
SET_TILE_INFO_MEMBER(2, data & 0x3ff, color, TILE_FLIPYX(data >> 11));
tileinfo.category = (color != 0);
}
static const gfx_layout zwackery_layout =
{
16,16,
RGN_FRAC(1,2),
8,
{ 0, 0, 0, 0, 0, 0, 0, 0 },
{ STEP4(3,-1), STEP4(11,-1), STEP4(19,-1), STEP4(27,-1) },
{ 4, RGN_FRAC(1,2)+4, 0, RGN_FRAC(1,2)+0, 36, RGN_FRAC(1,2)+36, 32, RGN_FRAC(1,2)+32,
68, RGN_FRAC(1,2)+68, 64, RGN_FRAC(1,2)+64, 100, RGN_FRAC(1,2)+100, 96, RGN_FRAC(1,2)+96 },
128
};
static const gfx_layout mcr68_sprite_layout =
{
32,32,
RGN_FRAC(1,4),
4,
{ STEP4(0,1) },
{ STEP2(RGN_FRAC(0,4)+0,4), STEP2(RGN_FRAC(1,4)+0,4), STEP2(RGN_FRAC(2,4)+0,4), STEP2(RGN_FRAC(3,4)+0,4),
STEP2(RGN_FRAC(0,4)+8,4), STEP2(RGN_FRAC(1,4)+8,4), STEP2(RGN_FRAC(2,4)+8,4), STEP2(RGN_FRAC(3,4)+8,4),
STEP2(RGN_FRAC(0,4)+16,4), STEP2(RGN_FRAC(1,4)+16,4), STEP2(RGN_FRAC(2,4)+16,4), STEP2(RGN_FRAC(3,4)+16,4),
STEP2(RGN_FRAC(0,4)+24,4), STEP2(RGN_FRAC(1,4)+24,4), STEP2(RGN_FRAC(2,4)+24,4), STEP2(RGN_FRAC(3,4)+24,4) },
{ STEP32(0,32) },
32*32
};
static GFXDECODE_START( zwackery )
GFXDECODE_ENTRY( "gfx1", 0, zwackery_layout, 0, 16 )
GFXDECODE_ENTRY( "sprites", 0, mcr68_sprite_layout, 0x800, 32 )
GFXDECODE_ENTRY( "gfx1", 0, zwackery_layout, 0, 16 ) // yes, an extra copy
GFXDECODE_END
//**************************************************************************
// AUDIO
//**************************************************************************
WRITE8_MEMBER( zwackery_state::pia1_porta_w )
{
m_sound_data = (data >> 4) & 0x0f;
}
WRITE_LINE_MEMBER( zwackery_state::pia1_ca2_w )
{
m_chip_squeak_deluxe->write(machine().dummy_space(), 0, (state << 4) | m_sound_data);
}
//**************************************************************************
// INPUTS/OUTPUTS
//**************************************************************************
WRITE8_MEMBER( zwackery_state::pia0_porta_w )
{
// bits 0, 1 and 2 control meters?
// bits 3 and 4 control coin counters?
// bits 5 and 6 control hflip/vflip
// bit 7, watchdog
if (BIT(data, 7) == 0)
m_watchdog->watchdog_reset();
}
WRITE_LINE_MEMBER(zwackery_state::pia0_irq_w)
{
int irq_state = m_pia0->irq_a_state() | m_pia0->irq_b_state();
m_maincpu->set_input_line(5, irq_state ? ASSERT_LINE : CLEAR_LINE);
}
READ8_MEMBER( zwackery_state::pia1_porta_r )
{
uint8_t data = ioport("IN1")->read();
m_pia1->set_port_a_z_mask(data);
return data;
}
READ8_MEMBER( zwackery_state::pia1_portb_r )
{
uint8_t result = ioport("IN2")->read();
uint8_t wheel = ioport("IN5")->read();
return result | ((wheel >> 2) & 0x3e);
}
READ8_MEMBER( zwackery_state::pia2_porta_r )
{
uint8_t data = ioport("IN3")->read();
m_pia2->set_port_a_z_mask(data);
return data;
}
//**************************************************************************
// MACHINE EMULATION
//**************************************************************************
// Zwackery does a timer test:
// It loads $1388 into one of the timers clocked by E
// Then it sits in a tight loop counting down from $4E4
// BTST #$1,($2,A0)
// DBNE D1,*-6
// It expects D1 to end up between 0 and 5; in order to
// make this happen, we must assume that reads from the
// 6840 take 14 additional cycles
READ8_MEMBER( zwackery_state::ptm_r )
{
space.device().execute().adjust_icount(-14);
return m_ptm->read(space, offset);
}
void zwackery_state::machine_start()
{
// allocate 8-bit spriteram
m_spriteram = std::make_unique<uint8_t[]>(0x800);
// register for save states
save_pointer(NAME(m_spriteram.get()), 0x800);
save_item(NAME(m_sound_data));
}
//**************************************************************************
// MACHINE DEFINTIONS
//**************************************************************************
static MACHINE_CONFIG_START( zwackery, zwackery_state )
// basic machine hardware
MCFG_CPU_ADD("maincpu", M68000, 7652400) // based on counter usage, should be XTAL_16MHz/2
MCFG_CPU_PROGRAM_MAP(zwackery_map)
MCFG_WATCHDOG_ADD("watchdog")
MCFG_DEVICE_ADD("ptm", PTM6840, 7652400 / 10)
MCFG_PTM6840_IRQ_CB(INPUTLINE("maincpu", 6))
MCFG_DEVICE_ADD("pia0", PIA6821, 0)
MCFG_PIA_READPB_HANDLER(IOPORT("IN0"))
MCFG_PIA_WRITEPA_HANDLER(WRITE8(zwackery_state, pia0_porta_w))
MCFG_PIA_IRQA_HANDLER(WRITELINE(zwackery_state, pia0_irq_w))
MCFG_PIA_IRQB_HANDLER(WRITELINE(zwackery_state, pia0_irq_w))
MCFG_DEVICE_ADD("pia1", PIA6821, 0)
MCFG_PIA_READPA_HANDLER(READ8(zwackery_state, pia1_porta_r))
MCFG_PIA_WRITEPA_HANDLER(WRITE8(zwackery_state, pia1_porta_w))
MCFG_PIA_READPB_HANDLER(READ8(zwackery_state, pia1_portb_r))
MCFG_PIA_CA2_HANDLER(WRITELINE(zwackery_state, pia1_ca2_w))
MCFG_DEVICE_ADD("pia2", PIA6821, 0)
MCFG_PIA_READPA_HANDLER(READ8(zwackery_state, pia2_porta_r))
MCFG_PIA_READPB_HANDLER(IOPORT("DSW"))
// video hardware
MCFG_SCREEN_ADD("screen", RASTER)
MCFG_SCREEN_REFRESH_RATE(30)
MCFG_SCREEN_VBLANK_TIME(ATTOSECONDS_IN_USEC(2500)) // not accurate
MCFG_SCREEN_SIZE(32*16, 30*16)
MCFG_SCREEN_VISIBLE_AREA(0, 32*16-1, 0, 30*16-1)
MCFG_SCREEN_UPDATE_DRIVER(zwackery_state, screen_update)
MCFG_SCREEN_PALETTE("palette")
MCFG_TIMER_DRIVER_ADD_SCANLINE("scantimer", zwackery_state, scanline_cb, "screen", 0, 1)
MCFG_GFXDECODE_ADD("gfxdecode", "palette", zwackery)
MCFG_PALETTE_ADD("palette", 4096)
MCFG_PALETTE_FORMAT(xRRRRRBBBBBGGGGG_inverted)
MCFG_VIDEO_START_OVERRIDE(zwackery_state, zwackery)
// sound hardware
MCFG_SPEAKER_STANDARD_MONO("speaker")
MCFG_SOUND_ADD("csd", MIDWAY_CHIP_SQUEAK_DELUXE, 0)
MCFG_SOUND_ROUTE(ALL_OUTPUTS, "speaker", 1.0)
MACHINE_CONFIG_END
//**************************************************************************
// ROM DEFINITIONS
//**************************************************************************
ROM_START( zwackery )
ROM_REGION( 0x40000, "maincpu", 0 )
ROM_LOAD16_BYTE( "pro0.bin", 0x00000, 0x4000, CRC(6fb9731c) SHA1(ee5b297ef2b4cf20df5e776f1c585b51f174bfa7) )
ROM_LOAD16_BYTE( "pro1.bin", 0x00001, 0x4000, CRC(84b92555) SHA1(9b4af81374828c1742c1e13fc425eea2973b0867) )
ROM_LOAD16_BYTE( "pro2.bin", 0x08000, 0x4000, CRC(e6977a2a) SHA1(602bf3f7e0f4080cb5b72d8fd3ee9fd11f27c558) )
ROM_LOAD16_BYTE( "pro3.bin", 0x08001, 0x4000, CRC(f5d0a60e) SHA1(7e0e4936cb37ac16d6db5533ae4aecdfb07ead93) )
ROM_LOAD16_BYTE( "pro4.bin", 0x10000, 0x4000, CRC(ec5841d9) SHA1(4bafe614e8993994b0ea9aedc8dc2474361e4594) )
ROM_LOAD16_BYTE( "pro5.bin", 0x10001, 0x4000, CRC(d7d99ce0) SHA1(fdf428ab9c96dae555d49bac47495613ba265452) )
ROM_LOAD16_BYTE( "pro6.bin", 0x18000, 0x4000, CRC(b9fe7bf5) SHA1(a94f80f49b4520a2c1098eee8983560b4ecdf3d5) )
ROM_LOAD16_BYTE( "pro7.bin", 0x18001, 0x4000, CRC(5e261b3b) SHA1(dcf99f528c9e3b4f8b52d413c088559bfb37d733) )
ROM_LOAD16_BYTE( "pro8.bin", 0x20000, 0x4000, CRC(55e380a5) SHA1(e3fef8486858cd714086449327a93b4a70ae73ff) )
ROM_LOAD16_BYTE( "pro9.bin", 0x20001, 0x4000, CRC(12249dca) SHA1(154170286047ea78645d45dfdd895a597dad17da) )
ROM_LOAD16_BYTE( "pro10.bin", 0x28000, 0x4000, CRC(6a39a8ca) SHA1(8ac9c3e60dc6f1918bfb95acf3ee170cedfb20ea) )
ROM_LOAD16_BYTE( "pro11.bin", 0x28001, 0x4000, CRC(ad6b45bc) SHA1(118496e898654b028f008a3d493e693ba000ef38) )
ROM_LOAD16_BYTE( "pro12.bin", 0x30000, 0x4000, CRC(e2d25e1f) SHA1(5d8ff303441eccf431422b453a173983a4513630) )
ROM_LOAD16_BYTE( "pro13.bin", 0x30001, 0x4000, CRC(e131f9b8) SHA1(08b131f2acc84d4c2c931bfd24e7de3d92a8a817) )
ROM_REGION( 0x20000, "csd:cpu", 0 )
ROM_LOAD16_BYTE( "csd7.bin", 0x00000, 0x2000, CRC(5501f54b) SHA1(84c0851fb868e81400cfe3ebfd7b91fe98a47bac) )
ROM_LOAD16_BYTE( "csd17.bin", 0x00001, 0x2000, CRC(2e482580) SHA1(92bd3e64ff580800ee16579d97bcb8b3bd9f755c) )
ROM_LOAD16_BYTE( "csd8.bin", 0x04000, 0x2000, CRC(13366575) SHA1(bcf25a7d4c6b2ccd7cd9978edafc66ef0cadfe72) )
ROM_LOAD16_BYTE( "csd18.bin", 0x04001, 0x2000, CRC(bcfe5820) SHA1(ca32daa645851a2373b3cdb8a5e63ebda84aa762) )
ROM_REGION( 0x8000, "gfx1", ROMREGION_INVERT )
ROM_LOAD( "tileh.bin", 0x00000, 0x4000, CRC(a7237eb1) SHA1(197e5838ac2bc732ae9eb33a9257b9391d50abf8) )
ROM_LOAD( "tileg.bin", 0x04000, 0x4000, CRC(626cc69b) SHA1(86142bafa78f45d1a0bed0b83f3558b21384fa1a) )
ROM_REGION( 0x20000, "sprites", 0 )
ROM_LOAD( "spr6h.bin", 0x00000, 0x4000, CRC(a51158dc) SHA1(8d3b0054950443fdf57f83dcb973d05f6c7ad9c8) )
ROM_LOAD( "spr7h.bin", 0x04000, 0x4000, CRC(941feecf) SHA1(8e88c956332e78dc7e55139879f2272116415714) )
ROM_LOAD( "spr6j.bin", 0x08000, 0x4000, CRC(f3eef316) SHA1(026e18bdfdda8cc9d0774e6d9d758686bf16992c) )
ROM_LOAD( "spr7j.bin", 0x0c000, 0x4000, CRC(a8a34033) SHA1(abd9fde84bb079c84126ad04d584ec03b44b60cd) )
ROM_LOAD( "spr10h.bin", 0x10000, 0x4000, CRC(a99daea6) SHA1(c323e05f398b7e9e04b75fd8ac5e8ab675236d66) )
ROM_LOAD( "spr11h.bin", 0x14000, 0x4000, CRC(c1a767fb) SHA1(c16e09b39b09d409b534ce4c53366e43237a3759) )
ROM_LOAD( "spr10j.bin", 0x18000, 0x4000, CRC(4dd04376) SHA1(069b64397e7a961c1fc246671472f759bd9f6c03) )
ROM_LOAD( "spr11j.bin", 0x1c000, 0x4000, CRC(e8c6a880) SHA1(dd3d52ddbc36e244b96cfb87e6a80adb94626407) )
ROM_REGION( 0x8000, "bg_color", 0 )
ROM_LOAD16_BYTE( "tilef.bin", 0x0000, 0x4000, CRC(a0dfcd7e) SHA1(0fc6723eddef2a96de9bf1f48006dd067c148540) )
ROM_LOAD16_BYTE( "tilee.bin", 0x0001, 0x4000, CRC(ab504dc8) SHA1(4ebdcd42624e94c29ccdb8247bfff2d8e936ddd7) )
ROM_REGION( 0x000D, "plds", 0 )
// located on the "Venus CPU" board
ROM_LOAD( "pal.d5", 0x0000, 0x00001, NO_DUMP ) // H-T
ROM_LOAD( "pal.d2", 0x0001, 0x00001, NO_DUMP ) // V-T
ROM_LOAD( "pal.d4", 0x0002, 0x00001, NO_DUMP ) // MISC V&H PAL
ROM_LOAD( "pal.d3", 0x0003, 0x00001, NO_DUMP ) // MISC CUSTOM PAL
ROM_LOAD( "pal.e6", 0x0004, 0x00001, NO_DUMP ) // CPU WTS PAL
ROM_LOAD( "pal.f8", 0x0005, 0x00001, NO_DUMP ) // CPU IOC PAL
ROM_LOAD( "pal.a5", 0x0006, 0x00001, NO_DUMP ) // CPU RMD PAL
// located on the "Venus VIDEO" board
ROM_LOAD( "pal.1f", 0x0007, 0x00001, NO_DUMP ) // PAL FGBDCD
ROM_LOAD( "pal.1d", 0x0008, 0x00001, NO_DUMP ) // PAL HCT
// located on the "Venus BACKGROUND" board
ROM_LOAD( "pal.1c", 0x0009, 0x00001, NO_DUMP ) // BGBPE PAL
ROM_LOAD( "pal.5c", 0x000a, 0x00001, NO_DUMP ) // HCT PAL
ROM_LOAD( "pal.5j", 0x000b, 0x00001, NO_DUMP ) // BGBDCD PAL
// located on the "Artificial Artist" board
ROM_LOAD( "pal20.u15", 0x000c, 0x00001, NO_DUMP ) // CSD002R0, pal type not specified */
ROM_END
//**************************************************************************
// SYSTEM DRIVERS
//**************************************************************************
// YEAR NAME PARENT MACHINE INPUT CLASS INIT ROTATION COMPANY FULLNAME FLAGS
GAME( 1984, zwackery, 0, zwackery, zwackery, driver_device, 0, ROT0, "Bally Midway", "Zwackery", MACHINE_SUPPORTS_SAVE )

View File

@ -6,7 +6,6 @@
***************************************************************************/
#include "machine/6821pia.h"
#include "machine/watchdog.h"
#include "audio/midway.h"
#include "audio/williams.h"
@ -17,21 +16,17 @@ class mcr68_state : public driver_device
public:
mcr68_state(const machine_config &mconfig, device_type type, const char *tag)
: driver_device(mconfig, type, tag),
m_chip_squeak_deluxe(*this, "csd"),
m_sounds_good(*this, "sg"),
m_turbo_chip_squeak(*this, "tcs"),
m_cvsd_sound(*this, "cvsd"),
m_videoram(*this, "videoram"),
m_spriteram(*this, "spriteram") ,
m_maincpu(*this, "maincpu"),
m_watchdog(*this, "watchdog"),
m_gfxdecode(*this, "gfxdecode"),
m_screen(*this, "screen"),
m_palette(*this, "palette"),
m_ptm(*this, "ptm")
{ }
optional_device<midway_chip_squeak_deluxe_device> m_chip_squeak_deluxe;
optional_device<midway_sounds_good_device> m_sounds_good;
optional_device<midway_turbo_chip_squeak_device> m_turbo_chip_squeak;
optional_device<williams_cvsd_sound_device> m_cvsd_sound;
@ -43,15 +38,9 @@ public:
attotime m_timing_factor;
uint8_t m_sprite_clip;
int8_t m_sprite_xoffset;
uint8_t m_m6840_irq_state;
uint8_t m_m6840_irq_vector;
uint8_t m_v493_irq_state;
uint8_t m_v493_irq_vector;
timer_expired_delegate m_v493_callback;
uint8_t m_zwackery_sound_data;
tilemap_t *m_bg_tilemap;
tilemap_t *m_fg_tilemap;
DECLARE_READ8_MEMBER(zwackery_6840_r);
DECLARE_WRITE16_MEMBER(xenophobe_control_w);
DECLARE_WRITE16_MEMBER(blasted_control_w);
DECLARE_READ16_MEMBER(spyhunt2_port_0_r);
@ -64,14 +53,9 @@ public:
DECLARE_READ16_MEMBER(pigskin_port_1_r);
DECLARE_READ16_MEMBER(pigskin_port_2_r);
DECLARE_READ16_MEMBER(trisport_port_1_r);
DECLARE_WRITE_LINE_MEMBER(ptm_irq_w);
DECLARE_WRITE16_MEMBER(mcr68_videoram_w);
DECLARE_WRITE16_MEMBER(zwackery_videoram_w);
DECLARE_WRITE16_MEMBER(zwackery_spriteram_w);
DECLARE_READ8_MEMBER(zwackery_port_2_r);
DECLARE_DRIVER_INIT(intlaser);
DECLARE_DRIVER_INIT(pigskin);
DECLARE_DRIVER_INIT(zwackery);
DECLARE_DRIVER_INIT(blasted);
DECLARE_DRIVER_INIT(trisport);
DECLARE_DRIVER_INIT(xenophob);
@ -80,36 +64,18 @@ public:
DECLARE_DRIVER_INIT(archrivlb);
DECLARE_READ16_MEMBER(archrivlb_port_1_r);
TILE_GET_INFO_MEMBER(get_bg_tile_info);
TILE_GET_INFO_MEMBER(zwackery_get_bg_tile_info);
TILE_GET_INFO_MEMBER(zwackery_get_fg_tile_info);
DECLARE_MACHINE_START(zwackery);
DECLARE_MACHINE_RESET(zwackery);
DECLARE_VIDEO_START(zwackery);
DECLARE_MACHINE_START(mcr68);
DECLARE_MACHINE_RESET(mcr68);
DECLARE_VIDEO_START(mcr68);
uint32_t screen_update_zwackery(screen_device &screen, bitmap_ind16 &bitmap, const rectangle &cliprect);
uint32_t screen_update_mcr68(screen_device &screen, bitmap_ind16 &bitmap, const rectangle &cliprect);
TIMER_DEVICE_CALLBACK_MEMBER(scanline_cb);
TIMER_CALLBACK_MEMBER(mcr68_493_off_callback);
TIMER_CALLBACK_MEMBER(mcr68_493_callback);
TIMER_CALLBACK_MEMBER(zwackery_493_off_callback);
TIMER_CALLBACK_MEMBER(zwackery_493_callback);
DECLARE_READ8_MEMBER(zwackery_port_1_r);
DECLARE_READ8_MEMBER(zwackery_port_3_r);
DECLARE_WRITE8_MEMBER(zwackery_pia0_w);
DECLARE_WRITE8_MEMBER(zwackery_pia1_w);
DECLARE_WRITE_LINE_MEMBER(zwackery_ca2_w);
DECLARE_WRITE_LINE_MEMBER(zwackery_pia_irq);
void mcr68_update_sprites(screen_device &screen, bitmap_ind16 &bitmap, const rectangle &cliprect, int priority);
void zwackery_update_sprites(screen_device &screen, bitmap_ind16 &bitmap, const rectangle &cliprect, int priority);
void update_mcr68_interrupts();
void mcr68_common_init(int clip, int xoffset);
required_device<cpu_device> m_maincpu;
required_device<watchdog_timer_device> m_watchdog;
required_device<gfxdecode_device> m_gfxdecode;
required_device<screen_device> m_screen;
required_device<palette_device> m_palette;
std::unique_ptr<uint8_t[]> m_srcdata0;
std::unique_ptr<uint8_t[]> m_srcdata2;

View File

@ -13,32 +13,6 @@
#define VERBOSE 0
/*************************************
*
* 6821 PIA declarations
*
*************************************/
READ8_MEMBER(mcr68_state::zwackery_port_1_r)
{
uint8_t ret = ioport("IN1")->read();
downcast<pia6821_device *>(machine().device("pia1"))->set_port_a_z_mask(ret);
return ret;
}
READ8_MEMBER(mcr68_state::zwackery_port_3_r)
{
uint8_t ret = ioport("IN3")->read();
downcast<pia6821_device *>(machine().device("pia2"))->set_port_a_z_mask(ret);
return ret;
}
/*************************************
*
@ -48,8 +22,6 @@ READ8_MEMBER(mcr68_state::zwackery_port_3_r)
MACHINE_START_MEMBER(mcr68_state,mcr68)
{
save_item(NAME(m_v493_irq_state));
save_item(NAME(m_zwackery_sound_data));
}
@ -57,27 +29,6 @@ MACHINE_RESET_MEMBER(mcr68_state,mcr68)
{
/* for the most part all MCR/68k games are the same */
m_v493_callback = timer_expired_delegate(FUNC(mcr68_state::mcr68_493_callback),this);
/* vectors are 1 and 2 */
m_v493_irq_vector = 1;
m_m6840_irq_vector = 2;
}
MACHINE_START_MEMBER(mcr68_state,zwackery)
{
MACHINE_START_CALL_MEMBER(mcr68);
}
MACHINE_RESET_MEMBER(mcr68_state,zwackery)
{
/* for the most part all MCR/68k games are the same */
m_v493_callback = timer_expired_delegate(FUNC(mcr68_state::zwackery_493_callback),this);
/* vectors are 5 and 6 */
m_v493_irq_vector = 5;
m_m6840_irq_vector = 6;
}
@ -118,87 +69,17 @@ TIMER_DEVICE_CALLBACK_MEMBER( mcr68_state::scanline_cb )
*
*************************************/
void mcr68_state::update_mcr68_interrupts()
{
m_maincpu->set_input_line(m_v493_irq_vector, m_v493_irq_state ? ASSERT_LINE : CLEAR_LINE);
m_maincpu->set_input_line(m_m6840_irq_vector, m_m6840_irq_state ? ASSERT_LINE : CLEAR_LINE);
}
TIMER_CALLBACK_MEMBER(mcr68_state::mcr68_493_off_callback)
{
m_v493_irq_state = 0;
update_mcr68_interrupts();
m_maincpu->set_input_line(1, CLEAR_LINE);
}
TIMER_CALLBACK_MEMBER(mcr68_state::mcr68_493_callback)
{
m_v493_irq_state = 1;
update_mcr68_interrupts();
m_maincpu->set_input_line(1, ASSERT_LINE);
machine().scheduler().timer_set(m_screen->scan_period(), timer_expired_delegate(FUNC(mcr68_state::mcr68_493_off_callback),this));
if (VERBOSE)
logerror("--- (INT1) ---\n");
}
WRITE_LINE_MEMBER( mcr68_state::ptm_irq_w )
{
m_m6840_irq_state = state;
update_mcr68_interrupts();
}
/*************************************
*
* Zwackery-specific interfaces
*
*************************************/
WRITE8_MEMBER(mcr68_state::zwackery_pia0_w)
{
/* bit 7 is the watchdog */
if (!(data & 0x80)) m_watchdog->watchdog_reset();
/* bits 5 and 6 control hflip/vflip */
/* bits 3 and 4 control coin counters? */
/* bits 0, 1 and 2 control meters? */
}
WRITE8_MEMBER(mcr68_state::zwackery_pia1_w)
{
m_zwackery_sound_data = (data >> 4) & 0x0f;
}
WRITE_LINE_MEMBER(mcr68_state::zwackery_ca2_w)
{
address_space &space = m_maincpu->space(AS_PROGRAM);
m_chip_squeak_deluxe->write(space, 0, (state << 4) | m_zwackery_sound_data);
}
WRITE_LINE_MEMBER(mcr68_state::zwackery_pia_irq)
{
pia6821_device *pia = machine().device<pia6821_device>("pia0");
m_v493_irq_state = pia->irq_a_state() | pia->irq_b_state();
update_mcr68_interrupts();
}
TIMER_CALLBACK_MEMBER(mcr68_state::zwackery_493_off_callback)
{
pia6821_device *pia = machine().device<pia6821_device>("pia0");
pia->ca1_w(0);
}
TIMER_CALLBACK_MEMBER(mcr68_state::zwackery_493_callback)
{
pia6821_device *pia = machine().device<pia6821_device>("pia0");
pia->ca1_w(1);
machine().scheduler().timer_set(m_screen->scan_period(), timer_expired_delegate(FUNC(mcr68_state::zwackery_493_off_callback),this));
}

View File

@ -19765,7 +19765,6 @@ spyhunt2 // (c) 1987
spyhunt2a // (c) 1987
trisport // (c) 1989
xenophob // (c) 1987
zwackery // (c) 1984
@source:meadows.cpp
bowl3d // [1978?]
@ -37979,6 +37978,9 @@ zrt80 //
@source:zsbc3.cpp
zsbc3 //
@source:zwackery.cpp
zwackery // (c) 1984
@source:zx.cpp
lambda // Lambda 8300
pc8300 // Your Computer - PC8300

View File

@ -31,25 +31,6 @@ TILE_GET_INFO_MEMBER(mcr68_state::get_bg_tile_info)
}
TILE_GET_INFO_MEMBER(mcr68_state::zwackery_get_bg_tile_info)
{
uint16_t *videoram = m_videoram;
int data = videoram[tile_index];
int color = (data >> 13) & 7;
SET_TILE_INFO_MEMBER(0, data & 0x3ff, color, TILE_FLIPYX(data >> 11));
}
TILE_GET_INFO_MEMBER(mcr68_state::zwackery_get_fg_tile_info)
{
uint16_t *videoram = m_videoram;
int data = videoram[tile_index];
int color = (data >> 13) & 7;
SET_TILE_INFO_MEMBER(2, data & 0x3ff, color, TILE_FLIPYX(data >> 11));
tileinfo.category = (color != 0);
}
/*************************************
*
@ -65,70 +46,6 @@ VIDEO_START_MEMBER(mcr68_state,mcr68)
}
VIDEO_START_MEMBER(mcr68_state,zwackery)
{
const uint8_t *colordatabase = (const uint8_t *)memregion("gfx3")->base();
gfx_element *gfx0 = m_gfxdecode->gfx(0);
gfx_element *gfx2 = m_gfxdecode->gfx(2);
uint8_t *dest0;
uint8_t *dest2;
int code, y, x;
/* initialize the background tilemap */
m_bg_tilemap = &machine().tilemap().create(*m_gfxdecode, tilemap_get_info_delegate(FUNC(mcr68_state::zwackery_get_bg_tile_info),this), TILEMAP_SCAN_ROWS, 16,16, 32,32);
/* initialize the foreground tilemap */
m_fg_tilemap = &machine().tilemap().create(*m_gfxdecode, tilemap_get_info_delegate(FUNC(mcr68_state::zwackery_get_fg_tile_info),this), TILEMAP_SCAN_ROWS, 16,16, 32,32);
m_fg_tilemap->set_transparent_pen(0);
/* allocate memory for the assembled gfx data */
m_srcdata0 = std::make_unique<uint8_t[]>(gfx0->elements() * gfx0->width() * gfx0->height());
m_srcdata2 = std::make_unique<uint8_t[]>(gfx2->elements() * gfx2->width() * gfx2->height());
/* "colorize" each code */
dest0 = m_srcdata0.get();
dest2 = m_srcdata2.get();
for (code = 0; code < gfx0->elements(); code++)
{
const uint8_t *coldata = colordatabase + code * 32;
const uint8_t *gfxdata0 = gfx0->get_data(code);
const uint8_t *gfxdata2 = gfx2->get_data(code);
/* assume 16 rows */
for (y = 0; y < 16; y++)
{
const uint8_t *gd0 = gfxdata0;
const uint8_t *gd2 = gfxdata2;
/* 16 columns */
for (x = 0; x < 16; x++, gd0++, gd2++)
{
int coloffs = (y & 0x0c) | ((x >> 2) & 0x03);
int pen0 = coldata[coloffs * 2 + 0];
int pen1 = coldata[coloffs * 2 + 1];
int tp0, tp1;
/* every 4 pixels gets its own foreground/background colors */
*dest0++ = *gd0 ? pen1 : pen0;
/* for gfx 2, we convert all low-priority pens to 0 */
tp0 = (pen0 & 0x80) ? pen0 : 0;
tp1 = (pen1 & 0x80) ? pen1 : 0;
*dest2++ = *gd2 ? tp1 : tp0;
}
/* advance */
gfxdata0 += gfx0->rowbytes();
gfxdata2 += gfx2->rowbytes();
}
}
/* make the assembled data our new source data */
gfx0->set_raw_layout(m_srcdata0.get(), gfx0->width(), gfx0->height(), gfx0->elements(), 8 * gfx0->width(), 8 * gfx0->width() * gfx0->height());
gfx2->set_raw_layout(m_srcdata2.get(), gfx2->width(), gfx2->height(), gfx2->elements(), 8 * gfx2->width(), 8 * gfx2->width() * gfx2->height());
}
/*************************************
*
@ -144,24 +61,6 @@ WRITE16_MEMBER(mcr68_state::mcr68_videoram_w)
}
WRITE16_MEMBER(mcr68_state::zwackery_videoram_w)
{
uint16_t *videoram = m_videoram;
COMBINE_DATA(&videoram[offset]);
m_bg_tilemap->mark_tile_dirty(offset);
m_fg_tilemap->mark_tile_dirty(offset);
}
WRITE16_MEMBER(mcr68_state::zwackery_spriteram_w)
{
/* yech -- Zwackery relies on the upper 8 bits of a spriteram read being $ff! */
/* to make this happen we always write $ff in the upper 8 bits */
COMBINE_DATA(&m_spriteram[offset]);
m_spriteram[offset] |= 0xff00;
}
/*************************************
*
@ -222,63 +121,6 @@ void mcr68_state::mcr68_update_sprites(screen_device &screen, bitmap_ind16 &bitm
}
void mcr68_state::zwackery_update_sprites(screen_device &screen, bitmap_ind16 &bitmap, const rectangle &cliprect, int priority)
{
uint16_t *spriteram = m_spriteram;
int offs;
screen.priority().fill(1, cliprect);
/* loop over sprite RAM */
for (offs = m_spriteram.bytes() / 2 - 4;offs >= 0;offs -= 4)
{
int code, color, flipx, flipy, x, y, flags;
/* get the code and skip if zero */
code = LOW_BYTE(spriteram[offs + 2]);
if (code == 0)
continue;
/* extract the flag bits and determine the color */
flags = LOW_BYTE(spriteram[offs + 1]);
color = ((~flags >> 2) & 0x0f) | ((flags & 0x02) << 3);
/* for low priority, draw everything but color 7 */
if (!priority)
{
if (color == 7)
continue;
}
/* for high priority, only draw color 7 */
else
{
if (color != 7)
continue;
}
/* determine flipping and coordinates */
flipx = ~flags & 0x40;
flipy = flags & 0x80;
x = (231 - LOW_BYTE(spriteram[offs + 3])) * 2;
y = (241 - LOW_BYTE(spriteram[offs])) * 2;
if (x <= -32) x += 512;
/* sprites use color 0 for background pen and 8 for the 'under tile' pen.
The color 8 is used to cover over other sprites. */
/* first draw the sprite, visible */
m_gfxdecode->gfx(1)->prio_transmask(bitmap,cliprect, code, color, flipx, flipy, x, y,
screen.priority(), 0x00, 0x0101);
/* then draw the mask, behind the background but obscuring following sprites */
m_gfxdecode->gfx(1)->prio_transmask(bitmap,cliprect, code, color, flipx, flipy, x, y,
screen.priority(), 0x02, 0xfeff);
}
}
/*************************************
*
@ -301,20 +143,3 @@ uint32_t mcr68_state::screen_update_mcr68(screen_device &screen, bitmap_ind16 &b
mcr68_update_sprites(screen, bitmap, cliprect, 1);
return 0;
}
uint32_t mcr68_state::screen_update_zwackery(screen_device &screen, bitmap_ind16 &bitmap, const rectangle &cliprect)
{
/* draw the background */
m_bg_tilemap->draw(screen, bitmap, cliprect, 0, 0);
/* draw the low-priority sprites */
zwackery_update_sprites(screen, bitmap, cliprect, 0);
/* redraw tiles with priority over sprites */
m_fg_tilemap->draw(screen, bitmap, cliprect, 1, 0);
/* draw the high-priority sprites */
zwackery_update_sprites(screen, bitmap, cliprect, 1);
return 0;
}