diff --git a/src/mame/drivers/mrdo.cpp b/src/mame/drivers/mrdo.cpp index de2fe93b70f..1463ccc4747 100644 --- a/src/mame/drivers/mrdo.cpp +++ b/src/mame/drivers/mrdo.cpp @@ -38,19 +38,6 @@ constexpr XTAL VIDEO_CLOCK = 19.6_MHz_XTAL; } // anonymous namespace - - -/* PAL16R6CN used for protection. The game doesn't clear the screen - if a read from this address doesn't return the value it expects. */ -uint8_t mrdo_state::mrdo_SECRE_r() -{ - uint8_t *RAM = memregion("maincpu")->base(); - - return RAM[m_maincpu->state_int(Z80_HL)]; -} - - - void mrdo_state::main_map(address_map &map) { map(0x0000, 0x7fff).rom(); @@ -60,7 +47,7 @@ void mrdo_state::main_map(address_map &map) map(0x9800, 0x9800).w(FUNC(mrdo_state::mrdo_flipscreen_w)); // screen flip + playfield priority map(0x9801, 0x9801).w("sn1", FUNC(sn76489_device::write)); map(0x9802, 0x9802).w("sn2", FUNC(sn76489_device::write)); - map(0x9803, 0x9803).r(FUNC(mrdo_state::mrdo_SECRE_r)); + map(0x9803, 0x9803).r(FUNC(mrdo_state::mrdo_secre_r)); map(0xa000, 0xa000).portr("P1"); map(0xa001, 0xa001).portr("P2"); map(0xa002, 0xa002).portr("DSW1"); @@ -199,6 +186,17 @@ void mrdo_state::mrdo(machine_config &config) SN76489(config, "sn2", MAIN_CLOCK/2).add_route(ALL_OUTPUTS, "mono", 0.50); // Verified } +void mrdo_state::machine_start() +{ + save_item(NAME(m_pal_u001)); +} + +void mrdo_state::machine_reset() +{ + // initial outputs are high on power-up + m_pal_u001 = 0xff; +} + void mrdo_state::mrlo(machine_config &config) { mrdo(config); diff --git a/src/mame/includes/mrdo.h b/src/mame/includes/mrdo.h index 331894c97f7..fdab799f466 100644 --- a/src/mame/includes/mrdo.h +++ b/src/mame/includes/mrdo.h @@ -33,6 +33,9 @@ public: protected: virtual void video_start() override; + virtual void machine_start() override; + virtual void machine_reset() override; + private: // memory pointers required_shared_ptr m_bgvideoram; @@ -47,8 +50,10 @@ private: tilemap_t *m_bg_tilemap; tilemap_t *m_fg_tilemap; int m_flipscreen; + uint8_t m_pal_u001; + + uint8_t mrdo_secre_r(); - uint8_t mrdo_SECRE_r(); void mrdo_bgvideoram_w(offs_t offset, uint8_t data); void mrdo_fgvideoram_w(offs_t offset, uint8_t data); void mrdo_scrollx_w(uint8_t data); diff --git a/src/mame/video/mrdo.cpp b/src/mame/video/mrdo.cpp index 51ddcff46f1..b28a1465b73 100644 --- a/src/mame/video/mrdo.cpp +++ b/src/mame/video/mrdo.cpp @@ -185,13 +185,59 @@ void mrdo_state::mrdo_bgvideoram_w(offs_t offset, uint8_t data) m_bg_tilemap->mark_tile_dirty(offset & 0x3ff); } +/* PAL16R6CN used for protection. The game doesn't clear the screen + if a read from this address doesn't return the value it expects. */ +uint8_t mrdo_state::mrdo_secre_r() +{ + return m_pal_u001; +} + void mrdo_state::mrdo_fgvideoram_w(offs_t offset, uint8_t data) { m_fgvideoram[offset] = data; m_fg_tilemap->mark_tile_dirty(offset & 0x3ff); + + // protection. each write latches a new value on IC u001 (PAL16R6) + const uint8_t i9 = BIT(data,0); + const uint8_t i8 = BIT(data,1); +// const uint8_t i7 = BIT(data,2); pin 7 not used in equations + const uint8_t i6 = BIT(data,3); + const uint8_t i5 = BIT(data,4); + const uint8_t i4 = BIT(data,5); + const uint8_t i3 = BIT(data,6); + const uint8_t i2 = BIT(data,7); + + // equations extracted from dump using jedutil + const uint8_t t1 = i2 & (1^i3) & i4 & (1^i5) & (1^i6) & (1^i8) & i9; + const uint8_t t2 = (1^i2) & (1^i3) & i4 & i5 & (1^i6) & i8 & (1^i9); + const uint8_t t3 = i2 & i3 & (1^i4) & (1^i5) & i6 & (1^i8) & i9; + const uint8_t t4 = (1^i2) & i3 & i4 & (1^i5) & i6 & i8 & i9; + + const uint8_t r12 = 0; + const uint8_t r13 = (1^( t1 )) << 1 ; + const uint8_t r14 = (1^( t1 | t2 )) << 2 ; + const uint8_t r15 = (1^( t1 | t3 )) << 3 ; + const uint8_t r16 = (1^( t1 )) << 4 ; + const uint8_t r17 = (1^( t1 | t3 )) << 5 ; + const uint8_t r18 = (1^( t3 | t4 )) << 6 ; + const uint8_t r19 = 0; + + m_pal_u001 = r19 | r18 | r17 | r16 | r15 | r14 | r13 | r12 ; } +/* +/rf13 := i2 & /i3 & i4 & /i5 & /i6 & /i8 & i9 t1 +/rf14 := /i2 & /i3 & i4 & i5 & /i6 & i8 & /i9 + i2 & /i3 & i4 & /i5 & /i6 & /i8 & i9 t2 | t1 + +/rf15 := i2 & i3 & /i4 & /i5 & i6 & /i8 & i9 + i2 & /i3 & i4 & /i5 & /i6 & /i8 & i9 t3 | t1 + +/rf16 := i2 & /i3 & i4 & /i5 & /i6 & /i8 & i9 t1 + +/rf17 := i2 & i3 & /i4 & /i5 & i6 & /i8 & i9 + i2 & /i3 & i4 & /i5 & /i6 & /i8 & i9 t3 | t1 + +/rf18 := /i2 & i3 & i4 & /i5 & i6 & i8 & i9 + i2 & i3 & /i4 & /i5 & i6 & /i8 & i9 t4 | t2 +*/ void mrdo_state::mrdo_scrollx_w(uint8_t data) { m_bg_tilemap->set_scrollx(0, data);