diff options
Diffstat (limited to 'src/devices/sound/ymz770.cpp')
-rw-r--r-- | src/devices/sound/ymz770.cpp | 114 |
1 files changed, 51 insertions, 63 deletions
diff --git a/src/devices/sound/ymz770.cpp b/src/devices/sound/ymz770.cpp index f5c84203300..f175cac853d 100644 --- a/src/devices/sound/ymz770.cpp +++ b/src/devices/sound/ymz770.cpp @@ -2,17 +2,17 @@ // copyright-holders:Olivier Galibert, R. Belmont, MetalliC /*************************************************************************** - Yamaha YMZ770C "AMMS-A" and YMZ774 "AMMS2C" + Yamaha YMZ770B "AMMSL", YMZ770C "AMMS-A" and YMZ774 "AMMS2C" Emulation by R. Belmont and MetalliC AMM decode by Olivier Galibert ----- TODO: -- What does channel ATBL mean? - Simple Access mode. SACs is register / data lists same as SEQ. in 770C, when both /SEL and /CS pins goes low - will be run SAC with number set at data bus. can not be used in CV1K (/SEL pin is NC, internally pulled to VCC), probably not used in PGM2 too. 770: +- Configurable clock (currently hardcoded at 16kHz) - sequencer timers implemented but seems unused, presumably because of design flaws or bugs, likely due to lack of automatic adding of sequencer # to register offset. in result sequences uses very long chains of 32-sample wait commands instead, wasting a lot of ROM space. - sequencer triggers not implemented, not sure how they works (Deathsmiles ending tune starts sequence with TGST = 01h, likely a bug and don't affect tune playback) @@ -23,7 +23,7 @@ TODO: - sequencer off trigger (not used in games) known SPUs in this series: - YMZ770B AMMSL Capcom medal hardware (alien.cpp), sample format is not AMM, in other parts looks like 770C + YMZ770B AMMSL Capcom medal hardware (alien.cpp) YMZ770C AMMS-A Cave CV1000 YMZ771 SSGS3 YMZ773 AMMS2 Cron corp. video slots @@ -77,7 +77,7 @@ ymz770_device::ymz770_device(const machine_config &mconfig, device_type type, co void ymz770_device::device_start() { // create the stream - m_stream = machine().sound().stream_alloc(*this, 0, 2, m_sclock); + m_stream = stream_alloc(0, 2, m_sclock); for (auto & channel : m_channels) { @@ -98,47 +98,40 @@ void ymz770_device::device_start() save_item(NAME(m_bsl)); save_item(NAME(m_cpl)); - for (int ch = 0; ch < 16; ch++) // TODO array size - { - save_item(NAME(m_channels[ch].phrase), ch); - save_item(NAME(m_channels[ch].pan), ch); - save_item(NAME(m_channels[ch].pan_delay), ch); - save_item(NAME(m_channels[ch].pan1), ch); - save_item(NAME(m_channels[ch].pan1_delay), ch); - save_item(NAME(m_channels[ch].volume), ch); - save_item(NAME(m_channels[ch].volume_target), ch); - save_item(NAME(m_channels[ch].volume_delay), ch); - save_item(NAME(m_channels[ch].volume2), ch); - save_item(NAME(m_channels[ch].loop), ch); - save_item(NAME(m_channels[ch].is_playing), ch); - save_item(NAME(m_channels[ch].last_block), ch); - save_item(NAME(m_channels[ch].is_paused), ch); - save_item(NAME(m_channels[ch].output_remaining), ch); - save_item(NAME(m_channels[ch].output_ptr), ch); - save_item(NAME(m_channels[ch].atbl), ch); - save_item(NAME(m_channels[ch].pptr), ch); - save_item(NAME(m_channels[ch].output_data), ch); - } - for (int ch = 0; ch < 8; ch++) - { - save_item(NAME(m_sequences[ch].delay), ch); - save_item(NAME(m_sequences[ch].sequence), ch); - save_item(NAME(m_sequences[ch].timer), ch); - save_item(NAME(m_sequences[ch].stopchan), ch); - save_item(NAME(m_sequences[ch].loop), ch); - save_item(NAME(m_sequences[ch].bank), ch); - save_item(NAME(m_sequences[ch].is_playing), ch); - save_item(NAME(m_sequences[ch].is_paused), ch); - save_item(NAME(m_sequences[ch].offset), ch); - } - for (int ch = 0; ch < 8; ch++) - { - save_item(NAME(m_sqcs[ch].sqc), ch); - save_item(NAME(m_sqcs[ch].loop), ch); - save_item(NAME(m_sqcs[ch].is_playing), ch); - save_item(NAME(m_sqcs[ch].is_waiting), ch); - save_item(NAME(m_sqcs[ch].offset), ch); - } + save_item(STRUCT_MEMBER(m_channels, phrase)); + save_item(STRUCT_MEMBER(m_channels, pan)); + save_item(STRUCT_MEMBER(m_channels, pan_delay)); + save_item(STRUCT_MEMBER(m_channels, pan1)); + save_item(STRUCT_MEMBER(m_channels, pan1_delay)); + save_item(STRUCT_MEMBER(m_channels, volume)); + save_item(STRUCT_MEMBER(m_channels, volume_target)); + save_item(STRUCT_MEMBER(m_channels, volume_delay)); + save_item(STRUCT_MEMBER(m_channels, volume2)); + save_item(STRUCT_MEMBER(m_channels, loop)); + save_item(STRUCT_MEMBER(m_channels, is_playing)); + save_item(STRUCT_MEMBER(m_channels, last_block)); + save_item(STRUCT_MEMBER(m_channels, is_paused)); + save_item(STRUCT_MEMBER(m_channels, output_remaining)); + save_item(STRUCT_MEMBER(m_channels, output_ptr)); + save_item(STRUCT_MEMBER(m_channels, atbl)); + save_item(STRUCT_MEMBER(m_channels, pptr)); + save_item(STRUCT_MEMBER(m_channels, output_data)); + + save_item(STRUCT_MEMBER(m_sequences, delay)); + save_item(STRUCT_MEMBER(m_sequences, sequence)); + save_item(STRUCT_MEMBER(m_sequences, timer)); + save_item(STRUCT_MEMBER(m_sequences, stopchan)); + save_item(STRUCT_MEMBER(m_sequences, loop)); + save_item(STRUCT_MEMBER(m_sequences, bank)); + save_item(STRUCT_MEMBER(m_sequences, is_playing)); + save_item(STRUCT_MEMBER(m_sequences, is_paused)); + save_item(STRUCT_MEMBER(m_sequences, offset)); + + save_item(STRUCT_MEMBER(m_sqcs, sqc)); + save_item(STRUCT_MEMBER(m_sqcs, loop)); + save_item(STRUCT_MEMBER(m_sqcs, is_playing)); + save_item(STRUCT_MEMBER(m_sqcs, is_waiting)); + save_item(STRUCT_MEMBER(m_sqcs, offset)); } @@ -189,14 +182,9 @@ void ymz770_device::device_reset() // our sound stream //------------------------------------------------- -void ymz770_device::sound_stream_update(sound_stream &stream, stream_sample_t **inputs, stream_sample_t **outputs, int samples) +void ymz770_device::sound_stream_update(sound_stream &stream) { - stream_sample_t *outL, *outR; - - outL = outputs[0]; - outR = outputs[1]; - - for (int i = 0; i < samples; i++) + for (int i = 0; i < stream.samples(); i++) { sequencer(); @@ -245,7 +233,7 @@ retry: { // next block int sample_rate, channel_count; - if (!channel.decoder->decode_buffer(channel.pptr, m_rom.bytes()*8, channel.output_data, channel.output_remaining, sample_rate, channel_count) || channel.output_remaining == 0) + if (!channel.decoder->decode_buffer(channel.pptr, m_rom.bytes()*8, channel.output_data, channel.output_remaining, sample_rate, channel_count, channel.atbl) || channel.output_remaining == 0) { channel.is_playing = !channel.last_block; // detect infinite retry loop channel.last_block = true; @@ -275,22 +263,22 @@ retry: switch (m_cpl) { case 3: - mixl = (mixl > ClipMax3) ? ClipMax3 : (mixl < -ClipMax3) ? -ClipMax3 : mixl; - mixr = (mixr > ClipMax3) ? ClipMax3 : (mixr < -ClipMax3) ? -ClipMax3 : mixr; + mixl = std::clamp(mixl, -ClipMax3, ClipMax3); + mixr = std::clamp(mixr, -ClipMax3, ClipMax3); break; case 2: - mixl = (mixl > ClipMax2) ? ClipMax2 : (mixl < -ClipMax2) ? -ClipMax2 : mixl; - mixr = (mixr > ClipMax2) ? ClipMax2 : (mixr < -ClipMax2) ? -ClipMax2 : mixr; + mixl = std::clamp(mixl, -ClipMax2, ClipMax2); + mixr = std::clamp(mixr, -ClipMax2, ClipMax2); break; case 1: - mixl = (mixl > 32767) ? 32767 : (mixl < -32768) ? -32768 : mixl; - mixr = (mixr > 32767) ? 32767 : (mixr < -32768) ? -32768 : mixr; + mixl = std::clamp(mixl, -32768, 32767); + mixr = std::clamp(mixr, -32768, 32767); break; } if (m_mute) mixr = mixl = 0; - outL[i] = mixl; - outR[i] = mixr; + stream.put_int(0, i, mixl, 32768); + stream.put_int(1, i, mixr, 32768); } } @@ -333,7 +321,7 @@ void ymz770_device::sequencer() // write - write to the chip's registers //------------------------------------------------- -WRITE8_MEMBER( ymz770_device::write ) +void ymz770_device::write(offs_t offset, uint8_t data) { if (offset & 1) { @@ -478,7 +466,7 @@ ymz774_device::ymz774_device(const machine_config &mconfig, const char *tag, dev } } -READ8_MEMBER(ymz774_device::read) +uint8_t ymz774_device::read(offs_t offset) { if (offset & 1) { |