summaryrefslogtreecommitdiffstatshomepage
path: root/src/mame/audio/wpcsnd.cpp
diff options
context:
space:
mode:
Diffstat (limited to 'src/mame/audio/wpcsnd.cpp')
-rw-r--r--src/mame/audio/wpcsnd.cpp169
1 files changed, 169 insertions, 0 deletions
diff --git a/src/mame/audio/wpcsnd.cpp b/src/mame/audio/wpcsnd.cpp
new file mode 100644
index 00000000000..134456fe19b
--- /dev/null
+++ b/src/mame/audio/wpcsnd.cpp
@@ -0,0 +1,169 @@
+// license:BSD-3-Clause
+// copyright-holders:Barry Rodewald
+/*
+ * wpcsnd.c - Williams WPC pinball sound
+ * M6809E + YM2151 + HC55516 + DAC
+ *
+ * Created on: 4/10/2013
+ */
+
+#include "wpcsnd.h"
+
+#define LOG_WPCSND (0)
+
+const device_type WPCSND = &device_creator<wpcsnd_device>;
+
+wpcsnd_device::wpcsnd_device(const machine_config &mconfig, const char *tag, device_t *owner, UINT32 clock)
+ : device_t(mconfig,WPCSND,"Williams WPC Sound",tag,owner,clock, "wpcsnd", __FILE__),
+ m_cpu(*this,"bgcpu"),
+ m_ym2151(*this,"ym2151"),
+ m_hc55516(*this,"hc55516"),
+ m_dac(*this,"dac"),
+ m_cpubank(*this,"rombank"),
+ m_fixedbank(*this,"fixed"),
+ m_reply_cb(*this)
+{
+}
+
+static ADDRESS_MAP_START( wpcsnd_map, AS_PROGRAM, 8, wpcsnd_device )
+ AM_RANGE(0x0000, 0x1fff) AM_RAM
+ AM_RANGE(0x2000, 0x2000) AM_MIRROR(0x03ff) AM_WRITE(rombank_w)
+ AM_RANGE(0x2400, 0x2401) AM_MIRROR(0x03fe) AM_DEVREADWRITE("ym2151", ym2151_device, read, write)
+ AM_RANGE(0x2800, 0x2800) AM_MIRROR(0x03ff) AM_DEVWRITE("dac", dac_device, write_unsigned8)
+ AM_RANGE(0x2c00, 0x2fff) AM_WRITE(bg_speech_digit_w)
+ AM_RANGE(0x3000, 0x33ff) AM_READ(latch_r)
+ AM_RANGE(0x3400, 0x37ff) AM_WRITE(bg_speech_clock_w)
+ AM_RANGE(0x3800, 0x3bff) AM_WRITE(volume_w)
+ AM_RANGE(0x3c00, 0x3fff) AM_WRITE(latch_w)
+ AM_RANGE(0x4000, 0xbfff) AM_ROMBANK("rombank")
+ AM_RANGE(0xc000, 0xffff) AM_ROMBANK("fixed")
+ADDRESS_MAP_END
+
+void wpcsnd_device::ctrl_w(UINT8 data)
+{
+ m_cpu->set_input_line(INPUT_LINE_RESET,PULSE_LINE);
+}
+
+void wpcsnd_device::data_w(UINT8 data)
+{
+ m_latch = data;
+ m_cpu->set_input_line(M6809_IRQ_LINE,ASSERT_LINE);
+}
+
+UINT8 wpcsnd_device::ctrl_r()
+{
+ return (m_reply_available) ? 0x01 : 0x00;
+}
+
+UINT8 wpcsnd_device::data_r()
+{
+ m_reply_available = false;
+ m_reply_cb(m_cpu->space(AS_PROGRAM),0);
+ return m_reply;
+}
+
+MACHINE_CONFIG_FRAGMENT( wpcsnd )
+ MCFG_CPU_ADD("bgcpu", M6809E, XTAL_8MHz) // MC68B09E
+ MCFG_CPU_PROGRAM_MAP(wpcsnd_map)
+ MCFG_QUANTUM_TIME(attotime::from_hz(50))
+
+ MCFG_SPEAKER_STANDARD_MONO("bg")
+ MCFG_YM2151_ADD("ym2151", 3580000)
+ MCFG_YM2151_IRQ_HANDLER(WRITELINE(wpcsnd_device, ym2151_irq_w))
+ MCFG_SOUND_ROUTE(ALL_OUTPUTS, "bg", 0.25)
+
+ MCFG_DAC_ADD("dac")
+ MCFG_SOUND_ROUTE(ALL_OUTPUTS, "bg", 0.50)
+
+ MCFG_SOUND_ADD("hc55516", HC55516, 0)
+ MCFG_SOUND_ROUTE(ALL_OUTPUTS, "bg", 0.50)
+MACHINE_CONFIG_END
+
+machine_config_constructor wpcsnd_device::device_mconfig_additions() const
+{
+ return MACHINE_CONFIG_NAME( wpcsnd );
+}
+
+void wpcsnd_device::device_start()
+{
+ // resolve callback
+ m_reply_cb.resolve_safe();
+}
+
+void wpcsnd_device::device_reset()
+{
+ UINT8* ROM;
+
+ m_rom = memregion(m_regiontag);
+ ROM = m_rom->base();
+ m_cpubank->configure_entries(0, 0x80, &ROM[0], 0x8000);
+ m_cpubank->set_entry(0);
+ m_fixedbank->configure_entries(0, 1, &ROM[0x17c000], 0x4000);
+ m_fixedbank->set_entry(0);
+
+ // reset the CPU again, so that the CPU is starting with the right vectors (otherwise sound may die on reset)
+ m_cpu->set_input_line(INPUT_LINE_RESET,PULSE_LINE);
+
+ m_reply_available = false;
+}
+
+void wpcsnd_device::static_set_gfxregion(device_t &device, const char *tag)
+{
+ wpcsnd_device &cpuboard = downcast<wpcsnd_device &>(device);
+ cpuboard.m_regiontag = tag;
+}
+
+WRITE_LINE_MEMBER( wpcsnd_device::ym2151_irq_w)
+{
+ m_cpu->set_input_line(M6809_FIRQ_LINE,state ? ASSERT_LINE : CLEAR_LINE);
+}
+
+WRITE8_MEMBER( wpcsnd_device::bg_speech_clock_w )
+{
+ // pulses clock input?
+ m_hc55516->clock_w(1);
+ m_hc55516->clock_w(0);
+}
+
+WRITE8_MEMBER( wpcsnd_device::bg_speech_digit_w )
+{
+ m_hc55516->digit_w(data);
+}
+
+WRITE8_MEMBER( wpcsnd_device::rombank_w )
+{
+ UINT8 bank = data & 0x0f;
+
+ switch((~data) & 0xe0)
+ {
+ case 0x80:
+ bank |= 0x20;
+ break;
+ case 0x40:
+ bank |= 0x10;
+ break;
+ case 0x20:
+ break;
+ }
+
+ m_cpubank->set_entry(bank);
+
+ if(LOG_WPCSND) logerror("WPCSND: Bank set to %02x\n",bank);
+}
+
+READ8_MEMBER(wpcsnd_device::latch_r)
+{
+ m_cpu->set_input_line(M6809_IRQ_LINE,CLEAR_LINE);
+ return m_latch;
+}
+
+WRITE8_MEMBER(wpcsnd_device::latch_w)
+{
+ m_reply_available = true;
+ m_reply = data;
+ m_reply_cb(space,1);
+}
+
+WRITE8_MEMBER(wpcsnd_device::volume_w)
+{
+}