diff --git a/src/mame/seta/albazg.cpp b/src/mame/seta/albazg.cpp index a952ea13a2c..96416e12a5a 100644 --- a/src/mame/seta/albazg.cpp +++ b/src/mame/seta/albazg.cpp @@ -98,7 +98,7 @@ private: tilemap_t *m_tilemap = nullptr; uint8_t m_port_select = 0; - uint8_t m_prot_lock = 0; + uint8_t m_prot_unlock = 0; required_device m_maincpu; required_shared_ptr m_custom_ram; @@ -165,7 +165,7 @@ uint8_t albazg_state::custom_ram_r(offs_t offset) void albazg_state::custom_ram_w(offs_t offset, uint8_t data) { LOGPROTRAM("Custom RAM write at %02x : %02x PC = %x\n", offset + 0xaf80, data, m_maincpu->pc()); - if (m_prot_lock) + if (m_prot_unlock) m_custom_ram[offset] = data; } @@ -173,7 +173,7 @@ void albazg_state::custom_ram_w(offs_t offset, uint8_t data) void albazg_state::prot_lock_w(uint8_t data) { LOGPROTRAM("PC %04x Prot lock value written %02x\n", m_maincpu->pc(), data); - m_prot_lock = data; + m_prot_unlock = data; } uint8_t albazg_state::key_matrix_r() @@ -348,13 +348,13 @@ void albazg_state::machine_start() m_rombank->configure_entries(0, 4, memregion("maincpu")->base() + 0x8000, 0x2000); save_item(NAME(m_port_select)); - save_item(NAME(m_prot_lock)); + save_item(NAME(m_prot_unlock)); } void albazg_state::machine_reset() { m_port_select = 0; - m_prot_lock = 0; + m_prot_unlock = 0; } void albazg_state::yumefuda(machine_config &config) diff --git a/src/mame/seta/hanadojo.cpp b/src/mame/seta/hanadojo.cpp index aa891bdff92..b55e7dc26c2 100644 --- a/src/mame/seta/hanadojo.cpp +++ b/src/mame/seta/hanadojo.cpp @@ -4,17 +4,19 @@ 花道場 (Hana Doujou) - Alba 1984 AAJ-11 PCB +Test Mode tests a "N-Board I/O" TODO: -- Resets itself in attract sequence, NVRAM thrash protection? +- Uses a form of NVRAM thrash protection, not completely understood: \- bp b6e sub-routine: loops with ld hl,$8f14 de,$0005 expecting all values to be 0x55 or 0xaa; \- writes a 0 to $8f28 the 3rd time around, expecting one of the IOX to prevent that; \- some code uploaded in RAM at $8c00, including an IOX data_w 0x60; \- wpset 0x8f00,0x100,r,PC!=0xb91 \- program and I/O accesses to $b8xx / $bcxx areas; -\- second reset: bp 1a3,1,{a=4;g} for gameplay and attract; +- Resets itself at the end of first attract hand & coin-in sequences +\- bp 1a3,1,{a=4;g} to bypass; - Hookup NMI for coin chutes; -- Eventually uses hopper; +- Hopper plus other bits and bobs ("noise detection" antenna?); - CRTC processes params as 1088x224 with char width 8; - hanadojoa: slightly more protected, keeps resetting at IOX tests; @@ -36,6 +38,11 @@ unknown 40-pin chip (stickered AN-003) 2x AX-014 epoxy covered chips AX-013 epoxy covered chip +=================================================================================================== + +CN1 connects to hopper drive NS-01 +CN2/CN3 connects to 1P/2P control panels + **************************************************************************************************/ #include "emu.h" @@ -63,6 +70,7 @@ public: : driver_device(mconfig, type, tag) , m_maincpu(*this, "maincpu") , m_iox(*this, "iox_%u", 1U) + , m_nvram(*this, "nvram") , m_dswb(*this, "DSWB") , m_dswc(*this, "DSWC") , m_patsw(*this, "PATSW") @@ -75,10 +83,13 @@ public: protected: virtual void video_start() override ATTR_COLD; + virtual void machine_start() override ATTR_COLD; + virtual void machine_reset() override ATTR_COLD; private: required_device m_maincpu; required_device_array m_iox; + required_device m_nvram; required_ioport m_dswb; required_ioport m_dswc; required_ioport m_patsw; @@ -92,6 +103,9 @@ private: void program_map(address_map &map) ATTR_COLD; void io_map(address_map &map) ATTR_COLD; + + bool m_nvram_lock; + std::unique_ptr m_nvram_ptr; }; void hanadojo_state::palette_init(palette_device &palette) const @@ -162,8 +176,15 @@ void hanadojo_state::program_map(address_map &map) { // ldir 0-0x1ff at POST map(0x0000, 0x7fff).rom().nopw(); - map(0x8800, 0x8fff).ram(); - map(0x8f28, 0x8f28).lr8(NAME([] (offs_t offset) { return 0x55; })); + map(0x8800, 0x8eff).ram(); + map(0x8f00, 0x8fff).lrw8( + NAME([this] (offs_t offset) { return m_nvram_ptr[offset]; }), + NAME([this] (offs_t offset, u8 data) { + // NOTE: not all of it, would otherwise never decrease coin counter in-game + if (!m_nvram_lock || (offset & 0x28) != 0x28) + m_nvram_ptr[offset] = data; + }) + ); map(0x9000, 0x97ff).ram().share(m_videoram); } @@ -197,6 +218,7 @@ void hanadojo_state::io_map(address_map &map) } +// TODO: may make more sense to just use IPT_POKER_HOLD* instead. static INPUT_PORTS_START( hanadojo ) PORT_START("P1_KEY0") PORT_BIT( 0x01, IP_ACTIVE_LOW, IPT_UNUSED ) @@ -228,7 +250,7 @@ static INPUT_PORTS_START( hanadojo ) PORT_BIT( 0x04, IP_ACTIVE_LOW, IPT_HANAFUDA_A ) PORT_PLAYER(2) PORT_BIT( 0x08, IP_ACTIVE_LOW, IPT_HANAFUDA_D ) PORT_PLAYER(2) PORT_BIT( 0x10, IP_ACTIVE_LOW, IPT_UNUSED ) - PORT_BIT( 0x20, IP_ACTIVE_LOW, IPT_HANAFUDA_F ) PORT_PLAYER(2) PORT_NAME("P2 Cancel") + PORT_BIT( 0x20, IP_ACTIVE_LOW, IPT_POKER_CANCEL ) PORT_PLAYER(2) PORT_NAME("P2 Cancel") PORT_BIT( 0x40, IP_ACTIVE_LOW, IPT_UNUSED ) PORT_BIT( 0x80, IP_ACTIVE_LOW, IPT_HANAFUDA_B ) PORT_PLAYER(2) @@ -283,18 +305,14 @@ static INPUT_PORTS_START( hanadojo ) // NOTE: DSWD is 4 bit banks, near AY on board. // Game has no clear bank display compared to the others, assume one is SW2 nearby. PORT_START("DSWD") - PORT_DIPNAME( 0x01, 0x00, "ARS" ) + PORT_DIPNAME( 0x01, 0x00, "ARS" ) // Credit Clear PORT_DIPSETTING( 0x00, DEF_STR( Off ) ) PORT_DIPSETTING( 0x01, DEF_STR( On ) ) PORT_DIPNAME( 0x02, 0x00, "RES" ) // RST? PORT_DIPSETTING( 0x00, DEF_STR( Off ) ) PORT_DIPSETTING( 0x02, DEF_STR( On ) ) - PORT_DIPNAME( 0x04, 0x00, "M M" ) - PORT_DIPSETTING( 0x00, DEF_STR( Off ) ) - PORT_DIPSETTING( 0x04, DEF_STR( On ) ) - PORT_DIPNAME( 0x08, 0x00, "CLR" ) - PORT_DIPSETTING( 0x00, DEF_STR( Off ) ) - PORT_DIPSETTING( 0x08, DEF_STR( On ) ) + PORT_BIT( 0x04, IP_ACTIVE_HIGH, IPT_SERVICE1 ) // "M M" -> Memory Mode + PORT_BIT( 0x08, IP_ACTIVE_HIGH, IPT_MEMORY_RESET ) // "CLR" PORT_BIT( 0x10, IP_ACTIVE_HIGH, IPT_GAMBLE_KEYIN ) PORT_DIPNAME( 0x20, 0x00, "MDL" ) PORT_DIPSETTING( 0x00, DEF_STR( Off ) ) @@ -311,6 +329,21 @@ static GFXDECODE_START( gfx_hanadojo ) GFXDECODE_ENTRY( "tiles", 0, gfx_8x8x3_planar, 0, 32 * 2 ) GFXDECODE_END +void hanadojo_state::machine_start() +{ + save_item(NAME(m_nvram_lock)); + + const u32 nvram_size = 0x100; + m_nvram_ptr = std::make_unique(nvram_size); + m_nvram->set_base(m_nvram_ptr.get(), nvram_size); + + save_pointer(NAME(m_nvram_ptr), nvram_size); +} + +void hanadojo_state::machine_reset() +{ + m_nvram_lock = false; +} void hanadojo_state::hanadojo(machine_config &config) { @@ -331,6 +364,8 @@ void hanadojo_state::hanadojo(machine_config &config) // TODO: looks latch inverted compared to the $a0-$a1 version m_iox[1]->p2_direct_input_cb().set([this] () { return (m_dswb->read() & 0x3f) ^ 0x3f; }); + NVRAM(config, "nvram", nvram_device::DEFAULT_ALL_0); + hd6845s_device &crtc(HD6845S(config, "crtc", 12_MHz_XTAL / 4)); // divider guessed crtc.set_screen("screen"); crtc.set_show_border_area(false); @@ -353,7 +388,14 @@ void hanadojo_state::hanadojo(machine_config &config) SPEAKER(config, "speaker").front_center(); ay8910_device &ay(AY8910(config, "ay", 12_MHz_XTAL / 16)); // divider guessed -// ay.port_a_read_callback() + ay.port_a_write_callback().set([this] (u8 data) { + // avoid locking the NVRAM on device startup + if (data == 0xff) + return; + m_nvram_lock = !!BIT(data, 7); + // bit 5 is flip screen, others unknown + logerror("AY Port A: %02x\n", data); + }); ay.port_b_read_callback().set_ioport("DSWA"); ay.add_route(ALL_OUTPUTS, "speaker", 0.33); }