diff options
author | 2019-03-30 06:50:57 +0900 | |
---|---|---|
committer | 2019-03-29 17:50:57 -0400 | |
commit | 6dbd636a809ce7bda3ec476239f7b32a2d1de537 (patch) | |
tree | 9a9e2ef85cb6d581fe3db8eafe99c46e9f49744a | |
parent | 8b08ad2ce691219eefa67f8b99baaeecadd35a81 (diff) |
vrc6.cpp : Updates (#4819)
* vrc6.cpp : Updates
Implement master frequency register, Fix frequency / square duty behaviors, Use shorter type values, Reduce unnecessary lines
device/bus/nes/konami.cpp : Fix vrc6 sound volume, Remove outdated comment
* vrc6.cpp : Fix regression
-rw-r--r-- | src/devices/bus/nes/konami.cpp | 4 | ||||
-rw-r--r-- | src/devices/sound/vrc6.cpp | 97 | ||||
-rw-r--r-- | src/devices/sound/vrc6.h | 14 |
3 files changed, 55 insertions, 60 deletions
diff --git a/src/devices/bus/nes/konami.cpp b/src/devices/bus/nes/konami.cpp index 2d3f20863cb..b936b06b48a 100644 --- a/src/devices/bus/nes/konami.cpp +++ b/src/devices/bus/nes/konami.cpp @@ -560,8 +560,6 @@ void nes_konami_vrc4_device::write_h(offs_t offset, uint8_t data) In MESS: Supported. It also uses konami_irq (there are IRQ issues though: see Akumajou Densetsu intro). - TODO: Add sound capabilities support! - -------------------------------------------------*/ void nes_konami_vrc6_device::write_h(offs_t offset, uint8_t data) @@ -644,7 +642,7 @@ void nes_konami_vrc6_device::device_add_mconfig(machine_config &config) // TODO: this is not how VRC6 clock signaling works! // The board uses the CLK pin in reality, not hardcoded NTSC values! - VRC6(config, m_vrc6snd, XTAL(21'477'272)/12).add_route(ALL_OUTPUTS, "addon", 0.5); + VRC6(config, m_vrc6snd, XTAL(21'477'272)/12).add_route(ALL_OUTPUTS, "addon", 1.0); } /*------------------------------------------------- diff --git a/src/devices/sound/vrc6.cpp b/src/devices/sound/vrc6.cpp index e990a0edd69..b769fde4043 100644 --- a/src/devices/sound/vrc6.cpp +++ b/src/devices/sound/vrc6.cpp @@ -16,8 +16,6 @@ #include "emu.h" #include "vrc6.h" -#define DISABLE_VRC6_SOUND // not ready yet - // device type definition DEFINE_DEVICE_TYPE(VRC6, vrc6snd_device, "vrc6snd", "Konami VRC6 (Sound)") @@ -29,10 +27,10 @@ DEFINE_DEVICE_TYPE(VRC6, vrc6snd_device, "vrc6snd", "Konami VRC6 (Sound)") // vrc6snd_device - constructor //------------------------------------------------- -vrc6snd_device::vrc6snd_device(const machine_config &mconfig, const char *tag, device_t *owner, uint32_t clock) +vrc6snd_device::vrc6snd_device(const machine_config &mconfig, const char *tag, device_t *owner, u32 clock) : device_t(mconfig, VRC6, tag, owner, clock) , device_sound_interface(mconfig, *this) - , m_freqctrl(0), m_pulsectrl{ 0, 0 }, m_sawrate(0) + , m_freqctrl(0), m_pulsectrl{ 0, 0 }, m_sawrate(0), m_master_freq(0) , m_pulsefrql{ 0, 0 }, m_pulsefrqh{ 0, 0 }, m_pulseduty{ 0, 0 } , m_sawfrql(0), m_sawfrqh(0), m_sawclock(0), m_sawaccum(0) , m_ticks{ 0, 0, 0 } @@ -55,10 +53,12 @@ void vrc6snd_device::device_start() m_ticks[0] = m_ticks[1] = m_ticks[2] = 0; m_output[0] = m_output[1] = m_output[2] = 0; m_pulseduty[0] = m_pulseduty[1] = 15; + m_master_freq = 0; save_item(NAME(m_freqctrl)); save_item(NAME(m_pulsectrl)); save_item(NAME(m_sawrate)); + save_item(NAME(m_master_freq)); save_item(NAME(m_sawaccum)); save_item(NAME(m_pulsefrql)); save_item(NAME(m_pulsefrqh)); @@ -85,6 +85,7 @@ void vrc6snd_device::device_reset() m_output[0] = m_output[1] = m_output[2] = 0; m_pulseduty[0] = m_pulseduty[1] = 15; m_pulsefrqh[0] = m_pulsefrqh[1] = m_sawfrqh = 0; + m_master_freq = 0; } //------------------------------------------------- @@ -94,27 +95,22 @@ void vrc6snd_device::device_reset() void vrc6snd_device::sound_stream_update(sound_stream &stream, stream_sample_t **inputs, stream_sample_t **outputs, int samples) { - stream_sample_t *out = outputs[0]; - int16_t tmp; - int i; + std::fill_n(&outputs[0][0], samples, 0); // check global halt bit if (m_freqctrl & 1) - { return; - } - for (i = 0; i < samples; i++) + for (int i = 0; i < samples; i++) { // update pulse1 if (m_pulsefrqh[0] & 0x80) { - m_ticks[0]--; if (m_ticks[0] == 0) { - m_ticks[0] = m_pulsefrql[0] | (m_pulsefrqh[0] & 0xf)<<4; + m_ticks[0] = (m_pulsefrql[0] | ((m_pulsefrqh[0] & 0xf) << 8)) >> m_master_freq; - m_pulseduty[0]--; + m_pulseduty[0] = (m_pulseduty[0] - 1) & 0xf; if (m_pulsectrl[0] & 0x80) { m_output[0] = m_pulsectrl[0] & 0xf; @@ -130,12 +126,9 @@ void vrc6snd_device::sound_stream_update(sound_stream &stream, stream_sample_t * m_output[0] = 0; } } - - if (m_pulseduty[0] == 0) - { - m_pulseduty[0] = 15; - } } + else + m_ticks[0]--; } else { @@ -145,12 +138,11 @@ void vrc6snd_device::sound_stream_update(sound_stream &stream, stream_sample_t * // update pulse2 if (m_pulsefrqh[1] & 0x80) { - m_ticks[1]--; if (m_ticks[1] == 0) { - m_ticks[1] = m_pulsefrql[1] | (m_pulsefrqh[1] & 0xf)<<4; + m_ticks[1] = (m_pulsefrql[1] | ((m_pulsefrqh[1] & 0xf) << 8)) >> m_master_freq; - m_pulseduty[1]--; + m_pulseduty[1] = (m_pulseduty[1] - 1) & 0xf; if (m_pulsectrl[1] & 0x80) { m_output[1] = m_pulsectrl[1] & 0xf; @@ -166,12 +158,9 @@ void vrc6snd_device::sound_stream_update(sound_stream &stream, stream_sample_t * m_output[1] = 0; } } - - if (m_pulseduty[1] == 0) - { - m_pulseduty[1] = 15; - } } + else + m_ticks[1]--; } else { @@ -181,10 +170,9 @@ void vrc6snd_device::sound_stream_update(sound_stream &stream, stream_sample_t * // update saw if (m_sawfrqh & 0x80) { - m_ticks[2]--; if (m_ticks[2] == 0) { - m_ticks[2] = m_sawfrql | (m_sawfrqh & 0xf)<<4; + m_ticks[2] = (m_sawfrql | ((m_sawfrqh & 0xf) << 8)) >> m_master_freq; // only update on even steps if ((m_sawclock > 0) && (!(m_sawclock & 1))) @@ -200,6 +188,8 @@ void vrc6snd_device::sound_stream_update(sound_stream &stream, stream_sample_t * m_output[2] = 0; } } + else + m_ticks[2]--; } else { @@ -207,10 +197,10 @@ void vrc6snd_device::sound_stream_update(sound_stream &stream, stream_sample_t * } // sum 2 4-bit pulses, 1 5-bit saw = unsigned 6 bit output - tmp = (int16_t)(uint8_t)(m_output[0] + m_output[1] + m_output[2]); + s16 tmp = (s16)(u8)(m_output[0] + m_output[1] + m_output[2]); tmp <<= 8; - out[i] = tmp; + outputs[0][i] = tmp; } } @@ -218,7 +208,7 @@ void vrc6snd_device::sound_stream_update(sound_stream &stream, stream_sample_t * // write - write to the chip's registers //--------------------------------------- -void vrc6snd_device::write(offs_t offset, uint8_t data) +void vrc6snd_device::write(offs_t offset, u8 data) { switch (offset >> 8) { @@ -232,28 +222,43 @@ void vrc6snd_device::write(offs_t offset, uint8_t data) case 1: m_pulsefrql[0] = data; - if (!(m_pulsefrqh[1] & 0x80)) + if (!(m_pulsefrqh[0] & 0x80)) { - m_ticks[0] &= ~0xff; - m_ticks[0] |= m_pulsefrql[0]; + m_ticks[0] = (m_pulsefrql[0] | ((m_pulsefrqh[0] & 0xf) << 8)) >> m_master_freq; } break; case 2: - #ifndef DISABLE_VRC6_SOUND m_pulsefrqh[0] = data; // if disabling channel, reset phase if (!(data & 0x80)) { m_pulseduty[0] = 15; - m_ticks[0] &= 0xff; - m_ticks[0] |= (m_pulsefrqh[0] & 0xf)<<4; + m_ticks[0] = (m_pulsefrql[0] | ((m_pulsefrqh[0] & 0xf) << 8)) >> m_master_freq; } - #endif break; case 3: m_freqctrl = data; + if (m_freqctrl & 4) + m_master_freq = 0x8; + else if (m_freqctrl & 2) + m_master_freq = 0x4; + else + m_master_freq = 0; + + if (!(m_pulsefrqh[0] & 0x80)) + { + m_ticks[0] = (m_pulsefrql[0] | ((m_pulsefrqh[0] & 0xf) << 8)) >> m_master_freq; + } + if (!(m_pulsefrqh[1] & 0x80)) + { + m_ticks[1] = (m_pulsefrql[1] | ((m_pulsefrqh[1] & 0xf) << 8)) >> m_master_freq; + } + if (!(m_sawfrqh & 0x80)) + { + m_ticks[2] = (m_sawfrql | ((m_sawfrqh & 0xf) << 8)) >> m_master_freq; + } break; } break; @@ -270,22 +275,18 @@ void vrc6snd_device::write(offs_t offset, uint8_t data) m_pulsefrql[1] = data; if (!(m_pulsefrqh[1] & 0x80)) { - m_ticks[1] &= ~0xff; - m_ticks[1] |= m_pulsefrql[1]; + m_ticks[1] = (m_pulsefrql[1] | ((m_pulsefrqh[1] & 0xf) << 8)) >> m_master_freq; } break; case 2: - #ifndef DISABLE_VRC6_SOUND m_pulsefrqh[1] = data; // if disabling channel, reset phase if (!(data & 0x80)) { m_pulseduty[1] = 15; - m_ticks[1] &= 0xff; - m_ticks[1] |= (m_pulsefrqh[1] & 0xf)<<4; + m_ticks[1] = (m_pulsefrql[1] | ((m_pulsefrqh[1] & 0xf) << 8)) >> m_master_freq; } - #endif break; } break; @@ -302,22 +303,18 @@ void vrc6snd_device::write(offs_t offset, uint8_t data) m_sawfrql = data; if (!(m_sawfrqh & 0x80)) { - m_ticks[2] &= ~0xff; - m_ticks[2] |= m_sawfrql; + m_ticks[2] = (m_sawfrql | ((m_sawfrqh & 0xf) << 8)) >> m_master_freq; } break; case 2: - #ifndef DISABLE_VRC6_SOUND m_sawfrqh = data; // if disabling channel, reset phase if (!(data & 0x80)) { m_sawaccum = 0; - m_ticks[2] &= 0xff; - m_ticks[2] |= (m_sawfrqh & 0xf)<<4; + m_ticks[2] = (m_sawfrql | ((m_sawfrqh & 0xf) << 8)) >> m_master_freq; } - #endif break; } break; diff --git a/src/devices/sound/vrc6.h b/src/devices/sound/vrc6.h index a24d34a90c4..f1ea8f5c9e3 100644 --- a/src/devices/sound/vrc6.h +++ b/src/devices/sound/vrc6.h @@ -22,9 +22,9 @@ class vrc6snd_device : public device_t, public device_sound_interface { public: // construction/destruction - vrc6snd_device(const machine_config &mconfig, const char *tag, device_t *owner, uint32_t clock); + vrc6snd_device(const machine_config &mconfig, const char *tag, device_t *owner, u32 clock); - void write(offs_t offset, uint8_t data); + void write(offs_t offset, u8 data); protected: // device-level overrides @@ -34,11 +34,11 @@ protected: virtual void sound_stream_update(sound_stream &stream, stream_sample_t **inputs, stream_sample_t **outputs, int samples) override; private: - uint8_t m_freqctrl, m_pulsectrl[2], m_sawrate; - uint8_t m_pulsefrql[2], m_pulsefrqh[2], m_pulseduty[2]; - uint8_t m_sawfrql, m_sawfrqh, m_sawclock, m_sawaccum; - uint16_t m_ticks[3]; - uint8_t m_output[3]; + u8 m_freqctrl, m_pulsectrl[2], m_sawrate, m_master_freq; + u8 m_pulsefrql[2], m_pulsefrqh[2], m_pulseduty[2]; + u8 m_sawfrql, m_sawfrqh, m_sawclock, m_sawaccum; + u16 m_ticks[3]; + u8 m_output[3]; sound_stream *m_stream; }; |