diff options
author | David Haywood <28625134+DavidHaywood@users.noreply.github.com> | 2020-11-18 08:19:38 +0000 |
---|---|---|
committer | GitHub <noreply@github.com> | 2020-11-18 19:19:38 +1100 |
commit | 572be478e0cec1e08a7d1d4e166eceeab671d849 (patch) | |
tree | ab2632c1ee01014777dc32d6830078f033689c08 | |
parent | 310c5d02ce7c55b7ac6b3b2f5d52537a68a83266 (diff) |
vicdual.cpp: Simulate protection for carnivalh and carnivalha. [David Haywood]
-rw-r--r-- | src/mame/drivers/vicdual.cpp | 64 | ||||
-rw-r--r-- | src/mame/includes/vicdual.h | 24 |
2 files changed, 81 insertions, 7 deletions
diff --git a/src/mame/drivers/vicdual.cpp b/src/mame/drivers/vicdual.cpp index 90cda190337..fb28d89e326 100644 --- a/src/mame/drivers/vicdual.cpp +++ b/src/mame/drivers/vicdual.cpp @@ -273,6 +273,18 @@ void carnival_state::machine_start() save_item(NAME(m_musicBus)); } +void carnivalh_state::machine_start() +{ + carnival_state::machine_start(); + + m_previousaddress = 0; + m_previousvalue = 0; + + save_item(NAME(m_previousaddress)); + save_item(NAME(m_previousvalue)); +} + + void tranqgun_state::machine_start() { vicdual_state::machine_start(); @@ -764,7 +776,7 @@ INPUT_PORTS_END static INPUT_PORTS_START( carnivalh ) PORT_START("IN0") PORT_BIT( 0x01, IP_ACTIVE_LOW, IPT_START1 ) - PORT_BIT( 0x02, IP_ACTIVE_LOW, IPT_UNKNOWN ) // IPT_START2, but not implemented in game? - it goes game-over after player 1's turn + PORT_BIT( 0x02, IP_ACTIVE_LOW, IPT_START2 ) PORT_BIT( 0x04, IP_ACTIVE_LOW, IPT_UNKNOWN ) PORT_BIT( 0x08, IP_ACTIVE_LOW, IPT_BUTTON1 ) PORT_BIT( 0x10, IP_ACTIVE_LOW, IPT_JOYSTICK_RIGHT ) PORT_2WAY @@ -1264,6 +1276,47 @@ void tranqgun_state::tranqgun_dualgame_map(address_map &map) map(0x4000, 0x7fff).rw(FUNC(tranqgun_state::tranqgun_prot_r), FUNC(tranqgun_state::tranqgun_prot_w)); } +uint8_t carnivalh_state::carnivalh_prot_r(offs_t offset) +{ + // There appear to be 2 protection functions in the code + // The first one is called if a duck gets to the bottom of the screen, or if Player 1 Game Over condition is reached and Player 2 needs to start + // The second one is called when you complete a bonus round + + uint8_t retdat = 0; + + if (/*((m_previousaddress == 0xe3d4) || (m_previousaddress == 0xe76b)) && */(m_previousvalue == 0x24)) + retdat = 0x02; + else if (/*((m_previousaddress == 0xe3d4) || (m_previousaddress == 0xe76d)) && */(m_previousvalue == 0x66)) + retdat = 0x07; + else if (/*((m_previousaddress == 0xe3d4) || (m_previousaddress == 0xe76f)) && */(m_previousvalue == 0x48)) + retdat = 0x03; + else + popmessage("%s: carnivalh_prot_r %04x %04x %02x\n", machine().describe_context(), offset, m_previousaddress, m_previousvalue); + + return retdat; +} + +void carnivalh_state::carnivalh_prot_w(offs_t offset, uint8_t data) +{ + // the protection writes appear to overlay regular RAM areas? + // protection writes are to 0xe76b, 0xe76d, 0xe76f for one function and 0xe3d4 for the other (see code at 0x26AF & 0x2892) + + m_previousaddress = offset+0xe000; + m_previousvalue = data; + + // fall through to usual accesses (write to the non-mirror address so we're not recursive) + address_space& spc = m_maincpu->space(AS_PROGRAM); + spc.write_byte(0x8000+offset, data); +} + + +void carnivalh_state::carnivalh_dualgame_map(address_map &map) +{ + vicdual_dualgame_map(map); + map(0x4000, 0x7fff).r(FUNC(carnivalh_state::carnivalh_prot_r)); + map(0xe000, 0xefff).w(FUNC(carnivalh_state::carnivalh_prot_w)); +} + void vicdual_state::carhntds_dualgame_map(address_map &map) { map(0x0000, 0x7fff).rom(); // also has part of a rom mapped at 0x4000 @@ -2285,12 +2338,13 @@ void carnival_state::carnivalb(machine_config &config) carnivalb_audio(config); } -void carnival_state::carnivalh(machine_config &config) +void carnivalh_state::carnivalh(machine_config &config) { carnival(config); /* basic machine hardware */ - m_maincpu->set_addrmap(AS_IO, &carnival_state::headon_io_map); + m_maincpu->set_addrmap(AS_PROGRAM, &carnivalh_state::carnivalh_dualgame_map); + m_maincpu->set_addrmap(AS_IO, &carnivalh_state::headon_io_map); } @@ -4067,8 +4121,8 @@ GAME( 1980, spacetrkc, spacetrk, spacetrk, spacetrkc, vicdual_state, empty_in GAME( 1980, carnival, 0, carnival, carnival, carnival_state, empty_init, ROT270, "Sega", "Carnival (upright, AY8912 music)", MACHINE_IMPERFECT_SOUND | MACHINE_SUPPORTS_SAVE ) GAME( 1980, carnivalb, carnival, carnivalb, carnival, carnival_state, empty_init, ROT270, "Sega", "Carnival (upright, PIT8253 music)", MACHINE_IMPERFECT_SOUND | MACHINE_SUPPORTS_SAVE ) GAME( 1980, carnivalc, carnival, carnival, carnivalc, carnival_state, empty_init, ROT270, "Sega", "Carnival (cocktail)", MACHINE_IMPERFECT_SOUND | MACHINE_SUPPORTS_SAVE ) -GAME( 1980, carnivalh, carnival, carnivalh, carnivalh, carnival_state, empty_init, ROT270, "Sega", "Carnival (Head On hardware, set 1)", MACHINE_IMPERFECT_SOUND | MACHINE_SUPPORTS_SAVE ) -GAME( 1980, carnivalha, carnival, carnivalh, carnivalh, carnival_state, empty_init, ROT270, "Sega", "Carnival (Head On hardware, set 2)", MACHINE_IMPERFECT_SOUND | MACHINE_SUPPORTS_SAVE ) +GAME( 1980, carnivalh, carnival, carnivalh, carnivalh, carnivalh_state, empty_init, ROT270, "Sega", "Carnival (Head On hardware, set 1)", MACHINE_IMPERFECT_SOUND | MACHINE_SUPPORTS_SAVE ) +GAME( 1980, carnivalha, carnival, carnivalh, carnivalh, carnivalh_state, empty_init, ROT270, "Sega", "Carnival (Head On hardware, set 2)", MACHINE_IMPERFECT_SOUND | MACHINE_SUPPORTS_SAVE ) GAME( 1980, verbena, carnival, carnival, carnival, carnival_state, empty_init, ROT270, "bootleg (Cocamatic)", "Verbena (bootleg of Carnival)", MACHINE_IMPERFECT_SOUND | MACHINE_SUPPORTS_SAVE ) GAME( 1981, brdrline, 0, brdrline, brdrline, vicdual_state, empty_init, ROT270, "Sega", "Borderline", MACHINE_SUPPORTS_SAVE ) GAME( 1981, starrkr, brdrline, brdrline, starrkr, vicdual_state, empty_init, ROT270, "Sega", "Star Raker", MACHINE_IMPERFECT_SOUND | MACHINE_SUPPORTS_SAVE ) diff --git a/src/mame/includes/vicdual.h b/src/mame/includes/vicdual.h index ec9fa53afe8..67798c1c948 100644 --- a/src/mame/includes/vicdual.h +++ b/src/mame/includes/vicdual.h @@ -223,7 +223,6 @@ private: uint8_t m_tranqgun_prot_return; }; - class nsub_state : public vicdual_state { public: @@ -270,7 +269,6 @@ public: void carnival(machine_config &config); void carnivalb(machine_config &config); - void carnivalh(machine_config &config); void carnivala_audio(machine_config &config); void carnivalb_audio(machine_config &config); @@ -302,6 +300,28 @@ protected: void carnivalb_music_port_2_w(uint8_t data); }; +class carnivalh_state : public carnival_state +{ +public: + carnivalh_state(const machine_config &mconfig, device_type type, const char *tag) : + carnival_state(mconfig, type, tag) + { } + + void carnivalh(machine_config &config); + +protected: + virtual void machine_start() override; + +private: + uint8_t carnivalh_prot_r(offs_t offset); + void carnivalh_prot_w(offs_t offset, uint8_t data); + + void carnivalh_dualgame_map(address_map &map); + + uint16_t m_previousaddress; + uint8_t m_previousvalue; +}; + class headonsa_state : public vicdual_state { public: |