atari\offtwall.cpp, atari\orbit.cpp, atari\poolshrk.cpp, atari\rampart.cpp, atari\relief.cpp, atari\shuuz.cpp, atari\skullxbo.cpp: consolidated drivers in single files

This commit is contained in:
Ivan Vangelista 2023-02-13 17:03:36 +01:00
parent 332c4ebefd
commit 1b35c0b9a5
25 changed files with 1965 additions and 2008 deletions

View File

@ -1,5 +1,6 @@
// license:BSD-3-Clause
// copyright-holders:Aaron Giles
/***************************************************************************
Atari "Round" hardware
@ -20,15 +21,188 @@
#include "emu.h"
#include "offtwall.h"
#include "atarijsa.h"
#include "atarimo.h"
#include "atarivad.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"
// configurable logging
#define LOG_SOUNDCTRL (1U << 1)
#define LOG_BANKSW (1U << 2)
//#define VERBOSE (LOG_GENERAL | LOG_SOUNDCTRL | LOG_BANKSW)
#include "logmacro.h"
#define LOGSOUNDCTRL(...) LOGMASKED(LOG_SOUNDCTRL, __VA_ARGS__)
#define LOGBANKSW(...) LOGMASKED(LOG_BANKSW, __VA_ARGS__)
namespace {
class offtwall_state : public driver_device
{
public:
offtwall_state(const machine_config &mconfig, device_type type, const char *tag) :
driver_device(mconfig, type, tag),
m_maincpu(*this, "maincpu"),
m_jsa(*this, "jsa"),
m_vad(*this, "vad"),
m_mainram(*this, "mainram"),
m_bankrom_base(*this, "maincpu")
{ }
void offtwall(machine_config &config);
void init_offtwall();
void init_offtwalc();
protected:
virtual void machine_start() override;
private:
required_device<cpu_device> m_maincpu;
required_device<atari_jsa_iii_device> m_jsa;
required_device<atari_vad_device> m_vad;
required_shared_ptr<uint16_t> m_mainram;
uint16_t *m_bankswitch_base = nullptr;
required_region_ptr<uint16_t> m_bankrom_base;
uint32_t m_bank_offset = 0;
uint16_t *m_spritecache_count = nullptr;
uint16_t *m_unknown_verify_base = nullptr;
static const atari_motion_objects_config s_mob_config;
void io_latch_w(offs_t offset, uint16_t data, uint16_t mem_mask = ~0);
uint16_t bankswitch_r(offs_t offset);
uint16_t bankrom_r(address_space &space, offs_t offset);
uint16_t spritecache_count_r(offs_t offset);
uint16_t unknown_verify_r(offs_t offset);
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);
};
// video
/*************************************
*
* Tilemap callbacks
*
*************************************/
TILE_GET_INFO_MEMBER(offtwall_state::get_playfield_tile_info)
{
uint16_t const data1 = m_vad->playfield().basemem_read(tile_index);
uint16_t const data2 = m_vad->playfield().extmem_read(tile_index) >> 8;
int const code = data1 & 0x7fff;
int const color = 0x10 + (data2 & 0x0f);
tileinfo.set(0, code, color, (data1 >> 15) & 1);
}
/*************************************
*
* Video system start
*
*************************************/
const atari_motion_objects_config offtwall_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
{{ 0x00ff,0,0,0 }}, // mask for the link
{{ 0,0x7fff,0,0 }}, // mask for the code index
{{ 0,0,0x000f,0 }}, // mask for the color
{{ 0,0,0xff80,0 }}, // mask for the X position
{{ 0,0,0,0xff80 }}, // mask for the Y position
{{ 0,0,0,0x0070 }}, // mask for the width, in tiles
{{ 0,0,0,0x0007 }}, // mask for the height, in tiles
{{ 0,0x8000,0,0 }}, // mask for the horizontal flip
{{ 0 }}, // mask for the vertical flip
{{ 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 offtwall_state::screen_update(screen_device &screen, bitmap_ind16 &bitmap, const rectangle &cliprect)
{
// start drawing
m_vad->mob().draw_async(cliprect);
// draw the playfield
m_vad->playfield().draw(screen, bitmap, cliprect, 0, 0);
// draw and merge the MO
bitmap_ind16 &mobitmap = m_vad->mob().bitmap();
for (const sparse_dirty_rect *rect = m_vad->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)
{
// not yet verified
pf[x] = mo[x];
}
}
return 0;
}
// machine
/*************************************
*
* Initialization
*
*************************************/
void offtwall_state::machine_start()
{
save_item(NAME(m_bank_offset));
}
/*************************************
*
@ -38,16 +212,16 @@
void offtwall_state::io_latch_w(offs_t offset, uint16_t data, uint16_t mem_mask)
{
/* lower byte */
// lower byte
if (ACCESSING_BITS_0_7)
{
/* bit 4 resets the sound CPU */
// bit 4 resets the sound CPU
m_jsa->soundcpu().set_input_line(INPUT_LINE_RESET, (data & 0x10) ? CLEAR_LINE : ASSERT_LINE);
if (!(data & 0x10))
m_jsa->reset();
}
logerror("sound control = %04X\n", data);
LOGSOUNDCTRL("sound control = %04X\n", data);
}
@ -90,9 +264,9 @@ void offtwall_state::io_latch_w(offs_t offset, uint16_t data, uint16_t mem_mask)
uint16_t offtwall_state::bankswitch_r(offs_t offset)
{
/* this is the table lookup; the bank is determined by the address that was requested */
// this is the table lookup; the bank is determined by the address that was requested
m_bank_offset = (offset & 3) * 0x1000;
logerror("Bankswitch index %d -> %04X\n", offset, m_bank_offset);
LOGBANKSW("Bankswitch index %d -> %04X\n", offset, m_bank_offset);
return m_bankswitch_base[offset];
}
@ -100,15 +274,15 @@ uint16_t offtwall_state::bankswitch_r(offs_t offset)
uint16_t offtwall_state::bankrom_r(address_space &space, offs_t offset)
{
/* this is the banked ROM read */
logerror("%06X: %04X\n", m_maincpu->pcbase(), offset);
// this is the banked ROM read
logerror("Banked ROM read: %06X: %04X\n", m_maincpu->pcbase(), offset);
/* if the values are $3e000 or $3e002 are being read by code just below the
ROM bank area, we need to return the correct value to give the proper checksum */
if ((offset == 0x3000 || offset == 0x3001) && m_maincpu->pcbase() > 0x37000)
{
uint32_t checksum = (space.read_word(0x3fd210) << 16) | space.read_word(0x3fd212);
uint32_t us = 0xaaaa5555 - checksum;
uint32_t const checksum = (space.read_word(0x3fd210) << 16) | space.read_word(0x3fd212);
uint32_t const us = 0xaaaa5555 - checksum;
if (offset == 0x3001)
return us & 0xffff;
else
@ -140,21 +314,21 @@ uint16_t offtwall_state::bankrom_r(address_space &space, offs_t offset)
uint16_t offtwall_state::spritecache_count_r(offs_t offset)
{
int prevpc = m_maincpu->pcbase();
int const prevpc = m_maincpu->pcbase();
/* if this read is coming from $99f8 or $9992, it's in the sprite copy loop */
// if this read is coming from $99f8 or $9992, it's in the sprite copy loop
if (prevpc == 0x99f8 || prevpc == 0x9992)
{
uint16_t *data = &m_spritecache_count[-0x100];
int oldword = m_spritecache_count[0];
int const oldword = m_spritecache_count[0];
int count = oldword >> 8;
int i, width = 0;
int width = 0;
/* compute the current total width */
for (i = 0; i < count; i++)
// compute the current total width
for (int i = 0; i < count; i++)
width += 1 + ((data[i * 4 + 1] >> 4) & 7);
/* if we're less than 39, keep adding dummy sprites until we hit it */
// if we're less than 39, keep adding dummy sprites until we hit it
if (width <= 38)
{
while (width <= 38)
@ -166,12 +340,12 @@ uint16_t offtwall_state::spritecache_count_r(offs_t offset)
count++;
}
/* update the final count in memory */
// update the final count in memory
m_spritecache_count[0] = (count << 8) | (oldword & 0xff);
}
}
/* and then read the data */
// and then read the data
return m_spritecache_count[offset];
}
@ -194,7 +368,7 @@ uint16_t offtwall_state::spritecache_count_r(offs_t offset)
uint16_t offtwall_state::unknown_verify_r(offs_t offset)
{
int prevpc = m_maincpu->pcbase();
int const prevpc = m_maincpu->pcbase();
if (prevpc < 0x5c5e || prevpc > 0xc432)
return m_unknown_verify_base[offset];
else
@ -278,12 +452,12 @@ static INPUT_PORTS_START( offtwall )
PORT_START("260010")
PORT_BIT( 0x0001, IP_ACTIVE_LOW, IPT_UNUSED )
PORT_DIPNAME( 0x0002, 0x0000, DEF_STR( Controls ) )
PORT_DIPSETTING( 0x0000, "Whirly-gigs" ) /* this is official Atari terminology! */
PORT_DIPSETTING( 0x0000, "Whirly-gigs" ) // this is official Atari terminology!
PORT_DIPSETTING( 0x0002, "Joysticks" )
PORT_BIT( 0x0004, IP_ACTIVE_LOW, IPT_UNUSED ) /* tested at a454 */
PORT_BIT( 0x0008, IP_ACTIVE_LOW, IPT_UNUSED ) /* tested at a466 */
PORT_BIT( 0x0004, IP_ACTIVE_LOW, IPT_UNUSED ) // tested at a454
PORT_BIT( 0x0008, IP_ACTIVE_LOW, IPT_UNUSED ) // tested at a466
PORT_BIT( 0x0010, IP_ACTIVE_LOW, IPT_UNUSED )
PORT_BIT( 0x0020, IP_ACTIVE_LOW, IPT_CUSTOM ) PORT_ATARI_JSA_MAIN_TO_SOUND_READY("jsa") /* tested before writing to 260040 */
PORT_BIT( 0x0020, IP_ACTIVE_LOW, IPT_CUSTOM ) PORT_ATARI_JSA_MAIN_TO_SOUND_READY("jsa") // tested before writing to 260040
PORT_SERVICE( 0x0040, IP_ACTIVE_LOW )
PORT_BIT( 0x0080, IP_ACTIVE_LOW, IPT_CUSTOM ) PORT_VBLANK("screen")
PORT_BIT( 0xff00, IP_ACTIVE_LOW, IPT_UNUSED )
@ -325,7 +499,7 @@ static const gfx_layout pfmolayout =
static GFXDECODE_START( gfx_offtwall )
GFXDECODE_ENTRY( "gfx1", 0, pfmolayout, 256, 32 ) /* sprites & playfield */
GFXDECODE_ENTRY( "sprites", 0, pfmolayout, 256, 32 ) // sprites & playfield
GFXDECODE_END
@ -338,15 +512,15 @@ GFXDECODE_END
void offtwall_state::offtwall(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, &offtwall_state::main_map);
EEPROM_2816(config, "eeprom").lock_after_write(true);
WATCHDOG_TIMER(config, "watchdog");
/* video hardware */
// video hardware
GFXDECODE(config, "gfxdecode", "palette", gfx_offtwall);
PALETTE(config, "palette").set_format(palette_device::IRGB_1555, 2048);
@ -357,13 +531,13 @@ void offtwall_state::offtwall(machine_config &config)
screen_device &screen(SCREEN(config, "screen", SCREEN_TYPE_RASTER));
screen.set_video_attributes(VIDEO_UPDATE_BEFORE_VBLANK);
/* note: these parameters are from published specs, not derived */
/* the board uses a VAD chip to generate video signals */
screen.set_raw(14.318181_MHz_XTAL/2, 456, 0, 336, 262, 0, 240);
screen.set_screen_update(FUNC(offtwall_state::screen_update_offtwall));
/* note: these parameters are from published specs, not derived
the board uses a VAD chip to generate video signals */
screen.set_raw(14.318181_MHz_XTAL / 2, 456, 0, 336, 262, 0, 240);
screen.set_screen_update(FUNC(offtwall_state::screen_update));
screen.set_palette("palette");
/* sound hardware */
// sound hardware
SPEAKER(config, "mono").front_center();
ATARI_JSA_III(config, m_jsa, 0);
@ -382,14 +556,14 @@ void offtwall_state::offtwall(machine_config &config)
*************************************/
ROM_START( offtwall )
ROM_REGION( 0x40000, "maincpu", 0 ) /* 4*64k for 68000 code */
ROM_REGION( 0x40000, "maincpu", 0 ) // 68000 code
ROM_LOAD16_BYTE( "136090-2012.17e", 0x00000, 0x20000, CRC(d08d81eb) SHA1(5a72aa2e4fc6455b94aa59a7719d0ddc8bcc80f2) )
ROM_LOAD16_BYTE( "136090-2013.17j", 0x00001, 0x20000, CRC(61c2553d) SHA1(343d39f9b75fd236e9769ec21ab65310f85e31ca) )
ROM_REGION( 0x10000, "jsa:cpu", 0 ) /* 64k for 6502 code */
ROM_REGION( 0x10000, "jsa:cpu", 0 ) // 6502 code
ROM_LOAD( "136090-1020.12c", 0x00000, 0x10000, CRC(488112a5) SHA1(55e84855daacfa303d1031de8c9adb992a846e21) )
ROM_REGION( 0xc0000, "gfx1", ROMREGION_INVERT )
ROM_REGION( 0xc0000, "sprites", ROMREGION_INVERT )
ROM_LOAD( "136090-1014.14s", 0x000000, 0x20000, CRC(4d64507e) SHA1(cb2ac41aecd2702cd57c746a6f5986cd753bc29e) )
ROM_LOAD( "136090-1016.14p", 0x020000, 0x20000, CRC(f5454f3a) SHA1(87d82bd227f7fcfd13b6f4ad88a573d1b96a4fc1) )
ROM_LOAD( "136090-1018.14m", 0x040000, 0x20000, CRC(17864231) SHA1(22f93fcb5d413281157ab8545647f3713f98c135) )
@ -401,28 +575,28 @@ ROM_START( offtwall )
ROM_LOAD( "offtwall-eeprom.17l", 0x0000, 0x800, CRC(5eaf2d5b) SHA1(934a76a23960e6ed2cc33c359f9735caee762145) )
ROM_REGION(0x022f, "jsa:plds", 0)
ROM_LOAD("136085-1038.17c.bin", 0x0000, 0x0117, NO_DUMP ) /* GAL16V8A-25LP is read protected */
ROM_LOAD("136085-1039.20c.bin", 0x0118, 0x0117, NO_DUMP ) /* GAL16V8A-25LP is read protected */
ROM_LOAD("136085-1038.17c.bin", 0x0000, 0x0117, NO_DUMP ) // GAL16V8A-25LP is read protected
ROM_LOAD("136085-1039.20c.bin", 0x0118, 0x0117, NO_DUMP ) // GAL16V8A-25LP is read protected
ROM_REGION(0x2591, "main:plds", 0)
ROM_LOAD("136090-1001.14l.bin", 0x0000, 0x201d, NO_DUMP ) /* GAL6001-35P is read protected */
ROM_LOAD("136090-1002.11r.bin", 0x201e, 0x0117, NO_DUMP ) /* GAL16V8A-25LP is read protected */
ROM_LOAD("136090-1003.15f.bin", 0x2135, 0x0117, CRC(5e723b46) SHA1(e686920d0af342e33f836fec15b6e8b5ef1b8be5)) /* GAL16V8A-25LP */
ROM_LOAD("136090-1005.5n.bin", 0x224c, 0x0117, NO_DUMP ) /* GAL16V8A-25LP is read protected */
ROM_LOAD("136090-1006.5f.bin", 0x2363, 0x0117, NO_DUMP ) /* GAL16V8A-25LP is read protected */
ROM_LOAD("136090-1007.3f.bin", 0x247a, 0x0117, NO_DUMP ) /* GAL16V8A-25LP is read protected */
ROM_LOAD("136090-1001.14l.bin", 0x0000, 0x201d, NO_DUMP ) // GAL6001-35P is read protected
ROM_LOAD("136090-1002.11r.bin", 0x201e, 0x0117, NO_DUMP ) // GAL16V8A-25LP is read protected
ROM_LOAD("136090-1003.15f.bin", 0x2135, 0x0117, CRC(5e723b46) SHA1(e686920d0af342e33f836fec15b6e8b5ef1b8be5)) // GAL16V8A-25LP
ROM_LOAD("136090-1005.5n.bin", 0x224c, 0x0117, NO_DUMP ) // GAL16V8A-25LP is read protected
ROM_LOAD("136090-1006.5f.bin", 0x2363, 0x0117, NO_DUMP ) // GAL16V8A-25LP is read protected
ROM_LOAD("136090-1007.3f.bin", 0x247a, 0x0117, NO_DUMP ) // GAL16V8A-25LP is read protected
ROM_END
ROM_START( offtwallc )
ROM_REGION( 0x40000, "maincpu", 0 ) /* 4*64k for 68000 code */
ROM_REGION( 0x40000, "maincpu", 0 ) // 68000 code
ROM_LOAD16_BYTE( "090-2612.rom", 0x00000, 0x20000, CRC(fc891a3f) SHA1(027815a20fbc6c0c9242768581b97362b39941c2) )
ROM_LOAD16_BYTE( "090-2613.rom", 0x00001, 0x20000, CRC(805d79d4) SHA1(943ec9f408ba875bdf1794ce7d24803043480401) )
ROM_REGION( 0x10000, "jsa:cpu", 0 ) /* 64k for 6502 code */
ROM_REGION( 0x10000, "jsa:cpu", 0 ) // 6502 code
ROM_LOAD( "136090-1020.12c", 0x00000, 0x10000, CRC(488112a5) SHA1(55e84855daacfa303d1031de8c9adb992a846e21) )
ROM_REGION( 0xc0000, "gfx1", ROMREGION_INVERT )
ROM_REGION( 0xc0000, "sprites", ROMREGION_INVERT )
ROM_LOAD( "090-1614.rom", 0x000000, 0x20000, CRC(307ed447) SHA1(acee15e58cd8def8e52a7586aa14240e1f8be319) )
ROM_LOAD( "090-1616.rom", 0x020000, 0x20000, CRC(a5bd3d9b) SHA1(756d96eac2398dc68679b7641acbf0e79204eebb) )
ROM_LOAD( "090-1618.rom", 0x040000, 0x20000, CRC(c7d9df5d) SHA1(d5e5fbb7faf42d865862b9ac60f94d20820b00f3) )
@ -444,27 +618,28 @@ ROM_END
void offtwall_state::init_offtwall()
{
/* install son-of-slapstic workarounds */
// install son-of-slapstic workarounds
m_maincpu->space(AS_PROGRAM).install_read_handler(0x3fde42, 0x3fde43, read16sm_delegate(*this, FUNC(offtwall_state::spritecache_count_r)));
m_maincpu->space(AS_PROGRAM).install_read_handler(0x037ec2, 0x037f39, read16sm_delegate(*this, FUNC(offtwall_state::bankswitch_r)));
m_maincpu->space(AS_PROGRAM).install_read_handler(0x3fdf1e, 0x3fdf1f, read16sm_delegate(*this, FUNC(offtwall_state::unknown_verify_r)));
m_spritecache_count = m_mainram + (0x3fde42 - 0x3fd800)/2;
m_spritecache_count = m_mainram + (0x3fde42 - 0x3fd800) / 2;
m_bankswitch_base = (uint16_t *)(memregion("maincpu")->base() + 0x37ec2);
m_unknown_verify_base = m_mainram + (0x3fdf1e - 0x3fd800)/2;
m_unknown_verify_base = m_mainram + (0x3fdf1e - 0x3fd800) / 2;
}
void offtwall_state::init_offtwalc()
{
/* install son-of-slapstic workarounds */
// install son-of-slapstic workarounds
m_maincpu->space(AS_PROGRAM).install_read_handler(0x3fde42, 0x3fde43, read16sm_delegate(*this, FUNC(offtwall_state::spritecache_count_r)));
m_maincpu->space(AS_PROGRAM).install_read_handler(0x037eca, 0x037f43, read16sm_delegate(*this, FUNC(offtwall_state::bankswitch_r)));
m_maincpu->space(AS_PROGRAM).install_read_handler(0x3fdf24, 0x3fdf25, read16sm_delegate(*this, FUNC(offtwall_state::unknown_verify_r)));
m_spritecache_count = m_mainram + (0x3fde42 - 0x3fd800)/2;
m_spritecache_count = m_mainram + (0x3fde42 - 0x3fd800) / 2;
m_bankswitch_base = (uint16_t *)(memregion("maincpu")->base() + 0x37eca);
m_unknown_verify_base = m_mainram + (0x3fdf24 - 0x3fd800)/2;
m_unknown_verify_base = m_mainram + (0x3fdf24 - 0x3fd800) / 2;
}
} // anonymous namespace
/*************************************
@ -473,5 +648,5 @@ void offtwall_state::init_offtwalc()
*
*************************************/
GAME( 1991, offtwall, 0, offtwall, offtwall, offtwall_state, init_offtwall, ROT0, "Atari Games", "Off the Wall (2/3-player upright)", 0 )
GAME( 1991, offtwallc,offtwall, offtwall, offtwall, offtwall_state, init_offtwalc, ROT0, "Atari Games", "Off the Wall (2-player cocktail)", 0 )
GAME( 1991, offtwall, 0, offtwall, offtwall, offtwall_state, init_offtwall, ROT0, "Atari Games", "Off the Wall (2/3-player upright)", MACHINE_SUPPORTS_SAVE )
GAME( 1991, offtwallc, offtwall, offtwall, offtwall, offtwall_state, init_offtwalc, ROT0, "Atari Games", "Off the Wall (2-player cocktail)", MACHINE_SUPPORTS_SAVE )

View File

@ -1,61 +0,0 @@
// license:BSD-3-Clause
// copyright-holders:Aaron Giles
/*************************************************************************
Atari "Round" hardware
*************************************************************************/
#ifndef MAME_ATARI_OFFTWALL_H
#define MAME_ATARI_OFFTWALL_H
#pragma once
#include "atarijsa.h"
#include "atarimo.h"
#include "atarivad.h"
#include "screen.h"
#include "tilemap.h"
class offtwall_state : public driver_device
{
public:
offtwall_state(const machine_config &mconfig, device_type type, const char *tag) :
driver_device(mconfig, type, tag),
m_maincpu(*this, "maincpu"),
m_jsa(*this, "jsa"),
m_vad(*this, "vad"),
m_mainram(*this, "mainram"),
m_bankrom_base(*this, "maincpu")
{ }
void offtwall(machine_config &config);
void init_offtwall();
void init_offtwalc();
private:
void io_latch_w(offs_t offset, uint16_t data, uint16_t mem_mask = ~0);
uint16_t bankswitch_r(offs_t offset);
uint16_t bankrom_r(address_space &space, offs_t offset);
uint16_t spritecache_count_r(offs_t offset);
uint16_t unknown_verify_r(offs_t offset);
TILE_GET_INFO_MEMBER(get_playfield_tile_info);
uint32_t screen_update_offtwall(screen_device &screen, bitmap_ind16 &bitmap, const rectangle &cliprect);
void main_map(address_map &map);
required_device<cpu_device> m_maincpu;
required_device<atari_jsa_iii_device> m_jsa;
required_device<atari_vad_device> m_vad;
required_shared_ptr<uint16_t> m_mainram;
uint16_t *m_bankswitch_base = nullptr;
required_region_ptr<uint16_t> m_bankrom_base;
uint32_t m_bank_offset = 0;
uint16_t *m_spritecache_count = nullptr;
uint16_t *m_unknown_verify_base = nullptr;
static const atari_motion_objects_config s_mob_config;
};
#endif // MAME_ATARI_OFFTWALL_H

View File

@ -1,102 +0,0 @@
// license:BSD-3-Clause
// copyright-holders:Aaron Giles
/***************************************************************************
Atari "Round" hardware
****************************************************************************/
#include "emu.h"
#include "offtwall.h"
/*************************************
*
* Tilemap callbacks
*
*************************************/
TILE_GET_INFO_MEMBER(offtwall_state::get_playfield_tile_info)
{
uint16_t data1 = m_vad->playfield().basemem_read(tile_index);
uint16_t data2 = m_vad->playfield().extmem_read(tile_index) >> 8;
int code = data1 & 0x7fff;
int color = 0x10 + (data2 & 0x0f);
tileinfo.set(0, code, color, (data1 >> 15) & 1);
}
/*************************************
*
* Video system start
*
*************************************/
const atari_motion_objects_config offtwall_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 */
{{ 0x00ff,0,0,0 }}, /* mask for the link */
{{ 0,0x7fff,0,0 }}, /* mask for the code index */
{{ 0,0,0x000f,0 }}, /* mask for the color */
{{ 0,0,0xff80,0 }}, /* mask for the X position */
{{ 0,0,0,0xff80 }}, /* mask for the Y position */
{{ 0,0,0,0x0070 }}, /* mask for the width, in tiles*/
{{ 0,0,0,0x0007 }}, /* mask for the height, in tiles */
{{ 0,0x8000,0,0 }}, /* mask for the horizontal flip */
{{ 0 }}, /* mask for the vertical flip */
{{ 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 offtwall_state::screen_update_offtwall(screen_device &screen, bitmap_ind16 &bitmap, const rectangle &cliprect)
{
// start drawing
m_vad->mob().draw_async(cliprect);
/* draw the playfield */
m_vad->playfield().draw(screen, bitmap, cliprect, 0, 0);
// draw and merge the MO
bitmap_ind16 &mobitmap = m_vad->mob().bitmap();
for (const sparse_dirty_rect *rect = m_vad->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)
{
// not yet verified
pf[x] = mo[x];
}
}
return 0;
}

View File

@ -1,5 +1,6 @@
// license:BSD-3-Clause
// copyright-holders:Stefan Jokisch
/***************************************************************************
Atari Orbit Driver
@ -20,14 +21,167 @@ Atari Orbit Driver
***************************************************************************/
#include "emu.h"
#include "orbit.h"
#include "orbit_a.h"
#include "cpu/m6800/m6800.h"
#include "machine/74259.h"
#include "machine/timer.h"
#include "machine/watchdog.h"
#include "sound/discrete.h"
#include "emupal.h"
#include "screen.h"
#include "speaker.h"
#include "tilemap.h"
#define MASTER_CLOCK XTAL(12'096'000)
namespace {
class orbit_state : public driver_device
{
public:
orbit_state(const machine_config &mconfig, device_type type, const char *tag) :
driver_device(mconfig, type, tag),
m_playfield_ram(*this, "playfield_ram"),
m_sprite_ram(*this, "sprite_ram"),
m_discrete(*this, "discrete"),
m_latch(*this, "latch"),
m_maincpu(*this, "maincpu"),
m_gfxdecode(*this, "gfxdecode"),
m_screen(*this, "screen"),
m_palette(*this, "palette"),
m_dsw2(*this, "DSW2"),
m_bg_tilemap(nullptr),
m_flip_screen(0)
{ }
void orbit(machine_config &config);
protected:
virtual void machine_start() override;
virtual void machine_reset() override;
virtual void video_start() override;
private:
// memory pointers
required_shared_ptr<uint8_t> m_playfield_ram;
required_shared_ptr<uint8_t> m_sprite_ram;
// devices
required_device<discrete_sound_device> m_discrete;
required_device<f9334_device> m_latch;
required_device<cpu_device> m_maincpu;
required_device<gfxdecode_device> m_gfxdecode;
required_device<screen_device> m_screen;
required_device<palette_device> m_palette;
required_ioport m_dsw2;
// video-related
tilemap_t *m_bg_tilemap;
uint8_t m_flip_screen;
emu_timer *m_irq_off_timer = nullptr;
DECLARE_WRITE_LINE_MEMBER(coin_lockout_w);
void playfield_w(offs_t offset, uint8_t data);
TILE_GET_INFO_MEMBER(get_tile_info);
uint32_t screen_update(screen_device &screen, bitmap_ind16 &bitmap, const rectangle &cliprect);
INTERRUPT_GEN_MEMBER(interrupt);
TIMER_CALLBACK_MEMBER(irq_off);
TIMER_DEVICE_CALLBACK_MEMBER(nmi_32v);
void note_w(uint8_t data);
void note_amp_w(uint8_t data);
void noise_amp_w(uint8_t data);
void noise_rst_w(uint8_t data);
void main_map(address_map &map);
void draw_sprites(bitmap_ind16 &bitmap, const rectangle &cliprect);
void update_misc_flags(address_space &space, uint8_t val);
};
// video
void orbit_state::playfield_w(offs_t offset, uint8_t data)
{
m_playfield_ram[offset] = data;
m_bg_tilemap->mark_tile_dirty(offset);
}
TILE_GET_INFO_MEMBER(orbit_state::get_tile_info)
{
uint8_t const code = m_playfield_ram[tile_index];
int flags = 0;
if (BIT(code, 6))
flags |= TILE_FLIPX;
if (m_flip_screen)
flags |= TILE_FLIPY;
tileinfo.set(3, code & 0x3f, 0, flags);
}
void orbit_state::video_start()
{
m_bg_tilemap = &machine().tilemap().create(*m_gfxdecode, tilemap_get_info_delegate(*this, FUNC(orbit_state::get_tile_info)), TILEMAP_SCAN_ROWS, 16, 16, 32, 30);
}
void orbit_state::draw_sprites(bitmap_ind16 &bitmap, const rectangle &cliprect)
{
const uint8_t* p = m_sprite_ram;
for (int i = 0; i < 16; i++)
{
int code = *p++;
int vpos = *p++;
int hpos = *p++;
int const flag = *p++;
int const layout =
((flag & 0xc0) == 0x80) ? 1 :
((flag & 0xc0) == 0xc0) ? 2 : 0;
int const flip_x = BIT(code, 6);
int const flip_y = BIT(code, 7);
int zoom_x = 0x10000;
int const zoom_y = 0x10000;
code &= 0x3f;
if (flag & 1)
code |= 0x40;
if (flag & 2)
zoom_x *= 2;
vpos = 240 - vpos;
hpos <<= 1;
vpos <<= 1;
m_gfxdecode->gfx(layout)->zoom_transpen(bitmap, cliprect, code, 0, flip_x, flip_y,
hpos, vpos, zoom_x, zoom_y, 0);
}
}
uint32_t orbit_state::screen_update(screen_device &screen, bitmap_ind16 &bitmap, const rectangle &cliprect)
{
m_flip_screen = m_dsw2->read() & 8;
m_bg_tilemap->draw(screen, bitmap, cliprect, 0, 0);
draw_sprites(bitmap, cliprect);
return 0;
}
// machine
/*************************************
*
@ -37,8 +191,8 @@ Atari Orbit Driver
TIMER_DEVICE_CALLBACK_MEMBER(orbit_state::nmi_32v)
{
int scanline = param;
int nmistate = (scanline & 32) && m_latch->q2_r();
int const scanline = param;
int const nmistate = (scanline & 32) && m_latch->q2_r();
m_maincpu->set_input_line(INPUT_LINE_NMI, nmistate ? ASSERT_LINE : CLEAR_LINE);
}
@ -72,6 +226,36 @@ WRITE_LINE_MEMBER(orbit_state::coin_lockout_w)
/*************************************
*
* Write handlers
*
*************************************/
void orbit_state::note_w(uint8_t data)
{
m_discrete->write(ORBIT_NOTE_FREQ, (~data) & 0xff);
}
void orbit_state::note_amp_w(uint8_t data)
{
m_discrete->write(ORBIT_ANOTE1_AMP, data & 0x0f);
m_discrete->write(ORBIT_ANOTE2_AMP, data >> 4);
}
void orbit_state::noise_amp_w(uint8_t data)
{
m_discrete->write(ORBIT_NOISE1_AMP, data & 0x0f);
m_discrete->write(ORBIT_NOISE2_AMP, data >> 4);
}
void orbit_state::noise_rst_w(uint8_t data)
{
m_discrete->write(ORBIT_NOISE_EN, 0);
}
/*************************************
*
* Address maps
@ -107,27 +291,27 @@ void orbit_state::main_map(address_map &map)
*************************************/
static INPUT_PORTS_START( orbit )
PORT_START("P1") /* 0800 */
PORT_START("P1") // 0800
PORT_BIT( 0x01, IP_ACTIVE_LOW, IPT_UNUSED )
PORT_BIT( 0x02, IP_ACTIVE_LOW, IPT_BUTTON2 ) PORT_PLAYER(1)
PORT_BIT( 0x04, IP_ACTIVE_LOW, IPT_JOYSTICK_LEFT ) PORT_PLAYER(1) /* actually buttons */
PORT_BIT( 0x04, IP_ACTIVE_LOW, IPT_JOYSTICK_LEFT ) PORT_PLAYER(1) // actually buttons
PORT_BIT( 0x08, IP_ACTIVE_LOW, IPT_JOYSTICK_RIGHT ) PORT_PLAYER(1)
PORT_BIT( 0x10, IP_ACTIVE_LOW, IPT_BUTTON3 ) PORT_PLAYER(1)
PORT_BIT( 0x20, IP_ACTIVE_LOW, IPT_BUTTON1 ) PORT_PLAYER(1)
PORT_BIT( 0x40, IP_ACTIVE_LOW, IPT_TILT )
PORT_BIT( 0x80, IP_ACTIVE_LOW, IPT_COIN2 )
PORT_START("P2") /* 1000 */
PORT_START("P2") // 1000
PORT_BIT( 0x01, IP_ACTIVE_LOW, IPT_UNUSED )
PORT_BIT( 0x02, IP_ACTIVE_LOW, IPT_BUTTON2 ) PORT_PLAYER(2)
PORT_BIT( 0x04, IP_ACTIVE_LOW, IPT_JOYSTICK_LEFT ) PORT_PLAYER(2) /* actually buttons */
PORT_BIT( 0x04, IP_ACTIVE_LOW, IPT_JOYSTICK_LEFT ) PORT_PLAYER(2) // actually buttons
PORT_BIT( 0x08, IP_ACTIVE_LOW, IPT_JOYSTICK_RIGHT ) PORT_PLAYER(2)
PORT_BIT( 0x10, IP_ACTIVE_LOW, IPT_BUTTON3 ) PORT_PLAYER(2)
PORT_BIT( 0x20, IP_ACTIVE_LOW, IPT_BUTTON1 ) PORT_PLAYER(2)
PORT_SERVICE( 0x40, IP_ACTIVE_LOW )
PORT_BIT( 0x80, IP_ACTIVE_LOW, IPT_COIN1 )
PORT_START("DSW1") /* 1800 */
PORT_START("DSW1") // 1800
PORT_DIPNAME( 0x07, 0x00, "Play Time Per Credit" ) PORT_DIPLOCATION("DSW1:1,2,3")
PORT_DIPSETTING( 0x00, "0:30" )
PORT_DIPSETTING( 0x01, "1:00" )
@ -148,7 +332,7 @@ static INPUT_PORTS_START( orbit )
PORT_DIPUNUSED_DIPLOC( 0x40, 0x00, "DSW1:7" )
PORT_DIPUNUSED_DIPLOC( 0x80, 0x00, "DSW1:8" )
PORT_START("DSW2") /* 2000 */
PORT_START("DSW2") // 2000
PORT_BIT( 0x01, IP_ACTIVE_LOW, IPT_BUTTON1 ) PORT_NAME("Game Reset") PORT_CODE(KEYCODE_PLUS_PAD)
PORT_BIT( 0x02, IP_ACTIVE_LOW, IPT_BUTTON1 ) PORT_NAME("Game 9") PORT_CODE(KEYCODE_9_PAD)
PORT_BIT( 0x04, IP_ACTIVE_LOW, IPT_BUTTON1 ) PORT_NAME("Game 8") PORT_CODE(KEYCODE_8_PAD)
@ -156,15 +340,15 @@ static INPUT_PORTS_START( orbit )
PORT_DIPSETTING( 0x00, DEF_STR( Off ))
PORT_DIPSETTING( 0x08, DEF_STR( On ))
PORT_BIT( 0x10, IP_ACTIVE_LOW, IPT_BUTTON1 ) PORT_NAME("Heat Reset") PORT_CODE(KEYCODE_ENTER_PAD)
PORT_DIPNAME( 0x20, 0x20, "NEXT TEST" ) /* should be off */
PORT_DIPNAME( 0x20, 0x20, "NEXT TEST" ) // should be off
PORT_DIPSETTING( 0x20, DEF_STR( Off ))
PORT_DIPSETTING( 0x00, DEF_STR( On ))
PORT_DIPNAME( 0x40, 0x40, "DIAG TEST" ) /* should be off */
PORT_DIPNAME( 0x40, 0x40, "DIAG TEST" ) // should be off
PORT_DIPSETTING( 0x40, DEF_STR( Off ))
PORT_DIPSETTING( 0x00, DEF_STR( On ))
PORT_BIT( 0x80, IP_ACTIVE_HIGH, IPT_CUSTOM ) PORT_VBLANK("screen")
PORT_START("BUTTONS") /* 2800 */
PORT_START("BUTTONS") // 2800
PORT_BIT( 0x01, IP_ACTIVE_LOW, IPT_BUTTON1 ) PORT_NAME("Game 7 / Strong Gravity") PORT_CODE(KEYCODE_7_PAD)
PORT_BIT( 0x02, IP_ACTIVE_LOW, IPT_BUTTON1 ) PORT_NAME("Game 6 / Stars") PORT_CODE(KEYCODE_6_PAD)
PORT_BIT( 0x04, IP_ACTIVE_LOW, IPT_BUTTON1 ) PORT_NAME("Game 5 / Unlimited Supplies") PORT_CODE(KEYCODE_5_PAD)
@ -219,23 +403,11 @@ static const gfx_layout orbit_lower_sprite_layout =
};
static const gfx_layout orbit_tile_layout =
{
8, 8,
RGN_FRAC(1,1),
1,
{ 0 },
{ STEP8(0,1) },
{ STEP8(0,8) },
0x40
};
static GFXDECODE_START( gfx_orbit )
GFXDECODE_ENTRY( "gfx1", 0, orbit_full_sprite_layout, 0, 1 )
GFXDECODE_ENTRY( "gfx1", 0, orbit_upper_sprite_layout, 0, 1 )
GFXDECODE_ENTRY( "gfx1", 0, orbit_lower_sprite_layout, 0, 1 )
GFXDECODE_SCALE( "gfx2", 0, orbit_tile_layout, 0, 1, 2, 2 )
GFXDECODE_ENTRY( "sprites", 0, orbit_full_sprite_layout, 0, 1 )
GFXDECODE_ENTRY( "sprites", 0, orbit_upper_sprite_layout, 0, 1 )
GFXDECODE_ENTRY( "sprites", 0, orbit_lower_sprite_layout, 0, 1 )
GFXDECODE_SCALE( "tiles", 0, gfx_8x8x1, 0, 1, 2, 2 )
GFXDECODE_END
@ -267,7 +439,9 @@ void orbit_state::machine_reset()
void orbit_state::orbit(machine_config &config)
{
/* basic machine hardware */
constexpr XTAL MASTER_CLOCK = XTAL(12'096'000);
// basic machine hardware
M6800(config, m_maincpu, MASTER_CLOCK / 16);
m_maincpu->set_addrmap(AS_PROGRAM, &orbit_state::main_map);
m_maincpu->set_vblank_int("screen", FUNC(orbit_state::interrupt));
@ -275,14 +449,14 @@ void orbit_state::orbit(machine_config &config)
TIMER(config, "32v").configure_scanline(FUNC(orbit_state::nmi_32v), "screen", 0, 32);
F9334(config, m_latch); // M6
/* BIT0 => UNUSED */
/* BIT1 => LOCKOUT */
/* BIT2 => NMI ENABLE */
/* BIT3 => HEAT RST LED */
/* BIT4 => PANEL BUS OC */
/* BIT5 => PANEL STROBE */
/* BIT6 => HYPER LED */
/* BIT7 => WARNING SND */
// BIT0 => UNUSED
// BIT1 => LOCKOUT
// BIT2 => NMI ENABLE
// BIT3 => HEAT RST LED
// BIT4 => PANEL BUS OC
// BIT5 => PANEL STROBE
// BIT6 => HYPER LED
// BIT7 => WARNING SND
m_latch->q_out_cb<1>().set(FUNC(orbit_state::coin_lockout_w));
m_latch->q_out_cb<3>().set_output("led0");
m_latch->q_out_cb<6>().set_output("led1");
@ -290,7 +464,7 @@ void orbit_state::orbit(machine_config &config)
WATCHDOG_TIMER(config, "watchdog");
/* video hardware */
// video hardware
SCREEN(config, m_screen, SCREEN_TYPE_RASTER);
m_screen->set_raw(MASTER_CLOCK*2, 384*2, 0, 256*2, 261*2, 0, 240*2);
m_screen->set_screen_update(FUNC(orbit_state::screen_update));
@ -300,7 +474,7 @@ void orbit_state::orbit(machine_config &config)
PALETTE(config, m_palette, palette_device::MONOCHROME);
/* sound hardware */
// sound hardware
SPEAKER(config, "lspeaker").front_left();
SPEAKER(config, "rspeaker").front_right();
@ -321,30 +495,31 @@ ROM_START( orbit )
ROM_REGION( 0x10000, "maincpu", 0 )
ROM_LOAD_NIB_LOW ( "033701.h2", 0x6800, 0x400, CRC(6de43b85) SHA1(1643972f45d3a0dd6540158c575cd84cee2b0c9a) )
ROM_LOAD_NIB_HIGH( "033693.l2", 0x6800, 0x400, CRC(8878409e) SHA1(a14e0161705bbc230f0aec1837ebc41d62178368) )
ROM_LOAD_NIB_LOW ( "033702.h1", 0x6C00, 0x400, CRC(8166bdcb) SHA1(b7ae6cd46b4aff6e1e1ec9273cf068dec4a8cd46) )
ROM_LOAD_NIB_HIGH( "033694.l1", 0x6C00, 0x400, CRC(5337a8ee) SHA1(1606bfa652bb5253c387f11c96d77d7a84983344) )
ROM_LOAD_NIB_LOW ( "033702.h1", 0x6c00, 0x400, CRC(8166bdcb) SHA1(b7ae6cd46b4aff6e1e1ec9273cf068dec4a8cd46) )
ROM_LOAD_NIB_HIGH( "033694.l1", 0x6c00, 0x400, CRC(5337a8ee) SHA1(1606bfa652bb5253c387f11c96d77d7a84983344) )
ROM_LOAD_NIB_LOW ( "033699.f2", 0x7000, 0x400, CRC(b498b36f) SHA1(5d150af193196fccd7c20ba731a020a9ae75e516) )
ROM_LOAD_NIB_HIGH( "033691.m2", 0x7000, 0x400, CRC(6cbabb21) SHA1(fffb3f7be73c72b4775d8cdfe174c75ae4389cba) )
ROM_LOAD_NIB_LOW ( "033700.f1", 0x7400, 0x400, CRC(9807c922) SHA1(b6b62530b24d967104f632540ef98f2b4780c3ed) )
ROM_LOAD_NIB_HIGH( "033692.m1", 0x7400, 0x400, CRC(96167d1b) SHA1(6f272b2f1b30aa94f51ea5710f4114bfdea19f2c) )
ROM_LOAD_NIB_LOW ( "033697.e2", 0x7800, 0x400, CRC(19ccf0dc) SHA1(7d12c4985bd0a25ef518246faf2849e5a0cf600b) )
ROM_LOAD_NIB_HIGH( "033689.n2", 0x7800, 0x400, CRC(ea3b70c1) SHA1(5e985fed057f362deaeb5e4049c4e8c1d449d6e1) )
ROM_LOAD_NIB_LOW ( "033698.e1", 0x7C00, 0x400, CRC(356a7c32) SHA1(a3496c0f9d9f3e2e0b452cdc0e908dc93d179990) )
ROM_RELOAD( 0xFC00, 0x400 )
ROM_LOAD_NIB_HIGH( "033690.n1", 0x7C00, 0x400, CRC(f756ebd4) SHA1(4e473541b712078c6a81901714a6243de348e543) )
ROM_RELOAD( 0xFC00, 0x400 )
ROM_LOAD_NIB_LOW ( "033698.e1", 0x7c00, 0x400, CRC(356a7c32) SHA1(a3496c0f9d9f3e2e0b452cdc0e908dc93d179990) )
ROM_RELOAD( 0xfc00, 0x400 )
ROM_LOAD_NIB_HIGH( "033690.n1", 0x7c00, 0x400, CRC(f756ebd4) SHA1(4e473541b712078c6a81901714a6243de348e543) )
ROM_RELOAD( 0xfc00, 0x400 )
ROM_REGION( 0x1000, "gfx1", 0 ) /* sprites */
ROM_REGION( 0x1000, "sprites", 0 )
ROM_LOAD( "033712.b7", 0x0000, 0x800, CRC(cfd43bf2) SHA1(dbca0da6ed355aac921bae5adeef2f384f5fa2c3) )
ROM_LOAD( "033713.d7", 0x0800, 0x800, CRC(5ac89f4d) SHA1(747889b33cd83510a640e68fb4581a3e881c43a3) )
ROM_REGION( 0x200, "gfx2", 0 ) /* tiles */
ROM_REGION( 0x200, "tiles", 0 )
ROM_LOAD( "033711.a7", 0x0000, 0x200, CRC(9987174a) SHA1(d2117b6e6d64c29aef8ad8c94256baea493bce5c) )
ROM_REGION( 0x100, "proms", 0 ) /* sync, unused */
ROM_REGION( 0x100, "sync_prom", 0 ) // unused
ROM_LOAD( "033688.p6", 0x0000, 0x100, CRC(ee66ddba) SHA1(5b9ae4cbf019375c8d54528b69280413c641c4f2) )
ROM_END
} // anonymous namespace
/*************************************

View File

@ -1,93 +0,0 @@
// license:BSD-3-Clause
// copyright-holders:Stefan Jokisch
/*************************************************************************
Atari Orbit hardware
*************************************************************************/
#ifndef MAME_ATARI_ORBIT_H
#define MAME_ATARI_ORBIT_H
#pragma once
#include "machine/74259.h"
#include "machine/timer.h"
#include "sound/discrete.h"
#include "emupal.h"
#include "screen.h"
#include "tilemap.h"
/* Discrete Sound Input Nodes */
#define ORBIT_NOTE_FREQ NODE_01
#define ORBIT_ANOTE1_AMP NODE_02
#define ORBIT_ANOTE2_AMP NODE_03
#define ORBIT_NOISE1_AMP NODE_04
#define ORBIT_NOISE2_AMP NODE_05
#define ORBIT_WARNING_EN NODE_06
#define ORBIT_NOISE_EN NODE_07
class orbit_state : public driver_device
{
public:
orbit_state(const machine_config &mconfig, device_type type, const char *tag) :
driver_device(mconfig, type, tag),
m_playfield_ram(*this, "playfield_ram"),
m_sprite_ram(*this, "sprite_ram"),
m_discrete(*this, "discrete"),
m_bg_tilemap(nullptr),
m_flip_screen(0),
m_latch(*this, "latch"),
m_maincpu(*this, "maincpu"),
m_gfxdecode(*this, "gfxdecode"),
m_screen(*this, "screen"),
m_palette(*this, "palette")
{ }
void orbit(machine_config &config);
protected:
virtual void machine_start() override;
virtual void machine_reset() override;
virtual void video_start() override;
private:
DECLARE_WRITE_LINE_MEMBER(coin_lockout_w);
void playfield_w(offs_t offset, uint8_t data);
TILE_GET_INFO_MEMBER(get_tile_info);
uint32_t screen_update(screen_device &screen, bitmap_ind16 &bitmap, const rectangle &cliprect);
INTERRUPT_GEN_MEMBER(interrupt);
TIMER_CALLBACK_MEMBER(irq_off);
TIMER_DEVICE_CALLBACK_MEMBER(nmi_32v);
void note_w(uint8_t data);
void note_amp_w(uint8_t data);
void noise_amp_w(uint8_t data);
void noise_rst_w(uint8_t data);
void main_map(address_map &map);
void draw_sprites(bitmap_ind16 &bitmap, const rectangle &cliprect);
void update_misc_flags(address_space &space, uint8_t val);
/* memory pointers */
required_shared_ptr<uint8_t> m_playfield_ram;
required_shared_ptr<uint8_t> m_sprite_ram;
required_device<discrete_sound_device> m_discrete;
/* video-related */
tilemap_t *m_bg_tilemap;
int m_flip_screen;
emu_timer *m_irq_off_timer = nullptr;
/* devices */
required_device<f9334_device> m_latch;
required_device<cpu_device> m_maincpu;
required_device<gfxdecode_device> m_gfxdecode;
required_device<screen_device> m_screen;
required_device<palette_device> m_palette;
};
/*----------- defined in audio/orbit.c -----------*/
DISCRETE_SOUND_EXTERN( orbit_discrete );
#endif // MAME_ATARI_ORBIT_H

View File

@ -1,40 +1,14 @@
// license:BSD-3-Clause
// copyright-holders:Derrick Renaud
/*************************************************************************
audio\orbit.cpp
atari\orbit_a.cpp
*************************************************************************/
#include "emu.h"
#include "orbit.h"
/*************************************
*
* Write handlers
*
*************************************/
void orbit_state::note_w(uint8_t data)
{
m_discrete->write(ORBIT_NOTE_FREQ, (~data) & 0xff);
}
void orbit_state::note_amp_w(uint8_t data)
{
m_discrete->write(ORBIT_ANOTE1_AMP, data & 0x0f);
m_discrete->write(ORBIT_ANOTE2_AMP, data >> 4);
}
void orbit_state::noise_amp_w(uint8_t data)
{
m_discrete->write(ORBIT_NOISE1_AMP, data & 0x0f);
m_discrete->write(ORBIT_NOISE2_AMP, data >> 4);
}
void orbit_state::noise_rst_w(uint8_t data)
{
m_discrete->write(ORBIT_NOISE_EN, 0);
}
#include "orbit_a.h"
/************************************************************************/
@ -66,7 +40,7 @@ static const discrete_lfsr_desc orbit_lfsr =
DISCRETE_SOUND_START(orbit_discrete)
/************************************************/
/* orbit Effects Relataive Gain Table */
/* orbit Effects Relative Gain Table */
/* */
/* Effect V-ampIn Gain ratio Relative */
/* Note 3.8 10/(20.1+.47+.55) 962.1 */

28
src/mame/atari/orbit_a.h Normal file
View File

@ -0,0 +1,28 @@
// license:BSD-3-Clause
// copyright-holders:Derrick Renaud
/***************************************************************************
Orbit Audio
***************************************************************************/
#ifndef MAME_ATARI_ORBIT_A_H
#define MAME_ATARI_ORBIT_A_H
#pragma once
#include "sound/discrete.h"
// discrete sound input nodes
#define ORBIT_NOTE_FREQ NODE_01
#define ORBIT_ANOTE1_AMP NODE_02
#define ORBIT_ANOTE2_AMP NODE_03
#define ORBIT_NOISE1_AMP NODE_04
#define ORBIT_NOISE2_AMP NODE_05
#define ORBIT_WARNING_EN NODE_06
#define ORBIT_NOISE_EN NODE_07
DISCRETE_SOUND_EXTERN( orbit_discrete );
#endif // MAME_ATARI_ORBIT_A_H

View File

@ -1,86 +0,0 @@
// license:BSD-3-Clause
// copyright-holders:Stefan Jokisch
/***************************************************************************
Atari Orbit video emulation
***************************************************************************/
#include "emu.h"
#include "orbit.h"
void orbit_state::playfield_w(offs_t offset, uint8_t data)
{
m_playfield_ram[offset] = data;
m_bg_tilemap->mark_tile_dirty(offset);
}
TILE_GET_INFO_MEMBER(orbit_state::get_tile_info)
{
uint8_t code = m_playfield_ram[tile_index];
int flags = 0;
if (BIT(code, 6))
flags |= TILE_FLIPX;
if (m_flip_screen)
flags |= TILE_FLIPY;
tileinfo.set(3, code & 0x3f, 0, flags);
}
void orbit_state::video_start()
{
m_bg_tilemap = &machine().tilemap().create(*m_gfxdecode, tilemap_get_info_delegate(*this, FUNC(orbit_state::get_tile_info)), TILEMAP_SCAN_ROWS, 16, 16, 32, 30);
}
void orbit_state::draw_sprites(bitmap_ind16 &bitmap, const rectangle &cliprect)
{
const uint8_t* p = m_sprite_ram;
for (int i = 0; i < 16; i++)
{
int code = *p++;
int vpos = *p++;
int hpos = *p++;
int flag = *p++;
int layout =
((flag & 0xc0) == 0x80) ? 1 :
((flag & 0xc0) == 0xc0) ? 2 : 0;
int flip_x = BIT(code, 6);
int flip_y = BIT(code, 7);
int zoom_x = 0x10000;
int zoom_y = 0x10000;
code &= 0x3f;
if (flag & 1)
code |= 0x40;
if (flag & 2)
zoom_x *= 2;
vpos = 240 - vpos;
hpos <<= 1;
vpos <<= 1;
m_gfxdecode->gfx(layout)->zoom_transpen(bitmap,cliprect, code, 0, flip_x, flip_y,
hpos, vpos, zoom_x, zoom_y, 0);
}
}
uint32_t orbit_state::screen_update(screen_device &screen, bitmap_ind16 &bitmap, const rectangle &cliprect)
{
m_flip_screen = ioport("DSW2")->read() & 8;
m_bg_tilemap->draw(screen, bitmap, cliprect, 0, 0);
draw_sprites(bitmap, cliprect);
return 0;
}

View File

@ -1,5 +1,6 @@
// license:BSD-3-Clause
// copyright-holders:Stefan Jokisch
/***************************************************************************
Atari Poolshark Driver
@ -7,36 +8,145 @@ Atari Poolshark Driver
***************************************************************************/
#include "emu.h"
#include "poolshrk.h"
#include "poolshrk_a.h"
#include "cpu/m6800/m6800.h"
#include "machine/watchdog.h"
#include "sound/discrete.h"
#include "emupal.h"
#include "screen.h"
#include "speaker.h"
#include "tilemap.h"
namespace {
class poolshrk_state : public driver_device
{
public:
poolshrk_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_gfxdecode(*this, "gfxdecode"),
m_palette(*this, "palette"),
m_discrete(*this, "discrete"),
m_playfield_ram(*this, "playfield_ram"),
m_hpos_ram(*this, "hpos_ram"),
m_vpos_ram(*this, "vpos_ram"),
m_in(*this, "IN%u", 0U),
m_an(*this, "AN%u", 0U),
m_leds(*this, "led%u", 0U)
{ }
void poolshrk(machine_config &config);
void init_poolshrk();
protected:
virtual void machine_start() override { m_leds.resolve(); }
virtual void video_start() override;
private:
required_device<cpu_device> m_maincpu;
required_device<watchdog_timer_device> m_watchdog;
required_device<gfxdecode_device> m_gfxdecode;
required_device<palette_device> m_palette;
required_device<discrete_device> m_discrete;
required_shared_ptr<uint8_t> m_playfield_ram;
required_shared_ptr<uint8_t> m_hpos_ram;
required_shared_ptr<uint8_t> m_vpos_ram;
required_ioport_array<4> m_in;
required_ioport_array<4> m_an;
output_finder<2> m_leds;
tilemap_t *m_bg_tilemap = nullptr;
uint8_t m_da_latch = 0;
void da_latch_w(uint8_t data);
void led_w(offs_t offset, uint8_t data);
void watchdog_w(offs_t offset, uint8_t data);
uint8_t input_r(offs_t offset);
uint8_t irq_reset_r();
void scratch_sound_w(offs_t offset, uint8_t data);
void score_sound_w(uint8_t data);
void click_sound_w(uint8_t data);
void bump_sound_w(offs_t offset, uint8_t data);
TILE_GET_INFO_MEMBER(get_tile_info);
void palette(palette_device &palette) const;
uint32_t screen_update(screen_device &screen, bitmap_ind16 &bitmap, const rectangle &cliprect);
void cpu_map(address_map &map);
};
// video
TILE_GET_INFO_MEMBER(poolshrk_state::get_tile_info)
{
tileinfo.set(1, m_playfield_ram[tile_index] & 0x3f, 0, 0);
}
void poolshrk_state::video_start()
{
m_bg_tilemap = &machine().tilemap().create(*m_gfxdecode, tilemap_get_info_delegate(*this, FUNC(poolshrk_state::get_tile_info)), TILEMAP_SCAN_ROWS, 8, 8, 32, 32);
m_bg_tilemap->set_transparent_pen(0);
}
uint32_t poolshrk_state::screen_update(screen_device &screen, bitmap_ind16 &bitmap, const rectangle &cliprect)
{
m_bg_tilemap->mark_all_dirty();
bitmap.fill(0, cliprect);
// draw sprites
for (int i = 0; i < 16; i++)
{
int const hpos = m_hpos_ram[i];
int const vpos = m_vpos_ram[i];
m_gfxdecode->gfx(0)->transpen(bitmap,cliprect, i, (i == 0) ? 0 : 1, 0, 0, 248 - hpos, vpos - 15, 0);
}
// draw playfield
m_bg_tilemap->draw(screen, bitmap, cliprect, 0, 0);
return 0;
}
// machine
void poolshrk_state::init_poolshrk()
{
uint8_t* pSprite = memregion("gfx1")->base();
uint8_t* pOffset = memregion("proms")->base();
uint8_t *pSprite = memregion("sprites")->base();
uint8_t *pOffset = memregion("proms")->base();
/* re-arrange sprite data using the PROM */
// re-arrange sprite data using the PROM
for (int i = 0; i < 16; i++)
{
for (int j = 0; j < 16; j++)
{
uint16_t v =
(pSprite[0] << 0xC) |
(pSprite[0] << 0xc) |
(pSprite[1] << 0x8) |
(pSprite[2] << 0x4) |
(pSprite[3] << 0x0);
v >>= pOffset[j];
pSprite[0] = (v >> 0xC) & 15;
pSprite[0] = (v >> 0xc) & 15;
pSprite[1] = (v >> 0x8) & 15;
pSprite[2] = (v >> 0x4) & 15;
pSprite[3] = (v >> 0x0) & 15;
@ -49,6 +159,33 @@ void poolshrk_state::init_poolshrk()
}
/*************************************
*
* Write handlers
*
*************************************/
void poolshrk_state::scratch_sound_w(offs_t offset, uint8_t data)
{
m_discrete->write(POOLSHRK_SCRATCH_SND, offset & 1);
}
void poolshrk_state::score_sound_w(uint8_t data)
{
m_discrete->write(POOLSHRK_SCORE_EN, 1); // this will trigger the sound code for 1 sample
}
void poolshrk_state::click_sound_w(uint8_t data)
{
m_discrete->write(POOLSHRK_CLICK_EN, 1); // this will trigger the sound code for 1 sample
}
void poolshrk_state::bump_sound_w(offs_t offset, uint8_t data)
{
m_discrete->write(POOLSHRK_BUMP_EN, offset & 1);
}
void poolshrk_state::da_latch_w(uint8_t data)
{
m_da_latch = data & 15;
@ -75,11 +212,10 @@ void poolshrk_state::watchdog_w(offs_t offset, uint8_t data)
uint8_t poolshrk_state::input_r(offs_t offset)
{
static const char *const portnames[] = { "IN0", "IN1", "IN2", "IN3" };
uint8_t val = ioport(portnames[offset & 3])->read();
uint8_t val = m_in[offset & 3]->read();
int x = ioport((offset & 1) ? "AN1" : "AN0")->read();
int y = ioport((offset & 1) ? "AN3" : "AN2")->read();
int const x = (offset & 1) ? m_an[1]->read() : m_an[0]->read();
int const y = (offset & 1) ? m_an[3]->read() : m_an[2]->read();
if (x >= m_da_latch) val |= 8;
if (y >= m_da_latch) val |= 4;
@ -101,18 +237,18 @@ uint8_t poolshrk_state::irq_reset_r()
}
void poolshrk_state::poolshrk_cpu_map(address_map &map)
void poolshrk_state::cpu_map(address_map &map)
{
map.global_mask(0x7fff);
map(0x0000, 0x00ff).mirror(0x2300).ram();
map(0x0400, 0x07ff).mirror(0x2000).writeonly().share("playfield_ram");
map(0x0800, 0x080f).mirror(0x23f0).writeonly().share("hpos_ram");
map(0x0c00, 0x0c0f).mirror(0x23f0).writeonly().share("vpos_ram");
map(0x0400, 0x07ff).mirror(0x2000).writeonly().share(m_playfield_ram);
map(0x0800, 0x080f).mirror(0x23f0).writeonly().share(m_hpos_ram);
map(0x0c00, 0x0c0f).mirror(0x23f0).writeonly().share(m_vpos_ram);
map(0x1000, 0x13ff).mirror(0x2000).rw(FUNC(poolshrk_state::input_r), FUNC(poolshrk_state::watchdog_w));
map(0x1400, 0x17ff).mirror(0x2000).w(FUNC(poolshrk_state::scratch_sound_w));
map(0x1800, 0x1bff).mirror(0x2000).w(FUNC(poolshrk_state::score_sound_w));
map(0x1c00, 0x1fff).mirror(0x2000).w(FUNC(poolshrk_state::click_sound_w));
map(0x4000, 0x4000).noprw(); /* diagnostic ROM location */
map(0x4000, 0x4000).noprw(); // diagnostic ROM location
map(0x6000, 0x63ff).w(FUNC(poolshrk_state::da_latch_w));
map(0x6400, 0x67ff).w(FUNC(poolshrk_state::bump_sound_w));
map(0x6800, 0x6bff).r(FUNC(poolshrk_state::irq_reset_r));
@ -169,45 +305,45 @@ INPUT_PORTS_END
static const gfx_layout poolshrk_sprite_layout =
{
16, 16, /* width, height */
16, /* total */
1, /* planes */
{ 0 }, /* plane offsets */
16, 16, // width, height
16, // total
1, // planes
{ 0 }, // plane offsets
{
0x04, 0x05, 0x06, 0x07, 0x0C, 0x0D, 0x0E, 0x0F,
0x14, 0x15, 0x16, 0x17, 0x1C, 0x1D, 0x1E, 0x1F
0x04, 0x05, 0x06, 0x07, 0x0c, 0x0d, 0x0e, 0x0f,
0x14, 0x15, 0x16, 0x17, 0x1c, 0x1d, 0x1e, 0x1f
},
{
0x000, 0x020, 0x040, 0x060, 0x080, 0x0A0, 0x0C0, 0x0E0,
0x100, 0x120, 0x140, 0x160, 0x180, 0x1A0, 0x1C0, 0x1E0
0x000, 0x020, 0x040, 0x060, 0x080, 0x0a0, 0x0c0, 0x0e0,
0x100, 0x120, 0x140, 0x160, 0x180, 0x1a0, 0x1c0, 0x1e0
},
0x200 /* increment */
0x200 // increment
};
static const gfx_layout poolshrk_tile_layout =
{
8, 8, /* width, height */
64, /* total */
1, /* planes */
{ 0 }, /* plane offsets */
8, 8, // width, height
64, // total
1, // planes
{ 0 }, // plane offsets
{
7, 6, 5, 4, 3, 2, 1, 0
},
{
0x000, 0x200, 0x400, 0x600, 0x800, 0xA00, 0xC00, 0xE00
0x000, 0x200, 0x400, 0x600, 0x800, 0xa00, 0xc00, 0xe00
},
0x8 /* increment */
};
static GFXDECODE_START( gfx_poolshrk )
GFXDECODE_ENTRY( "gfx1", 0, poolshrk_sprite_layout, 0, 2 )
GFXDECODE_ENTRY( "gfx2", 0, poolshrk_tile_layout, 0, 1 )
GFXDECODE_ENTRY( "sprites", 0, poolshrk_sprite_layout, 0, 2 )
GFXDECODE_ENTRY( "tiles", 0, poolshrk_tile_layout, 0, 1 )
GFXDECODE_END
void poolshrk_state::poolshrk_palette(palette_device &palette) const
void poolshrk_state::palette(palette_device &palette) const
{
palette.set_pen_color(0, rgb_t(0x7f, 0x7f, 0x7f));
palette.set_pen_color(1, rgb_t(0xff, 0xff, 0xff));
@ -218,14 +354,14 @@ void poolshrk_state::poolshrk_palette(palette_device &palette) const
void poolshrk_state::poolshrk(machine_config &config)
{
/* basic machine hardware */
M6800(config, m_maincpu, 11055000 / 8); /* ? */
m_maincpu->set_addrmap(AS_PROGRAM, &poolshrk_state::poolshrk_cpu_map);
// basic machine hardware
M6800(config, m_maincpu, 11'055'000 / 8); // ?
m_maincpu->set_addrmap(AS_PROGRAM, &poolshrk_state::cpu_map);
m_maincpu->set_vblank_int("screen", FUNC(poolshrk_state::irq0_line_assert));
WATCHDOG_TIMER(config, m_watchdog);
/* video hardware */
// video hardware
screen_device &screen(SCREEN(config, "screen", SCREEN_TYPE_RASTER));
screen.set_refresh_hz(60);
screen.set_size(256, 256);
@ -234,9 +370,9 @@ void poolshrk_state::poolshrk(machine_config &config)
screen.set_palette(m_palette);
GFXDECODE(config, m_gfxdecode, m_palette, gfx_poolshrk);
PALETTE(config, m_palette, FUNC(poolshrk_state::poolshrk_palette), 4);
PALETTE(config, m_palette, FUNC(poolshrk_state::palette), 4);
/* sound hardware */
// sound hardware
SPEAKER(config, "mono").front_center();
DISCRETE(config, m_discrete, poolshrk_discrete).add_route(ALL_OUTPUTS, "mono", 1.0);
@ -248,16 +384,18 @@ ROM_START( poolshrk )
ROM_LOAD( "7329.k1", 0x7000, 0x800, CRC(88152245) SHA1(c7c5e43ea488a197e92a1dc2231578f8ed86c98d) )
ROM_LOAD( "7330.l1", 0x7800, 0x800, CRC(fb41d3e9) SHA1(c17994179362da13acfcd36a28f45e328428c031) )
ROM_REGION( 0x400, "gfx1", 0 ) /* sprites */
ROM_REGION( 0x400, "sprites", 0 )
ROM_LOAD( "7325.j5", 0x0000, 0x200, CRC(fae87eed) SHA1(8891d0ea60f72f826d71dc6b064a2ba81b298914) )
ROM_LOAD( "7326.h5", 0x0200, 0x200, CRC(05ec9762) SHA1(6119c4529334c98a0a42ca13a98a8661fc594d80) )
ROM_REGION( 0x200, "gfx2", 0 ) /* tiles */
ROM_REGION( 0x200, "tiles", 0 )
ROM_LOAD( "7328.n6", 0x0000, 0x200, CRC(64bcbf3a) SHA1(a4e3ce6b4734234359e3ef784a771e40580c2a2a) )
ROM_REGION( 0x20, "proms", 0 ) /* line offsets */
ROM_REGION( 0x20, "proms", 0 ) // line offsets
ROM_LOAD( "7327.k6", 0x0000, 0x020, CRC(f74cef5b) SHA1(f470bf5b193dae4b44e89bc4c4476cf8d98e7cfd) )
ROM_END
} // anonymous namespace
GAME( 1977, poolshrk, 0, poolshrk, poolshrk, poolshrk_state, init_poolshrk, 0, "Atari", "Poolshark", MACHINE_SUPPORTS_SAVE )

View File

@ -1,79 +0,0 @@
// license:BSD-3-Clause
// copyright-holders:Stefan Jokisch
/*************************************************************************
Atari Pool Shark hardware
*************************************************************************/
#ifndef MAME_ATARI_POOLSHRK_H
#define MAME_ATARI_POOLSHRK_H
#pragma once
#include "machine/watchdog.h"
#include "sound/discrete.h"
#include "emupal.h"
#include "tilemap.h"
/* Discrete Sound Input Nodes */
class poolshrk_state : public driver_device
{
public:
poolshrk_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_gfxdecode(*this, "gfxdecode"),
m_palette(*this, "palette"),
m_discrete(*this, "discrete"),
m_playfield_ram(*this, "playfield_ram"),
m_hpos_ram(*this, "hpos_ram"),
m_vpos_ram(*this, "vpos_ram"),
m_leds(*this, "led%u", 0U)
{ }
void poolshrk(machine_config &config);
void init_poolshrk();
private:
void da_latch_w(uint8_t data);
void led_w(offs_t offset, uint8_t data);
void watchdog_w(offs_t offset, uint8_t data);
uint8_t input_r(offs_t offset);
uint8_t irq_reset_r();
void scratch_sound_w(offs_t offset, uint8_t data);
void score_sound_w(uint8_t data);
void click_sound_w(uint8_t data);
void bump_sound_w(offs_t offset, uint8_t data);
TILE_GET_INFO_MEMBER(get_tile_info);
void poolshrk_palette(palette_device &palette) const;
uint32_t screen_update(screen_device &screen, bitmap_ind16 &bitmap, const rectangle &cliprect);
virtual void video_start() override;
void poolshrk_cpu_map(address_map &map);
virtual void machine_start() override { m_leds.resolve(); }
required_device<cpu_device> m_maincpu;
required_device<watchdog_timer_device> m_watchdog;
required_device<gfxdecode_device> m_gfxdecode;
required_device<palette_device> m_palette;
required_device<discrete_device> m_discrete;
required_shared_ptr<uint8_t> m_playfield_ram;
required_shared_ptr<uint8_t> m_hpos_ram;
required_shared_ptr<uint8_t> m_vpos_ram;
output_finder<2> m_leds;
tilemap_t* m_bg_tilemap = nullptr;
int m_da_latch = 0;
};
/*----------- defined in audio/poolshrk.c -----------*/
DISCRETE_SOUND_EXTERN( poolshrk_discrete );
#endif // MAME_ATARI_POOLSHRK_H

View File

@ -1,13 +1,14 @@
// license:BSD-3-Clause
// copyright-holders:Derrick Renaud
/*************************************************************************
audio\poolshrk.c
atari\poolshrk_a.cpp
*************************************************************************/
#include "emu.h"
#include "poolshrk.h"
#include "sound/discrete.h"
#include "poolshrk_a.h"
/************************************************************************/
/* poolshrk Sound System Analog emulation */
@ -45,16 +46,6 @@ static const discrete_mixer_desc poolshrk_mixer =
1000000
};
/* Nodes - Inputs */
#define POOLSHRK_BUMP_EN NODE_01
#define POOLSHRK_CLICK_EN NODE_02
#define POOLSHRK_SCORE_EN NODE_03
/* Nodes - Sounds */
#define POOLSHRK_BUMP_SND NODE_10
#define POOLSHRK_SCRATCH_SND NODE_11
#define POOLSHRK_CLICK_SND NODE_12
#define POOLSHRK_SCORE_SND NODE_13
DISCRETE_SOUND_START(poolshrk_discrete)
/************************************************/
/* Input register mapping for poolshrk */
@ -68,7 +59,7 @@ DISCRETE_SOUND_START(poolshrk_discrete)
/************************************************/
/* Scratch is just the trigger sent directly */
/* to the output. We take care of it's */
/* to the output. We take care of its */
/* amplitude right in it's DISCRETE_INPUTX. */
/************************************************/
@ -149,30 +140,3 @@ DISCRETE_SOUND_START(poolshrk_discrete)
DISCRETE_MIXER4(NODE_90, 1, POOLSHRK_SCRATCH_SND, POOLSHRK_CLICK_SND, POOLSHRK_SCORE_SND, POOLSHRK_BUMP_SND, &poolshrk_mixer)
DISCRETE_OUTPUT(NODE_90, 1)
DISCRETE_SOUND_END
/*************************************
*
* Write handlers
*
*************************************/
void poolshrk_state::scratch_sound_w(offs_t offset, uint8_t data)
{
m_discrete->write(POOLSHRK_SCRATCH_SND, offset & 1);
}
void poolshrk_state::score_sound_w(uint8_t data)
{
m_discrete->write(POOLSHRK_SCORE_EN, 1); /* this will trigger the sound code for 1 sample */
}
void poolshrk_state::click_sound_w(uint8_t data)
{
m_discrete->write(POOLSHRK_CLICK_EN, 1); /* this will trigger the sound code for 1 sample */
}
void poolshrk_state::bump_sound_w(offs_t offset, uint8_t data)
{
m_discrete->write(POOLSHRK_BUMP_EN, offset & 1);
}

View File

@ -0,0 +1,31 @@
// license:BSD-3-Clause
// copyright-holders:Derrick Renaud
/***************************************************************************
Pool Shark Audio
***************************************************************************/
#ifndef MAME_ATARI_POOLSHRK_A_H
#define MAME_ATARI_POOLSHRK_A_H
#pragma once
#include "sound/discrete.h"
// discrete sound input nodes
#define POOLSHRK_BUMP_EN NODE_01
#define POOLSHRK_CLICK_EN NODE_02
#define POOLSHRK_SCORE_EN NODE_03
// Nodes - Sounds
#define POOLSHRK_BUMP_SND NODE_10
#define POOLSHRK_SCRATCH_SND NODE_11
#define POOLSHRK_CLICK_SND NODE_12
#define POOLSHRK_SCORE_SND NODE_13
DISCRETE_SOUND_EXTERN( poolshrk_discrete );
#endif // MAME_ATARI_POOLSHRK_A_H

View File

@ -1,51 +0,0 @@
// license:BSD-3-Clause
// copyright-holders:Stefan Jokisch
/***************************************************************************
Atari Poolshark video emulation
***************************************************************************/
#include "emu.h"
#include "poolshrk.h"
TILE_GET_INFO_MEMBER(poolshrk_state::get_tile_info)
{
tileinfo.set(1, m_playfield_ram[tile_index] & 0x3f, 0, 0);
}
void poolshrk_state::video_start()
{
m_bg_tilemap = &machine().tilemap().create(*m_gfxdecode, tilemap_get_info_delegate(*this, FUNC(poolshrk_state::get_tile_info)), TILEMAP_SCAN_ROWS,
8, 8, 32, 32);
m_bg_tilemap->set_transparent_pen(0);
}
uint32_t poolshrk_state::screen_update(screen_device &screen, bitmap_ind16 &bitmap, const rectangle &cliprect)
{
m_bg_tilemap->mark_all_dirty();
bitmap.fill(0, cliprect);
/* draw sprites */
for (int i = 0; i < 16; i++)
{
int hpos = m_hpos_ram[i];
int vpos = m_vpos_ram[i];
m_gfxdecode->gfx(0)->transpen(bitmap,cliprect, i, (i == 0) ? 0 : 1, 0, 0,
248 - hpos, vpos - 15, 0);
}
/* draw playfield */
m_bg_tilemap->draw(screen, bitmap, cliprect, 0, 0);
return 0;
}

View File

@ -1,5 +1,6 @@
// license:BSD-3-Clause
// copyright-holders:Aaron Giles
/***************************************************************************
Atari Rampart hardware
@ -25,17 +26,200 @@
#include "emu.h"
#include "rampart.h"
#include "atarimo.h"
#include "slapstic.h"
#include "cpu/m68000/m68000.h"
#include "machine/eeprompar.h"
#include "machine/timer.h"
#include "machine/watchdog.h"
#include "sound/okim6295.h"
#include "sound/ymopl.h"
#include "emupal.h"
#include "screen.h"
#include "speaker.h"
#define MASTER_CLOCK XTAL(14'318'181)
// configurable logging
#define LOG_COLBANK (1U << 1)
//#define VERBOSE (LOG_GENERAL | LOG_COLBANK)
#include "logmacro.h"
#define LOGCOLBANK(...) LOGMASKED(LOG_COLBANK, __VA_ARGS__)
namespace {
class rampart_state : public driver_device
{
public:
rampart_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_gfxdecode(*this, "gfxdecode"),
m_screen(*this, "screen"),
m_mob(*this, "mob"),
m_oki(*this, "oki"),
m_ym2413(*this, "ymsnd"),
m_bitmap(*this, "bitmap")
{ }
void rampart(machine_config &config);
protected:
virtual void machine_start() override;
virtual void video_start() override;
private:
required_device<cpu_device> m_maincpu;
required_device<atari_slapstic_device> m_slapstic;
required_memory_bank m_slapstic_bank;
required_device<gfxdecode_device> m_gfxdecode;
required_device<screen_device> m_screen;
required_device<atari_motion_objects_device> m_mob;
required_device<okim6295_device> m_oki;
required_device<ym2413_device> m_ym2413;
required_shared_ptr<u16> m_bitmap;
static const atari_motion_objects_config s_mob_config;
TIMER_DEVICE_CALLBACK_MEMBER(scanline_interrupt);
void scanline_int_ack_w(u16 data);
void latch_w(offs_t offset, u16 data, u16 mem_mask = ~0);
u32 screen_update(screen_device &screen, bitmap_ind16 &bitmap, const rectangle &cliprect);
void bitmap_render(bitmap_ind16 &bitmap, const rectangle &cliprect);
void main_map(address_map &map);
};
// video
/*************************************
*
* Video system start
*
*************************************/
const atari_motion_objects_config rampart_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
{{ 0x00ff,0,0,0 }}, // mask for the link
{{ 0,0x7fff,0,0 }}, // mask for the code index
{{ 0,0,0x000f,0 }}, // mask for the color
{{ 0,0,0xff80,0 }}, // mask for the X position
{{ 0,0,0,0xff80 }}, // mask for the Y position
{{ 0,0,0,0x0070 }}, // mask for the width, in tiles
{{ 0,0,0,0x0007 }}, // mask for the height, in tiles
{{ 0,0x8000,0,0 }}, // mask for the horizontal flip
{{ 0 }}, // mask for the vertical flip
{{ 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 rampart_state::video_start()
{
// set the initial scroll offset
m_mob->set_xscroll(-12);
}
/*************************************
*
* Main refresh
*
*************************************/
uint32_t rampart_state::screen_update(screen_device &screen, bitmap_ind16 &bitmap, const rectangle &cliprect)
{
// start drawing
m_mob->draw_async(cliprect);
// draw the playfield
bitmap_render(bitmap, cliprect);
// 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)
{
// the PCB supports more complex priorities, but the PAL is not stuffed, so we get the default
pf[x] = mo[x];
}
}
return 0;
}
/*************************************
*
* Bitmap rendering
*
*************************************/
void rampart_state::bitmap_render(bitmap_ind16 &bitmap, const rectangle &cliprect)
{
// update any dirty scanlines
for (int y = cliprect.top(); y <= cliprect.bottom(); y++)
{
uint16_t const *const src = &m_bitmap[256 * y];
uint16_t *const dst = &bitmap.pix(y);
// regenerate the line
for (int x = cliprect.left() & ~1; x <= cliprect.right(); x += 2)
{
int const bits = src[(x - 8) / 2];
dst[x + 0] = bits >> 8;
dst[x + 1] = bits & 0xff;
}
}
}
// machine
/*************************************
*
* Initialization
*
*************************************/
void rampart_state::machine_start()
{
m_slapstic_bank->configure_entries(0, 4, memregion("maincpu")->base() + 0x40000, 0x2000);
}
/*************************************
*
@ -45,7 +229,7 @@
TIMER_DEVICE_CALLBACK_MEMBER(rampart_state::scanline_interrupt)
{
/* generate 32V signals */
// generate 32V signals
if ((param & 32) == 0)
m_maincpu->set_input_line(M68K_IRQ_4, ASSERT_LINE);
}
@ -82,16 +266,16 @@ void rampart_state::latch_w(offs_t offset, u16 data, u16 mem_mask)
0x0001 == /YAMRES (YM2413 reset)
*/
/* upper byte being modified? */
// upper byte being modified?
if (ACCESSING_BITS_8_15)
{
if (data & 0x1000)
logerror("Color bank set to 1!\n");
LOGCOLBANK("Color bank set to 1!\n");
machine().bookkeeping().coin_counter_w(0, (data >> 9) & 1);
machine().bookkeeping().coin_counter_w(1, (data >> 8) & 1);
}
/* lower byte being modified? */
// lower byte being modified?
if (ACCESSING_BITS_0_7)
{
m_oki->set_output_gain(ALL_OUTPUTS, (data & 0x0020) ? 1.0f : 0.0f);
@ -111,14 +295,14 @@ void rampart_state::latch_w(offs_t offset, u16 data, u16 mem_mask)
*
*************************************/
/* full memory map deduced from schematics and GALs */
// full memory map deduced from schematics and GALs
void rampart_state::main_map(address_map &map)
{
map.global_mask(0x7fffff);
map(0x000000, 0x0fffff).rom();
map(0x140000, 0x141fff).mirror(0x43e000).bankr(m_slapstic_bank); /* slapstic goes here */
map(0x200000, 0x21ffff).ram().share("bitmap");
map(0x220000, 0x3bffff).nopw(); /* the code blasts right through this when initializing */
map(0x140000, 0x141fff).mirror(0x43e000).bankr(m_slapstic_bank);
map(0x200000, 0x21ffff).ram().share(m_bitmap);
map(0x220000, 0x3bffff).nopw(); // the code blasts right through this when initializing
map(0x3c0000, 0x3c07ff).mirror(0x019800).rw("palette", FUNC(palette_device::read8), FUNC(palette_device::write8)).umask16(0xff00).share("palette");
map(0x3e0000, 0x3e07ff).mirror(0x010000).ram().share("mob");
map(0x3e0800, 0x3e3f3f).mirror(0x010000).ram();
@ -298,20 +482,8 @@ INPUT_PORTS_END
*
*************************************/
static const gfx_layout molayout =
{
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_rampart )
GFXDECODE_ENTRY( "gfx1", 0, molayout, 256, 16 )
GFXDECODE_ENTRY( "gfx", 0, gfx_8x8x4_packed_msb, 256, 16 )
GFXDECODE_END
@ -324,8 +496,10 @@ GFXDECODE_END
void rampart_state::rampart(machine_config &config)
{
/* basic machine hardware */
M68000(config, m_maincpu, MASTER_CLOCK/2);
constexpr XTAL MASTER_CLOCK = XTAL(14'318'181);
// basic machine hardware
M68000(config, m_maincpu, MASTER_CLOCK / 2);
m_maincpu->set_addrmap(AS_PROGRAM, &rampart_state::main_map);
SLAPSTIC(config, m_slapstic, 118);
@ -338,7 +512,7 @@ void rampart_state::rampart(machine_config &config)
WATCHDOG_TIMER(config, "watchdog").set_vblank_count(m_screen, 8);
/* video hardware */
// video hardware
GFXDECODE(config, m_gfxdecode, "palette", gfx_rampart);
PALETTE(config, "palette").set_format(palette_device::IRGB_1555, 512).set_membits(8);
@ -347,19 +521,19 @@ void rampart_state::rampart(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 an SOS-2 chip to generate video signals */
m_screen->set_raw(MASTER_CLOCK/2, 456, 0+12, 336+12, 262, 0, 240);
m_screen->set_screen_update(FUNC(rampart_state::screen_update_rampart));
/* note: these parameters are from published specs, not derived
the board uses an SOS-2 chip to generate video signals */
m_screen->set_raw(MASTER_CLOCK / 2, 456, 0+12, 336+12, 262, 0, 240);
m_screen->set_screen_update(FUNC(rampart_state::screen_update));
m_screen->set_palette("palette");
//m_screen->screen_vblank().set(FUNC(rampart_state::video_int_write_line));
/* sound hardware */
// sound hardware
SPEAKER(config, "mono").front_center();
OKIM6295(config, m_oki, MASTER_CLOCK/4/3, okim6295_device::PIN7_LOW).add_route(ALL_OUTPUTS, "mono", 0.60);
OKIM6295(config, m_oki, MASTER_CLOCK / 4 / 3, okim6295_device::PIN7_LOW).add_route(ALL_OUTPUTS, "mono", 0.60);
YM2413(config, m_ym2413, MASTER_CLOCK/4).add_route(ALL_OUTPUTS, "mono", 1.0);
YM2413(config, m_ym2413, MASTER_CLOCK / 4).add_route(ALL_OUTPUTS, "mono", 1.0);
}
@ -377,10 +551,10 @@ ROM_START( rampart )
ROM_LOAD16_BYTE( "136082-2031.13l", 0x00000, 0x10000, CRC(07650c7e) SHA1(0a8eec76aefd4fd1515c1a0d5b96f71c674cdce7) )
ROM_LOAD16_BYTE( "136082-2030.13h", 0x00001, 0x10000, CRC(e2bf2a26) SHA1(be15b3b0e302382518436441875a1b72954a589a) )
ROM_REGION( 0x20000, "gfx1", ROMREGION_INVERT )
ROM_REGION( 0x20000, "gfx", ROMREGION_INVERT )
ROM_LOAD( "136082-1009.2n", 0x000000, 0x20000, CRC(23b95f59) SHA1(cec8523eaf83d4c9bb0055f34024a6e9c52c4c0c) )
ROM_REGION( 0x40000, "oki", 0 ) /* ADPCM data */
ROM_REGION( 0x40000, "oki", 0 ) // ADPCM data
ROM_LOAD( "136082-1007.2d", 0x00000, 0x20000, CRC(c96a0fc3) SHA1(6e7e242d0afa4714ca31d77ccbf8ee487bbdb1e4) )
ROM_LOAD( "136082-1008.1d", 0x20000, 0x20000, CRC(518218d9) SHA1(edf1b11579dcfa9a872fa4bd866dc2f95fac767d) )
@ -404,10 +578,10 @@ ROM_START( rampart2p )
ROM_LOAD16_BYTE( "136082-2051.13kl", 0x00000, 0x20000, CRC(d4e26d0f) SHA1(5106549e6d003711bfd390aa2e19e6e5f33f2cf9) )
ROM_LOAD16_BYTE( "136082-2050.13h", 0x00001, 0x20000, CRC(ed2a49bd) SHA1(b97ee41b7f930ba7b8b113c1b19c7729a5880b1f) )
ROM_REGION( 0x20000, "gfx1", ROMREGION_INVERT )
ROM_REGION( 0x20000, "gfx", ROMREGION_INVERT )
ROM_LOAD( "136082-1019.2n", 0x000000, 0x20000, CRC(efa38bef) SHA1(d38448138134e7a0be2a75c3cd6ab0729da5b83b) )
ROM_REGION( 0x40000, "oki", 0 ) /* ADPCM data */
ROM_REGION( 0x40000, "oki", 0 ) // ADPCM data
ROM_LOAD( "136082-1007.2d", 0x00000, 0x20000, CRC(c96a0fc3) SHA1(6e7e242d0afa4714ca31d77ccbf8ee487bbdb1e4) )
ROM_LOAD( "136082-1008.1d", 0x20000, 0x20000, CRC(518218d9) SHA1(edf1b11579dcfa9a872fa4bd866dc2f95fac767d) )
@ -435,10 +609,10 @@ ROM_START( rampart2pa ) // original Atari PCB but with mostly hand-written label
ROM_LOAD16_BYTE( "3h.13n", 0xc0000, 0x20000, CRC(c23b1c98) SHA1(abd8e2738bb945476dc9f848290880d7ece92081) )
ROM_LOAD16_BYTE( "3l.13k", 0xc0001, 0x20000, CRC(0a12ca83) SHA1(2f44420b94b981af1d65cb775e4799bc43898041) )
ROM_REGION( 0x20000, "gfx1", ROMREGION_INVERT )
ROM_REGION( 0x20000, "gfx", ROMREGION_INVERT )
ROM_LOAD( "atr.2n", 0x000000, 0x20000, CRC(efa38bef) SHA1(d38448138134e7a0be2a75c3cd6ab0729da5b83b) )
ROM_REGION( 0x40000, "oki", 0 ) /* ADPCM data */
ROM_REGION( 0x40000, "oki", 0 ) // ADPCM data
ROM_LOAD( "arom0_2_player_136082-1007.2d", 0x00000, 0x20000, CRC(c96a0fc3) SHA1(6e7e242d0afa4714ca31d77ccbf8ee487bbdb1e4) )
ROM_LOAD( "arom1_2_player_136082-1006.1d", 0x20000, 0x20000, CRC(518218d9) SHA1(edf1b11579dcfa9a872fa4bd866dc2f95fac767d) )
@ -466,10 +640,10 @@ ROM_START( rampartj )
ROM_LOAD16_BYTE( "136082-1467.13n", 0xc0000, 0x20000, CRC(e0cfcda5) SHA1(0a1bf083e0589260caf6dfcb4e556b8f5e1ece25) )
ROM_LOAD16_BYTE( "136082-1466.13k", 0xc0001, 0x20000, CRC(a7a5a951) SHA1(a9a6adfa315c41cde4cca07d7e7d7f79ecba9f7a) )
ROM_REGION( 0x20000, "gfx1", ROMREGION_INVERT )
ROM_REGION( 0x20000, "gfx", ROMREGION_INVERT )
ROM_LOAD( "136082-2419.2m", 0x000000, 0x20000, CRC(456a8aae) SHA1(f35a3dc2069e20493661cf35fc0d4f4c4e11e420) )
ROM_REGION( 0x40000, "oki", 0 ) /* ADPCM data */
ROM_REGION( 0x40000, "oki", 0 ) // ADPCM data
ROM_LOAD( "136082-1007.2d", 0x00000, 0x20000, CRC(c96a0fc3) SHA1(6e7e242d0afa4714ca31d77ccbf8ee487bbdb1e4) )
ROM_LOAD( "136082-1008.1d", 0x20000, 0x20000, CRC(518218d9) SHA1(edf1b11579dcfa9a872fa4bd866dc2f95fac767d) )
@ -485,18 +659,7 @@ ROM_START( rampartj )
ROM_LOAD( "gal16v8-136082-1005.12c", 0x0a00, 0x0117, CRC(42c05114) SHA1(869a7f07da2d096b5a62f694db0dc1ca62d62242) )
ROM_END
/*************************************
*
* Driver initialization
*
*************************************/
void rampart_state::machine_start()
{
m_slapstic_bank->configure_entries(0, 4, memregion("maincpu")->base() + 0x40000, 0x2000);
}
} // anonymous namespace
/*************************************
@ -505,7 +668,7 @@ void rampart_state::machine_start()
*
*************************************/
GAME( 1990, rampart, 0, rampart, rampart, rampart_state, empty_init, ROT0, "Atari Games", "Rampart (Trackball)", MACHINE_SUPPORTS_SAVE )
GAME( 1990, rampart2p, rampart, rampart, ramprt2p, rampart_state, empty_init, ROT0, "Atari Games", "Rampart (Joystick, bigger ROMs)", MACHINE_SUPPORTS_SAVE )
GAME( 1990, rampart, 0, rampart, rampart, rampart_state, empty_init, ROT0, "Atari Games", "Rampart (Trackball)", MACHINE_SUPPORTS_SAVE )
GAME( 1990, rampart2p, rampart, rampart, ramprt2p, rampart_state, empty_init, ROT0, "Atari Games", "Rampart (Joystick, bigger ROMs)", MACHINE_SUPPORTS_SAVE )
GAME( 1990, rampart2pa, rampart, rampart, ramprt2p, rampart_state, empty_init, ROT0, "Atari Games", "Rampart (Joystick, smaller ROMs)", MACHINE_SUPPORTS_SAVE )
GAME( 1990, rampartj, rampart, rampart, rampartj, rampart_state, empty_init, ROT0, "Atari Games", "Rampart (Japan, Joystick)", MACHINE_SUPPORTS_SAVE )
GAME( 1990, rampartj, rampart, rampart, rampartj, rampart_state, empty_init, ROT0, "Atari Games", "Rampart (Japan, Joystick)", MACHINE_SUPPORTS_SAVE )

View File

@ -1,66 +0,0 @@
// license:BSD-3-Clause
// copyright-holders:Aaron Giles
/*************************************************************************
Atari Rampart hardware
*************************************************************************/
#ifndef MAME_ATARI_RAMPART_H
#define MAME_ATARI_RAMPART_H
#pragma once
#include "slapstic.h"
#include "machine/timer.h"
#include "sound/okim6295.h"
#include "sound/ymopl.h"
#include "atarimo.h"
#include "screen.h"
class rampart_state : public driver_device
{
public:
rampart_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_gfxdecode(*this, "gfxdecode"),
m_screen(*this, "screen"),
m_mob(*this, "mob"),
m_oki(*this, "oki"),
m_ym2413(*this, "ymsnd"),
m_bitmap(*this, "bitmap")
{ }
void init_rampart();
void rampart(machine_config &config);
protected:
virtual void machine_start() override;
virtual void video_start() override;
private:
TIMER_DEVICE_CALLBACK_MEMBER(scanline_interrupt);
void scanline_int_ack_w(u16 data);
void latch_w(offs_t offset, u16 data, u16 mem_mask = ~0);
u32 screen_update_rampart(screen_device &screen, bitmap_ind16 &bitmap, const rectangle &cliprect);
void rampart_bitmap_render(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<gfxdecode_device> m_gfxdecode;
required_device<screen_device> m_screen;
required_device<atari_motion_objects_device> m_mob;
required_device<okim6295_device> m_oki;
required_device<ym2413_device> m_ym2413;
required_shared_ptr<u16> m_bitmap;
static const atari_motion_objects_config s_mob_config;
};
#endif // MAME_ATARI_RAMPART_H

View File

@ -1,115 +0,0 @@
// license:BSD-3-Clause
// copyright-holders:Aaron Giles
/***************************************************************************
Atari Rampart hardware
****************************************************************************/
#include "emu.h"
#include "rampart.h"
/*************************************
*
* Video system start
*
*************************************/
const atari_motion_objects_config rampart_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 */
{{ 0x00ff,0,0,0 }}, /* mask for the link */
{{ 0,0x7fff,0,0 }}, /* mask for the code index */
{{ 0,0,0x000f,0 }}, /* mask for the color */
{{ 0,0,0xff80,0 }}, /* mask for the X position */
{{ 0,0,0,0xff80 }}, /* mask for the Y position */
{{ 0,0,0,0x0070 }}, /* mask for the width, in tiles*/
{{ 0,0,0,0x0007 }}, /* mask for the height, in tiles */
{{ 0,0x8000,0,0 }}, /* mask for the horizontal flip */
{{ 0 }}, /* mask for the vertical flip */
{{ 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 rampart_state::video_start()
{
/* set the intial scroll offset */
m_mob->set_xscroll(-12);
}
/*************************************
*
* Main refresh
*
*************************************/
uint32_t rampart_state::screen_update_rampart(screen_device &screen, bitmap_ind16 &bitmap, const rectangle &cliprect)
{
// start drawing
m_mob->draw_async(cliprect);
/* draw the playfield */
rampart_bitmap_render(bitmap, cliprect);
// 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)
{
/* the PCB supports more complex priorities, but the PAL is not stuffed, so we get the default */
pf[x] = mo[x];
}
}
return 0;
}
/*************************************
*
* Bitmap rendering
*
*************************************/
void rampart_state::rampart_bitmap_render(bitmap_ind16 &bitmap, const rectangle &cliprect)
{
/* update any dirty scanlines */
for (int y = cliprect.top(); y <= cliprect.bottom(); y++)
{
uint16_t const *const src = &m_bitmap[256 * y];
uint16_t *const dst = &bitmap.pix(y);
/* regenerate the line */
for (int x = cliprect.left() & ~1; x <= cliprect.right(); x += 2)
{
int const bits = src[(x - 8) / 2];
dst[x + 0] = bits >> 8;
dst[x + 1] = bits & 0xff;
}
}
}

View File

@ -1,5 +1,6 @@
// license:BSD-3-Clause
// copyright-holders:Aaron Giles
/***************************************************************************
Atari "Round" hardware
@ -87,16 +88,226 @@ ROM labels are in this format:
#include "emu.h"
#include "relief.h"
#include "atarimo.h"
#include "atarivad.h"
#include "cpu/m68000/m68000.h"
#include "machine/eeprompar.h"
#include "machine/watchdog.h"
#include "sound/okim6295.h"
#include "sound/ymopl.h"
#include "emupal.h"
#include "speaker.h"
#include "emupal.h"
#include "screen.h"
#include "speaker.h"
#include "tilemap.h"
namespace {
class relief_state : public driver_device
{
public:
relief_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_vad(*this, "vad"),
m_oki(*this, "oki"),
m_ym2413(*this, "ymsnd"),
m_okibank(*this, "okibank"),
m_260010(*this, "260010")
{ }
void relief(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<gfxdecode_device> m_gfxdecode;
required_device<screen_device> m_screen;
required_device<atari_vad_device> m_vad;
required_device<okim6295_device> m_oki;
required_device<ym2413_device> m_ym2413;
required_memory_bank m_okibank;
required_ioport m_260010;
uint8_t m_ym2413_volume = 0;
uint8_t m_overall_volume = 0;
uint8_t m_adpcm_bank = 0;
static const atari_motion_objects_config s_mob_config;
uint16_t special_port2_r();
void audio_control_w(offs_t offset, uint16_t data, uint16_t mem_mask = ~0);
void audio_volume_w(offs_t offset, uint16_t data, uint16_t mem_mask = ~0);
TILE_GET_INFO_MEMBER(get_playfield_tile_info);
TILE_GET_INFO_MEMBER(get_playfield2_tile_info);
uint32_t screen_update(screen_device &screen, bitmap_ind16 &bitmap, const rectangle &cliprect);
void main_map(address_map &map);
void oki_map(address_map &map);
};
// video
/*************************************
*
* Tilemap callbacks
*
*************************************/
TILE_GET_INFO_MEMBER(relief_state::get_playfield_tile_info)
{
uint16_t const data1 = m_vad->playfield().basemem_read(tile_index);
uint16_t const data2 = m_vad->playfield().extmem_read(tile_index) & 0xff;
int const code = data1 & 0x7fff;
int const color = 0x20 + (data2 & 0x0f);
tileinfo.set(0, code, color, (data1 >> 15) & 1);
}
TILE_GET_INFO_MEMBER(relief_state::get_playfield2_tile_info)
{
uint16_t const data1 = m_vad->playfield2().basemem_read(tile_index);
uint16_t const data2 = m_vad->playfield2().extmem_read(tile_index) >> 8;
int const code = data1 & 0x7fff;
int const color = data2 & 0x0f;
tileinfo.set(0, code, color, (data1 >> 15) & 1);
}
/*************************************
*
* Video system start
*
*************************************/
const atari_motion_objects_config relief_state::s_mob_config =
{
1, // 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
{{ 0x00ff,0,0,0 }}, // mask for the link
{{ 0,0x7fff,0,0 }}, // mask for the code index
{{ 0,0,0x000f,0 }}, // mask for the color
{{ 0,0,0xff80,0 }}, // mask for the X position
{{ 0,0,0,0xff80 }}, // mask for the Y position
{{ 0,0,0,0x0070 }}, // mask for the width, in tiles
{{ 0,0,0,0x0007 }}, // mask for the height, in tiles
{{ 0,0x8000,0,0 }}, // mask for the horizontal flip
{{ 0 }}, // mask for the vertical flip
{{ 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 relief_state::video_start()
{
// MOs are 5bpp but with a 4-bit color granularity
m_gfxdecode->gfx(1)->set_granularity(16);
}
/*************************************
*
* Main refresh
*
*************************************/
uint32_t relief_state::screen_update(screen_device &screen, bitmap_ind16 &bitmap, const rectangle &cliprect)
{
// start drawing
m_vad->mob().draw_async(cliprect);
// draw the playfield
bitmap_ind8 &priority_bitmap = screen.priority();
priority_bitmap.fill(0, cliprect);
m_vad->playfield().draw(screen, bitmap, cliprect, 0, 0);
m_vad->playfield2().draw(screen, bitmap, cliprect, 0, 1);
// draw and merge the MO
bitmap_ind16 &mobitmap = m_vad->mob().bitmap();
for (const sparse_dirty_rect *rect = m_vad->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);
uint8_t const *const pri = &priority_bitmap.pix(y);
for (int x = rect->left(); x <= rect->right(); x++)
if (mo[x] != 0xffff)
{
/* verified from the GALs on the real PCB; equations follow
*
* --- PF/M is 1 if playfield has priority, or 0 if MOs have priority
* PF/M = PFXS
*
* --- CS0 is set to 1 if the MO is transparent
* CS0=!MPX0*!MPX1*!MPX2*!MPX3
*
* --- CS1 is 1 to select playfield pixels or 0 to select MO pixels
* !CS1=MPX5*MPX6*MPX7*!CS0
* +!MPX4*MPX5*MPX6*MPX7
* +PFXS*!CS0
* +!MPX4*PFXS
*
* --- CRA10 is the 0x200 bit of the color RAM index; set for the top playfield only
* CRA10:=CS1*PFXS
*
* --- CRA9 is the 0x100 bit of the color RAM index; set for MOs only
* !CA9:=CS1
*
* --- CRA8-1 are the low 8 bits of the color RAM index; set as expected
*/
// compute the CS0 signal
int cs0 = 0;
cs0 = ((mo[x] & 0x0f) == 0);
// compute the CS1 signal
int cs1 = 1;
if ((!cs0 && (mo[x] & 0xe0) == 0xe0) ||
((mo[x] & 0xf0) == 0xe0) ||
(!pri[x] && !cs0) ||
(!pri[x] && !(mo[x] & 0x10)))
cs1 = 0;
// MO is displayed if cs1 == 0
if (!cs1)
pf[x] = mo[x];
}
}
return 0;
}
// machine
/*************************************
*
@ -104,6 +315,16 @@ ROM labels are in this format:
*
*************************************/
void relief_state::machine_start()
{
m_okibank->configure_entries(0, 8, memregion("oki")->base(), 0x20000);
m_okibank->set_entry(0);
save_item(NAME(m_ym2413_volume));
save_item(NAME(m_overall_volume));
save_item(NAME(m_adpcm_bank));
}
void relief_state::machine_reset()
{
m_adpcm_bank = 0;
@ -122,7 +343,7 @@ void relief_state::machine_reset()
uint16_t relief_state::special_port2_r()
{
int result = ioport("260010")->read();
int result = m_260010->read();
if (!(result & 0x0080) || m_screen->hblank()) result ^= 0x0001;
return result;
}
@ -144,7 +365,7 @@ void relief_state::audio_control_w(offs_t offset, uint16_t data, uint16_t mem_ma
m_adpcm_bank = ((data >> 6) & 3) | (m_adpcm_bank & 4);
}
if (ACCESSING_BITS_8_15)
m_adpcm_bank = (((data >> 8) & 1)<<2) | (m_adpcm_bank & 3);
m_adpcm_bank = (((data >> 8) & 1) << 2) | (m_adpcm_bank & 3);
m_okibank->set_entry(m_adpcm_bank);
}
@ -162,7 +383,7 @@ void relief_state::audio_volume_w(offs_t offset, uint16_t data, uint16_t mem_mas
void relief_state::oki_map(address_map &map)
{
map(0x00000, 0x1ffff).bankr("okibank");
map(0x00000, 0x1ffff).bankr(m_okibank);
map(0x20000, 0x3ffff).rom();
}
@ -210,7 +431,7 @@ void relief_state::main_map(address_map &map)
*************************************/
static INPUT_PORTS_START( relief )
PORT_START("260000") /* 260000 */
PORT_START("260000")
PORT_BIT( 0x0001, IP_ACTIVE_LOW, IPT_SERVICE ) PORT_NAME("Button D0") PORT_CODE(KEYCODE_Z)
PORT_BIT( 0x0002, IP_ACTIVE_LOW, IPT_SERVICE ) PORT_NAME("Button D1") PORT_CODE(KEYCODE_X)
PORT_BIT( 0x0004, IP_ACTIVE_LOW, IPT_SERVICE ) PORT_NAME("Button D2") PORT_CODE(KEYCODE_C)
@ -237,7 +458,7 @@ static INPUT_PORTS_START( relief )
PORT_BIT( 0x4000, IP_ACTIVE_LOW, IPT_JOYSTICK_DOWN ) PORT_PLAYER(1)
PORT_BIT( 0x8000, IP_ACTIVE_LOW, IPT_JOYSTICK_UP ) PORT_PLAYER(1)
PORT_START("260002") /* 260002 */
PORT_START("260002")
PORT_BIT( 0x0001, IP_ACTIVE_LOW, IPT_SERVICE ) PORT_NAME("White") PORT_CODE(KEYCODE_COMMA)
PORT_DIPNAME( 0x0002, 0x0002, DEF_STR( Unknown ) )
PORT_DIPSETTING( 0x0002, DEF_STR( Off ) )
@ -262,14 +483,14 @@ static INPUT_PORTS_START( relief )
PORT_BIT( 0x4000, IP_ACTIVE_LOW, IPT_JOYSTICK_DOWN ) PORT_PLAYER(2)
PORT_BIT( 0x8000, IP_ACTIVE_LOW, IPT_JOYSTICK_UP ) PORT_PLAYER(2)
PORT_START("260010") /* 260010 */
PORT_START("260010")
PORT_BIT( 0x001f, IP_ACTIVE_LOW, IPT_UNUSED )
PORT_BIT( 0x0020, IP_ACTIVE_LOW, IPT_UNUSED )
PORT_SERVICE( 0x0040, IP_ACTIVE_LOW )
PORT_BIT( 0x0080, IP_ACTIVE_LOW, IPT_CUSTOM ) PORT_VBLANK("screen")
PORT_BIT( 0xff00, IP_ACTIVE_LOW, IPT_UNUSED )
PORT_START("260012") /* 260012 */
PORT_START("260012")
PORT_BIT( 0x0001, IP_ACTIVE_LOW, IPT_COIN1 )
PORT_BIT( 0x0002, IP_ACTIVE_LOW, IPT_COIN2 )
PORT_BIT( 0x000c, IP_ACTIVE_LOW, IPT_UNUSED )
@ -310,8 +531,8 @@ static const gfx_layout molayout =
static GFXDECODE_START( gfx_relief )
GFXDECODE_ENTRY( "gfx1", 0, pflayout, 0, 64 ) /* alpha & playfield */
GFXDECODE_ENTRY( "gfx1", 1, molayout, 256, 16 ) /* sprites */
GFXDECODE_ENTRY( "gfx", 0, pflayout, 0, 64 ) // alpha & playfield
GFXDECODE_ENTRY( "gfx", 1, molayout, 256, 16 ) // sprites
GFXDECODE_END
@ -324,15 +545,15 @@ GFXDECODE_END
void relief_state::relief(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, &relief_state::main_map);
EEPROM_2816(config, "eeprom").lock_after_write(true);
WATCHDOG_TIMER(config, "watchdog");
/* video hardware */
// video hardware
GFXDECODE(config, m_gfxdecode, "palette", gfx_relief);
PALETTE(config, "palette").set_format(palette_device::IRGB_1555, 2048);
@ -344,20 +565,20 @@ void relief_state::relief(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 VAD chip to generate video signals */
/* note: these parameters are from published specs, not derived
the board uses a VAD 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(relief_state::screen_update_relief));
m_screen->set_screen_update(FUNC(relief_state::screen_update));
m_screen->set_palette("palette");
/* sound hardware */
// sound hardware
SPEAKER(config, "mono").front_center();
OKIM6295(config, m_oki, 14.318181_MHz_XTAL/4/3, okim6295_device::PIN7_LOW);
OKIM6295(config, m_oki, 14.318181_MHz_XTAL / 4 / 3, okim6295_device::PIN7_LOW);
m_oki->add_route(ALL_OUTPUTS, "mono", 0.50);
m_oki->set_addrmap(0, &relief_state::oki_map);
YM2413(config, m_ym2413, 14.318181_MHz_XTAL/4).add_route(ALL_OUTPUTS, "mono", 1.0);
YM2413(config, m_ym2413, 14.318181_MHz_XTAL / 4).add_route(ALL_OUTPUTS, "mono", 1.0);
}
@ -371,20 +592,20 @@ void relief_state::relief(machine_config &config)
// OS: 28 MAY 1992 14:00:14
// MAIN: 07 JUN 1992 20:12:30
ROM_START( relief )
ROM_REGION( 0x80000, "maincpu", 0 ) /* 8*64k for 68000 code */
ROM_REGION( 0x80000, "maincpu", 0 ) // 68000 code
ROM_LOAD16_BYTE( "136093-0011d_cs_acff.19e", 0x00000, 0x20000, CRC(cb3f73ad) SHA1(533a96095e678b4a414d6d9b861b1d4010ced30f) ) // checksum == ACFF
ROM_LOAD16_BYTE( "136093-0012d_cs_e5fe.19j", 0x00001, 0x20000, CRC(90655721) SHA1(f50a2f317215a864d09e33a4acd927b873350425) ) // checksum == E5FE
ROM_LOAD16_BYTE( "136093-0013_cs_cbbf.17e", 0x40000, 0x20000, CRC(1e1e82e5) SHA1(d33c84ae950db9775f9db9bf953aa63188d3f2f9) )
ROM_LOAD16_BYTE( "136093-0014_cs_3ebe.17j", 0x40001, 0x20000, CRC(19e5decd) SHA1(8d93d93f966df46d59cf9f4cdaa689e4dcd2689a) )
ROM_REGION( 0x280000, "gfx1", ROMREGION_INVERT )
ROM_REGION( 0x280000, "gfx", ROMREGION_INVERT )
ROM_LOAD( "136093-0025a.14s", 0x000000, 0x80000, CRC(1b9e5ef2) SHA1(d7d14e75ca2d56c5c67154506096570c9ccbcf8e) )
ROM_LOAD( "136093-0026a.8d", 0x080000, 0x80000, CRC(09b25d93) SHA1(94d424b21410182b5121201066f4acfa415f4b6b) )
ROM_LOAD( "136093-0027a.18s", 0x100000, 0x80000, CRC(5bc1c37b) SHA1(89f1bca55dd431ca3171b89347209decf0b25e12) )
ROM_LOAD( "136093-0028a.10d", 0x180000, 0x80000, CRC(55fb9111) SHA1(a95508f0831842fa79ca2fc168cfadc8c6d3fbd4) )
ROM_LOAD16_BYTE( "136093-0029a.4d", 0x200001, 0x40000, CRC(e4593ff4) SHA1(7360ec7a65aabc90aa787dc30f39992e342495dd) )
ROM_REGION( 0x100000, "oki", 0 ) /* 2MB for ADPCM data */
ROM_REGION( 0x100000, "oki", 0 ) // ADPCM data
ROM_LOAD( "136093-0030a.9b", 0x000000, 0x80000, CRC(f4c567f5) SHA1(7e8c1d54d918b0b41625eacbaf6dcb5bd99d1949) )
ROM_LOAD( "136093-0031a.10b", 0x080000, 0x80000, CRC(ba908d73) SHA1(a83afd86f4c39394cf624b728a87b8d8b6de1944) )
@ -406,20 +627,20 @@ ROM_END
// OS: 08 APR 1992 09:09:02
// MAIN: 26 APR 1992 21:18:13
ROM_START( relief2 )
ROM_REGION( 0x80000, "maincpu", 0 ) /* 8*64k for 68000 code */
ROM_REGION( 0x80000, "maincpu", 0 ) // 68000 code
ROM_LOAD16_BYTE( "136093-0011c_cs_baff.19e", 0x00000, 0x20000, CRC(41373e02) SHA1(1982be3d2b959f3504cd7e4afacd96bbebc27b8e) ) // checksum == BAFF
ROM_LOAD16_BYTE( "136093-0012c_cs_8afe.19j", 0x00001, 0x20000, CRC(8187b026) SHA1(1408b5482194161c1fbb30911bb5b64a14b8ffb0) ) // checksum == 8AFE
ROM_LOAD16_BYTE( "136093-0013_cs_cbbf.17e", 0x40000, 0x20000, CRC(1e1e82e5) SHA1(d33c84ae950db9775f9db9bf953aa63188d3f2f9) )
ROM_LOAD16_BYTE( "136093-0014_cs_3ebe.17j", 0x40001, 0x20000, CRC(19e5decd) SHA1(8d93d93f966df46d59cf9f4cdaa689e4dcd2689a) )
ROM_REGION( 0x280000, "gfx1", ROMREGION_INVERT )
ROM_REGION( 0x280000, "gfx", ROMREGION_INVERT )
ROM_LOAD( "136093-0025a.14s", 0x000000, 0x80000, CRC(1b9e5ef2) SHA1(d7d14e75ca2d56c5c67154506096570c9ccbcf8e) )
ROM_LOAD( "136093-0026a.8d", 0x080000, 0x80000, CRC(09b25d93) SHA1(94d424b21410182b5121201066f4acfa415f4b6b) )
ROM_LOAD( "136093-0027a.18s", 0x100000, 0x80000, CRC(5bc1c37b) SHA1(89f1bca55dd431ca3171b89347209decf0b25e12) )
ROM_LOAD( "136093-0028a.10d", 0x180000, 0x80000, CRC(55fb9111) SHA1(a95508f0831842fa79ca2fc168cfadc8c6d3fbd4) )
ROM_LOAD16_BYTE( "136093-0029.4d", 0x200001, 0x40000, CRC(e4593ff4) SHA1(7360ec7a65aabc90aa787dc30f39992e342495dd) )
ROM_REGION( 0x100000, "oki", 0 ) /* 2MB for ADPCM data */
ROM_REGION( 0x100000, "oki", 0 ) // ADPCM data
ROM_LOAD( "136093-0030a.9b", 0x000000, 0x80000, CRC(f4c567f5) SHA1(7e8c1d54d918b0b41625eacbaf6dcb5bd99d1949) )
ROM_LOAD( "136093-0031a.10b", 0x080000, 0x80000, CRC(ba908d73) SHA1(a83afd86f4c39394cf624b728a87b8d8b6de1944) )
@ -440,20 +661,20 @@ ROM_END
// OS: 08 APR 1992 09:09:02
// MAIN: 10 APR 1992 09:50:05
ROM_START( relief3 )
ROM_REGION( 0x80000, "maincpu", 0 ) /* 8*64k for 68000 code */
ROM_REGION( 0x80000, "maincpu", 0 ) // 68000 code
ROM_LOAD16_BYTE( "136093-0011b_cs_23ff.19e", 0x00000, 0x20000, CRC(794cea33) SHA1(6e9830ce04a505746dea5aafaf37c629c28b061d) ) // checksum == 23FF
ROM_LOAD16_BYTE( "136093-0012b_cs_3cfe.19j", 0x00001, 0x20000, CRC(577495f8) SHA1(f45b0928b13db7f49b7688620008fc03fca08cde) ) // checksum == 3CFE
ROM_LOAD16_BYTE( "136093-0013_cs_cbbf.17e", 0x40000, 0x20000, CRC(1e1e82e5) SHA1(d33c84ae950db9775f9db9bf953aa63188d3f2f9) )
ROM_LOAD16_BYTE( "136093-0014_cs_3ebe.17j", 0x40001, 0x20000, CRC(19e5decd) SHA1(8d93d93f966df46d59cf9f4cdaa689e4dcd2689a) )
ROM_REGION( 0x280000, "gfx1", ROMREGION_INVERT )
ROM_REGION( 0x280000, "gfx", ROMREGION_INVERT )
ROM_LOAD( "136093-0025a.14s", 0x000000, 0x80000, CRC(1b9e5ef2) SHA1(d7d14e75ca2d56c5c67154506096570c9ccbcf8e) )
ROM_LOAD( "136093-0026a.8d", 0x080000, 0x80000, CRC(09b25d93) SHA1(94d424b21410182b5121201066f4acfa415f4b6b) )
ROM_LOAD( "136093-0027a.18s", 0x100000, 0x80000, CRC(5bc1c37b) SHA1(89f1bca55dd431ca3171b89347209decf0b25e12) )
ROM_LOAD( "136093-0028a.10d", 0x180000, 0x80000, CRC(55fb9111) SHA1(a95508f0831842fa79ca2fc168cfadc8c6d3fbd4) )
ROM_LOAD16_BYTE( "136093-0029.4d", 0x200001, 0x40000, CRC(e4593ff4) SHA1(7360ec7a65aabc90aa787dc30f39992e342495dd) )
ROM_REGION( 0x100000, "oki", 0 ) /* 2MB for ADPCM data */
ROM_REGION( 0x100000, "oki", 0 ) // ADPCM data
ROM_LOAD( "136093-0030a.9b", 0x000000, 0x80000, CRC(f4c567f5) SHA1(7e8c1d54d918b0b41625eacbaf6dcb5bd99d1949) )
ROM_LOAD( "136093-0031a.10b", 0x080000, 0x80000, CRC(ba908d73) SHA1(a83afd86f4c39394cf624b728a87b8d8b6de1944) )
@ -471,21 +692,7 @@ ROM_START( relief3 )
ROM_LOAD( "gal16v8a-136093-0010.15a", 0x0e00, 0x0117, CRC(5f49c736) SHA1(91ff18e4780ee6c904735fc0f0e73ffb5a80b49a) )
ROM_END
/*************************************
*
* Driver initialization
*
*************************************/
void relief_state::init_relief()
{
m_okibank->configure_entries(0, 8, memregion("oki")->base(), 0x20000);
m_okibank->set_entry(0);
}
} // anonymous namespace
/*************************************
@ -494,6 +701,6 @@ void relief_state::init_relief()
*
*************************************/
GAME( 1992, relief, 0, relief, relief, relief_state, init_relief, ROT0, "Atari Games", "Relief Pitcher (Rev D, 07 Jun 1992 / 28 May 1992)", 0 )
GAME( 1992, relief2, relief, relief, relief, relief_state, init_relief, ROT0, "Atari Games", "Relief Pitcher (Rev C, 26 Apr 1992 / 08 Apr 1992)", 0 )
GAME( 1992, relief3, relief, relief, relief, relief_state, init_relief, ROT0, "Atari Games", "Relief Pitcher (Rev B, 10 Apr 1992 / 08 Apr 1992)", 0 )
GAME( 1992, relief, 0, relief, relief, relief_state, empty_init, ROT0, "Atari Games", "Relief Pitcher (Rev D, 07 Jun 1992 / 28 May 1992)", MACHINE_SUPPORTS_SAVE )
GAME( 1992, relief2, relief, relief, relief, relief_state, empty_init, ROT0, "Atari Games", "Relief Pitcher (Rev C, 26 Apr 1992 / 08 Apr 1992)", MACHINE_SUPPORTS_SAVE )
GAME( 1992, relief3, relief, relief, relief, relief_state, empty_init, ROT0, "Atari Games", "Relief Pitcher (Rev B, 10 Apr 1992 / 08 Apr 1992)", MACHINE_SUPPORTS_SAVE )

View File

@ -1,66 +0,0 @@
// license:BSD-3-Clause
// copyright-holders:Aaron Giles
/*************************************************************************
Atari "Round" hardware
*************************************************************************/
#ifndef MAME_ATARI_RELIEF_H
#define MAME_ATARI_RELIEF_H
#pragma once
#include "sound/okim6295.h"
#include "sound/ymopl.h"
#include "atarimo.h"
#include "atarivad.h"
#include "screen.h"
#include "tilemap.h"
class relief_state : public driver_device
{
public:
relief_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_vad(*this, "vad"),
m_oki(*this, "oki"),
m_ym2413(*this, "ymsnd"),
m_okibank(*this, "okibank")
{ }
void relief(machine_config &config);
void init_relief();
private:
virtual void machine_reset() override;
virtual void video_start() override;
uint16_t special_port2_r();
void audio_control_w(offs_t offset, uint16_t data, uint16_t mem_mask = ~0);
void audio_volume_w(offs_t offset, uint16_t data, uint16_t mem_mask = ~0);
TILE_GET_INFO_MEMBER(get_playfield_tile_info);
TILE_GET_INFO_MEMBER(get_playfield2_tile_info);
uint32_t screen_update_relief(screen_device &screen, bitmap_ind16 &bitmap, const rectangle &cliprect);
void main_map(address_map &map);
void oki_map(address_map &map);
required_device<cpu_device> m_maincpu;
required_device<gfxdecode_device> m_gfxdecode;
required_device<screen_device> m_screen;
required_device<atari_vad_device> m_vad;
required_device<okim6295_device> m_oki;
required_device<ym2413_device> m_ym2413;
required_memory_bank m_okibank;
uint8_t m_ym2413_volume = 0;
uint8_t m_overall_volume = 0;
uint8_t m_adpcm_bank = 0;
static const atari_motion_objects_config s_mob_config;
};
#endif // MAME_ATARI_RELIEF_H

View File

@ -1,158 +0,0 @@
// license:BSD-3-Clause
// copyright-holders:Aaron Giles
/***************************************************************************
Atari "Round" hardware
****************************************************************************/
#include "emu.h"
#include "relief.h"
/*************************************
*
* Tilemap callbacks
*
*************************************/
TILE_GET_INFO_MEMBER(relief_state::get_playfield_tile_info)
{
uint16_t data1 = m_vad->playfield().basemem_read(tile_index);
uint16_t data2 = m_vad->playfield().extmem_read(tile_index) & 0xff;
int code = data1 & 0x7fff;
int color = 0x20 + (data2 & 0x0f);
tileinfo.set(0, code, color, (data1 >> 15) & 1);
}
TILE_GET_INFO_MEMBER(relief_state::get_playfield2_tile_info)
{
uint16_t data1 = m_vad->playfield2().basemem_read(tile_index);
uint16_t data2 = m_vad->playfield2().extmem_read(tile_index) >> 8;
int code = data1 & 0x7fff;
int color = data2 & 0x0f;
tileinfo.set(0, code, color, (data1 >> 15) & 1);
}
/*************************************
*
* Video system start
*
*************************************/
const atari_motion_objects_config relief_state::s_mob_config =
{
1, /* 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 */
{{ 0x00ff,0,0,0 }}, /* mask for the link */
{{ 0,0x7fff,0,0 }}, /* mask for the code index */
{{ 0,0,0x000f,0 }}, /* mask for the color */
{{ 0,0,0xff80,0 }}, /* mask for the X position */
{{ 0,0,0,0xff80 }}, /* mask for the Y position */
{{ 0,0,0,0x0070 }}, /* mask for the width, in tiles*/
{{ 0,0,0,0x0007 }}, /* mask for the height, in tiles */
{{ 0,0x8000,0,0 }}, /* mask for the horizontal flip */
{{ 0 }}, /* mask for the vertical flip */
{{ 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 relief_state::video_start()
{
/* MOs are 5bpp but with a 4-bit color granularity */
m_gfxdecode->gfx(1)->set_granularity(16);
}
/*************************************
*
* Main refresh
*
*************************************/
uint32_t relief_state::screen_update_relief(screen_device &screen, bitmap_ind16 &bitmap, const rectangle &cliprect)
{
// start drawing
m_vad->mob().draw_async(cliprect);
/* draw the playfield */
bitmap_ind8 &priority_bitmap = screen.priority();
priority_bitmap.fill(0, cliprect);
m_vad->playfield().draw(screen, bitmap, cliprect, 0, 0);
m_vad->playfield2().draw(screen, bitmap, cliprect, 0, 1);
// draw and merge the MO
bitmap_ind16 &mobitmap = m_vad->mob().bitmap();
for (const sparse_dirty_rect *rect = m_vad->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);
uint8_t const *const pri = &priority_bitmap.pix(y);
for (int x = rect->left(); x <= rect->right(); x++)
if (mo[x] != 0xffff)
{
/* verified from the GALs on the real PCB; equations follow
*
* --- PF/M is 1 if playfield has priority, or 0 if MOs have priority
* PF/M = PFXS
*
* --- CS0 is set to 1 if the MO is transparent
* CS0=!MPX0*!MPX1*!MPX2*!MPX3
*
* --- CS1 is 1 to select playfield pixels or 0 to select MO pixels
* !CS1=MPX5*MPX6*MPX7*!CS0
* +!MPX4*MPX5*MPX6*MPX7
* +PFXS*!CS0
* +!MPX4*PFXS
*
* --- CRA10 is the 0x200 bit of the color RAM index; set for the top playfield only
* CRA10:=CS1*PFXS
*
* --- CRA9 is the 0x100 bit of the color RAM index; set for MOs only
* !CA9:=CS1
*
* --- CRA8-1 are the low 8 bits of the color RAM index; set as expected
*/
/* compute the CS0 signal */
int cs0 = 0;
cs0 = ((mo[x] & 0x0f) == 0);
/* compute the CS1 signal */
int cs1 = 1;
if ((!cs0 && (mo[x] & 0xe0) == 0xe0) ||
((mo[x] & 0xf0) == 0xe0) ||
(!pri[x] && !cs0) ||
(!pri[x] && !(mo[x] & 0x10)))
cs1 = 0;
/* MO is displayed if cs1 == 0 */
if (!cs1)
pf[x] = mo[x];
}
}
return 0;
}

View File

@ -1,5 +1,6 @@
// license:BSD-3-Clause
// copyright-holders:Aaron Giles
/***************************************************************************
Atari Shuuz hardware
@ -20,15 +21,184 @@
#include "emu.h"
#include "shuuz.h"
#include "atarimo.h"
#include "atarivad.h"
#include "cpu/m68000/m68000.h"
#include "machine/eeprompar.h"
#include "machine/watchdog.h"
#include "sound/okim6295.h"
#include "emupal.h"
#include "speaker.h"
#include "emupal.h"
#include "screen.h"
#include "speaker.h"
#include "tilemap.h"
namespace {
class shuuz_state : public driver_device
{
public:
shuuz_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_vad(*this, "vad")
, m_system(*this, "SYSTEM")
, m_track(*this, "TRACK%c", 'X')
{ }
void shuuz(machine_config &config);
protected:
virtual void machine_start() override;
private:
required_device<cpu_device> m_maincpu;
required_device<gfxdecode_device> m_gfxdecode;
required_device<screen_device> m_screen;
required_device<atari_vad_device> m_vad;
required_ioport m_system;
required_ioport_array<2> m_track;
int16_t m_cur[2]{};
static const atari_motion_objects_config s_mob_config;
void latch_w(uint16_t data);
uint16_t leta_r(offs_t offset);
uint16_t special_port0_r();
int get_hblank() const { return (m_screen->hpos() > (m_screen->width() * 9 / 10)); }
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);
};
// video
/*************************************
*
* Tilemap callbacks
*
*************************************/
TILE_GET_INFO_MEMBER(shuuz_state::get_playfield_tile_info)
{
uint16_t const data1 = m_vad->playfield().basemem_read(tile_index);
uint16_t const data2 = m_vad->playfield().extmem_read(tile_index) >> 8;
int const code = data1 & 0x3fff;
int const color = data2 & 0x0f;
tileinfo.set(0, code, color, (data1 >> 15) & 1);
}
/*************************************
*
* Video system start
*
*************************************/
const atari_motion_objects_config shuuz_state::s_mob_config =
{
1, // 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)
0x000, // base palette entry
0x100, // maximum number of colors
0, // transparent pen index
{{ 0x00ff,0,0,0 }}, // mask for the link
{{ 0,0x7fff,0,0 }}, // mask for the code index
{{ 0,0,0x000f,0 }}, // mask for the color
{{ 0,0,0xff80,0 }}, // mask for the X position
{{ 0,0,0,0xff80 }}, // mask for the Y position
{{ 0,0,0,0x0070 }}, // mask for the width, in tiles
{{ 0,0,0,0x0007 }}, // mask for the height, in tiles
{{ 0,0x8000,0,0 }}, // mask for the horizontal flip
{{ 0 }}, // mask for the vertical flip
{{ 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 shuuz_state::screen_update(screen_device &screen, bitmap_ind16 &bitmap, const rectangle &cliprect)
{
// start drawing
m_vad->mob().draw_async(cliprect);
// draw the playfield
m_vad->playfield().draw(screen, bitmap, cliprect, 0, 0);
// draw and merge the MO
bitmap_ind16 &mobitmap = m_vad->mob().bitmap();
for (const sparse_dirty_rect *rect = m_vad->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 from the GALs on the real PCB; equations follow
*
* --- O13 is 1 if (PFS7-4 == 0xf)
* O13=PFS6*PFS7*(PFS5&PFS4)
*
* --- PF/M is 1 if MOs have priority, or 0 if playfield has priority
* MO/PF=!PFS7*!(LBD7&LBD6)*!M1*!O13
* +!PFS7*!(LBD7&LBD6)*!M2*!O13
* +!PFS7*!(LBD7&LBD6)*!M3*!O13
* +PFS7*(LBD7&LBD6)*!M1*!O13
* +PFS7*(LBD7&LBD6)*!M2*!O13
* +PFS7*(LBD7&LBD6)*!M3*!O13
*
*/
int const o13 = ((pf[x] & 0xf0) == 0xf0);
// compute the MO/PF signal
int mopf = 0;
if ((!(pf[x] & 0x80) && ((mo[x] & 0xc0) != 0xc0) && ((mo[x] & 0x0e) != 0x00) && !o13) ||
((pf[x] & 0x80) && ((mo[x] & 0xc0) == 0xc0) && ((mo[x] & 0x0e) != 0x00) && !o13))
mopf = 1;
// if MO/PF is 1, we draw the MO
if (mopf)
pf[x] = mo[x];
}
}
return 0;
}
// machine
void shuuz_state::machine_start()
{
@ -41,7 +211,7 @@ void shuuz_state::machine_start()
*
*************************************/
void shuuz_state::latch_w(uint16_t data)
void shuuz_state::latch_w(uint16_t data) // TODO
{
}
@ -55,20 +225,19 @@ void shuuz_state::latch_w(uint16_t data)
uint16_t shuuz_state::leta_r(offs_t offset)
{
/* trackball -- rotated 45 degrees? */
int which = offset & 1;
// trackball -- rotated 45 degrees?
int const which = offset & 1;
/* when reading the even ports, do a real analog port update */
// when reading the even ports, do a real analog port update
if (which == 0)
{
int dx = (int8_t)ioport("TRACKX")->read();
int dy = (int8_t)ioport("TRACKY")->read();
int const dx = (int8_t)m_track[0]->read();
int const dy = (int8_t)m_track[0]->read();
m_cur[0] = dx + dy;
m_cur[1] = dx - dy;
}
/* clip the result to -0x3f to +0x3f to remove directional ambiguities */
return m_cur[which];
}
@ -82,9 +251,9 @@ uint16_t shuuz_state::leta_r(offs_t offset)
uint16_t shuuz_state::special_port0_r()
{
int result = ioport("SYSTEM")->read();
int result = m_system->read();
if ((result & 0x0800) && get_hblank(*m_screen))
if ((result & 0x0800) && get_hblank())
result &= ~0x0800;
return result;
@ -208,8 +377,8 @@ static const gfx_layout pfmolayout =
static GFXDECODE_START( gfx_shuuz )
GFXDECODE_ENTRY( "gfx1", 0, pfmolayout, 256, 16 ) /* sprites & playfield */
GFXDECODE_ENTRY( "gfx2", 0, pfmolayout, 0, 16 ) /* sprites & playfield */
GFXDECODE_ENTRY( "gfx1", 0, pfmolayout, 256, 16 ) // sprites & playfield
GFXDECODE_ENTRY( "gfx2", 0, pfmolayout, 0, 16 ) // sprites & playfield
GFXDECODE_END
@ -222,15 +391,15 @@ GFXDECODE_END
void shuuz_state::shuuz(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, &shuuz_state::main_map);
EEPROM_2816(config, "eeprom").lock_after_write(true);
WATCHDOG_TIMER(config, "watchdog");
/* video hardware */
// video hardware
GFXDECODE(config, m_gfxdecode, "palette", gfx_shuuz);
PALETTE(config, "palette").set_format(palette_device::IRGB_1555, 1024);
@ -241,16 +410,16 @@ void shuuz_state::shuuz(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 VAD chip to generate video signals */
m_screen->set_raw(14.318181_MHz_XTAL/2, 456, 0, 336, 262, 0, 240);
/* note: these parameters are from published specs, not derived
the board uses a VAD 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(shuuz_state::screen_update));
m_screen->set_palette("palette");
/* sound hardware */
// sound hardware
SPEAKER(config, "mono").front_center();
OKIM6295(config, "oki", 14.318181_MHz_XTAL/16, okim6295_device::PIN7_HIGH).add_route(ALL_OUTPUTS, "mono", 1.0);
OKIM6295(config, "oki", 14.318181_MHz_XTAL / 16, okim6295_device::PIN7_HIGH).add_route(ALL_OUTPUTS, "mono", 1.0);
}
@ -262,7 +431,7 @@ void shuuz_state::shuuz(machine_config &config)
*************************************/
ROM_START( shuuz )
ROM_REGION( 0x40000, "maincpu", 0 ) /* 4*64k for 68000 code */
ROM_REGION( 0x40000, "maincpu", 0 ) // 68000 code
ROM_LOAD16_BYTE( "136083-4010.23p", 0x00000, 0x20000, CRC(1c2459f8) SHA1(4b8daf196e3ba17cf958a3c1af4e4dacfb79b9e7) )
ROM_LOAD16_BYTE( "136083-4011.13p", 0x00001, 0x20000, CRC(6db53a85) SHA1(7f9b3ea78fa65221931bfdab1aa5f1913ffed753) )
@ -282,21 +451,21 @@ ROM_START( shuuz )
ROM_LOAD( "136083-1025.87m", 0x0c0000, 0x20000, CRC(f7b20a64) SHA1(667c539fa809d3ae4a1c127e2044dd3a4e533266) )
ROM_LOAD( "136083-1027.65m", 0x0e0000, 0x20000, CRC(55d54952) SHA1(73e1a388ea48bab567bde8958ee228432ebfbf67) )
ROM_REGION( 0x40000, "oki", 0 ) /* ADPCM data */
ROM_REGION( 0x40000, "oki", 0 ) // ADPCM data
ROM_LOAD( "136083-1040.75b", 0x00000, 0x20000, CRC(0896702b) SHA1(d826bb4812d393889584c7c656c317fd5745a05f) )
ROM_LOAD( "136083-1041.65b", 0x20000, 0x20000, CRC(b3b07ce9) SHA1(f1128a143b72867c16b9803b0beb0188420cbfb5) )
ROM_REGION( 0x0005, "pals", 0 )
ROM_LOAD( "136083-1050.55c", 0x0000, 0x0001, NO_DUMP ) /* GAL16V8A-25LP */
ROM_LOAD( "136083-1051.45e", 0x0000, 0x0001, NO_DUMP ) /* GAL16V8A-25LP */
ROM_LOAD( "136083-1052.32l", 0x0000, 0x0001, NO_DUMP ) /* GAL16V8A-25LP */
ROM_LOAD( "136083-1053.85n", 0x0000, 0x0001, NO_DUMP ) /* GAL16V8A-25LP */
ROM_LOAD( "136083-1054.97n", 0x0000, 0x0001, NO_DUMP ) /* GAL16V8A-25LP */
ROM_LOAD( "136083-1050.55c", 0x0000, 0x0001, NO_DUMP ) // GAL16V8A-25LP
ROM_LOAD( "136083-1051.45e", 0x0000, 0x0001, NO_DUMP ) // GAL16V8A-25LP
ROM_LOAD( "136083-1052.32l", 0x0000, 0x0001, NO_DUMP ) // GAL16V8A-25LP
ROM_LOAD( "136083-1053.85n", 0x0000, 0x0001, NO_DUMP ) // GAL16V8A-25LP
ROM_LOAD( "136083-1054.97n", 0x0000, 0x0001, NO_DUMP ) // GAL16V8A-25LP
ROM_END
ROM_START( shuuz2 )
ROM_REGION( 0x40000, "maincpu", 0 ) /* 4*64k for 68000 code */
ROM_REGION( 0x40000, "maincpu", 0 ) // 68000 code
ROM_LOAD16_BYTE( "136083-23p.rom", 0x00000, 0x20000, CRC(98aec4e7) SHA1(8cbe6e7835ecf0ef74a2de723ef970a63d3bddd1) )
ROM_LOAD16_BYTE( "136083-13p.rom", 0x00001, 0x20000, CRC(dd9d5d5c) SHA1(0bde6be55532c232b1d27824c2ce61f33501cbb0) )
@ -316,18 +485,19 @@ ROM_START( shuuz2 )
ROM_LOAD( "136083-1025.87m", 0x0c0000, 0x20000, CRC(f7b20a64) SHA1(667c539fa809d3ae4a1c127e2044dd3a4e533266) )
ROM_LOAD( "136083-1027.65m", 0x0e0000, 0x20000, CRC(55d54952) SHA1(73e1a388ea48bab567bde8958ee228432ebfbf67) )
ROM_REGION( 0x40000, "oki", 0 ) /* ADPCM data */
ROM_REGION( 0x40000, "oki", 0 ) // ADPCM data
ROM_LOAD( "136083-1040.75b", 0x00000, 0x20000, CRC(0896702b) SHA1(d826bb4812d393889584c7c656c317fd5745a05f) )
ROM_LOAD( "136083-1041.65b", 0x20000, 0x20000, CRC(b3b07ce9) SHA1(f1128a143b72867c16b9803b0beb0188420cbfb5) )
ROM_REGION( 0x0005, "pals", 0 )
ROM_LOAD( "136083-1050.55c", 0x0000, 0x0001, NO_DUMP ) /* GAL16V8A-25LP */
ROM_LOAD( "136083-1051.45e", 0x0000, 0x0001, NO_DUMP ) /* GAL16V8A-25LP */
ROM_LOAD( "136083-1052.32l", 0x0000, 0x0001, NO_DUMP ) /* GAL16V8A-25LP */
ROM_LOAD( "136083-1053.85n", 0x0000, 0x0001, NO_DUMP ) /* GAL16V8A-25LP */
ROM_LOAD( "136083-1054.97n", 0x0000, 0x0001, NO_DUMP ) /* GAL16V8A-25LP */
ROM_LOAD( "136083-1050.55c", 0x0000, 0x0001, NO_DUMP ) // GAL16V8A-25LP
ROM_LOAD( "136083-1051.45e", 0x0000, 0x0001, NO_DUMP ) // GAL16V8A-25LP
ROM_LOAD( "136083-1052.32l", 0x0000, 0x0001, NO_DUMP ) // GAL16V8A-25LP
ROM_LOAD( "136083-1053.85n", 0x0000, 0x0001, NO_DUMP ) // GAL16V8A-25LP
ROM_LOAD( "136083-1054.97n", 0x0000, 0x0001, NO_DUMP ) // GAL16V8A-25LP
ROM_END
} // anonymous namespace
/*************************************

View File

@ -1,56 +0,0 @@
// license:BSD-3-Clause
// copyright-holders:Aaron Giles
/*************************************************************************
Atari Shuuz hardware
*************************************************************************/
#ifndef MAME_ATARI_SHUUZ_H
#define MAME_ATARI_SHUUZ_H
#pragma once
#include "atarimo.h"
#include "atarivad.h"
#include "screen.h"
#include "tilemap.h"
class shuuz_state : public driver_device
{
public:
shuuz_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_vad(*this, "vad")
{ }
void shuuz(machine_config &config);
private:
void latch_w(uint16_t data);
uint16_t leta_r(offs_t offset);
uint16_t special_port0_r();
virtual void machine_start() override;
int get_hblank(screen_device &screen) const { return (screen.hpos() > (screen.width() * 9 / 10)); }
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);
required_device<cpu_device> m_maincpu;
required_device<gfxdecode_device> m_gfxdecode;
required_device<screen_device> m_screen;
required_device<atari_vad_device> m_vad;
int m_cur[2]{};
static const atari_motion_objects_config s_mob_config;
};
#endif // MAME_ATARI_SHUUZ_H

View File

@ -1,124 +0,0 @@
// license:BSD-3-Clause
// copyright-holders:Aaron Giles
/***************************************************************************
Atari Shuuz hardware
****************************************************************************/
#include "emu.h"
#include "shuuz.h"
/*************************************
*
* Tilemap callbacks
*
*************************************/
TILE_GET_INFO_MEMBER(shuuz_state::get_playfield_tile_info)
{
uint16_t data1 = m_vad->playfield().basemem_read(tile_index);
uint16_t data2 = m_vad->playfield().extmem_read(tile_index) >> 8;
int code = data1 & 0x3fff;
int color = data2 & 0x0f;
tileinfo.set(0, code, color, (data1 >> 15) & 1);
}
/*************************************
*
* Video system start
*
*************************************/
const atari_motion_objects_config shuuz_state::s_mob_config =
{
1, /* 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) */
0x000, /* base palette entry */
0x100, /* maximum number of colors */
0, /* transparent pen index */
{{ 0x00ff,0,0,0 }}, /* mask for the link */
{{ 0,0x7fff,0,0 }}, /* mask for the code index */
{{ 0,0,0x000f,0 }}, /* mask for the color */
{{ 0,0,0xff80,0 }}, /* mask for the X position */
{{ 0,0,0,0xff80 }}, /* mask for the Y position */
{{ 0,0,0,0x0070 }}, /* mask for the width, in tiles*/
{{ 0,0,0,0x0007 }}, /* mask for the height, in tiles */
{{ 0,0x8000,0,0 }}, /* mask for the horizontal flip */
{{ 0 }}, /* mask for the vertical flip */
{{ 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 shuuz_state::screen_update(screen_device &screen, bitmap_ind16 &bitmap, const rectangle &cliprect)
{
// start drawing
m_vad->mob().draw_async(cliprect);
/* draw the playfield */
m_vad->playfield().draw(screen, bitmap, cliprect, 0, 0);
// draw and merge the MO
bitmap_ind16 &mobitmap = m_vad->mob().bitmap();
for (const sparse_dirty_rect *rect = m_vad->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 from the GALs on the real PCB; equations follow
*
* --- O13 is 1 if (PFS7-4 == 0xf)
* O13=PFS6*PFS7*(PFS5&PFS4)
*
* --- PF/M is 1 if MOs have priority, or 0 if playfield has priority
* MO/PF=!PFS7*!(LBD7&LBD6)*!M1*!O13
* +!PFS7*!(LBD7&LBD6)*!M2*!O13
* +!PFS7*!(LBD7&LBD6)*!M3*!O13
* +PFS7*(LBD7&LBD6)*!M1*!O13
* +PFS7*(LBD7&LBD6)*!M2*!O13
* +PFS7*(LBD7&LBD6)*!M3*!O13
*
*/
int const o13 = ((pf[x] & 0xf0) == 0xf0);
/* compute the MO/PF signal */
int mopf = 0;
if ((!(pf[x] & 0x80) && ((mo[x] & 0xc0) != 0xc0) && ((mo[x] & 0x0e) != 0x00) && !o13) ||
((pf[x] & 0x80) && ((mo[x] & 0xc0) == 0xc0) && ((mo[x] & 0x0e) != 0x00) && !o13))
mopf = 1;
/* if MO/PF is 1, we draw the MO */
if (mopf)
pf[x] = mo[x];
}
}
return 0;
}

File diff suppressed because it is too large Load Diff

View File

@ -1,74 +0,0 @@
// license:BSD-3-Clause
// copyright-holders:Aaron Giles
/*************************************************************************
Atari Skull & Crossbones hardware
*************************************************************************/
#ifndef MAME_ATARI_SKULLXBO_H
#define MAME_ATARI_SKULLXBO_H
#pragma once
#include "atarigen.h"
#include "machine/timer.h"
#include "atarijsa.h"
#include "atarimo.h"
#include "tilemap.h"
class skullxbo_state : public atarigen_state
{
public:
skullxbo_state(const machine_config &mconfig, device_type type, const char *tag) :
atarigen_state(mconfig, type, tag),
m_jsa(*this, "jsa"),
m_playfield_tilemap(*this, "playfield"),
m_alpha_tilemap(*this, "alpha"),
m_xscroll(*this, "xscroll"),
m_yscroll(*this, "yscroll"),
m_mob(*this, "mob"),
m_playfield_latch(-1),
m_scanline_int_state(0)
{ }
void skullxbo(machine_config &config);
void init_skullxbo();
protected:
virtual void machine_start() override;
private:
void skullxbo_halt_until_hblank_0_w(uint16_t data);
void skullxbo_mobwr_w(offs_t offset, uint16_t data);
TILE_GET_INFO_MEMBER(get_alpha_tile_info);
TILE_GET_INFO_MEMBER(get_playfield_tile_info);
void playfield_latch_w(uint16_t data);
void playfield_latched_w(offs_t offset, uint16_t data, uint16_t mem_mask = ~0);
uint32_t screen_update_skullxbo(screen_device &screen, bitmap_ind16 &bitmap, const rectangle &cliprect);
TIMER_CALLBACK_MEMBER(scanline_interrupt);
void scanline_int_ack_w(uint16_t data = 0);
void video_int_ack_w(uint16_t data = 0);
TIMER_DEVICE_CALLBACK_MEMBER(scanline_timer);
void skullxbo_scanline_update(int scanline);
void skullxbo_xscroll_w(offs_t offset, uint16_t data, uint16_t mem_mask = ~0);
void skullxbo_yscroll_w(offs_t offset, uint16_t data, uint16_t mem_mask = ~0);
void skullxbo_mobmsb_w(offs_t offset, uint16_t data);
void main_map(address_map &map);
required_device<atari_jsa_ii_device> m_jsa;
required_device<tilemap_device> m_playfield_tilemap;
required_device<tilemap_device> m_alpha_tilemap;
required_shared_ptr<uint16_t> m_xscroll;
required_shared_ptr<uint16_t> m_yscroll;
required_device<atari_motion_objects_device> m_mob;
int m_playfield_latch;
static const atari_motion_objects_config s_mob_config;
emu_timer *m_scanline_int_timer = nullptr;
bool m_scanline_int_state;
};
#endif // MAME_ATARI_SKULLXBO_H

View File

@ -1,302 +0,0 @@
// license:BSD-3-Clause
// copyright-holders:Aaron Giles
/***************************************************************************
Atari Skull & Crossbones hardware
****************************************************************************/
#include "emu.h"
#include "skullxbo.h"
/*************************************
*
* Tilemap callbacks
*
*************************************/
TILE_GET_INFO_MEMBER(skullxbo_state::get_alpha_tile_info)
{
uint16_t data = m_alpha_tilemap->basemem_read(tile_index);
int code = (data ^ 0x400) & 0x7ff;
int color = (data >> 11) & 0x0f;
int opaque = data & 0x8000;
tileinfo.set(2, code, color, opaque ? TILE_FORCE_LAYER0 : 0);
}
TILE_GET_INFO_MEMBER(skullxbo_state::get_playfield_tile_info)
{
uint16_t data1 = m_playfield_tilemap->basemem_read(tile_index);
uint16_t data2 = m_playfield_tilemap->extmem_read(tile_index) & 0xff;
int code = data1 & 0x7fff;
int color = data2 & 0x0f;
tileinfo.set(1, code, color, (data1 >> 15) & 1);
}
/*************************************
*
* Video system start
*
*************************************/
const atari_motion_objects_config skullxbo_state::s_mob_config =
{
0, /* index to which gfx system */
2, /* 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) */
0x000, /* base palette entry */
0x200, /* maximum number of colors */
0, /* transparent pen index */
{{ 0x00ff,0,0,0 }}, /* mask for the link */
{{ 0,0x7fff,0,0 }}, /* mask for the code index */
{{ 0,0,0x000f,0 }}, /* mask for the color */
{{ 0,0,0xffc0,0 }}, /* mask for the X position */
{{ 0,0,0,0xff80 }}, /* mask for the Y position */
{{ 0,0,0,0x0070 }}, /* mask for the width, in tiles*/
{{ 0,0,0,0x000f }}, /* mask for the height, in tiles */
{{ 0,0x8000,0,0 }}, /* mask for the horizontal flip */
{{ 0 }}, /* mask for the vertical flip */
{{ 0,0,0x0030,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" */
};
/*************************************
*
* Video data latch
*
*************************************/
void skullxbo_state::skullxbo_xscroll_w(offs_t offset, uint16_t data, uint16_t mem_mask)
{
/* combine data */
uint16_t oldscroll = *m_xscroll;
uint16_t newscroll = oldscroll;
COMBINE_DATA(&newscroll);
/* if something changed, force an update */
if (oldscroll != newscroll)
m_screen->update_partial(m_screen->vpos());
/* adjust the actual scrolls */
m_playfield_tilemap->set_scrollx(0, 2 * (newscroll >> 7));
m_mob->set_xscroll(2 * (newscroll >> 7));
/* update the data */
*m_xscroll = newscroll;
}
void skullxbo_state::skullxbo_yscroll_w(offs_t offset, uint16_t data, uint16_t mem_mask)
{
/* combine data */
int scanline = m_screen->vpos();
uint16_t oldscroll = *m_yscroll;
uint16_t newscroll = oldscroll;
uint16_t effscroll;
COMBINE_DATA(&newscroll);
/* if something changed, force an update */
if (oldscroll != newscroll)
m_screen->update_partial(scanline);
/* adjust the effective scroll for the current scanline */
if (scanline > m_screen->visible_area().bottom())
scanline = 0;
effscroll = (newscroll >> 7) - scanline;
/* adjust the actual scrolls */
m_playfield_tilemap->set_scrolly(0, effscroll);
m_mob->set_yscroll(effscroll & 0x1ff);
/* update the data */
*m_yscroll = newscroll;
}
/*************************************
*
* Motion object bank handler
*
*************************************/
void skullxbo_state::skullxbo_mobmsb_w(offs_t offset, uint16_t data)
{
m_screen->update_partial(m_screen->vpos());
m_mob->set_bank((offset >> 9) & 1);
}
/*************************************
*
* Playfield latch write handler
*
*************************************/
void skullxbo_state::playfield_latch_w(uint16_t data)
{
m_playfield_latch = data;
}
void skullxbo_state::playfield_latched_w(offs_t offset, uint16_t data, uint16_t mem_mask)
{
m_playfield_tilemap->write16(offset, data, mem_mask);
if (m_playfield_latch != -1)
{
uint16_t oldval = m_playfield_tilemap->extmem_read(offset);
uint16_t newval = (oldval & ~0x00ff) | (m_playfield_latch & 0x00ff);
m_playfield_tilemap->extmem_write(offset, newval);
}
}
/*************************************
*
* Periodic playfield updater
*
*************************************/
void skullxbo_state::skullxbo_scanline_update(int scanline)
{
int x;
/* keep in range */
int offset = (scanline / 8) * 64 + 42;
if (offset >= 0x7c0)
return;
/* special case: scanline 0 should re-latch the previous raw scroll */
if (scanline == 0)
{
int newscroll = (*m_yscroll >> 7) & 0x1ff;
m_playfield_tilemap->set_scrolly(0, newscroll);
m_mob->set_yscroll(newscroll);
}
/* update the current parameters */
for (x = 42; x < 64; x++)
{
uint16_t data = m_alpha_tilemap->basemem_read(offset++);
uint16_t command = data & 0x000f;
/* only command I've ever seen */
if (command == 0x0d)
{
/* a new vscroll latches the offset into a counter; we must adjust for this */
int newscroll = ((data >> 7) - scanline) & 0x1ff;
/* force a partial update with the previous scroll */
if (scanline > 0)
m_screen->update_partial(scanline - 1);
/* update the new scroll */
m_playfield_tilemap->set_scrolly(0, newscroll);
m_mob->set_yscroll(newscroll);
/* make sure we change this value so that writes to the scroll register */
/* know whether or not they are a different scroll */
*m_yscroll = data;
}
}
}
/*************************************
*
* Main refresh
*
*************************************/
uint32_t skullxbo_state::screen_update_skullxbo(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 from the GALs on the real PCB; equations follow
--- O17 is an intermediate value
O17=PFPIX3*PFPAL2S*PFPAL3S
--- CRAM.A10 controls the high bit of the palette select; used for shadows
CRAM.A10=BA11*CRAMD
+!CRAMD*!LBPRI0*!LBPRI1*!O17*(LBPIX==1)*(ANPIX==0)
+!CRAMD*LBPRI0*!LBPRI1*(LBPIX==1)*(ANPIX==0)*!PFPAL3S
+!CRAMD*LBPRI1*(LBPIX==1)*(ANPIX==0)*!PFPAL2S*!PFPAL3S
+!CRAMD*!PFPIX3*(LBPIX==1)*(ANPIX==0)
--- SA and SB are the mux select lines:
--- 0 = motion objects
--- 1 = playfield
--- 2 = alpha
--- 3 = color RAM access from CPU
!SA=!CRAMD*(ANPIX!=0)
+!CRAMD*!LBPRI0*!LBPRI1*!O17*(LBPIX!=1)*(LBPIX!=0)
+!CRAMD*LBPRI0*!LBPRI1*(LBPIX!=1)*(LBPIX!=0)*!PFPAL3S
+!CRAMD*LBPRI1*(LBPIX!=1)*(LBPIX!=0)*!PFPAL2S*!PFPAL3S
+!CRAMD*!PFPIX3*(LBPIX!=1)*(LBPIX!=0)
!SB=!CRAMD*(ANPIX==0)
+!CRAMD*LBMISC*(LBPIX!=0)
*/
int const mopriority = mo[x] >> atari_motion_objects_device::PRIORITY_SHIFT;
int const mopix = mo[x] & 0x1f;
int const pfcolor = (pf[x] >> 4) & 0x0f;
int const pfpix = pf[x] & 0x0f;
int const o17 = ((pf[x] & 0xc8) == 0xc8);
/* implement the equations */
if ((mopriority == 0 && !o17 && mopix >= 2) ||
(mopriority == 1 && mopix >= 2 && !(pfcolor & 0x08)) ||
((mopriority & 2) && mopix >= 2 && !(pfcolor & 0x0c)) ||
(!(pfpix & 8) && mopix >= 2))
pf[x] = mo[x] & atari_motion_objects_device::DATA_MASK;
if ((mopriority == 0 && !o17 && mopix == 1) ||
(mopriority == 1 && mopix == 1 && !(pfcolor & 0x08)) ||
((mopriority & 2) && mopix == 1 && !(pfcolor & 0x0c)) ||
(!(pfpix & 8) && mopix == 1))
pf[x] |= 0x400;
}
}
/* add the alpha on top */
m_alpha_tilemap->draw(screen, bitmap, cliprect, 0, 0);
return 0;
}