mirror of
https://github.com/holub/mame
synced 2025-06-09 14:22:41 +03:00
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
This commit is contained in:
parent
ddc7ec4db2
commit
0307b9664c
@ -3,8 +3,8 @@
|
|||||||
/*********************************************************/
|
/*********************************************************/
|
||||||
/* ricoh RF5C68(or clone) PCM controller */
|
/* ricoh RF5C68(or clone) PCM controller */
|
||||||
/* */
|
/* */
|
||||||
/* TODO : RF5C164 (Sega CD/Mega CD) */
|
/* TODO: Verify RF5C105,164 (Sega CD/Mega CD) */
|
||||||
/* has difference? */
|
/* differences */
|
||||||
/*********************************************************/
|
/*********************************************************/
|
||||||
|
|
||||||
#include "emu.h"
|
#include "emu.h"
|
||||||
@ -12,8 +12,8 @@
|
|||||||
|
|
||||||
|
|
||||||
// device type definition
|
// device type definition
|
||||||
DEFINE_DEVICE_TYPE(RF5C68, rf5c68_device, "rf5c68", "Ricoh RF5C68")
|
DEFINE_DEVICE_TYPE(RF5C68, rf5c68_device, "rf5c68", "Ricoh RF5C68")
|
||||||
DEFINE_DEVICE_TYPE(RF5C164, rf5c164_device, "rf5c164", "Ricoh RF5C164")
|
DEFINE_DEVICE_TYPE(RF5C164, rf5c164_device, "rf5c164", "Ricoh RF5C164") // or Sega 315-5476A
|
||||||
|
|
||||||
|
|
||||||
void rf5c68_device::map(address_map &map)
|
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
|
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
|
// LIVE DEVICE
|
||||||
@ -32,7 +40,7 @@ void rf5c68_device::map(address_map &map)
|
|||||||
// rf5c68_device - constructor
|
// 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_t(mconfig, type, tag, owner, clock)
|
||||||
, device_sound_interface(mconfig, *this)
|
, device_sound_interface(mconfig, *this)
|
||||||
, device_memory_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_cbank(0)
|
||||||
, m_wbank(0)
|
, m_wbank(0)
|
||||||
, m_enable(0)
|
, m_enable(0)
|
||||||
|
, m_output_bits(output_bits)
|
||||||
, m_sample_end_cb(*this)
|
, m_sample_end_cb(*this)
|
||||||
{
|
{
|
||||||
}
|
}
|
||||||
|
|
||||||
rf5c68_device::rf5c68_device(const machine_config &mconfig, const char *tag, device_t *owner, uint32_t clock)
|
rf5c68_device::rf5c68_device(const machine_config &mconfig, const char *tag, device_t *owner, u32 clock)
|
||||||
: rf5c68_device(mconfig, RF5C68, tag, owner, 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)
|
rf5c164_device::rf5c164_device(const machine_config &mconfig, const char *tag, device_t *owner, u32 clock)
|
||||||
: rf5c68_device(mconfig, RF5C164, tag, owner, 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++)
|
for (int j = 0; j < samples; j++)
|
||||||
{
|
{
|
||||||
stream_sample_t temp;
|
stream_sample_t temp;
|
||||||
@ -181,12 +195,12 @@ void rf5c68_device::sound_stream_update(sound_stream &stream, stream_sample_t **
|
|||||||
temp = left[j];
|
temp = left[j];
|
||||||
if (temp > 32767) temp = 32767;
|
if (temp > 32767) temp = 32767;
|
||||||
else if (temp < -32768) temp = -32768;
|
else if (temp < -32768) temp = -32768;
|
||||||
left[j] = temp & ~0x3f;
|
left[j] = temp & ~output_nandmask;
|
||||||
|
|
||||||
temp = right[j];
|
temp = right[j];
|
||||||
if (temp > 32767) temp = 32767;
|
if (temp > 32767) temp = 32767;
|
||||||
else if (temp < -32768) temp = -32768;
|
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?
|
// TODO: RF5C164 only?
|
||||||
u8 rf5c68_device::rf5c68_r(offs_t offset)
|
u8 rf5c68_device::rf5c68_r(offs_t offset)
|
||||||
{
|
{
|
||||||
uint8_t shift;
|
u8 shift;
|
||||||
|
|
||||||
m_stream->update();
|
m_stream->update();
|
||||||
shift = (offset & 1) ? 11 + 8 : 11;
|
shift = (offset & 1) ? 11 + 8 : 11;
|
||||||
|
@ -26,7 +26,7 @@ class rf5c68_device : public device_t,
|
|||||||
public:
|
public:
|
||||||
typedef device_delegate<void (int channel)> sample_end_cb_delegate;
|
typedef device_delegate<void (int channel)> 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 <typename... T> void set_end_callback(T &&... args) { m_sample_end_cb.set(std::forward<T>(args)...); }
|
template <typename... T> void set_end_callback(T &&... args) { m_sample_end_cb.set(std::forward<T>(args)...); }
|
||||||
|
|
||||||
@ -38,7 +38,7 @@ public:
|
|||||||
|
|
||||||
void map(address_map &map);
|
void map(address_map &map);
|
||||||
protected:
|
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
|
// device-level overrides
|
||||||
virtual void device_start() override;
|
virtual void device_start() override;
|
||||||
@ -59,21 +59,22 @@ private:
|
|||||||
{
|
{
|
||||||
pcm_channel() { }
|
pcm_channel() { }
|
||||||
|
|
||||||
uint8_t enable = 0;
|
u8 enable = 0;
|
||||||
uint8_t env = 0;
|
u8 env = 0;
|
||||||
uint8_t pan = 0;
|
u8 pan = 0;
|
||||||
uint8_t start = 0;
|
u8 start = 0;
|
||||||
uint32_t addr = 0;
|
u32 addr = 0;
|
||||||
uint16_t step = 0;
|
u16 step = 0;
|
||||||
uint16_t loopst = 0;
|
u16 loopst = 0;
|
||||||
};
|
};
|
||||||
|
|
||||||
memory_access<16, 0, 0, ENDIANNESS_LITTLE>::cache m_cache;
|
memory_access<16, 0, 0, ENDIANNESS_LITTLE>::cache m_cache;
|
||||||
sound_stream* m_stream;
|
sound_stream* m_stream;
|
||||||
pcm_channel m_chan[NUM_CHANNELS];
|
pcm_channel m_chan[NUM_CHANNELS];
|
||||||
uint8_t m_cbank;
|
u8 m_cbank;
|
||||||
uint16_t m_wbank;
|
u16 m_wbank;
|
||||||
uint8_t m_enable;
|
u8 m_enable;
|
||||||
|
int m_output_bits;
|
||||||
|
|
||||||
sample_end_cb_delegate m_sample_end_cb;
|
sample_end_cb_delegate m_sample_end_cb;
|
||||||
};
|
};
|
||||||
@ -81,7 +82,9 @@ private:
|
|||||||
class rf5c164_device : public rf5c68_device
|
class rf5c164_device : public rf5c68_device
|
||||||
{
|
{
|
||||||
public:
|
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)
|
DECLARE_DEVICE_TYPE(RF5C68, rf5c68_device)
|
||||||
|
@ -1375,7 +1375,7 @@ void segas18_state::system18(machine_config &config)
|
|||||||
ym3438_device &ym2(YM3438(config, "ym2", 8000000));
|
ym3438_device &ym2(YM3438(config, "ym2", 8000000));
|
||||||
ym2.add_route(ALL_OUTPUTS, "mono", 0.40);
|
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.add_route(ALL_OUTPUTS, "mono", 1.0);
|
||||||
rfsnd.set_addrmap(0, &segas18_state::pcm_map);
|
rfsnd.set_addrmap(0, &segas18_state::pcm_map);
|
||||||
}
|
}
|
||||||
|
@ -2297,7 +2297,7 @@ void segas32_state::device_add_mconfig(machine_config &config)
|
|||||||
ym2.add_route(0, "lspeaker", 0.40);
|
ym2.add_route(0, "lspeaker", 0.40);
|
||||||
ym2.add_route(1, "rspeaker", 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(0, "lspeaker", 0.55);
|
||||||
rfsnd.add_route(1, "rspeaker", 0.55);
|
rfsnd.add_route(1, "rspeaker", 0.55);
|
||||||
rfsnd.set_addrmap(0, &segas32_state::rf5c68_map);
|
rfsnd.set_addrmap(0, &segas32_state::rf5c68_map);
|
||||||
|
@ -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(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(0xff0000, 0xff3fff).m(m_rfsnd, FUNC(rf5c164_device::rf5c164_map)).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(0xff8000, 0xff8001).rw(FUNC(sega_segacd_device::segacd_sub_led_ready_r), FUNC(sega_segacd_device::segacd_sub_led_ready_w));
|
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));
|
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);
|
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( 0, ":lspeaker", 0.50 );
|
||||||
m_rfsnd->add_route( 1, ":rspeaker", 0.50 );
|
m_rfsnd->add_route( 1, ":rspeaker", 0.50 );
|
||||||
m_rfsnd->set_addrmap(0, &sega_segacd_device::segacd_pcm_map);
|
m_rfsnd->set_addrmap(0, &sega_segacd_device::segacd_pcm_map);
|
||||||
|
@ -111,7 +111,7 @@ protected:
|
|||||||
|
|
||||||
required_device<cpu_device> m_scdcpu;
|
required_device<cpu_device> m_scdcpu;
|
||||||
required_device<cpu_device> m_hostcpu;
|
required_device<cpu_device> m_hostcpu;
|
||||||
required_device<rf5c68_device> m_rfsnd;
|
required_device<rf5c164_device> m_rfsnd;
|
||||||
required_device<lc89510_temp_device> m_lc89510_temp;
|
required_device<lc89510_temp_device> m_lc89510_temp;
|
||||||
required_device<timer_device> m_stopwatch_timer;
|
required_device<timer_device> m_stopwatch_timer;
|
||||||
required_device<timer_device> m_stamp_timer;
|
required_device<timer_device> m_stamp_timer;
|
||||||
|
Loading…
Reference in New Issue
Block a user