atari/ultratnk.cpp, atari/vindictr.cpp, atari/xybots.cpp: consolidated drivers in single files

This commit is contained in:
Ivan Vangelista 2023-02-08 18:04:18 +01:00
parent 5f85581eb7
commit ffc3454fb9
12 changed files with 1313 additions and 1386 deletions

View File

@ -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 )

View File

@ -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

View File

@ -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);
}

View File

@ -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 )

View File

@ -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

View File

@ -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;
}

View File

@ -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 )

View File

@ -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

View File

@ -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;
}
}

View File

@ -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 )

View File

@ -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

View File

@ -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;
}