From f7c06306e08d3cf024ce21405e48facbdc5881da Mon Sep 17 00:00:00 2001 From: Vas Crabb Date: Wed, 25 Sep 2024 00:17:08 +1000 Subject: misc/changyu.cpp: Implemented changyu2 MCU communication well enough to get attract mode working with music. --- src/devices/bus/a2gameio/brightpen.cpp | 2 +- src/mame/misc/changyu.cpp | 162 ++++++++++++++++++++++++--------- 2 files changed, 121 insertions(+), 43 deletions(-) diff --git a/src/devices/bus/a2gameio/brightpen.cpp b/src/devices/bus/a2gameio/brightpen.cpp index 6429b16b5f2..c018b92baf1 100644 --- a/src/devices/bus/a2gameio/brightpen.cpp +++ b/src/devices/bus/a2gameio/brightpen.cpp @@ -126,7 +126,7 @@ int apple2_brightpen_device::sw0_r() } // light detected if average brightness is above threshold - return (brightness_sum >= BRIGHTNESS_THRESHOLD * pixels_scanned); + return brightness_sum >= BRIGHTNESS_THRESHOLD * pixels_scanned; } } // anonymous namespace diff --git a/src/mame/misc/changyu.cpp b/src/mame/misc/changyu.cpp index 7a6275f70cd..772f9d00500 100644 --- a/src/mame/misc/changyu.cpp +++ b/src/mame/misc/changyu.cpp @@ -45,6 +45,7 @@ main PCB (marked 9101): #include "cpu/m6502/m6502.h" #include "cpu/mcs51/mcs51.h" +#include "machine/gen_latch.h" #include "sound/ay8910.h" #include "sound/hc55516.h" #include "sound/ymopl.h" @@ -71,10 +72,14 @@ public: { } - void changyu(machine_config &config); - void changyu2(machine_config &config); + void changyu(machine_config &config) ATTR_COLD; protected: + virtual void machine_start() override ATTR_COLD; + virtual void video_start() override ATTR_COLD; + + void common_map(address_map &map) ATTR_COLD; + required_device m_maincpu; required_device m_mcu; required_device m_crtc; @@ -83,24 +88,49 @@ protected: required_shared_ptr m_videoram; private: - uint32_t screen_update(screen_device &screen, bitmap_ind16 &bitmap, const rectangle &cliprect); - void palette_init(palette_device &palette) const; - - void main_map(address_map &map); - void main2_map(address_map &map); - void prog2_map(address_map &map); - void ext2_map(address_map &map); - - virtual void machine_start() override; + void palette_init(palette_device &palette) const ATTR_COLD; - tilemap_t *m_bg_tilemap{}; + void main_map(address_map &map) ATTR_COLD; - virtual void video_start() override; TILE_GET_INFO_MEMBER(get_bg_tile_info); void videoram_w(offs_t offset, u8 data); + + tilemap_t *m_bg_tilemap = nullptr; }; + +class changyu2_state : public changyu_state +{ +public: + changyu2_state(const machine_config &mconfig, device_type type, const char *tag) + : changyu_state(mconfig, type, tag) + , m_mcu_response_latch(*this, "mcu_response") + { + } + + void changyu2(machine_config &config) ATTR_COLD; + +protected: + virtual void machine_start() override ATTR_COLD; + +private: + void main2_map(address_map &map) ATTR_COLD; + void ext2_map(address_map &map) ATTR_COLD; + + void mcu_cmd_w(u8 data); + void mcu_ctrl_w(u8 data); + u8 mcu_status_r(); + u8 mcu_cmd_r(); + u8 mcu_p1_r(); + TIMER_CALLBACK_MEMBER(set_mcu_cmd); + + required_device m_mcu_response_latch; + + u8 m_mcu_cmd = 0; +}; + + void changyu_state::palette_init(palette_device &palette) const { uint8_t const *const color_prom = memregion("proms")->base(); @@ -130,11 +160,37 @@ void changyu_state::videoram_w(offs_t offset, u8 data) m_bg_tilemap->mark_tile_dirty(offset & 0x7ff); } -void changyu_state::video_start() +void changyu2_state::mcu_cmd_w(u8 data) { - m_bg_tilemap = &machine().tilemap().create(*m_gfxdecode, tilemap_get_info_delegate(*this, FUNC(changyu_state::get_bg_tile_info)), TILEMAP_SCAN_ROWS, 8, 8, 64, 32); + machine().scheduler().perfect_quantum(attotime::from_usec(50)); // enough time for the MCU to take the interrupt about to be triggered + machine().scheduler().synchronize(timer_expired_delegate(FUNC(changyu2_state::set_mcu_cmd), this), s32(u32(data))); +} -// m_bg_tilemap->set_transparent_pen(0); +void changyu2_state::mcu_ctrl_w(u8 data) +{ + // other bits unknown + m_mcu->set_input_line(MCS51_INT0_LINE, BIT(data, 7) ? CLEAR_LINE : ASSERT_LINE); +} + +u8 changyu2_state::mcu_status_r() +{ + // other bits unknown + return m_mcu_response_latch->pending_r() ? 0x01 : 0x00; +} + +u8 changyu2_state::mcu_cmd_r() +{ + return m_mcu_cmd; +} + +u8 changyu2_state::mcu_p1_r() +{ + return m_mcu_response_latch->pending_r() ? 0x7f : 0xff; +} + +TIMER_CALLBACK_MEMBER(changyu2_state::set_mcu_cmd) +{ + m_mcu_cmd = u8(u32(param)); } uint32_t changyu_state::screen_update(screen_device &screen, bitmap_ind16 &bitmap, const rectangle &cliprect) @@ -144,36 +200,42 @@ uint32_t changyu_state::screen_update(screen_device &screen, bitmap_ind16 &bitma return 0; } -void changyu_state::main_map(address_map &map) +void changyu_state::common_map(address_map &map) { + map.unmap_value_high(); + map(0x0000, 0x0fff).ram(); - map(0x1000, 0x1fff).ram().w(FUNC(changyu_state::videoram_w)).share("videoram"); + map(0x1000, 0x1fff).ram().w(FUNC(changyu_state::videoram_w)).share(m_videoram); +} + +void changyu_state::main_map(address_map &map) +{ + common_map(map); + map(0x3000, 0x37ff).ram(); + map(0x8000, 0xffff).rom().region("boot_rom", 0x8000); } -void changyu_state::main2_map(address_map &map) +void changyu2_state::main2_map(address_map &map) { - map.unmap_value_high(); - main_map(map); + common_map(map); + map(0x2030, 0x2030).w(m_crtc, FUNC(mc6845_device::address_w)); map(0x2031, 0x2031).rw(m_crtc, FUNC(mc6845_device::register_r), FUNC(mc6845_device::register_w)); + map(0x2038, 0x2038).w(FUNC(changyu2_state::mcu_cmd_w)); map(0x2800, 0x2801).w("ymsnd", FUNC(ym2413_device::write)); - - map(0x3000, 0x37ff).unmaprw(); + map(0x2808, 0x2808).r(FUNC(changyu2_state::mcu_status_r)); + map(0x2020, 0x2020).r(m_mcu_response_latch, FUNC(generic_latch_8_device::read)); + map(0x3000, 0x3000).w(FUNC(changyu2_state::mcu_ctrl_w)); map(0x6000, 0xffff).rom().region("boot_rom", 0x6000); } -void changyu_state::prog2_map(address_map &map) -{ - - map(0x0000, 0xfff).rom().region("mcu", 0); -} - - -void changyu_state::ext2_map(address_map &map) +void changyu2_state::ext2_map(address_map &map) { + map(0x0300, 0x0300).r(FUNC(changyu2_state::mcu_cmd_r)); + map(0x0400, 0x0400).w(m_mcu_response_latch, FUNC(generic_latch_8_device::write)); map(0x0502, 0x0503).w("ay", FUNC(ay8910_device::data_address_w)); } @@ -234,6 +296,20 @@ void changyu_state::machine_start() { } +void changyu2_state::machine_start() +{ + changyu_state::machine_start(); + + save_item(NAME(m_mcu_cmd)); +} + +void changyu_state::video_start() +{ + m_bg_tilemap = &machine().tilemap().create(*m_gfxdecode, tilemap_get_info_delegate(*this, FUNC(changyu_state::get_bg_tile_info)), TILEMAP_SCAN_ROWS, 8, 8, 64, 32); + +// m_bg_tilemap->set_transparent_pen(0); +} + static GFXDECODE_START( gfx_changyu ) GFXDECODE_ENTRY( "gfx1", 0, gfx_8x8x4_planar, 0, 16 ) GFXDECODE_END @@ -267,22 +343,24 @@ void changyu_state::changyu(machine_config &config) /* sound hardware */ SPEAKER(config, "mono").front_center(); - AY8910(config, "ay", XTAL(12'000'000 / 6)).add_route(ALL_OUTPUTS, "mono", 1.00); // divisor not verified + AY8910(config, "ay", XTAL(12'000'000 / 6)).add_route(ALL_OUTPUTS, "mono", 0.9); // divisor not verified - HC55516(config, "voice", XTAL(12'000'000 / 6)).add_route(ALL_OUTPUTS, "mono", 1.00); // UM5100 is a HC55536 with ROM hook-up, divisor not verified + HC55516(config, "voice", XTAL(12'000'000 / 6)).add_route(ALL_OUTPUTS, "mono", 0.9); // UM5100 is a HC55536 with ROM hook-up, divisor not verified } -void changyu_state::changyu2(machine_config &config) +void changyu2_state::changyu2(machine_config &config) { changyu(config); - m_maincpu->set_addrmap(AS_PROGRAM, &changyu_state::main2_map); - I87C51(config.replace(), m_mcu, XTAL(8'000'000)); -// m_mcu->set_disable(); - m_mcu->set_addrmap(AS_PROGRAM, &changyu_state::prog2_map); - m_mcu->set_addrmap(AS_IO, &changyu_state::ext2_map); + m_maincpu->set_addrmap(AS_PROGRAM, &changyu2_state::main2_map); + + auto &mcu(I87C51(config.replace(), m_mcu, XTAL(8'000'000))); + mcu.set_addrmap(AS_IO, &changyu2_state::ext2_map); + mcu.port_in_cb<0>().set(FUNC(changyu2_state::mcu_p1_r)); + + GENERIC_LATCH_8(config, m_mcu_response_latch); - YM2413(config, "ymsnd", 3.579545_MHz_XTAL).add_route(ALL_OUTPUTS, "mono", 1.0); + YM2413(config, "ymsnd", 3.579545_MHz_XTAL).add_route(ALL_OUTPUTS, "mono", 0.9); } ROM_START( changyu ) @@ -353,5 +431,5 @@ ROM_END } // anonymous namespace -GAME( 1989, changyu, 0, changyu, changyu, changyu_state, empty_init, ROT0, "Chang Yu Electronic", "unknown Chang Yu Electronic gambling game 1", MACHINE_IS_SKELETON ) // Wing Co. in GFX1, year taken from start of maincpu ROM -GAME( 19??, changyu2, 0, changyu2, changyu, changyu_state, empty_init, ROT0, "Chang Yu Electronic", "unknown Chang Yu Electronic gambling game 2", MACHINE_IS_SKELETON ) // Wing Co. in GFX1 +GAME( 1989, changyu, 0, changyu, changyu, changyu_state, empty_init, ROT0, "Chang Yu Electronic", "unknown Chang Yu Electronic gambling game 1", MACHINE_IS_SKELETON ) // Wing Co. in GFX1, year taken from start of maincpu ROM +GAME( 19??, changyu2, 0, changyu2, changyu, changyu2_state, empty_init, ROT0, "Chang Yu Electronic", "unknown Chang Yu Electronic gambling game 2", MACHINE_IS_SKELETON ) // Wing Co. in GFX1 -- cgit v1.2.3