mirror of
https://github.com/holub/mame
synced 2025-04-23 08:49:55 +03:00
atari/ultratnk.cpp, atari/vindictr.cpp, atari/xybots.cpp: consolidated drivers in single files
This commit is contained in:
parent
5f85581eb7
commit
ffc3454fb9
@ -7,22 +7,235 @@ Atari Ultra Tank driver
|
||||
***************************************************************************/
|
||||
|
||||
#include "emu.h"
|
||||
#include "ultratnk.h"
|
||||
|
||||
#include "sprint4_a.h"
|
||||
|
||||
#include "cpu/m6502/m6502.h"
|
||||
#include "machine/74259.h"
|
||||
#include "machine/watchdog.h"
|
||||
#include "sound/discrete.h"
|
||||
|
||||
#include "emupal.h"
|
||||
#include "screen.h"
|
||||
#include "speaker.h"
|
||||
|
||||
#define MASTER_CLOCK XTAL(12'096'000)
|
||||
|
||||
#define HTOTAL 384
|
||||
#define VTOTAL 262
|
||||
|
||||
#define PIXEL_CLOCK (MASTER_CLOCK / 2)
|
||||
#include "tilemap.h"
|
||||
|
||||
|
||||
namespace {
|
||||
|
||||
class ultratnk_state : public driver_device
|
||||
{
|
||||
public:
|
||||
ultratnk_state(const machine_config &mconfig, device_type type, const char *tag) :
|
||||
driver_device(mconfig, type, tag),
|
||||
m_maincpu(*this, "maincpu"),
|
||||
m_watchdog(*this, "watchdog"),
|
||||
m_discrete(*this, "discrete"),
|
||||
m_gfxdecode(*this, "gfxdecode"),
|
||||
m_screen(*this, "screen"),
|
||||
m_palette(*this, "palette"),
|
||||
m_videoram(*this, "videoram"),
|
||||
m_joy(*this, "JOY-%c", 'W'),
|
||||
m_in0(*this, "IN0"),
|
||||
m_analog(*this, "ANALOG"),
|
||||
m_coin(*this, "COIN"),
|
||||
m_collision_port(*this, "COLLISION"),
|
||||
m_dip(*this, "DIP")
|
||||
{ }
|
||||
|
||||
template <int N> DECLARE_READ_LINE_MEMBER(collision_flipflop_r);
|
||||
template <int N> DECLARE_READ_LINE_MEMBER(joystick_r);
|
||||
void ultratnk(machine_config &config);
|
||||
|
||||
protected:
|
||||
virtual void machine_start() override;
|
||||
virtual void machine_reset() override;
|
||||
virtual void video_start() override;
|
||||
|
||||
private:
|
||||
required_device<cpu_device> m_maincpu;
|
||||
required_device<watchdog_timer_device> m_watchdog;
|
||||
required_device<discrete_device> m_discrete;
|
||||
required_device<gfxdecode_device> m_gfxdecode;
|
||||
required_device<screen_device> m_screen;
|
||||
required_device<palette_device> m_palette;
|
||||
|
||||
required_shared_ptr<uint8_t> m_videoram;
|
||||
|
||||
required_ioport_array<4> m_joy;
|
||||
required_ioport m_in0;
|
||||
required_ioport m_analog;
|
||||
required_ioport m_coin;
|
||||
required_ioport m_collision_port;
|
||||
required_ioport m_dip;
|
||||
|
||||
uint8_t m_da_latch = 0;
|
||||
uint8_t m_collision[4]{};
|
||||
tilemap_t* m_playfield = nullptr;
|
||||
bitmap_ind16 m_helper;
|
||||
emu_timer *m_nmi_timer = nullptr;
|
||||
|
||||
static constexpr int HTOTAL = 384;
|
||||
static constexpr int VTOTAL = 262;
|
||||
|
||||
uint8_t wram_r(offs_t offset);
|
||||
uint8_t analog_r(offs_t offset);
|
||||
uint8_t coin_r(offs_t offset);
|
||||
uint8_t collision_r(offs_t offset);
|
||||
uint8_t options_r(offs_t offset);
|
||||
void wram_w(offs_t offset, uint8_t data);
|
||||
void collision_reset_w(offs_t offset, uint8_t data);
|
||||
void da_latch_w(uint8_t data);
|
||||
DECLARE_WRITE_LINE_MEMBER(lockout_w);
|
||||
void video_ram_w(offs_t offset, uint8_t data);
|
||||
void attract_w(uint8_t data);
|
||||
void explosion_w(uint8_t data);
|
||||
|
||||
void palette(palette_device &palette) const;
|
||||
|
||||
TILE_GET_INFO_MEMBER(tile_info);
|
||||
uint32_t screen_update(screen_device &screen, bitmap_ind16 &bitmap, const rectangle &cliprect);
|
||||
DECLARE_WRITE_LINE_MEMBER(screen_vblank);
|
||||
TIMER_CALLBACK_MEMBER(nmi_callback);
|
||||
|
||||
void cpu_map(address_map &map);
|
||||
};
|
||||
|
||||
|
||||
// video
|
||||
|
||||
void ultratnk_state::palette(palette_device &palette) const
|
||||
{
|
||||
const uint8_t *color_prom = memregion("proms")->base();
|
||||
|
||||
palette.set_indirect_color(0, rgb_t(0x00, 0x00, 0x00));
|
||||
palette.set_indirect_color(1, rgb_t(0xa4, 0xa4, 0xa4));
|
||||
palette.set_indirect_color(2, rgb_t(0x5b, 0x5b, 0x5b));
|
||||
palette.set_indirect_color(3, rgb_t(0xff, 0xff, 0xff));
|
||||
|
||||
palette.set_pen_indirect(0, color_prom[0x00] & 3);
|
||||
palette.set_pen_indirect(2, color_prom[0x00] & 3);
|
||||
palette.set_pen_indirect(4, color_prom[0x00] & 3);
|
||||
palette.set_pen_indirect(6, color_prom[0x00] & 3);
|
||||
palette.set_pen_indirect(8, color_prom[0x00] & 3);
|
||||
|
||||
palette.set_pen_indirect(1, color_prom[0x01] & 3);
|
||||
palette.set_pen_indirect(3, color_prom[0x02] & 3);
|
||||
palette.set_pen_indirect(5, color_prom[0x04] & 3);
|
||||
palette.set_pen_indirect(7, color_prom[0x08] & 3);
|
||||
palette.set_pen_indirect(9, color_prom[0x10] & 3);
|
||||
}
|
||||
|
||||
|
||||
TILE_GET_INFO_MEMBER(ultratnk_state::tile_info)
|
||||
{
|
||||
uint8_t const code = m_videoram[tile_index];
|
||||
|
||||
if (code & 0x20)
|
||||
tileinfo.set(0, code, code >> 6, 0);
|
||||
else
|
||||
tileinfo.set(0, code, 4, 0);
|
||||
}
|
||||
|
||||
|
||||
void ultratnk_state::video_start()
|
||||
{
|
||||
m_screen->register_screen_bitmap(m_helper);
|
||||
|
||||
m_playfield = &machine().tilemap().create(*m_gfxdecode, tilemap_get_info_delegate(*this, FUNC(ultratnk_state::tile_info)), TILEMAP_SCAN_ROWS, 8, 8, 32, 32);
|
||||
|
||||
std::fill(std::begin(m_collision), std::end(m_collision), 0);
|
||||
}
|
||||
|
||||
|
||||
uint32_t ultratnk_state::screen_update(screen_device &screen, bitmap_ind16 &bitmap, const rectangle &cliprect)
|
||||
{
|
||||
m_playfield->draw(screen, bitmap, cliprect, 0, 0);
|
||||
|
||||
for (int i = 0; i < 4; i++)
|
||||
{
|
||||
int bank = 0;
|
||||
|
||||
uint8_t horz = m_videoram[0x390 + 2 * i + 0];
|
||||
uint8_t attr = m_videoram[0x390 + 2 * i + 1];
|
||||
uint8_t vert = m_videoram[0x398 + 2 * i + 0];
|
||||
uint8_t code = m_videoram[0x398 + 2 * i + 1];
|
||||
|
||||
if (code & 4)
|
||||
bank = 32;
|
||||
|
||||
if (!(attr & 0x80))
|
||||
{
|
||||
m_gfxdecode->gfx(1)->transpen(bitmap, cliprect,
|
||||
(code >> 3) | bank,
|
||||
i,
|
||||
0, 0,
|
||||
horz - 15,
|
||||
vert - 15, 0);
|
||||
}
|
||||
}
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
|
||||
WRITE_LINE_MEMBER(ultratnk_state::screen_vblank)
|
||||
{
|
||||
// rising edge
|
||||
if (state)
|
||||
{
|
||||
uint16_t const bg = m_palette->pen_indirect(0);
|
||||
|
||||
// check for sprite-playfield collisions
|
||||
|
||||
for (int i = 0; i < 4; i++)
|
||||
{
|
||||
int bank = 0;
|
||||
|
||||
uint8_t horz = m_videoram[0x390 + 2 * i + 0];
|
||||
uint8_t vert = m_videoram[0x398 + 2 * i + 0];
|
||||
uint8_t code = m_videoram[0x398 + 2 * i + 1];
|
||||
|
||||
rectangle rect(
|
||||
horz - 15,
|
||||
horz - 15 + m_gfxdecode->gfx(1)->width() - 1,
|
||||
vert - 15,
|
||||
vert - 15 + m_gfxdecode->gfx(1)->height() - 1);
|
||||
rect &= m_screen->visible_area();
|
||||
|
||||
m_playfield->draw(*m_screen, m_helper, rect, 0, 0);
|
||||
|
||||
if (code & 4)
|
||||
bank = 32;
|
||||
|
||||
m_gfxdecode->gfx(1)->transpen(m_helper, rect,
|
||||
(code >> 3) | bank,
|
||||
4,
|
||||
0, 0,
|
||||
horz - 15,
|
||||
vert - 15, 1);
|
||||
|
||||
for (int y = rect.top(); y <= rect.bottom(); y++)
|
||||
for (int x = rect.left(); x <= rect.right(); x++)
|
||||
if (m_palette->pen_indirect(m_helper.pix(y, x)) != bg)
|
||||
m_collision[i] = 1;
|
||||
}
|
||||
|
||||
// update sound status
|
||||
m_discrete->write(ULTRATNK_MOTOR_DATA_1, m_videoram[0x391] & 15);
|
||||
m_discrete->write(ULTRATNK_MOTOR_DATA_2, m_videoram[0x393] & 15);
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
void ultratnk_state::video_ram_w(offs_t offset, uint8_t data)
|
||||
{
|
||||
m_videoram[offset] = data;
|
||||
m_playfield->mark_tile_dirty(offset);
|
||||
}
|
||||
|
||||
|
||||
// machine
|
||||
|
||||
template <int N>
|
||||
READ_LINE_MEMBER(ultratnk_state::collision_flipflop_r)
|
||||
@ -34,7 +247,7 @@ READ_LINE_MEMBER(ultratnk_state::collision_flipflop_r)
|
||||
template <int N>
|
||||
READ_LINE_MEMBER(ultratnk_state::joystick_r)
|
||||
{
|
||||
uint8_t joy = m_joy[N]->read() & 3;
|
||||
uint8_t const joy = m_joy[N]->read() & 3;
|
||||
|
||||
if (joy == 1)
|
||||
{
|
||||
@ -56,11 +269,11 @@ TIMER_CALLBACK_MEMBER(ultratnk_state::nmi_callback)
|
||||
if (scanline >= VTOTAL)
|
||||
scanline = 32;
|
||||
|
||||
/* NMI and watchdog are disabled during service mode */
|
||||
// NMI and watchdog are disabled during service mode
|
||||
|
||||
m_watchdog->watchdog_enable(ioport("IN0")->read() & 0x40);
|
||||
m_watchdog->watchdog_enable(m_in0->read() & 0x40);
|
||||
|
||||
if (ioport("IN0")->read() & 0x40)
|
||||
if (m_in0->read() & 0x40)
|
||||
m_maincpu->pulse_input_line(INPUT_LINE_NMI, attotime::zero);
|
||||
|
||||
m_nmi_timer->adjust(m_screen->time_until_pos(scanline), scanline);
|
||||
@ -90,21 +303,23 @@ uint8_t ultratnk_state::wram_r(offs_t offset)
|
||||
|
||||
uint8_t ultratnk_state::analog_r(offs_t offset)
|
||||
{
|
||||
return (ioport("ANALOG")->read() << (~offset & 7)) & 0x80;
|
||||
return (m_analog->read() << (~offset & 7)) & 0x80;
|
||||
}
|
||||
|
||||
uint8_t ultratnk_state::coin_r(offs_t offset)
|
||||
{
|
||||
return (ioport("COIN")->read() << (~offset & 7)) & 0x80;
|
||||
return (m_coin->read() << (~offset & 7)) & 0x80;
|
||||
}
|
||||
|
||||
uint8_t ultratnk_state::collision_r(offs_t offset)
|
||||
{
|
||||
return (ioport("COLLISION")->read() << (~offset & 7)) & 0x80;
|
||||
return (m_collision_port->read() << (~offset & 7)) & 0x80;
|
||||
}
|
||||
|
||||
|
||||
uint8_t ultratnk_state::options_r(offs_t offset)
|
||||
{
|
||||
return (ioport("DIP")->read() >> (2 * (offset & 3))) & 3;
|
||||
return (m_dip->read() >> (2 * (offset & 3))) & 3;
|
||||
}
|
||||
|
||||
|
||||
@ -136,20 +351,21 @@ void ultratnk_state::attract_w(uint8_t data)
|
||||
{
|
||||
m_discrete->write(ULTRATNK_ATTRACT_EN, data & 1);
|
||||
}
|
||||
|
||||
void ultratnk_state::explosion_w(uint8_t data)
|
||||
{
|
||||
m_discrete->write(ULTRATNK_EXPLOSION_DATA, data & 15);
|
||||
}
|
||||
|
||||
|
||||
void ultratnk_state::ultratnk_cpu_map(address_map &map)
|
||||
void ultratnk_state::cpu_map(address_map &map)
|
||||
{
|
||||
|
||||
map.global_mask(0x3fff);
|
||||
|
||||
map(0x0000, 0x007f).mirror(0x700).ram();
|
||||
map(0x0080, 0x00ff).mirror(0x700).rw(FUNC(ultratnk_state::wram_r), FUNC(ultratnk_state::wram_w));
|
||||
map(0x0800, 0x0bff).mirror(0x400).ram().w(FUNC(ultratnk_state::video_ram_w)).share("videoram");
|
||||
map(0x0800, 0x0bff).mirror(0x400).ram().w(FUNC(ultratnk_state::video_ram_w)).share(m_videoram);
|
||||
|
||||
map(0x1000, 0x17ff).portr("IN0");
|
||||
map(0x1800, 0x1fff).portr("IN1");
|
||||
@ -166,7 +382,7 @@ void ultratnk_state::ultratnk_cpu_map(address_map &map)
|
||||
map(0x2044, 0x2045).mirror(0x718).w(m_watchdog, FUNC(watchdog_timer_device::reset_w));
|
||||
map(0x2060, 0x206f).mirror(0x710).w("latch", FUNC(f9334_device::write_a0));
|
||||
|
||||
map(0x2800, 0x2fff).noprw(); /* diagnostic ROM */
|
||||
map(0x2800, 0x2fff).noprw(); // diagnostic ROM
|
||||
map(0x3000, 0x3fff).rom();
|
||||
|
||||
}
|
||||
@ -275,16 +491,20 @@ static const gfx_layout motion_layout =
|
||||
|
||||
|
||||
static GFXDECODE_START( gfx_ultratnk )
|
||||
GFXDECODE_ENTRY( "gfx1", 0, gfx_8x8x1, 0, 5 )
|
||||
GFXDECODE_ENTRY( "gfx2", 0, motion_layout, 0, 5 )
|
||||
GFXDECODE_ENTRY( "playfield", 0, gfx_8x8x1, 0, 5 )
|
||||
GFXDECODE_ENTRY( "motion", 0, motion_layout, 0, 5 )
|
||||
GFXDECODE_END
|
||||
|
||||
|
||||
|
||||
void ultratnk_state::ultratnk(machine_config &config)
|
||||
{
|
||||
/* basic machine hardware */
|
||||
static constexpr XTAL MASTER_CLOCK = XTAL(12'096'000);
|
||||
static constexpr XTAL PIXEL_CLOCK = (MASTER_CLOCK / 2);
|
||||
|
||||
// basic machine hardware
|
||||
M6502(config, m_maincpu, PIXEL_CLOCK / 8);
|
||||
m_maincpu->set_addrmap(AS_PROGRAM, &ultratnk_state::ultratnk_cpu_map);
|
||||
m_maincpu->set_addrmap(AS_PROGRAM, &ultratnk_state::cpu_map);
|
||||
|
||||
f9334_device &latch(F9334(config, "latch")); // E11
|
||||
latch.q_out_cb<3>().set(FUNC(ultratnk_state::lockout_w));
|
||||
@ -295,7 +515,7 @@ void ultratnk_state::ultratnk(machine_config &config)
|
||||
|
||||
WATCHDOG_TIMER(config, m_watchdog).set_vblank_count(m_screen, 8);
|
||||
|
||||
/* video hardware */
|
||||
// video hardware
|
||||
SCREEN(config, m_screen, SCREEN_TYPE_RASTER);
|
||||
m_screen->set_raw(PIXEL_CLOCK, HTOTAL, 0, 256, VTOTAL, 0, 224);
|
||||
m_screen->set_screen_update(FUNC(ultratnk_state::screen_update));
|
||||
@ -303,9 +523,9 @@ void ultratnk_state::ultratnk(machine_config &config)
|
||||
m_screen->set_palette(m_palette);
|
||||
|
||||
GFXDECODE(config, m_gfxdecode, m_palette, gfx_ultratnk);
|
||||
PALETTE(config, m_palette, FUNC(ultratnk_state::ultratnk_palette), 10, 4);
|
||||
PALETTE(config, m_palette, FUNC(ultratnk_state::palette), 10, 4);
|
||||
|
||||
/* sound hardware */
|
||||
// sound hardware
|
||||
SPEAKER(config, "mono").front_center();
|
||||
|
||||
DISCRETE(config, m_discrete, ultratnk_discrete).add_route(0, "mono", 1.0);
|
||||
@ -314,16 +534,16 @@ void ultratnk_state::ultratnk(machine_config &config)
|
||||
|
||||
ROM_START( ultratnk )
|
||||
ROM_REGION( 0x4000, "maincpu", 0 )
|
||||
ROM_LOAD_NIB_LOW ( "030180.n1", 0x3000, 0x0800, CRC(b6aa6056) SHA1(6de094017b5d87a238053fac88129d20260f8222) ) /* ROM 3 */
|
||||
ROM_LOAD_NIB_HIGH( "030181.k1", 0x3000, 0x0800, CRC(17145c97) SHA1(afe0c9c562c27cd1fba57ea83377b0a4c12496db) ) /* ROM 3 */
|
||||
ROM_LOAD_NIB_LOW ( "030182.m1", 0x3800, 0x0800, CRC(034366a2) SHA1(dc289ce4c79e9937977ca8804ce07b4c8e40e969) ) /* ROM 4 */
|
||||
ROM_LOAD_NIB_HIGH( "030183.l1", 0x3800, 0x0800, CRC(be141602) SHA1(17aad9bab9bf6bd22dc3c2214b049bbd68c87380) ) /* ROM 4 */
|
||||
ROM_LOAD_NIB_LOW ( "030180.n1", 0x3000, 0x0800, CRC(b6aa6056) SHA1(6de094017b5d87a238053fac88129d20260f8222) ) // ROM 3
|
||||
ROM_LOAD_NIB_HIGH( "030181.k1", 0x3000, 0x0800, CRC(17145c97) SHA1(afe0c9c562c27cd1fba57ea83377b0a4c12496db) ) // ROM 3
|
||||
ROM_LOAD_NIB_LOW ( "030182.m1", 0x3800, 0x0800, CRC(034366a2) SHA1(dc289ce4c79e9937977ca8804ce07b4c8e40e969) ) // ROM 4
|
||||
ROM_LOAD_NIB_HIGH( "030183.l1", 0x3800, 0x0800, CRC(be141602) SHA1(17aad9bab9bf6bd22dc3c2214b049bbd68c87380) ) // ROM 4
|
||||
|
||||
ROM_REGION( 0x0200, "gfx1", 0 ) /* playfield */
|
||||
ROM_REGION( 0x0200, "playfield", 0 )
|
||||
ROM_LOAD_NIB_HIGH( "30172-01.j6", 0x0000, 0x0200, CRC(1d364b23) SHA1(44c5792ed3f33f40cd8632718b0e82152559ecdf) )
|
||||
ROM_LOAD_NIB_LOW ( "30173-01.h6", 0x0000, 0x0200, CRC(5c32f331) SHA1(c1d675891490fbc533eaa0da57545398d7325df8) )
|
||||
|
||||
ROM_REGION( 0x1000, "gfx2", 0 ) /* motion */
|
||||
ROM_REGION( 0x1000, "motion", 0 )
|
||||
ROM_LOAD( "30174-01.n6", 0x0000, 0x0400, CRC(d0e20e73) SHA1(0df1ed4a73255032bb809fb4d0a4bf3f151c749d) )
|
||||
ROM_LOAD( "30175-01.m6", 0x0400, 0x0400, CRC(a47459c9) SHA1(4ca92edc172fbac923ba71731a25546c04ffc7b0) )
|
||||
ROM_LOAD( "30176-01.l6", 0x0800, 0x0400, CRC(1cc7c2dd) SHA1(7f8aebe8375751183afeae35ea2d241d22ee7a4f) )
|
||||
@ -332,9 +552,11 @@ ROM_START( ultratnk )
|
||||
ROM_REGION( 0x0020, "proms", 0 )
|
||||
ROM_LOAD( "30218-01.j10", 0x0000, 0x0020, CRC(d7a2c7b4) SHA1(7453921ecb6268b604dee3743f6e217db19c9871) )
|
||||
|
||||
ROM_REGION( 0x0200, "user1", 0 )
|
||||
ROM_LOAD( "30024-01.p8", 0x0000, 0x0200, CRC(e71d2e22) SHA1(434c3a8237468604cce7feb40e6061d2670013b3) ) /* SYNC */
|
||||
ROM_REGION( 0x0200, "sync_prom", 0 )
|
||||
ROM_LOAD( "30024-01.p8", 0x0000, 0x0200, CRC(e71d2e22) SHA1(434c3a8237468604cce7feb40e6061d2670013b3) ) // SYNC
|
||||
ROM_END
|
||||
|
||||
} // anonymous namespace
|
||||
|
||||
|
||||
GAME( 1978, ultratnk, 0, ultratnk, ultratnk, ultratnk_state, empty_init, ROT0, "Atari (Kee Games)", "Ultra Tank", MACHINE_SUPPORTS_SAVE )
|
||||
|
@ -1,84 +0,0 @@
|
||||
// license:BSD-3-Clause
|
||||
// copyright-holders:Phil Stroffolino, Stefan Jokisch
|
||||
/*************************************************************************
|
||||
|
||||
Atari Ultra Tank hardware
|
||||
|
||||
*************************************************************************/
|
||||
#ifndef MAME_ATARI_ULTRATNK_H
|
||||
#define MAME_ATARI_ULTRATNK_H
|
||||
|
||||
#pragma once
|
||||
|
||||
#include "machine/watchdog.h"
|
||||
#include "sound/discrete.h"
|
||||
#include "emupal.h"
|
||||
#include "screen.h"
|
||||
#include "tilemap.h"
|
||||
|
||||
class ultratnk_state : public driver_device
|
||||
{
|
||||
public:
|
||||
ultratnk_state(const machine_config &mconfig, device_type type, const char *tag) :
|
||||
driver_device(mconfig, type, tag),
|
||||
m_maincpu(*this, "maincpu"),
|
||||
m_watchdog(*this, "watchdog"),
|
||||
m_discrete(*this, "discrete"),
|
||||
m_gfxdecode(*this, "gfxdecode"),
|
||||
m_screen(*this, "screen"),
|
||||
m_palette(*this, "palette"),
|
||||
m_videoram(*this, "videoram"),
|
||||
m_joy(*this, "JOY-%c", 'W')
|
||||
{ }
|
||||
|
||||
template <int N> DECLARE_READ_LINE_MEMBER(collision_flipflop_r);
|
||||
template <int N> DECLARE_READ_LINE_MEMBER(joystick_r);
|
||||
void ultratnk(machine_config &config);
|
||||
|
||||
protected:
|
||||
virtual void machine_start() override;
|
||||
virtual void machine_reset() override;
|
||||
virtual void video_start() override;
|
||||
|
||||
private:
|
||||
uint8_t wram_r(offs_t offset);
|
||||
uint8_t analog_r(offs_t offset);
|
||||
uint8_t coin_r(offs_t offset);
|
||||
uint8_t collision_r(offs_t offset);
|
||||
uint8_t options_r(offs_t offset);
|
||||
void wram_w(offs_t offset, uint8_t data);
|
||||
void collision_reset_w(offs_t offset, uint8_t data);
|
||||
void da_latch_w(uint8_t data);
|
||||
DECLARE_WRITE_LINE_MEMBER(lockout_w);
|
||||
void video_ram_w(offs_t offset, uint8_t data);
|
||||
void attract_w(uint8_t data);
|
||||
void explosion_w(uint8_t data);
|
||||
|
||||
void ultratnk_palette(palette_device &palette) const;
|
||||
|
||||
TILE_GET_INFO_MEMBER(tile_info);
|
||||
uint32_t screen_update(screen_device &screen, bitmap_ind16 &bitmap, const rectangle &cliprect);
|
||||
DECLARE_WRITE_LINE_MEMBER(screen_vblank);
|
||||
TIMER_CALLBACK_MEMBER(nmi_callback);
|
||||
|
||||
void ultratnk_cpu_map(address_map &map);
|
||||
|
||||
required_device<cpu_device> m_maincpu;
|
||||
required_device<watchdog_timer_device> m_watchdog;
|
||||
required_device<discrete_device> m_discrete;
|
||||
required_device<gfxdecode_device> m_gfxdecode;
|
||||
required_device<screen_device> m_screen;
|
||||
required_device<palette_device> m_palette;
|
||||
|
||||
required_shared_ptr<uint8_t> m_videoram;
|
||||
|
||||
required_ioport_array<4> m_joy;
|
||||
|
||||
int m_da_latch = 0;
|
||||
int m_collision[4]{};
|
||||
tilemap_t* m_playfield = nullptr;
|
||||
bitmap_ind16 m_helper;
|
||||
emu_timer *m_nmi_timer = nullptr;
|
||||
};
|
||||
|
||||
#endif // MAME_ATARI_ULTRATNK_H
|
@ -1,142 +0,0 @@
|
||||
// license:BSD-3-Clause
|
||||
// copyright-holders:Phil Stroffolino, Stefan Jokisch
|
||||
/***************************************************************************
|
||||
|
||||
Atari Ultra Tank video emulation
|
||||
|
||||
***************************************************************************/
|
||||
|
||||
#include "emu.h"
|
||||
#include "ultratnk.h"
|
||||
#include "sprint4_a.h"
|
||||
|
||||
|
||||
void ultratnk_state::ultratnk_palette(palette_device &palette) const
|
||||
{
|
||||
const uint8_t *color_prom = memregion("proms")->base();
|
||||
|
||||
palette.set_indirect_color(0, rgb_t(0x00, 0x00, 0x00));
|
||||
palette.set_indirect_color(1, rgb_t(0xa4, 0xa4, 0xa4));
|
||||
palette.set_indirect_color(2, rgb_t(0x5b, 0x5b, 0x5b));
|
||||
palette.set_indirect_color(3, rgb_t(0xff, 0xff, 0xff));
|
||||
|
||||
palette.set_pen_indirect(0, color_prom[0x00] & 3);
|
||||
palette.set_pen_indirect(2, color_prom[0x00] & 3);
|
||||
palette.set_pen_indirect(4, color_prom[0x00] & 3);
|
||||
palette.set_pen_indirect(6, color_prom[0x00] & 3);
|
||||
palette.set_pen_indirect(8, color_prom[0x00] & 3);
|
||||
|
||||
palette.set_pen_indirect(1, color_prom[0x01] & 3);
|
||||
palette.set_pen_indirect(3, color_prom[0x02] & 3);
|
||||
palette.set_pen_indirect(5, color_prom[0x04] & 3);
|
||||
palette.set_pen_indirect(7, color_prom[0x08] & 3);
|
||||
palette.set_pen_indirect(9, color_prom[0x10] & 3);
|
||||
}
|
||||
|
||||
|
||||
TILE_GET_INFO_MEMBER(ultratnk_state::tile_info)
|
||||
{
|
||||
uint8_t code = m_videoram[tile_index];
|
||||
|
||||
if (code & 0x20)
|
||||
tileinfo.set(0, code, code >> 6, 0);
|
||||
else
|
||||
tileinfo.set(0, code, 4, 0);
|
||||
}
|
||||
|
||||
|
||||
void ultratnk_state::video_start()
|
||||
{
|
||||
m_screen->register_screen_bitmap(m_helper);
|
||||
|
||||
m_playfield = &machine().tilemap().create(*m_gfxdecode, tilemap_get_info_delegate(*this, FUNC(ultratnk_state::tile_info)), TILEMAP_SCAN_ROWS, 8, 8, 32, 32);
|
||||
|
||||
std::fill(std::begin(m_collision), std::end(m_collision), 0);
|
||||
}
|
||||
|
||||
|
||||
uint32_t ultratnk_state::screen_update(screen_device &screen, bitmap_ind16 &bitmap, const rectangle &cliprect)
|
||||
{
|
||||
m_playfield->draw(screen, bitmap, cliprect, 0, 0);
|
||||
|
||||
for (int i = 0; i < 4; i++)
|
||||
{
|
||||
int bank = 0;
|
||||
|
||||
uint8_t horz = m_videoram[0x390 + 2 * i + 0];
|
||||
uint8_t attr = m_videoram[0x390 + 2 * i + 1];
|
||||
uint8_t vert = m_videoram[0x398 + 2 * i + 0];
|
||||
uint8_t code = m_videoram[0x398 + 2 * i + 1];
|
||||
|
||||
if (code & 4)
|
||||
bank = 32;
|
||||
|
||||
if (!(attr & 0x80))
|
||||
{
|
||||
m_gfxdecode->gfx(1)->transpen(bitmap,cliprect,
|
||||
(code >> 3) | bank,
|
||||
i,
|
||||
0, 0,
|
||||
horz - 15,
|
||||
vert - 15, 0);
|
||||
}
|
||||
}
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
|
||||
WRITE_LINE_MEMBER(ultratnk_state::screen_vblank)
|
||||
{
|
||||
// rising edge
|
||||
if (state)
|
||||
{
|
||||
uint16_t BG = m_palette->pen_indirect(0);
|
||||
|
||||
/* check for sprite-playfield collisions */
|
||||
|
||||
for (int i = 0; i < 4; i++)
|
||||
{
|
||||
int bank = 0;
|
||||
|
||||
uint8_t horz = m_videoram[0x390 + 2 * i + 0];
|
||||
uint8_t vert = m_videoram[0x398 + 2 * i + 0];
|
||||
uint8_t code = m_videoram[0x398 + 2 * i + 1];
|
||||
|
||||
rectangle rect(
|
||||
horz - 15,
|
||||
horz - 15 + m_gfxdecode->gfx(1)->width() - 1,
|
||||
vert - 15,
|
||||
vert - 15 + m_gfxdecode->gfx(1)->height() - 1);
|
||||
rect &= m_screen->visible_area();
|
||||
|
||||
m_playfield->draw(*m_screen, m_helper, rect, 0, 0);
|
||||
|
||||
if (code & 4)
|
||||
bank = 32;
|
||||
|
||||
m_gfxdecode->gfx(1)->transpen(m_helper,rect,
|
||||
(code >> 3) | bank,
|
||||
4,
|
||||
0, 0,
|
||||
horz - 15,
|
||||
vert - 15, 1);
|
||||
|
||||
for (int y = rect.top(); y <= rect.bottom(); y++)
|
||||
for (int x = rect.left(); x <= rect.right(); x++)
|
||||
if (m_palette->pen_indirect(m_helper.pix(y, x)) != BG)
|
||||
m_collision[i] = 1;
|
||||
}
|
||||
|
||||
/* update sound status */
|
||||
m_discrete->write(ULTRATNK_MOTOR_DATA_1, m_videoram[0x391] & 15);
|
||||
m_discrete->write(ULTRATNK_MOTOR_DATA_2, m_videoram[0x393] & 15);
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
void ultratnk_state::video_ram_w(offs_t offset, uint8_t data)
|
||||
{
|
||||
m_videoram[offset] = data;
|
||||
m_playfield->mark_tile_dirty(offset);
|
||||
}
|
@ -20,14 +20,345 @@
|
||||
|
||||
|
||||
#include "emu.h"
|
||||
#include "vindictr.h"
|
||||
|
||||
#include "atarijsa.h"
|
||||
#include "atarimo.h"
|
||||
|
||||
#include "cpu/m68000/m68010.h"
|
||||
#include "machine/eeprompar.h"
|
||||
#include "machine/timer.h"
|
||||
#include "machine/watchdog.h"
|
||||
|
||||
#include "emupal.h"
|
||||
#include "screen.h"
|
||||
#include "speaker.h"
|
||||
#include "tilemap.h"
|
||||
|
||||
|
||||
namespace {
|
||||
|
||||
class vindictr_state : public driver_device
|
||||
{
|
||||
public:
|
||||
vindictr_state(const machine_config &mconfig, device_type type, const char *tag) :
|
||||
driver_device(mconfig, type, tag),
|
||||
m_maincpu(*this, "maincpu"),
|
||||
m_gfxdecode(*this, "gfxdecode"),
|
||||
m_screen(*this, "screen"),
|
||||
m_playfield_tilemap(*this, "playfield"),
|
||||
m_alpha_tilemap(*this, "alpha"),
|
||||
m_mob(*this, "mob"),
|
||||
m_jsa(*this, "jsa"),
|
||||
m_palette(*this, "palette"),
|
||||
m_paletteram(*this, "paletteram"),
|
||||
m_260010(*this, "260010")
|
||||
{ }
|
||||
|
||||
void vindictr(machine_config &config);
|
||||
|
||||
protected:
|
||||
virtual void video_start() override;
|
||||
|
||||
private:
|
||||
required_device<cpu_device> m_maincpu;
|
||||
required_device<gfxdecode_device> m_gfxdecode;
|
||||
required_device<screen_device> m_screen;
|
||||
required_device<tilemap_device> m_playfield_tilemap;
|
||||
required_device<tilemap_device> m_alpha_tilemap;
|
||||
required_device<atari_motion_objects_device> m_mob;
|
||||
required_device<atari_jsa_i_device> m_jsa;
|
||||
required_device<palette_device> m_palette;
|
||||
required_shared_ptr<uint16_t> m_paletteram;
|
||||
required_ioport m_260010;
|
||||
|
||||
uint8_t m_playfield_tile_bank = 0;
|
||||
uint16_t m_playfield_xscroll = 0;
|
||||
uint16_t m_playfield_yscroll = 0;
|
||||
|
||||
void scanline_interrupt();
|
||||
void scanline_int_ack_w(uint16_t data);
|
||||
TIMER_DEVICE_CALLBACK_MEMBER(scanline_update);
|
||||
uint16_t port1_r();
|
||||
TILE_GET_INFO_MEMBER(get_alpha_tile_info);
|
||||
TILE_GET_INFO_MEMBER(get_playfield_tile_info);
|
||||
uint32_t screen_update(screen_device &screen, bitmap_ind16 &bitmap, const rectangle &cliprect);
|
||||
void paletteram_w(offs_t offset, uint16_t data, uint16_t mem_mask = ~0);
|
||||
|
||||
static const atari_motion_objects_config s_mob_config;
|
||||
void main_map(address_map &map);
|
||||
};
|
||||
|
||||
|
||||
// video
|
||||
|
||||
/*************************************
|
||||
*
|
||||
* Tilemap callbacks
|
||||
*
|
||||
*************************************/
|
||||
|
||||
TILE_GET_INFO_MEMBER(vindictr_state::get_alpha_tile_info)
|
||||
{
|
||||
uint16_t const data = m_alpha_tilemap->basemem_read(tile_index);
|
||||
int const code = data & 0x3ff;
|
||||
int const color = ((data >> 10) & 0x0f) | ((data >> 9) & 0x20);
|
||||
int const opaque = data & 0x8000;
|
||||
tileinfo.set(1, code, color, opaque ? TILE_FORCE_LAYER0 : 0);
|
||||
}
|
||||
|
||||
|
||||
TILE_GET_INFO_MEMBER(vindictr_state::get_playfield_tile_info)
|
||||
{
|
||||
uint16_t const data = m_playfield_tilemap->basemem_read(tile_index);
|
||||
int const code = (m_playfield_tile_bank * 0x1000) + (data & 0xfff);
|
||||
int const color = 0x10 + 2 * ((data >> 12) & 7);
|
||||
tileinfo.set(0, code, color, (data >> 15) & 1);
|
||||
}
|
||||
|
||||
|
||||
|
||||
/*************************************
|
||||
*
|
||||
* Video system start
|
||||
*
|
||||
*************************************/
|
||||
|
||||
const atari_motion_objects_config vindictr_state::s_mob_config =
|
||||
{
|
||||
0, // index to which gfx system
|
||||
1, // number of motion object banks
|
||||
1, // are the entries linked?
|
||||
0, // are the entries split?
|
||||
0, // render in reverse order?
|
||||
0, // render in swapped X/Y order?
|
||||
0, // does the neighbor bit affect the next object?
|
||||
8, // pixels per SLIP entry (0 for no-slip)
|
||||
0, // pixel offset for SLIPs
|
||||
0, // maximum number of links to visit/scanline (0=all)
|
||||
|
||||
0x100, // base palette entry
|
||||
0x100, // maximum number of colors
|
||||
0, // transparent pen index
|
||||
|
||||
{{ 0,0,0,0x03ff }}, // mask for the link
|
||||
{{ 0x7fff,0,0,0 }}, // mask for the code index
|
||||
{{ 0,0x000f,0,0 }}, // mask for the color
|
||||
{{ 0,0xff80,0,0 }}, // mask for the X position
|
||||
{{ 0,0,0xff80,0 }}, // mask for the Y position
|
||||
{{ 0,0,0x0038,0 }}, // mask for the width, in tiles
|
||||
{{ 0,0,0x0007,0 }}, // mask for the height, in tiles
|
||||
{{ 0,0,0x0040,0 }}, // mask for the horizontal flip
|
||||
{{ 0 }}, // mask for the vertical flip
|
||||
{{ 0,0x0070,0,0 }}, // mask for the priority
|
||||
{{ 0 }}, // mask for the neighbor
|
||||
{{ 0 }}, // mask for absolute coordinates
|
||||
|
||||
{{ 0 }}, // mask for the special value
|
||||
0 // resulting value to indicate "special"
|
||||
};
|
||||
|
||||
void vindictr_state::video_start()
|
||||
{
|
||||
// save states
|
||||
save_item(NAME(m_playfield_tile_bank));
|
||||
save_item(NAME(m_playfield_xscroll));
|
||||
save_item(NAME(m_playfield_yscroll));
|
||||
}
|
||||
|
||||
|
||||
|
||||
/*************************************
|
||||
*
|
||||
* Palette RAM control
|
||||
*
|
||||
*************************************/
|
||||
|
||||
void vindictr_state::paletteram_w(offs_t offset, uint16_t data, uint16_t mem_mask)
|
||||
{
|
||||
static const int ztable[16] =
|
||||
{ 0x0, 0x3, 0x4, 0x5, 0x6, 0x7, 0x8, 0x9, 0xa, 0xb, 0xc, 0xd, 0xe, 0xf, 0x10, 0x11 };
|
||||
|
||||
// first blend the data
|
||||
COMBINE_DATA(&m_paletteram[offset]);
|
||||
data = m_paletteram[offset];
|
||||
|
||||
// now generate colors at all 16 intensities
|
||||
for (int c = 0; c < 8; c++)
|
||||
{
|
||||
int const i = ztable[((data >> 12) + (c * 2)) & 15];
|
||||
int const r = ((data >> 8) & 15) * i;
|
||||
int const g = ((data >> 4) & 15) * i;
|
||||
int const b = ((data >> 0) & 15) * i;
|
||||
|
||||
m_palette->set_pen_color(offset + c * 2048, rgb_t(r, g, b));
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
|
||||
/*************************************
|
||||
*
|
||||
* Periodic scanline updater
|
||||
*
|
||||
*************************************/
|
||||
|
||||
TIMER_DEVICE_CALLBACK_MEMBER(vindictr_state::scanline_update)
|
||||
{
|
||||
int const scanline = param;
|
||||
|
||||
// keep in range
|
||||
int offset = ((scanline - 8) / 8) * 64 + 42;
|
||||
if (offset < 0)
|
||||
offset += 0x7c0;
|
||||
else if (offset >= 0x7c0)
|
||||
return;
|
||||
|
||||
// update the current parameters
|
||||
for (int x = 42; x < 64; x++)
|
||||
{
|
||||
uint16_t const data = m_alpha_tilemap->basemem_read(offset++);
|
||||
|
||||
switch ((data >> 9) & 7)
|
||||
{
|
||||
case 2: // /PFB
|
||||
if (m_playfield_tile_bank != (data & 7))
|
||||
{
|
||||
m_screen->update_partial(scanline - 1);
|
||||
m_playfield_tile_bank = data & 7;
|
||||
m_playfield_tilemap->mark_all_dirty();
|
||||
}
|
||||
break;
|
||||
|
||||
case 3: // /PFHSLD
|
||||
if (m_playfield_xscroll != (data & 0x1ff))
|
||||
{
|
||||
m_screen->update_partial(scanline - 1);
|
||||
m_playfield_tilemap->set_scrollx(0, data);
|
||||
m_playfield_xscroll = data & 0x1ff;
|
||||
}
|
||||
break;
|
||||
|
||||
case 4: // /MOHS
|
||||
if (m_mob->xscroll() != (data & 0x1ff))
|
||||
{
|
||||
m_screen->update_partial(scanline - 1);
|
||||
m_mob->set_xscroll(data & 0x1ff);
|
||||
}
|
||||
break;
|
||||
|
||||
case 5: // /PFSPC
|
||||
break;
|
||||
|
||||
case 6: // /VIRQ
|
||||
scanline_interrupt();
|
||||
break;
|
||||
|
||||
case 7: // /PFVS
|
||||
{
|
||||
// a new vscroll latches the offset into a counter; we must adjust for this
|
||||
int offset = scanline;
|
||||
const rectangle &visible_area = m_screen->visible_area();
|
||||
if (offset > visible_area.bottom())
|
||||
offset -= visible_area.bottom() + 1;
|
||||
|
||||
if (m_playfield_yscroll != ((data - offset) & 0x1ff))
|
||||
{
|
||||
m_screen->update_partial(scanline - 1);
|
||||
m_playfield_tilemap->set_scrolly(0, data - offset);
|
||||
m_mob->set_yscroll((data - offset) & 0x1ff);
|
||||
}
|
||||
break;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
|
||||
/*************************************
|
||||
*
|
||||
* Main refresh
|
||||
*
|
||||
*************************************/
|
||||
|
||||
uint32_t vindictr_state::screen_update(screen_device &screen, bitmap_ind16 &bitmap, const rectangle &cliprect)
|
||||
{
|
||||
// start drawing
|
||||
m_mob->draw_async(cliprect);
|
||||
|
||||
// draw the playfield
|
||||
m_playfield_tilemap->draw(screen, bitmap, cliprect, 0, 0);
|
||||
|
||||
// draw and merge the MO
|
||||
bitmap_ind16 &mobitmap = m_mob->bitmap();
|
||||
for (const sparse_dirty_rect *rect = m_mob->first_dirty_rect(cliprect); rect != nullptr; rect = rect->next())
|
||||
for (int y = rect->top(); y <= rect->bottom(); y++)
|
||||
{
|
||||
uint16_t const *const mo = &mobitmap.pix(y);
|
||||
uint16_t *const pf = &bitmap.pix(y);
|
||||
for (int x = rect->left(); x <= rect->right(); x++)
|
||||
if (mo[x] != 0xffff)
|
||||
{
|
||||
/* partially verified via schematics (there are a lot of PALs involved!):
|
||||
|
||||
SHADE = PAL(MPR1-0, LB7-0, PFX6-5, PFX3-2, PF/M)
|
||||
|
||||
if (SHADE)
|
||||
CRA |= 0x100
|
||||
|
||||
MOG3-1 = ~MAT3-1 if MAT6==1 and MSD3==1
|
||||
*/
|
||||
int const mopriority = mo[x] >> atari_motion_objects_device::PRIORITY_SHIFT;
|
||||
|
||||
// upper bit of MO priority signals special rendering and doesn't draw anything
|
||||
if (mopriority & 4)
|
||||
continue;
|
||||
|
||||
// MO pen 1 doesn't draw, but it sets the SHADE flag and bumps the palette offset
|
||||
if ((mo[x] & 0x0f) == 1)
|
||||
{
|
||||
if ((mo[x] & 0xf0) != 0)
|
||||
pf[x] |= 0x100;
|
||||
}
|
||||
else
|
||||
pf[x] = mo[x] & atari_motion_objects_device::DATA_MASK;
|
||||
|
||||
// don't erase yet -- we need to make another pass later
|
||||
}
|
||||
}
|
||||
|
||||
// add the alpha on top
|
||||
m_alpha_tilemap->draw(screen, bitmap, cliprect, 0, 0);
|
||||
|
||||
// now go back and process the upper bit of MO priority
|
||||
for (const sparse_dirty_rect *rect = m_mob->first_dirty_rect(cliprect); rect != nullptr; rect = rect->next())
|
||||
for (int y = rect->top(); y <= rect->bottom(); y++)
|
||||
{
|
||||
uint16_t const *const mo = &mobitmap.pix(y);
|
||||
uint16_t *const pf = &bitmap.pix(y);
|
||||
for (int x = rect->left(); x <= rect->right(); x++)
|
||||
if (mo[x] != 0xffff)
|
||||
{
|
||||
int const mopriority = mo[x] >> atari_motion_objects_device::PRIORITY_SHIFT;
|
||||
|
||||
// upper bit of MO priority might mean palette kludges
|
||||
if (mopriority & 4)
|
||||
{
|
||||
// if bit 2 is set, start setting high palette bits
|
||||
if (mo[x] & 2)
|
||||
m_mob->apply_stain(bitmap, pf, mo, x, y);
|
||||
|
||||
// if the upper bit of pen data is set, we adjust the final intensity
|
||||
if (mo[x] & 8)
|
||||
pf[x] |= (~mo[x] & 0xe0) << 6;
|
||||
}
|
||||
}
|
||||
}
|
||||
return 0;
|
||||
}
|
||||
|
||||
|
||||
// machine
|
||||
|
||||
/*************************************
|
||||
*
|
||||
@ -47,11 +378,6 @@ void vindictr_state::scanline_int_ack_w(uint16_t data)
|
||||
}
|
||||
|
||||
|
||||
void vindictr_state::machine_reset()
|
||||
{
|
||||
}
|
||||
|
||||
|
||||
|
||||
/*************************************
|
||||
*
|
||||
@ -61,7 +387,7 @@ void vindictr_state::machine_reset()
|
||||
|
||||
uint16_t vindictr_state::port1_r()
|
||||
{
|
||||
int result = ioport("260010")->read();
|
||||
int result = m_260010->read();
|
||||
result ^= 0x0010;
|
||||
return result;
|
||||
}
|
||||
@ -90,7 +416,7 @@ void vindictr_state::main_map(address_map &map)
|
||||
map(0x360010, 0x360011).nopw();
|
||||
map(0x360020, 0x360021).w(m_jsa, FUNC(atari_jsa_i_device::sound_reset_w));
|
||||
map(0x360031, 0x360031).w(m_jsa, FUNC(atari_jsa_i_device::main_command_w));
|
||||
map(0x3e0000, 0x3e0fff).ram().w(FUNC(vindictr_state::vindictr_paletteram_w)).share("paletteram");
|
||||
map(0x3e0000, 0x3e0fff).ram().w(FUNC(vindictr_state::paletteram_w)).share(m_paletteram);
|
||||
map(0x3f0000, 0x3f1fff).mirror(0x8000).ram().w(m_playfield_tilemap, FUNC(tilemap_device::write16)).share("playfield");
|
||||
map(0x3f2000, 0x3f3fff).mirror(0x8000).ram().share("mob");
|
||||
map(0x3f4000, 0x3f4f7f).mirror(0x8000).ram().w(m_alpha_tilemap, FUNC(tilemap_device::write16)).share("alpha");
|
||||
@ -174,8 +500,8 @@ static const gfx_layout pfmolayout =
|
||||
|
||||
|
||||
static GFXDECODE_START( gfx_vindictr )
|
||||
GFXDECODE_ENTRY( "gfx1", 0, pfmolayout, 256, 32 ) /* sprites & playfield */
|
||||
GFXDECODE_ENTRY( "gfx2", 0, anlayout, 0, 64 ) /* characters 8x8 */
|
||||
GFXDECODE_ENTRY( "sprites_pf", 0, pfmolayout, 256, 32 )
|
||||
GFXDECODE_ENTRY( "chars", 0, anlayout, 0, 64 )
|
||||
GFXDECODE_END
|
||||
|
||||
|
||||
@ -188,8 +514,8 @@ GFXDECODE_END
|
||||
|
||||
void vindictr_state::vindictr(machine_config &config)
|
||||
{
|
||||
/* basic machine hardware */
|
||||
M68010(config, m_maincpu, 14.318181_MHz_XTAL/2);
|
||||
// basic machine hardware
|
||||
M68010(config, m_maincpu, 14.318181_MHz_XTAL / 2);
|
||||
m_maincpu->set_addrmap(AS_PROGRAM, &vindictr_state::main_map);
|
||||
|
||||
TIMER(config, "scantimer").configure_scanline(FUNC(vindictr_state::scanline_update), m_screen, 0, 8);
|
||||
@ -198,25 +524,25 @@ void vindictr_state::vindictr(machine_config &config)
|
||||
|
||||
WATCHDOG_TIMER(config, "watchdog");
|
||||
|
||||
/* video hardware */
|
||||
// video hardware
|
||||
GFXDECODE(config, m_gfxdecode, m_palette, gfx_vindictr);
|
||||
PALETTE(config, m_palette).set_entries(2048*8);
|
||||
|
||||
TILEMAP(config, m_playfield_tilemap, m_gfxdecode, 2, 8,8, TILEMAP_SCAN_COLS, 64,64).set_info_callback(FUNC(vindictr_state::get_playfield_tile_info));
|
||||
TILEMAP(config, m_alpha_tilemap, m_gfxdecode, 2, 8,8, TILEMAP_SCAN_ROWS, 64,32, 0).set_info_callback(FUNC(vindictr_state::get_alpha_tile_info));
|
||||
TILEMAP(config, m_playfield_tilemap, m_gfxdecode, 2, 8, 8, TILEMAP_SCAN_COLS, 64, 64).set_info_callback(FUNC(vindictr_state::get_playfield_tile_info));
|
||||
TILEMAP(config, m_alpha_tilemap, m_gfxdecode, 2, 8, 8, TILEMAP_SCAN_ROWS, 64, 32, 0).set_info_callback(FUNC(vindictr_state::get_alpha_tile_info));
|
||||
|
||||
ATARI_MOTION_OBJECTS(config, m_mob, 0, m_screen, vindictr_state::s_mob_config);
|
||||
m_mob->set_gfxdecode(m_gfxdecode);
|
||||
|
||||
SCREEN(config, m_screen, SCREEN_TYPE_RASTER);
|
||||
m_screen->set_video_attributes(VIDEO_UPDATE_BEFORE_VBLANK);
|
||||
/* note: these parameters are from published specs, not derived */
|
||||
/* the board uses a SYNGEN chip to generate video signals */
|
||||
m_screen->set_raw(14.318181_MHz_XTAL/2, 456, 0, 336, 262, 0, 240);
|
||||
m_screen->set_screen_update(FUNC(vindictr_state::screen_update_vindictr));
|
||||
// note: these parameters are from published specs, not derived
|
||||
// the board uses a SYNGEN chip to generate video signals
|
||||
m_screen->set_raw(14.318181_MHz_XTAL / 2, 456, 0, 336, 262, 0, 240);
|
||||
m_screen->set_screen_update(FUNC(vindictr_state::screen_update));
|
||||
m_screen->set_palette(m_palette);
|
||||
|
||||
/* sound hardware */
|
||||
// sound hardware
|
||||
SPEAKER(config, "lspeaker").front_left();
|
||||
SPEAKER(config, "rspeaker").front_right();
|
||||
|
||||
@ -237,7 +563,7 @@ void vindictr_state::vindictr(machine_config &config)
|
||||
*************************************/
|
||||
|
||||
ROM_START( vindictr )
|
||||
ROM_REGION( 0x60000, "maincpu", 0 ) /* 6*64k for 68000 code */
|
||||
ROM_REGION( 0x60000, "maincpu", 0 ) // 68000 code
|
||||
ROM_LOAD16_BYTE( "136059-5117.d1", 0x000000, 0x010000, CRC(2e5135e4) SHA1(804b3ba201088ac2c35cfcbd530acbd73548ea8c) )
|
||||
ROM_LOAD16_BYTE( "136059-5118.d3", 0x000001, 0x010000, CRC(e357fa79) SHA1(220a10287f4bf9d981fd412c8dd0a9c106eaf342) )
|
||||
ROM_LOAD16_BYTE( "136059-5119.f1", 0x020000, 0x010000, CRC(0deb7330) SHA1(e9fb311e96bcf57f2136fff87a973a5a3b5208b3) )
|
||||
@ -245,10 +571,10 @@ ROM_START( vindictr )
|
||||
ROM_LOAD16_BYTE( "136059-5121.k1", 0x040000, 0x010000, CRC(96b150c5) SHA1(405c848f7990c981fefd355ca635bfb0ac24eb26) )
|
||||
ROM_LOAD16_BYTE( "136059-5122.k3", 0x040001, 0x010000, CRC(6415d312) SHA1(0115e32c1c42421cb3d978cc8642f7f88d492043) )
|
||||
|
||||
ROM_REGION( 0x10000, "jsa:cpu", 0 ) /* 64k for 6502 code */
|
||||
ROM_REGION( 0x10000, "jsa:cpu", 0 ) // 6502 code
|
||||
ROM_LOAD( "136059-1124.2k", 0x00000, 0x10000, CRC(d2212c0a) SHA1(df11fe76d74abc0cea23f18264cef4b0f33b1ffd) )
|
||||
|
||||
ROM_REGION( 0x100000, "gfx1", ROMREGION_INVERT )
|
||||
ROM_REGION( 0x100000, "sprites_pf", ROMREGION_INVERT )
|
||||
ROM_LOAD( "136059-1104.12p", 0x000000, 0x020000, CRC(062f8e52) SHA1(0968b8c822d8fee1cf7ddcf9c3b1bf059e446417) )
|
||||
ROM_LOAD( "136059-1116.19p", 0x020000, 0x010000, CRC(0e4366fa) SHA1(1891f6b818f7b0e447e8a83ad0c12aade0b776ee) )
|
||||
ROM_RELOAD( 0x030000, 0x010000 )
|
||||
@ -262,7 +588,7 @@ ROM_START( vindictr )
|
||||
ROM_LOAD( "136059-1113.2r", 0x0e0000, 0x010000, CRC(0a2aba63) SHA1(e4780c790278034f0332697d5f06e6ed6b57d273) )
|
||||
ROM_RELOAD( 0x0f0000, 0x010000 )
|
||||
|
||||
ROM_REGION( 0x04000, "gfx2", 0 )
|
||||
ROM_REGION( 0x04000, "chars", 0 )
|
||||
ROM_LOAD( "136059-1123.16n", 0x000000, 0x004000, CRC(f99b631a) SHA1(7a2430b6810c77b0f717d6e9d71823eadbcf6013) )
|
||||
|
||||
ROM_REGION( 0x00800, "plds", 0 )
|
||||
@ -274,7 +600,7 @@ ROM_END
|
||||
|
||||
|
||||
ROM_START( vindictre )
|
||||
ROM_REGION( 0x60000, "maincpu", 0 ) /* 6*64k for 68000 code */
|
||||
ROM_REGION( 0x60000, "maincpu", 0 ) // 68000 code
|
||||
ROM_LOAD16_BYTE( "136059-5717.d1", 0x000000, 0x010000, CRC(af5ba4a8) SHA1(fdb6e7f0707af94b39368cc39ae45c53209ce32e) )
|
||||
ROM_LOAD16_BYTE( "136059-5718.d3", 0x000001, 0x010000, CRC(c87b0581) SHA1(f33c72e83e8c811d3405deb470573327c7b68ea6) )
|
||||
ROM_LOAD16_BYTE( "136059-5719.f1", 0x020000, 0x010000, CRC(1e5f94e1) SHA1(bf14e4d3c26507ad3a78ad28b6b54e4ea0939ceb) )
|
||||
@ -282,10 +608,10 @@ ROM_START( vindictre )
|
||||
ROM_LOAD16_BYTE( "136059-5721.k1", 0x040000, 0x010000, CRC(96b150c5) SHA1(405c848f7990c981fefd355ca635bfb0ac24eb26) )
|
||||
ROM_LOAD16_BYTE( "136059-5722.k3", 0x040001, 0x010000, CRC(6415d312) SHA1(0115e32c1c42421cb3d978cc8642f7f88d492043) )
|
||||
|
||||
ROM_REGION( 0x10000, "jsa:cpu", 0 ) /* 64k for 6502 code */
|
||||
ROM_REGION( 0x10000, "jsa:cpu", 0 ) // 6502 code
|
||||
ROM_LOAD( "136059-1124.2k", 0x00000, 0x10000, CRC(d2212c0a) SHA1(df11fe76d74abc0cea23f18264cef4b0f33b1ffd) )
|
||||
|
||||
ROM_REGION( 0x100000, "gfx1", ROMREGION_INVERT )
|
||||
ROM_REGION( 0x100000, "sprites_pf", ROMREGION_INVERT )
|
||||
ROM_LOAD( "136059-1104.12p", 0x000000, 0x020000, CRC(062f8e52) SHA1(0968b8c822d8fee1cf7ddcf9c3b1bf059e446417) )
|
||||
ROM_LOAD( "136059-1116.19p", 0x020000, 0x010000, CRC(0e4366fa) SHA1(1891f6b818f7b0e447e8a83ad0c12aade0b776ee) )
|
||||
ROM_RELOAD( 0x030000, 0x010000 )
|
||||
@ -299,7 +625,7 @@ ROM_START( vindictre )
|
||||
ROM_LOAD( "136059-1113.2r", 0x0e0000, 0x010000, CRC(0a2aba63) SHA1(e4780c790278034f0332697d5f06e6ed6b57d273) )
|
||||
ROM_RELOAD( 0x0f0000, 0x010000 )
|
||||
|
||||
ROM_REGION( 0x04000, "gfx2", 0 )
|
||||
ROM_REGION( 0x04000, "chars", 0 )
|
||||
ROM_LOAD( "136059-1123.16n", 0x000000, 0x004000, CRC(f99b631a) SHA1(7a2430b6810c77b0f717d6e9d71823eadbcf6013) )
|
||||
|
||||
ROM_REGION( 0x00800, "plds", 0 )
|
||||
@ -311,7 +637,7 @@ ROM_END
|
||||
|
||||
|
||||
ROM_START( vindictrg )
|
||||
ROM_REGION( 0x60000, "maincpu", 0 ) /* 6*64k for 68000 code */
|
||||
ROM_REGION( 0x60000, "maincpu", 0 ) // 68000 code
|
||||
ROM_LOAD16_BYTE( "136059-1217.d1", 0x000000, 0x010000, CRC(0a589e9a) SHA1(6770212b57599cd9bcdeb126aec30d9815608005) )
|
||||
ROM_LOAD16_BYTE( "136059-1218.d3", 0x000001, 0x010000, CRC(e8b7959a) SHA1(b63747934b188f44a5e59a54f52d15b33f9d676b) )
|
||||
ROM_LOAD16_BYTE( "136059-1219.f1", 0x020000, 0x010000, CRC(2534fcbc) SHA1(d8a2121de88efabf99a153fd477c7bf2fddc88c9) )
|
||||
@ -319,10 +645,10 @@ ROM_START( vindictrg )
|
||||
ROM_LOAD16_BYTE( "136059-1221.k1", 0x040000, 0x010000, CRC(ee1b1014) SHA1(ddfe01cdec4654a42c9e49660e3532e5c865a9b7) )
|
||||
ROM_LOAD16_BYTE( "136059-1222.k3", 0x040001, 0x010000, CRC(517b33f0) SHA1(f6430862bb00e11a68e964c89adcad1f05bc021b) )
|
||||
|
||||
ROM_REGION( 0x10000, "jsa:cpu", 0 ) /* 64k for 6502 code */
|
||||
ROM_REGION( 0x10000, "jsa:cpu", 0 ) // 6502 code
|
||||
ROM_LOAD( "136059-1124.2k", 0x00000, 0x10000, CRC(d2212c0a) SHA1(df11fe76d74abc0cea23f18264cef4b0f33b1ffd) )
|
||||
|
||||
ROM_REGION( 0x100000, "gfx1", ROMREGION_INVERT )
|
||||
ROM_REGION( 0x100000, "sprites_pf", ROMREGION_INVERT )
|
||||
ROM_LOAD( "136059-1104.12p", 0x000000, 0x020000, CRC(062f8e52) SHA1(0968b8c822d8fee1cf7ddcf9c3b1bf059e446417) )
|
||||
ROM_LOAD( "136059-1116.19p", 0x020000, 0x010000, CRC(0e4366fa) SHA1(1891f6b818f7b0e447e8a83ad0c12aade0b776ee) )
|
||||
ROM_RELOAD( 0x030000, 0x010000 )
|
||||
@ -336,7 +662,7 @@ ROM_START( vindictrg )
|
||||
ROM_LOAD( "136059-1113.2r", 0x0e0000, 0x010000, CRC(0a2aba63) SHA1(e4780c790278034f0332697d5f06e6ed6b57d273) )
|
||||
ROM_RELOAD( 0x0f0000, 0x010000 )
|
||||
|
||||
ROM_REGION( 0x04000, "gfx2", 0 )
|
||||
ROM_REGION( 0x04000, "chars", 0 )
|
||||
ROM_LOAD( "136059-1223.16n", 0x000000, 0x004000, CRC(d27975bb) SHA1(a8ab8bdbd9fbcbcf73e8621b2a4447d25bf612b8) )
|
||||
|
||||
ROM_REGION( 0x00800, "plds", 0 )
|
||||
@ -348,7 +674,7 @@ ROM_END
|
||||
|
||||
|
||||
ROM_START( vindictre4 )
|
||||
ROM_REGION( 0x60000, "maincpu", 0 ) /* 6*64k for 68000 code */
|
||||
ROM_REGION( 0x60000, "maincpu", 0 ) // 68000 code
|
||||
ROM_LOAD16_BYTE( "136059-1117.d1", 0x000000, 0x010000, CRC(2e5135e4) SHA1(804b3ba201088ac2c35cfcbd530acbd73548ea8c) )
|
||||
ROM_LOAD16_BYTE( "136059-1118.d3", 0x000001, 0x010000, CRC(e357fa79) SHA1(220a10287f4bf9d981fd412c8dd0a9c106eaf342) )
|
||||
ROM_LOAD16_BYTE( "136059-4719.f1", 0x020000, 0x010000, CRC(3b27ab80) SHA1(330a6fe0e0265cce40c913aa5c3607429afe510b) )
|
||||
@ -356,10 +682,10 @@ ROM_START( vindictre4 )
|
||||
ROM_LOAD16_BYTE( "136059-4121.k1", 0x040000, 0x010000, CRC(9a0444ee) SHA1(211be931a8b6ca42dd140baf3e165ce23f75431f) )
|
||||
ROM_LOAD16_BYTE( "136059-4122.k3", 0x040001, 0x010000, CRC(d5022d78) SHA1(eeb6876ee6994f5736114a786c5c4ba97f26ef01) )
|
||||
|
||||
ROM_REGION( 0x10000, "jsa:cpu", 0 ) /* 64k for 6502 code */
|
||||
ROM_REGION( 0x10000, "jsa:cpu", 0 ) // 6502 code
|
||||
ROM_LOAD( "136059-1124.2k", 0x00000, 0x10000, CRC(d2212c0a) SHA1(df11fe76d74abc0cea23f18264cef4b0f33b1ffd) )
|
||||
|
||||
ROM_REGION( 0x100000, "gfx1", ROMREGION_INVERT )
|
||||
ROM_REGION( 0x100000, "sprites_pf", ROMREGION_INVERT )
|
||||
ROM_LOAD( "136059-1104.12p", 0x000000, 0x020000, CRC(062f8e52) SHA1(0968b8c822d8fee1cf7ddcf9c3b1bf059e446417) )
|
||||
ROM_LOAD( "136059-1116.19p", 0x020000, 0x010000, CRC(0e4366fa) SHA1(1891f6b818f7b0e447e8a83ad0c12aade0b776ee) )
|
||||
ROM_RELOAD( 0x030000, 0x010000 )
|
||||
@ -373,7 +699,7 @@ ROM_START( vindictre4 )
|
||||
ROM_LOAD( "136059-1113.2r", 0x0e0000, 0x010000, CRC(0a2aba63) SHA1(e4780c790278034f0332697d5f06e6ed6b57d273) )
|
||||
ROM_RELOAD( 0x0f0000, 0x010000 )
|
||||
|
||||
ROM_REGION( 0x04000, "gfx2", 0 )
|
||||
ROM_REGION( 0x04000, "chars", 0 )
|
||||
ROM_LOAD( "136059-1123.16n", 0x000000, 0x004000, CRC(f99b631a) SHA1(7a2430b6810c77b0f717d6e9d71823eadbcf6013) )
|
||||
|
||||
ROM_REGION( 0x00800, "plds", 0 )
|
||||
@ -385,7 +711,7 @@ ROM_END
|
||||
|
||||
|
||||
ROM_START( vindictr4 )
|
||||
ROM_REGION( 0x60000, "maincpu", 0 ) /* 6*64k for 68000 code */
|
||||
ROM_REGION( 0x60000, "maincpu", 0 ) // 68000 code
|
||||
ROM_LOAD16_BYTE( "136059-1117.d1", 0x000000, 0x010000, CRC(2e5135e4) SHA1(804b3ba201088ac2c35cfcbd530acbd73548ea8c) )
|
||||
ROM_LOAD16_BYTE( "136059-1118.d3", 0x000001, 0x010000, CRC(e357fa79) SHA1(220a10287f4bf9d981fd412c8dd0a9c106eaf342) )
|
||||
ROM_LOAD16_BYTE( "136059-4119.f1", 0x020000, 0x010000, CRC(44c77ee0) SHA1(f47307126a4960d59d19d1783497971f76ee00a5) )
|
||||
@ -393,10 +719,10 @@ ROM_START( vindictr4 )
|
||||
ROM_LOAD16_BYTE( "136059-4121.k1", 0x040000, 0x010000, CRC(9a0444ee) SHA1(211be931a8b6ca42dd140baf3e165ce23f75431f) )
|
||||
ROM_LOAD16_BYTE( "136059-4122.k3", 0x040001, 0x010000, CRC(d5022d78) SHA1(eeb6876ee6994f5736114a786c5c4ba97f26ef01) )
|
||||
|
||||
ROM_REGION( 0x10000, "jsa:cpu", 0 ) /* 64k for 6502 code */
|
||||
ROM_REGION( 0x10000, "jsa:cpu", 0 ) // 6502 code
|
||||
ROM_LOAD( "136059-1124.2k", 0x00000, 0x10000, CRC(d2212c0a) SHA1(df11fe76d74abc0cea23f18264cef4b0f33b1ffd) )
|
||||
|
||||
ROM_REGION( 0x100000, "gfx1", ROMREGION_INVERT )
|
||||
ROM_REGION( 0x100000, "sprites_pf", ROMREGION_INVERT )
|
||||
ROM_LOAD( "136059-1104.12p", 0x000000, 0x020000, CRC(062f8e52) SHA1(0968b8c822d8fee1cf7ddcf9c3b1bf059e446417) )
|
||||
ROM_LOAD( "136059-1116.19p", 0x020000, 0x010000, CRC(0e4366fa) SHA1(1891f6b818f7b0e447e8a83ad0c12aade0b776ee) )
|
||||
ROM_RELOAD( 0x030000, 0x010000 )
|
||||
@ -410,7 +736,7 @@ ROM_START( vindictr4 )
|
||||
ROM_LOAD( "136059-1113.2r", 0x0e0000, 0x010000, CRC(0a2aba63) SHA1(e4780c790278034f0332697d5f06e6ed6b57d273) )
|
||||
ROM_RELOAD( 0x0f0000, 0x010000 )
|
||||
|
||||
ROM_REGION( 0x04000, "gfx2", 0 )
|
||||
ROM_REGION( 0x04000, "chars", 0 )
|
||||
ROM_LOAD( "136059-1123.16n", 0x000000, 0x004000, CRC(f99b631a) SHA1(7a2430b6810c77b0f717d6e9d71823eadbcf6013) )
|
||||
|
||||
ROM_REGION( 0x00800, "plds", 0 )
|
||||
@ -422,7 +748,7 @@ ROM_END
|
||||
|
||||
|
||||
ROM_START( vindictre3 )
|
||||
ROM_REGION( 0x60000, "maincpu", 0 ) /* 6*64k for 68000 code */
|
||||
ROM_REGION( 0x60000, "maincpu", 0 ) // 68000 code
|
||||
ROM_LOAD16_BYTE( "136059-3117.d1", 0x000000, 0x010000, CRC(af5ba4a8) SHA1(fdb6e7f0707af94b39368cc39ae45c53209ce32e) )
|
||||
ROM_LOAD16_BYTE( "136059-3118.d3", 0x000001, 0x010000, CRC(c87b0581) SHA1(f33c72e83e8c811d3405deb470573327c7b68ea6) )
|
||||
ROM_LOAD16_BYTE( "136059-3119.f1", 0x020000, 0x010000, CRC(f0516142) SHA1(16f23a9a8939cead728108fc23fccebf2529d553) )
|
||||
@ -430,10 +756,10 @@ ROM_START( vindictre3 )
|
||||
ROM_LOAD16_BYTE( "136059-2121.k1", 0x040000, 0x010000, CRC(9b6111e0) SHA1(427197b21a5db2a06751ab281fde7a2f63818db8) )
|
||||
ROM_LOAD16_BYTE( "136059-2122.k3", 0x040001, 0x010000, CRC(8d029a28) SHA1(a166d2a767f70050397f0f12add44ad1f5bc9fde) )
|
||||
|
||||
ROM_REGION( 0x10000, "jsa:cpu", 0 ) /* 64k for 6502 code */
|
||||
ROM_REGION( 0x10000, "jsa:cpu", 0 ) // 6502 code
|
||||
ROM_LOAD( "136059-1124.2k", 0x00000, 0x10000, CRC(d2212c0a) SHA1(df11fe76d74abc0cea23f18264cef4b0f33b1ffd) )
|
||||
|
||||
ROM_REGION( 0x100000, "gfx1", ROMREGION_INVERT )
|
||||
ROM_REGION( 0x100000, "sprites_pf", ROMREGION_INVERT )
|
||||
ROM_LOAD( "136059-1104.12p", 0x000000, 0x020000, CRC(062f8e52) SHA1(0968b8c822d8fee1cf7ddcf9c3b1bf059e446417) )
|
||||
ROM_LOAD( "136059-1116.19p", 0x020000, 0x010000, CRC(0e4366fa) SHA1(1891f6b818f7b0e447e8a83ad0c12aade0b776ee) )
|
||||
ROM_RELOAD( 0x030000, 0x010000 )
|
||||
@ -447,7 +773,7 @@ ROM_START( vindictre3 )
|
||||
ROM_LOAD( "136059-1113.2r", 0x0e0000, 0x010000, CRC(0a2aba63) SHA1(e4780c790278034f0332697d5f06e6ed6b57d273) )
|
||||
ROM_RELOAD( 0x0f0000, 0x010000 )
|
||||
|
||||
ROM_REGION( 0x04000, "gfx2", 0 )
|
||||
ROM_REGION( 0x04000, "chars", 0 )
|
||||
ROM_LOAD( "136059-1123.16n", 0x000000, 0x004000, CRC(f99b631a) SHA1(7a2430b6810c77b0f717d6e9d71823eadbcf6013) )
|
||||
|
||||
ROM_REGION( 0x00800, "plds", 0 )
|
||||
@ -459,7 +785,7 @@ ROM_END
|
||||
|
||||
|
||||
ROM_START( vindictr2 )
|
||||
ROM_REGION( 0x60000, "maincpu", 0 ) /* 6*64k for 68000 code */
|
||||
ROM_REGION( 0x60000, "maincpu", 0 ) // 68000 code
|
||||
ROM_LOAD16_BYTE( "136059-1117.d1", 0x000000, 0x010000, CRC(2e5135e4) SHA1(804b3ba201088ac2c35cfcbd530acbd73548ea8c) )
|
||||
ROM_LOAD16_BYTE( "136059-1118.d3", 0x000001, 0x010000, CRC(e357fa79) SHA1(220a10287f4bf9d981fd412c8dd0a9c106eaf342) )
|
||||
ROM_LOAD16_BYTE( "136059-2119.f1", 0x020000, 0x010000, CRC(7f8c044e) SHA1(56cd047ff12ff2968bf403b38b86fdceb9c2b83d) )
|
||||
@ -467,10 +793,10 @@ ROM_START( vindictr2 )
|
||||
ROM_LOAD16_BYTE( "136059-2121.k1", 0x040000, 0x010000, CRC(9b6111e0) SHA1(427197b21a5db2a06751ab281fde7a2f63818db8) )
|
||||
ROM_LOAD16_BYTE( "136059-2122.k3", 0x040001, 0x010000, CRC(8d029a28) SHA1(a166d2a767f70050397f0f12add44ad1f5bc9fde) )
|
||||
|
||||
ROM_REGION( 0x10000, "jsa:cpu", 0 ) /* 64k for 6502 code */
|
||||
ROM_REGION( 0x10000, "jsa:cpu", 0 ) // 6502 code
|
||||
ROM_LOAD( "136059-1124.2k", 0x00000, 0x10000, CRC(d2212c0a) SHA1(df11fe76d74abc0cea23f18264cef4b0f33b1ffd) )
|
||||
|
||||
ROM_REGION( 0x100000, "gfx1", ROMREGION_INVERT )
|
||||
ROM_REGION( 0x100000, "sprites_pf", ROMREGION_INVERT )
|
||||
ROM_LOAD( "136059-1104.12p", 0x000000, 0x020000, CRC(062f8e52) SHA1(0968b8c822d8fee1cf7ddcf9c3b1bf059e446417) )
|
||||
ROM_LOAD( "136059-1116.19p", 0x020000, 0x010000, CRC(0e4366fa) SHA1(1891f6b818f7b0e447e8a83ad0c12aade0b776ee) )
|
||||
ROM_RELOAD( 0x030000, 0x010000 )
|
||||
@ -484,7 +810,7 @@ ROM_START( vindictr2 )
|
||||
ROM_LOAD( "136059-1113.2r", 0x0e0000, 0x010000, CRC(0a2aba63) SHA1(e4780c790278034f0332697d5f06e6ed6b57d273) )
|
||||
ROM_RELOAD( 0x0f0000, 0x010000 )
|
||||
|
||||
ROM_REGION( 0x04000, "gfx2", 0 )
|
||||
ROM_REGION( 0x04000, "chars", 0 )
|
||||
ROM_LOAD( "136059-1123.16n", 0x000000, 0x004000, CRC(f99b631a) SHA1(7a2430b6810c77b0f717d6e9d71823eadbcf6013) )
|
||||
|
||||
ROM_REGION( 0x00800, "plds", 0 )
|
||||
@ -496,7 +822,7 @@ ROM_END
|
||||
|
||||
|
||||
ROM_START( vindictr1 )
|
||||
ROM_REGION( 0x60000, "maincpu", 0 ) /* 6*64k for 68000 code */
|
||||
ROM_REGION( 0x60000, "maincpu", 0 ) // 68000 code
|
||||
ROM_LOAD16_BYTE( "136059-1117.d1", 0x000000, 0x010000, CRC(2e5135e4) SHA1(804b3ba201088ac2c35cfcbd530acbd73548ea8c) )
|
||||
ROM_LOAD16_BYTE( "136059-1118.d3", 0x000001, 0x010000, CRC(e357fa79) SHA1(220a10287f4bf9d981fd412c8dd0a9c106eaf342) )
|
||||
ROM_LOAD16_BYTE( "136059-1119.f1", 0x020000, 0x010000, CRC(48938c95) SHA1(061771b074135b945621d781fbde7ec1260f31a1) )
|
||||
@ -504,10 +830,10 @@ ROM_START( vindictr1 )
|
||||
ROM_LOAD16_BYTE( "136059-1121.k1", 0x040000, 0x010000, CRC(9b6111e0) SHA1(427197b21a5db2a06751ab281fde7a2f63818db8) )
|
||||
ROM_LOAD16_BYTE( "136059-1122.k3", 0x040001, 0x010000, CRC(a94773f1) SHA1(2be841ab755d4ce319f3d562e9990918923384ee) )
|
||||
|
||||
ROM_REGION( 0x10000, "jsa:cpu", 0 ) /* 64k for 6502 code */
|
||||
ROM_REGION( 0x10000, "jsa:cpu", 0 ) // 6502 code
|
||||
ROM_LOAD( "136059-1124.2k", 0x00000, 0x10000, CRC(d2212c0a) SHA1(df11fe76d74abc0cea23f18264cef4b0f33b1ffd) )
|
||||
|
||||
ROM_REGION( 0x100000, "gfx1", ROMREGION_INVERT )
|
||||
ROM_REGION( 0x100000, "sprites_pf", ROMREGION_INVERT )
|
||||
ROM_LOAD( "136059-1104.12p", 0x000000, 0x020000, CRC(062f8e52) SHA1(0968b8c822d8fee1cf7ddcf9c3b1bf059e446417) )
|
||||
ROM_LOAD( "136059-1116.19p", 0x020000, 0x010000, CRC(0e4366fa) SHA1(1891f6b818f7b0e447e8a83ad0c12aade0b776ee) )
|
||||
ROM_RELOAD( 0x030000, 0x010000 )
|
||||
@ -521,7 +847,7 @@ ROM_START( vindictr1 )
|
||||
ROM_LOAD( "136059-1113.2r", 0x0e0000, 0x010000, CRC(0a2aba63) SHA1(e4780c790278034f0332697d5f06e6ed6b57d273) )
|
||||
ROM_RELOAD( 0x0f0000, 0x010000 )
|
||||
|
||||
ROM_REGION( 0x04000, "gfx2", 0 )
|
||||
ROM_REGION( 0x04000, "chars", 0 )
|
||||
ROM_LOAD( "136059-1123.16n", 0x000000, 0x004000, CRC(f99b631a) SHA1(7a2430b6810c77b0f717d6e9d71823eadbcf6013) )
|
||||
|
||||
ROM_REGION( 0x00800, "plds", 0 )
|
||||
@ -531,18 +857,7 @@ ROM_START( vindictr1 )
|
||||
ROM_LOAD( "pal16r6a-136059-1153.n7", 0x0600, 0x0104, CRC(61076033) SHA1(c860835a8fa48e141f3d24732395ac35a4b908a4) )
|
||||
ROM_END
|
||||
|
||||
|
||||
|
||||
/*************************************
|
||||
*
|
||||
* Driver initialization
|
||||
*
|
||||
*************************************/
|
||||
|
||||
void vindictr_state::init_vindictr()
|
||||
{
|
||||
}
|
||||
|
||||
} // anonymous namespace
|
||||
|
||||
|
||||
/*************************************
|
||||
@ -551,11 +866,11 @@ void vindictr_state::init_vindictr()
|
||||
*
|
||||
*************************************/
|
||||
|
||||
GAME( 1988, vindictr, 0, vindictr, vindictr, vindictr_state, init_vindictr, ROT0, "Atari Games", "Vindicators (rev 5)", 0 )
|
||||
GAME( 1988, vindictre, vindictr, vindictr, vindictr, vindictr_state, init_vindictr, ROT0, "Atari Games", "Vindicators (Europe, rev 5)", 0 )
|
||||
GAME( 1988, vindictrg, vindictr, vindictr, vindictr, vindictr_state, init_vindictr, ROT0, "Atari Games", "Vindicators (German, rev 1)", 0 )
|
||||
GAME( 1988, vindictre4,vindictr, vindictr, vindictr, vindictr_state, init_vindictr, ROT0, "Atari Games", "Vindicators (Europe, rev 4)", 0 )
|
||||
GAME( 1988, vindictr4, vindictr, vindictr, vindictr, vindictr_state, init_vindictr, ROT0, "Atari Games", "Vindicators (rev 4)", 0 )
|
||||
GAME( 1988, vindictre3,vindictr, vindictr, vindictr, vindictr_state, init_vindictr, ROT0, "Atari Games", "Vindicators (Europe, rev 3)", 0 )
|
||||
GAME( 1988, vindictr2, vindictr, vindictr, vindictr, vindictr_state, init_vindictr, ROT0, "Atari Games", "Vindicators (rev 2)", 0 )
|
||||
GAME( 1988, vindictr1, vindictr, vindictr, vindictr, vindictr_state, init_vindictr, ROT0, "Atari Games", "Vindicators (rev 1)", 0 )
|
||||
GAME( 1988, vindictr, 0, vindictr, vindictr, vindictr_state, empty_init, ROT0, "Atari Games", "Vindicators (rev 5)", MACHINE_SUPPORTS_SAVE )
|
||||
GAME( 1988, vindictre, vindictr, vindictr, vindictr, vindictr_state, empty_init, ROT0, "Atari Games", "Vindicators (Europe, rev 5)", MACHINE_SUPPORTS_SAVE )
|
||||
GAME( 1988, vindictrg, vindictr, vindictr, vindictr, vindictr_state, empty_init, ROT0, "Atari Games", "Vindicators (German, rev 1)", MACHINE_SUPPORTS_SAVE )
|
||||
GAME( 1988, vindictre4,vindictr, vindictr, vindictr, vindictr_state, empty_init, ROT0, "Atari Games", "Vindicators (Europe, rev 4)", MACHINE_SUPPORTS_SAVE )
|
||||
GAME( 1988, vindictr4, vindictr, vindictr, vindictr, vindictr_state, empty_init, ROT0, "Atari Games", "Vindicators (rev 4)", MACHINE_SUPPORTS_SAVE )
|
||||
GAME( 1988, vindictre3,vindictr, vindictr, vindictr, vindictr_state, empty_init, ROT0, "Atari Games", "Vindicators (Europe, rev 3)", MACHINE_SUPPORTS_SAVE )
|
||||
GAME( 1988, vindictr2, vindictr, vindictr, vindictr, vindictr_state, empty_init, ROT0, "Atari Games", "Vindicators (rev 2)", MACHINE_SUPPORTS_SAVE )
|
||||
GAME( 1988, vindictr1, vindictr, vindictr, vindictr, vindictr_state, empty_init, ROT0, "Atari Games", "Vindicators (rev 1)", MACHINE_SUPPORTS_SAVE )
|
||||
|
@ -1,70 +0,0 @@
|
||||
// license:BSD-3-Clause
|
||||
// copyright-holders:Aaron Giles
|
||||
/*************************************************************************
|
||||
|
||||
Atari Vindicators hardware
|
||||
|
||||
*************************************************************************/
|
||||
#ifndef MAME_ATARI_VINDICTR_H
|
||||
#define MAME_ATARI_VINDICTR_H
|
||||
|
||||
#pragma once
|
||||
|
||||
#include "machine/timer.h"
|
||||
#include "atarijsa.h"
|
||||
#include "atarimo.h"
|
||||
#include "emupal.h"
|
||||
#include "screen.h"
|
||||
#include "tilemap.h"
|
||||
|
||||
class vindictr_state : public driver_device
|
||||
{
|
||||
public:
|
||||
vindictr_state(const machine_config &mconfig, device_type type, const char *tag) :
|
||||
driver_device(mconfig, type, tag),
|
||||
m_maincpu(*this, "maincpu"),
|
||||
m_gfxdecode(*this, "gfxdecode"),
|
||||
m_screen(*this, "screen"),
|
||||
m_playfield_tilemap(*this, "playfield"),
|
||||
m_alpha_tilemap(*this, "alpha"),
|
||||
m_mob(*this, "mob"),
|
||||
m_jsa(*this, "jsa"),
|
||||
m_palette(*this, "palette"),
|
||||
m_paletteram(*this, "paletteram")
|
||||
{ }
|
||||
|
||||
void vindictr(machine_config &config);
|
||||
|
||||
void init_vindictr();
|
||||
|
||||
private:
|
||||
virtual void machine_reset() override;
|
||||
virtual void video_start() override;
|
||||
void scanline_interrupt();
|
||||
void scanline_int_ack_w(uint16_t data);
|
||||
TIMER_DEVICE_CALLBACK_MEMBER(scanline_update);
|
||||
uint16_t port1_r();
|
||||
TILE_GET_INFO_MEMBER(get_alpha_tile_info);
|
||||
TILE_GET_INFO_MEMBER(get_playfield_tile_info);
|
||||
uint32_t screen_update_vindictr(screen_device &screen, bitmap_ind16 &bitmap, const rectangle &cliprect);
|
||||
void vindictr_paletteram_w(offs_t offset, uint16_t data, uint16_t mem_mask = ~0);
|
||||
|
||||
static const atari_motion_objects_config s_mob_config;
|
||||
void main_map(address_map &map);
|
||||
|
||||
required_device<cpu_device> m_maincpu;
|
||||
required_device<gfxdecode_device> m_gfxdecode;
|
||||
required_device<screen_device> m_screen;
|
||||
required_device<tilemap_device> m_playfield_tilemap;
|
||||
required_device<tilemap_device> m_alpha_tilemap;
|
||||
required_device<atari_motion_objects_device> m_mob;
|
||||
required_device<atari_jsa_i_device> m_jsa;
|
||||
required_device<palette_device> m_palette;
|
||||
required_shared_ptr<uint16_t> m_paletteram;
|
||||
|
||||
uint8_t m_playfield_tile_bank = 0;
|
||||
uint16_t m_playfield_xscroll = 0;
|
||||
uint16_t m_playfield_yscroll = 0;
|
||||
};
|
||||
|
||||
#endif // MAME_ATARI_VINDICTR_H
|
@ -1,279 +0,0 @@
|
||||
// license:BSD-3-Clause
|
||||
// copyright-holders:Aaron Giles
|
||||
/***************************************************************************
|
||||
|
||||
Atari Vindicators hardware
|
||||
|
||||
****************************************************************************/
|
||||
|
||||
#include "emu.h"
|
||||
#include "vindictr.h"
|
||||
|
||||
|
||||
|
||||
/*************************************
|
||||
*
|
||||
* Tilemap callbacks
|
||||
*
|
||||
*************************************/
|
||||
|
||||
TILE_GET_INFO_MEMBER(vindictr_state::get_alpha_tile_info)
|
||||
{
|
||||
uint16_t data = m_alpha_tilemap->basemem_read(tile_index);
|
||||
int code = data & 0x3ff;
|
||||
int color = ((data >> 10) & 0x0f) | ((data >> 9) & 0x20);
|
||||
int opaque = data & 0x8000;
|
||||
tileinfo.set(1, code, color, opaque ? TILE_FORCE_LAYER0 : 0);
|
||||
}
|
||||
|
||||
|
||||
TILE_GET_INFO_MEMBER(vindictr_state::get_playfield_tile_info)
|
||||
{
|
||||
uint16_t data = m_playfield_tilemap->basemem_read(tile_index);
|
||||
int code = (m_playfield_tile_bank * 0x1000) + (data & 0xfff);
|
||||
int color = 0x10 + 2 * ((data >> 12) & 7);
|
||||
tileinfo.set(0, code, color, (data >> 15) & 1);
|
||||
}
|
||||
|
||||
|
||||
|
||||
/*************************************
|
||||
*
|
||||
* Video system start
|
||||
*
|
||||
*************************************/
|
||||
|
||||
const atari_motion_objects_config vindictr_state::s_mob_config =
|
||||
{
|
||||
0, /* index to which gfx system */
|
||||
1, /* number of motion object banks */
|
||||
1, /* are the entries linked? */
|
||||
0, /* are the entries split? */
|
||||
0, /* render in reverse order? */
|
||||
0, /* render in swapped X/Y order? */
|
||||
0, /* does the neighbor bit affect the next object? */
|
||||
8, /* pixels per SLIP entry (0 for no-slip) */
|
||||
0, /* pixel offset for SLIPs */
|
||||
0, /* maximum number of links to visit/scanline (0=all) */
|
||||
|
||||
0x100, /* base palette entry */
|
||||
0x100, /* maximum number of colors */
|
||||
0, /* transparent pen index */
|
||||
|
||||
{{ 0,0,0,0x03ff }}, /* mask for the link */
|
||||
{{ 0x7fff,0,0,0 }}, /* mask for the code index */
|
||||
{{ 0,0x000f,0,0 }}, /* mask for the color */
|
||||
{{ 0,0xff80,0,0 }}, /* mask for the X position */
|
||||
{{ 0,0,0xff80,0 }}, /* mask for the Y position */
|
||||
{{ 0,0,0x0038,0 }}, /* mask for the width, in tiles*/
|
||||
{{ 0,0,0x0007,0 }}, /* mask for the height, in tiles */
|
||||
{{ 0,0,0x0040,0 }}, /* mask for the horizontal flip */
|
||||
{{ 0 }}, /* mask for the vertical flip */
|
||||
{{ 0,0x0070,0,0 }}, /* mask for the priority */
|
||||
{{ 0 }}, /* mask for the neighbor */
|
||||
{{ 0 }}, /* mask for absolute coordinates */
|
||||
|
||||
{{ 0 }}, /* mask for the special value */
|
||||
0 /* resulting value to indicate "special" */
|
||||
};
|
||||
|
||||
void vindictr_state::video_start()
|
||||
{
|
||||
/* save states */
|
||||
save_item(NAME(m_playfield_tile_bank));
|
||||
save_item(NAME(m_playfield_xscroll));
|
||||
save_item(NAME(m_playfield_yscroll));
|
||||
}
|
||||
|
||||
|
||||
|
||||
/*************************************
|
||||
*
|
||||
* Palette RAM control
|
||||
*
|
||||
*************************************/
|
||||
|
||||
void vindictr_state::vindictr_paletteram_w(offs_t offset, uint16_t data, uint16_t mem_mask)
|
||||
{
|
||||
static const int ztable[16] =
|
||||
{ 0x0, 0x3, 0x4, 0x5, 0x6, 0x7, 0x8, 0x9, 0xa, 0xb, 0xc, 0xd, 0xe, 0xf, 0x10, 0x11 };
|
||||
int c;
|
||||
|
||||
/* first blend the data */
|
||||
COMBINE_DATA(&m_paletteram[offset]);
|
||||
data = m_paletteram[offset];
|
||||
|
||||
/* now generate colors at all 16 intensities */
|
||||
for (c = 0; c < 8; c++)
|
||||
{
|
||||
int i = ztable[((data >> 12) + (c * 2)) & 15];
|
||||
int r = ((data >> 8) & 15) * i;
|
||||
int g = ((data >> 4) & 15) * i;
|
||||
int b = ((data >> 0) & 15) * i;
|
||||
|
||||
m_palette->set_pen_color(offset + c*2048,rgb_t(r,g,b));
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
|
||||
/*************************************
|
||||
*
|
||||
* Periodic scanline updater
|
||||
*
|
||||
*************************************/
|
||||
|
||||
TIMER_DEVICE_CALLBACK_MEMBER(vindictr_state::scanline_update)
|
||||
{
|
||||
int scanline = param;
|
||||
|
||||
/* keep in range */
|
||||
int offset = ((scanline - 8) / 8) * 64 + 42;
|
||||
if (offset < 0)
|
||||
offset += 0x7c0;
|
||||
else if (offset >= 0x7c0)
|
||||
return;
|
||||
|
||||
/* update the current parameters */
|
||||
for (int x = 42; x < 64; x++)
|
||||
{
|
||||
uint16_t data = m_alpha_tilemap->basemem_read(offset++);
|
||||
|
||||
switch ((data >> 9) & 7)
|
||||
{
|
||||
case 2: /* /PFB */
|
||||
if (m_playfield_tile_bank != (data & 7))
|
||||
{
|
||||
m_screen->update_partial(scanline - 1);
|
||||
m_playfield_tile_bank = data & 7;
|
||||
m_playfield_tilemap->mark_all_dirty();
|
||||
}
|
||||
break;
|
||||
|
||||
case 3: /* /PFHSLD */
|
||||
if (m_playfield_xscroll != (data & 0x1ff))
|
||||
{
|
||||
m_screen->update_partial(scanline - 1);
|
||||
m_playfield_tilemap->set_scrollx(0, data);
|
||||
m_playfield_xscroll = data & 0x1ff;
|
||||
}
|
||||
break;
|
||||
|
||||
case 4: /* /MOHS */
|
||||
if (m_mob->xscroll() != (data & 0x1ff))
|
||||
{
|
||||
m_screen->update_partial(scanline - 1);
|
||||
m_mob->set_xscroll(data & 0x1ff);
|
||||
}
|
||||
break;
|
||||
|
||||
case 5: /* /PFSPC */
|
||||
break;
|
||||
|
||||
case 6: /* /VIRQ */
|
||||
scanline_interrupt();
|
||||
break;
|
||||
|
||||
case 7: /* /PFVS */
|
||||
{
|
||||
/* a new vscroll latches the offset into a counter; we must adjust for this */
|
||||
int offset = scanline;
|
||||
const rectangle &visible_area = m_screen->visible_area();
|
||||
if (offset > visible_area.bottom())
|
||||
offset -= visible_area.bottom() + 1;
|
||||
|
||||
if (m_playfield_yscroll != ((data - offset) & 0x1ff))
|
||||
{
|
||||
m_screen->update_partial(scanline - 1);
|
||||
m_playfield_tilemap->set_scrolly(0, data - offset);
|
||||
m_mob->set_yscroll((data - offset) & 0x1ff);
|
||||
}
|
||||
break;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
|
||||
/*************************************
|
||||
*
|
||||
* Main refresh
|
||||
*
|
||||
*************************************/
|
||||
|
||||
uint32_t vindictr_state::screen_update_vindictr(screen_device &screen, bitmap_ind16 &bitmap, const rectangle &cliprect)
|
||||
{
|
||||
// start drawing
|
||||
m_mob->draw_async(cliprect);
|
||||
|
||||
/* draw the playfield */
|
||||
m_playfield_tilemap->draw(screen, bitmap, cliprect, 0, 0);
|
||||
|
||||
// draw and merge the MO
|
||||
bitmap_ind16 &mobitmap = m_mob->bitmap();
|
||||
for (const sparse_dirty_rect *rect = m_mob->first_dirty_rect(cliprect); rect != nullptr; rect = rect->next())
|
||||
for (int y = rect->top(); y <= rect->bottom(); y++)
|
||||
{
|
||||
uint16_t const *const mo = &mobitmap.pix(y);
|
||||
uint16_t *const pf = &bitmap.pix(y);
|
||||
for (int x = rect->left(); x <= rect->right(); x++)
|
||||
if (mo[x] != 0xffff)
|
||||
{
|
||||
/* partially verified via schematics (there are a lot of PALs involved!):
|
||||
|
||||
SHADE = PAL(MPR1-0, LB7-0, PFX6-5, PFX3-2, PF/M)
|
||||
|
||||
if (SHADE)
|
||||
CRA |= 0x100
|
||||
|
||||
MOG3-1 = ~MAT3-1 if MAT6==1 and MSD3==1
|
||||
*/
|
||||
int const mopriority = mo[x] >> atari_motion_objects_device::PRIORITY_SHIFT;
|
||||
|
||||
/* upper bit of MO priority signals special rendering and doesn't draw anything */
|
||||
if (mopriority & 4)
|
||||
continue;
|
||||
|
||||
/* MO pen 1 doesn't draw, but it sets the SHADE flag and bumps the palette offset */
|
||||
if ((mo[x] & 0x0f) == 1)
|
||||
{
|
||||
if ((mo[x] & 0xf0) != 0)
|
||||
pf[x] |= 0x100;
|
||||
}
|
||||
else
|
||||
pf[x] = mo[x] & atari_motion_objects_device::DATA_MASK;
|
||||
|
||||
/* don't erase yet -- we need to make another pass later */
|
||||
}
|
||||
}
|
||||
|
||||
/* add the alpha on top */
|
||||
m_alpha_tilemap->draw(screen, bitmap, cliprect, 0, 0);
|
||||
|
||||
/* now go back and process the upper bit of MO priority */
|
||||
for (const sparse_dirty_rect *rect = m_mob->first_dirty_rect(cliprect); rect != nullptr; rect = rect->next())
|
||||
for (int y = rect->top(); y <= rect->bottom(); y++)
|
||||
{
|
||||
uint16_t const *const mo = &mobitmap.pix(y);
|
||||
uint16_t *const pf = &bitmap.pix(y);
|
||||
for (int x = rect->left(); x <= rect->right(); x++)
|
||||
if (mo[x] != 0xffff)
|
||||
{
|
||||
int mopriority = mo[x] >> atari_motion_objects_device::PRIORITY_SHIFT;
|
||||
|
||||
/* upper bit of MO priority might mean palette kludges */
|
||||
if (mopriority & 4)
|
||||
{
|
||||
/* if bit 2 is set, start setting high palette bits */
|
||||
if (mo[x] & 2)
|
||||
m_mob->apply_stain(bitmap, pf, mo, x, y);
|
||||
|
||||
/* if the upper bit of pen data is set, we adjust the final intensity */
|
||||
if (mo[x] & 8)
|
||||
pf[x] |= (~mo[x] & 0xe0) << 6;
|
||||
}
|
||||
}
|
||||
}
|
||||
return 0;
|
||||
}
|
@ -1,5 +1,6 @@
|
||||
// license:BSD-3-Clause
|
||||
// copyright-holders:Stefan Jokisch
|
||||
|
||||
/***************************************************************************
|
||||
|
||||
Atari Wolf Pack (prototype) driver
|
||||
@ -7,13 +8,397 @@
|
||||
***************************************************************************/
|
||||
|
||||
#include "emu.h"
|
||||
#include "wolfpack.h"
|
||||
|
||||
#include "cpu/m6502/m6502.h"
|
||||
#include "machine/watchdog.h"
|
||||
#include "sound/s14001a.h"
|
||||
|
||||
#include "emupal.h"
|
||||
#include "screen.h"
|
||||
#include "speaker.h"
|
||||
|
||||
|
||||
namespace {
|
||||
|
||||
class wolfpack_state : public driver_device
|
||||
{
|
||||
public:
|
||||
wolfpack_state(const machine_config &mconfig, device_type type, const char *tag) :
|
||||
driver_device(mconfig, type, tag),
|
||||
m_alpha_num_ram(*this, "alpha_num_ram"),
|
||||
m_maincpu(*this, "maincpu"),
|
||||
m_s14001a(*this, "speech"),
|
||||
m_gfxdecode(*this, "gfxdecode"),
|
||||
m_screen(*this, "screen"),
|
||||
m_palette(*this, "palette"),
|
||||
m_dial(*this, "DIAL"),
|
||||
m_led(*this, "led0")
|
||||
{ }
|
||||
|
||||
void wolfpack(machine_config &config);
|
||||
|
||||
template <int Bit> DECLARE_READ_LINE_MEMBER(dial_r);
|
||||
|
||||
protected:
|
||||
virtual void machine_start() override;
|
||||
virtual void machine_reset() override;
|
||||
virtual void video_start() override;
|
||||
|
||||
private:
|
||||
// devices, pointers
|
||||
required_shared_ptr<uint8_t> m_alpha_num_ram;
|
||||
required_device<cpu_device> m_maincpu;
|
||||
required_device<s14001a_device> m_s14001a;
|
||||
required_device<gfxdecode_device> m_gfxdecode;
|
||||
required_device<screen_device> m_screen;
|
||||
required_device<palette_device> m_palette;
|
||||
required_ioport m_dial;
|
||||
output_finder<> m_led;
|
||||
|
||||
bool m_collision = false;
|
||||
unsigned m_current_index = 0;
|
||||
uint8_t m_video_invert = 0;
|
||||
uint8_t m_ship_reflect = 0;
|
||||
uint8_t m_pt_pos_select = 0;
|
||||
uint8_t m_pt_horz = 0;
|
||||
uint8_t m_pt_pic = 0;
|
||||
uint8_t m_ship_h = 0;
|
||||
uint8_t m_torpedo_pic = 0;
|
||||
uint8_t m_ship_size = 0;
|
||||
uint8_t m_ship_h_precess = 0;
|
||||
uint8_t m_ship_pic = 0;
|
||||
uint8_t m_torpedo_h = 0;
|
||||
uint8_t m_torpedo_v = 0;
|
||||
std::unique_ptr<uint8_t[]> m_lfsr;
|
||||
bitmap_ind16 m_helper;
|
||||
emu_timer *m_periodic_timer = nullptr;
|
||||
|
||||
void main_map(address_map &map);
|
||||
|
||||
void wolfpack_palette(palette_device &palette) const;
|
||||
|
||||
uint32_t screen_update(screen_device &screen, bitmap_ind16 &bitmap, const rectangle &cliprect);
|
||||
DECLARE_WRITE_LINE_MEMBER(screen_vblank);
|
||||
TIMER_CALLBACK_MEMBER(periodic_callback);
|
||||
void draw_ship(bitmap_ind16 &bitmap, const rectangle &cliprect);
|
||||
void draw_torpedo(bitmap_ind16 &bitmap, const rectangle &cliprect);
|
||||
void draw_pt(bitmap_ind16 &bitmap, const rectangle &cliprect);
|
||||
void draw_water(palette_device &palette, bitmap_ind16 &bitmap, const rectangle &cliprect);
|
||||
|
||||
uint8_t misc_r();
|
||||
void high_explo_w(uint8_t data);
|
||||
void sonar_ping_w(uint8_t data);
|
||||
void sirlat_w(uint8_t data);
|
||||
void pt_sound_w(uint8_t data);
|
||||
void launch_torpedo_w(uint8_t data);
|
||||
void low_explo_w(uint8_t data);
|
||||
void screw_cont_w(uint8_t data);
|
||||
void lamp_flash_w(uint8_t data);
|
||||
void warning_light_w(uint8_t data);
|
||||
void audamp_w(uint8_t data);
|
||||
void attract_w(uint8_t data);
|
||||
void credit_w(uint8_t data);
|
||||
void coldetres_w(uint8_t data);
|
||||
void ship_size_w(uint8_t data);
|
||||
void video_invert_w(uint8_t data);
|
||||
void ship_reflect_w(uint8_t data);
|
||||
void pt_pos_select_w(uint8_t data);
|
||||
void pt_horz_w(uint8_t data);
|
||||
void pt_pic_w(uint8_t data);
|
||||
void ship_h_w(uint8_t data);
|
||||
void torpedo_pic_w(uint8_t data);
|
||||
void ship_h_precess_w(uint8_t data);
|
||||
void ship_pic_w(uint8_t data);
|
||||
void torpedo_h_w(uint8_t data);
|
||||
void torpedo_v_w(uint8_t data);
|
||||
void word_w(uint8_t data);
|
||||
void start_speech_w(uint8_t data);
|
||||
};
|
||||
|
||||
|
||||
// video
|
||||
|
||||
void wolfpack_state::wolfpack_palette(palette_device &palette) const
|
||||
{
|
||||
palette.set_indirect_color(0, rgb_t(0x00, 0x00, 0x00));
|
||||
palette.set_indirect_color(1, rgb_t(0xc1, 0xc1, 0xc1));
|
||||
palette.set_indirect_color(2, rgb_t(0x81, 0x81, 0x81));
|
||||
palette.set_indirect_color(3, rgb_t(0x48, 0x48, 0x48));
|
||||
|
||||
for (int i = 0; i < 4; i++)
|
||||
{
|
||||
rgb_t const color = palette.indirect_color(i);
|
||||
palette.set_indirect_color(
|
||||
4 + i,
|
||||
rgb_t(
|
||||
(color.r() < 0xb8) ? (color.r() + 0x48) : 0xff,
|
||||
(color.g() < 0xb8) ? (color.g() + 0x48) : 0xff,
|
||||
(color.b() < 0xb8) ? (color.b() + 0x48) : 0xff));
|
||||
}
|
||||
|
||||
palette.set_pen_indirect(0x00, 0);
|
||||
palette.set_pen_indirect(0x01, 1);
|
||||
palette.set_pen_indirect(0x02, 1);
|
||||
palette.set_pen_indirect(0x03, 0);
|
||||
palette.set_pen_indirect(0x04, 0);
|
||||
palette.set_pen_indirect(0x05, 2);
|
||||
palette.set_pen_indirect(0x06, 0);
|
||||
palette.set_pen_indirect(0x07, 3);
|
||||
palette.set_pen_indirect(0x08, 4);
|
||||
palette.set_pen_indirect(0x09, 5);
|
||||
palette.set_pen_indirect(0x0a, 6);
|
||||
palette.set_pen_indirect(0x0b, 7);
|
||||
}
|
||||
|
||||
|
||||
void wolfpack_state::ship_size_w(uint8_t data)
|
||||
{
|
||||
m_ship_size = data;
|
||||
}
|
||||
void wolfpack_state::video_invert_w(uint8_t data)
|
||||
{
|
||||
m_video_invert = data & 1;
|
||||
}
|
||||
void wolfpack_state::ship_reflect_w(uint8_t data)
|
||||
{
|
||||
m_ship_reflect = data & 1;
|
||||
}
|
||||
void wolfpack_state::pt_pos_select_w(uint8_t data)
|
||||
{
|
||||
m_pt_pos_select = data & 1;
|
||||
}
|
||||
void wolfpack_state::pt_horz_w(uint8_t data)
|
||||
{
|
||||
m_pt_horz = data;
|
||||
}
|
||||
void wolfpack_state::pt_pic_w(uint8_t data)
|
||||
{
|
||||
m_pt_pic = data & 0x3f;
|
||||
}
|
||||
void wolfpack_state::ship_h_w(uint8_t data)
|
||||
{
|
||||
m_ship_h = data;
|
||||
}
|
||||
void wolfpack_state::torpedo_pic_w(uint8_t data)
|
||||
{
|
||||
m_torpedo_pic = data;
|
||||
}
|
||||
void wolfpack_state::ship_h_precess_w(uint8_t data)
|
||||
{
|
||||
m_ship_h_precess = data & 0x3f;
|
||||
}
|
||||
void wolfpack_state::ship_pic_w(uint8_t data)
|
||||
{
|
||||
m_ship_pic = data & 0x0f;
|
||||
}
|
||||
void wolfpack_state::torpedo_h_w(uint8_t data)
|
||||
{
|
||||
m_torpedo_h = data;
|
||||
}
|
||||
void wolfpack_state::torpedo_v_w(uint8_t data)
|
||||
{
|
||||
m_torpedo_v = data;
|
||||
}
|
||||
|
||||
|
||||
void wolfpack_state::video_start()
|
||||
{
|
||||
m_screen->register_screen_bitmap(m_helper);
|
||||
|
||||
m_lfsr = std::make_unique<uint8_t []>(0x8000);
|
||||
for (uint16_t i = 0, val = 0; i < 0x8000; i++)
|
||||
{
|
||||
uint16_t const bit = ~(val ^ (val >> 14)) & 1;
|
||||
val = (val << 1) | bit;
|
||||
m_lfsr[i] = (val & 0x0c00) == 0x0c00;
|
||||
}
|
||||
|
||||
m_current_index = 0x80;
|
||||
|
||||
save_item(NAME(m_collision));
|
||||
save_item(NAME(m_current_index));
|
||||
save_item(NAME(m_video_invert));
|
||||
save_item(NAME(m_ship_reflect));
|
||||
save_item(NAME(m_pt_pos_select));
|
||||
save_item(NAME(m_pt_horz));
|
||||
save_item(NAME(m_pt_pic));
|
||||
save_item(NAME(m_ship_h));
|
||||
save_item(NAME(m_torpedo_pic));
|
||||
save_item(NAME(m_ship_size));
|
||||
save_item(NAME(m_ship_h_precess));
|
||||
save_item(NAME(m_ship_pic));
|
||||
save_item(NAME(m_torpedo_h));
|
||||
save_item(NAME(m_torpedo_v));
|
||||
}
|
||||
|
||||
|
||||
void wolfpack_state::draw_ship(bitmap_ind16 &bitmap, const rectangle &cliprect)
|
||||
{
|
||||
static const uint32_t scaler[] =
|
||||
{
|
||||
0x00000, 0x00500, 0x00a00, 0x01000,
|
||||
0x01000, 0x01200, 0x01500, 0x01800,
|
||||
0x01800, 0x01d00, 0x02200, 0x02800,
|
||||
0x02800, 0x02800, 0x02800, 0x02800,
|
||||
0x02800, 0x03000, 0x03800, 0x04000,
|
||||
0x04000, 0x04500, 0x04a00, 0x05000,
|
||||
0x05000, 0x05500, 0x05a00, 0x06000,
|
||||
0x06000, 0x06a00, 0x07500, 0x08000,
|
||||
0x08000, 0x08a00, 0x09500, 0x0a000,
|
||||
0x0a000, 0x0b000, 0x0c000, 0x0d000,
|
||||
0x0d000, 0x0e000, 0x0f000, 0x10000,
|
||||
0x10000, 0x11a00, 0x13500, 0x15000,
|
||||
0x15000, 0x17500, 0x19a00, 0x1c000,
|
||||
0x1c000, 0x1ea00, 0x21500, 0x24000,
|
||||
0x24000, 0x26a00, 0x29500, 0x2c000,
|
||||
0x2c000, 0x2fa00, 0x33500, 0x37000
|
||||
};
|
||||
|
||||
int const chop = (scaler[m_ship_size >> 2] * m_ship_h_precess) >> 16;
|
||||
|
||||
|
||||
m_gfxdecode->gfx(1)->zoom_transpen(bitmap, cliprect,
|
||||
m_ship_pic,
|
||||
0,
|
||||
m_ship_reflect, 0,
|
||||
2 * (m_ship_h - chop),
|
||||
128,
|
||||
2 * scaler[m_ship_size >> 2], scaler[m_ship_size >> 2], 0);
|
||||
}
|
||||
|
||||
|
||||
void wolfpack_state::draw_torpedo(bitmap_ind16 &bitmap, const rectangle &cliprect)
|
||||
{
|
||||
int count = 0;
|
||||
|
||||
m_gfxdecode->gfx(3)->transpen(bitmap, cliprect,
|
||||
m_torpedo_pic,
|
||||
0,
|
||||
0, 0,
|
||||
2 * (244 - m_torpedo_h),
|
||||
224 - m_torpedo_v, 0);
|
||||
|
||||
for (int y = 16; y < 224 - m_torpedo_v; y++)
|
||||
{
|
||||
if (y % 16 == 1)
|
||||
count = (count - 1) & 7;
|
||||
|
||||
int const x1 = 248 - m_torpedo_h - count;
|
||||
int const x2 = 248 - m_torpedo_h + count;
|
||||
|
||||
for (int x = 2 * x1; x < 2 * x2; x++)
|
||||
if (m_lfsr[(m_current_index + 0x300 * y + x) % 0x8000])
|
||||
bitmap.pix(y, x) = 1;
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
void wolfpack_state::draw_pt(bitmap_ind16 &bitmap, const rectangle &cliprect)
|
||||
{
|
||||
rectangle rect(cliprect);
|
||||
rect.setx(
|
||||
(m_pt_pic & 0x20) ? rect.left() : 256,
|
||||
(m_pt_pic & 0x10) ? rect.right() : 255);
|
||||
|
||||
m_gfxdecode->gfx(2)->transpen(bitmap, rect,
|
||||
m_pt_pic,
|
||||
0,
|
||||
0, 0,
|
||||
2 * m_pt_horz,
|
||||
m_pt_pos_select ? 0x70 : 0xa0, 0);
|
||||
|
||||
|
||||
m_gfxdecode->gfx(2)->transpen(bitmap, rect,
|
||||
m_pt_pic,
|
||||
0,
|
||||
0, 0,
|
||||
2 * m_pt_horz - 512,
|
||||
m_pt_pos_select ? 0x70 : 0xa0, 0);
|
||||
}
|
||||
|
||||
|
||||
void wolfpack_state::draw_water(palette_device &palette, bitmap_ind16 &bitmap, const rectangle &cliprect)
|
||||
{
|
||||
for (int y = cliprect.top(); y <= (std::min)(cliprect.bottom(), 127); y++)
|
||||
{
|
||||
uint16_t *const p = &bitmap.pix(y);
|
||||
|
||||
for (int x = cliprect.left(); x <= cliprect.right(); x++)
|
||||
p[x] = palette.pen_indirect(p[x]) | 0x08;
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
uint32_t wolfpack_state::screen_update(screen_device &screen, bitmap_ind16 &bitmap, const rectangle &cliprect)
|
||||
{
|
||||
uint8_t color = 0x48;
|
||||
if (m_ship_size & 0x10) color += 0x13;
|
||||
if (m_ship_size & 0x20) color += 0x22;
|
||||
if (m_ship_size & 0x40) color += 0x3a;
|
||||
if (m_ship_size & 0x80) color += 0x48;
|
||||
|
||||
m_palette->set_indirect_color(3, rgb_t(color,color,color));
|
||||
m_palette->set_indirect_color(7, rgb_t(color < 0xb8 ? color + 0x48 : 0xff,
|
||||
color < 0xb8 ? color + 0x48 : 0xff,
|
||||
color < 0xb8 ? color + 0x48 : 0xff));
|
||||
|
||||
bitmap.fill(m_video_invert, cliprect);
|
||||
|
||||
for (int i = 0; i < 8; i++)
|
||||
for (int j = 0; j < 32; j++)
|
||||
{
|
||||
int const code = m_alpha_num_ram[32 * i + j];
|
||||
|
||||
|
||||
m_gfxdecode->gfx(0)->opaque(bitmap, cliprect,
|
||||
code,
|
||||
m_video_invert,
|
||||
0, 0,
|
||||
16 * j,
|
||||
192 + 8 * i);
|
||||
}
|
||||
|
||||
draw_pt(bitmap, cliprect);
|
||||
draw_ship(bitmap, cliprect);
|
||||
draw_torpedo(bitmap, cliprect);
|
||||
draw_water(*m_palette, bitmap, cliprect);
|
||||
return 0;
|
||||
}
|
||||
|
||||
|
||||
WRITE_LINE_MEMBER(wolfpack_state::screen_vblank)
|
||||
{
|
||||
// rising edge
|
||||
if (state)
|
||||
{
|
||||
m_helper.fill(0);
|
||||
|
||||
draw_ship(m_helper, m_helper.cliprect());
|
||||
|
||||
for (int y = 128; y < 224 - m_torpedo_v; y++)
|
||||
{
|
||||
int x1 = 248 - m_torpedo_h - 1;
|
||||
int x2 = 248 - m_torpedo_h + 1;
|
||||
|
||||
for (int x = 2 * x1; x < 2 * x2; x++)
|
||||
{
|
||||
if (x < 0 || x >= m_helper.width())
|
||||
continue;
|
||||
if (y < 0 || y >= m_helper.height())
|
||||
continue;
|
||||
|
||||
if (m_helper.pix(y, x))
|
||||
m_collision = 1;
|
||||
}
|
||||
}
|
||||
|
||||
m_current_index += 0x300 * 262;
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
// machine
|
||||
|
||||
TIMER_CALLBACK_MEMBER(wolfpack_state::periodic_callback)
|
||||
{
|
||||
int scanline = param;
|
||||
@ -43,7 +428,7 @@ void wolfpack_state::machine_reset()
|
||||
template <int Bit>
|
||||
READ_LINE_MEMBER(wolfpack_state::dial_r)
|
||||
{
|
||||
return ((ioport("DIAL")->read() + Bit) / 2) & 0x01;
|
||||
return ((m_dial->read() + Bit) / 2) & 0x01;
|
||||
}
|
||||
|
||||
|
||||
@ -51,14 +436,14 @@ uint8_t wolfpack_state::misc_r()
|
||||
{
|
||||
uint8_t val = 0;
|
||||
|
||||
/* BIT0 => SPEECH BUSY */
|
||||
/* BIT1 => COMP SIREN */
|
||||
/* BIT2 => SPARE */
|
||||
/* BIT3 => SPARE */
|
||||
/* BIT4 => COL DETECT */
|
||||
/* BIT5 => UNUSED */
|
||||
/* BIT6 => UNUSED */
|
||||
/* BIT7 => VBLANK */
|
||||
// BIT0 => SPEECH BUSY
|
||||
// BIT1 => COMP SIREN
|
||||
// BIT2 => SPARE
|
||||
// BIT3 => SPARE
|
||||
// BIT4 => COL DETECT
|
||||
// BIT5 => UNUSED
|
||||
// BIT6 => UNUSED
|
||||
// BIT7 => VBLANK
|
||||
|
||||
if (!m_s14001a->busy_r())
|
||||
val |= 0x01;
|
||||
@ -73,7 +458,7 @@ uint8_t wolfpack_state::misc_r()
|
||||
}
|
||||
|
||||
|
||||
void wolfpack_state::high_explo_w(uint8_t data){ }
|
||||
void wolfpack_state::high_explo_w(uint8_t data){}
|
||||
void wolfpack_state::sonar_ping_w(uint8_t data){}
|
||||
void wolfpack_state::sirlat_w(uint8_t data){}
|
||||
void wolfpack_state::pt_sound_w(uint8_t data){}
|
||||
@ -86,14 +471,14 @@ void wolfpack_state::audamp_w(uint8_t data){}
|
||||
|
||||
void wolfpack_state::word_w(uint8_t data)
|
||||
{
|
||||
/* latch word from bus into temp register, and place on s14001a input bus */
|
||||
/* there is no real need for a temp register at all, since the bus 'register' acts as one */
|
||||
m_s14001a->data_w(data & 0x1f); /* SA0 (IN5) is pulled low according to the schematic, so its 0x1f and not 0x3f as one would expect */
|
||||
// latch word from bus into temp register, and place on s14001a input bus
|
||||
// there is no real need for a temp register at all, since the bus 'register' acts as one
|
||||
m_s14001a->data_w(data & 0x1f); // SA0 (IN5) is pulled low according to the schematic, so it's 0x1f and not 0x3f as one would expect
|
||||
}
|
||||
|
||||
void wolfpack_state::start_speech_w(uint8_t data)
|
||||
{
|
||||
m_s14001a->start_w(data&1);
|
||||
m_s14001a->start_w(data & 1);
|
||||
}
|
||||
|
||||
|
||||
@ -119,7 +504,7 @@ void wolfpack_state::main_map(address_map &map)
|
||||
{
|
||||
map(0x0000, 0x00ff).ram().mirror(0x100);
|
||||
map(0x1000, 0x1000).portr("INPUTS");
|
||||
map(0x1000, 0x10ff).writeonly().share("alpha_num_ram");
|
||||
map(0x1000, 0x10ff).writeonly().share(m_alpha_num_ram);
|
||||
map(0x2000, 0x2000).r(FUNC(wolfpack_state::misc_r));
|
||||
map(0x2000, 0x2000).w(FUNC(wolfpack_state::high_explo_w));
|
||||
map(0x2001, 0x2001).w(FUNC(wolfpack_state::sonar_ping_w));
|
||||
@ -151,7 +536,7 @@ void wolfpack_state::main_map(address_map &map)
|
||||
map(0x4006, 0x4006).w(FUNC(wolfpack_state::torpedo_v_w));
|
||||
map(0x5000, 0x5fff).w("watchdog", FUNC(watchdog_timer_device::reset_w));
|
||||
map(0x7000, 0x7fff).rom();
|
||||
map(0x9000, 0x9000).nopr(); /* debugger ROM location? */
|
||||
map(0x9000, 0x9000).nopr(); // debugger ROM location?
|
||||
map(0xf000, 0xffff).rom();
|
||||
}
|
||||
|
||||
@ -181,7 +566,7 @@ static INPUT_PORTS_START( wolfpack )
|
||||
PORT_DIPSETTING( 0x08, "97 seconds" )
|
||||
PORT_DIPSETTING( 0x10, "130 seconds" )
|
||||
PORT_DIPSETTING( 0x18, "160 seconds" )
|
||||
PORT_DIPNAME( 0x20, 0x00, DEF_STR( Unknown ) ) /* demo sound? */
|
||||
PORT_DIPNAME( 0x20, 0x00, DEF_STR( Unknown ) ) // demo sound?
|
||||
PORT_DIPSETTING( 0x20, DEF_STR( Off ) )
|
||||
PORT_DIPSETTING( 0x00, DEF_STR( On ) )
|
||||
PORT_DIPNAME( 0xc0, 0x80, "Score for Extended Play" )
|
||||
@ -286,22 +671,22 @@ static const gfx_layout torpedo_layout =
|
||||
|
||||
|
||||
static GFXDECODE_START( gfx_wolfpack )
|
||||
GFXDECODE_ENTRY( "gfx1", 0, tile_layout, 0, 2 )
|
||||
GFXDECODE_ENTRY( "gfx2", 0, ship_layout, 6, 1 )
|
||||
GFXDECODE_ENTRY( "gfx3", 0, pt_layout, 0, 1 )
|
||||
GFXDECODE_ENTRY( "gfx4", 0, torpedo_layout, 4, 1 )
|
||||
GFXDECODE_ENTRY( "tile", 0, tile_layout, 0, 2 )
|
||||
GFXDECODE_ENTRY( "ship", 0, ship_layout, 6, 1 )
|
||||
GFXDECODE_ENTRY( "pt", 0, pt_layout, 0, 1 )
|
||||
GFXDECODE_ENTRY( "torpedo", 0, torpedo_layout, 4, 1 )
|
||||
GFXDECODE_END
|
||||
|
||||
|
||||
void wolfpack_state::wolfpack(machine_config &config)
|
||||
{
|
||||
/* basic machine hardware */
|
||||
M6502(config, m_maincpu, 12096000 / 16);
|
||||
// basic machine hardware
|
||||
M6502(config, m_maincpu, 12'096'000 / 16);
|
||||
m_maincpu->set_addrmap(AS_PROGRAM, &wolfpack_state::main_map);
|
||||
|
||||
WATCHDOG_TIMER(config, "watchdog");
|
||||
|
||||
/* video hardware */
|
||||
// video hardware
|
||||
SCREEN(config, m_screen, SCREEN_TYPE_RASTER);
|
||||
m_screen->set_refresh_hz(60);
|
||||
m_screen->set_size(512, 262);
|
||||
@ -313,9 +698,9 @@ void wolfpack_state::wolfpack(machine_config &config)
|
||||
GFXDECODE(config, m_gfxdecode, m_palette, gfx_wolfpack);
|
||||
PALETTE(config, m_palette, FUNC(wolfpack_state::wolfpack_palette), 12, 8);
|
||||
|
||||
/* sound hardware */
|
||||
// sound hardware
|
||||
SPEAKER(config, "mono").front_center();
|
||||
S14001A(config, m_s14001a, 20000); /* RC Clock (C=100pf, R=470K-670K ohms, adjustable) ranging from 14925.37313hz to 21276.59574hz, likely factory set to 20000hz since anything below 19500 is too slow */
|
||||
S14001A(config, m_s14001a, 20'000); // RC Clock (C=100pf, R=470K-670K ohms, adjustable) ranging from 14925.37313hz to 21276.59574hz, likely factory set to 20000hz since anything below 19500 is too slow
|
||||
m_s14001a->add_route(ALL_OUTPUTS, "mono", 1.00);
|
||||
}
|
||||
|
||||
@ -323,31 +708,33 @@ void wolfpack_state::wolfpack(machine_config &config)
|
||||
ROM_START( wolfpack )
|
||||
ROM_REGION( 0x10000, "maincpu", 0 )
|
||||
ROM_LOAD_NIB_LOW ( "30285.e3", 0x7000, 0x0800, CRC(b4d30b33) SHA1(46645c227828632b57244bdccad455e1831b5273) )
|
||||
ROM_RELOAD ( 0xF000, 0x0800 )
|
||||
ROM_RELOAD ( 0xf000, 0x0800 )
|
||||
ROM_LOAD_NIB_HIGH( "30287.g3", 0x7000, 0x0800, CRC(c6300dc9) SHA1(6a0ec0bfa6ad4c870aa6f21bfde094da6975b58b) )
|
||||
ROM_RELOAD ( 0xF000, 0x0800 )
|
||||
ROM_RELOAD ( 0xf000, 0x0800 )
|
||||
ROM_LOAD_NIB_LOW ( "30286.f3", 0x7800, 0x0800, CRC(17dce9e8) SHA1(9c7bac1aa676548dc7908f1518efd58c72645ab7) )
|
||||
ROM_RELOAD ( 0xF800, 0x0800 )
|
||||
ROM_RELOAD ( 0xf800, 0x0800 )
|
||||
ROM_LOAD_NIB_HIGH( "30288.h3", 0x7800, 0x0800, CRC(b80ab7b6) SHA1(f2ede98ac5337064499ae2262a8a81f83505bd66) )
|
||||
ROM_RELOAD ( 0xF800, 0x0800 )
|
||||
ROM_RELOAD ( 0xf800, 0x0800 )
|
||||
|
||||
ROM_REGION( 0x0400, "gfx1", 0 )
|
||||
ROM_REGION( 0x0400, "tile", 0 )
|
||||
ROM_LOAD( "30291.c1", 0x0000, 0x0400, CRC(7e3d22cf) SHA1(92e6bbe049dc8fcd674f2ff96cde3786f714508d) )
|
||||
|
||||
ROM_REGION( 0x1000, "gfx2", 0 )
|
||||
ROM_REGION( 0x1000, "ship", 0 )
|
||||
ROM_LOAD( "30289.j6", 0x0000, 0x0800, CRC(f63e5629) SHA1(d64f19fc62060d395df5bb8663a7694a23b0aa2e) )
|
||||
ROM_LOAD( "30290.k6", 0x0800, 0x0800, CRC(70d5430e) SHA1(d512fc3bb0cf0816a1c987f7188c4b331303347f) )
|
||||
|
||||
ROM_REGION( 0x0400, "gfx3", 0 )
|
||||
ROM_REGION( 0x0400, "pt", 0 )
|
||||
ROM_LOAD( "30294.p4", 0x0000, 0x0400, CRC(ea93f4b9) SHA1(48b4e0136f5349eb53fea7127a969d87457d70f9) )
|
||||
|
||||
ROM_REGION( 0x0400, "gfx4", 0 )
|
||||
ROM_REGION( 0x0400, "torpedo", 0 )
|
||||
ROM_LOAD( "30293.m6", 0x0000, 0x0400, CRC(11900d47) SHA1(2dcb3c3488a5e9ed7f1751649f8dc25696f0f57a) )
|
||||
|
||||
ROM_REGION( 0x0800, "speech", 0 ) /* voice data */
|
||||
ROM_REGION( 0x0800, "speech", 0 )
|
||||
ROM_LOAD_NIB_LOW ( "30863.r1", 0x0000, 0x0800, CRC(3f779f13) SHA1(8ed8a1bf680e8277066416f467388e3875e8cbbd) )
|
||||
ROM_LOAD_NIB_HIGH( "30864.r3", 0x0000, 0x0800, CRC(c4a58d1d) SHA1(a2ba9354b99c739bbfa94458d671c109be163ca0) )
|
||||
ROM_END
|
||||
|
||||
} // anonymous namespace
|
||||
|
||||
|
||||
GAME( 1978, wolfpack, 0, wolfpack, wolfpack, wolfpack_state, empty_init, ORIENTATION_FLIP_Y, "Atari", "Wolf Pack (prototype)", MACHINE_IMPERFECT_SOUND | MACHINE_SUPPORTS_SAVE )
|
||||
|
@ -1,109 +0,0 @@
|
||||
// license:BSD-3-Clause
|
||||
// copyright-holders:Stefan Jokisch
|
||||
/***************************************************************************
|
||||
|
||||
Atari Wolf Pack (prototype) driver
|
||||
|
||||
***************************************************************************/
|
||||
#ifndef MAME_ATARI_WOLFPACK_H
|
||||
#define MAME_ATARI_WOLFPACK_H
|
||||
|
||||
#pragma once
|
||||
|
||||
#include "sound/s14001a.h"
|
||||
#include "emupal.h"
|
||||
#include "screen.h"
|
||||
|
||||
class wolfpack_state : public driver_device
|
||||
{
|
||||
public:
|
||||
wolfpack_state(const machine_config &mconfig, device_type type, const char *tag) :
|
||||
driver_device(mconfig, type, tag),
|
||||
m_alpha_num_ram(*this, "alpha_num_ram"),
|
||||
m_maincpu(*this, "maincpu"),
|
||||
m_s14001a(*this, "speech"),
|
||||
m_gfxdecode(*this, "gfxdecode"),
|
||||
m_screen(*this, "screen"),
|
||||
m_palette(*this, "palette"),
|
||||
m_led(*this, "led0")
|
||||
{ }
|
||||
|
||||
void wolfpack(machine_config &config);
|
||||
|
||||
template <int Bit> DECLARE_READ_LINE_MEMBER(dial_r);
|
||||
|
||||
private:
|
||||
virtual void machine_start() override;
|
||||
virtual void machine_reset() override;
|
||||
virtual void video_start() override;
|
||||
|
||||
void main_map(address_map &map);
|
||||
|
||||
void wolfpack_palette(palette_device &palette) const;
|
||||
|
||||
uint32_t screen_update(screen_device &screen, bitmap_ind16 &bitmap, const rectangle &cliprect);
|
||||
DECLARE_WRITE_LINE_MEMBER(screen_vblank);
|
||||
TIMER_CALLBACK_MEMBER(periodic_callback);
|
||||
void draw_ship(bitmap_ind16 &bitmap, const rectangle &cliprect);
|
||||
void draw_torpedo(bitmap_ind16 &bitmap, const rectangle &cliprect);
|
||||
void draw_pt(bitmap_ind16 &bitmap, const rectangle &cliprect);
|
||||
void draw_water(palette_device &palette, bitmap_ind16 &bitmap, const rectangle &cliprect);
|
||||
|
||||
uint8_t misc_r();
|
||||
void high_explo_w(uint8_t data);
|
||||
void sonar_ping_w(uint8_t data);
|
||||
void sirlat_w(uint8_t data);
|
||||
void pt_sound_w(uint8_t data);
|
||||
void launch_torpedo_w(uint8_t data);
|
||||
void low_explo_w(uint8_t data);
|
||||
void screw_cont_w(uint8_t data);
|
||||
void lamp_flash_w(uint8_t data);
|
||||
void warning_light_w(uint8_t data);
|
||||
void audamp_w(uint8_t data);
|
||||
void attract_w(uint8_t data);
|
||||
void credit_w(uint8_t data);
|
||||
void coldetres_w(uint8_t data);
|
||||
void ship_size_w(uint8_t data);
|
||||
void video_invert_w(uint8_t data);
|
||||
void ship_reflect_w(uint8_t data);
|
||||
void pt_pos_select_w(uint8_t data);
|
||||
void pt_horz_w(uint8_t data);
|
||||
void pt_pic_w(uint8_t data);
|
||||
void ship_h_w(uint8_t data);
|
||||
void torpedo_pic_w(uint8_t data);
|
||||
void ship_h_precess_w(uint8_t data);
|
||||
void ship_pic_w(uint8_t data);
|
||||
void torpedo_h_w(uint8_t data);
|
||||
void torpedo_v_w(uint8_t data);
|
||||
void word_w(uint8_t data);
|
||||
void start_speech_w(uint8_t data);
|
||||
|
||||
// devices, pointers
|
||||
required_shared_ptr<uint8_t> m_alpha_num_ram;
|
||||
required_device<cpu_device> m_maincpu;
|
||||
required_device<s14001a_device> m_s14001a;
|
||||
required_device<gfxdecode_device> m_gfxdecode;
|
||||
required_device<screen_device> m_screen;
|
||||
required_device<palette_device> m_palette;
|
||||
output_finder<> m_led;
|
||||
|
||||
bool m_collision = false;
|
||||
unsigned m_current_index = 0;
|
||||
uint8_t m_video_invert = 0;
|
||||
uint8_t m_ship_reflect = 0;
|
||||
uint8_t m_pt_pos_select = 0;
|
||||
uint8_t m_pt_horz = 0;
|
||||
uint8_t m_pt_pic = 0;
|
||||
uint8_t m_ship_h = 0;
|
||||
uint8_t m_torpedo_pic = 0;
|
||||
uint8_t m_ship_size = 0;
|
||||
uint8_t m_ship_h_precess = 0;
|
||||
uint8_t m_ship_pic = 0;
|
||||
uint8_t m_torpedo_h = 0;
|
||||
uint8_t m_torpedo_v = 0;
|
||||
std::unique_ptr<uint8_t[]> m_LFSR;
|
||||
bitmap_ind16 m_helper;
|
||||
emu_timer *m_periodic_timer = nullptr;
|
||||
};
|
||||
|
||||
#endif // MAME_ATARI_WOLFPACK_H
|
@ -1,289 +0,0 @@
|
||||
// license:BSD-3-Clause
|
||||
// copyright-holders:Stefan Jokisch
|
||||
/***************************************************************************
|
||||
|
||||
Atari Wolf Pack (prototype) video emulation
|
||||
|
||||
***************************************************************************/
|
||||
|
||||
#include "emu.h"
|
||||
#include "wolfpack.h"
|
||||
|
||||
|
||||
void wolfpack_state::wolfpack_palette(palette_device &palette) const
|
||||
{
|
||||
palette.set_indirect_color(0, rgb_t(0x00, 0x00, 0x00));
|
||||
palette.set_indirect_color(1, rgb_t(0xc1, 0xc1, 0xc1));
|
||||
palette.set_indirect_color(2, rgb_t(0x81, 0x81, 0x81));
|
||||
palette.set_indirect_color(3, rgb_t(0x48, 0x48, 0x48));
|
||||
|
||||
for (int i = 0; i < 4; i++)
|
||||
{
|
||||
rgb_t const color = palette.indirect_color(i);
|
||||
palette.set_indirect_color(
|
||||
4 + i,
|
||||
rgb_t(
|
||||
(color.r() < 0xb8) ? (color.r() + 0x48) : 0xff,
|
||||
(color.g() < 0xb8) ? (color.g() + 0x48) : 0xff,
|
||||
(color.b() < 0xb8) ? (color.b() + 0x48) : 0xff));
|
||||
}
|
||||
|
||||
palette.set_pen_indirect(0x00, 0);
|
||||
palette.set_pen_indirect(0x01, 1);
|
||||
palette.set_pen_indirect(0x02, 1);
|
||||
palette.set_pen_indirect(0x03, 0);
|
||||
palette.set_pen_indirect(0x04, 0);
|
||||
palette.set_pen_indirect(0x05, 2);
|
||||
palette.set_pen_indirect(0x06, 0);
|
||||
palette.set_pen_indirect(0x07, 3);
|
||||
palette.set_pen_indirect(0x08, 4);
|
||||
palette.set_pen_indirect(0x09, 5);
|
||||
palette.set_pen_indirect(0x0a, 6);
|
||||
palette.set_pen_indirect(0x0b, 7);
|
||||
}
|
||||
|
||||
|
||||
void wolfpack_state::ship_size_w(uint8_t data)
|
||||
{
|
||||
m_ship_size = data;
|
||||
}
|
||||
void wolfpack_state::video_invert_w(uint8_t data)
|
||||
{
|
||||
m_video_invert = data & 1;
|
||||
}
|
||||
void wolfpack_state::ship_reflect_w(uint8_t data)
|
||||
{
|
||||
m_ship_reflect = data & 1;
|
||||
}
|
||||
void wolfpack_state::pt_pos_select_w(uint8_t data)
|
||||
{
|
||||
m_pt_pos_select = data & 1;
|
||||
}
|
||||
void wolfpack_state::pt_horz_w(uint8_t data)
|
||||
{
|
||||
m_pt_horz = data;
|
||||
}
|
||||
void wolfpack_state::pt_pic_w(uint8_t data)
|
||||
{
|
||||
m_pt_pic = data & 0x3f;
|
||||
}
|
||||
void wolfpack_state::ship_h_w(uint8_t data)
|
||||
{
|
||||
m_ship_h = data;
|
||||
}
|
||||
void wolfpack_state::torpedo_pic_w(uint8_t data)
|
||||
{
|
||||
m_torpedo_pic = data;
|
||||
}
|
||||
void wolfpack_state::ship_h_precess_w(uint8_t data)
|
||||
{
|
||||
m_ship_h_precess = data & 0x3f;
|
||||
}
|
||||
void wolfpack_state::ship_pic_w(uint8_t data)
|
||||
{
|
||||
m_ship_pic = data & 0x0f;
|
||||
}
|
||||
void wolfpack_state::torpedo_h_w(uint8_t data)
|
||||
{
|
||||
m_torpedo_h = data;
|
||||
}
|
||||
void wolfpack_state::torpedo_v_w(uint8_t data)
|
||||
{
|
||||
m_torpedo_v = data;
|
||||
}
|
||||
|
||||
|
||||
void wolfpack_state::video_start()
|
||||
{
|
||||
m_screen->register_screen_bitmap(m_helper);
|
||||
|
||||
m_LFSR = std::make_unique<uint8_t []>(0x8000);
|
||||
for (uint16_t i = 0, val = 0; i < 0x8000; i++)
|
||||
{
|
||||
uint16_t const bit = ~(val ^ (val >> 14)) & 1;
|
||||
val = (val << 1) | bit;
|
||||
m_LFSR[i] = (val & 0x0c00) == 0x0c00;
|
||||
}
|
||||
|
||||
m_current_index = 0x80;
|
||||
|
||||
save_item(NAME(m_collision));
|
||||
save_item(NAME(m_current_index));
|
||||
save_item(NAME(m_video_invert));
|
||||
save_item(NAME(m_ship_reflect));
|
||||
save_item(NAME(m_pt_pos_select));
|
||||
save_item(NAME(m_pt_horz));
|
||||
save_item(NAME(m_pt_pic));
|
||||
save_item(NAME(m_ship_h));
|
||||
save_item(NAME(m_torpedo_pic));
|
||||
save_item(NAME(m_ship_size));
|
||||
save_item(NAME(m_ship_h_precess));
|
||||
save_item(NAME(m_ship_pic));
|
||||
save_item(NAME(m_torpedo_h));
|
||||
save_item(NAME(m_torpedo_v));
|
||||
}
|
||||
|
||||
|
||||
void wolfpack_state::draw_ship(bitmap_ind16 &bitmap, const rectangle &cliprect)
|
||||
{
|
||||
static const uint32_t scaler[] =
|
||||
{
|
||||
0x00000, 0x00500, 0x00a00, 0x01000,
|
||||
0x01000, 0x01200, 0x01500, 0x01800,
|
||||
0x01800, 0x01d00, 0x02200, 0x02800,
|
||||
0x02800, 0x02800, 0x02800, 0x02800,
|
||||
0x02800, 0x03000, 0x03800, 0x04000,
|
||||
0x04000, 0x04500, 0x04a00, 0x05000,
|
||||
0x05000, 0x05500, 0x05a00, 0x06000,
|
||||
0x06000, 0x06a00, 0x07500, 0x08000,
|
||||
0x08000, 0x08a00, 0x09500, 0x0a000,
|
||||
0x0a000, 0x0b000, 0x0c000, 0x0d000,
|
||||
0x0d000, 0x0e000, 0x0f000, 0x10000,
|
||||
0x10000, 0x11a00, 0x13500, 0x15000,
|
||||
0x15000, 0x17500, 0x19a00, 0x1c000,
|
||||
0x1c000, 0x1ea00, 0x21500, 0x24000,
|
||||
0x24000, 0x26a00, 0x29500, 0x2c000,
|
||||
0x2c000, 0x2fa00, 0x33500, 0x37000
|
||||
};
|
||||
|
||||
int chop = (scaler[m_ship_size >> 2] * m_ship_h_precess) >> 16;
|
||||
|
||||
|
||||
m_gfxdecode->gfx(1)->zoom_transpen(bitmap,cliprect,
|
||||
m_ship_pic,
|
||||
0,
|
||||
m_ship_reflect, 0,
|
||||
2 * (m_ship_h - chop),
|
||||
128,
|
||||
2 * scaler[m_ship_size >> 2], scaler[m_ship_size >> 2], 0);
|
||||
}
|
||||
|
||||
|
||||
void wolfpack_state::draw_torpedo(bitmap_ind16 &bitmap, const rectangle &cliprect)
|
||||
{
|
||||
int count = 0;
|
||||
|
||||
m_gfxdecode->gfx(3)->transpen(bitmap,cliprect,
|
||||
m_torpedo_pic,
|
||||
0,
|
||||
0, 0,
|
||||
2 * (244 - m_torpedo_h),
|
||||
224 - m_torpedo_v, 0);
|
||||
|
||||
for (int y = 16; y < 224 - m_torpedo_v; y++)
|
||||
{
|
||||
if (y % 16 == 1)
|
||||
count = (count - 1) & 7;
|
||||
|
||||
int const x1 = 248 - m_torpedo_h - count;
|
||||
int const x2 = 248 - m_torpedo_h + count;
|
||||
|
||||
for (int x = 2 * x1; x < 2 * x2; x++)
|
||||
if (m_LFSR[(m_current_index + 0x300 * y + x) % 0x8000])
|
||||
bitmap.pix(y, x) = 1;
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
void wolfpack_state::draw_pt(bitmap_ind16 &bitmap, const rectangle &cliprect)
|
||||
{
|
||||
rectangle rect(cliprect);
|
||||
rect.setx(
|
||||
(m_pt_pic & 0x20) ? rect.left() : 256,
|
||||
(m_pt_pic & 0x10) ? rect.right() : 255);
|
||||
|
||||
m_gfxdecode->gfx(2)->transpen(bitmap,rect,
|
||||
m_pt_pic,
|
||||
0,
|
||||
0, 0,
|
||||
2 * m_pt_horz,
|
||||
m_pt_pos_select ? 0x70 : 0xA0, 0);
|
||||
|
||||
|
||||
m_gfxdecode->gfx(2)->transpen(bitmap,rect,
|
||||
m_pt_pic,
|
||||
0,
|
||||
0, 0,
|
||||
2 * m_pt_horz - 512,
|
||||
m_pt_pos_select ? 0x70 : 0xA0, 0);
|
||||
}
|
||||
|
||||
|
||||
void wolfpack_state::draw_water(palette_device &palette, bitmap_ind16 &bitmap, const rectangle &cliprect)
|
||||
{
|
||||
for (int y = cliprect.top(); y <= (std::min)(cliprect.bottom(), 127); y++)
|
||||
{
|
||||
uint16_t *const p = &bitmap.pix(y);
|
||||
|
||||
for (int x = cliprect.left(); x <= cliprect.right(); x++)
|
||||
p[x] = palette.pen_indirect(p[x]) | 0x08;
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
uint32_t wolfpack_state::screen_update(screen_device &screen, bitmap_ind16 &bitmap, const rectangle &cliprect)
|
||||
{
|
||||
uint8_t color = 0x48;
|
||||
if (m_ship_size & 0x10) color += 0x13;
|
||||
if (m_ship_size & 0x20) color += 0x22;
|
||||
if (m_ship_size & 0x40) color += 0x3a;
|
||||
if (m_ship_size & 0x80) color += 0x48;
|
||||
|
||||
m_palette->set_indirect_color(3, rgb_t(color,color,color));
|
||||
m_palette->set_indirect_color(7, rgb_t(color < 0xb8 ? color + 0x48 : 0xff,
|
||||
color < 0xb8 ? color + 0x48 : 0xff,
|
||||
color < 0xb8 ? color + 0x48 : 0xff));
|
||||
|
||||
bitmap.fill(m_video_invert, cliprect);
|
||||
|
||||
for (int i = 0; i < 8; i++)
|
||||
for (int j = 0; j < 32; j++)
|
||||
{
|
||||
int code = m_alpha_num_ram[32 * i + j];
|
||||
|
||||
|
||||
m_gfxdecode->gfx(0)->opaque(bitmap,cliprect,
|
||||
code,
|
||||
m_video_invert,
|
||||
0, 0,
|
||||
16 * j,
|
||||
192 + 8 * i);
|
||||
}
|
||||
|
||||
draw_pt(bitmap, cliprect);
|
||||
draw_ship(bitmap, cliprect);
|
||||
draw_torpedo(bitmap, cliprect);
|
||||
draw_water(*m_palette, bitmap, cliprect);
|
||||
return 0;
|
||||
}
|
||||
|
||||
|
||||
WRITE_LINE_MEMBER(wolfpack_state::screen_vblank)
|
||||
{
|
||||
// rising edge
|
||||
if (state)
|
||||
{
|
||||
m_helper.fill(0);
|
||||
|
||||
draw_ship(m_helper, m_helper.cliprect());
|
||||
|
||||
for (int y = 128; y < 224 - m_torpedo_v; y++)
|
||||
{
|
||||
int x1 = 248 - m_torpedo_h - 1;
|
||||
int x2 = 248 - m_torpedo_h + 1;
|
||||
|
||||
for (int x = 2 * x1; x < 2 * x2; x++)
|
||||
{
|
||||
if (x < 0 || x >= m_helper.width())
|
||||
continue;
|
||||
if (y < 0 || y >= m_helper.height())
|
||||
continue;
|
||||
|
||||
if (m_helper.pix(y, x))
|
||||
m_collision = 1;
|
||||
}
|
||||
}
|
||||
|
||||
m_current_index += 0x300 * 262;
|
||||
}
|
||||
}
|
@ -1,5 +1,6 @@
|
||||
// license:BSD-3-Clause
|
||||
// copyright-holders:Aaron Giles
|
||||
|
||||
/***************************************************************************
|
||||
|
||||
Atari Xybots hardware
|
||||
@ -20,15 +21,209 @@
|
||||
|
||||
|
||||
#include "emu.h"
|
||||
#include "xybots.h"
|
||||
|
||||
#include "atarijsa.h"
|
||||
#include "atarimo.h"
|
||||
#include "slapstic.h"
|
||||
|
||||
#include "cpu/m68000/m68000.h"
|
||||
#include "machine/eeprompar.h"
|
||||
#include "machine/watchdog.h"
|
||||
|
||||
#include "emupal.h"
|
||||
#include "screen.h"
|
||||
#include "speaker.h"
|
||||
#include "tilemap.h"
|
||||
|
||||
|
||||
namespace {
|
||||
|
||||
class xybots_state : public driver_device
|
||||
{
|
||||
public:
|
||||
xybots_state(const machine_config &mconfig, device_type type, const char *tag) :
|
||||
driver_device(mconfig, type, tag),
|
||||
m_maincpu(*this, "maincpu"),
|
||||
m_slapstic(*this, "slapstic"),
|
||||
m_slapstic_bank(*this, "slapstic_bank"),
|
||||
m_jsa(*this, "jsa"),
|
||||
m_gfxdecode(*this, "gfxdecode"),
|
||||
m_screen(*this, "screen"),
|
||||
m_playfield_tilemap(*this, "playfield"),
|
||||
m_alpha_tilemap(*this, "alpha"),
|
||||
m_mob(*this, "mob"),
|
||||
m_ffe200(*this, "FFE200")
|
||||
{ }
|
||||
|
||||
void xybots(machine_config &config);
|
||||
|
||||
protected:
|
||||
virtual void machine_start() override;
|
||||
|
||||
private:
|
||||
required_device<cpu_device> m_maincpu;
|
||||
required_device<atari_slapstic_device> m_slapstic;
|
||||
required_memory_bank m_slapstic_bank;
|
||||
required_device<atari_jsa_i_device> m_jsa;
|
||||
required_device<gfxdecode_device> m_gfxdecode;
|
||||
required_device<screen_device> m_screen;
|
||||
required_device<tilemap_device> m_playfield_tilemap;
|
||||
required_device<tilemap_device> m_alpha_tilemap;
|
||||
required_device<atari_motion_objects_device> m_mob;
|
||||
required_ioport m_ffe200;
|
||||
|
||||
uint16_t m_h256 = 0;
|
||||
|
||||
void video_int_ack_w(uint16_t data = 0);
|
||||
uint16_t special_port1_r();
|
||||
TILE_GET_INFO_MEMBER(get_alpha_tile_info);
|
||||
TILE_GET_INFO_MEMBER(get_playfield_tile_info);
|
||||
uint32_t screen_update(screen_device &screen, bitmap_ind16 &bitmap, const rectangle &cliprect);
|
||||
void main_map(address_map &map);
|
||||
|
||||
static const atari_motion_objects_config s_mob_config;
|
||||
};
|
||||
|
||||
|
||||
// video
|
||||
|
||||
/*************************************
|
||||
*
|
||||
* Tilemap callbacks
|
||||
*
|
||||
*************************************/
|
||||
|
||||
TILE_GET_INFO_MEMBER(xybots_state::get_alpha_tile_info)
|
||||
{
|
||||
uint16_t const data = m_alpha_tilemap->basemem_read(tile_index);
|
||||
int const code = data & 0x3ff;
|
||||
int const color = (data >> 12) & 7;
|
||||
int const opaque = data & 0x8000;
|
||||
tileinfo.set(2, code, color, opaque ? TILE_FORCE_LAYER0 : 0);
|
||||
}
|
||||
|
||||
|
||||
TILE_GET_INFO_MEMBER(xybots_state::get_playfield_tile_info)
|
||||
{
|
||||
uint16_t const data = m_playfield_tilemap->basemem_read(tile_index);
|
||||
int const code = data & 0x1fff;
|
||||
int const color = (data >> 11) & 0x0f;
|
||||
tileinfo.set(0, code, color, (data >> 15) & 1);
|
||||
}
|
||||
|
||||
|
||||
|
||||
/*************************************
|
||||
*
|
||||
* Video system start
|
||||
*
|
||||
*************************************/
|
||||
|
||||
const atari_motion_objects_config xybots_state::s_mob_config =
|
||||
{
|
||||
1, // index to which gfx system
|
||||
1, // number of motion object banks
|
||||
0, // are the entries linked?
|
||||
0, // are the entries split?
|
||||
0, // render in reverse order?
|
||||
0, // render in swapped X/Y order?
|
||||
0, // does the neighbor bit affect the next object?
|
||||
0, // pixels per SLIP entry (0 for no-slip)
|
||||
0, // pixel offset for SLIPs
|
||||
0, // maximum number of links to visit/scanline (0=all)
|
||||
|
||||
0x100, // base palette entry
|
||||
0x300, // maximum number of colors
|
||||
0, // transparent pen index
|
||||
|
||||
{{ 0x3f }}, // mask for the link (dummy)
|
||||
{{ 0x3fff,0,0,0 }}, // mask for the code index
|
||||
{{ 0,0,0,0x000f }}, // mask for the color
|
||||
{{ 0,0,0,0xff80 }}, // mask for the X position
|
||||
{{ 0,0,0xff80,0 }}, // mask for the Y position
|
||||
{{ 0 }}, // mask for the width, in tiles
|
||||
{{ 0,0,0x0007,0 }}, // mask for the height, in tiles
|
||||
{{ 0x8000,0,0,0 }}, // mask for the horizontal flip
|
||||
{{ 0 }}, // mask for the vertical flip
|
||||
{{ 0,0x000f,0,0 }}, // mask for the priority
|
||||
{{ 0 }}, // mask for the neighbor
|
||||
{{ 0 }}, // mask for absolute coordinates
|
||||
|
||||
{{ 0 }}, // mask for the special value
|
||||
0 // resulting value to indicate "special"
|
||||
};
|
||||
|
||||
|
||||
|
||||
/*************************************
|
||||
*
|
||||
* Main refresh
|
||||
*
|
||||
*************************************/
|
||||
|
||||
uint32_t xybots_state::screen_update(screen_device &screen, bitmap_ind16 &bitmap, const rectangle &cliprect)
|
||||
{
|
||||
// start drawing
|
||||
m_mob->draw_async(cliprect);
|
||||
|
||||
// draw the playfield
|
||||
m_playfield_tilemap->draw(screen, bitmap, cliprect, 0, 0);
|
||||
|
||||
// draw and merge the MO
|
||||
bitmap_ind16 &mobitmap = m_mob->bitmap();
|
||||
for (const sparse_dirty_rect *rect = m_mob->first_dirty_rect(cliprect); rect != nullptr; rect = rect->next())
|
||||
for (int y = rect->top(); y <= rect->bottom(); y++)
|
||||
{
|
||||
uint16_t const *const mo = &mobitmap.pix(y);
|
||||
uint16_t *const pf = &bitmap.pix(y);
|
||||
for (int x = rect->left(); x <= rect->right(); x++)
|
||||
if (mo[x] != 0xffff)
|
||||
{
|
||||
/* verified via schematics:
|
||||
|
||||
PRIEN = ~(~MOPIX3 & ~MOPIX2 & ~MOPIX1) = (MOPIX3-0 > 1)
|
||||
|
||||
if (PRIEN)
|
||||
PF/MO = (~MOPRI3-0 > PFCOL3-0)
|
||||
else
|
||||
PF/MO = (~MOPRI3-0 >= PFCOL3-0)
|
||||
|
||||
if (PF/MO | ~(PRIEN & MOCOL3))
|
||||
GPC(P3-0) = PFPIX3-0
|
||||
else
|
||||
GPC(P3-0) = ~MOCOL3-0
|
||||
*/
|
||||
int const mopriority = (mo[x] >> atari_motion_objects_device::PRIORITY_SHIFT) ^ 15;
|
||||
int const pfcolor = (pf[x] >> 4) & 0x0f;
|
||||
int const prien = ((mo[x] & 0x0f) > 1);
|
||||
|
||||
if (prien)
|
||||
{
|
||||
if (mopriority <= pfcolor)
|
||||
{
|
||||
/* this first case doesn't make sense from the schematics, but it has
|
||||
the correct effect */
|
||||
if (mo[x] & 0x80)
|
||||
pf[x] = (mo[x] ^ 0x2f0) & atari_motion_objects_device::DATA_MASK;
|
||||
else
|
||||
pf[x] = mo[x] & atari_motion_objects_device::DATA_MASK;
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
if (mopriority < pfcolor)
|
||||
pf[x] = mo[x] & atari_motion_objects_device::DATA_MASK;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
// add the alpha on top
|
||||
m_alpha_tilemap->draw(screen, bitmap, cliprect, 0, 0);
|
||||
return 0;
|
||||
}
|
||||
|
||||
|
||||
// machine
|
||||
|
||||
/*************************************
|
||||
*
|
||||
@ -51,7 +246,7 @@ void xybots_state::video_int_ack_w(uint16_t data)
|
||||
|
||||
uint16_t xybots_state::special_port1_r()
|
||||
{
|
||||
int result = ioport("FFE200")->read();
|
||||
int result = m_ffe200->read();
|
||||
result ^= m_h256 ^= 0x0400;
|
||||
return result;
|
||||
}
|
||||
@ -64,12 +259,12 @@ uint16_t xybots_state::special_port1_r()
|
||||
*
|
||||
*************************************/
|
||||
|
||||
/* full map verified from schematics */
|
||||
// full map verified from schematics
|
||||
void xybots_state::main_map(address_map &map)
|
||||
{
|
||||
map.unmap_value_high();
|
||||
map(0x000000, 0x007fff).mirror(0x7c0000).rom();
|
||||
map(0x008000, 0x009fff).mirror(0x7c6000).bankr(m_slapstic_bank); /* slapstic maps here */
|
||||
map(0x008000, 0x009fff).mirror(0x7c6000).bankr(m_slapstic_bank); // slapstic maps here
|
||||
map(0x010000, 0x03ffff).mirror(0x7c0000).rom();
|
||||
map(0x800000, 0x800fff).mirror(0x7f8000).ram().w(m_alpha_tilemap, FUNC(tilemap_device::write16)).share("alpha");
|
||||
map(0x801000, 0x802dff).mirror(0x7f8000).ram();
|
||||
@ -117,9 +312,9 @@ static INPUT_PORTS_START( xybots )
|
||||
PORT_START("FFE200")
|
||||
PORT_BIT( 0x00ff, IP_ACTIVE_LOW, IPT_UNUSED )
|
||||
PORT_SERVICE( 0x0100, IP_ACTIVE_LOW )
|
||||
PORT_BIT( 0x0200, IP_ACTIVE_LOW, IPT_CUSTOM ) PORT_ATARI_JSA_MAIN_TO_SOUND_READY("jsa") /* /AUDBUSY */
|
||||
PORT_BIT( 0x0400, IP_ACTIVE_HIGH, IPT_CUSTOM ) /* 256H */
|
||||
PORT_BIT( 0x0800, IP_ACTIVE_HIGH, IPT_CUSTOM ) PORT_VBLANK("screen") /* VBLANK */
|
||||
PORT_BIT( 0x0200, IP_ACTIVE_LOW, IPT_CUSTOM ) PORT_ATARI_JSA_MAIN_TO_SOUND_READY("jsa") // /AUDBUSY
|
||||
PORT_BIT( 0x0400, IP_ACTIVE_HIGH, IPT_CUSTOM ) // 256H
|
||||
PORT_BIT( 0x0800, IP_ACTIVE_HIGH, IPT_CUSTOM ) PORT_VBLANK("screen") // VBLANK
|
||||
PORT_BIT( 0xf000, IP_ACTIVE_LOW, IPT_UNUSED )
|
||||
INPUT_PORTS_END
|
||||
|
||||
@ -143,22 +338,10 @@ static const gfx_layout anlayout =
|
||||
};
|
||||
|
||||
|
||||
static const gfx_layout pfmolayout =
|
||||
{
|
||||
8,8,
|
||||
RGN_FRAC(1,1),
|
||||
4,
|
||||
{ 0, 1, 2, 3 },
|
||||
{ 0, 4, 8, 12, 16, 20, 24, 28 },
|
||||
{ 0*8, 4*8, 8*8, 12*8, 16*8, 20*8, 24*8, 28*8 },
|
||||
32*8
|
||||
};
|
||||
|
||||
|
||||
static GFXDECODE_START( gfx_xybots )
|
||||
GFXDECODE_ENTRY( "gfx1", 0, pfmolayout, 512, 16 ) /* playfield */
|
||||
GFXDECODE_ENTRY( "gfx2", 0, pfmolayout, 256, 48 ) /* sprites */
|
||||
GFXDECODE_ENTRY( "gfx3", 0, anlayout, 0, 64 ) /* characters 8x8 */
|
||||
GFXDECODE_ENTRY( "tiles", 0, gfx_8x8x4_packed_msb, 512, 16 )
|
||||
GFXDECODE_ENTRY( "sprites", 0, gfx_8x8x4_packed_msb, 256, 48 )
|
||||
GFXDECODE_ENTRY( "chars", 0, anlayout, 0, 64 )
|
||||
GFXDECODE_END
|
||||
|
||||
|
||||
@ -171,8 +354,8 @@ GFXDECODE_END
|
||||
|
||||
void xybots_state::xybots(machine_config &config)
|
||||
{
|
||||
/* basic machine hardware */
|
||||
M68000(config, m_maincpu, 14.318181_MHz_XTAL/2);
|
||||
// basic machine hardware
|
||||
M68000(config, m_maincpu, 14.318181_MHz_XTAL / 2);
|
||||
m_maincpu->set_addrmap(AS_PROGRAM, &xybots_state::main_map);
|
||||
|
||||
SLAPSTIC(config, m_slapstic, 107);
|
||||
@ -183,7 +366,7 @@ void xybots_state::xybots(machine_config &config)
|
||||
|
||||
WATCHDOG_TIMER(config, "watchdog");
|
||||
|
||||
/* video hardware */
|
||||
// video hardware
|
||||
GFXDECODE(config, "gfxdecode", "palette", gfx_xybots);
|
||||
PALETTE(config, "palette").set_format(palette_device::IRGB_4444, 1024);
|
||||
|
||||
@ -195,14 +378,14 @@ void xybots_state::xybots(machine_config &config)
|
||||
|
||||
SCREEN(config, m_screen, SCREEN_TYPE_RASTER);
|
||||
m_screen->set_video_attributes(VIDEO_UPDATE_BEFORE_VBLANK);
|
||||
/* note: these parameters are from published specs, not derived */
|
||||
/* the board uses a SYNGEN chip to generate video signals */
|
||||
m_screen->set_raw(14.318181_MHz_XTAL/2, 456, 0, 336, 262, 0, 240);
|
||||
m_screen->set_screen_update(FUNC(xybots_state::screen_update_xybots));
|
||||
// note: these parameters are from published specs, not derived
|
||||
// the board uses a SYNGEN chip to generate video signals
|
||||
m_screen->set_raw(14.318181_MHz_XTAL / 2, 456, 0, 336, 262, 0, 240);
|
||||
m_screen->set_screen_update(FUNC(xybots_state::screen_update));
|
||||
m_screen->set_palette("palette");
|
||||
m_screen->screen_vblank().set_inputline(m_maincpu, M68K_IRQ_1, ASSERT_LINE);
|
||||
|
||||
/* sound hardware */
|
||||
// sound hardware
|
||||
SPEAKER(config, "lspeaker").front_left();
|
||||
SPEAKER(config, "rspeaker").front_right();
|
||||
|
||||
@ -225,22 +408,22 @@ void xybots_state::xybots(machine_config &config)
|
||||
*************************************/
|
||||
|
||||
ROM_START( xybots )
|
||||
ROM_REGION( 0x90000, "maincpu", 0 ) /* 8*64k for 68000 code */
|
||||
ROM_REGION( 0x90000, "maincpu", 0 ) // 68000 code
|
||||
ROM_LOAD16_BYTE( "136054-2112.17cd", 0x000000, 0x010000, CRC(16d64748) SHA1(3c2ba8ec3185b69c4e1947ac842f2250ee35216e) )
|
||||
ROM_LOAD16_BYTE( "136054-2113.19cd", 0x000001, 0x010000, CRC(2677d44a) SHA1(23a3538df13a47f2fd78d4842b9f8b81e38c802e) )
|
||||
ROM_LOAD16_BYTE( "136054-2114.17b", 0x020000, 0x008000, CRC(d31890cb) SHA1(b58722a4dcc79e97484c2f5e35b8dbf8c3520bd9) )
|
||||
ROM_LOAD16_BYTE( "136054-2115.19b", 0x020001, 0x008000, CRC(750ab1b0) SHA1(0638de738bd804bde4b93cd23190ee0465887cf8) )
|
||||
|
||||
ROM_REGION( 0x10000, "jsa:cpu", 0 ) /* 64k for 6502 code */
|
||||
ROM_REGION( 0x10000, "jsa:cpu", 0 ) // 6502 code
|
||||
ROM_LOAD( "136054-1116.2k", 0x00000, 0x10000, CRC(3b9f155d) SHA1(7080681a7eab282023034379825ca88adc6b300f) )
|
||||
|
||||
ROM_REGION( 0x40000, "gfx1", 0 )
|
||||
ROM_REGION( 0x40000, "tiles", 0 )
|
||||
ROM_LOAD( "136054-2102.12l", 0x000000, 0x008000, CRC(c1309674) SHA1(5a163c894142c8d662557c8322dc04fded637227) )
|
||||
ROM_RELOAD( 0x008000, 0x008000 )
|
||||
ROM_LOAD( "136054-2103.11l", 0x010000, 0x010000, CRC(907c024d) SHA1(d41c7471136f4a0632cbae28644ab1650af1467f) )
|
||||
ROM_LOAD( "136054-2117.8l", 0x030000, 0x010000, CRC(0cc9b42d) SHA1(a744d97d40afb469ee61c2fc8d4b04ff8cc72755) )
|
||||
|
||||
ROM_REGION( 0x80000, "gfx2", 0 )
|
||||
ROM_REGION( 0x80000, "sprites", 0 )
|
||||
ROM_LOAD( "136054-1105.2e", 0x000000, 0x010000, CRC(315a4274) SHA1(9a6cfdd655560e5d0320f95c8b60e733991a0909) )
|
||||
ROM_LOAD( "136054-1106.2ef", 0x010000, 0x010000, CRC(3d8c1dd2) SHA1(dd61fc0b96c395e1e65bb7114a60b45d68d08140) )
|
||||
ROM_LOAD( "136054-1107.2f", 0x020000, 0x010000, CRC(b7217da5) SHA1(b00ff4a3d0cffb94636f84cd923a78b5a02f9741) )
|
||||
@ -249,28 +432,28 @@ ROM_START( xybots )
|
||||
ROM_LOAD( "136054-1110.2k", 0x050000, 0x010000, CRC(99665ff4) SHA1(e93a85a601ae364d1e773174d488fca74b8d5753) )
|
||||
ROM_LOAD( "136054-1111.2l", 0x060000, 0x010000, CRC(416107ee) SHA1(cdfe6c6bd8efaa08506cd5707887c552500c2108) )
|
||||
|
||||
ROM_REGION( 0x02000, "gfx3", 0 )
|
||||
ROM_REGION( 0x02000, "chars", 0 )
|
||||
ROM_LOAD( "136054-1101.5c", 0x000000, 0x002000, CRC(59c028a2) SHA1(27dcde0da88f949a5e4a7632d4b403b937c8c6e0) )
|
||||
ROM_END
|
||||
|
||||
|
||||
ROM_START( xybotsg )
|
||||
ROM_REGION( 0x90000, "maincpu", 0 ) /* 8*64k for 68000 code */
|
||||
ROM_REGION( 0x90000, "maincpu", 0 ) // 68000 code
|
||||
ROM_LOAD16_BYTE( "136054-3212.17cd", 0x000000, 0x010000, CRC(4cac5d7c) SHA1(79cdd754fb6055249dace31fe9f8939f13aae8ca) )
|
||||
ROM_LOAD16_BYTE( "136054-3213.19cd", 0x000001, 0x010000, CRC(bfcb0b00) SHA1(3e45f72051ea74b544c8578c6fc1284f925caa3d) )
|
||||
ROM_LOAD16_BYTE( "136054-3214.17b", 0x020000, 0x008000, CRC(4ad35093) SHA1(6d2d82fb481c68819ec6c87d483eed17d4ae5d1a) )
|
||||
ROM_LOAD16_BYTE( "136054-3215.19b", 0x020001, 0x008000, CRC(3a2afbaf) SHA1(61b88d15d95681eb24559d0696203cd4ee63d11f) )
|
||||
|
||||
ROM_REGION( 0x10000, "jsa:cpu", 0 ) /* 64k for 6502 code */
|
||||
ROM_REGION( 0x10000, "jsa:cpu", 0 ) // 6502 code
|
||||
ROM_LOAD( "136054-1116.2k", 0x00000, 0x10000, CRC(3b9f155d) SHA1(7080681a7eab282023034379825ca88adc6b300f) )
|
||||
|
||||
ROM_REGION( 0x40000, "gfx1", 0 )
|
||||
ROM_REGION( 0x40000, "tiles", 0 )
|
||||
ROM_LOAD( "136054-2102.12l", 0x000000, 0x008000, CRC(c1309674) SHA1(5a163c894142c8d662557c8322dc04fded637227) )
|
||||
ROM_RELOAD( 0x008000, 0x008000 )
|
||||
ROM_LOAD( "136054-2103.11l", 0x010000, 0x010000, CRC(907c024d) SHA1(d41c7471136f4a0632cbae28644ab1650af1467f) )
|
||||
ROM_LOAD( "136054-2117.8l", 0x030000, 0x010000, CRC(0cc9b42d) SHA1(a744d97d40afb469ee61c2fc8d4b04ff8cc72755) )
|
||||
|
||||
ROM_REGION( 0x80000, "gfx2", 0 )
|
||||
ROM_REGION( 0x80000, "sprites", 0 )
|
||||
ROM_LOAD( "136054-1105.2e", 0x000000, 0x010000, CRC(315a4274) SHA1(9a6cfdd655560e5d0320f95c8b60e733991a0909) )
|
||||
ROM_LOAD( "136054-1106.2ef", 0x010000, 0x010000, CRC(3d8c1dd2) SHA1(dd61fc0b96c395e1e65bb7114a60b45d68d08140) )
|
||||
ROM_LOAD( "136054-1107.2f", 0x020000, 0x010000, CRC(b7217da5) SHA1(b00ff4a3d0cffb94636f84cd923a78b5a02f9741) )
|
||||
@ -279,28 +462,28 @@ ROM_START( xybotsg )
|
||||
ROM_LOAD( "136054-1110.2k", 0x050000, 0x010000, CRC(99665ff4) SHA1(e93a85a601ae364d1e773174d488fca74b8d5753) )
|
||||
ROM_LOAD( "136054-1111.2l", 0x060000, 0x010000, CRC(416107ee) SHA1(cdfe6c6bd8efaa08506cd5707887c552500c2108) )
|
||||
|
||||
ROM_REGION( 0x02000, "gfx3", 0 )
|
||||
ROM_REGION( 0x02000, "chars", 0 )
|
||||
ROM_LOAD( "136054-1101.5c", 0x000000, 0x002000, CRC(59c028a2) SHA1(27dcde0da88f949a5e4a7632d4b403b937c8c6e0) )
|
||||
ROM_END
|
||||
|
||||
|
||||
ROM_START( xybotsf )
|
||||
ROM_REGION( 0x90000, "maincpu", 0 ) /* 8*64k for 68000 code */
|
||||
ROM_REGION( 0x90000, "maincpu", 0 ) // 68000 code
|
||||
ROM_LOAD16_BYTE( "136054-3612.17cd", 0x000000, 0x010000, CRC(b03a3f3c) SHA1(c88ad0ba5381562095f5b5a13d338d10fa0597f5) )
|
||||
ROM_LOAD16_BYTE( "136054-3613.19cd", 0x000001, 0x010000, CRC(ab33eb1f) SHA1(926c32f07c0bcc5832db3a1adf0357e55cae707a) )
|
||||
ROM_LOAD16_BYTE( "136054-3614.17b", 0x020000, 0x008000, CRC(7385e0b6) SHA1(98a69901069872b14413c1bfe48783fdb43c1c37) )
|
||||
ROM_LOAD16_BYTE( "136054-3615.19b", 0x020001, 0x008000, CRC(8e37b812) SHA1(40f973a49c4b40f3a5d982d332995e792f718dcc) )
|
||||
|
||||
ROM_REGION( 0x10000, "jsa:cpu", 0 ) /* 64k for 6502 code */
|
||||
ROM_REGION( 0x10000, "jsa:cpu", 0 ) // 6502 code
|
||||
ROM_LOAD( "136054-1116.2k", 0x00000, 0x10000, CRC(3b9f155d) SHA1(7080681a7eab282023034379825ca88adc6b300f) )
|
||||
|
||||
ROM_REGION( 0x40000, "gfx1", 0 )
|
||||
ROM_REGION( 0x40000, "tiles", 0 )
|
||||
ROM_LOAD( "136054-2102.12l", 0x000000, 0x008000, CRC(c1309674) SHA1(5a163c894142c8d662557c8322dc04fded637227) )
|
||||
ROM_RELOAD( 0x008000, 0x008000 )
|
||||
ROM_LOAD( "136054-2103.11l", 0x010000, 0x010000, CRC(907c024d) SHA1(d41c7471136f4a0632cbae28644ab1650af1467f) )
|
||||
ROM_LOAD( "136054-2117.8l", 0x030000, 0x010000, CRC(0cc9b42d) SHA1(a744d97d40afb469ee61c2fc8d4b04ff8cc72755) )
|
||||
|
||||
ROM_REGION( 0x80000, "gfx2", 0 )
|
||||
ROM_REGION( 0x80000, "sprites", 0 )
|
||||
ROM_LOAD( "136054-1105.2e", 0x000000, 0x010000, CRC(315a4274) SHA1(9a6cfdd655560e5d0320f95c8b60e733991a0909) )
|
||||
ROM_LOAD( "136054-1106.2ef", 0x010000, 0x010000, CRC(3d8c1dd2) SHA1(dd61fc0b96c395e1e65bb7114a60b45d68d08140) )
|
||||
ROM_LOAD( "136054-1107.2f", 0x020000, 0x010000, CRC(b7217da5) SHA1(b00ff4a3d0cffb94636f84cd923a78b5a02f9741) )
|
||||
@ -309,28 +492,28 @@ ROM_START( xybotsf )
|
||||
ROM_LOAD( "136054-1110.2k", 0x050000, 0x010000, CRC(99665ff4) SHA1(e93a85a601ae364d1e773174d488fca74b8d5753) )
|
||||
ROM_LOAD( "136054-1111.2l", 0x060000, 0x010000, CRC(416107ee) SHA1(cdfe6c6bd8efaa08506cd5707887c552500c2108) )
|
||||
|
||||
ROM_REGION( 0x02000, "gfx3", 0 )
|
||||
ROM_REGION( 0x02000, "chars", 0 )
|
||||
ROM_LOAD( "136054-1101.5c", 0x000000, 0x002000, CRC(59c028a2) SHA1(27dcde0da88f949a5e4a7632d4b403b937c8c6e0) )
|
||||
ROM_END
|
||||
|
||||
|
||||
ROM_START( xybots1 )
|
||||
ROM_REGION( 0x90000, "maincpu", 0 ) /* 8*64k for 68000 code */
|
||||
ROM_REGION( 0x90000, "maincpu", 0 ) // 68000 code
|
||||
ROM_LOAD16_BYTE( "136054-1112.17cd", 0x000000, 0x010000, CRC(2dbab363) SHA1(1473bf1246c6fb3e6b8b1f86a345b532ccf18e8d) )
|
||||
ROM_LOAD16_BYTE( "136054-1113.19cd", 0x000001, 0x010000, CRC(847b056e) SHA1(cc4b90f19d7eaee09569ba228c2654f64cec3200) )
|
||||
ROM_LOAD16_BYTE( "136054-1114.17b", 0x020000, 0x008000, CRC(7444f88f) SHA1(e2a27754a57a809398ee639fe5d0920b564d4c0b) )
|
||||
ROM_LOAD16_BYTE( "136054-1115.19b", 0x020001, 0x008000, CRC(848d072d) SHA1(c4d1181f0227200e60d99a99c1a83897275b055f) )
|
||||
|
||||
ROM_REGION( 0x10000, "jsa:cpu", 0 ) /* 64k for 6502 code */
|
||||
ROM_REGION( 0x10000, "jsa:cpu", 0 ) // 6502 code
|
||||
ROM_LOAD( "136054-1116.2k", 0x00000, 0x10000, CRC(3b9f155d) SHA1(7080681a7eab282023034379825ca88adc6b300f) )
|
||||
|
||||
ROM_REGION( 0x40000, "gfx1", 0 )
|
||||
ROM_REGION( 0x40000, "tiles", 0 )
|
||||
ROM_LOAD( "136054-2102.12l", 0x000000, 0x008000, CRC(c1309674) SHA1(5a163c894142c8d662557c8322dc04fded637227) )
|
||||
ROM_RELOAD( 0x008000, 0x008000 )
|
||||
ROM_LOAD( "136054-2103.11l", 0x010000, 0x010000, CRC(907c024d) SHA1(d41c7471136f4a0632cbae28644ab1650af1467f) )
|
||||
ROM_LOAD( "136054-2117.8l", 0x030000, 0x010000, CRC(0cc9b42d) SHA1(a744d97d40afb469ee61c2fc8d4b04ff8cc72755) )
|
||||
|
||||
ROM_REGION( 0x80000, "gfx2", 0 )
|
||||
ROM_REGION( 0x80000, "sprites", 0 )
|
||||
ROM_LOAD( "136054-1105.2e", 0x000000, 0x010000, CRC(315a4274) SHA1(9a6cfdd655560e5d0320f95c8b60e733991a0909) )
|
||||
ROM_LOAD( "136054-1106.2ef", 0x010000, 0x010000, CRC(3d8c1dd2) SHA1(dd61fc0b96c395e1e65bb7114a60b45d68d08140) )
|
||||
ROM_LOAD( "136054-1107.2f", 0x020000, 0x010000, CRC(b7217da5) SHA1(b00ff4a3d0cffb94636f84cd923a78b5a02f9741) )
|
||||
@ -339,28 +522,28 @@ ROM_START( xybots1 )
|
||||
ROM_LOAD( "136054-1110.2k", 0x050000, 0x010000, CRC(99665ff4) SHA1(e93a85a601ae364d1e773174d488fca74b8d5753) )
|
||||
ROM_LOAD( "136054-1111.2l", 0x060000, 0x010000, CRC(416107ee) SHA1(cdfe6c6bd8efaa08506cd5707887c552500c2108) )
|
||||
|
||||
ROM_REGION( 0x02000, "gfx3", 0 )
|
||||
ROM_REGION( 0x02000, "chars", 0 )
|
||||
ROM_LOAD( "136054-1101.5c", 0x000000, 0x002000, CRC(59c028a2) SHA1(27dcde0da88f949a5e4a7632d4b403b937c8c6e0) )
|
||||
ROM_END
|
||||
|
||||
|
||||
ROM_START( xybots0 )
|
||||
ROM_REGION( 0x90000, "maincpu", 0 ) /* 8*64k for 68000 code */
|
||||
ROM_REGION( 0x90000, "maincpu", 0 ) // 68000 code
|
||||
ROM_LOAD16_BYTE( "136054-0112.17cd", 0x000000, 0x010000, CRC(4b830ac4) SHA1(1f6dc0c6648f74c4775b52e3f502e835a8741182) )
|
||||
ROM_LOAD16_BYTE( "136054-0113.19cd", 0x000001, 0x010000, CRC(dcfbf8a7) SHA1(0106cd7be55147f4b59e17391e5bb339aaf80535) )
|
||||
ROM_LOAD16_BYTE( "136054-0114.17b", 0x020000, 0x008000, CRC(18b875f7) SHA1(aa78553bd3556d0b209513ba80b782cfb0e3bb8b) )
|
||||
ROM_LOAD16_BYTE( "136054-0115.19b", 0x020001, 0x008000, CRC(7f116360) SHA1(d12c339ce973bd74be4a4ac9e9d293f6a6e358d6) )
|
||||
|
||||
ROM_REGION( 0x10000, "jsa:cpu", 0 ) /* 64k for 6502 code */
|
||||
ROM_LOAD( "136054-0116.2k", 0x00000, 0x10000, BAD_DUMP CRC(3b9f155d) SHA1(7080681a7eab282023034379825ca88adc6b300f) ) // not dumped from this pcb, rom taken from another set instead
|
||||
ROM_REGION( 0x10000, "jsa:cpu", 0 ) // 6502 code
|
||||
ROM_LOAD( "136054-0116.2k", 0x00000, 0x10000, BAD_DUMP CRC(3b9f155d) SHA1(7080681a7eab282023034379825ca88adc6b300f) ) // not dumped from this PCB, ROM taken from another set instead
|
||||
|
||||
ROM_REGION( 0x40000, "gfx1", 0 )
|
||||
ROM_REGION( 0x40000, "tiles", 0 )
|
||||
ROM_LOAD( "136054-1102.12l", 0x000000, 0x008000, CRC(0d304e5b) SHA1(203c86c865667b1538f61c0950682fb17ebd9abb) )
|
||||
ROM_RELOAD( 0x008000, 0x008000 )
|
||||
ROM_LOAD( "136054-1103.11l", 0x010000, 0x010000, CRC(a514da1d) SHA1(5af3c703e0c8e8d47123241ce39f202c88a8cdb0) )
|
||||
ROM_LOAD( "136054-1117.8l", 0x030000, 0x010000, CRC(6b79154d) SHA1(6fd47503c91a23f75046acd1ef8000b63f8e8ba6) )
|
||||
|
||||
ROM_REGION( 0x80000, "gfx2", 0 )
|
||||
ROM_REGION( 0x80000, "sprites", 0 )
|
||||
ROM_LOAD( "136054-1105.2e", 0x000000, 0x010000, CRC(315a4274) SHA1(9a6cfdd655560e5d0320f95c8b60e733991a0909) )
|
||||
ROM_LOAD( "136054-1106.2ef", 0x010000, 0x010000, CRC(3d8c1dd2) SHA1(dd61fc0b96c395e1e65bb7114a60b45d68d08140) )
|
||||
ROM_LOAD( "136054-1107.2f", 0x020000, 0x010000, CRC(b7217da5) SHA1(b00ff4a3d0cffb94636f84cd923a78b5a02f9741) )
|
||||
@ -369,7 +552,7 @@ ROM_START( xybots0 )
|
||||
ROM_LOAD( "136054-1110.2k", 0x050000, 0x010000, CRC(99665ff4) SHA1(e93a85a601ae364d1e773174d488fca74b8d5753) )
|
||||
ROM_LOAD( "136054-1111.2l", 0x060000, 0x010000, CRC(416107ee) SHA1(cdfe6c6bd8efaa08506cd5707887c552500c2108) )
|
||||
|
||||
ROM_REGION( 0x02000, "gfx3", 0 )
|
||||
ROM_REGION( 0x02000, "chars", 0 )
|
||||
ROM_LOAD( "136054-1101.5c", 0x000000, 0x002000, CRC(59c028a2) SHA1(27dcde0da88f949a5e4a7632d4b403b937c8c6e0) )
|
||||
ROM_END
|
||||
|
||||
@ -385,8 +568,11 @@ void xybots_state::machine_start()
|
||||
{
|
||||
m_slapstic_bank->configure_entries(0, 4, memregion("maincpu")->base() + 0x8000, 0x2000);
|
||||
m_h256 = 0x0400;
|
||||
|
||||
save_item(NAME(m_h256));
|
||||
}
|
||||
|
||||
} // anonymous namespace
|
||||
|
||||
|
||||
/*************************************
|
||||
@ -395,8 +581,8 @@ void xybots_state::machine_start()
|
||||
*
|
||||
*************************************/
|
||||
|
||||
GAME( 1987, xybots, 0, xybots, xybots, xybots_state, empty_init, ROT0, "Atari Games", "Xybots (rev 2)", 0 )
|
||||
GAME( 1987, xybotsg, xybots, xybots, xybots, xybots_state, empty_init, ROT0, "Atari Games", "Xybots (German, rev 3)", 0 )
|
||||
GAME( 1987, xybotsf, xybots, xybots, xybots, xybots_state, empty_init, ROT0, "Atari Games", "Xybots (French, rev 3)", 0 )
|
||||
GAME( 1987, xybots1, xybots, xybots, xybots, xybots_state, empty_init, ROT0, "Atari Games", "Xybots (rev 1)", 0 )
|
||||
GAME( 1987, xybots0, xybots, xybots, xybots, xybots_state, empty_init, ROT0, "Atari Games", "Xybots (rev 0)", 0 )
|
||||
GAME( 1987, xybots, 0, xybots, xybots, xybots_state, empty_init, ROT0, "Atari Games", "Xybots (rev 2)", MACHINE_SUPPORTS_SAVE )
|
||||
GAME( 1987, xybotsg, xybots, xybots, xybots, xybots_state, empty_init, ROT0, "Atari Games", "Xybots (German, rev 3)", MACHINE_SUPPORTS_SAVE )
|
||||
GAME( 1987, xybotsf, xybots, xybots, xybots, xybots_state, empty_init, ROT0, "Atari Games", "Xybots (French, rev 3)", MACHINE_SUPPORTS_SAVE )
|
||||
GAME( 1987, xybots1, xybots, xybots, xybots, xybots_state, empty_init, ROT0, "Atari Games", "Xybots (rev 1)", MACHINE_SUPPORTS_SAVE )
|
||||
GAME( 1987, xybots0, xybots, xybots, xybots, xybots_state, empty_init, ROT0, "Atari Games", "Xybots (rev 0)", MACHINE_SUPPORTS_SAVE )
|
||||
|
@ -1,63 +0,0 @@
|
||||
// license:BSD-3-Clause
|
||||
// copyright-holders:Aaron Giles
|
||||
/*************************************************************************
|
||||
|
||||
Atari Xybots hardware
|
||||
|
||||
*************************************************************************/
|
||||
#ifndef MAME_ATARI_XYBOTS_H
|
||||
#define MAME_ATARI_XYBOTS_H
|
||||
|
||||
#pragma once
|
||||
|
||||
#include "slapstic.h"
|
||||
#include "atarijsa.h"
|
||||
#include "atarimo.h"
|
||||
#include "screen.h"
|
||||
#include "tilemap.h"
|
||||
|
||||
class xybots_state : public driver_device
|
||||
{
|
||||
public:
|
||||
xybots_state(const machine_config &mconfig, device_type type, const char *tag) :
|
||||
driver_device(mconfig, type, tag),
|
||||
m_maincpu(*this, "maincpu"),
|
||||
m_slapstic(*this, "slapstic"),
|
||||
m_slapstic_bank(*this, "slapstic_bank"),
|
||||
m_jsa(*this, "jsa"),
|
||||
m_gfxdecode(*this, "gfxdecode"),
|
||||
m_screen(*this, "screen"),
|
||||
m_playfield_tilemap(*this, "playfield"),
|
||||
m_alpha_tilemap(*this, "alpha"),
|
||||
m_mob(*this, "mob")
|
||||
{ }
|
||||
|
||||
void xybots(machine_config &config);
|
||||
|
||||
protected:
|
||||
virtual void machine_start() override;
|
||||
|
||||
private:
|
||||
void video_int_ack_w(uint16_t data = 0);
|
||||
uint16_t special_port1_r();
|
||||
TILE_GET_INFO_MEMBER(get_alpha_tile_info);
|
||||
TILE_GET_INFO_MEMBER(get_playfield_tile_info);
|
||||
uint32_t screen_update_xybots(screen_device &screen, bitmap_ind16 &bitmap, const rectangle &cliprect);
|
||||
void main_map(address_map &map);
|
||||
|
||||
required_device<cpu_device> m_maincpu;
|
||||
required_device<atari_slapstic_device> m_slapstic;
|
||||
required_memory_bank m_slapstic_bank;
|
||||
required_device<atari_jsa_i_device> m_jsa;
|
||||
required_device<gfxdecode_device> m_gfxdecode;
|
||||
required_device<screen_device> m_screen;
|
||||
required_device<tilemap_device> m_playfield_tilemap;
|
||||
required_device<tilemap_device> m_alpha_tilemap;
|
||||
required_device<atari_motion_objects_device> m_mob;
|
||||
|
||||
uint16_t m_h256 = 0;
|
||||
|
||||
static const atari_motion_objects_config s_mob_config;
|
||||
};
|
||||
|
||||
#endif // MAME_ATARI_XYBOTS_H
|
@ -1,147 +0,0 @@
|
||||
// license:BSD-3-Clause
|
||||
// copyright-holders:Aaron Giles
|
||||
/***************************************************************************
|
||||
|
||||
Atari Xybots hardware
|
||||
|
||||
****************************************************************************/
|
||||
|
||||
#include "emu.h"
|
||||
#include "xybots.h"
|
||||
|
||||
|
||||
|
||||
/*************************************
|
||||
*
|
||||
* Tilemap callbacks
|
||||
*
|
||||
*************************************/
|
||||
|
||||
TILE_GET_INFO_MEMBER(xybots_state::get_alpha_tile_info)
|
||||
{
|
||||
uint16_t data = m_alpha_tilemap->basemem_read(tile_index);
|
||||
int code = data & 0x3ff;
|
||||
int color = (data >> 12) & 7;
|
||||
int opaque = data & 0x8000;
|
||||
tileinfo.set(2, code, color, opaque ? TILE_FORCE_LAYER0 : 0);
|
||||
}
|
||||
|
||||
|
||||
TILE_GET_INFO_MEMBER(xybots_state::get_playfield_tile_info)
|
||||
{
|
||||
uint16_t data = m_playfield_tilemap->basemem_read(tile_index);
|
||||
int code = data & 0x1fff;
|
||||
int color = (data >> 11) & 0x0f;
|
||||
tileinfo.set(0, code, color, (data >> 15) & 1);
|
||||
}
|
||||
|
||||
|
||||
|
||||
/*************************************
|
||||
*
|
||||
* Video system start
|
||||
*
|
||||
*************************************/
|
||||
|
||||
const atari_motion_objects_config xybots_state::s_mob_config =
|
||||
{
|
||||
1, /* index to which gfx system */
|
||||
1, /* number of motion object banks */
|
||||
0, /* are the entries linked? */
|
||||
0, /* are the entries split? */
|
||||
0, /* render in reverse order? */
|
||||
0, /* render in swapped X/Y order? */
|
||||
0, /* does the neighbor bit affect the next object? */
|
||||
0, /* pixels per SLIP entry (0 for no-slip) */
|
||||
0, /* pixel offset for SLIPs */
|
||||
0, /* maximum number of links to visit/scanline (0=all) */
|
||||
|
||||
0x100, /* base palette entry */
|
||||
0x300, /* maximum number of colors */
|
||||
0, /* transparent pen index */
|
||||
|
||||
{{ 0x3f }}, /* mask for the link (dummy) */
|
||||
{{ 0x3fff,0,0,0 }}, /* mask for the code index */
|
||||
{{ 0,0,0,0x000f }}, /* mask for the color */
|
||||
{{ 0,0,0,0xff80 }}, /* mask for the X position */
|
||||
{{ 0,0,0xff80,0 }}, /* mask for the Y position */
|
||||
{{ 0 }}, /* mask for the width, in tiles*/
|
||||
{{ 0,0,0x0007,0 }}, /* mask for the height, in tiles */
|
||||
{{ 0x8000,0,0,0 }}, /* mask for the horizontal flip */
|
||||
{{ 0 }}, /* mask for the vertical flip */
|
||||
{{ 0,0x000f,0,0 }}, /* mask for the priority */
|
||||
{{ 0 }}, /* mask for the neighbor */
|
||||
{{ 0 }}, /* mask for absolute coordinates */
|
||||
|
||||
{{ 0 }}, /* mask for the special value */
|
||||
0 /* resulting value to indicate "special" */
|
||||
};
|
||||
|
||||
|
||||
|
||||
/*************************************
|
||||
*
|
||||
* Main refresh
|
||||
*
|
||||
*************************************/
|
||||
|
||||
uint32_t xybots_state::screen_update_xybots(screen_device &screen, bitmap_ind16 &bitmap, const rectangle &cliprect)
|
||||
{
|
||||
// start drawing
|
||||
m_mob->draw_async(cliprect);
|
||||
|
||||
/* draw the playfield */
|
||||
m_playfield_tilemap->draw(screen, bitmap, cliprect, 0, 0);
|
||||
|
||||
// draw and merge the MO
|
||||
bitmap_ind16 &mobitmap = m_mob->bitmap();
|
||||
for (const sparse_dirty_rect *rect = m_mob->first_dirty_rect(cliprect); rect != nullptr; rect = rect->next())
|
||||
for (int y = rect->top(); y <= rect->bottom(); y++)
|
||||
{
|
||||
uint16_t const *const mo = &mobitmap.pix(y);
|
||||
uint16_t *const pf = &bitmap.pix(y);
|
||||
for (int x = rect->left(); x <= rect->right(); x++)
|
||||
if (mo[x] != 0xffff)
|
||||
{
|
||||
/* verified via schematics:
|
||||
|
||||
PRIEN = ~(~MOPIX3 & ~MOPIX2 & ~MOPIX1) = (MOPIX3-0 > 1)
|
||||
|
||||
if (PRIEN)
|
||||
PF/MO = (~MOPRI3-0 > PFCOL3-0)
|
||||
else
|
||||
PF/MO = (~MOPRI3-0 >= PFCOL3-0)
|
||||
|
||||
if (PF/MO | ~(PRIEN & MOCOL3))
|
||||
GPC(P3-0) = PFPIX3-0
|
||||
else
|
||||
GPC(P3-0) = ~MOCOL3-0
|
||||
*/
|
||||
int const mopriority = (mo[x] >> atari_motion_objects_device::PRIORITY_SHIFT) ^ 15;
|
||||
int const pfcolor = (pf[x] >> 4) & 0x0f;
|
||||
int const prien = ((mo[x] & 0x0f) > 1);
|
||||
|
||||
if (prien)
|
||||
{
|
||||
if (mopriority <= pfcolor)
|
||||
{
|
||||
/* this first case doesn't make sense from the schematics, but it has */
|
||||
/* the correct effect */
|
||||
if (mo[x] & 0x80)
|
||||
pf[x] = (mo[x] ^ 0x2f0) & atari_motion_objects_device::DATA_MASK;
|
||||
else
|
||||
pf[x] = mo[x] & atari_motion_objects_device::DATA_MASK;
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
if (mopriority < pfcolor)
|
||||
pf[x] = mo[x] & atari_motion_objects_device::DATA_MASK;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
/* add the alpha on top */
|
||||
m_alpha_tilemap->draw(screen, bitmap, cliprect, 0, 0);
|
||||
return 0;
|
||||
}
|
Loading…
Reference in New Issue
Block a user