mirror of
https://github.com/holub/mame
synced 2025-07-06 18:39:28 +03:00
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:
parent
332c4ebefd
commit
1b35c0b9a5
@ -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 )
|
||||
|
@ -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
|
@ -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;
|
||||
}
|
@ -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
|
||||
|
||||
|
||||
/*************************************
|
||||
|
@ -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
|
@ -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
28
src/mame/atari/orbit_a.h
Normal 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
|
@ -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;
|
||||
}
|
@ -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 )
|
||||
|
@ -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
|
@ -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);
|
||||
}
|
||||
|
31
src/mame/atari/poolshrk_a.h
Normal file
31
src/mame/atari/poolshrk_a.h
Normal 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
|
@ -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;
|
||||
}
|
@ -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 )
|
||||
|
@ -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
|
@ -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;
|
||||
}
|
||||
}
|
||||
}
|
@ -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 )
|
||||
|
@ -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
|
@ -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;
|
||||
}
|
@ -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
|
||||
|
||||
|
||||
/*************************************
|
||||
|
@ -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
|
@ -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
@ -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
|
@ -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;
|
||||
}
|
Loading…
Reference in New Issue
Block a user