summaryrefslogtreecommitdiffstatshomepage
diff options
context:
space:
mode:
author Vas Crabb <vas@vastheman.com>2018-03-16 04:26:46 +1100
committer Vas Crabb <vas@vastheman.com>2018-03-16 04:26:46 +1100
commit1e1369c02b191bb201f093b5b9517f4fc732bc40 (patch)
tree9711851618d7fd3aa9b384ddd6bb798bc02ffb0a
parentbb11fbd2bd66ad45571146ec5a660f5775949ef1 (diff)
qsound: clean up host and DAC comms a bit, hopefully fix desync
ie15: fix shortname conflict (nw) Motorola naming M68000 = family, MC68000 = main production implementation, XC68LC040 = pre-main production implementation. The M prefix should only be used for devices representing a family in the abstract, like the M6805 device that represents the PMOS 6805 core but not a particular implementation with onboard peripherals and memory. (nw)
-rw-r--r--src/devices/cpu/ie15/ie15.cpp2
-rw-r--r--src/devices/cpu/m68000/m68kcpu.cpp30
-rw-r--r--src/devices/sound/qsound.cpp79
-rw-r--r--src/devices/sound/qsound.h7
-rw-r--r--src/devices/sound/qsoundhle.cpp2
5 files changed, 62 insertions, 58 deletions
diff --git a/src/devices/cpu/ie15/ie15.cpp b/src/devices/cpu/ie15/ie15.cpp
index 23e69cadd45..80c0fecdbe7 100644
--- a/src/devices/cpu/ie15/ie15.cpp
+++ b/src/devices/cpu/ie15/ie15.cpp
@@ -22,7 +22,7 @@
//**************************************************************************
// device type definition
-DEFINE_DEVICE_TYPE(IE15_CPU, ie15_cpu_device, "ie15", "ie15 CPU")
+DEFINE_DEVICE_TYPE(IE15_CPU, ie15_cpu_device, "ie15_cpu", "ie15 CPU")
//**************************************************************************
// DEVICE INTERFACE
diff --git a/src/devices/cpu/m68000/m68kcpu.cpp b/src/devices/cpu/m68000/m68kcpu.cpp
index c8a13cadb4e..bf8a92a600b 100644
--- a/src/devices/cpu/m68000/m68kcpu.cpp
+++ b/src/devices/cpu/m68000/m68kcpu.cpp
@@ -2464,21 +2464,21 @@ device_memory_interface::space_config_vector m68000_base_device::memory_space_co
-DEFINE_DEVICE_TYPE(M68000, m68000_device, "m68000", "Motorola M68000")
-DEFINE_DEVICE_TYPE(M68301, m68301_device, "m68301", "Motorola M68301")
-DEFINE_DEVICE_TYPE(M68008, m68008_device, "m68008", "Motorola M68008")
-DEFINE_DEVICE_TYPE(M68008PLCC, m68008plcc_device, "m68008plcc", "Motorola M68008PLCC")
-DEFINE_DEVICE_TYPE(M68010, m68010_device, "m68010", "Motorola M68010")
-DEFINE_DEVICE_TYPE(M68EC020, m68ec020_device, "m68ec020", "Motorola M68EC020")
-DEFINE_DEVICE_TYPE(M68020, m68020_device, "m68020", "Motorola M68020")
-DEFINE_DEVICE_TYPE(M68020FPU, m68020fpu_device, "m68020fpu", "Motorola M68020FPU")
-DEFINE_DEVICE_TYPE(M68020PMMU, m68020pmmu_device, "m68020pmmu", "Motorola M68020PMMU")
-DEFINE_DEVICE_TYPE(M68020HMMU, m68020hmmu_device, "m68020hmmu", "Motorola M68020HMMU")
-DEFINE_DEVICE_TYPE(M68EC030, m68ec030_device, "m68ec030", "Motorola M68EC030")
-DEFINE_DEVICE_TYPE(M68030, m68030_device, "m68030", "Motorola M68030")
-DEFINE_DEVICE_TYPE(M68EC040, m68ec040_device, "m68ec040", "Motorola M68EC040")
-DEFINE_DEVICE_TYPE(M68LC040, m68lc040_device, "m68lc040", "Motorola M68LC040")
-DEFINE_DEVICE_TYPE(M68040, m68040_device, "m68040", "Motorola M68040")
+DEFINE_DEVICE_TYPE(M68000, m68000_device, "m68000", "Motorola MC68000")
+DEFINE_DEVICE_TYPE(M68301, m68301_device, "m68301", "Motorola MC68301")
+DEFINE_DEVICE_TYPE(M68008, m68008_device, "m68008", "Motorola MC68008")
+DEFINE_DEVICE_TYPE(M68008PLCC, m68008plcc_device, "m68008plcc", "Motorola MC68008PLCC")
+DEFINE_DEVICE_TYPE(M68010, m68010_device, "m68010", "Motorola MC68010")
+DEFINE_DEVICE_TYPE(M68EC020, m68ec020_device, "m68ec020", "Motorola MC68EC020")
+DEFINE_DEVICE_TYPE(M68020, m68020_device, "m68020", "Motorola MC68020")
+DEFINE_DEVICE_TYPE(M68020FPU, m68020fpu_device, "m68020fpu", "Motorola MC68020FPU")
+DEFINE_DEVICE_TYPE(M68020PMMU, m68020pmmu_device, "m68020pmmu", "Motorola MC68020PMMU")
+DEFINE_DEVICE_TYPE(M68020HMMU, m68020hmmu_device, "m68020hmmu", "Motorola MC68020HMMU")
+DEFINE_DEVICE_TYPE(M68EC030, m68ec030_device, "m68ec030", "Motorola MC68EC030")
+DEFINE_DEVICE_TYPE(M68030, m68030_device, "m68030", "Motorola MC68030")
+DEFINE_DEVICE_TYPE(M68EC040, m68ec040_device, "m68ec040", "Motorola MC68EC040")
+DEFINE_DEVICE_TYPE(M68LC040, m68lc040_device, "m68lc040", "Motorola MC68LC040")
+DEFINE_DEVICE_TYPE(M68040, m68040_device, "m68040", "Motorola MC68040")
DEFINE_DEVICE_TYPE(SCC68070, scc68070_device, "scc68070", "Philips SCC68070")
DEFINE_DEVICE_TYPE(FSCPU32, fscpu32_device, "fscpu32", "Freescale CPU32 Core")
DEFINE_DEVICE_TYPE(MCF5206E, mcf5206e_device, "mcf5206e", "Freescale MCF5206E")
diff --git a/src/devices/sound/qsound.cpp b/src/devices/sound/qsound.cpp
index f5411dfa94b..402c7c80a02 100644
--- a/src/devices/sound/qsound.cpp
+++ b/src/devices/sound/qsound.cpp
@@ -42,12 +42,13 @@
are 16-bit signed values, but Capcom only has 8-bit ROMs connected.
I'm assuming byte smearing, but it may be zero-padded in the LSBs.
- The DSP sends out 16-bit samples on its SIO port clocked at 2.5 MHz.
+ The DSP sends out 16-bit samples on its SIO port clocked at 5 MHz.
The stereo samples aren't loaded fast enough for consecutive frames
so there's an empty frame between them. Sample pairs are loaded
every 1,248 machine cycles, giving a sample rate of 24.03846 kHz
- (60 MHz / 2 / 1248). It's unknown how the real hardware identifies
- left/right samples - I'm using a massive hack at the moment.
+ (60 MHz / 2 / 1248). The glue logic seems to generate the WS signal
+ for the DAC from the PSEL line and the SIO control lines, but it
+ isn't clear exactly how this is achieved.
The DSP writes values to pdx1 every sample cycle (alternating
between zero and non-zero values). This may be for the volume
@@ -93,7 +94,7 @@
#define LOG_COMMAND (1U << 1)
#define LOG_SAMPLE (1U << 2)
-//#define VERBOSE (LOG_GENERAL | LOG_SAMPLE)
+//#define VERBOSE (LOG_GENERAL | LOG_COMMAND | LOG_SAMPLE)
//#define LOG_OUTPUT_STREAM std::cout
#include "logmacro.h"
@@ -122,8 +123,8 @@ qsound_device::qsound_device(machine_config const &mconfig, char const *tag, dev
, device_sound_interface(mconfig, *this)
, device_rom_interface(mconfig, *this, 24)
, m_dsp(*this, "dsp"), m_stream(nullptr)
- , m_rom_bank(0U), m_rom_offset(0U), m_cmd_addr(0U), m_cmd_data(0U), m_cmd_pending(0U), m_dsp_ready(1U)
- , m_last_time(0U), m_samples{ 0, 0 }, m_sr(0U), m_fsr(0U), m_ock(1U), m_old(1U), m_ready(0U), m_channel(0U)
+ , m_rom_bank(0U), m_rom_offset(0U), m_cmd_addr(0U), m_cmd_data(0U), m_new_data(0U), m_cmd_pending(0U), m_dsp_ready(1U)
+ , m_samples{ 0, 0 }, m_sr(0U), m_fsr(0U), m_ock(1U), m_old(1U), m_ready(0U), m_channel(0U)
{
}
@@ -133,14 +134,22 @@ WRITE8_MEMBER(qsound_device::qsound_w)
switch (offset)
{
case 0:
- machine().scheduler().synchronize(timer_expired_delegate(FUNC(qsound_device::set_cmd_data_high), this), unsigned(data));
+ LOGCOMMAND(
+ "QSound: set command data[h] = %02X (%04X -> %04X)\n",
+ data, m_new_data, (m_new_data & 0x00ffU) | (u16(data) << 8));
+ m_new_data = (m_new_data & 0x00ffU) | (u16(data) << 8);
break;
case 1:
- machine().scheduler().synchronize(timer_expired_delegate(FUNC(qsound_device::set_cmd_data_low), this), unsigned(data));
+ LOGCOMMAND(
+ "QSound: set command data[l] = %02X (%04X -> %04X)\n",
+ data, m_new_data, (m_new_data & 0xff00U) | data);
+ m_new_data = (m_new_data & 0xff00U) | data;
break;
case 2:
m_dsp_ready = 0U;
- machine().scheduler().synchronize(timer_expired_delegate(FUNC(qsound_device::set_cmd_addr), this), unsigned(data));
+ machine().scheduler().synchronize(
+ timer_expired_delegate(FUNC(qsound_device::set_cmd), this),
+ (unsigned(data) << 16) | m_new_data);
break;
default:
logerror("QSound: host write to unknown register %01X = %02X (%s)\n", offset, data, machine().describe_context());
@@ -192,11 +201,11 @@ void qsound_device::device_start()
save_item(NAME(m_rom_offset));
save_item(NAME(m_cmd_addr));
save_item(NAME(m_cmd_data));
+ save_item(NAME(m_new_data));
save_item(NAME(m_cmd_pending));
save_item(NAME(m_dsp_ready));
// save serial sample recovery state
- save_item(NAME(m_last_time));
save_item(NAME(m_samples));
save_item(NAME(m_sr));
save_item(NAME(m_fsr));
@@ -251,7 +260,7 @@ void qsound_device::dsp_io_map(address_map &map)
READ16_MEMBER(qsound_device::dsp_sample_r)
{
- // TODO: DSP16 doesn't like bytes, only signed words - should this zero-pad or byte-smear?
+ // FIXME: DSP16 doesn't like bytes, only signed words - should this zero-pad or byte-smear?
u8 const byte(read_byte((u32(m_rom_bank) << 16) | m_rom_offset));
if (!machine().side_effects_disabled())
m_rom_bank = offset;
@@ -269,7 +278,11 @@ WRITE_LINE_MEMBER(qsound_device::dsp_ock_w)
// detect start of word
if (m_ready && !m_fsr && !m_dsp->ose_r())
+ {
+ // FIXME: PSEL at beginning of word seems to select channel, but how does the logic derive WS from the DSP outputs?
+ m_channel = m_dsp->psel_r();
m_fsr = 0xffffU;
+ }
// shift in data
if (m_fsr)
@@ -278,16 +291,10 @@ WRITE_LINE_MEMBER(qsound_device::dsp_ock_w)
m_fsr >>= 1;
if (!m_fsr)
{
- // FIXME: this is an epic hack, but I don't know how the hardware actually identifies channels
- u64 const now(m_dsp->total_cycles());
- if ((now - m_last_time) > 500)
- m_channel = 0U;
- m_last_time = now;
LOGSAMPLE("QSound: recovered channel %u sample %04X\n", m_channel, m_sr);
if (!m_channel)
m_stream->update();
m_samples[m_channel] = m_sr;
- m_channel = m_channel ? 0U : 1U;
#if 0 // enable to log PCM to a file - can be imported with "ffmpeg -f s16be -ar 24038 -ac 2 -i qsound.pcm qsound.wav"
static std::ofstream logfile("qsound.pcm", std::ios::binary);
logfile.put(u8(m_sr >> 8));
@@ -304,6 +311,21 @@ WRITE_LINE_MEMBER(qsound_device::dsp_ock_w)
WRITE16_MEMBER(qsound_device::dsp_pio_w)
{
+ /*
+ * FIXME: what does this do when PDX is high?
+ * There are seemingly two significant points where the program writes PDX1 every sample interval.
+ *
+ * Before writing the right-channel sample to SDX - this causes the PSEL 0->1 transition:
+ * 0:5d4: 996e if true a0 = rnd(a0)
+ * 0:5d5: 51e0 0000 pdx1 = 0x0000
+ * 0:5d7: 49a0 move sdx = a0
+ *
+ * This curious code where it writes out the a word from RAM@0x00f1 - this value seems significant:
+ * 0:335: 18f1 set r0 = 0x00f1
+ * 0:336: 3cd0 nop, a0 = *r0
+ * 0:337: d850 p = x*y, y = a1, x = *pt++i
+ * 0:338: 49e0 move pdx1 = a0
+ */
if (offset)
LOG("QSound: DSP PDX1 = %04X\n", data);
else
@@ -334,26 +356,11 @@ void qsound_device::set_dsp_ready(void *ptr, s32 param)
m_dsp_ready = 1U;
}
-void qsound_device::set_cmd_addr(void *ptr, s32 param)
+void qsound_device::set_cmd(void *ptr, s32 param)
{
- LOGCOMMAND("QSound: DSP command @%02X = %04X\n", param, m_cmd_data);
- m_cmd_addr = u16(u32(param));
+ LOGCOMMAND("QSound: DSP command @%02X = %04X\n", u32(param) >> 16, u16(u32(param)));
+ m_cmd_addr = u16(u32(param) >> 16);
+ m_cmd_data = u16(u32(param));
m_cmd_pending = 1U;
m_dsp->set_input_line(DSP16_INT_LINE, ASSERT_LINE);
}
-
-void qsound_device::set_cmd_data_high(void *ptr, s32 param)
-{
- LOGCOMMAND(
- "QSound: set command data[h] = %02X (%04X -> %04X)\n",
- param, m_cmd_data, (m_cmd_data & 0x00ffU) | (u32(param) << 8));
- m_cmd_data = u16((m_cmd_data & 0x00ffU) | (u32(param) << 8));
-}
-
-void qsound_device::set_cmd_data_low(void *ptr, s32 param)
-{
- LOGCOMMAND(
- "QSound: set command data[l] = %02X (%04X -> %04X)\n",
- param, m_cmd_data, (m_cmd_data & 0xff00U) | u32(param));
- m_cmd_data = u16((m_cmd_data & 0xff00U) | u32(param));
-}
diff --git a/src/devices/sound/qsound.h b/src/devices/sound/qsound.h
index 53966e8b701..9bdbdc5716e 100644
--- a/src/devices/sound/qsound.h
+++ b/src/devices/sound/qsound.h
@@ -47,9 +47,7 @@ private:
DECLARE_WRITE_LINE_MEMBER(dsp_ock_w);
DECLARE_READ16_MEMBER(dsp_pio_r);
void set_dsp_ready(void *ptr, s32 param);
- void set_cmd_addr(void *ptr, s32 param);
- void set_cmd_data_high(void *ptr, s32 param);
- void set_cmd_data_low(void *ptr, s32 param);
+ void set_cmd(void *ptr, s32 param);
// MAME resources
required_device<dsp16_device_base> m_dsp;
@@ -57,11 +55,10 @@ private:
// DSP communication
u16 m_rom_bank, m_rom_offset;
- u16 m_cmd_addr, m_cmd_data;
+ u16 m_cmd_addr, m_cmd_data, m_new_data;
u8 m_cmd_pending, m_dsp_ready;
// serial sample recovery
- u64 m_last_time;
s16 m_samples[2];
u16 m_sr, m_fsr;
u8 m_ock, m_old, m_ready, m_channel;
diff --git a/src/devices/sound/qsoundhle.cpp b/src/devices/sound/qsoundhle.cpp
index 31b28b36e49..e310fb98090 100644
--- a/src/devices/sound/qsoundhle.cpp
+++ b/src/devices/sound/qsoundhle.cpp
@@ -27,7 +27,7 @@
***************************************************************************/
#include "emu.h"
-#include "qsound.h"
+#include "qsoundhle.h"
// device type definition
DEFINE_DEVICE_TYPE(QSOUND_HLE, qsound_hle_device, "qsound_hle", "QSound (HLE)")