Skip to content

Commit

Permalink
misc/changyu.cpp: Implemented changyu2 MCU communication well enough …
Browse files Browse the repository at this point in the history
…to get attract mode working with music.
  • Loading branch information
cuavas committed Sep 24, 2024
1 parent 8c97667 commit f7c0630
Show file tree
Hide file tree
Showing 2 changed files with 121 additions and 43 deletions.
2 changes: 1 addition & 1 deletion src/devices/bus/a2gameio/brightpen.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -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
Expand Down
162 changes: 120 additions & 42 deletions src/mame/misc/changyu.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -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"
Expand All @@ -71,10 +72,14 @@ class changyu_state : public driver_device
{
}

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<cpu_device> m_maincpu;
required_device<cpu_device> m_mcu;
required_device<mc6845_device> m_crtc;
Expand All @@ -83,24 +88,49 @@ class changyu_state : public driver_device
required_shared_ptr<uint8_t> 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<generic_latch_8_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();
Expand Down Expand Up @@ -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)
Expand All @@ -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));
}

Expand Down Expand Up @@ -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
Expand Down Expand Up @@ -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 )
Expand Down Expand Up @@ -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

0 comments on commit f7c0630

Please sign in to comment.