From 85066528d6e7e562b82ba3a3c4d33afa33ad40ec Mon Sep 17 00:00:00 2001 From: Ivan Vangelista Date: Wed, 6 Sep 2023 18:22:49 +0200 Subject: atari/batman, atari/beathead, atari/blstroid, atari/canyon, atari/ccastles: consolidated drivers in single files --- src/mame/atari/batman.cpp | 318 +++++++++++++++++-- src/mame/atari/batman.h | 58 ---- src/mame/atari/batman_v.cpp | 212 ------------- src/mame/atari/beathead.cpp | 325 +++++++++++++++++--- src/mame/atari/beathead.h | 92 ------ src/mame/atari/beathead_v.cpp | 175 ----------- src/mame/atari/blstroid.cpp | 290 +++++++++++++++--- src/mame/atari/blstroid.h | 62 ---- src/mame/atari/blstroid_v.cpp | 162 ---------- src/mame/atari/canyon.cpp | 215 +++++++++++-- src/mame/atari/canyon.h | 82 ----- src/mame/atari/canyon_a.cpp | 81 ++--- src/mame/atari/canyon_a.h | 28 ++ src/mame/atari/canyon_v.cpp | 84 ----- src/mame/atari/ccastles.cpp | 692 +++++++++++++++++++++++++++++++++++------- src/mame/atari/ccastles.h | 97 ------ src/mame/atari/ccastles_v.cpp | 344 --------------------- 17 files changed, 1646 insertions(+), 1671 deletions(-) delete mode 100644 src/mame/atari/batman.h delete mode 100644 src/mame/atari/batman_v.cpp delete mode 100644 src/mame/atari/beathead.h delete mode 100644 src/mame/atari/beathead_v.cpp delete mode 100644 src/mame/atari/blstroid.h delete mode 100644 src/mame/atari/blstroid_v.cpp delete mode 100644 src/mame/atari/canyon.h create mode 100644 src/mame/atari/canyon_a.h delete mode 100644 src/mame/atari/canyon_v.cpp delete mode 100644 src/mame/atari/ccastles.h delete mode 100644 src/mame/atari/ccastles_v.cpp diff --git a/src/mame/atari/batman.cpp b/src/mame/atari/batman.cpp index 2ad7b2b134b..47e7b3a44fc 100644 --- a/src/mame/atari/batman.cpp +++ b/src/mame/atari/batman.cpp @@ -20,14 +20,267 @@ #include "emu.h" -#include "batman.h" + +#include "atarijsa.h" +#include "atarimo.h" +#include "atarivad.h" + #include "cpu/m68000/m68000.h" #include "machine/eeprompar.h" #include "machine/watchdog.h" -#include "atarimo.h" + +#include "emupal.h" +#include "screen.h" #include "speaker.h" +#include "tilemap.h" + + +namespace { + +class batman_state : public driver_device +{ +public: + batman_state(const machine_config &mconfig, device_type type, const char *tag) : + driver_device(mconfig, type, tag), + m_maincpu(*this, "maincpu"), + m_screen(*this, "screen"), + m_jsa(*this, "jsa"), + m_vad(*this, "vad"), + m_mob(*this, "vad:mob") + { } + + void init_batman(); + void batman(machine_config &config); + +protected: + virtual void machine_start() override; + +private: + required_device m_maincpu; + required_device m_screen; + required_device m_jsa; + required_device m_vad; + required_device m_mob; + + uint16_t m_latch_data = 0U; + uint8_t m_alpha_tile_bank = 0U; + + static const atari_motion_objects_config s_mob_config; + + void latch_w(offs_t offset, uint16_t data, uint16_t mem_mask = ~0); + TILE_GET_INFO_MEMBER(get_alpha_tile_info); + 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); +}; + + +// video + +/************************************* + * + * Tilemap callbacks + * + *************************************/ + +TILE_GET_INFO_MEMBER(batman_state::get_alpha_tile_info) +{ + uint16_t const data = m_vad->alpha().basemem_read(tile_index); + int const code = ((data & 0x400) ? (m_alpha_tile_bank * 0x400) : 0) + (data & 0x3ff); + int const color = (data >> 11) & 0x0f; + int const opaque = data & 0x8000; + tileinfo.set(2, code, color, opaque ? TILE_FORCE_LAYER0 : 0); +} + + +TILE_GET_INFO_MEMBER(batman_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 = 0x10 + (data2 & 0x0f); + tileinfo.set(0, code, color, (data1 >> 15) & 1); + tileinfo.category = (data2 >> 4) & 3; +} + + +TILE_GET_INFO_MEMBER(batman_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); + tileinfo.category = (data2 >> 4) & 3; +} + + + +/************************************* + * + * Video system start + * + *************************************/ + +const atari_motion_objects_config batman_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? + 1, // 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 + + {{ 0x03ff,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,0,0x0070,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 batman_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, 0x00); + m_vad->playfield().draw(screen, bitmap, cliprect, 1, 0x01); + m_vad->playfield().draw(screen, bitmap, cliprect, 2, 0x02); + m_vad->playfield().draw(screen, bitmap, cliprect, 3, 0x03); + m_vad->playfield2().draw(screen, bitmap, cliprect, 0, 0x80); + m_vad->playfield2().draw(screen, bitmap, cliprect, 1, 0x84); + m_vad->playfield2().draw(screen, bitmap, cliprect, 2, 0x88); + m_vad->playfield2().draw(screen, bitmap, cliprect, 3, 0x8c); + + // 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 on real hardware: + + for all MO colors, MO priority 0: + obscured by low fg playfield pens priority 1-3 + obscured by high fg playfield pens priority 3 only + obscured by bg playfield priority 3 only + + for all MO colors, MO priority 1: + obscured by low fg playfield pens priority 2-3 + obscured by high fg playfield pens priority 3 only + obscured by bg playfield priority 3 only + + for all MO colors, MO priority 2-3: + obscured by low fg playfield pens priority 3 only + obscured by high fg playfield pens priority 3 only + obscured by bg playfield priority 3 only + */ + int const mopriority = mo[x] >> atari_motion_objects_device::PRIORITY_SHIFT; + + // upper bit of MO priority signals special rendering and doesn't draw anything + if (mopriority & 4) + continue; + + // foreground playfield case + if (pri[x] & 0x80) + { + int const pfpriority = (pri[x] >> 2) & 3; + + // playfield priority 3 always wins + if (pfpriority == 3) + ; + + // priority is consistent for upper pens in playfield + else if (pf[x] & 0x08) + pf[x] = mo[x] & atari_motion_objects_device::DATA_MASK; + + // otherwise, we need to compare + else if (mopriority >= pfpriority) + pf[x] = mo[x] & atari_motion_objects_device::DATA_MASK; + } + + // background playfield case + else + { + int const pfpriority = pri[x] & 3; + + // playfield priority 3 always wins + if (pfpriority == 3) + ; + + // otherwise, MOs get shown + else + pf[x] = mo[x] & atari_motion_objects_device::DATA_MASK; + } + + // don't erase yet -- we need to make another pass later + } + } + + // add the alpha on top + m_vad->alpha().draw(screen, bitmap, cliprect, 0, 0); + + // now go back and process the upper bit of MO priority + 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) + { + int const mopriority = mo[x] >> atari_motion_objects_device::PRIORITY_SHIFT; + + // upper bit of MO priority might mean palette kludges + if (mopriority & 4) + { + // if bit 2 is set, start setting high palette bits + if (mo[x] & 2) + m_vad->mob().apply_stain(bitmap, pf, mo, x, y); + } + } + } + return 0; +} +// machine /************************************* * @@ -51,10 +304,10 @@ void batman_state::machine_start() void batman_state::latch_w(offs_t offset, uint16_t data, uint16_t mem_mask) { - int oldword = m_latch_data; + int const oldword = m_latch_data; COMBINE_DATA(&m_latch_data); - /* bit 4 is connected to the /RESET pin on the 6502 */ + // bit 4 is connected to the /RESET pin on the 6502 if (m_latch_data & 0x0010) m_jsa->soundcpu().set_input_line(INPUT_LINE_RESET, CLEAR_LINE); else @@ -77,9 +330,9 @@ void batman_state::latch_w(offs_t offset, uint16_t data, uint16_t mem_mask) * *************************************/ -/* full map verified from schematics and GALs */ -/* addresses in the 1xxxxx region map to /WAIT */ -/* addresses in the 2xxxxx region map to /WAIT2 */ +// full map verified from schematics and GALs +// addresses in the 1xxxxx region map to /WAIT +// addresses in the 2xxxxx region map to /WAIT2 void batman_state::main_map(address_map &map) { map.unmap_value_high(); @@ -116,7 +369,7 @@ void batman_state::main_map(address_map &map) *************************************/ static INPUT_PORTS_START( batman ) - PORT_START("260000") /* 260000 */ + PORT_START("260000") PORT_BIT( 0x01ff, IP_ACTIVE_LOW, IPT_UNUSED ) PORT_BIT( 0x0200, IP_ACTIVE_LOW, IPT_BUTTON1 ) PORT_PLAYER(1) PORT_BIT( 0x0400, IP_ACTIVE_LOW, IPT_BUTTON2 ) PORT_PLAYER(1) @@ -126,13 +379,13 @@ static INPUT_PORTS_START( batman ) 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( 0xffff, IP_ACTIVE_LOW, IPT_UNUSED ) - PORT_START("260010") /* 260010 */ + PORT_START("260010") PORT_BIT( 0x000f, IP_ACTIVE_LOW, IPT_UNUSED ) - PORT_BIT( 0x0010, IP_ACTIVE_LOW, IPT_CUSTOM ) PORT_ATARI_JSA_SOUND_TO_MAIN_READY("jsa") /* Input buffer full (@260030) */ - PORT_BIT( 0x0020, IP_ACTIVE_LOW, IPT_CUSTOM ) PORT_ATARI_JSA_MAIN_TO_SOUND_READY("jsa") /* Output buffer full (@260040) */ + PORT_BIT( 0x0010, IP_ACTIVE_LOW, IPT_CUSTOM ) PORT_ATARI_JSA_SOUND_TO_MAIN_READY("jsa") // Input buffer full (@260030) + PORT_BIT( 0x0020, IP_ACTIVE_LOW, IPT_CUSTOM ) PORT_ATARI_JSA_MAIN_TO_SOUND_READY("jsa") // Output buffer full (@260040) PORT_SERVICE( 0x0040, IP_ACTIVE_LOW ) PORT_BIT( 0x0080, IP_ACTIVE_LOW, IPT_CUSTOM ) PORT_VBLANK("screen") INPUT_PORTS_END @@ -170,9 +423,9 @@ static const gfx_layout pfmolayout = static GFXDECODE_START( gfx_batman ) - GFXDECODE_ENTRY( "gfx3", 0, pfmolayout, 512, 32 ) /* sprites & playfield */ - GFXDECODE_ENTRY( "gfx2", 0, pfmolayout, 256, 16 ) /* sprites & playfield */ - GFXDECODE_ENTRY( "gfx1", 0, anlayout, 0, 64 ) /* characters 8x8 */ + GFXDECODE_ENTRY( "spr_tiles_2", 0, pfmolayout, 512, 32 ) // sprites & playfield + GFXDECODE_ENTRY( "spr_tiles_1", 0, pfmolayout, 256, 16 ) // sprites & playfield + GFXDECODE_ENTRY( "chars", 0, anlayout, 0, 64 ) // characters 8x8 GFXDECODE_END @@ -185,7 +438,7 @@ GFXDECODE_END void batman_state::batman(machine_config &config) { - /* basic machine hardware */ + // basic machine hardware M68000(config, m_maincpu, 14.318181_MHz_XTAL); m_maincpu->set_addrmap(AS_PROGRAM, &batman_state::main_map); @@ -193,7 +446,7 @@ void batman_state::batman(machine_config &config) WATCHDOG_TIMER(config, "watchdog"); - /* video hardware */ + // video hardware GFXDECODE(config, "gfxdecode", "palette", gfx_batman); PALETTE(config, "palette").set_format(palette_device::IRGB_1555, 2048); @@ -210,13 +463,13 @@ void batman_state::batman(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(batman_state::screen_update_batman)); + m_screen->set_screen_update(FUNC(batman_state::screen_update)); m_screen->set_palette("palette"); - /* sound hardware */ + // sound hardware SPEAKER(config, "mono").front_center(); ATARI_JSA_III(config, m_jsa, 0); @@ -234,7 +487,7 @@ void batman_state::batman(machine_config &config) *************************************/ ROM_START( batman ) - ROM_REGION( 0xc0000, "maincpu", 0 ) /* 6*128k for 68000 code */ + ROM_REGION( 0xc0000, "maincpu", 0 ) // 68000 code ROM_LOAD16_BYTE( "136085-2030.10r", 0x00000, 0x20000, CRC(7cf4e5bf) SHA1(d6068a65fb524d839a34e596a272fac1ce90981c) ) ROM_LOAD16_BYTE( "136085-2031.7r", 0x00001, 0x20000, CRC(7d7f3fc4) SHA1(8ee3e9ad3464006a26c36155b6099433110e2a6e) ) ROM_LOAD16_BYTE( "136085-2032.91r", 0x40000, 0x20000, CRC(d80afb20) SHA1(5696627f6fa713dba4d12443c945f3e1cb6452a3) ) @@ -242,23 +495,23 @@ ROM_START( batman ) ROM_LOAD16_BYTE( "136085-2034.9r", 0x80000, 0x20000, CRC(05388c62) SHA1(de037203d94e72e2922c89256da080ae023ca0e7) ) ROM_LOAD16_BYTE( "136085-2035.5r", 0x80001, 0x20000, CRC(e77c92dd) SHA1(6d475092f7628114960d26b8ec1c5eae5e61ce25) ) - ROM_REGION( 0x10000, "jsa:cpu", 0 ) /* 64k for 6502 code */ + ROM_REGION( 0x10000, "jsa:cpu", 0 ) // 6502 code ROM_LOAD( "136085-1040.12c", 0x00000, 0x10000, CRC(080db83c) SHA1(ec084b7c1dc5878acd6d081e2e8b8d1e8b3d8a45) ) - ROM_REGION( 0x20000, "gfx1", 0 ) - ROM_LOAD( "136085-2009.10m", 0x00000, 0x20000, CRC(a82d4923) SHA1(38e03eebd95347a383f3d7357462252961bd3c7f) ) /* alphanumerics */ + ROM_REGION( 0x20000, "chars", 0 ) + ROM_LOAD( "136085-2009.10m", 0x00000, 0x20000, CRC(a82d4923) SHA1(38e03eebd95347a383f3d7357462252961bd3c7f) ) - ROM_REGION( 0x100000, "gfx2", ROMREGION_INVERT ) - ROM_LOAD( "136085-1010.13r", 0x000000, 0x20000, CRC(466e1365) SHA1(318530e8a97c1b6ee3e671e677fc7684df5cc3a8) ) /* graphics, plane 0 */ + ROM_REGION( 0x100000, "spr_tiles_1", ROMREGION_INVERT ) + ROM_LOAD( "136085-1010.13r", 0x000000, 0x20000, CRC(466e1365) SHA1(318530e8a97c1b6ee3e671e677fc7684df5cc3a8) ) // graphics, plane 0 ROM_LOAD( "136085-1014.14r", 0x020000, 0x20000, CRC(ef53475a) SHA1(9bfc66bb8dd02757e4a79a75928b260f4518a94b) ) - ROM_LOAD( "136085-1011.13m", 0x040000, 0x20000, CRC(8cda5efc) SHA1(b0410f9bf1f38f5f1e9add15079b03d7f19b4c8f) ) /* graphics, plane 1 */ + ROM_LOAD( "136085-1011.13m", 0x040000, 0x20000, CRC(8cda5efc) SHA1(b0410f9bf1f38f5f1e9add15079b03d7f19b4c8f) ) // graphics, plane 1 ROM_LOAD( "136085-1015.14m", 0x060000, 0x20000, CRC(043e7f8b) SHA1(a3b2c539c1fa9b1e8d3dc8163b9a7c6e22408122) ) - ROM_LOAD( "136085-1012.13f", 0x080000, 0x20000, CRC(b017f2c3) SHA1(12846f0ae33e808dfb0795ea4138115b0eb36c4e) ) /* graphics, plane 2 */ + ROM_LOAD( "136085-1012.13f", 0x080000, 0x20000, CRC(b017f2c3) SHA1(12846f0ae33e808dfb0795ea4138115b0eb36c4e) ) // graphics, plane 2 ROM_LOAD( "136085-1016.14f", 0x0a0000, 0x20000, CRC(70aa2360) SHA1(5b944b533be40b859b7fae64559286034409ac6c) ) - ROM_LOAD( "136085-1013.13c", 0x0c0000, 0x20000, CRC(68b64975) SHA1(f3fb45dd74fc21dd2eece87e739c734963962f93) ) /* graphics, plane 3 */ + ROM_LOAD( "136085-1013.13c", 0x0c0000, 0x20000, CRC(68b64975) SHA1(f3fb45dd74fc21dd2eece87e739c734963962f93) ) // graphics, plane 3 ROM_LOAD( "136085-1017.14c", 0x0e0000, 0x20000, CRC(e4af157b) SHA1(ddf9eff84c882a096f7e435a6227b32d31029f9e) ) - ROM_REGION( 0x100000, "gfx3", ROMREGION_INVERT ) + ROM_REGION( 0x100000, "spr_tiles_2", ROMREGION_INVERT ) ROM_LOAD( "136085-1018.15r", 0x000000, 0x20000, CRC(4c14f1e5) SHA1(2a65d0aafd944886d9e801c9de0f857f2e9db773) ) ROM_LOAD( "136085-1022.16r", 0x020000, 0x20000, CRC(7476a15d) SHA1(779f9aec114aa71a268a7a646d998c1593f55d08) ) ROM_LOAD( "136085-1019.15m", 0x040000, 0x20000, CRC(2046d9ec) SHA1(3b14b18545eac2e6cb1d3157ec1af251287b3e45) ) @@ -268,7 +521,7 @@ ROM_START( batman ) ROM_LOAD( "136085-1021.15c", 0x0c0000, 0x20000, CRC(9c8ef9ba) SHA1(c2540adfc227a654a3f91e2cfdcd98b3a04ae4fb) ) ROM_LOAD( "136085-1025.16c", 0x0e0000, 0x20000, CRC(5d30bcd1) SHA1(817e225511ab98e7575ee512d659c51fcb7716dc) ) - ROM_REGION( 0x80000, "jsa:oki1", 0 ) /* 1MB for ADPCM */ + ROM_REGION( 0x80000, "jsa:oki1", 0 ) // ADPCM ROM_LOAD( "136085-1041.19e", 0x00000, 0x20000, CRC(d97d5dbb) SHA1(7609841c773e3d1ae5a21da81e3387260fd8da41) ) ROM_LOAD( "136085-1042.17e", 0x20000, 0x20000, CRC(8c496986) SHA1(07c84c68885e2ab3e81ee92942d6a0f29e4dffa8) ) ROM_LOAD( "136085-1043.15e", 0x40000, 0x20000, CRC(51812d3b) SHA1(6748fecef753179a9257c0da5a7b7c9648437208) ) @@ -288,6 +541,7 @@ ROM_START( batman ) ROM_LOAD( "gal16v8a-136085-1039.c19", 0x0e00, 0x0117, CRC(47565e09) SHA1(7aeac8de6f9fda23da50655352b845f692ab0747) ) ROM_END +} // anonymous namespace /************************************* diff --git a/src/mame/atari/batman.h b/src/mame/atari/batman.h deleted file mode 100644 index d6d0145d734..00000000000 --- a/src/mame/atari/batman.h +++ /dev/null @@ -1,58 +0,0 @@ -// license:BSD-3-Clause -// copyright-holders:Aaron Giles -/************************************************************************* - - Atari Batman hardware - -*************************************************************************/ -#ifndef MAME_ATARI_BATMAN_H -#define MAME_ATARI_BATMAN_H - -#pragma once - -#include "atarijsa.h" -#include "atarimo.h" -#include "atarivad.h" -#include "emupal.h" -#include "screen.h" -#include "tilemap.h" - -class batman_state : public driver_device -{ -public: - batman_state(const machine_config &mconfig, device_type type, const char *tag) : - driver_device(mconfig, type, tag), - m_maincpu(*this, "maincpu"), - m_screen(*this, "screen"), - m_jsa(*this, "jsa"), - m_vad(*this, "vad"), - m_mob(*this, "vad:mob") - { } - - void init_batman(); - void batman(machine_config &config); - -protected: - virtual void machine_start() override; - void latch_w(offs_t offset, uint16_t data, uint16_t mem_mask = ~0); - TILE_GET_INFO_MEMBER(get_alpha_tile_info); - TILE_GET_INFO_MEMBER(get_playfield_tile_info); - TILE_GET_INFO_MEMBER(get_playfield2_tile_info); - uint32_t screen_update_batman(screen_device &screen, bitmap_ind16 &bitmap, const rectangle &cliprect); - - void main_map(address_map &map); - -private: - required_device m_maincpu; - required_device m_screen; - required_device m_jsa; - required_device m_vad; - required_device m_mob; - - uint16_t m_latch_data = 0U; - uint8_t m_alpha_tile_bank = 0U; - - static const atari_motion_objects_config s_mob_config; -}; - -#endif // MAME_ATARI_BATMAN_H diff --git a/src/mame/atari/batman_v.cpp b/src/mame/atari/batman_v.cpp deleted file mode 100644 index ee4d5a875bc..00000000000 --- a/src/mame/atari/batman_v.cpp +++ /dev/null @@ -1,212 +0,0 @@ -// license:BSD-3-Clause -// copyright-holders:Aaron Giles -/*************************************************************************** - - Atari Batman hardware - -****************************************************************************/ - -#include "emu.h" -#include "batman.h" - - - -/************************************* - * - * Tilemap callbacks - * - *************************************/ - -TILE_GET_INFO_MEMBER(batman_state::get_alpha_tile_info) -{ - uint16_t data = m_vad->alpha().basemem_read(tile_index); - int code = ((data & 0x400) ? (m_alpha_tile_bank * 0x400) : 0) + (data & 0x3ff); - int color = (data >> 11) & 0x0f; - int opaque = data & 0x8000; - tileinfo.set(2, code, color, opaque ? TILE_FORCE_LAYER0 : 0); -} - - -TILE_GET_INFO_MEMBER(batman_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 = 0x10 + (data2 & 0x0f); - tileinfo.set(0, code, color, (data1 >> 15) & 1); - tileinfo.category = (data2 >> 4) & 3; -} - - -TILE_GET_INFO_MEMBER(batman_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); - tileinfo.category = (data2 >> 4) & 3; -} - - - -/************************************* - * - * Video system start - * - *************************************/ - -const atari_motion_objects_config batman_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? */ - 1, /* 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 */ - - {{ 0x03ff,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,0,0x0070,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 batman_state::screen_update_batman(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, 0x00); - m_vad->playfield().draw(screen, bitmap, cliprect, 1, 0x01); - m_vad->playfield().draw(screen, bitmap, cliprect, 2, 0x02); - m_vad->playfield().draw(screen, bitmap, cliprect, 3, 0x03); - m_vad->playfield2().draw(screen, bitmap, cliprect, 0, 0x80); - m_vad->playfield2().draw(screen, bitmap, cliprect, 1, 0x84); - m_vad->playfield2().draw(screen, bitmap, cliprect, 2, 0x88); - m_vad->playfield2().draw(screen, bitmap, cliprect, 3, 0x8c); - - // 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 on real hardware: - - for all MO colors, MO priority 0: - obscured by low fg playfield pens priority 1-3 - obscured by high fg playfield pens priority 3 only - obscured by bg playfield priority 3 only - - for all MO colors, MO priority 1: - obscured by low fg playfield pens priority 2-3 - obscured by high fg playfield pens priority 3 only - obscured by bg playfield priority 3 only - - for all MO colors, MO priority 2-3: - obscured by low fg playfield pens priority 3 only - obscured by high fg playfield pens priority 3 only - obscured by bg playfield priority 3 only - */ - int const mopriority = mo[x] >> atari_motion_objects_device::PRIORITY_SHIFT; - - /* upper bit of MO priority signals special rendering and doesn't draw anything */ - if (mopriority & 4) - continue; - - /* foreground playfield case */ - if (pri[x] & 0x80) - { - int const pfpriority = (pri[x] >> 2) & 3; - - /* playfield priority 3 always wins */ - if (pfpriority == 3) - ; - - /* priority is consistent for upper pens in playfield */ - else if (pf[x] & 0x08) - pf[x] = mo[x] & atari_motion_objects_device::DATA_MASK; - - /* otherwise, we need to compare */ - else if (mopriority >= pfpriority) - pf[x] = mo[x] & atari_motion_objects_device::DATA_MASK; - } - - /* background playfield case */ - else - { - int const pfpriority = pri[x] & 3; - - /* playfield priority 3 always wins */ - if (pfpriority == 3) - ; - - /* otherwise, MOs get shown */ - else - pf[x] = mo[x] & atari_motion_objects_device::DATA_MASK; - } - - /* don't erase yet -- we need to make another pass later */ - } - } - - /* add the alpha on top */ - m_vad->alpha().draw(screen, bitmap, cliprect, 0, 0); - - /* now go back and process the upper bit of MO priority */ - 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) - { - int const mopriority = mo[x] >> atari_motion_objects_device::PRIORITY_SHIFT; - - /* upper bit of MO priority might mean palette kludges */ - if (mopriority & 4) - { - /* if bit 2 is set, start setting high palette bits */ - if (mo[x] & 2) - m_vad->mob().apply_stain(bitmap, pf, mo, x, y); - } - } - } - return 0; -} diff --git a/src/mame/atari/beathead.cpp b/src/mame/atari/beathead.cpp index bfabcfb271a..10fa0cf5696 100644 --- a/src/mame/atari/beathead.cpp +++ b/src/mame/atari/beathead.cpp @@ -1,5 +1,6 @@ // license:BSD-3-Clause -// copyright-holders:Aaron Giles +// copyright-holders: Aaron Giles + /*************************************************************************** Atari "Stella on Steroids" hardware @@ -100,16 +101,265 @@ #include "emu.h" -#include "beathead.h" + +#include "atarijsa.h" + +#include "cpu/asap/asap.h" #include "machine/eeprompar.h" +#include "machine/timer.h" #include "machine/watchdog.h" + +#include "emupal.h" +#include "screen.h" #include "speaker.h" -#define MAX_SCANLINES 262 +namespace { + +class beathead_state : public driver_device +{ +public: + beathead_state(const machine_config &mconfig, device_type type, const char *tag) : + driver_device(mconfig, type, tag), + m_maincpu(*this, "maincpu"), + m_palette(*this, "palette"), + m_screen(*this, "screen"), + m_jsa(*this, "jsa"), + m_scan_timer(*this, "scan_timer"), + m_videoram(*this, "videoram"), + m_vram_bulk_latch(*this, "vram_bulk_latch"), + m_palette_select(*this, "palette_select"), + m_ram_base(*this, "ram_base"), + m_rom_base(*this, "maincpu") + { } + + void beathead(machine_config &config); + +protected: + virtual void machine_reset() override; + virtual void video_start() override; + +private: + required_device m_maincpu; + required_device m_palette; + required_device m_screen; + required_device m_jsa; + required_device m_scan_timer; + + required_shared_ptr m_videoram; + required_shared_ptr m_vram_bulk_latch; + required_shared_ptr m_palette_select; + required_shared_ptr m_ram_base; + required_region_ptr m_rom_base; + + uint32_t m_finescroll = 0U; + offs_t m_vram_latch_offset = 0U; + + offs_t m_hsyncram_offset = 0U; + offs_t m_hsyncram_start = 0U; + uint8_t m_hsyncram[0x800]{}; + + attotime m_hblank_offset; + + uint8_t m_irq_line_state = 0U; + uint8_t m_irq_enable[3]{}; + uint8_t m_irq_state[3]{}; + + static constexpr int MAX_SCANLINES = 262; + + void update_interrupts(); + void interrupt_control_w(offs_t offset, uint32_t data); + uint32_t interrupt_control_r(); + void sound_reset_w(offs_t offset, uint32_t data); + void coin_count_w(offs_t offset, uint32_t data); + void vram_transparent_w(offs_t offset, uint32_t data, uint32_t mem_mask = ~0); + void vram_bulk_w(offs_t offset, uint32_t data, uint32_t mem_mask = ~0); + void vram_latch_w(offs_t offset, uint32_t data); + void vram_copy_w(offs_t offset, uint32_t data); + void finescroll_w(offs_t offset, uint32_t data, uint32_t mem_mask = ~0); + uint32_t hsync_ram_r(offs_t offset); + void hsync_ram_w(offs_t offset, uint32_t data, uint32_t mem_mask = ~0); + TIMER_DEVICE_CALLBACK_MEMBER(scanline_callback); + + + void main_map(address_map &map); + + uint32_t screen_update(screen_device &screen, bitmap_ind16 &bitmap, const rectangle &cliprect); +}; + + +// video + +/************************************* + * + * Video start/stop + * + *************************************/ + +void beathead_state::video_start() +{ + save_item(NAME(m_finescroll)); + save_item(NAME(m_vram_latch_offset)); + save_item(NAME(m_hsyncram_offset)); + save_item(NAME(m_hsyncram_start)); + save_item(NAME(m_hsyncram)); + + save_item(NAME(m_irq_line_state)); + save_item(NAME(m_irq_enable)); + save_item(NAME(m_irq_state)); + + m_hsyncram_offset = 0; +} + + + +/************************************* + * + * VRAM handling + * + *************************************/ + +void beathead_state::vram_transparent_w(offs_t offset, uint32_t data, uint32_t mem_mask) +{ + // writes to this area appear to handle transparency + if (!(data & 0x000000ff)) mem_mask &= ~0x000000ff; + if (!(data & 0x0000ff00)) mem_mask &= ~0x0000ff00; + if (!(data & 0x00ff0000)) mem_mask &= ~0x00ff0000; + if (!(data & 0xff000000)) mem_mask &= ~0xff000000; + COMBINE_DATA(&m_videoram[offset]); +} + + +void beathead_state::vram_bulk_w(offs_t offset, uint32_t data, uint32_t mem_mask) +{ + // it appears that writes to this area pass in a mask for 4 words in VRAM + // allowing them to be filled from a preset latch + offset &= ~3; + data = data & mem_mask & 0x0f0f0f0f; + + // for now, just handle the bulk fill case; the others we'll catch later + if (data == 0x0f0f0f0f) + m_videoram[offset + 0] = m_videoram[offset + 1] = m_videoram[offset + 2] = m_videoram[offset + 3] = *m_vram_bulk_latch; + else + logerror("Detected bulk VRAM write with mask %08x\n", data); +} + + +void beathead_state::vram_latch_w(offs_t offset, uint32_t data) +{ + // latch the address + m_vram_latch_offset = (4 * offset) & 0x7ffff; +} + + +void beathead_state::vram_copy_w(offs_t offset, uint32_t data) +{ + // copy from VRAM to VRAM, for 1024 bytes + offs_t const dest_offset = (4 * offset) & 0x7ffff; + memcpy(&m_videoram[dest_offset / 4], &m_videoram[m_vram_latch_offset / 4], 0x400); +} + + + +/************************************* + * + * Scroll offset handling + * + *************************************/ + +void beathead_state::finescroll_w(offs_t offset, uint32_t data, uint32_t mem_mask) +{ + uint32_t const oldword = m_finescroll; + uint32_t const newword = COMBINE_DATA(&m_finescroll); + + // if VBLANK is going off on a scanline other than the last, suspend time + if ((oldword & 8) && !(newword & 8) && m_screen->vpos() != 261) + { + logerror("Suspending time! (scanline = %d)\n", m_screen->vpos()); + m_maincpu->set_input_line(INPUT_LINE_HALT, ASSERT_LINE); + } +} +/************************************* + * + * HSYNC RAM handling + * + *************************************/ + +uint32_t beathead_state::hsync_ram_r(offs_t offset) +{ + // offset 0 is probably write-only + if (offset == 0) + logerror("%08X:Unexpected HSYNC RAM read at offset 0\n", m_maincpu->pcbase()); + + // offset 1 reads the data + else + return m_hsyncram[m_hsyncram_offset]; + + return 0; +} + +void beathead_state::hsync_ram_w(offs_t offset, uint32_t data, uint32_t mem_mask) +{ + // offset 0 selects the address, and can specify the start address + if (offset == 0) + { + COMBINE_DATA(&m_hsyncram_offset); + if (m_hsyncram_offset & 0x800) + m_hsyncram_start = m_hsyncram_offset & 0x7ff; + } + + // offset 1 writes the data + else + COMBINE_DATA(&m_hsyncram[m_hsyncram_offset]); +} + + + +/************************************* + * + * Main screen refresher + * + *************************************/ + +uint32_t beathead_state::screen_update(screen_device &screen, bitmap_ind16 &bitmap, const rectangle &cliprect) +{ + const auto videoram = util::little_endian_cast(m_videoram.target()); + + // generate the final screen + for (int y = cliprect.top(); y <= cliprect.bottom(); y++) + { + const pen_t pen_base = (*m_palette_select & 0x7f) * 256; + uint16_t scanline[336]; + + if (m_finescroll & 8) + { + // blanking + for (int x = cliprect.left(); x <= cliprect.right(); x++) + scanline[x] = pen_base; + } + else + { + // non-blanking + const offs_t scanline_offset = m_vram_latch_offset + (m_finescroll & 3); + offs_t src = scanline_offset + cliprect.left(); + + // unswizzle the scanline first + for (int x = cliprect.left(); x <= cliprect.right(); x++) + scanline[x] = pen_base | videoram[src++]; + } + + // then draw it + draw_scanline16(bitmap, cliprect.left(), y, cliprect.width(), &scanline[cliprect.left()], nullptr); + } + return 0; +} + + +// machine + /************************************* * * Machine init @@ -120,38 +370,38 @@ TIMER_DEVICE_CALLBACK_MEMBER(beathead_state::scanline_callback) { int scanline = param; - /* update the video */ + // update the video m_screen->update_partial(m_screen->vpos()); - /* on scanline zero, clear any halt condition */ + // on scanline zero, clear any halt condition if (scanline == 0) m_maincpu->set_input_line(INPUT_LINE_HALT, CLEAR_LINE); - /* wrap around at 262 */ + // wrap around at 262 scanline++; if (scanline >= MAX_SCANLINES) scanline = 0; - /* set the scanline IRQ */ + // set the scanline IRQ m_irq_state[2] = 1; update_interrupts(); - /* set the timer for the next one */ + // set the timer for the next one m_scan_timer->adjust(m_screen->time_until_pos(scanline) - m_hblank_offset, scanline); } void beathead_state::machine_reset() { - /* the code is temporarily mapped at 0 at startup */ - /* just copying the first 0x40 bytes is sufficient */ + // the code is temporarily mapped at 0 at startup + // just copying the first 0x40 bytes is sufficient memcpy(m_ram_base, m_rom_base, 0x40); - /* compute the timing of the HBLANK interrupt and set the first timer */ + // compute the timing of the HBLANK interrupt and set the first timer m_hblank_offset = m_screen->scan_period() * (455 - 336 - 25) / 455; m_scan_timer->adjust(m_screen->time_until_pos(0) - m_hblank_offset); - /* reset IRQs */ + // reset IRQs m_irq_line_state = CLEAR_LINE; m_irq_state[0] = m_irq_state[1] = m_irq_state[2] = 0; m_irq_enable[0] = m_irq_enable[1] = m_irq_enable[2] = 0; @@ -167,15 +417,13 @@ void beathead_state::machine_reset() void beathead_state::update_interrupts() { - int gen_int; - - /* compute the combined interrupt signal */ - gen_int = m_irq_state[0] & m_irq_enable[0]; + // compute the combined interrupt signal + int gen_int = m_irq_state[0] & m_irq_enable[0]; gen_int |= m_irq_state[1] & m_irq_enable[1]; gen_int |= m_irq_state[2] & m_irq_enable[2]; gen_int = gen_int ? ASSERT_LINE : CLEAR_LINE; - /* if it's changed since the last time, call through */ + // if it's changed since the last time, call through if (m_irq_line_state != gen_int) { m_irq_line_state = gen_int; @@ -189,25 +437,25 @@ void beathead_state::update_interrupts() void beathead_state::interrupt_control_w(offs_t offset, uint32_t data) { - int irq = offset & 3; - int control = (offset >> 2) & 1; + int const irq = offset & 3; + int const control = (offset >> 2) & 1; - /* offsets 1-3 seem to be the enable latches for the IRQs */ + // offsets 1-3 seem to be the enable latches for the IRQs if (irq != 0) m_irq_enable[irq - 1] = control; - /* offset 0 seems to be the interrupt ack */ + // offset 0 seems to be the interrupt ack else m_irq_state[0] = m_irq_state[1] = m_irq_state[2] = 0; - /* update the current state */ + // update the current state update_interrupts(); } uint32_t beathead_state::interrupt_control_r() { - /* return the enables as a bitfield */ + // return the enables as a bitfield return (m_irq_enable[0]) | (m_irq_enable[1] << 1) | (m_irq_enable[2] << 2); } @@ -248,8 +496,8 @@ void beathead_state::coin_count_w(offs_t offset, uint32_t data) void beathead_state::main_map(address_map &map) { - map(0x00000000, 0x0001ffff).ram().share("ram_base"); - map(0x01800000, 0x01bfffff).rom().region("user1", 0); + map(0x00000000, 0x0001ffff).ram().share(m_ram_base); + map(0x01800000, 0x01bfffff).rom().region("maincpu", 0); map(0x40000000, 0x400007ff).rw("eeprom", FUNC(eeprom_parallel_28xx_device::read), FUNC(eeprom_parallel_28xx_device::write)).umask32(0x000000ff); map(0x41000000, 0x41000000).rw(m_jsa, FUNC(atari_jsa_iii_device::main_response_r), FUNC(atari_jsa_iii_device::main_command_w)); map(0x41000100, 0x41000103).r(FUNC(beathead_state::interrupt_control_r)); @@ -260,18 +508,18 @@ void beathead_state::main_map(address_map &map) map(0x41000220, 0x41000227).w(FUNC(beathead_state::coin_count_w)); map(0x41000300, 0x41000303).portr("IN2"); map(0x41000304, 0x41000307).portr("IN3"); - map(0x41000400, 0x41000403).writeonly().share("palette_select"); + map(0x41000400, 0x41000403).writeonly().share(m_palette_select); map(0x41000500, 0x41000500).w("eeprom", FUNC(eeprom_parallel_28xx_device::unlock_write8)); map(0x41000600, 0x41000603).w(FUNC(beathead_state::finescroll_w)); map(0x41000700, 0x41000703).w("watchdog", FUNC(watchdog_timer_device::reset32_w)); map(0x42000000, 0x4201ffff).rw(m_palette, FUNC(palette_device::read16), FUNC(palette_device::write16)).umask32(0x0000ffff).share("palette"); map(0x43000000, 0x43000007).rw(FUNC(beathead_state::hsync_ram_r), FUNC(beathead_state::hsync_ram_w)); - map(0x8df80000, 0x8df80003).nopr(); /* noisy x4 during scanline int */ + map(0x8df80000, 0x8df80003).nopr(); // noisy x4 during scanline int map(0x8f380000, 0x8f3fffff).w(FUNC(beathead_state::vram_latch_w)); map(0x8f900000, 0x8f97ffff).w(FUNC(beathead_state::vram_transparent_w)); - map(0x8f980000, 0x8f9fffff).ram().share("videoram"); + map(0x8f980000, 0x8f9fffff).ram().share(m_videoram); map(0x8fb80000, 0x8fbfffff).w(FUNC(beathead_state::vram_bulk_w)); - map(0x8fff8000, 0x8fff8003).writeonly().share("vram_bulk_latch"); + map(0x8fff8000, 0x8fff8003).writeonly().share(m_vram_bulk_latch); map(0x9e280000, 0x9e2fffff).w(FUNC(beathead_state::vram_copy_w)); } @@ -284,7 +532,7 @@ void beathead_state::main_map(address_map &map) *************************************/ static INPUT_PORTS_START( beathead ) - PORT_START("IN0") /* Player 1 */ + PORT_START("IN0") // Player 1 PORT_BIT( 0x00ff, IP_ACTIVE_LOW, IPT_UNUSED ) PORT_BIT( 0x0100, IP_ACTIVE_LOW, IPT_BUTTON2 ) PORT_PLAYER(1) PORT_BIT( 0x0200, IP_ACTIVE_LOW, IPT_BUTTON1 ) PORT_PLAYER(1) @@ -295,7 +543,7 @@ static INPUT_PORTS_START( beathead ) 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("IN1") /* Player 2 */ + PORT_START("IN1") // Player 2 PORT_BIT( 0x0001, IP_ACTIVE_LOW, IPT_BUTTON2 ) PORT_PLAYER(2) PORT_BIT( 0x0002, IP_ACTIVE_LOW, IPT_BUTTON1 ) PORT_PLAYER(2) PORT_BIT( 0x0004, IP_ACTIVE_LOW, IPT_UNUSED ) @@ -335,7 +583,7 @@ INPUT_PORTS_END void beathead_state::beathead(machine_config &config) { - /* basic machine hardware */ + // basic machine hardware ASAP(config, m_maincpu, 14.318181_MHz_XTAL); m_maincpu->set_addrmap(AS_PROGRAM, &beathead_state::main_map); @@ -345,7 +593,7 @@ void beathead_state::beathead(machine_config &config) TIMER(config, m_scan_timer).configure_generic(FUNC(beathead_state::scanline_callback)); - /* video hardware */ + // video hardware SCREEN(config, m_screen, SCREEN_TYPE_RASTER); m_screen->set_video_attributes(VIDEO_UPDATE_BEFORE_VBLANK); m_screen->set_refresh_hz(60); @@ -358,7 +606,7 @@ void beathead_state::beathead(machine_config &config) m_palette->set_format(palette_device::IRGB_1555, 32768); m_palette->set_membits(16); - /* sound hardware */ + // sound hardware SPEAKER(config, "mono").front_center(); ATARI_JSA_III(config, m_jsa, 0); @@ -375,10 +623,10 @@ void beathead_state::beathead(machine_config &config) *************************************/ ROM_START( beathead ) - ROM_REGION( 0x10000, "jsa:cpu", 0 ) /* 64k for 6502 code */ + ROM_REGION( 0x10000, "jsa:cpu", 0 ) // 6502 code ROM_LOAD( "bhsnd.bin", 0x00000, 0x10000, CRC(dfd33f02) SHA1(479a4838c89691d5a4654a4cd84b6433a9e86109) ) - ROM_REGION32_LE( 0x400000, "user1", 0 ) /* 4MB for ASAP code */ + ROM_REGION32_LE( 0x400000, "maincpu", 0 ) // ASAP code ROM_LOAD32_BYTE( "bhprog0.bin", 0x000000, 0x80000, CRC(87975721) SHA1(862cb3a290c829aedea26ee7100c50a12e9517e7) ) ROM_LOAD32_BYTE( "bhprog1.bin", 0x000001, 0x80000, CRC(25d89743) SHA1(9ff9a41355aa6914efc4a44909026e648a3c40f3) ) ROM_LOAD32_BYTE( "bhprog2.bin", 0x000002, 0x80000, CRC(87722609) SHA1(dbd766fa57f4528702a98db28ae48fb5d2a7f7df) ) @@ -388,13 +636,14 @@ ROM_START( beathead ) ROM_LOAD32_BYTE( "bhpics2.bin", 0x200002, 0x80000, CRC(00b96481) SHA1(39daa46321c1d4f8bce8c25d0450b97f1f19dedb) ) ROM_LOAD32_BYTE( "bhpics3.bin", 0x200003, 0x80000, CRC(99c4f1db) SHA1(aba4440c5cdf413f970a0c65457e2d1b37caf2d6) ) - ROM_REGION( 0x80000, "jsa:oki1", 0 ) /* 1MB for ADPCM */ + ROM_REGION( 0x80000, "jsa:oki1", 0 ) // ADPCM ROM_LOAD( "bhpcm0.bin", 0x00000, 0x20000, CRC(609ca626) SHA1(9bfc913fc4c3453b132595f8553245376bce3a51) ) ROM_LOAD( "bhpcm1.bin", 0x20000, 0x20000, CRC(35511509) SHA1(41294b81e253db5d2f30f8589dd59729a31bb2bb) ) ROM_LOAD( "bhpcm2.bin", 0x40000, 0x20000, CRC(f71a840a) SHA1(09d045552704cd1434307f9a36ce03c5c06a8ff6) ) ROM_LOAD( "bhpcm3.bin", 0x60000, 0x20000, CRC(fedd4936) SHA1(430ed894fa4bfcd56ee5a8a8ef5e161246530e2d) ) ROM_END +} // anonymous namespace /************************************* @@ -403,4 +652,4 @@ ROM_END * *************************************/ -GAME( 1993, beathead, 0, beathead, beathead, beathead_state, empty_init, ROT0, "Atari Games", "BeatHead (prototype)", 0 ) +GAME( 1993, beathead, 0, beathead, beathead, beathead_state, empty_init, ROT0, "Atari Games", "BeatHead (prototype)", MACHINE_SUPPORTS_SAVE ) diff --git a/src/mame/atari/beathead.h b/src/mame/atari/beathead.h deleted file mode 100644 index 95eb3b931fc..00000000000 --- a/src/mame/atari/beathead.h +++ /dev/null @@ -1,92 +0,0 @@ -// license:BSD-3-Clause -// copyright-holders:Aaron Giles -/*************************************************************************** - - Atari "Stella on Steroids" hardware - -***************************************************************************/ -#ifndef MAME_ATARI_BEATHEAD_H -#define MAME_ATARI_BEATHEAD_H - -#pragma once - -#include "machine/timer.h" -#include "cpu/asap/asap.h" -#include "atarijsa.h" -#include "emupal.h" -#include "screen.h" - -class beathead_state : public driver_device -{ -public: - beathead_state(const machine_config &mconfig, device_type type, const char *tag) : - driver_device(mconfig, type, tag), - m_maincpu(*this, "maincpu"), - m_palette(*this, "palette"), - m_screen(*this, "screen"), - m_jsa(*this, "jsa"), - m_scan_timer(*this, "scan_timer"), - m_videoram(*this, "videoram"), - m_vram_bulk_latch(*this, "vram_bulk_latch"), - m_palette_select(*this, "palette_select"), - m_ram_base(*this, "ram_base"), - m_rom_base(*this, "user1") - { } - - void beathead(machine_config &config); - -protected: - // in drivers/beathead.cpp - void update_interrupts(); - void interrupt_control_w(offs_t offset, uint32_t data); - uint32_t interrupt_control_r(); - void sound_reset_w(offs_t offset, uint32_t data); - void coin_count_w(offs_t offset, uint32_t data); - - // in video/beathead.cpp - void vram_transparent_w(offs_t offset, uint32_t data, uint32_t mem_mask = ~0); - void vram_bulk_w(offs_t offset, uint32_t data, uint32_t mem_mask = ~0); - void vram_latch_w(offs_t offset, uint32_t data); - void vram_copy_w(offs_t offset, uint32_t data); - void finescroll_w(offs_t offset, uint32_t data, uint32_t mem_mask = ~0); - uint32_t hsync_ram_r(offs_t offset); - void hsync_ram_w(offs_t offset, uint32_t data, uint32_t mem_mask = ~0); - TIMER_DEVICE_CALLBACK_MEMBER(scanline_callback); - - virtual void machine_reset() override; - virtual void video_start() override; - void main_map(address_map &map); - - uint32_t screen_update(screen_device &screen, bitmap_ind16 &bitmap, const rectangle &cliprect); - -private: - required_device m_maincpu; - required_device m_palette; - required_device m_screen; - - required_device m_jsa; - required_device m_scan_timer; - - required_shared_ptr m_videoram; - - required_shared_ptr m_vram_bulk_latch; - required_shared_ptr m_palette_select; - - uint32_t m_finescroll = 0U; - offs_t m_vram_latch_offset = 0U; - - offs_t m_hsyncram_offset = 0U; - offs_t m_hsyncram_start = 0U; - uint8_t m_hsyncram[0x800]{}; - - required_shared_ptr m_ram_base; - required_region_ptr m_rom_base; - - attotime m_hblank_offset; - - uint8_t m_irq_line_state = 0U; - uint8_t m_irq_enable[3]{}; - uint8_t m_irq_state[3]{}; -}; - -#endif // MAME_ATARI_BEATHEAD_H diff --git a/src/mame/atari/beathead_v.cpp b/src/mame/atari/beathead_v.cpp deleted file mode 100644 index 581c8b80a56..00000000000 --- a/src/mame/atari/beathead_v.cpp +++ /dev/null @@ -1,175 +0,0 @@ -// license:BSD-3-Clause -// copyright-holders:Aaron Giles -/*************************************************************************** - - Atari "Stella on Steroids" hardware - -****************************************************************************/ - -#include "emu.h" -#include "beathead.h" - - - -/************************************* - * - * Video start/stop - * - *************************************/ - -void beathead_state::video_start() -{ - save_item(NAME(m_finescroll)); - save_item(NAME(m_vram_latch_offset)); - save_item(NAME(m_hsyncram_offset)); - save_item(NAME(m_hsyncram_start)); - save_item(NAME(m_hsyncram)); - - m_hsyncram_offset = 0; -} - - - -/************************************* - * - * VRAM handling - * - *************************************/ - -void beathead_state::vram_transparent_w(offs_t offset, uint32_t data, uint32_t mem_mask) -{ - /* writes to this area appear to handle transparency */ - if (!(data & 0x000000ff)) mem_mask &= ~0x000000ff; - if (!(data & 0x0000ff00)) mem_mask &= ~0x0000ff00; - if (!(data & 0x00ff0000)) mem_mask &= ~0x00ff0000; - if (!(data & 0xff000000)) mem_mask &= ~0xff000000; - COMBINE_DATA(&m_videoram[offset]); -} - - -void beathead_state::vram_bulk_w(offs_t offset, uint32_t data, uint32_t mem_mask) -{ - /* it appears that writes to this area pass in a mask for 4 words in VRAM */ - /* allowing them to be filled from a preset latch */ - offset &= ~3; - data = data & mem_mask & 0x0f0f0f0f; - - /* for now, just handle the bulk fill case; the others we'll catch later */ - if (data == 0x0f0f0f0f) - m_videoram[offset+0] = m_videoram[offset+1] = m_videoram[offset+2] = m_videoram[offset+3] = *m_vram_bulk_latch; - else - logerror("Detected bulk VRAM write with mask %08x\n", data); -} - - -void beathead_state::vram_latch_w(offs_t offset, uint32_t data) -{ - /* latch the address */ - m_vram_latch_offset = (4 * offset) & 0x7ffff; -} - - -void beathead_state::vram_copy_w(offs_t offset, uint32_t data) -{ - /* copy from VRAM to VRAM, for 1024 bytes */ - offs_t dest_offset = (4 * offset) & 0x7ffff; - memcpy(&m_videoram[dest_offset / 4], &m_videoram[m_vram_latch_offset / 4], 0x400); -} - - - -/************************************* - * - * Scroll offset handling - * - *************************************/ - -void beathead_state::finescroll_w(offs_t offset, uint32_t data, uint32_t mem_mask) -{ - uint32_t oldword = m_finescroll; - uint32_t newword = COMBINE_DATA(&m_finescroll); - - /* if VBLANK is going off on a scanline other than the last, suspend time */ - if ((oldword & 8) && !(newword & 8) && m_screen->vpos() != 261) - { - logerror("Suspending time! (scanline = %d)\n", m_screen->vpos()); - m_maincpu->set_input_line(INPUT_LINE_HALT, ASSERT_LINE); - } -} - - - -/************************************* - * - * HSYNC RAM handling - * - *************************************/ - -uint32_t beathead_state::hsync_ram_r(offs_t offset) -{ - /* offset 0 is probably write-only */ - if (offset == 0) - logerror("%08X:Unexpected HSYNC RAM read at offset 0\n", m_maincpu->pcbase()); - - /* offset 1 reads the data */ - else - return m_hsyncram[m_hsyncram_offset]; - - return 0; -} - -void beathead_state::hsync_ram_w(offs_t offset, uint32_t data, uint32_t mem_mask) -{ - /* offset 0 selects the address, and can specify the start address */ - if (offset == 0) - { - COMBINE_DATA(&m_hsyncram_offset); - if (m_hsyncram_offset & 0x800) - m_hsyncram_start = m_hsyncram_offset & 0x7ff; - } - - /* offset 1 writes the data */ - else - COMBINE_DATA(&m_hsyncram[m_hsyncram_offset]); -} - - - -/************************************* - * - * Main screen refresher - * - *************************************/ - -uint32_t beathead_state::screen_update(screen_device &screen, bitmap_ind16 &bitmap, const rectangle &cliprect) -{ - const auto videoram = util::little_endian_cast(m_videoram.target()); - - // generate the final screen - for (int y = cliprect.top(); y <= cliprect.bottom(); y++) - { - const pen_t pen_base = (*m_palette_select & 0x7f) * 256; - uint16_t scanline[336]; - - if (m_finescroll & 8) - { - // blanking - for (int x = cliprect.left(); x <= cliprect.right(); x++) - scanline[x] = pen_base; - } - else - { - // non-blanking - const offs_t scanline_offset = m_vram_latch_offset + (m_finescroll & 3); - offs_t src = scanline_offset + cliprect.left(); - - // unswizzle the scanline first - for (int x = cliprect.left(); x <= cliprect.right(); x++) - scanline[x] = pen_base | videoram[src++]; - } - - // then draw it - draw_scanline16(bitmap, cliprect.left(), y, cliprect.width(), &scanline[cliprect.left()], nullptr); - } - return 0; -} diff --git a/src/mame/atari/blstroid.cpp b/src/mame/atari/blstroid.cpp index 82006e7e2a8..04a5ba0a7f8 100644 --- a/src/mame/atari/blstroid.cpp +++ b/src/mame/atari/blstroid.cpp @@ -1,5 +1,6 @@ // license:BSD-3-Clause -// copyright-holders:Aaron Giles +// copyright-holders: Aaron Giles + /*************************************************************************** Atari Blasteroids hardware @@ -20,15 +21,219 @@ #include "emu.h" -#include "blstroid.h" + +#include "atarigen.h" +#include "atarijsa.h" +#include "atarimo.h" #include "cpu/m68000/m68000.h" #include "machine/eeprompar.h" +#include "machine/timer.h" #include "machine/watchdog.h" + #include "emupal.h" #include "speaker.h" +#include "tilemap.h" + + +namespace { + +class blstroid_state : public atarigen_state +{ +public: + blstroid_state(const machine_config &mconfig, device_type type, const char *tag) : + atarigen_state(mconfig, type, tag), + m_playfield_tilemap(*this, "playfield"), + m_jsa(*this, "jsa"), + m_mob(*this, "mob"), + m_priorityram(*this, "priorityram") + { } + + void blstroid(machine_config &config); + +protected: + virtual void machine_reset() override; + virtual void video_start() override; + +private: + TIMER_CALLBACK_MEMBER(irq_off); + TIMER_CALLBACK_MEMBER(irq_on); + TIMER_DEVICE_CALLBACK_MEMBER(scanline_update); + void scanline_int_ack_w(uint16_t data = 0); + void video_int_ack_w(uint16_t data = 0); + void halt_until_hblank_0_w(uint16_t data = 0); + 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 m_playfield_tilemap; + required_device m_jsa; + required_device m_mob; + required_shared_ptr m_priorityram; + + emu_timer *m_irq_off_timer = nullptr; + emu_timer *m_irq_on_timer = nullptr; + + static const atari_motion_objects_config s_mob_config; + + bool m_scanline_int_state = false; +}; + + +// video + +/************************************* + * + * Tilemap callbacks + * + *************************************/ + +TILE_GET_INFO_MEMBER(blstroid_state::get_playfield_tile_info) +{ + uint16_t const data = m_playfield_tilemap->basemem_read(tile_index); + int const code = data & 0x1fff; + int const color = (data >> 13) & 0x07; + tileinfo.set(0, code, color, 0); +} + + + +/************************************* + * + * Video system start + * + *************************************/ + +const atari_motion_objects_config blstroid_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? + 0, // 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 + + {{ 0,0,0x0ff8,0 }}, // mask for the link + {{ 0,0x3fff,0,0 }}, // mask for the code index + {{ 0,0,0,0x000f }}, // mask for the color + {{ 0,0,0,0xffc0 }}, // mask for the X position + {{ 0xff80,0,0,0 }}, // mask for the Y position + {{ 0 }}, // mask for the width, in tiles + {{ 0x000f,0,0,0 }}, // mask for the height, in tiles + {{ 0,0x8000,0,0 }}, // mask for the horizontal flip + {{ 0,0x4000,0,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 blstroid_state::video_start() +{ + m_irq_off_timer = timer_alloc(FUNC(blstroid_state::irq_off), this); + m_irq_on_timer = timer_alloc(FUNC(blstroid_state::irq_on), this); + + m_scanline_int_state = false; + + save_item(NAME(m_scanline_int_state)); +} + + + +/************************************* + * + * Periodic scanline updater + * + *************************************/ + +TIMER_CALLBACK_MEMBER(blstroid_state::irq_off) +{ + m_maincpu->set_input_line(M68K_IRQ_1, CLEAR_LINE); +} + +TIMER_CALLBACK_MEMBER(blstroid_state::irq_on) +{ + m_maincpu->set_input_line(M68K_IRQ_1, ASSERT_LINE); +} + + +TIMER_DEVICE_CALLBACK_MEMBER(blstroid_state::scanline_update) +{ + int const scanline = param; + int const offset = (scanline / 8) * 64 + 40; + + // check for interrupts + if (offset < 0x800) + if (m_playfield_tilemap->basemem_read(offset) & 0x8000) + { + // FIXME: - the only thing this IRQ does it tweak the starting MO link + // unfortunately, it does it too early for the given MOs! + // perhaps it is not actually hooked up on the real PCB... + return; + + // set a timer to turn the interrupt on at HBLANK of the 7th scanline + // and another to turn it off one scanline later + int const width = m_screen->width(); + int const vpos = m_screen->vpos(); + attotime const period_on = m_screen->time_until_pos(vpos + 7, width * 0.9); + attotime const period_off = m_screen->time_until_pos(vpos + 8, width * 0.9); + + m_irq_on_timer->adjust(period_on); + m_irq_off_timer->adjust(period_off); + } +} + + + +/************************************* + * + * Main refresh + * + *************************************/ + +uint32_t blstroid_state::screen_update(screen_device &screen, bitmap_ind16 &bitmap, const rectangle &cliprect) +{ + // start drawing + m_mob->draw_async(cliprect); + + // draw the playfield + m_playfield_tilemap->draw(screen, bitmap, cliprect, 0, 0); + + // draw and merge the MO + bitmap_ind16 &mobitmap = m_mob->bitmap(); + for (const sparse_dirty_rect *rect = m_mob->first_dirty_rect(cliprect); rect != nullptr; rect = rect->next()) + for (int y = rect->top(); y <= rect->bottom(); y++) + { + uint16_t const *const mo = &mobitmap.pix(y); + uint16_t *const pf = &bitmap.pix(y); + for (int x = rect->left(); x <= rect->right(); x++) + if (mo[x] != 0xffff) + { + /* verified via schematics + + priority address = HPPPMMMM + */ + int const priaddr = ((pf[x] & 8) << 4) | (pf[x] & 0x70) | ((mo[x] & 0xf0) >> 4); + if (m_priorityram[priaddr] & 1) + pf[x] = mo[x]; + } + } + return 0; +} +// machine /************************************* * @@ -67,7 +272,7 @@ void blstroid_state::machine_reset() * *************************************/ -/* full map verified from schematics */ +// full map verified from schematics void blstroid_state::main_map(address_map &map) { map.unmap_value_high(); @@ -77,7 +282,7 @@ void blstroid_state::main_map(address_map &map) map(0x800200, 0x800201).mirror(0x0381fe).w(FUNC(blstroid_state::scanline_int_ack_w)); map(0x800400, 0x800401).mirror(0x0381fe).w(FUNC(blstroid_state::video_int_ack_w)); map(0x800600, 0x800601).mirror(0x0381fe).w("eeprom", FUNC(eeprom_parallel_28xx_device::unlock_write16)); - map(0x800800, 0x8009ff).mirror(0x038000).writeonly().share("priorityram"); + map(0x800800, 0x8009ff).mirror(0x038000).writeonly().share(m_priorityram); map(0x800a01, 0x800a01).mirror(0x0381fe).w(m_jsa, FUNC(atari_jsa_i_device::main_command_w)); map(0x800c00, 0x800c01).mirror(0x0381fe).w(m_jsa, FUNC(atari_jsa_i_device::sound_reset_w)); map(0x800e00, 0x800e01).mirror(0x0381fe).w(FUNC(blstroid_state::halt_until_hblank_0_w)); @@ -102,15 +307,15 @@ void blstroid_state::main_map(address_map &map) *************************************/ static INPUT_PORTS_START( blstroid ) - PORT_START("DIAL0") /* ff9800 */ + PORT_START("DIAL0") // ff9800 PORT_BIT( 0x00ff, 0, IPT_DIAL ) PORT_SENSITIVITY(60) PORT_KEYDELTA(10) PORT_PLAYER(1) PORT_BIT( 0xff00, IP_ACTIVE_LOW, IPT_UNUSED ) - PORT_START("DIAL1") /* ff9804 */ + PORT_START("DIAL1") // ff9804 PORT_BIT( 0x00ff, 0, IPT_DIAL ) PORT_SENSITIVITY(60) PORT_KEYDELTA(10) PORT_PLAYER(2) PORT_BIT( 0xff00, IP_ACTIVE_LOW, IPT_UNUSED ) - PORT_START("IN0") /* ff9c00 */ + PORT_START("IN0") // ff9c00 PORT_BIT( 0x0001, IP_ACTIVE_LOW, IPT_BUTTON1 ) PORT_PLAYER(1) PORT_BIT( 0x0002, IP_ACTIVE_LOW, IPT_BUTTON2 ) PORT_PLAYER(1) PORT_BIT( 0x0004, IP_ACTIVE_LOW, IPT_BUTTON3 ) PORT_PLAYER(1) @@ -121,7 +326,7 @@ static INPUT_PORTS_START( blstroid ) PORT_SERVICE( 0x0080, IP_ACTIVE_LOW ) PORT_BIT( 0xff00, IP_ACTIVE_LOW, IPT_UNUSED ) - PORT_START("IN1") /* ff9c02 */ + PORT_START("IN1") // ff9c02 PORT_BIT( 0x0001, IP_ACTIVE_LOW, IPT_BUTTON1 ) PORT_PLAYER(2) PORT_BIT( 0x0002, IP_ACTIVE_LOW, IPT_BUTTON2 ) PORT_PLAYER(2) PORT_BIT( 0x0004, IP_ACTIVE_LOW, IPT_BUTTON3 ) PORT_PLAYER(2) @@ -167,8 +372,8 @@ static const gfx_layout molayout = static GFXDECODE_START( gfx_blstroid ) - GFXDECODE_ENTRY( "gfx1", 0, pflayout, 256, 16 ) - GFXDECODE_ENTRY( "gfx2", 0, molayout, 0, 16 ) + GFXDECODE_ENTRY( "tiles", 0, pflayout, 256, 16 ) + GFXDECODE_ENTRY( "sprites", 0, molayout, 0, 16 ) GFXDECODE_END @@ -181,8 +386,8 @@ GFXDECODE_END void blstroid_state::blstroid(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, &blstroid_state::main_map); EEPROM_2804(config, "eeprom").lock_after_write(true); @@ -191,7 +396,7 @@ void blstroid_state::blstroid(machine_config &config) WATCHDOG_TIMER(config, "watchdog"); - /* video hardware */ + // video hardware GFXDECODE(config, "gfxdecode", "palette", gfx_blstroid); PALETTE(config, "palette").set_format(palette_device::xRGB_555, 512); @@ -203,14 +408,14 @@ void blstroid_state::blstroid(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 */ + // note: these parameters are from published specs, not derived + // the board uses an SOS-2 chip to generate video signals m_screen->set_raw(14.318181_MHz_XTAL, 456*2, 0, 320*2, 262, 0, 240); - m_screen->set_screen_update(FUNC(blstroid_state::screen_update_blstroid)); + m_screen->set_screen_update(FUNC(blstroid_state::screen_update)); m_screen->set_palette("palette"); m_screen->screen_vblank().set_inputline(m_maincpu, M68K_IRQ_2, ASSERT_LINE); - /* sound hardware */ + // sound hardware SPEAKER(config, "lspeaker").front_left(); SPEAKER(config, "rspeaker").front_right(); @@ -232,22 +437,22 @@ void blstroid_state::blstroid(machine_config &config) *************************************/ ROM_START( blstroid ) - ROM_REGION( 0x40000, "maincpu", 0 ) /* 4*64k for 68000 code */ + ROM_REGION( 0x40000, "maincpu", 0 ) // 68000 code ROM_LOAD16_BYTE( "136057-4123.6c", 0x000000, 0x010000, CRC(d14badc4) SHA1(ccba30e1eb6b3351cbc7ea18951debb7f7aa4520) ) ROM_LOAD16_BYTE( "136057-4121.6b", 0x000001, 0x010000, CRC(ae3e93e8) SHA1(66ccff68e9b0f7e97abf126f977775e29ce4eee5) ) ROM_LOAD16_BYTE( "136057-4124.4c", 0x020000, 0x010000, CRC(fd2365df) SHA1(63ed3f9a92fed985f9ddb93687f11a24c8309f56) ) ROM_LOAD16_BYTE( "136057-4122.4b", 0x020001, 0x010000, CRC(c364706e) SHA1(e03cd60d139000607d83240b0b48865eafb1188b) ) - ROM_REGION( 0x10000, "jsa:cpu", 0 ) /* 64k for 6502 code */ + ROM_REGION( 0x10000, "jsa:cpu", 0 ) // 6502 code ROM_LOAD( "136057-1135.2k", 0x00000, 0x10000, CRC(baa8b5fe) SHA1(4af1f9bec3ffa856016a89bc20041d572305ba3a) ) - ROM_REGION( 0x040000, "gfx1", 0 ) + ROM_REGION( 0x040000, "tiles", 0 ) ROM_LOAD( "136057-1101.1l", 0x000000, 0x010000, CRC(3c2daa5b) SHA1(2710a05e95afd8452104c4f4a9250a3b7d728a42) ) ROM_LOAD( "136057-1102.1m", 0x010000, 0x010000, CRC(f84f0b97) SHA1(00cb5f1e0f92742683ee71854085b1e4db4bd6bb) ) ROM_LOAD( "136057-1103.3l", 0x020000, 0x010000, CRC(ae5274f0) SHA1(87070e6e51d557c1b10ef32ac0ed670856d5aaf1) ) ROM_LOAD( "136057-1104.3m", 0x030000, 0x010000, CRC(4bb72060) SHA1(94cd1a6900f47a5178cec041fa6dc9cfee1f9c3f) ) - ROM_REGION( 0x100000, "gfx2", 0 ) + ROM_REGION( 0x100000, "sprites", 0 ) ROM_LOAD( "136057-1105.5m", 0x000000, 0x010000, CRC(50e0823f) SHA1(f638becad83307ed43d138d452199e4c6725512f) ) ROM_LOAD( "136057-1107.67m", 0x010000, 0x010000, CRC(729de7a9) SHA1(526b08e6d54cd0b991c4207c23119d2940a34009) ) ROM_LOAD( "136057-1109.8m", 0x020000, 0x010000, CRC(090e42ab) SHA1(903aa99e6e39407319f6e90102b24604884ee047) ) @@ -268,22 +473,22 @@ ROM_END ROM_START( blstroid3 ) - ROM_REGION( 0x40000, "maincpu", 0 ) /* 4*64k for 68000 code */ + ROM_REGION( 0x40000, "maincpu", 0 ) // 68000 code ROM_LOAD16_BYTE( "136057-3123.6c", 0x000000, 0x010000, CRC(8fb050f5) SHA1(4944ffb0843262afe41fc6b876ab6858dcefc95f) ) ROM_LOAD16_BYTE( "136057-3121.6b", 0x000001, 0x010000, CRC(21fae262) SHA1(2516a75d76bcfdea5ab41a4898d47ed166bd1996) ) ROM_LOAD16_BYTE( "136057-3124.4c", 0x020000, 0x010000, CRC(a9140c31) SHA1(02518bf998c0c74dff66f3192dcb1f91b1812cf8) ) ROM_LOAD16_BYTE( "136057-3122.4b", 0x020001, 0x010000, CRC(137fbb17) SHA1(3dda03ecdb2dc9a9cd78aeaa502497662496a26d) ) - ROM_REGION( 0x10000, "jsa:cpu", 0 ) /* 64k for 6502 code */ + ROM_REGION( 0x10000, "jsa:cpu", 0 ) // 6502 code ROM_LOAD( "136057-1135.2k", 0x00000, 0x10000, CRC(baa8b5fe) SHA1(4af1f9bec3ffa856016a89bc20041d572305ba3a) ) - ROM_REGION( 0x040000, "gfx1", 0 ) + ROM_REGION( 0x040000, "tiles", 0 ) ROM_LOAD( "136057-1101.1l", 0x000000, 0x010000, CRC(3c2daa5b) SHA1(2710a05e95afd8452104c4f4a9250a3b7d728a42) ) ROM_LOAD( "136057-1102.1m", 0x010000, 0x010000, CRC(f84f0b97) SHA1(00cb5f1e0f92742683ee71854085b1e4db4bd6bb) ) ROM_LOAD( "136057-1103.3l", 0x020000, 0x010000, CRC(ae5274f0) SHA1(87070e6e51d557c1b10ef32ac0ed670856d5aaf1) ) ROM_LOAD( "136057-1104.3m", 0x030000, 0x010000, CRC(4bb72060) SHA1(94cd1a6900f47a5178cec041fa6dc9cfee1f9c3f) ) - ROM_REGION( 0x100000, "gfx2", 0 ) + ROM_REGION( 0x100000, "sprites", 0 ) ROM_LOAD( "136057-1105.5m", 0x000000, 0x010000, CRC(50e0823f) SHA1(f638becad83307ed43d138d452199e4c6725512f) ) ROM_LOAD( "136057-1107.67m", 0x010000, 0x010000, CRC(729de7a9) SHA1(526b08e6d54cd0b991c4207c23119d2940a34009) ) ROM_LOAD( "136057-1109.8m", 0x020000, 0x010000, CRC(090e42ab) SHA1(903aa99e6e39407319f6e90102b24604884ee047) ) @@ -304,22 +509,22 @@ ROM_END ROM_START( blstroid2 ) - ROM_REGION( 0x40000, "maincpu", 0 ) /* 4*64k for 68000 code */ + ROM_REGION( 0x40000, "maincpu", 0 ) // 68000 code ROM_LOAD16_BYTE( "136057-2123.6c", 0x000000, 0x010000, CRC(5a092513) SHA1(11396125842ea3a43d61b4ce266bb8053fdefd73) ) ROM_LOAD16_BYTE( "136057-2121.6b", 0x000001, 0x010000, CRC(486aac51) SHA1(5e7fe7eb225d1c2701c21658ba2bad14ef7b64b1) ) ROM_LOAD16_BYTE( "136057-2124.4c", 0x020000, 0x010000, CRC(d0fa38fe) SHA1(8aeae50dff6bcd14ac5faf10f15724b7f7430f5c) ) ROM_LOAD16_BYTE( "136057-2122.4b", 0x020001, 0x010000, CRC(744bf921) SHA1(bb9118bfc04745df2eb78e1d1e70f7fc2e0509d4) ) - ROM_REGION( 0x10000, "jsa:cpu", 0 ) /* 64k for 6502 code */ + ROM_REGION( 0x10000, "jsa:cpu", 0 ) // 6502 code ROM_LOAD( "136057-1135.2k", 0x00000, 0x10000, CRC(baa8b5fe) SHA1(4af1f9bec3ffa856016a89bc20041d572305ba3a) ) - ROM_REGION( 0x040000, "gfx1", 0 ) + ROM_REGION( 0x040000, "tiles", 0 ) ROM_LOAD( "136057-1101.1l", 0x000000, 0x010000, CRC(3c2daa5b) SHA1(2710a05e95afd8452104c4f4a9250a3b7d728a42) ) ROM_LOAD( "136057-1102.1m", 0x010000, 0x010000, CRC(f84f0b97) SHA1(00cb5f1e0f92742683ee71854085b1e4db4bd6bb) ) ROM_LOAD( "136057-1103.3l", 0x020000, 0x010000, CRC(ae5274f0) SHA1(87070e6e51d557c1b10ef32ac0ed670856d5aaf1) ) ROM_LOAD( "136057-1104.3m", 0x030000, 0x010000, CRC(4bb72060) SHA1(94cd1a6900f47a5178cec041fa6dc9cfee1f9c3f) ) - ROM_REGION( 0x100000, "gfx2", 0 ) + ROM_REGION( 0x100000, "sprites", 0 ) ROM_LOAD( "136057-1105.5m", 0x000000, 0x010000, CRC(50e0823f) SHA1(f638becad83307ed43d138d452199e4c6725512f) ) ROM_LOAD( "136057-1107.67m", 0x010000, 0x010000, CRC(729de7a9) SHA1(526b08e6d54cd0b991c4207c23119d2940a34009) ) ROM_LOAD( "136057-1109.8m", 0x020000, 0x010000, CRC(090e42ab) SHA1(903aa99e6e39407319f6e90102b24604884ee047) ) @@ -340,22 +545,22 @@ ROM_END ROM_START( blstroidg ) - ROM_REGION( 0x40000, "maincpu", 0 ) /* 4*64k for 68000 code */ + ROM_REGION( 0x40000, "maincpu", 0 ) // 68000 code ROM_LOAD16_BYTE( "136057-2223.6c", 0x000000, 0x010000, CRC(cc82108b) SHA1(487a80cac2a196e9b17c64c5d0b884d1ed8da401) ) ROM_LOAD16_BYTE( "136057-2221.6b", 0x000001, 0x010000, CRC(84822e68) SHA1(763edc9b3605e583506ca1d9befab66411fc720a) ) ROM_LOAD16_BYTE( "136057-2224.4c", 0x020000, 0x010000, CRC(849249d4) SHA1(61d6eaff7df54f0353639e192eb6074a80916e29) ) ROM_LOAD16_BYTE( "136057-2222.4b", 0x020001, 0x010000, CRC(bdeaba0d) SHA1(f479514b5d9543f9e12aa1ac48e20bf054cb18d0) ) - ROM_REGION( 0x10000, "jsa:cpu", 0 ) /* 64k for 6502 code */ + ROM_REGION( 0x10000, "jsa:cpu", 0 ) // 6502 code ROM_LOAD( "136057-1135.2k", 0x00000, 0x10000, CRC(baa8b5fe) SHA1(4af1f9bec3ffa856016a89bc20041d572305ba3a) ) - ROM_REGION( 0x040000, "gfx1", 0 ) + ROM_REGION( 0x040000, "tiles", 0 ) ROM_LOAD( "136057-1101.1l", 0x000000, 0x010000, CRC(3c2daa5b) SHA1(2710a05e95afd8452104c4f4a9250a3b7d728a42) ) ROM_LOAD( "136057-1102.1m", 0x010000, 0x010000, CRC(f84f0b97) SHA1(00cb5f1e0f92742683ee71854085b1e4db4bd6bb) ) ROM_LOAD( "136057-1103.3l", 0x020000, 0x010000, CRC(ae5274f0) SHA1(87070e6e51d557c1b10ef32ac0ed670856d5aaf1) ) ROM_LOAD( "136057-1104.3m", 0x030000, 0x010000, CRC(4bb72060) SHA1(94cd1a6900f47a5178cec041fa6dc9cfee1f9c3f) ) - ROM_REGION( 0x100000, "gfx2", 0 ) + ROM_REGION( 0x100000, "sprites", 0 ) ROM_LOAD( "136057-1105.5m", 0x000000, 0x010000, CRC(50e0823f) SHA1(f638becad83307ed43d138d452199e4c6725512f) ) ROM_LOAD( "136057-1107.67m", 0x010000, 0x010000, CRC(729de7a9) SHA1(526b08e6d54cd0b991c4207c23119d2940a34009) ) ROM_LOAD( "136057-1109.8m", 0x020000, 0x010000, CRC(090e42ab) SHA1(903aa99e6e39407319f6e90102b24604884ee047) ) @@ -376,22 +581,22 @@ ROM_END ROM_START( blstroidh ) - ROM_REGION( 0x40000, "maincpu", 0 ) /* 4*64k for 68000 code */ + ROM_REGION( 0x40000, "maincpu", 0 ) // 68000 code ROM_LOAD16_BYTE( "eheadh0.c6", 0x00000, 0x10000, CRC(061f0898) SHA1(a277399aa8af665b1fb40c2bb4cf5d36d333db8d) ) ROM_LOAD16_BYTE( "eheadl0.b6", 0x00001, 0x10000, CRC(ae8df7cb) SHA1(9eaf377bbfa09e2d3ae77764dbf09ff79b65b34f) ) ROM_LOAD16_BYTE( "eheadh1.c5", 0x20000, 0x10000, CRC(0b7a3cb6) SHA1(7dc585ff536055e85b0849aa075f2fdab34a8e1c) ) ROM_LOAD16_BYTE( "eheadl1.b5", 0x20001, 0x10000, CRC(43971694) SHA1(a39a8da244645bb56081fd71609a33d8b7d78478) ) - ROM_REGION( 0x10000, "jsa:cpu", 0 ) /* 64k for 6502 code */ + ROM_REGION( 0x10000, "jsa:cpu", 0 ) // 6502 code ROM_LOAD( "136057-1135.2k", 0x00000, 0x10000, CRC(baa8b5fe) SHA1(4af1f9bec3ffa856016a89bc20041d572305ba3a) ) - ROM_REGION( 0x040000, "gfx1", 0 ) + ROM_REGION( 0x040000, "tiles", 0 ) ROM_LOAD( "136057-1101.1l", 0x000000, 0x010000, CRC(3c2daa5b) SHA1(2710a05e95afd8452104c4f4a9250a3b7d728a42) ) ROM_LOAD( "136057-1102.1m", 0x010000, 0x010000, CRC(f84f0b97) SHA1(00cb5f1e0f92742683ee71854085b1e4db4bd6bb) ) ROM_LOAD( "136057-1103.3l", 0x020000, 0x010000, CRC(ae5274f0) SHA1(87070e6e51d557c1b10ef32ac0ed670856d5aaf1) ) ROM_LOAD( "136057-1104.3m", 0x030000, 0x010000, CRC(4bb72060) SHA1(94cd1a6900f47a5178cec041fa6dc9cfee1f9c3f) ) - ROM_REGION( 0x100000, "gfx2", 0 ) + ROM_REGION( 0x100000, "sprites", 0 ) ROM_LOAD( "136057-1105.5m", 0x000000, 0x010000, CRC(50e0823f) SHA1(f638becad83307ed43d138d452199e4c6725512f) ) ROM_LOAD( "136057-1107.67m", 0x010000, 0x010000, CRC(729de7a9) SHA1(526b08e6d54cd0b991c4207c23119d2940a34009) ) ROM_LOAD( "136057-1109.8m", 0x020000, 0x010000, CRC(090e42ab) SHA1(903aa99e6e39407319f6e90102b24604884ee047) ) @@ -410,6 +615,7 @@ ROM_START( blstroidh ) ROM_LOAD( "moh7.n16", 0x0f0000, 0x010000, CRC(a93cbbe7) SHA1(5583e2421ae25181039c6145319453fb73e7bbf5) ) ROM_END +} // anonymous namespace /************************************* @@ -418,8 +624,8 @@ ROM_END * *************************************/ -GAME( 1987, blstroid, 0, blstroid, blstroid, blstroid_state, empty_init, ROT0, "Atari Games", "Blasteroids (rev 4)", 0 ) -GAME( 1987, blstroid3, blstroid, blstroid, blstroid, blstroid_state, empty_init, ROT0, "Atari Games", "Blasteroids (rev 3)", 0 ) -GAME( 1987, blstroid2, blstroid, blstroid, blstroid, blstroid_state, empty_init, ROT0, "Atari Games", "Blasteroids (rev 2)", 0 ) -GAME( 1987, blstroidg, blstroid, blstroid, blstroid, blstroid_state, empty_init, ROT0, "Atari Games", "Blasteroids (German, rev 2)", 0 ) -GAME( 1987, blstroidh, blstroid, blstroid, blstroid, blstroid_state, empty_init, ROT0, "Atari Games", "Blasteroids (with heads)", 0 ) +GAME( 1987, blstroid, 0, blstroid, blstroid, blstroid_state, empty_init, ROT0, "Atari Games", "Blasteroids (rev 4)", MACHINE_SUPPORTS_SAVE ) +GAME( 1987, blstroid3, blstroid, blstroid, blstroid, blstroid_state, empty_init, ROT0, "Atari Games", "Blasteroids (rev 3)", MACHINE_SUPPORTS_SAVE ) +GAME( 1987, blstroid2, blstroid, blstroid, blstroid, blstroid_state, empty_init, ROT0, "Atari Games", "Blasteroids (rev 2)", MACHINE_SUPPORTS_SAVE ) +GAME( 1987, blstroidg, blstroid, blstroid, blstroid, blstroid_state, empty_init, ROT0, "Atari Games", "Blasteroids (German, rev 2)", MACHINE_SUPPORTS_SAVE ) +GAME( 1987, blstroidh, blstroid, blstroid, blstroid, blstroid_state, empty_init, ROT0, "Atari Games", "Blasteroids (with heads)", MACHINE_SUPPORTS_SAVE ) diff --git a/src/mame/atari/blstroid.h b/src/mame/atari/blstroid.h deleted file mode 100644 index 4254d6e1c8a..00000000000 --- a/src/mame/atari/blstroid.h +++ /dev/null @@ -1,62 +0,0 @@ -// license:BSD-3-Clause -// copyright-holders:Aaron Giles -/************************************************************************* - - Atari Blasteroids hardware - -*************************************************************************/ -#ifndef MAME_ATARI_BLSTROID_H -#define MAME_ATARI_BLSTROID_H - -#pragma once - -#include "atarigen.h" -#include "machine/timer.h" -#include "atarijsa.h" -#include "atarimo.h" -#include "tilemap.h" - -class blstroid_state : public atarigen_state -{ -public: - blstroid_state(const machine_config &mconfig, device_type type, const char *tag) : - atarigen_state(mconfig, type, tag), - m_playfield_tilemap(*this, "playfield"), - m_jsa(*this, "jsa"), - m_mob(*this, "mob"), - m_priorityram(*this, "priorityram") - { } - - void blstroid(machine_config &config); - -protected: - virtual void machine_reset() override; - virtual void video_start() override; - - TIMER_CALLBACK_MEMBER(irq_off); - TIMER_CALLBACK_MEMBER(irq_on); - -private: - TIMER_DEVICE_CALLBACK_MEMBER(scanline_update); - void scanline_int_ack_w(uint16_t data = 0); - void video_int_ack_w(uint16_t data = 0); - void halt_until_hblank_0_w(uint16_t data = 0); - TILE_GET_INFO_MEMBER(get_playfield_tile_info); - uint32_t screen_update_blstroid(screen_device &screen, bitmap_ind16 &bitmap, const rectangle &cliprect); - - void main_map(address_map &map); - - required_device m_playfield_tilemap; - required_device m_jsa; - required_device m_mob; - required_shared_ptr m_priorityram; - - emu_timer *m_irq_off_timer = nullptr; - emu_timer *m_irq_on_timer = nullptr; - - static const atari_motion_objects_config s_mob_config; - - bool m_scanline_int_state = false; -}; - -#endif // MAME_ATARI_BLSTROID_H diff --git a/src/mame/atari/blstroid_v.cpp b/src/mame/atari/blstroid_v.cpp deleted file mode 100644 index 187e5ba55d9..00000000000 --- a/src/mame/atari/blstroid_v.cpp +++ /dev/null @@ -1,162 +0,0 @@ -// license:BSD-3-Clause -// copyright-holders:Aaron Giles -/*************************************************************************** - - Atari Blasteroids hardware - -****************************************************************************/ - -#include "emu.h" -#include "blstroid.h" -#include "cpu/m68000/m68000.h" - - - -/************************************* - * - * Tilemap callbacks - * - *************************************/ - -TILE_GET_INFO_MEMBER(blstroid_state::get_playfield_tile_info) -{ - uint16_t data = m_playfield_tilemap->basemem_read(tile_index); - int code = data & 0x1fff; - int color = (data >> 13) & 0x07; - tileinfo.set(0, code, color, 0); -} - - - -/************************************* - * - * Video system start - * - *************************************/ - -const atari_motion_objects_config blstroid_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? */ - 0, /* 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 */ - - {{ 0,0,0x0ff8,0 }}, /* mask for the link */ - {{ 0,0x3fff,0,0 }}, /* mask for the code index */ - {{ 0,0,0,0x000f }}, /* mask for the color */ - {{ 0,0,0,0xffc0 }}, /* mask for the X position */ - {{ 0xff80,0,0,0 }}, /* mask for the Y position */ - {{ 0 }}, /* mask for the width, in tiles*/ - {{ 0x000f,0,0,0 }}, /* mask for the height, in tiles */ - {{ 0,0x8000,0,0 }}, /* mask for the horizontal flip */ - {{ 0,0x4000,0,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 blstroid_state::video_start() -{ - m_irq_off_timer = timer_alloc(FUNC(blstroid_state::irq_off), this); - m_irq_on_timer = timer_alloc(FUNC(blstroid_state::irq_on), this); - - m_scanline_int_state = false; - - save_item(NAME(m_scanline_int_state)); -} - - - -/************************************* - * - * Periodic scanline updater - * - *************************************/ - -TIMER_CALLBACK_MEMBER(blstroid_state::irq_off) -{ - m_maincpu->set_input_line(M68K_IRQ_1, CLEAR_LINE); -} - -TIMER_CALLBACK_MEMBER(blstroid_state::irq_on) -{ - m_maincpu->set_input_line(M68K_IRQ_1, ASSERT_LINE); -} - - -TIMER_DEVICE_CALLBACK_MEMBER(blstroid_state::scanline_update) -{ - int scanline = param; - int offset = (scanline / 8) * 64 + 40; - - /* check for interrupts */ - if (offset < 0x800) - if (m_playfield_tilemap->basemem_read(offset) & 0x8000) - { - /* FIXME: - the only thing this IRQ does it tweak the starting MO link */ - /* unfortunately, it does it too early for the given MOs! */ - /* perhaps it is not actually hooked up on the real PCB... */ - return; - - /* set a timer to turn the interrupt on at HBLANK of the 7th scanline */ - /* and another to turn it off one scanline later */ - int width = m_screen->width(); - int vpos = m_screen->vpos(); - attotime period_on = m_screen->time_until_pos(vpos + 7, width * 0.9); - attotime period_off = m_screen->time_until_pos(vpos + 8, width * 0.9); - - m_irq_on_timer->adjust(period_on); - m_irq_off_timer->adjust(period_off); - } -} - - - -/************************************* - * - * Main refresh - * - *************************************/ - -uint32_t blstroid_state::screen_update_blstroid(screen_device &screen, bitmap_ind16 &bitmap, const rectangle &cliprect) -{ - // start drawing - m_mob->draw_async(cliprect); - - /* draw the playfield */ - m_playfield_tilemap->draw(screen, bitmap, cliprect, 0, 0); - - /* draw and merge the MO */ - bitmap_ind16 &mobitmap = m_mob->bitmap(); - for (const sparse_dirty_rect *rect = m_mob->first_dirty_rect(cliprect); rect != nullptr; rect = rect->next()) - for (int y = rect->top(); y <= rect->bottom(); y++) - { - uint16_t const *const mo = &mobitmap.pix(y); - uint16_t *const pf = &bitmap.pix(y); - for (int x = rect->left(); x <= rect->right(); x++) - if (mo[x] != 0xffff) - { - /* verified via schematics - - priority address = HPPPMMMM - */ - int const priaddr = ((pf[x] & 8) << 4) | (pf[x] & 0x70) | ((mo[x] & 0xf0) >> 4); - if (m_priorityram[priaddr] & 1) - pf[x] = mo[x]; - } - } - return 0; -} diff --git a/src/mame/atari/canyon.cpp b/src/mame/atari/canyon.cpp index 0515254305e..0ef9d99b868 100644 --- a/src/mame/atari/canyon.cpp +++ b/src/mame/atari/canyon.cpp @@ -39,13 +39,169 @@ ***************************************************************************/ #include "emu.h" -#include "canyon.h" + +#include "canyon_a.h" #include "cpu/m6502/m6502.h" +#include "machine/74259.h" +#include "machine/watchdog.h" #include "sound/discrete.h" + +#include "emupal.h" #include "screen.h" #include "speaker.h" +#include "tilemap.h" + + +namespace { + +class canyon_state : public driver_device +{ +public: + canyon_state(const machine_config &mconfig, device_type type, const char *tag) : + driver_device(mconfig, type, tag), + m_videoram(*this, "videoram"), + m_maincpu(*this, "maincpu"), + m_watchdog(*this, "watchdog"), + m_gfxdecode(*this, "gfxdecode"), + m_palette(*this, "palette"), + m_outlatch(*this, "outlatch"), + m_discrete(*this, "discrete"), + m_in(*this, "IN%u", 1U), + m_dsw(*this, "DSW") + { } + + void canyon(machine_config &config); + +protected: + virtual void video_start() override; + +private: + // memory pointers + required_shared_ptr m_videoram; + + // devices + required_device m_maincpu; + required_device m_watchdog; + required_device m_gfxdecode; + required_device m_palette; + required_device m_outlatch; + required_device m_discrete; + + required_ioport_array<2> m_in; + required_ioport m_dsw; + + // video-related + tilemap_t *m_bg_tilemap = nullptr; + + uint8_t switches_r(offs_t offset); + uint8_t options_r(offs_t offset); + void output_latch_w(offs_t offset, uint8_t data); + void videoram_w(offs_t offset, uint8_t data); + TILE_GET_INFO_MEMBER(get_bg_tile_info); + void palette(palette_device &palette) const; + uint32_t screen_update(screen_device &screen, bitmap_ind16 &bitmap, const rectangle &cliprect); + void motor_w(offs_t offset, uint8_t data); + void explode_w(uint8_t data); + void draw_sprites(bitmap_ind16 &bitmap, const rectangle &cliprect); + void draw_bombs(bitmap_ind16 &bitmap, const rectangle &cliprect); + void main_map(address_map &map); +}; + + +// audio + +/************************************* + * + * Write handlers + * + *************************************/ + +void canyon_state::motor_w(offs_t offset, uint8_t data) +{ + m_discrete->write(NODE_RELATIVE(CANYON_MOTOR1_DATA, (offset & 0x01)), data & 0x0f); +} + + +void canyon_state::explode_w(uint8_t data) +{ + m_discrete->write(CANYON_EXPLODE_DATA, data >> 4); +} + + +// video + +void canyon_state::videoram_w(offs_t offset, uint8_t data) +{ + m_videoram[offset] = data; + m_bg_tilemap->mark_tile_dirty(offset); +} + + +TILE_GET_INFO_MEMBER(canyon_state::get_bg_tile_info) +{ + uint8_t const code = m_videoram[tile_index]; + + tileinfo.set(0, code & 0x3f, code >> 7, 0); +} + + +void canyon_state::video_start() +{ + m_bg_tilemap = &machine().tilemap().create(*m_gfxdecode, tilemap_get_info_delegate(*this, FUNC(canyon_state::get_bg_tile_info)), TILEMAP_SCAN_ROWS, 8, 8, 32, 32); +} + + +void canyon_state::draw_sprites(bitmap_ind16 &bitmap, const rectangle &cliprect) +{ + for (int i = 0; i < 2; i++) + { + int const x = m_videoram[0x3d0 + 2 * i + 0x1]; + int const y = m_videoram[0x3d0 + 2 * i + 0x8]; + int const c = m_videoram[0x3d0 + 2 * i + 0x9]; + + + m_gfxdecode->gfx(1)->transpen(bitmap, cliprect, + c >> 3, + i, + !(c & 0x80), 0, + 224 - x, + 240 - y, 0); + } +} + + +void canyon_state::draw_bombs(bitmap_ind16 &bitmap, const rectangle &cliprect) +{ + for (int i = 0; i < 2; i++) + { + int const sx = 254 - m_videoram[0x3d0 + 2 * i + 0x5]; + int const sy = 246 - m_videoram[0x3d0 + 2 * i + 0xc]; + + rectangle rect(sx, sx + 1, sy, sy + 1); + rect &= cliprect; + + bitmap.fill(1 + 2 * i, rect); + } +} + + +uint32_t canyon_state::screen_update(screen_device &screen, bitmap_ind16 &bitmap, const rectangle &cliprect) +{ + m_bg_tilemap->draw(screen, bitmap, cliprect, 0, 0); + + draw_sprites(bitmap, cliprect); + + draw_bombs(bitmap, cliprect); + + // watchdog is disabled during service mode + m_watchdog->watchdog_enable(!(m_in[1]->read() & 0x10)); + + return 0; +} + +// machine /************************************* * @@ -53,7 +209,7 @@ * *************************************/ -void canyon_state::canyon_palette(palette_device &palette) const +void canyon_state::palette(palette_device &palette) const { palette.set_pen_color(0, rgb_t(0x80, 0x80, 0x80)); // GREY palette.set_pen_color(1, rgb_t(0x00, 0x00, 0x00)); // BLACK @@ -68,23 +224,23 @@ void canyon_state::canyon_palette(palette_device &palette) const * *************************************/ -uint8_t canyon_state::canyon_switches_r(offs_t offset) +uint8_t canyon_state::switches_r(offs_t offset) { uint8_t val = 0; - if ((ioport("IN2")->read() >> (offset & 7)) & 1) + if ((m_in[1]->read() >> (offset & 7)) & 1) val |= 0x80; - if ((ioport("IN1")->read() >> (offset & 3)) & 1) + if ((m_in[0]->read() >> (offset & 3)) & 1) val |= 0x01; return val; } -uint8_t canyon_state::canyon_options_r(offs_t offset) +uint8_t canyon_state::options_r(offs_t offset) { - return (ioport("DSW")->read() >> (2 * (~offset & 3))) & 3; + return (m_dsw->read() >> (2 * (~offset & 3))) & 3; } @@ -115,13 +271,13 @@ void canyon_state::main_map(address_map &map) { map.global_mask(0x3fff); map(0x0000, 0x00ff).mirror(0x100).ram(); - map(0x0400, 0x0401).w(FUNC(canyon_state::canyon_motor_w)); - map(0x0500, 0x0500).w(FUNC(canyon_state::canyon_explode_w)); - map(0x0501, 0x0501).w(m_watchdog, FUNC(watchdog_timer_device::reset_w)); /* watchdog, disabled in service mode */ + map(0x0400, 0x0401).w(FUNC(canyon_state::motor_w)); + map(0x0500, 0x0500).w(FUNC(canyon_state::explode_w)); + map(0x0501, 0x0501).w(m_watchdog, FUNC(watchdog_timer_device::reset_w)); // watchdog, disabled in service mode map(0x0600, 0x0603).select(0x0180).w(FUNC(canyon_state::output_latch_w)); - map(0x0800, 0x0bff).ram().w(FUNC(canyon_state::canyon_videoram_w)).share("videoram"); - map(0x1000, 0x17ff).r(FUNC(canyon_state::canyon_switches_r)).nopw(); /* sloppy code writes here */ - map(0x1800, 0x1fff).r(FUNC(canyon_state::canyon_options_r)); + map(0x0800, 0x0bff).ram().w(FUNC(canyon_state::videoram_w)).share(m_videoram); + map(0x1000, 0x17ff).r(FUNC(canyon_state::switches_r)).nopw(); // sloppy code writes here + map(0x1800, 0x1fff).r(FUNC(canyon_state::options_r)); map(0x2000, 0x3fff).rom(); } @@ -140,8 +296,8 @@ static INPUT_PORTS_START( canyon ) PORT_DIPSETTING( 0x01, DEF_STR( Spanish ) ) PORT_DIPSETTING( 0x02, DEF_STR( French ) ) PORT_DIPSETTING( 0x03, DEF_STR( German ) ) - PORT_DIPUNKNOWN_DIPLOC( 0x04, 0x04, "SW:3" ) /* Manual says these are unused */ - PORT_DIPUNKNOWN_DIPLOC( 0x08, 0x08, "SW:4" ) /* Manual says these are unused */ + PORT_DIPUNKNOWN_DIPLOC( 0x04, 0x04, "SW:3" ) // Manual says these are unused + PORT_DIPUNKNOWN_DIPLOC( 0x08, 0x08, "SW:4" ) // Manual says these are unused PORT_DIPNAME( 0x30, 0x00, "Misses Per Play" ) PORT_DIPLOCATION("SW:5,6") PORT_DIPSETTING( 0x00, "3" ) PORT_DIPSETTING( 0x10, "4" ) @@ -227,8 +383,8 @@ static const gfx_layout sprite_layout = static GFXDECODE_START( gfx_canyon ) - GFXDECODE_ENTRY( "gfx1", 0, tile_layout, 0, 2 ) - GFXDECODE_ENTRY( "gfx2", 0, sprite_layout, 0, 2 ) + GFXDECODE_ENTRY( "tiles", 0, tile_layout, 0, 2 ) + GFXDECODE_ENTRY( "sprites", 0, sprite_layout, 0, 2 ) GFXDECODE_END @@ -241,7 +397,7 @@ GFXDECODE_END void canyon_state::canyon(machine_config &config) { - /* basic machine hardware */ + // basic machine hardware M6502(config, m_maincpu, 12.096_MHz_XTAL / 16); m_maincpu->set_addrmap(AS_PROGRAM, &canyon_state::main_map); @@ -255,17 +411,17 @@ void canyon_state::canyon(machine_config &config) WATCHDOG_TIMER(config, m_watchdog).set_vblank_count("screen", 8); - /* video hardware */ + // video hardware screen_device &screen(SCREEN(config, "screen", SCREEN_TYPE_RASTER)); screen.set_raw(12.096_MHz_XTAL / 2, 384, 0, 256, 262, 0, 240); // HSYNC = 15,750 Hz - screen.set_screen_update(FUNC(canyon_state::screen_update_canyon)); + screen.set_screen_update(FUNC(canyon_state::screen_update)); screen.set_palette(m_palette); screen.screen_vblank().set_inputline(m_maincpu, m6502_device::NMI_LINE); GFXDECODE(config, m_gfxdecode, m_palette, gfx_canyon); - PALETTE(config, m_palette, FUNC(canyon_state::canyon_palette), 4); + PALETTE(config, m_palette, FUNC(canyon_state::palette), 4); - /* sound hardware */ + // sound hardware SPEAKER(config, "lspeaker").front_left(); SPEAKER(config, "rspeaker").front_right(); @@ -288,15 +444,15 @@ ROM_START( canyon ) ROM_LOAD_NIB_HIGH( "9503-01.p1", 0x3000, 0x0400, CRC(1eddbe28) SHA1(7d30280bf9edff743c16386d7cdec78094477996) ) ROM_LOAD ( "9496-01.d1", 0x3800, 0x0800, CRC(8be15080) SHA1(095c15e9ac91623b2d514858dca2e4c261d36fd0) ) - ROM_REGION( 0x0400, "gfx1", 0 ) + ROM_REGION( 0x0400, "tiles", 0 ) ROM_LOAD( "9492-01.n8", 0x0000, 0x0400, CRC(7449f754) SHA1(a8ffc39e1a86c94487551f5026eedbbd066b12c9) ) - ROM_REGION( 0x0100, "gfx2", 0 ) + ROM_REGION( 0x0100, "sprites", 0 ) ROM_LOAD_NIB_LOW ( "9506-01.m5", 0x0000, 0x0100, CRC(0d63396a) SHA1(147fae3b02a86310c8d022a7e7cfbf71ea511616) ) ROM_LOAD_NIB_HIGH( "9505-01.n5", 0x0000, 0x0100, CRC(60507c07) SHA1(fcb76890cbaa37e02392bf8b97f7be9a6fe6a721) ) ROM_REGION( 0x0100, "proms", 0 ) - ROM_LOAD( "9491-01.j6", 0x0000, 0x0100, CRC(b8094b4c) SHA1(82dc6799a19984f3b204ee3aeeb007e55afc8be3) ) /* sync (not used) */ + ROM_LOAD( "9491-01.j6", 0x0000, 0x0100, CRC(b8094b4c) SHA1(82dc6799a19984f3b204ee3aeeb007e55afc8be3) ) // sync (not used) ROM_END @@ -307,17 +463,18 @@ ROM_START( canyonp ) ROM_LOAD_NIB_LOW ( "cbp3800l.h1", 0x3800, 0x0800, CRC(c7ee4431) SHA1(7a0f4454a981c4e9ee27e273e9a8379458e660e5) ) ROM_LOAD_NIB_HIGH( "cbp3800m.r1", 0x3800, 0x0800, CRC(94246a9a) SHA1(5ff8b69fb744a5f62d4cf291e8f25e3620b479e7) ) - ROM_REGION( 0x0400, "gfx1", 0 ) + ROM_REGION( 0x0400, "tiles", 0 ) ROM_LOAD( "9492-01.n8", 0x0000, 0x0400, CRC(7449f754) SHA1(a8ffc39e1a86c94487551f5026eedbbd066b12c9) ) - ROM_REGION( 0x0100, "gfx2", 0 ) + ROM_REGION( 0x0100, "sprites", 0 ) ROM_LOAD_NIB_LOW ( "9506-01.m5", 0x0000, 0x0100, CRC(0d63396a) SHA1(147fae3b02a86310c8d022a7e7cfbf71ea511616) ) ROM_LOAD_NIB_HIGH( "9505-01.n5", 0x0000, 0x0100, CRC(60507c07) SHA1(fcb76890cbaa37e02392bf8b97f7be9a6fe6a721) ) ROM_REGION( 0x0100, "proms", 0 ) - ROM_LOAD( "9491-01.j6", 0x0000, 0x0100, CRC(b8094b4c) SHA1(82dc6799a19984f3b204ee3aeeb007e55afc8be3) ) /* sync (not used) */ + ROM_LOAD( "9491-01.j6", 0x0000, 0x0100, CRC(b8094b4c) SHA1(82dc6799a19984f3b204ee3aeeb007e55afc8be3) ) // sync (not used) ROM_END +} // anonymous namespace /************************************* @@ -326,5 +483,5 @@ ROM_END * *************************************/ -GAME( 1977, canyon, 0, canyon, canyon, canyon_state, empty_init, ROT0, "Atari", "Canyon Bomber", MACHINE_SUPPORTS_SAVE ) +GAME( 1977, canyon, 0, canyon, canyon, canyon_state, empty_init, ROT0, "Atari", "Canyon Bomber", MACHINE_SUPPORTS_SAVE ) GAME( 1977, canyonp, canyon, canyon, canyon, canyon_state, empty_init, ROT0, "Atari", "Canyon Bomber (prototype)", MACHINE_SUPPORTS_SAVE ) diff --git a/src/mame/atari/canyon.h b/src/mame/atari/canyon.h deleted file mode 100644 index 4681c13e4bb..00000000000 --- a/src/mame/atari/canyon.h +++ /dev/null @@ -1,82 +0,0 @@ -// license:BSD-3-Clause -// copyright-holders:Mike Balfour -/************************************************************************* - - Atari Canyon Bomber hardware - -*************************************************************************/ -#ifndef MAME_ATARI_CANYON_H -#define MAME_ATARI_CANYON_H - -#pragma once - -#include "machine/74259.h" -#include "machine/watchdog.h" -#include "sound/discrete.h" -#include "emupal.h" -#include "tilemap.h" - -/* Discrete Sound Input Nodes */ -#define CANYON_MOTOR1_DATA NODE_01 -#define CANYON_MOTOR2_DATA NODE_02 -#define CANYON_EXPLODE_DATA NODE_03 -#define CANYON_WHISTLE1_EN NODE_04 -#define CANYON_WHISTLE2_EN NODE_05 -#define CANYON_ATTRACT1_EN NODE_06 -#define CANYON_ATTRACT2_EN NODE_07 - - - -class canyon_state : public driver_device -{ -public: - canyon_state(const machine_config &mconfig, device_type type, const char *tag) : - driver_device(mconfig, type, tag), - m_videoram(*this, "videoram"), - m_outlatch(*this, "outlatch"), - m_discrete(*this, "discrete"), - m_maincpu(*this, "maincpu"), - m_watchdog(*this, "watchdog"), - m_gfxdecode(*this, "gfxdecode"), - m_palette(*this, "palette") - { } - - void canyon(machine_config &config); - -protected: - uint8_t canyon_switches_r(offs_t offset); - uint8_t canyon_options_r(offs_t offset); - void output_latch_w(offs_t offset, uint8_t data); - void canyon_videoram_w(offs_t offset, uint8_t data); - TILE_GET_INFO_MEMBER(get_bg_tile_info); - void canyon_palette(palette_device &palette) const; - uint32_t screen_update_canyon(screen_device &screen, bitmap_ind16 &bitmap, const rectangle &cliprect); - void canyon_motor_w(offs_t offset, uint8_t data); - void canyon_explode_w(uint8_t data); - void draw_sprites( bitmap_ind16 &bitmap, const rectangle &cliprect ); - void draw_bombs( bitmap_ind16 &bitmap, const rectangle &cliprect ); - - virtual void video_start() override; - void main_map(address_map &map); - -private: - /* memory pointers */ - required_shared_ptr m_videoram; - - required_device m_outlatch; - required_device m_discrete; - - /* video-related */ - tilemap_t *m_bg_tilemap = nullptr; - - required_device m_maincpu; - required_device m_watchdog; - required_device m_gfxdecode; - required_device m_palette; -}; - - -/*----------- defined in audio/canyon.c -----------*/ -DISCRETE_SOUND_EXTERN( canyon_discrete ); - -#endif // MAME_ATARI_CANYON_H diff --git a/src/mame/atari/canyon_a.cpp b/src/mame/atari/canyon_a.cpp index 395fb8d45d7..95713e74b70 100644 --- a/src/mame/atari/canyon_a.cpp +++ b/src/mame/atari/canyon_a.cpp @@ -1,32 +1,25 @@ // license:BSD-3-Clause -// copyright-holders:Mike Balfour +// copyright-holders: Mike Balfour + /************************************************************************* - audio\canyon.cpp + Atari Canyon Bomber sound system *************************************************************************/ #include "emu.h" -#include "canyon.h" -#include "sound/discrete.h" - -/************************************* - * - * Write handlers - * - *************************************/ - -void canyon_state::canyon_motor_w(offs_t offset, uint8_t data) -{ - m_discrete->write(NODE_RELATIVE(CANYON_MOTOR1_DATA, (offset & 0x01)), data & 0x0f); -} +#include "canyon_a.h" +#include "sound/discrete.h" -void canyon_state::canyon_explode_w(uint8_t data) -{ - m_discrete->write(CANYON_EXPLODE_DATA, data >> 4); -} +// Nodes - Sounds +#define CANYON_MOTORSND1 NODE_10 +#define CANYON_MOTORSND2 NODE_11 +#define CANYON_EXPLODESND NODE_12 +#define CANYON_WHISTLESND1 NODE_13 +#define CANYON_WHISTLESND2 NODE_14 +#define CANYON_NOISE NODE_15 /************************************************************************/ /* canyon Sound System Analog emulation */ @@ -42,26 +35,18 @@ static const discrete_555_desc canyonWhistl555 = static const discrete_lfsr_desc canyon_lfsr = { DISC_CLK_IS_FREQ, - 16, /* Bit Length */ - 0, /* Reset Value */ - 6, /* Use Bit 6 as XOR input 0 */ - 8, /* Use Bit 8 as XOR input 1 */ - DISC_LFSR_XNOR, /* Feedback stage1 is XNOR */ - DISC_LFSR_OR, /* Feedback stage2 is just stage 1 output OR with external feed */ - DISC_LFSR_REPLACE, /* Feedback stage3 replaces the shifted register contents */ - 0x000001, /* Everything is shifted into the first bit only */ - 0, /* Output is not inverted, Active Low Reset */ - 15 /* Output bit */ + 16, // Bit Length + 0, // Reset Value + 6, // Use Bit 6 as XOR input 0 + 8, // Use Bit 8 as XOR input 1 + DISC_LFSR_XNOR, // Feedback stage1 is XNOR + DISC_LFSR_OR, // Feedback stage2 is just stage 1 output OR with external feed + DISC_LFSR_REPLACE, // Feedback stage3 replaces the shifted register contents + 0x000001, // Everything is shifted into the first bit only + 0, // Output is not inverted, Active Low Reset + 15 // Output bit }; -/* Nodes - Sounds */ -#define CANYON_MOTORSND1 NODE_10 -#define CANYON_MOTORSND2 NODE_11 -#define CANYON_EXPLODESND NODE_12 -#define CANYON_WHISTLESND1 NODE_13 -#define CANYON_WHISTLESND2 NODE_14 -#define CANYON_NOISE NODE_15 - DISCRETE_SOUND_START(canyon_discrete) /************************************************/ /* Canyon sound system: 5 Sound Sources */ @@ -116,15 +101,15 @@ DISCRETE_SOUND_START(canyon_discrete) DISCRETE_ADJUSTMENT(NODE_21, (214.0-27.0)/12/15, (4416.0-27.0)/12/15, DISC_LOGADJ, "MOTOR1") DISCRETE_MULTIPLY(NODE_22, NODE_20, NODE_21) - DISCRETE_MULTADD(NODE_23, NODE_22, 2, 27.0/6) /* F1 = /12*2 = /6 */ + DISCRETE_MULTADD(NODE_23, NODE_22, 2, 27.0/6) // F1 = /12*2 = /6 DISCRETE_SQUAREWAVE(NODE_24, 1, NODE_23, (142.9/3), 50.0, 0, 0) DISCRETE_RCFILTER(NODE_25, NODE_24, 10000, 1e-7) - DISCRETE_MULTADD(NODE_26, NODE_22, 3, 27.0/4) /* F2 = /12*3 = /4 */ + DISCRETE_MULTADD(NODE_26, NODE_22, 3, 27.0/4) // F2 = /12*3 = /4 DISCRETE_SQUAREWAVE(NODE_27, 1, NODE_26, (142.9/3), 50.0, 0, 0) DISCRETE_RCFILTER(NODE_28, NODE_27, 10000, 1e-7) - DISCRETE_MULTADD(NODE_29, NODE_22, 4, 27.0/3) /* F3 = /12*4 = /3 */ + DISCRETE_MULTADD(NODE_29, NODE_22, 4, 27.0/3) // F3 = /12*4 = /3 DISCRETE_SQUAREWAVE(NODE_30, 1, NODE_29, (142.9/3), 100.0/3, 0, 360.0/3) DISCRETE_RCFILTER(NODE_31, NODE_30, 10000, 1e-7) @@ -139,15 +124,15 @@ DISCRETE_SOUND_START(canyon_discrete) DISCRETE_ADJUSTMENT(NODE_41, (214.0-27.0)/12/15, (4416.0-27.0)/12/15, DISC_LOGADJ, "MOTOR2") DISCRETE_MULTIPLY(NODE_42, NODE_40, NODE_41) - DISCRETE_MULTADD(NODE_43, NODE_42, 2, 27.0/6) /* F1 = /12*2 = /6 */ + DISCRETE_MULTADD(NODE_43, NODE_42, 2, 27.0/6) // F1 = /12*2 = /6 DISCRETE_SQUAREWAVE(NODE_44, 1, NODE_43, (142.9/3), 50.0, 0, 0) DISCRETE_RCFILTER(NODE_45, NODE_44, 10000, 1e-7) - DISCRETE_MULTADD(NODE_46, NODE_42, 3, 27.0/4) /* F2 = /12*3 = /4 */ + DISCRETE_MULTADD(NODE_46, NODE_42, 3, 27.0/4) // F2 = /12*3 = /4 DISCRETE_SQUAREWAVE(NODE_47, 1, NODE_46, (142.9/3), 50.0, 0, 0) DISCRETE_RCFILTER(NODE_48, NODE_47, 10000, 1e-7) - DISCRETE_MULTADD(NODE_49, NODE_42, 4, 27.0/3) /* F3 = /12*4 = /3 */ + DISCRETE_MULTADD(NODE_49, NODE_42, 4, 27.0/3) // F3 = /12*4 = /3 DISCRETE_SQUAREWAVE(NODE_50, 1, NODE_49, (142.9/3), 100.0/3, 0, 360.0/3) DISCRETE_RCFILTER(NODE_51, NODE_50, 10000, 1e-7) @@ -173,19 +158,19 @@ DISCRETE_SOUND_START(canyon_discrete) /* waveform. The original game pot varies from */ /* 0-100k, but we are going to limit it because */ /* below 50k the frequency is too high. */ - /* When triggered it starts at it's highest */ + /* When triggered it starts at its highest */ /* frequency, then decays at the rate set by */ /* a 68k resistor and 22uf capacitor. */ /************************************************/ - DISCRETE_ADJUSTMENT(NODE_70, 50000, 100000, DISC_LINADJ, "WHISTLE1") /* R59 */ + DISCRETE_ADJUSTMENT(NODE_70, 50000, 100000, DISC_LINADJ, "WHISTLE1") // R59 DISCRETE_MULTADD(NODE_71, CANYON_WHISTLE1_EN, 3.05-0.33, 0.33) - DISCRETE_RCDISC2(NODE_72, CANYON_WHISTLE1_EN, NODE_71, 1.0, NODE_71, 68000.0, 2.2e-5) /* CV */ + DISCRETE_RCDISC2(NODE_72, CANYON_WHISTLE1_EN, NODE_71, 1.0, NODE_71, 68000.0, 2.2e-5) // CV DISCRETE_555_ASTABLE_CV(NODE_73, CANYON_WHISTLE1_EN, 33000, NODE_70, 1e-8, NODE_72, &canyonWhistl555) DISCRETE_MULTIPLY(CANYON_WHISTLESND1, NODE_73, 519.4/3.3) - DISCRETE_ADJUSTMENT(NODE_75, 50000, 100000, DISC_LINADJ, "WHISTLE2") /* R69 */ + DISCRETE_ADJUSTMENT(NODE_75, 50000, 100000, DISC_LINADJ, "WHISTLE2") // R69 DISCRETE_MULTADD(NODE_76, CANYON_WHISTLE2_EN, 3.05-0.33, 0.33) - DISCRETE_RCDISC2(NODE_77, CANYON_WHISTLE2_EN, NODE_76, 1.0, NODE_76, 68000.0, 2.2e-5) /* CV */ + DISCRETE_RCDISC2(NODE_77, CANYON_WHISTLE2_EN, NODE_76, 1.0, NODE_76, 68000.0, 2.2e-5) // CV DISCRETE_555_ASTABLE_CV(NODE_78, CANYON_WHISTLE2_EN, 33000, NODE_75, 1e-8, NODE_77, &canyonWhistl555) DISCRETE_MULTIPLY(CANYON_WHISTLESND2, NODE_78, 519.4/3.3) diff --git a/src/mame/atari/canyon_a.h b/src/mame/atari/canyon_a.h new file mode 100644 index 00000000000..6b3cdff9291 --- /dev/null +++ b/src/mame/atari/canyon_a.h @@ -0,0 +1,28 @@ +// license:BSD-3-Clause +// copyright-holders: Mike Balfour + +/************************************************************************* + + Atari Canyon Bomber sound system + +*************************************************************************/ +#ifndef MAME_ATARI_CANYON_A_H +#define MAME_ATARI_CANYON_A_H + +#pragma once + +#include "sound/discrete.h" + +// Discrete Sound Input Nodes +#define CANYON_MOTOR1_DATA NODE_01 +#define CANYON_MOTOR2_DATA NODE_02 +#define CANYON_EXPLODE_DATA NODE_03 +#define CANYON_WHISTLE1_EN NODE_04 +#define CANYON_WHISTLE2_EN NODE_05 +#define CANYON_ATTRACT1_EN NODE_06 +#define CANYON_ATTRACT2_EN NODE_07 + + +DISCRETE_SOUND_EXTERN( canyon_discrete ); + +#endif // MAME_ATARI_CANYON_A_H diff --git a/src/mame/atari/canyon_v.cpp b/src/mame/atari/canyon_v.cpp deleted file mode 100644 index 75f8cffe6a8..00000000000 --- a/src/mame/atari/canyon_v.cpp +++ /dev/null @@ -1,84 +0,0 @@ -// license:BSD-3-Clause -// copyright-holders:Mike Balfour -/*************************************************************************** - -Atari Canyon Bomber video emulation - -***************************************************************************/ - -#include "emu.h" -#include "canyon.h" - - -void canyon_state::canyon_videoram_w(offs_t offset, uint8_t data) -{ - m_videoram[offset] = data; - m_bg_tilemap->mark_tile_dirty(offset); -} - - -TILE_GET_INFO_MEMBER(canyon_state::get_bg_tile_info) -{ - uint8_t code = m_videoram[tile_index]; - - tileinfo.set(0, code & 0x3f, code >> 7, 0); -} - - -void canyon_state::video_start() -{ - m_bg_tilemap = &machine().tilemap().create(*m_gfxdecode, tilemap_get_info_delegate(*this, FUNC(canyon_state::get_bg_tile_info)), TILEMAP_SCAN_ROWS, 8, 8, 32, 32); -} - - -void canyon_state::draw_sprites( bitmap_ind16 &bitmap, const rectangle &cliprect ) -{ - int i; - - for (i = 0; i < 2; i++) - { - int x = m_videoram[0x3d0 + 2 * i + 0x1]; - int y = m_videoram[0x3d0 + 2 * i + 0x8]; - int c = m_videoram[0x3d0 + 2 * i + 0x9]; - - - m_gfxdecode->gfx(1)->transpen(bitmap,cliprect, - c >> 3, - i, - !(c & 0x80), 0, - 224 - x, - 240 - y, 0); - } -} - - -void canyon_state::draw_bombs( bitmap_ind16 &bitmap, const rectangle &cliprect ) -{ - int i; - - for (i = 0; i < 2; i++) - { - int sx = 254 - m_videoram[0x3d0 + 2 * i + 0x5]; - int sy = 246 - m_videoram[0x3d0 + 2 * i + 0xc]; - - rectangle rect(sx, sx + 1, sy, sy + 1); - rect &= cliprect; - - bitmap.fill(1 + 2 * i, rect); - } -} - - -uint32_t canyon_state::screen_update_canyon(screen_device &screen, bitmap_ind16 &bitmap, const rectangle &cliprect) -{ - m_bg_tilemap->draw(screen, bitmap, cliprect, 0, 0); - - draw_sprites(bitmap, cliprect); - - draw_bombs(bitmap, cliprect); - - /* watchdog is disabled during service mode */ - m_watchdog->watchdog_enable(!(ioport("IN2")->read() & 0x10)); - - return 0; -} diff --git a/src/mame/atari/ccastles.cpp b/src/mame/atari/ccastles.cpp index 2cfd192d6c1..98d0c13f42a 100644 --- a/src/mame/atari/ccastles.cpp +++ b/src/mame/atari/ccastles.cpp @@ -1,5 +1,6 @@ // license:BSD-3-Clause -// copyright-holders:Aaron Giles +// copyright-holders: Aaron Giles + /*************************************************************************** Atari Crystal Castles hardware @@ -120,60 +121,479 @@ ***************************************************************************/ #include "emu.h" -#include "ccastles.h" #include "cpu/m6502/m6502.h" +#include "machine/74259.h" #include "machine/rescap.h" #include "machine/watchdog.h" +#include "machine/x2212.h" #include "sound/pokey.h" +#include "video/resnet.h" + +#include "emupal.h" +#include "screen.h" #include "speaker.h" -#define MASTER_CLOCK (10000000) +namespace { + +class ccastles_state : public driver_device +{ +public: + ccastles_state(const machine_config &mconfig, device_type type, const char *tag) : + driver_device(mconfig, type, tag), + m_maincpu(*this, "maincpu"), + m_nvram_4b(*this, "nvram_4b"), + m_nvram_4a(*this, "nvram_4a"), + m_outlatch(*this, "outlatch%u", 0U), + m_gfxdecode(*this, "gfxdecode"), + m_screen(*this, "screen"), + m_palette(*this, "palette"), + m_videoram(*this, "videoram"), + m_spriteram(*this, "spriteram"), + m_syncprom(*this, "syncprom"), + m_wpprom(*this, "wpprom"), + m_priprom(*this, "priprom"), + m_leta(*this, "LETA%u", 0U) + { } + + int vblank_r(); + void ccastles(machine_config &config); + +protected: + virtual void machine_start() override; + virtual void machine_reset() override; + virtual void video_start() override; + +private: + // devices + required_device m_maincpu; + required_device m_nvram_4b; + required_device m_nvram_4a; + required_device_array m_outlatch; + required_device m_gfxdecode; + required_device m_screen; + required_device m_palette; + + // memory pointers + required_shared_ptr m_videoram; + required_shared_ptr m_spriteram; + required_region_ptr m_syncprom; + required_region_ptr m_wpprom; + required_region_ptr m_priprom; + + required_ioport_array<4> m_leta; + + // video-related + bitmap_ind16 m_spritebitmap = 0; + double m_rweights[3]{}; + double m_gweights[3]{}; + double m_bweights[3]{}; + uint8_t m_bitmode_addr[2]{}; + uint8_t m_hscroll = 0U; + uint8_t m_vscroll = 0U; + + // misc + int m_vblank_start = 0; + int m_vblank_end = 0; + emu_timer *m_irq_timer = nullptr; + uint8_t m_irq_state = 0U; + + static constexpr int MASTER_CLOCK = 10'000'000; + static constexpr int PIXEL_CLOCK = MASTER_CLOCK / 2; + static constexpr int HTOTAL = 320; + static constexpr int VTOTAL = 256; + + void irq_ack_w(uint8_t data); + uint8_t leta_r(offs_t offset); + void nvram_recall_w(uint8_t data); + void nvram_store_w(int state); + uint8_t nvram_r(address_space &space, offs_t offset); + void nvram_w(offs_t offset, uint8_t data); + void hscroll_w(uint8_t data); + void vscroll_w(uint8_t data); + void video_control_w(offs_t offset, uint8_t data); + void paletteram_w(offs_t offset, uint8_t data); + void videoram_w(offs_t offset, uint8_t data); + uint8_t bitmode_r(); + void bitmode_w(uint8_t data); + void bitmode_addr_w(offs_t offset, uint8_t data); + uint32_t screen_update(screen_device &screen, bitmap_ind16 &bitmap, const rectangle &cliprect); + TIMER_CALLBACK_MEMBER(clock_irq); + inline void write_vram(uint16_t addr, uint8_t data, uint8_t bitmd, uint8_t pixba); + inline void bitmode_autoinc(); + inline void schedule_next_irq(int curscanline); + void main_map(address_map &map); +}; + + +// video + +/************************************* + * + * Video startup + * + *************************************/ + +void ccastles_state::video_start() +{ + static const int resistances[3] = { 22000, 10000, 4700 }; + + // compute the color output resistor weights at startup + compute_resistor_weights(0, 255, -1.0, + 3, resistances, m_rweights, 1000, 0, + 3, resistances, m_gweights, 1000, 0, + 3, resistances, m_bweights, 1000, 0); + + // allocate a bitmap for drawing sprites + m_screen->register_screen_bitmap(m_spritebitmap); + + // register for savestates + save_item(NAME(m_bitmode_addr)); + save_item(NAME(m_hscroll)); + save_item(NAME(m_vscroll)); +} + + + +/************************************* + * + * Video control registers + * + *************************************/ + +void ccastles_state::hscroll_w(uint8_t data) +{ + m_screen->update_partial(m_screen->vpos()); + m_hscroll = data; +} + + +void ccastles_state::vscroll_w(uint8_t data) +{ + m_vscroll = data; +} + + +void ccastles_state::video_control_w(offs_t offset, uint8_t data) +{ + // only D3 matters + m_outlatch[1]->write_bit(offset, BIT(data, 3)); +} + + -#define PIXEL_CLOCK (MASTER_CLOCK/2) -#define HTOTAL (320) -#define VTOTAL (256) +/************************************* + * + * Palette RAM accesses + * + *************************************/ + +void ccastles_state::paletteram_w(offs_t offset, uint8_t data) +{ + int bit0, bit1, bit2; + int r, g, b; + + // extract the raw RGB bits + r = ((data & 0xc0) >> 6) | ((offset & 0x20) >> 3); + b = (data & 0x38) >> 3; + g = (data & 0x07); + + // red component (inverted) + bit0 = (~r >> 0) & 0x01; + bit1 = (~r >> 1) & 0x01; + bit2 = (~r >> 2) & 0x01; + r = combine_weights(m_rweights, bit0, bit1, bit2); + + // green component (inverted) + bit0 = (~g >> 0) & 0x01; + bit1 = (~g >> 1) & 0x01; + bit2 = (~g >> 2) & 0x01; + g = combine_weights(m_gweights, bit0, bit1, bit2); + + // blue component (inverted) + bit0 = (~b >> 0) & 0x01; + bit1 = (~b >> 1) & 0x01; + bit2 = (~b >> 2) & 0x01; + b = combine_weights(m_bweights, bit0, bit1, bit2); + + m_palette->set_pen_color(offset & 0x1f, rgb_t(r, g, b)); +} + + + +/************************************* + * + * Video RAM access via the write + * protect PROM + * + *************************************/ + +inline void ccastles_state::write_vram(uint16_t addr, uint8_t data, uint8_t bitmd, uint8_t pixba) +{ + uint8_t *dest = &m_videoram[addr & 0x7ffe]; + uint8_t promaddr = 0; + + /* + Inputs to the write-protect PROM: + + Bit 7 = BA1520 = 0 if (BA15-BA12 != 0), or 1 otherwise + Bit 6 = DRBA11 + Bit 5 = DRBA10 + Bit 4 = /BITMD + Bit 3 = GND + Bit 2 = BA0 + Bit 1 = PIXB + Bit 0 = PIXA + */ + promaddr |= ((addr & 0xf000) == 0) << 7; + promaddr |= (addr & 0x0c00) >> 5; + promaddr |= (!bitmd) << 4; + promaddr |= (addr & 0x0001) << 2; + promaddr |= (pixba << 0); + + // look up the PROM result + uint8_t wpbits = m_wpprom[promaddr]; + + // write to the appropriate parts of VRAM depending on the result + if (!(wpbits & 1)) + dest[0] = (dest[0] & 0xf0) | (data & 0x0f); + if (!(wpbits & 2)) + dest[0] = (dest[0] & 0x0f) | (data & 0xf0); + if (!(wpbits & 4)) + dest[1] = (dest[1] & 0xf0) | (data & 0x0f); + if (!(wpbits & 8)) + dest[1] = (dest[1] & 0x0f) | (data & 0xf0); +} +/************************************* + * + * Autoincrement control for bit mode + * + *************************************/ + +inline void ccastles_state::bitmode_autoinc() +{ + // auto increment in the x-direction if it's enabled + if (!m_outlatch[1]->q0_r()) // /AX + { + if (!m_outlatch[1]->q2_r()) // /XINC + m_bitmode_addr[0]++; + else + m_bitmode_addr[0]--; + } + + // auto increment in the y-direction if it's enabled + if (!m_outlatch[1]->q1_r()) // /AY + { + if (!m_outlatch[1]->q3_r()) // /YINC + m_bitmode_addr[1]++; + else + m_bitmode_addr[1]--; + } +} + + + +/************************************* + * + * Standard video RAM access + * + *************************************/ + +void ccastles_state::videoram_w(offs_t offset, uint8_t data) +{ + // direct writes to VRAM go through the write protect PROM as well + write_vram(offset, data, 0, 0); +} + + + +/************************************* + * + * Bit mode video RAM access + * + *************************************/ + +uint8_t ccastles_state::bitmode_r() +{ + // in bitmode, the address comes from the autoincrement latches + uint16_t const addr = (m_bitmode_addr[1] << 7) | (m_bitmode_addr[0] >> 1); + + // the appropriate pixel is selected into the upper 4 bits + uint8_t const result = m_videoram[addr] << ((~m_bitmode_addr[0] & 1) * 4); + + // autoincrement because /BITMD was selected + bitmode_autoinc(); + + // the low 4 bits of the data lines are not driven so make them all 1's + return result | 0x0f; +} + + +void ccastles_state::bitmode_w(uint8_t data) +{ + // in bitmode, the address comes from the autoincrement latches + uint16_t const addr = (m_bitmode_addr[1] << 7) | (m_bitmode_addr[0] >> 1); + + // the upper 4 bits of data are replicated to the lower 4 bits + data = (data & 0xf0) | (data >> 4); + + // write through the generic VRAM routine, passing the low 2 X bits as PIXB/PIXA + write_vram(addr, data, 1, m_bitmode_addr[0] & 3); + + // autoincrement because /BITMD was selected + bitmode_autoinc(); +} + + +void ccastles_state::bitmode_addr_w(offs_t offset, uint8_t data) +{ + // write through to video RAM and also to the addressing latches + write_vram(offset, data, 0, 0); + m_bitmode_addr[offset] = data; +} + + + +/************************************* + * + * Video updating + * + *************************************/ + +uint32_t ccastles_state::screen_update(screen_device &screen, bitmap_ind16 &bitmap, const rectangle &cliprect) +{ + uint8_t const *const spriteaddr = &m_spriteram[m_outlatch[1]->q7_r() * 0x100]; // BUF1/BUF2 + int const flip = m_outlatch[1]->q4_r() ? 0xff : 0x00; // PLAYER2 + pen_t const black = m_palette->black_pen(); + + // draw the sprites + m_spritebitmap.fill(0x0f, cliprect); + for (int offs = 0; offs < 320 / 2; offs += 4) + { + int const x = spriteaddr[offs + 3]; + int const y = 256 - 16 - spriteaddr[offs + 1]; + int const which = spriteaddr[offs]; + int const color = spriteaddr[offs + 2] >> 7; + + m_gfxdecode->gfx(0)->transpen(m_spritebitmap, cliprect, which, color, flip, flip, x, y, 7); + } + + // draw the bitmap to the screen, looping over Y + for (int y = cliprect.top(); y <= cliprect.bottom(); y++) + { + uint16_t *const dst = &bitmap.pix(y); + + // if we're in the VBLANK region, just fill with black + if (m_syncprom[y] & 1) + { + for (int x = cliprect.left(); x <= cliprect.right(); x++) + dst[x] = black; + } + + // non-VBLANK region: merge the sprites and the bitmap + else + { + uint16_t const *const mosrc = &m_spritebitmap.pix(y); + + // the "POTATO" chip does some magic here; this is just a guess + int effy = (((y - m_vblank_end) + (flip ? 0 : m_vscroll)) ^ flip) & 0xff; + if (effy < 24) + effy = 24; + uint8_t const *const src = &m_videoram[effy * 128]; + + // loop over X + for (int x = cliprect.left(); x <= cliprect.right(); x++) + { + // if we're in the HBLANK region, just store black + if (x >= 256) + dst[x] = black; + + // otherwise, process normally + else + { + int const effx = (m_hscroll + (x ^ flip)) & 255; + + // low 4 bits = left pixel, high 4 bits = right pixel + uint8_t pix = (src[effx / 2] >> ((effx & 1) * 4)) & 0x0f; + uint8_t const mopix = mosrc[x]; + + /* Inputs to the priority PROM: + + Bit 7 = GND + Bit 6 = /CRAM + Bit 5 = BA4 + Bit 4 = MV2 + Bit 3 = MV1 + Bit 2 = MV0 + Bit 1 = MPI + Bit 0 = BIT3 + */ + uint8_t prindex = 0x40; + prindex |= (mopix & 7) << 2; + prindex |= (mopix & 8) >> 2; + prindex |= (pix & 8) >> 3; + uint8_t const prvalue = m_priprom[prindex]; + + // Bit 1 of prvalue selects the low 4 bits of the final pixel + if (prvalue & 2) + pix = mopix; + + // Bit 0 of prvalue selects bit 4 of the final color + pix |= (prvalue & 1) << 4; + + // store the pixel value and also a priority value based on the topmost bit + dst[x] = pix; + } + } + } + } + return 0; +} + + +// machine + /************************************* * * VBLANK and IRQ generation * *************************************/ -inline void ccastles_state::schedule_next_irq( int curscanline ) +inline void ccastles_state::schedule_next_irq(int curscanline) { - /* scan for a rising edge on the IRQCK signal */ + // scan for a rising edge on the IRQCK signal for (curscanline++; ; curscanline = (curscanline + 1) & 0xff) if ((m_syncprom[(curscanline - 1) & 0xff] & 8) == 0 && (m_syncprom[curscanline] & 8) != 0) break; - /* next one at the start of this scanline */ + // next one at the start of this scanline m_irq_timer->adjust(m_screen->time_until_pos(curscanline), curscanline); } TIMER_CALLBACK_MEMBER(ccastles_state::clock_irq) { - /* assert the IRQ if not already asserted */ + // assert the IRQ if not already asserted if (!m_irq_state) { m_maincpu->set_input_line(0, ASSERT_LINE); m_irq_state = 1; } - /* force an update now */ + // force an update now m_screen->update_partial(m_screen->vpos()); - /* find the next edge */ + // find the next edge schedule_next_irq(param); } int ccastles_state::vblank_r() { - int scanline = m_screen->vpos(); + int const scanline = m_screen->vpos(); return m_syncprom[scanline & 0xff] & 1; } @@ -189,37 +609,34 @@ void ccastles_state::machine_start() { rectangle visarea; - /* initialize globals */ - m_syncprom = memregion("proms")->base() + 0x000; - - /* find the start of VBLANK in the SYNC PROM */ + // find the start of VBLANK in the SYNC PROM for (m_vblank_start = 0; m_vblank_start < 256; m_vblank_start++) if ((m_syncprom[(m_vblank_start - 1) & 0xff] & 1) == 0 && (m_syncprom[m_vblank_start] & 1) != 0) break; if (m_vblank_start == 0) m_vblank_start = 256; - /* find the end of VBLANK in the SYNC PROM */ + // find the end of VBLANK in the SYNC PROM for (m_vblank_end = 0; m_vblank_end < 256; m_vblank_end++) if ((m_syncprom[(m_vblank_end - 1) & 0xff] & 1) != 0 && (m_syncprom[m_vblank_end] & 1) == 0) break; - /* can't handle the wrapping case */ + // can't handle the wrapping case assert(m_vblank_end < m_vblank_start); - /* reconfigure the visible area to match */ + // reconfigure the visible area to match visarea.set(0, 255, m_vblank_end, m_vblank_start - 1); m_screen->configure(320, 256, visarea, HZ_TO_ATTOSECONDS(PIXEL_CLOCK) * VTOTAL * HTOTAL); - /* configure the ROM banking */ - membank("bank1")->configure_entries(0, 2, memregion("maincpu")->base() + 0xa000, 0x6000); + // configure the ROM banking + membank("rombank")->configure_entries(0, 2, memregion("maincpu")->base() + 0xa000, 0x6000); - /* create a timer for IRQs and set up the first callback */ + // create a timer for IRQs and set up the first callback m_irq_timer = timer_alloc(FUNC(ccastles_state::clock_irq), this); m_irq_state = 0; schedule_next_irq(0); - /* setup for save states */ + // setup for save states save_item(NAME(m_irq_state)); } @@ -250,9 +667,7 @@ void ccastles_state::irq_ack_w(uint8_t data) uint8_t ccastles_state::leta_r(offs_t offset) { - static const char *const letanames[] = { "LETA0", "LETA1", "LETA2", "LETA3" }; - - return ioport(letanames[offset])->read(); + return m_leta[offset]->read(); } @@ -283,7 +698,7 @@ void ccastles_state::nvram_store_w(int state) uint8_t ccastles_state::nvram_r(address_space &space, offs_t offset) { - return (m_nvram_4b->read(space, offset) & 0x0f) | (m_nvram_4a->read(space,offset) << 4); + return (m_nvram_4b->read(space, offset) & 0x0f) | (m_nvram_4a->read(space, offset) << 4); } @@ -301,28 +716,28 @@ void ccastles_state::nvram_w(offs_t offset, uint8_t data) * *************************************/ -/* complete memory map derived from schematics */ +// complete memory map derived from schematics void ccastles_state::main_map(address_map &map) { - map(0x0000, 0x7fff).ram().w(FUNC(ccastles_state::ccastles_videoram_w)).share("videoram"); - map(0x0000, 0x0001).w(FUNC(ccastles_state::ccastles_bitmode_addr_w)); - map(0x0002, 0x0002).rw(FUNC(ccastles_state::ccastles_bitmode_r), FUNC(ccastles_state::ccastles_bitmode_w)); + map(0x0000, 0x7fff).ram().w(FUNC(ccastles_state::videoram_w)).share(m_videoram); + map(0x0000, 0x0001).w(FUNC(ccastles_state::bitmode_addr_w)); + map(0x0002, 0x0002).rw(FUNC(ccastles_state::bitmode_r), FUNC(ccastles_state::bitmode_w)); map(0x8000, 0x8dff).ram(); - map(0x8e00, 0x8fff).ram().share("spriteram"); + map(0x8e00, 0x8fff).ram().share(m_spriteram); map(0x9000, 0x90ff).mirror(0x0300).rw(FUNC(ccastles_state::nvram_r), FUNC(ccastles_state::nvram_w)); map(0x9400, 0x9403).mirror(0x01fc).r(FUNC(ccastles_state::leta_r)); map(0x9600, 0x97ff).portr("IN0"); map(0x9800, 0x980f).mirror(0x01f0).rw("pokey1", FUNC(pokey_device::read), FUNC(pokey_device::write)); map(0x9a00, 0x9a0f).mirror(0x01f0).rw("pokey2", FUNC(pokey_device::read), FUNC(pokey_device::write)); map(0x9c00, 0x9c7f).w(FUNC(ccastles_state::nvram_recall_w)); - map(0x9c80, 0x9cff).w(FUNC(ccastles_state::ccastles_hscroll_w)); - map(0x9d00, 0x9d7f).w(FUNC(ccastles_state::ccastles_vscroll_w)); + map(0x9c80, 0x9cff).w(FUNC(ccastles_state::hscroll_w)); + map(0x9d00, 0x9d7f).w(FUNC(ccastles_state::vscroll_w)); map(0x9d80, 0x9dff).w(FUNC(ccastles_state::irq_ack_w)); map(0x9e00, 0x9e7f).w("watchdog", FUNC(watchdog_timer_device::reset_w)); - map(0x9e80, 0x9e87).mirror(0x0078).w("outlatch0", FUNC(ls259_device::write_d0)); - map(0x9f00, 0x9f07).mirror(0x0078).w(FUNC(ccastles_state::ccastles_video_control_w)); - map(0x9f80, 0x9fbf).mirror(0x0040).w(FUNC(ccastles_state::ccastles_paletteram_w)); - map(0xa000, 0xdfff).bankr("bank1"); + map(0x9e80, 0x9e87).mirror(0x0078).w(m_outlatch[0], FUNC(ls259_device::write_d0)); + map(0x9f00, 0x9f07).mirror(0x0078).w(FUNC(ccastles_state::video_control_w)); + map(0x9f80, 0x9fbf).mirror(0x0040).w(FUNC(ccastles_state::paletteram_w)); + map(0xa000, 0xdfff).bankr("rombank"); map(0xe000, 0xffff).rom(); } @@ -335,19 +750,19 @@ void ccastles_state::main_map(address_map &map) *************************************/ static INPUT_PORTS_START( ccastles ) - PORT_START("IN0") /* IN0 */ + PORT_START("IN0") PORT_BIT( 0x01, IP_ACTIVE_LOW, IPT_COIN2 ) PORT_BIT( 0x02, IP_ACTIVE_LOW, IPT_COIN1 ) PORT_BIT( 0x04, IP_ACTIVE_LOW, IPT_SERVICE1 ) PORT_BIT( 0x08, IP_ACTIVE_LOW, IPT_TILT ) PORT_SERVICE( 0x10, IP_ACTIVE_LOW ) PORT_BIT( 0x20, IP_ACTIVE_HIGH, IPT_CUSTOM ) PORT_READ_LINE_MEMBER(ccastles_state, vblank_r) - PORT_BIT( 0x40, IP_ACTIVE_LOW, IPT_BUTTON1 ) PORT_NAME("Left Jump/1P Start Upright") PORT_CONDITION("IN1",0x20,EQUALS,0x00) /* left Jump, non-cocktail start1 */ - PORT_BIT( 0x40, IP_ACTIVE_LOW, IPT_BUTTON1 ) PORT_NAME("1P Jump") PORT_CONDITION("IN1",0x20,EQUALS,0x20) /* 1p Jump, cocktail */ - PORT_BIT( 0x80, IP_ACTIVE_LOW, IPT_BUTTON2 ) PORT_NAME("Right Jump/2P Start Upright") PORT_CONDITION("IN1",0x20,EQUALS,0x00) /* right Jump, non-cocktail start2 */ - PORT_BIT( 0x80, IP_ACTIVE_LOW, IPT_BUTTON1 ) PORT_COCKTAIL PORT_NAME("2P Jump") PORT_CONDITION("IN1",0x20,EQUALS,0x20) /* 2p Jump, cocktail */ + PORT_BIT( 0x40, IP_ACTIVE_LOW, IPT_BUTTON1 ) PORT_NAME("Left Jump/1P Start Upright") PORT_CONDITION("IN1", 0x20, EQUALS, 0x00) // left Jump, non-cocktail start1 + PORT_BIT( 0x40, IP_ACTIVE_LOW, IPT_BUTTON1 ) PORT_NAME("1P Jump") PORT_CONDITION("IN1", 0x20, EQUALS, 0x20) // 1p Jump, cocktail + PORT_BIT( 0x80, IP_ACTIVE_LOW, IPT_BUTTON2 ) PORT_NAME("Right Jump/2P Start Upright") PORT_CONDITION("IN1", 0x20, EQUALS, 0x00) // right Jump, non-cocktail start2 + PORT_BIT( 0x80, IP_ACTIVE_LOW, IPT_BUTTON1 ) PORT_COCKTAIL PORT_NAME("2P Jump") PORT_CONDITION("IN1", 0x20, EQUALS, 0x20) // 2p Jump, cocktail - PORT_START("IN1") /* IN1 */ + PORT_START("IN1") PORT_DIPNAME( 0x01, 0x01, DEF_STR( Unknown ) ) PORT_DIPSETTING( 0x01, DEF_STR( Off ) ) PORT_DIPSETTING( 0x00, DEF_STR( On ) ) @@ -357,8 +772,8 @@ static INPUT_PORTS_START( ccastles ) PORT_DIPNAME( 0x04, 0x04, DEF_STR( Unknown ) ) PORT_DIPSETTING( 0x04, DEF_STR( Off ) ) PORT_DIPSETTING( 0x00, DEF_STR( On ) ) - PORT_BIT( 0x08, IP_ACTIVE_LOW, IPT_START1 ) PORT_NAME("1P Start Cocktail") /* cocktail only */ - PORT_BIT( 0x10, IP_ACTIVE_LOW, IPT_START2 ) PORT_NAME("2P Start Cocktail") /* cocktail only */ + PORT_BIT( 0x08, IP_ACTIVE_LOW, IPT_START1 ) PORT_NAME("1P Start Cocktail") // cocktail only + PORT_BIT( 0x10, IP_ACTIVE_LOW, IPT_START2 ) PORT_NAME("2P Start Cocktail") // cocktail only PORT_DIPNAME( 0x20, 0x00, DEF_STR( Cabinet ) ) PORT_DIPSETTING( 0x00, DEF_STR( Upright ) ) PORT_DIPSETTING( 0x20, DEF_STR( Cocktail ) ) @@ -371,10 +786,10 @@ static INPUT_PORTS_START( ccastles ) PORT_BIT( 0xff, 0x00, IPT_TRACKBALL_X ) PORT_SENSITIVITY(10) PORT_KEYDELTA(30) PORT_START("LETA2") - PORT_BIT( 0xff, 0x00, IPT_TRACKBALL_Y ) PORT_COCKTAIL PORT_SENSITIVITY(10) PORT_KEYDELTA(30) PORT_REVERSE /* cocktail only */ + PORT_BIT( 0xff, 0x00, IPT_TRACKBALL_Y ) PORT_COCKTAIL PORT_SENSITIVITY(10) PORT_KEYDELTA(30) PORT_REVERSE // cocktail only PORT_START("LETA3") - PORT_BIT( 0xff, 0x00, IPT_TRACKBALL_X ) PORT_COCKTAIL PORT_SENSITIVITY(10) PORT_KEYDELTA(30) /* cocktail only */ + PORT_BIT( 0xff, 0x00, IPT_TRACKBALL_X ) PORT_COCKTAIL PORT_SENSITIVITY(10) PORT_KEYDELTA(30) // cocktail only INPUT_PORTS_END @@ -422,7 +837,7 @@ static const gfx_layout ccastles_spritelayout = static GFXDECODE_START( gfx_ccastles ) - GFXDECODE_ENTRY( "gfx1", 0x0000, ccastles_spritelayout, 0, 2 ) + GFXDECODE_ENTRY( "gfx", 0x0000, ccastles_spritelayout, 0, 2 ) GFXDECODE_END @@ -434,8 +849,8 @@ GFXDECODE_END void ccastles_state::ccastles(machine_config &config) { - /* basic machine hardware */ - M6502(config, m_maincpu, MASTER_CLOCK/8); + // basic machine hardware + M6502(config, m_maincpu, MASTER_CLOCK / 8); m_maincpu->set_addrmap(AS_PROGRAM, &ccastles_state::main_map); LS259(config, m_outlatch[0]); // 8N @@ -445,7 +860,7 @@ void ccastles_state::ccastles(machine_config &config) m_outlatch[0]->q_out_cb<3>().set(FUNC(ccastles_state::nvram_store_w)); m_outlatch[0]->q_out_cb<5>().set([this] (int state) { machine().bookkeeping().coin_counter_w(0, state); }); m_outlatch[0]->q_out_cb<6>().set([this] (int state) { machine().bookkeeping().coin_counter_w(1, state); }); - m_outlatch[0]->q_out_cb<7>().set_membank("bank1"); + m_outlatch[0]->q_out_cb<7>().set_membank("rombank"); LS259(config, m_outlatch[1]); // 6P @@ -454,25 +869,25 @@ void ccastles_state::ccastles(machine_config &config) X2212(config, "nvram_4b").set_auto_save(true); X2212(config, "nvram_4a").set_auto_save(true); - /* video hardware */ + // video hardware GFXDECODE(config, m_gfxdecode, m_palette, gfx_ccastles); PALETTE(config, m_palette).set_entries(32); SCREEN(config, m_screen, SCREEN_TYPE_RASTER); m_screen->set_raw(PIXEL_CLOCK, HTOTAL, 0, 256, VTOTAL, 24, 256); // potentially adjusted later - m_screen->set_screen_update(FUNC(ccastles_state::screen_update_ccastles)); + m_screen->set_screen_update(FUNC(ccastles_state::screen_update)); m_screen->set_palette(m_palette); - /* sound hardware */ + // sound hardware SPEAKER(config, "mono").front_center(); - pokey_device &pokey1(POKEY(config, "pokey1", MASTER_CLOCK/8)); - /* NOTE: 1k + 0.2k is not 100% exact, but should not make an audible difference */ + pokey_device &pokey1(POKEY(config, "pokey1", MASTER_CLOCK / 8)); + // NOTE: 1k + 0.2k is not 100% exact, but should not make an audible difference pokey1.set_output_opamp(RES_K(1) + RES_K(0.2), CAP_U(0.01), 5.0); pokey1.add_route(ALL_OUTPUTS, "mono", 1.0); - pokey_device &pokey2(POKEY(config, "pokey2", MASTER_CLOCK/8)); - /* NOTE: 1k + 0.2k is not 100% exact, but should not make an audible difference */ + pokey_device &pokey2(POKEY(config, "pokey2", MASTER_CLOCK / 8)); + // NOTE: 1k + 0.2k is not 100% exact, but should not make an audible difference pokey2.set_output_opamp(RES_K(1) + RES_K(0.2), CAP_U(0.01), 5.0); pokey2.allpot_r().set_ioport("IN1"); pokey2.add_route(ALL_OUTPUTS, "mono", 1.0); @@ -494,15 +909,21 @@ ROM_START( ccastles ) ROM_LOAD( "136022-102.1h", 0x10000, 0x2000, CRC(f6ccfbd4) SHA1(69c3da2cbefc5e03a77357e817e3015da5d8334a) ) ROM_LOAD( "136022-101.1f", 0x12000, 0x2000, CRC(e2e17236) SHA1(81fa95b4d9beacb06d6b4afdf346d94117396557) ) - ROM_REGION( 0x4000, "gfx1", 0 ) + ROM_REGION( 0x4000, "gfx", 0 ) ROM_LOAD( "136022-106.8d", 0x0000, 0x2000, CRC(9d1d89fc) SHA1(01c279edee322cc28f34506c312e4a9e3363b1be) ) ROM_LOAD( "136022-107.8b", 0x2000, 0x2000, CRC(39960b7d) SHA1(82bdf764ac23e72598883283c5e957169387abd4) ) - ROM_REGION( 0x0400, "proms", 0 ) + ROM_REGION( 0x0100, "syncprom", 0 ) ROM_LOAD( "82s129-136022-108.7k", 0x0000, 0x0100, CRC(6ed31e3b) SHA1(c3f3e4e7f313ecfd101cc52dfc44bd6b51a2ac88) ) // vertical sync generation - ROM_LOAD( "82s129-136022-109.6l", 0x0100, 0x0100, CRC(b3515f1a) SHA1(c1bf077242481ef2f958580602b8113532b58612) ) // address decoding - ROM_LOAD( "82s129-136022-110.11l", 0x0200, 0x0100, CRC(068bdc7e) SHA1(ae155918fdafd14299bc448b43eed8ad9c1ef5ef) ) // DRAM write protection - ROM_LOAD( "82s129-136022-111.10k", 0x0300, 0x0100, CRC(c29c18d9) SHA1(278bf61a290ae72ddaae2bafb4ab6739d3fb6238) ) // color selection + + ROM_REGION( 0x0100, "addressprom", 0 ) + ROM_LOAD( "82s129-136022-109.6l", 0x0000, 0x0100, CRC(b3515f1a) SHA1(c1bf077242481ef2f958580602b8113532b58612) ) // address decoding + + ROM_REGION( 0x0100, "wpprom", 0 ) + ROM_LOAD( "82s129-136022-110.11l", 0x0000, 0x0100, CRC(068bdc7e) SHA1(ae155918fdafd14299bc448b43eed8ad9c1ef5ef) ) // DRAM write protection + + ROM_REGION( 0x0100, "priprom", 0 ) + ROM_LOAD( "82s129-136022-111.10k", 0x0000, 0x0100, CRC(c29c18d9) SHA1(278bf61a290ae72ddaae2bafb4ab6739d3fb6238) ) // color selection ROM_END @@ -514,15 +935,21 @@ ROM_START( ccastlesg ) ROM_LOAD( "136022-102.1h", 0x10000, 0x2000, CRC(f6ccfbd4) SHA1(69c3da2cbefc5e03a77357e817e3015da5d8334a) ) ROM_LOAD( "136022-101.1f", 0x12000, 0x2000, CRC(e2e17236) SHA1(81fa95b4d9beacb06d6b4afdf346d94117396557) ) - ROM_REGION( 0x4000, "gfx1", 0 ) + ROM_REGION( 0x4000, "gfx", 0 ) ROM_LOAD( "136022-106.8d", 0x0000, 0x2000, CRC(9d1d89fc) SHA1(01c279edee322cc28f34506c312e4a9e3363b1be) ) ROM_LOAD( "136022-107.8b", 0x2000, 0x2000, CRC(39960b7d) SHA1(82bdf764ac23e72598883283c5e957169387abd4) ) - ROM_REGION( 0x0400, "proms", 0 ) - ROM_LOAD( "82s129-136022-108.7k", 0x0000, 0x0100, CRC(6ed31e3b) SHA1(c3f3e4e7f313ecfd101cc52dfc44bd6b51a2ac88) ) - ROM_LOAD( "82s129-136022-109.6l", 0x0100, 0x0100, CRC(b3515f1a) SHA1(c1bf077242481ef2f958580602b8113532b58612) ) - ROM_LOAD( "82s129-136022-110.11l", 0x0200, 0x0100, CRC(068bdc7e) SHA1(ae155918fdafd14299bc448b43eed8ad9c1ef5ef) ) - ROM_LOAD( "82s129-136022-111.10k", 0x0300, 0x0100, CRC(c29c18d9) SHA1(278bf61a290ae72ddaae2bafb4ab6739d3fb6238) ) + ROM_REGION( 0x0100, "syncprom", 0 ) + ROM_LOAD( "82s129-136022-108.7k", 0x0000, 0x0100, CRC(6ed31e3b) SHA1(c3f3e4e7f313ecfd101cc52dfc44bd6b51a2ac88) ) // vertical sync generation + + ROM_REGION( 0x0100, "addressprom", 0 ) + ROM_LOAD( "82s129-136022-109.6l", 0x0000, 0x0100, CRC(b3515f1a) SHA1(c1bf077242481ef2f958580602b8113532b58612) ) // address decoding + + ROM_REGION( 0x0100, "wpprom", 0 ) + ROM_LOAD( "82s129-136022-110.11l", 0x0000, 0x0100, CRC(068bdc7e) SHA1(ae155918fdafd14299bc448b43eed8ad9c1ef5ef) ) // DRAM write protection + + ROM_REGION( 0x0100, "priprom", 0 ) + ROM_LOAD( "82s129-136022-111.10k", 0x0000, 0x0100, CRC(c29c18d9) SHA1(278bf61a290ae72ddaae2bafb4ab6739d3fb6238) ) // color selection ROM_END @@ -534,15 +961,21 @@ ROM_START( ccastlesp ) ROM_LOAD( "136022-102.1h", 0x10000, 0x2000, CRC(f6ccfbd4) SHA1(69c3da2cbefc5e03a77357e817e3015da5d8334a) ) ROM_LOAD( "136022-101.1f", 0x12000, 0x2000, CRC(e2e17236) SHA1(81fa95b4d9beacb06d6b4afdf346d94117396557) ) - ROM_REGION( 0x4000, "gfx1", 0 ) + ROM_REGION( 0x4000, "gfx", 0 ) ROM_LOAD( "136022-106.8d", 0x0000, 0x2000, CRC(9d1d89fc) SHA1(01c279edee322cc28f34506c312e4a9e3363b1be) ) ROM_LOAD( "136022-107.8b", 0x2000, 0x2000, CRC(39960b7d) SHA1(82bdf764ac23e72598883283c5e957169387abd4) ) - ROM_REGION( 0x0400, "proms", 0 ) - ROM_LOAD( "82s129-136022-108.7k", 0x0000, 0x0100, CRC(6ed31e3b) SHA1(c3f3e4e7f313ecfd101cc52dfc44bd6b51a2ac88) ) - ROM_LOAD( "82s129-136022-109.6l", 0x0100, 0x0100, CRC(b3515f1a) SHA1(c1bf077242481ef2f958580602b8113532b58612) ) - ROM_LOAD( "82s129-136022-110.11l", 0x0200, 0x0100, CRC(068bdc7e) SHA1(ae155918fdafd14299bc448b43eed8ad9c1ef5ef) ) - ROM_LOAD( "82s129-136022-111.10k", 0x0300, 0x0100, CRC(c29c18d9) SHA1(278bf61a290ae72ddaae2bafb4ab6739d3fb6238) ) + ROM_REGION( 0x0100, "syncprom", 0 ) + ROM_LOAD( "82s129-136022-108.7k", 0x0000, 0x0100, CRC(6ed31e3b) SHA1(c3f3e4e7f313ecfd101cc52dfc44bd6b51a2ac88) ) // vertical sync generation + + ROM_REGION( 0x0100, "addressprom", 0 ) + ROM_LOAD( "82s129-136022-109.6l", 0x0000, 0x0100, CRC(b3515f1a) SHA1(c1bf077242481ef2f958580602b8113532b58612) ) // address decoding + + ROM_REGION( 0x0100, "wpprom", 0 ) + ROM_LOAD( "82s129-136022-110.11l", 0x0000, 0x0100, CRC(068bdc7e) SHA1(ae155918fdafd14299bc448b43eed8ad9c1ef5ef) ) // DRAM write protection + + ROM_REGION( 0x0100, "priprom", 0 ) + ROM_LOAD( "82s129-136022-111.10k", 0x0000, 0x0100, CRC(c29c18d9) SHA1(278bf61a290ae72ddaae2bafb4ab6739d3fb6238) ) // color selection ROM_END @@ -554,15 +987,21 @@ ROM_START( ccastlesf ) ROM_LOAD( "136022-102.1h", 0x10000, 0x2000, CRC(f6ccfbd4) SHA1(69c3da2cbefc5e03a77357e817e3015da5d8334a) ) ROM_LOAD( "136022-101.1f", 0x12000, 0x2000, CRC(e2e17236) SHA1(81fa95b4d9beacb06d6b4afdf346d94117396557) ) - ROM_REGION( 0x4000, "gfx1", 0 ) + ROM_REGION( 0x4000, "gfx", 0 ) ROM_LOAD( "136022-106.8d", 0x0000, 0x2000, CRC(9d1d89fc) SHA1(01c279edee322cc28f34506c312e4a9e3363b1be) ) ROM_LOAD( "136022-107.8b", 0x2000, 0x2000, CRC(39960b7d) SHA1(82bdf764ac23e72598883283c5e957169387abd4) ) - ROM_REGION( 0x0400, "proms", 0 ) - ROM_LOAD( "82s129-136022-108.7k", 0x0000, 0x0100, CRC(6ed31e3b) SHA1(c3f3e4e7f313ecfd101cc52dfc44bd6b51a2ac88) ) - ROM_LOAD( "82s129-136022-109.6l", 0x0100, 0x0100, CRC(b3515f1a) SHA1(c1bf077242481ef2f958580602b8113532b58612) ) - ROM_LOAD( "82s129-136022-110.11l", 0x0200, 0x0100, CRC(068bdc7e) SHA1(ae155918fdafd14299bc448b43eed8ad9c1ef5ef) ) - ROM_LOAD( "82s129-136022-111.10k", 0x0300, 0x0100, CRC(c29c18d9) SHA1(278bf61a290ae72ddaae2bafb4ab6739d3fb6238) ) + ROM_REGION( 0x0100, "syncprom", 0 ) + ROM_LOAD( "82s129-136022-108.7k", 0x0000, 0x0100, CRC(6ed31e3b) SHA1(c3f3e4e7f313ecfd101cc52dfc44bd6b51a2ac88) ) // vertical sync generation + + ROM_REGION( 0x0100, "addressprom", 0 ) + ROM_LOAD( "82s129-136022-109.6l", 0x0000, 0x0100, CRC(b3515f1a) SHA1(c1bf077242481ef2f958580602b8113532b58612) ) // address decoding + + ROM_REGION( 0x0100, "wpprom", 0 ) + ROM_LOAD( "82s129-136022-110.11l", 0x0000, 0x0100, CRC(068bdc7e) SHA1(ae155918fdafd14299bc448b43eed8ad9c1ef5ef) ) // DRAM write protection + + ROM_REGION( 0x0100, "priprom", 0 ) + ROM_LOAD( "82s129-136022-111.10k", 0x0000, 0x0100, CRC(c29c18d9) SHA1(278bf61a290ae72ddaae2bafb4ab6739d3fb6238) ) // color selection ROM_END @@ -574,15 +1013,21 @@ ROM_START( ccastles3 ) ROM_LOAD( "136022-102.1h", 0x10000, 0x2000, CRC(f6ccfbd4) SHA1(69c3da2cbefc5e03a77357e817e3015da5d8334a) ) ROM_LOAD( "136022-101.1f", 0x12000, 0x2000, CRC(e2e17236) SHA1(81fa95b4d9beacb06d6b4afdf346d94117396557) ) - ROM_REGION( 0x4000, "gfx1", 0 ) + ROM_REGION( 0x4000, "gfx", 0 ) ROM_LOAD( "136022-106.8d", 0x0000, 0x2000, CRC(9d1d89fc) SHA1(01c279edee322cc28f34506c312e4a9e3363b1be) ) ROM_LOAD( "136022-107.8b", 0x2000, 0x2000, CRC(39960b7d) SHA1(82bdf764ac23e72598883283c5e957169387abd4) ) - ROM_REGION( 0x0400, "proms", 0 ) - ROM_LOAD( "82s129-136022-108.7k", 0x0000, 0x0100, CRC(6ed31e3b) SHA1(c3f3e4e7f313ecfd101cc52dfc44bd6b51a2ac88) ) - ROM_LOAD( "82s129-136022-109.6l", 0x0100, 0x0100, CRC(b3515f1a) SHA1(c1bf077242481ef2f958580602b8113532b58612) ) - ROM_LOAD( "82s129-136022-110.11l", 0x0200, 0x0100, CRC(068bdc7e) SHA1(ae155918fdafd14299bc448b43eed8ad9c1ef5ef) ) - ROM_LOAD( "82s129-136022-111.10k", 0x0300, 0x0100, CRC(c29c18d9) SHA1(278bf61a290ae72ddaae2bafb4ab6739d3fb6238) ) + ROM_REGION( 0x0100, "syncprom", 0 ) + ROM_LOAD( "82s129-136022-108.7k", 0x0000, 0x0100, CRC(6ed31e3b) SHA1(c3f3e4e7f313ecfd101cc52dfc44bd6b51a2ac88) ) // vertical sync generation + + ROM_REGION( 0x0100, "addressprom", 0 ) + ROM_LOAD( "82s129-136022-109.6l", 0x0000, 0x0100, CRC(b3515f1a) SHA1(c1bf077242481ef2f958580602b8113532b58612) ) // address decoding + + ROM_REGION( 0x0100, "wpprom", 0 ) + ROM_LOAD( "82s129-136022-110.11l", 0x0000, 0x0100, CRC(068bdc7e) SHA1(ae155918fdafd14299bc448b43eed8ad9c1ef5ef) ) // DRAM write protection + + ROM_REGION( 0x0100, "priprom", 0 ) + ROM_LOAD( "82s129-136022-111.10k", 0x0000, 0x0100, CRC(c29c18d9) SHA1(278bf61a290ae72ddaae2bafb4ab6739d3fb6238) ) // color selection ROM_END @@ -594,15 +1039,21 @@ ROM_START( ccastles2 ) ROM_LOAD( "136022-102.1h", 0x10000, 0x2000, CRC(f6ccfbd4) SHA1(69c3da2cbefc5e03a77357e817e3015da5d8334a) ) ROM_LOAD( "136022-101.1f", 0x12000, 0x2000, CRC(e2e17236) SHA1(81fa95b4d9beacb06d6b4afdf346d94117396557) ) - ROM_REGION( 0x4000, "gfx1", 0 ) + ROM_REGION( 0x4000, "gfx", 0 ) ROM_LOAD( "136022-106.8d", 0x0000, 0x2000, CRC(9d1d89fc) SHA1(01c279edee322cc28f34506c312e4a9e3363b1be) ) ROM_LOAD( "136022-107.8b", 0x2000, 0x2000, CRC(39960b7d) SHA1(82bdf764ac23e72598883283c5e957169387abd4) ) - ROM_REGION( 0x0400, "proms", 0 ) - ROM_LOAD( "82s129-136022-108.7k", 0x0000, 0x0100, CRC(6ed31e3b) SHA1(c3f3e4e7f313ecfd101cc52dfc44bd6b51a2ac88) ) - ROM_LOAD( "82s129-136022-109.6l", 0x0100, 0x0100, CRC(b3515f1a) SHA1(c1bf077242481ef2f958580602b8113532b58612) ) - ROM_LOAD( "82s129-136022-110.11l", 0x0200, 0x0100, CRC(068bdc7e) SHA1(ae155918fdafd14299bc448b43eed8ad9c1ef5ef) ) - ROM_LOAD( "82s129-136022-111.10k", 0x0300, 0x0100, CRC(c29c18d9) SHA1(278bf61a290ae72ddaae2bafb4ab6739d3fb6238) ) + ROM_REGION( 0x0100, "syncprom", 0 ) + ROM_LOAD( "82s129-136022-108.7k", 0x0000, 0x0100, CRC(6ed31e3b) SHA1(c3f3e4e7f313ecfd101cc52dfc44bd6b51a2ac88) ) // vertical sync generation + + ROM_REGION( 0x0100, "addressprom", 0 ) + ROM_LOAD( "82s129-136022-109.6l", 0x0000, 0x0100, CRC(b3515f1a) SHA1(c1bf077242481ef2f958580602b8113532b58612) ) // address decoding + + ROM_REGION( 0x0100, "wpprom", 0 ) + ROM_LOAD( "82s129-136022-110.11l", 0x0000, 0x0100, CRC(068bdc7e) SHA1(ae155918fdafd14299bc448b43eed8ad9c1ef5ef) ) // DRAM write protection + + ROM_REGION( 0x0100, "priprom", 0 ) + ROM_LOAD( "82s129-136022-111.10k", 0x0000, 0x0100, CRC(c29c18d9) SHA1(278bf61a290ae72ddaae2bafb4ab6739d3fb6238) ) // color selection ROM_END @@ -614,15 +1065,21 @@ ROM_START( ccastles1 ) ROM_LOAD( "136022-102.1h", 0x10000, 0x2000, CRC(f6ccfbd4) SHA1(69c3da2cbefc5e03a77357e817e3015da5d8334a) ) ROM_LOAD( "136022-101.1f", 0x12000, 0x2000, CRC(e2e17236) SHA1(81fa95b4d9beacb06d6b4afdf346d94117396557) ) - ROM_REGION( 0x4000, "gfx1", 0 ) + ROM_REGION( 0x4000, "gfx", 0 ) ROM_LOAD( "136022-106.8d", 0x0000, 0x2000, CRC(9d1d89fc) SHA1(01c279edee322cc28f34506c312e4a9e3363b1be) ) ROM_LOAD( "136022-107.8b", 0x2000, 0x2000, CRC(39960b7d) SHA1(82bdf764ac23e72598883283c5e957169387abd4) ) - ROM_REGION( 0x0400, "proms", 0 ) - ROM_LOAD( "82s129-136022-108.7k", 0x0000, 0x0100, CRC(6ed31e3b) SHA1(c3f3e4e7f313ecfd101cc52dfc44bd6b51a2ac88) ) - ROM_LOAD( "82s129-136022-109.6l", 0x0100, 0x0100, CRC(b3515f1a) SHA1(c1bf077242481ef2f958580602b8113532b58612) ) - ROM_LOAD( "82s129-136022-110.11l", 0x0200, 0x0100, CRC(068bdc7e) SHA1(ae155918fdafd14299bc448b43eed8ad9c1ef5ef) ) - ROM_LOAD( "82s129-136022-111.10k", 0x0300, 0x0100, CRC(c29c18d9) SHA1(278bf61a290ae72ddaae2bafb4ab6739d3fb6238) ) + ROM_REGION( 0x0100, "syncprom", 0 ) + ROM_LOAD( "82s129-136022-108.7k", 0x0000, 0x0100, CRC(6ed31e3b) SHA1(c3f3e4e7f313ecfd101cc52dfc44bd6b51a2ac88) ) // vertical sync generation + + ROM_REGION( 0x0100, "addressprom", 0 ) + ROM_LOAD( "82s129-136022-109.6l", 0x0000, 0x0100, CRC(b3515f1a) SHA1(c1bf077242481ef2f958580602b8113532b58612) ) // address decoding + + ROM_REGION( 0x0100, "wpprom", 0 ) + ROM_LOAD( "82s129-136022-110.11l", 0x0000, 0x0100, CRC(068bdc7e) SHA1(ae155918fdafd14299bc448b43eed8ad9c1ef5ef) ) // DRAM write protection + + ROM_REGION( 0x0100, "priprom", 0 ) + ROM_LOAD( "82s129-136022-111.10k", 0x0000, 0x0100, CRC(c29c18d9) SHA1(278bf61a290ae72ddaae2bafb4ab6739d3fb6238) ) // color selection ROM_END @@ -634,17 +1091,24 @@ ROM_START( ccastlesj ) ROM_LOAD( "136022-102.1h", 0x10000, 0x2000, CRC(f6ccfbd4) SHA1(69c3da2cbefc5e03a77357e817e3015da5d8334a) ) ROM_LOAD( "136022-101.1f", 0x12000, 0x2000, CRC(e2e17236) SHA1(81fa95b4d9beacb06d6b4afdf346d94117396557) ) - ROM_REGION( 0x4000, "gfx1", 0 ) + ROM_REGION( 0x4000, "gfx", 0 ) ROM_LOAD( "136022-106.8d", 0x0000, 0x2000, CRC(9d1d89fc) SHA1(01c279edee322cc28f34506c312e4a9e3363b1be) ) ROM_LOAD( "136022-107.8b", 0x2000, 0x2000, CRC(39960b7d) SHA1(82bdf764ac23e72598883283c5e957169387abd4) ) - ROM_REGION( 0x0400, "proms", 0 ) - ROM_LOAD( "82s129-136022-108.7k", 0x0000, 0x0100, CRC(6ed31e3b) SHA1(c3f3e4e7f313ecfd101cc52dfc44bd6b51a2ac88) ) - ROM_LOAD( "82s129-136022-109.6l", 0x0100, 0x0100, CRC(b3515f1a) SHA1(c1bf077242481ef2f958580602b8113532b58612) ) - ROM_LOAD( "82s129-136022-110.11l", 0x0200, 0x0100, CRC(068bdc7e) SHA1(ae155918fdafd14299bc448b43eed8ad9c1ef5ef) ) - ROM_LOAD( "82s129-136022-111.10k", 0x0300, 0x0100, CRC(c29c18d9) SHA1(278bf61a290ae72ddaae2bafb4ab6739d3fb6238) ) + ROM_REGION( 0x0100, "syncprom", 0 ) + ROM_LOAD( "82s129-136022-108.7k", 0x0000, 0x0100, CRC(6ed31e3b) SHA1(c3f3e4e7f313ecfd101cc52dfc44bd6b51a2ac88) ) // vertical sync generation + + ROM_REGION( 0x0100, "addressprom", 0 ) + ROM_LOAD( "82s129-136022-109.6l", 0x0000, 0x0100, CRC(b3515f1a) SHA1(c1bf077242481ef2f958580602b8113532b58612) ) // address decoding + + ROM_REGION( 0x0100, "wpprom", 0 ) + ROM_LOAD( "82s129-136022-110.11l", 0x0000, 0x0100, CRC(068bdc7e) SHA1(ae155918fdafd14299bc448b43eed8ad9c1ef5ef) ) // DRAM write protection + + ROM_REGION( 0x0100, "priprom", 0 ) + ROM_LOAD( "82s129-136022-111.10k", 0x0000, 0x0100, CRC(c29c18d9) SHA1(278bf61a290ae72ddaae2bafb4ab6739d3fb6238) ) // color selection ROM_END +} // anonymous namespace /************************************* @@ -653,11 +1117,11 @@ ROM_END * *************************************/ -GAME( 1983, ccastles, 0, ccastles, ccastles, ccastles_state, empty_init, ROT0, "Atari", "Crystal Castles (version 4)", MACHINE_SUPPORTS_SAVE ) -GAME( 1983, ccastlesg, ccastles, ccastles, ccastles, ccastles_state, empty_init, ROT0, "Atari", "Crystal Castles (version 3, German)", MACHINE_SUPPORTS_SAVE ) +GAME( 1983, ccastles, 0, ccastles, ccastles, ccastles_state, empty_init, ROT0, "Atari", "Crystal Castles (version 4)", MACHINE_SUPPORTS_SAVE ) +GAME( 1983, ccastlesg, ccastles, ccastles, ccastles, ccastles_state, empty_init, ROT0, "Atari", "Crystal Castles (version 3, German)", MACHINE_SUPPORTS_SAVE ) GAME( 1983, ccastlesp, ccastles, ccastles, ccastles, ccastles_state, empty_init, ROT0, "Atari", "Crystal Castles (version 3, Spanish)", MACHINE_SUPPORTS_SAVE ) -GAME( 1983, ccastlesf, ccastles, ccastles, ccastles, ccastles_state, empty_init, ROT0, "Atari", "Crystal Castles (version 3, French)", MACHINE_SUPPORTS_SAVE ) -GAME( 1983, ccastles3, ccastles, ccastles, ccastles, ccastles_state, empty_init, ROT0, "Atari", "Crystal Castles (version 3)", MACHINE_SUPPORTS_SAVE ) -GAME( 1983, ccastles2, ccastles, ccastles, ccastles, ccastles_state, empty_init, ROT0, "Atari", "Crystal Castles (version 2)", MACHINE_SUPPORTS_SAVE ) -GAME( 1983, ccastles1, ccastles, ccastles, ccastles, ccastles_state, empty_init, ROT0, "Atari", "Crystal Castles (version 1)", MACHINE_SUPPORTS_SAVE ) -GAME( 1983, ccastlesj, ccastles, ccastles, ccastlesj, ccastles_state, empty_init, ROT0, "Atari", "Crystal Castles (joystick version)", MACHINE_SUPPORTS_SAVE ) +GAME( 1983, ccastlesf, ccastles, ccastles, ccastles, ccastles_state, empty_init, ROT0, "Atari", "Crystal Castles (version 3, French)", MACHINE_SUPPORTS_SAVE ) +GAME( 1983, ccastles3, ccastles, ccastles, ccastles, ccastles_state, empty_init, ROT0, "Atari", "Crystal Castles (version 3)", MACHINE_SUPPORTS_SAVE ) +GAME( 1983, ccastles2, ccastles, ccastles, ccastles, ccastles_state, empty_init, ROT0, "Atari", "Crystal Castles (version 2)", MACHINE_SUPPORTS_SAVE ) +GAME( 1983, ccastles1, ccastles, ccastles, ccastles, ccastles_state, empty_init, ROT0, "Atari", "Crystal Castles (version 1)", MACHINE_SUPPORTS_SAVE ) +GAME( 1983, ccastlesj, ccastles, ccastles, ccastlesj, ccastles_state, empty_init, ROT0, "Atari", "Crystal Castles (joystick version)", MACHINE_SUPPORTS_SAVE ) diff --git a/src/mame/atari/ccastles.h b/src/mame/atari/ccastles.h deleted file mode 100644 index 76796c2c28d..00000000000 --- a/src/mame/atari/ccastles.h +++ /dev/null @@ -1,97 +0,0 @@ -// license:BSD-3-Clause -// copyright-holders:Aaron Giles -/************************************************************************* - - Atari Crystal Castles hardware - -*************************************************************************/ -#ifndef MAME_ATARI_CCASTLES_H -#define MAME_ATARI_CCASTLES_H - -#pragma once - -#include "cpu/m6502/m6502.h" -#include "machine/74259.h" -#include "machine/x2212.h" -#include "emupal.h" -#include "screen.h" - -class ccastles_state : public driver_device -{ -public: - ccastles_state(const machine_config &mconfig, device_type type, const char *tag) : - driver_device(mconfig, type, tag), - m_maincpu(*this, "maincpu"), - m_nvram_4b(*this, "nvram_4b"), - m_nvram_4a(*this, "nvram_4a"), - m_outlatch(*this, "outlatch%u", 0U), - m_videoram(*this, "videoram"), - m_spriteram(*this, "spriteram"), - m_gfxdecode(*this, "gfxdecode"), - m_screen(*this, "screen"), - m_palette(*this, "palette") - { } - - int vblank_r(); - void ccastles(machine_config &config); - -protected: - void irq_ack_w(uint8_t data); - uint8_t leta_r(offs_t offset); - void nvram_recall_w(uint8_t data); - void nvram_store_w(int state); - uint8_t nvram_r(address_space &space, offs_t offset); - void nvram_w(offs_t offset, uint8_t data); - void ccastles_hscroll_w(uint8_t data); - void ccastles_vscroll_w(uint8_t data); - void ccastles_video_control_w(offs_t offset, uint8_t data); - void ccastles_paletteram_w(offs_t offset, uint8_t data); - void ccastles_videoram_w(offs_t offset, uint8_t data); - uint8_t ccastles_bitmode_r(); - void ccastles_bitmode_w(uint8_t data); - void ccastles_bitmode_addr_w(offs_t offset, uint8_t data); - virtual void machine_start() override; - virtual void machine_reset() override; - virtual void video_start() override; - uint32_t screen_update_ccastles(screen_device &screen, bitmap_ind16 &bitmap, const rectangle &cliprect); - TIMER_CALLBACK_MEMBER(clock_irq); - inline void ccastles_write_vram( uint16_t addr, uint8_t data, uint8_t bitmd, uint8_t pixba ); - inline void bitmode_autoinc( ); - inline void schedule_next_irq( int curscanline ); - void main_map(address_map &map); - -private: - /* devices */ - required_device m_maincpu; - required_device m_nvram_4b; - required_device m_nvram_4a; - required_device_array m_outlatch; - - /* memory pointers */ - required_shared_ptr m_videoram; - required_shared_ptr m_spriteram; - - required_device m_gfxdecode; - required_device m_screen; - required_device m_palette; - - /* video-related */ - const uint8_t *m_syncprom = nullptr; - const uint8_t *m_wpprom = nullptr; - const uint8_t *m_priprom = nullptr; - bitmap_ind16 m_spritebitmap = 0; - double m_rweights[3]{}; - double m_gweights[3]{}; - double m_bweights[3]{}; - uint8_t m_bitmode_addr[2]{}; - uint8_t m_hscroll = 0U; - uint8_t m_vscroll = 0U; - - /* misc */ - int m_vblank_start = 0; - int m_vblank_end = 0; - emu_timer *m_irq_timer = nullptr; - uint8_t m_irq_state = 0U; -}; - -#endif // MAME_ATARI_CCASTLES_H diff --git a/src/mame/atari/ccastles_v.cpp b/src/mame/atari/ccastles_v.cpp deleted file mode 100644 index fa962a4bd16..00000000000 --- a/src/mame/atari/ccastles_v.cpp +++ /dev/null @@ -1,344 +0,0 @@ -// license:BSD-3-Clause -// copyright-holders:Aaron Giles -/*************************************************************************** - - Atari Crystal Castles hardware - -***************************************************************************/ - -#include "emu.h" -#include "ccastles.h" -#include "video/resnet.h" - - -/************************************* - * - * Video startup - * - *************************************/ - -void ccastles_state::video_start() -{ - static const int resistances[3] = { 22000, 10000, 4700 }; - - /* get pointers to our PROMs */ - m_syncprom = memregion("proms")->base() + 0x000; - m_wpprom = memregion("proms")->base() + 0x200; - m_priprom = memregion("proms")->base() + 0x300; - - /* compute the color output resistor weights at startup */ - compute_resistor_weights(0, 255, -1.0, - 3, resistances, m_rweights, 1000, 0, - 3, resistances, m_gweights, 1000, 0, - 3, resistances, m_bweights, 1000, 0); - - /* allocate a bitmap for drawing sprites */ - m_screen->register_screen_bitmap(m_spritebitmap); - - /* register for savestates */ - save_item(NAME(m_bitmode_addr)); - save_item(NAME(m_hscroll)); - save_item(NAME(m_vscroll)); -} - - - -/************************************* - * - * Video control registers - * - *************************************/ - -void ccastles_state::ccastles_hscroll_w(uint8_t data) -{ - m_screen->update_partial(m_screen->vpos()); - m_hscroll = data; -} - - -void ccastles_state::ccastles_vscroll_w(uint8_t data) -{ - m_vscroll = data; -} - - -void ccastles_state::ccastles_video_control_w(offs_t offset, uint8_t data) -{ - /* only D3 matters */ - m_outlatch[1]->write_bit(offset, BIT(data, 3)); -} - - - -/************************************* - * - * Palette RAM accesses - * - *************************************/ - -void ccastles_state::ccastles_paletteram_w(offs_t offset, uint8_t data) -{ - int bit0, bit1, bit2; - int r, g, b; - - /* extract the raw RGB bits */ - r = ((data & 0xc0) >> 6) | ((offset & 0x20) >> 3); - b = (data & 0x38) >> 3; - g = (data & 0x07); - - /* red component (inverted) */ - bit0 = (~r >> 0) & 0x01; - bit1 = (~r >> 1) & 0x01; - bit2 = (~r >> 2) & 0x01; - r = combine_weights(m_rweights, bit0, bit1, bit2); - - /* green component (inverted) */ - bit0 = (~g >> 0) & 0x01; - bit1 = (~g >> 1) & 0x01; - bit2 = (~g >> 2) & 0x01; - g = combine_weights(m_gweights, bit0, bit1, bit2); - - /* blue component (inverted) */ - bit0 = (~b >> 0) & 0x01; - bit1 = (~b >> 1) & 0x01; - bit2 = (~b >> 2) & 0x01; - b = combine_weights(m_bweights, bit0, bit1, bit2); - - m_palette->set_pen_color(offset & 0x1f, rgb_t(r, g, b)); -} - - - -/************************************* - * - * Video RAM access via the write - * protect PROM - * - *************************************/ - -inline void ccastles_state::ccastles_write_vram( uint16_t addr, uint8_t data, uint8_t bitmd, uint8_t pixba ) -{ - uint8_t *dest = &m_videoram[addr & 0x7ffe]; - uint8_t promaddr = 0; - uint8_t wpbits; - - /* - Inputs to the write-protect PROM: - - Bit 7 = BA1520 = 0 if (BA15-BA12 != 0), or 1 otherwise - Bit 6 = DRBA11 - Bit 5 = DRBA10 - Bit 4 = /BITMD - Bit 3 = GND - Bit 2 = BA0 - Bit 1 = PIXB - Bit 0 = PIXA - */ - promaddr |= ((addr & 0xf000) == 0) << 7; - promaddr |= (addr & 0x0c00) >> 5; - promaddr |= (!bitmd) << 4; - promaddr |= (addr & 0x0001) << 2; - promaddr |= (pixba << 0); - - /* look up the PROM result */ - wpbits = m_wpprom[promaddr]; - - /* write to the appropriate parts of VRAM depending on the result */ - if (!(wpbits & 1)) - dest[0] = (dest[0] & 0xf0) | (data & 0x0f); - if (!(wpbits & 2)) - dest[0] = (dest[0] & 0x0f) | (data & 0xf0); - if (!(wpbits & 4)) - dest[1] = (dest[1] & 0xf0) | (data & 0x0f); - if (!(wpbits & 8)) - dest[1] = (dest[1] & 0x0f) | (data & 0xf0); -} - - - -/************************************* - * - * Autoincrement control for bit mode - * - *************************************/ - -inline void ccastles_state::bitmode_autoinc( ) -{ - /* auto increment in the x-direction if it's enabled */ - if (!m_outlatch[1]->q0_r()) /* /AX */ - { - if (!m_outlatch[1]->q2_r()) /* /XINC */ - m_bitmode_addr[0]++; - else - m_bitmode_addr[0]--; - } - - /* auto increment in the y-direction if it's enabled */ - if (!m_outlatch[1]->q1_r()) /* /AY */ - { - if (!m_outlatch[1]->q3_r()) /* /YINC */ - m_bitmode_addr[1]++; - else - m_bitmode_addr[1]--; - } -} - - - -/************************************* - * - * Standard video RAM access - * - *************************************/ - -void ccastles_state::ccastles_videoram_w(offs_t offset, uint8_t data) -{ - /* direct writes to VRAM go through the write protect PROM as well */ - ccastles_write_vram(offset, data, 0, 0); -} - - - -/************************************* - * - * Bit mode video RAM access - * - *************************************/ - -uint8_t ccastles_state::ccastles_bitmode_r() -{ - /* in bitmode, the address comes from the autoincrement latches */ - uint16_t addr = (m_bitmode_addr[1] << 7) | (m_bitmode_addr[0] >> 1); - - /* the appropriate pixel is selected into the upper 4 bits */ - uint8_t result = m_videoram[addr] << ((~m_bitmode_addr[0] & 1) * 4); - - /* autoincrement because /BITMD was selected */ - bitmode_autoinc(); - - /* the low 4 bits of the data lines are not driven so make them all 1's */ - return result | 0x0f; -} - - -void ccastles_state::ccastles_bitmode_w(uint8_t data) -{ - /* in bitmode, the address comes from the autoincrement latches */ - uint16_t addr = (m_bitmode_addr[1] << 7) | (m_bitmode_addr[0] >> 1); - - /* the upper 4 bits of data are replicated to the lower 4 bits */ - data = (data & 0xf0) | (data >> 4); - - /* write through the generic VRAM routine, passing the low 2 X bits as PIXB/PIXA */ - ccastles_write_vram(addr, data, 1, m_bitmode_addr[0] & 3); - - /* autoincrement because /BITMD was selected */ - bitmode_autoinc(); -} - - -void ccastles_state::ccastles_bitmode_addr_w(offs_t offset, uint8_t data) -{ - /* write through to video RAM and also to the addressing latches */ - ccastles_write_vram(offset, data, 0, 0); - m_bitmode_addr[offset] = data; -} - - - -/************************************* - * - * Video updating - * - *************************************/ - -uint32_t ccastles_state::screen_update_ccastles(screen_device &screen, bitmap_ind16 &bitmap, const rectangle &cliprect) -{ - uint8_t const *const spriteaddr = &m_spriteram[m_outlatch[1]->q7_r() * 0x100]; /* BUF1/BUF2 */ - int const flip = m_outlatch[1]->q4_r() ? 0xff : 0x00; /* PLAYER2 */ - pen_t const black = m_palette->black_pen(); - - /* draw the sprites */ - m_spritebitmap.fill(0x0f, cliprect); - for (int offs = 0; offs < 320/2; offs += 4) - { - int const x = spriteaddr[offs + 3]; - int const y = 256 - 16 - spriteaddr[offs + 1]; - int const which = spriteaddr[offs]; - int const color = spriteaddr[offs + 2] >> 7; - - m_gfxdecode->gfx(0)->transpen(m_spritebitmap,cliprect, which, color, flip, flip, x, y, 7); - } - - /* draw the bitmap to the screen, looping over Y */ - for (int y = cliprect.top(); y <= cliprect.bottom(); y++) - { - uint16_t *const dst = &bitmap.pix(y); - - /* if we're in the VBLANK region, just fill with black */ - if (m_syncprom[y] & 1) - { - for (int x = cliprect.left(); x <= cliprect.right(); x++) - dst[x] = black; - } - - /* non-VBLANK region: merge the sprites and the bitmap */ - else - { - uint16_t const *const mosrc = &m_spritebitmap.pix(y); - - /* the "POTATO" chip does some magic here; this is just a guess */ - int effy = (((y - m_vblank_end) + (flip ? 0 : m_vscroll)) ^ flip) & 0xff; - if (effy < 24) - effy = 24; - uint8_t const *const src = &m_videoram[effy * 128]; - - /* loop over X */ - for (int x = cliprect.left(); x <= cliprect.right(); x++) - { - /* if we're in the HBLANK region, just store black */ - if (x >= 256) - dst[x] = black; - - /* otherwise, process normally */ - else - { - int const effx = (m_hscroll + (x ^ flip)) & 255; - - /* low 4 bits = left pixel, high 4 bits = right pixel */ - uint8_t pix = (src[effx / 2] >> ((effx & 1) * 4)) & 0x0f; - uint8_t const mopix = mosrc[x]; - - /* Inputs to the priority PROM: - - Bit 7 = GND - Bit 6 = /CRAM - Bit 5 = BA4 - Bit 4 = MV2 - Bit 3 = MV1 - Bit 2 = MV0 - Bit 1 = MPI - Bit 0 = BIT3 - */ - uint8_t prindex; - prindex = 0x40; - prindex |= (mopix & 7) << 2; - prindex |= (mopix & 8) >> 2; - prindex |= (pix & 8) >> 3; - uint8_t const prvalue = m_priprom[prindex]; - - /* Bit 1 of prvalue selects the low 4 bits of the final pixel */ - if (prvalue & 2) - pix = mopix; - - /* Bit 0 of prvalue selects bit 4 of the final color */ - pix |= (prvalue & 1) << 4; - - /* store the pixel value and also a priority value based on the topmost bit */ - dst[x] = pix; - } - } - } - } - return 0; -} -- cgit v1.2.3