summaryrefslogtreecommitdiffstatshomepage
diff options
context:
space:
mode:
author angelosa <lordkale4@gmail.com>2025-10-29 14:45:22 +0100
committer angelosa <lordkale4@gmail.com>2025-10-29 14:45:22 +0100
commit126ae166b4c36db71eee84b40aec2a296db91c3a (patch)
tree20e97e76f3831dbe805116331ea2288da8b09bbf
parent8df6a1878230bb72ff100228a9e5666196068337 (diff)
bus/pc98_cbus/pc9801_14.cpp: hookup TMS3631 stub
-rw-r--r--scripts/src/sound.lua12
-rw-r--r--src/devices/bus/pc98_cbus/pc9801_14.cpp27
-rw-r--r--src/devices/bus/pc98_cbus/pc9801_14.h5
-rw-r--r--src/devices/sound/tms3631.cpp103
-rw-r--r--src/devices/sound/tms3631.h48
-rw-r--r--src/mame/amiga/paula.cpp7
6 files changed, 187 insertions, 15 deletions
diff --git a/scripts/src/sound.lua b/scripts/src/sound.lua
index 5d5bd768f65..ed8e9ad9a0d 100644
--- a/scripts/src/sound.lua
+++ b/scripts/src/sound.lua
@@ -1102,6 +1102,18 @@ end
---------------------------------------------------
+-- Texas Instruments TMS3631
+--@src/devices/sound/tms3631.h,SOUNDS["TMS3631"] = true
+---------------------------------------------------
+
+if (SOUNDS["TMS3631"]~=null) then
+ files {
+ MAME_DIR .. "src/devices/sound/tms3631.cpp",
+ MAME_DIR .. "src/devices/sound/tms3631.h",
+ }
+end
+
+---------------------------------------------------
-- Texas Instruments TMS5100-series speech synthesizers
--@src/devices/sound/tms5110.h,SOUNDS["TMS5110"] = true
---------------------------------------------------
diff --git a/src/devices/bus/pc98_cbus/pc9801_14.cpp b/src/devices/bus/pc98_cbus/pc9801_14.cpp
index 6cdacfc52be..9ab357923bb 100644
--- a/src/devices/bus/pc98_cbus/pc9801_14.cpp
+++ b/src/devices/bus/pc98_cbus/pc9801_14.cpp
@@ -6,9 +6,6 @@ PC9801-14 sound board
TMS3631 sound chip (same as Siel DK-600 / Opera 6)
4 octaves, 12 notes, 8 channels
-CH1 and CH2 are fixed to center with no envelope
-CH3-5 are fixed to the left
-CH6-8 to the right
7 knobs on back panel, F2/F4/F8/F16 then L/R and VOL
References:
@@ -46,7 +43,7 @@ pc9801_14_device::pc9801_14_device(const machine_config &mconfig, const char *ta
, m_bus(*this, DEVICE_SELF_OWNER)
, m_ppi(*this, "ppi")
, m_pit(*this, "pit")
-// , m_tms(*this, "tms")
+ , m_tms(*this, "tms")
{
}
@@ -67,12 +64,24 @@ void pc9801_14_device::device_add_mconfig(machine_config &config)
m_ppi->out_pa_callback().set([this](uint8_t data) { LOG("TMS3631: PA envelope 1 %02x\n", data); });
m_ppi->out_pb_callback().set([this](uint8_t data) { LOG("TMS3631: PB envelope 2 %02x\n", data); });
// m_ppi->in_pc_callback().set_constant(0x08);
- m_ppi->out_pc_callback().set([this](uint8_t data) { LOG("TMS3631: data %02x\n", data); });
+ m_ppi->out_pc_callback().set(m_tms, FUNC(tms3631_device::data_w));
// TODO: TMS3631-RI104 & TMS3631-RI105
- // TMS3631(config, m_tms, 1'996'800);
- // m_tms->add_route(0, "speaker", 0.5, 0);
- // m_tms->add_route(1, "speaker", 0.5, 1);
+ TMS3631(config, m_tms, 1'996'800);
+ // CH1 and CH2 are fixed to center with no envelope
+ m_tms->add_route(0, "speaker", 0.5, 0);
+ m_tms->add_route(0, "speaker", 0.5, 1);
+ m_tms->add_route(1, "speaker", 0.5, 0);
+ m_tms->add_route(1, "speaker", 0.5, 1);
+ // CH3-5 are fixed to the left
+ m_tms->add_route(2, "speaker", 0.5, 0);
+ m_tms->add_route(3, "speaker", 0.5, 0);
+ m_tms->add_route(4, "speaker", 0.5, 0);
+ // CH6-8 to the right
+ m_tms->add_route(5, "speaker", 0.5, 1);
+ m_tms->add_route(6, "speaker", 0.5, 1);
+ m_tms->add_route(7, "speaker", 0.5, 1);
+
}
ROM_START( pc9801_14 )
@@ -128,7 +137,7 @@ void pc9801_14_device::io_map(address_map &map)
// 0x00 and 0xff values aren't valid
map(0x008e, 0x008e).lr8(NAME([this] () { LOG("PC9801-14: read base port / identifier\n"); return 0x08; }));
// mirror according to io_sound.txt
- map(0x0188, 0x0188).mirror(2).lw8(NAME([this] (offs_t offset, u8 data) { LOG("TMS3631 mask %02x\n", data); }));
+ map(0x0188, 0x0188).mirror(2).w(m_tms, FUNC(tms3631_device::enable_w));
map(0x018c, 0x018c).lrw8(
NAME([this] (offs_t offset) { return m_pit->read(2); }),
NAME([this] (offs_t offset, u8 data) { m_pit->write(2, data); })
diff --git a/src/devices/bus/pc98_cbus/pc9801_14.h b/src/devices/bus/pc98_cbus/pc9801_14.h
index 7a554f07a42..4cfb447f488 100644
--- a/src/devices/bus/pc98_cbus/pc9801_14.h
+++ b/src/devices/bus/pc98_cbus/pc9801_14.h
@@ -10,14 +10,13 @@
#include "machine/i8255.h"
#include "machine/pit8253.h"
+#include "sound/tms3631.h"
class pc9801_14_device : public device_t
{
public:
pc9801_14_device(const machine_config &mconfig, const char *tag, device_t *owner, uint32_t clock);
- static constexpr feature_type unemulated_features() { return feature::SOUND; }
-
uint8_t read(offs_t offset);
void write(offs_t offset, uint8_t data);
@@ -37,7 +36,7 @@ private:
required_device<pc98_cbus_slot_device> m_bus;
required_device<i8255_device> m_ppi;
required_device<pit8253_device> m_pit;
-// required_device<tms3631_device> m_tms;
+ required_device<tms3631_device> m_tms;
};
// device type definition
diff --git a/src/devices/sound/tms3631.cpp b/src/devices/sound/tms3631.cpp
new file mode 100644
index 00000000000..77a08b34eb7
--- /dev/null
+++ b/src/devices/sound/tms3631.cpp
@@ -0,0 +1,103 @@
+// license:BSD-3-Clause
+// copyright-holders:Angelo Salese
+
+#include "emu.h"
+#include "tms3631.h"
+
+#define LIVE_AUDIO_VIEW 0
+
+//#define VERBOSE 1
+#include "logmacro.h"
+#include <cstring>
+
+DEFINE_DEVICE_TYPE(TMS3631, tms3631_device, "tms3631", "TMS3631")
+
+
+tms3631_device::tms3631_device(const machine_config &mconfig, const char *tag, device_t *owner, uint32_t clock)
+ : device_t(mconfig, TMS3631, tag, owner, clock)
+ , device_sound_interface(mconfig, *this)
+ , m_stream(nullptr)
+ , m_samplerate(0)
+ , m_basefreq(0)
+ , m_enable(0)
+{
+// std::fill(std::begin(m_counter8), std::end(m_counter8), 0);
+ std::fill(std::begin(m_channel_data), std::end(m_channel_data), 0);
+}
+
+
+void tms3631_device::device_start()
+{
+ m_stream = stream_alloc(0, 8, clock() / 8);
+ m_samplerate = clock() / 8;
+ m_basefreq = clock();
+}
+
+//-------------------------------------------------
+// sound_stream_update - handle a stream update
+//-------------------------------------------------
+
+void tms3631_device::sound_stream_update(sound_stream &stream)
+{
+// int samplerate = stream.sample_rate();
+
+ for (int i = 0; i < 8; i++)
+ stream.fill(i, 0);
+}
+
+// TODO: external to the chip(s)?
+void tms3631_device::enable_w(offs_t offset, u8 data)
+{
+ if (offset)
+ popmessage("TMS3631: select with offset (RI105?)");
+ m_enable = data;
+}
+
+void tms3631_device::data_w(u8 data)
+{
+ const int ce_state = BIT(data, 7);
+
+ if (!m_ce && ce_state)
+ {
+ m_program_enable = true;
+ m_channel_select = 0;
+ }
+ else if (m_ce && !ce_state)
+ {
+ m_program_enable = false;
+ }
+
+ if (m_program_enable)
+ {
+ const int wclk_state = BIT(data, 6);
+
+ if (!m_wclk && wclk_state)
+ {
+ m_channel_data[m_channel_select] = data & 0x3f;
+ m_stream->update();
+ if (LIVE_AUDIO_VIEW)
+ popmessage(print_audio_state());
+ }
+ else if (m_wclk && !wclk_state)
+ {
+ m_channel_select ++;
+ m_channel_select &= 7;
+ }
+
+ m_wclk = wclk_state;
+ }
+ m_ce = ce_state;
+}
+
+std::string tms3631_device::print_audio_state()
+{
+ std::ostringstream outbuffer;
+
+ for (int i = 0; i < 8; i++)
+ {
+ util::stream_format(outbuffer, "%02x ", m_channel_data[i]);
+ }
+
+ return outbuffer.str();
+}
+
diff --git a/src/devices/sound/tms3631.h b/src/devices/sound/tms3631.h
new file mode 100644
index 00000000000..62affa48bb5
--- /dev/null
+++ b/src/devices/sound/tms3631.h
@@ -0,0 +1,48 @@
+// license:BSD-3-Clause
+// copyright-holders:Angelo Salese
+#ifndef MAME_SOUND_TMS3631_H
+#define MAME_SOUND_TMS3631_H
+
+#pragma once
+
+
+//**************************************************************************
+// TYPE DEFINITIONS
+//**************************************************************************
+
+
+// ======================> tms3631_device
+
+class tms3631_device : public device_t, public device_sound_interface
+{
+public:
+ tms3631_device(const machine_config &mconfig, const char *tag, device_t *owner, uint32_t clock);
+
+ static constexpr feature_type unemulated_features() { return feature::SOUND; }
+
+ void enable_w(offs_t offset, u8 data);
+ void data_w(u8 data);
+
+protected:
+ virtual void device_start() override ATTR_COLD;
+
+ virtual void sound_stream_update(sound_stream &stream) override;
+
+private:
+ sound_stream *m_stream;
+ int m_samplerate;
+ int m_basefreq;
+// int m_counter8[8];
+// int m_output8;
+ int m_enable;
+ int m_wclk, m_ce;
+ u8 m_channel_select;
+ bool m_program_enable;
+ u8 m_channel_data[8];
+
+ std::string print_audio_state();
+};
+
+DECLARE_DEVICE_TYPE(TMS3631, tms3631_device)
+
+#endif // MAME_SOUND_TMS3631_H
diff --git a/src/mame/amiga/paula.cpp b/src/mame/amiga/paula.cpp
index 15b41d784d5..cc6d8b9eb56 100644
--- a/src/mame/amiga/paula.cpp
+++ b/src/mame/amiga/paula.cpp
@@ -381,10 +381,11 @@ void paula_device::sound_stream_update(sound_stream &stream)
// for silencing channels on-the-fly without relying on irqs.
// Without this the location will read at 0x632d8 (data=0x7a7d), causing annoying buzzing.
chan->dat = m_chipmem_r(chan->curlocation);
- // TODO: Ocean games (batmancc in particular) throws DC offset on main theme
- // if we non-zero the data. This however will break swos9596 and
- // "Mind Walker", latter using short 1 word DMA samples.
+ // batmancc throws DC offset on main theme if we non-zero the data.
+ // This however will break swos9596 and
+ // "Mind Walker" game, latter using short 1 word DMA samples.
// https://github.com/mamedev/mame/commit/8a9fb029a29a8a0f653ce4a8e011453834ef1fda#commitcomment-168255001
+ // Notice batmancc may just be a btanb, needs verifying on real HW.
//chan->dat = 0;
}
}