// license:BSD-3-Clause // copyright-holders:R. Belmont /*************************************************************************** Data East Pinball BSMT2000 sound board used for System 3 and Whitestar pinball games and Tattoo Assassins video ***************************************************************************/ #include "emu.h" #include "audio/decobsmt.h" #include "speaker.h" #define M6809_TAG "soundcpu" #define BSMT_TAG "bsmt" void decobsmt_device::decobsmt_map(address_map &map) { map(0x0000, 0x1fff).ram(); map(0x2000, 0xffff).rom().region(":soundcpu", 0x2000); map(0x2000, 0x2001).w(FUNC(decobsmt_device::bsmt_reset_w)); map(0x2002, 0x2003).r(FUNC(decobsmt_device::bsmt_comms_r)); map(0x2006, 0x2007).r(FUNC(decobsmt_device::bsmt_status_r)); map(0x6000, 0x6000).w(FUNC(decobsmt_device::bsmt0_w)); map(0xa000, 0xa0ff).w(FUNC(decobsmt_device::bsmt1_w)); } void decobsmt_device::bsmt_map(address_map &map) { map(0x000000, 0xffffff).rom().region(":bsmt", 0); } void decobsmt_device::bsmt_ready_callback() { m_ourcpu->set_input_line(M6809_IRQ_LINE, ASSERT_LINE); /* BSMT is ready */ } //************************************************************************** // GLOBAL VARIABLES //************************************************************************** DEFINE_DEVICE_TYPE(DECOBSMT, decobsmt_device, "decobsmt", "Data East/Sega/Stern BSMT2000 Sound Board") //------------------------------------------------- // device_add_mconfig - add device configuration //------------------------------------------------- void decobsmt_device::device_add_mconfig(machine_config &config) { MC6809E(config, m_ourcpu, XTAL(24'000'000) / 12); // 68B09E U6 (E & Q = 2 MHz according to manual) m_ourcpu->set_addrmap(AS_PROGRAM, &decobsmt_device::decobsmt_map); m_ourcpu->set_periodic_int(FUNC(decobsmt_device::decobsmt_firq_interrupt), attotime::from_hz(489)); /* Fixed FIRQ of 489Hz as measured on real (pinball) machine */ SPEAKER(config, "lspeaker").front_left(); SPEAKER(config, "rspeaker").front_right(); BSMT2000(config, m_bsmt, XTAL(24'000'000)); m_bsmt->set_addrmap(0, &decobsmt_device::bsmt_map); m_bsmt->set_ready_callback(FUNC(decobsmt_device::bsmt_ready_callback)); m_bsmt->add_route(0, "lspeaker", 2.0); m_bsmt->add_route(1, "rspeaker", 2.0); } //************************************************************************** // LIVE DEVICE //************************************************************************** //------------------------------------------------- // decobsmt_device - constructor //------------------------------------------------- decobsmt_device::decobsmt_device(const machine_config &mconfig, const char *tag, device_t *owner, uint32_t clock) : device_t(mconfig, DECOBSMT, tag, owner, clock) , m_ourcpu(*this, M6809_TAG) , m_bsmt(*this, BSMT_TAG) { } //------------------------------------------------- // device_start - device-specific startup //------------------------------------------------- void decobsmt_device::device_start() { } //------------------------------------------------- // device_reset - device-specific reset //------------------------------------------------- void decobsmt_device::device_reset() { m_bsmt_latch = 0; m_bsmt_reset = 0; m_bsmt_comms = 0; } void decobsmt_device::bsmt_reset_w(u8 data) { uint8_t diff = data ^ m_bsmt_reset; m_bsmt_reset = data; if ((diff & 0x80) && !(data & 0x80)) m_bsmt->reset(); } void decobsmt_device::bsmt0_w(u8 data) { m_bsmt_latch = data; } void decobsmt_device::bsmt1_w(offs_t offset, u8 data) { m_bsmt->write_reg(offset ^ 0xff); m_bsmt->write_data((m_bsmt_latch << 8) | data); m_ourcpu->set_input_line(M6809_IRQ_LINE, CLEAR_LINE); /* BSMT is not ready */ } u8 decobsmt_device::bsmt_status_r() { return m_bsmt->read_status() << 7; } u8 decobsmt_device::bsmt_comms_r() { return m_bsmt_comms; } void decobsmt_device::bsmt_comms_w(u8 data) { m_bsmt_comms = data; } WRITE_LINE_MEMBER(decobsmt_device::bsmt_reset_line) { m_ourcpu->set_input_line(INPUT_LINE_RESET, state); } INTERRUPT_GEN_MEMBER(decobsmt_device::decobsmt_firq_interrupt) { device.execute().set_input_line(M6809_FIRQ_LINE, HOLD_LINE); }