From 0307b9664ccad1ac977aa27289f702af68e14ac5 Mon Sep 17 00:00:00 2001 From: cam900 Date: Mon, 8 Jun 2020 23:38:46 +0900 Subject: [PATCH] rf5c68.cpp: Implement some chip variant differences, Verify,Implement RF5C164 default register map Reference: RF5C68 Datasheet, Mega CD hardware manual PCM sound source segas18.cpp, segas32.cpp: Add notes for sound chip megacd.cpp: Correct sound chip variation --- src/devices/sound/rf5c68.cpp | 42 ++++++++++++++++++++++++------------ src/devices/sound/rf5c68.h | 29 ++++++++++++++----------- src/mame/drivers/segas18.cpp | 2 +- src/mame/drivers/segas32.cpp | 2 +- src/mame/machine/megacd.cpp | 6 ++---- src/mame/machine/megacd.h | 2 +- 6 files changed, 49 insertions(+), 34 deletions(-) diff --git a/src/devices/sound/rf5c68.cpp b/src/devices/sound/rf5c68.cpp index 22d4e37a3b9..adb544afc64 100644 --- a/src/devices/sound/rf5c68.cpp +++ b/src/devices/sound/rf5c68.cpp @@ -3,8 +3,8 @@ /*********************************************************/ /* ricoh RF5C68(or clone) PCM controller */ /* */ -/* TODO : RF5C164 (Sega CD/Mega CD) */ -/* has difference? */ +/* TODO: Verify RF5C105,164 (Sega CD/Mega CD) */ +/* differences */ /*********************************************************/ #include "emu.h" @@ -12,8 +12,8 @@ // device type definition -DEFINE_DEVICE_TYPE(RF5C68, rf5c68_device, "rf5c68", "Ricoh RF5C68") -DEFINE_DEVICE_TYPE(RF5C164, rf5c164_device, "rf5c164", "Ricoh RF5C164") +DEFINE_DEVICE_TYPE(RF5C68, rf5c68_device, "rf5c68", "Ricoh RF5C68") +DEFINE_DEVICE_TYPE(RF5C164, rf5c164_device, "rf5c164", "Ricoh RF5C164") // or Sega 315-5476A void rf5c68_device::map(address_map &map) @@ -23,6 +23,14 @@ void rf5c68_device::map(address_map &map) map(0x1000, 0x1fff).rw(FUNC(rf5c68_device::rf5c68_mem_r), FUNC(rf5c68_device::rf5c68_mem_w)); // A12 = 1 : Waveform data } +void rf5c164_device::rf5c164_map(address_map &map) +{ + // TODO: Not mirrored? + map(0x0000, 0x0008).w(FUNC(rf5c68_device::rf5c68_w)); // A12 = 0 : Register + map(0x0010, 0x001f).r(FUNC(rf5c68_device::rf5c68_r)); + map(0x1000, 0x1fff).rw(FUNC(rf5c68_device::rf5c68_mem_r), FUNC(rf5c68_device::rf5c68_mem_w)); // A12 = 1 : Waveform data +} + //************************************************************************** // LIVE DEVICE @@ -32,7 +40,7 @@ void rf5c68_device::map(address_map &map) // rf5c68_device - constructor //------------------------------------------------- -rf5c68_device::rf5c68_device(const machine_config & mconfig, device_type type, const char * tag, device_t * owner, u32 clock) +rf5c68_device::rf5c68_device(const machine_config & mconfig, device_type type, const char * tag, device_t * owner, u32 clock, int output_bits) : device_t(mconfig, type, tag, owner, clock) , device_sound_interface(mconfig, *this) , device_memory_interface(mconfig, *this) @@ -41,22 +49,23 @@ rf5c68_device::rf5c68_device(const machine_config & mconfig, device_type type, c , m_cbank(0) , m_wbank(0) , m_enable(0) + , m_output_bits(output_bits) , m_sample_end_cb(*this) { } -rf5c68_device::rf5c68_device(const machine_config &mconfig, const char *tag, device_t *owner, uint32_t clock) - : rf5c68_device(mconfig, RF5C68, tag, owner, clock) +rf5c68_device::rf5c68_device(const machine_config &mconfig, const char *tag, device_t *owner, u32 clock) + : rf5c68_device(mconfig, RF5C68, tag, owner, clock, 10) { } //------------------------------------------------- -// rf5c68_device - constructor +// rf5c164_device - constructor //------------------------------------------------- -rf5c164_device::rf5c164_device(const machine_config &mconfig, const char *tag, device_t *owner, uint32_t clock) - : rf5c68_device(mconfig, RF5C164, tag, owner, clock) +rf5c164_device::rf5c164_device(const machine_config &mconfig, const char *tag, device_t *owner, u32 clock) + : rf5c68_device(mconfig, RF5C164, tag, owner, clock, 16) { } @@ -173,7 +182,12 @@ void rf5c68_device::sound_stream_update(sound_stream &stream, stream_sample_t ** } } - /* now clamp and shift the result (output is only 10 bits) */ + /* + now clamp and shift the result (output is only 10 bits for RF5C68, 16 bits for RF5C164) + reference: Mega CD hardware manual, RF5C68 datasheet + */ + const u8 output_shift = (m_output_bits > 16) ? 0 : (16 - m_output_bits); + const s32 output_nandmask = (1 << output_shift) - 1; for (int j = 0; j < samples; j++) { stream_sample_t temp; @@ -181,12 +195,12 @@ void rf5c68_device::sound_stream_update(sound_stream &stream, stream_sample_t ** temp = left[j]; if (temp > 32767) temp = 32767; else if (temp < -32768) temp = -32768; - left[j] = temp & ~0x3f; + left[j] = temp & ~output_nandmask; temp = right[j]; if (temp > 32767) temp = 32767; else if (temp < -32768) temp = -32768; - right[j] = temp & ~0x3f; + right[j] = temp & ~output_nandmask; } } @@ -198,7 +212,7 @@ void rf5c68_device::sound_stream_update(sound_stream &stream, stream_sample_t ** // TODO: RF5C164 only? u8 rf5c68_device::rf5c68_r(offs_t offset) { - uint8_t shift; + u8 shift; m_stream->update(); shift = (offset & 1) ? 11 + 8 : 11; diff --git a/src/devices/sound/rf5c68.h b/src/devices/sound/rf5c68.h index b6d662c2814..f5585506828 100644 --- a/src/devices/sound/rf5c68.h +++ b/src/devices/sound/rf5c68.h @@ -26,7 +26,7 @@ class rf5c68_device : public device_t, public: typedef device_delegate sample_end_cb_delegate; - rf5c68_device(const machine_config &mconfig, const char *tag, device_t *owner, uint32_t clock); + rf5c68_device(const machine_config &mconfig, const char *tag, device_t *owner, u32 clock); template void set_end_callback(T &&... args) { m_sample_end_cb.set(std::forward(args)...); } @@ -38,7 +38,7 @@ public: void map(address_map &map); protected: - rf5c68_device(const machine_config &mconfig, device_type type, const char *tag, device_t *owner, u32 clock); + rf5c68_device(const machine_config &mconfig, device_type type, const char *tag, device_t *owner, u32 clock, int output_bits); // device-level overrides virtual void device_start() override; @@ -59,21 +59,22 @@ private: { pcm_channel() { } - uint8_t enable = 0; - uint8_t env = 0; - uint8_t pan = 0; - uint8_t start = 0; - uint32_t addr = 0; - uint16_t step = 0; - uint16_t loopst = 0; + u8 enable = 0; + u8 env = 0; + u8 pan = 0; + u8 start = 0; + u32 addr = 0; + u16 step = 0; + u16 loopst = 0; }; memory_access<16, 0, 0, ENDIANNESS_LITTLE>::cache m_cache; sound_stream* m_stream; pcm_channel m_chan[NUM_CHANNELS]; - uint8_t m_cbank; - uint16_t m_wbank; - uint8_t m_enable; + u8 m_cbank; + u16 m_wbank; + u8 m_enable; + int m_output_bits; sample_end_cb_delegate m_sample_end_cb; }; @@ -81,7 +82,9 @@ private: class rf5c164_device : public rf5c68_device { public: - rf5c164_device(const machine_config &mconfig, const char *tag, device_t *owner, uint32_t clock); + rf5c164_device(const machine_config &mconfig, const char *tag, device_t *owner, u32 clock); + + void rf5c164_map(address_map &map); }; DECLARE_DEVICE_TYPE(RF5C68, rf5c68_device) diff --git a/src/mame/drivers/segas18.cpp b/src/mame/drivers/segas18.cpp index 3a75b63d341..62ae430220c 100644 --- a/src/mame/drivers/segas18.cpp +++ b/src/mame/drivers/segas18.cpp @@ -1375,7 +1375,7 @@ void segas18_state::system18(machine_config &config) ym3438_device &ym2(YM3438(config, "ym2", 8000000)); ym2.add_route(ALL_OUTPUTS, "mono", 0.40); - rf5c68_device &rfsnd(RF5C68(config, "rfsnd", 10000000)); + rf5c68_device &rfsnd(RF5C68(config, "rfsnd", 10000000)); // ASSP (RF)5C68A rfsnd.add_route(ALL_OUTPUTS, "mono", 1.0); rfsnd.set_addrmap(0, &segas18_state::pcm_map); } diff --git a/src/mame/drivers/segas32.cpp b/src/mame/drivers/segas32.cpp index c2d7ce2c389..ce33f9f330b 100644 --- a/src/mame/drivers/segas32.cpp +++ b/src/mame/drivers/segas32.cpp @@ -2297,7 +2297,7 @@ void segas32_state::device_add_mconfig(machine_config &config) ym2.add_route(0, "lspeaker", 0.40); ym2.add_route(1, "rspeaker", 0.40); - rf5c68_device &rfsnd(RF5C68(config, "rfsnd", RFC_CLOCK/4)); + rf5c68_device &rfsnd(RF5C68(config, "rfsnd", RFC_CLOCK/4)); // ASSP (RF)5C105 or Sega 315-5476A rfsnd.add_route(0, "lspeaker", 0.55); rfsnd.add_route(1, "rspeaker", 0.55); rfsnd.set_addrmap(0, &segas32_state::rf5c68_map); diff --git a/src/mame/machine/megacd.cpp b/src/mame/machine/megacd.cpp index d8e41d48c13..f8938ad60cc 100644 --- a/src/mame/machine/megacd.cpp +++ b/src/mame/machine/megacd.cpp @@ -86,9 +86,7 @@ void sega_segacd_device::segacd_map(address_map &map) map(0xfe0000, 0xfe3fff).rw(FUNC(sega_segacd_device::backupram_r), FUNC(sega_segacd_device::backupram_w)).umask16(0x00ff); // backup RAM, odd bytes only! - map(0xff0000, 0xff001f).w("rfsnd", FUNC(rf5c68_device::rf5c68_w)).umask16(0x00ff); // PCM, RF5C164 - map(0xff0020, 0xff003f).r("rfsnd", FUNC(rf5c68_device::rf5c68_r)).umask16(0x00ff); - map(0xff2000, 0xff3fff).rw("rfsnd", FUNC(rf5c68_device::rf5c68_mem_r), FUNC(rf5c68_device::rf5c68_mem_w)).umask16(0x00ff); // PCM, RF5C164 + map(0xff0000, 0xff3fff).m(m_rfsnd, FUNC(rf5c164_device::rf5c164_map)).umask16(0x00ff); // PCM, RF5C164 map(0xff8000, 0xff8001).rw(FUNC(sega_segacd_device::segacd_sub_led_ready_r), FUNC(sega_segacd_device::segacd_sub_led_ready_w)); map(0xff8002, 0xff8003).rw(FUNC(sega_segacd_device::segacd_sub_memory_mode_r), FUNC(sega_segacd_device::segacd_sub_memory_mode_w)); @@ -314,7 +312,7 @@ void sega_segacd_device::device_add_mconfig(machine_config &config) config.set_default_layout(layout_megacd); - RF5C68(config, m_rfsnd, SEGACD_CLOCK); // RF5C164! + RF5C164(config, m_rfsnd, SEGACD_CLOCK); // or Sega 315-5476A m_rfsnd->add_route( 0, ":lspeaker", 0.50 ); m_rfsnd->add_route( 1, ":rspeaker", 0.50 ); m_rfsnd->set_addrmap(0, &sega_segacd_device::segacd_pcm_map); diff --git a/src/mame/machine/megacd.h b/src/mame/machine/megacd.h index e50287a83df..6ec41979bc4 100644 --- a/src/mame/machine/megacd.h +++ b/src/mame/machine/megacd.h @@ -111,7 +111,7 @@ protected: required_device m_scdcpu; required_device m_hostcpu; - required_device m_rfsnd; + required_device m_rfsnd; required_device m_lc89510_temp; required_device m_stopwatch_timer; required_device m_stamp_timer;