diff options
Diffstat (limited to 'src/mame/atari/arcadecl.cpp')
-rw-r--r-- | src/mame/atari/arcadecl.cpp | 212 |
1 files changed, 187 insertions, 25 deletions
diff --git a/src/mame/atari/arcadecl.cpp b/src/mame/atari/arcadecl.cpp index d4ef61f5cc5..577848984f0 100644 --- a/src/mame/atari/arcadecl.cpp +++ b/src/mame/atari/arcadecl.cpp @@ -1,5 +1,6 @@ // license:BSD-3-Clause -// copyright-holders:Aaron Giles +// copyright-holders: Aaron Giles + /*************************************************************************** Atari Arcade Classics hardware (prototypes) @@ -56,7 +57,7 @@ W -------- x------- (ADPCM bank select) W -------- ---xxxxx (Volume) 640060 W -------- -------- EEPROM enable - 641000-641FFF R/W -------- xxxxxxxx EEPROM + 641000-6413FF R/W -------- xxxxxxxx EEPROM 642000-642001 R/W xxxxxxxx -------- MSM6295 communications 646000 W -------- -------- 32V IRQ acknowledge 647000 W -------- -------- Watchdog reset @@ -69,51 +70,209 @@ #include "emu.h" -#include "arcadecl.h" + +#include "atarimo.h" + #include "cpu/m68000/m68000.h" #include "machine/eeprompar.h" +#include "machine/timer.h" #include "machine/watchdog.h" #include "sound/okim6295.h" -#include "atarimo.h" + #include "emupal.h" +#include "screen.h" #include "speaker.h" -#define MASTER_CLOCK XTAL(14'318'181) +namespace { + +class sparkz_state : public driver_device +{ +public: + sparkz_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_oki(*this, "oki") + , m_bitmap(*this, "bitmap") + { } + + void sparkz(machine_config &config); + +protected: + virtual uint32_t screen_update(screen_device &screen, bitmap_ind16 &bitmap, const rectangle &cliprect); + + required_device<cpu_device> m_maincpu; + required_device<gfxdecode_device> m_gfxdecode; + required_device<screen_device> m_screen; + required_device<okim6295_device> m_oki; + required_shared_ptr<uint16_t> m_bitmap; + +private: + TIMER_DEVICE_CALLBACK_MEMBER(scanline_interrupt); + void scanline_int_ack_w(uint16_t data); + void latch_w(uint8_t data); + void main_map(address_map &map); +}; + + +class arcadecl_state : public sparkz_state +{ +public: + arcadecl_state(const machine_config &mconfig, device_type type, const char *tag) + : sparkz_state(mconfig, type, tag) + , m_mob(*this, "mob") + { } + + void arcadecl(machine_config &config); + +protected: + virtual void video_start() override; + virtual uint32_t screen_update(screen_device &screen, bitmap_ind16 &bitmap, const rectangle &cliprect) override; + +private: + required_device<atari_motion_objects_device> m_mob; + + static const atari_motion_objects_config s_mob_config; +}; + + +/*************************************************************************** + + Note: this video hardware has some similarities to Shuuz & company + The sprite offset registers are stored to 3EFF80 + +****************************************************************************/ /************************************* * - * Interrupt handling + * Video system start * *************************************/ -TIMER_DEVICE_CALLBACK_MEMBER(sparkz_state::scanline_interrupt) +const atari_motion_objects_config arcadecl_state::s_mob_config = { - /* generate 32V signals */ - if ((param & 32) == 0) - m_maincpu->set_input_line(M68K_IRQ_4, ASSERT_LINE); + 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? + 0, // pixels per SLIP entry (0 for no-slip) + 0, // pixel offset for SLIPs + 0, // maximum number of links to visit/scanline (0=all) + + 0x100, // base palette entry + 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 arcadecl_state::video_start() +{ + m_mob->set_scroll(-12, 0x110); } -void sparkz_state::scanline_int_ack_w(uint16_t data) + +/************************************* + * + * Main refresh + * + *************************************/ + +uint32_t arcadecl_state::screen_update(screen_device &screen, bitmap_ind16 &bitmap, const rectangle &cliprect) { - m_maincpu->set_input_line(M68K_IRQ_4, CLEAR_LINE); + // start drawing + m_mob->draw_async(cliprect); + + // draw the playfield + sparkz_state::screen_update(screen, 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) + { + // not yet verified + pf[x] = mo[x]; + } + } + + return 0; } /************************************* * - * Initialization + * Bitmap rendering * *************************************/ -void sparkz_state::machine_reset() +uint32_t sparkz_state::screen_update(screen_device &screen, bitmap_ind16 &bitmap, const rectangle &cliprect) { + // update any dirty scanlines + for (int y = cliprect.top(); y <= cliprect.bottom(); y++) + { + const uint16_t *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; + } + } + + return 0; } +/************************************* + * + * Interrupt handling + * + *************************************/ + +TIMER_DEVICE_CALLBACK_MEMBER(sparkz_state::scanline_interrupt) +{ + // generate 32V signals + if ((param & 32) == 0) + m_maincpu->set_input_line(M68K_IRQ_4, ASSERT_LINE); +} + + +void sparkz_state::scanline_int_ack_w(uint16_t data) +{ + m_maincpu->set_input_line(M68K_IRQ_4, CLEAR_LINE); +} + /************************************* * @@ -144,7 +303,7 @@ void sparkz_state::latch_w(uint8_t data) void sparkz_state::main_map(address_map &map) { map(0x000000, 0x0fffff).rom(); - map(0x200000, 0x21ffff).ram().share("bitmap"); + map(0x200000, 0x21ffff).ram().share(m_bitmap); map(0x3c0000, 0x3c07ff).rw("palette", FUNC(palette_device::read8), FUNC(palette_device::write8)).umask16(0xff00).share("palette"); map(0x3e0000, 0x3e07ff).ram().share("mob"); map(0x3e0800, 0x3effbf).ram(); @@ -159,7 +318,7 @@ void sparkz_state::main_map(address_map &map) map(0x640026, 0x640027).portr("TRACKY1"); map(0x640041, 0x640041).mirror(0xe).w(FUNC(sparkz_state::latch_w)); map(0x640060, 0x64006f).w("eeprom", FUNC(eeprom_parallel_28xx_device::unlock_write16)); - map(0x641000, 0x641fff).rw("eeprom", FUNC(eeprom_parallel_28xx_device::read), FUNC(eeprom_parallel_28xx_device::write)).umask16(0x00ff); + map(0x641000, 0x6413ff).rw("eeprom", FUNC(eeprom_parallel_28xx_device::read), FUNC(eeprom_parallel_28xx_device::write)).umask16(0x00ff); map(0x642000, 0x642000).rw("oki", FUNC(okim6295_device::read), FUNC(okim6295_device::write)); map(0x646000, 0x646001).mirror(0xffe).w(FUNC(sparkz_state::scanline_int_ack_w)); map(0x647000, 0x647fff).w("watchdog", FUNC(watchdog_timer_device::reset16_w)); @@ -266,7 +425,7 @@ static INPUT_PORTS_START( sparkz ) PORT_BIT( 0x0002, IP_ACTIVE_LOW, IPT_COIN2 ) PORT_BIT( 0x000c, IP_ACTIVE_LOW, IPT_UNUSED ) PORT_BIT( 0x0010, IP_ACTIVE_LOW, IPT_SERVICE1 ) - PORT_BIT( 0x0020, IP_ACTIVE_LOW, IPT_SERVICE2 ) /* not in "test mode" */ + PORT_BIT( 0x0020, IP_ACTIVE_LOW, IPT_SERVICE2 ) // not in "test mode" PORT_BIT( 0xffc0, IP_ACTIVE_LOW, IPT_UNUSED ) PORT_START("TRACKX2") @@ -291,7 +450,7 @@ INPUT_PORTS_END *************************************/ static GFXDECODE_START( gfx_arcadecl ) - GFXDECODE_ENTRY( "gfx1", 0, gfx_8x8x4_packed_msb, 256, 16 ) + GFXDECODE_ENTRY( "gfx1", 0, gfx_8x8x4_packed_msb, 256, 16 ) GFXDECODE_END @@ -304,7 +463,9 @@ GFXDECODE_END void sparkz_state::sparkz(machine_config &config) { - /* basic machine hardware */ + static constexpr XTAL MASTER_CLOCK = 14.318181_MHz_XTAL; + + // basic machine hardware M68000(config, m_maincpu, MASTER_CLOCK); m_maincpu->set_addrmap(AS_PROGRAM, &sparkz_state::main_map); @@ -314,7 +475,7 @@ void sparkz_state::sparkz(machine_config &config) WATCHDOG_TIMER(config, "watchdog"); - /* video hardware */ + // video hardware GFXDECODE(config, m_gfxdecode, "palette", gfx_arcadecl); palette_device &palette(PALETTE(config, "palette")); palette.set_format(palette_device::IRGB_1555, 512); @@ -322,17 +483,17 @@ void sparkz_state::sparkz(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); + // 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(sparkz_state::screen_update)); m_screen->set_palette("palette"); //m_screen->screen_vblank().set(FUNC(sparkz_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", 1.0); + OKIM6295(config, m_oki, MASTER_CLOCK / 4 / 3, okim6295_device::PIN7_LOW).add_route(ALL_OUTPUTS, "mono", 1.0); } void arcadecl_state::arcadecl(machine_config &config) @@ -375,6 +536,7 @@ ROM_START( sparkz ) ROM_LOAD( "sparkzsn", 0x00000, 0x80000, CRC(87097ce2) SHA1(dc4d199b5af692d111c087af3edc01e2ac0287a8) ) ROM_END +} // anonymous namespace /************************************* |