diff options
Diffstat (limited to 'src/devices/sound')
-rw-r--r-- | src/devices/sound/astrocde.cpp | 2 | ||||
-rw-r--r-- | src/devices/sound/rf5c400.cpp | 82 | ||||
-rw-r--r-- | src/devices/sound/rf5c400.h | 11 | ||||
-rw-r--r-- | src/devices/sound/tms5110.cpp | 2 | ||||
-rw-r--r-- | src/devices/sound/ymz770.cpp | 63 | ||||
-rw-r--r-- | src/devices/sound/ymz770.h | 10 |
6 files changed, 135 insertions, 35 deletions
diff --git a/src/devices/sound/astrocde.cpp b/src/devices/sound/astrocde.cpp index 1e8349bbd9d..36b0f76601a 100644 --- a/src/devices/sound/astrocde.cpp +++ b/src/devices/sound/astrocde.cpp @@ -87,7 +87,7 @@ void astrocade_device::device_start() /* generate a bitswap table for the noise */ for (i = 0; i < 256; i++) - m_bitswap[i] = BITSWAP8(i, 0,1,2,3,4,5,6,7); + m_bitswap[i] = bitswap<8>(i, 0,1,2,3,4,5,6,7); /* allocate a stream for output */ m_stream = stream_alloc(0, 1, clock()); diff --git a/src/devices/sound/rf5c400.cpp b/src/devices/sound/rf5c400.cpp index 39440c66991..6c047935399 100644 --- a/src/devices/sound/rf5c400.cpp +++ b/src/devices/sound/rf5c400.cpp @@ -129,7 +129,7 @@ void rf5c400_device::envelope_tables::init(uint32_t clock) rf5c400_device::rf5c400_device(const machine_config &mconfig, const char *tag, device_t *owner, uint32_t clock) : device_t(mconfig, RF5C400, tag, owner, clock) , device_sound_interface(mconfig, *this) - , m_rom(*this, DEVICE_SELF) + , device_rom_interface(mconfig, *this, 25, ENDIANNESS_LITTLE, 16) , m_stream(nullptr) , m_env_tables() { @@ -155,6 +155,10 @@ void rf5c400_device::device_start() chan.env_scale = 1.0; } + save_item(NAME(m_rf5c400_status)); + save_item(NAME(m_ext_mem_address)); + save_item(NAME(m_ext_mem_data)); + for (int i = 0; i < ARRAY_LENGTH(m_channels); i++) { save_item(NAME(m_channels[i].startH), i); @@ -180,8 +184,6 @@ void rf5c400_device::device_start() } m_stream = stream_alloc(0, 2, clock() / 384); - - m_rommask = m_rom.length() - 1; } //------------------------------------------------- @@ -191,7 +193,6 @@ void rf5c400_device::device_start() void rf5c400_device::sound_stream_update(sound_stream &stream, stream_sample_t **inputs, stream_sample_t **outputs, int samples) { int i, ch; - int16_t *rom = m_rom; uint32_t end, loop; uint64_t pos; uint8_t vol, lvol, rvol, type; @@ -228,7 +229,7 @@ void rf5c400_device::sound_stream_update(sound_stream &stream, stream_sample_t * if (env_phase == PHASE_NONE) break; - tmp = rom[(pos>>16) & m_rommask]; + tmp = read_word((pos>>16)<<1); switch ( type ) { case TYPE_16: @@ -258,7 +259,7 @@ void rf5c400_device::sound_stream_update(sound_stream &stream, stream_sample_t * { env_phase = PHASE_DECAY; env_level = 1.0; - if (channel->decay & 0x0080) + if ((channel->decay & 0x0080) || (channel->decay == 0x100)) { env_step = 0.0; } @@ -295,7 +296,7 @@ void rf5c400_device::sound_stream_update(sound_stream &stream, stream_sample_t * *buf1++ += sample * pan_table[rvol]; pos += channel->step; - if ( (pos>>16) > m_rom.length() || (pos>>16) > end) + if ((pos>>16) > end) { pos -= loop<<16; pos &= 0xFFFFFF0000U; @@ -310,31 +311,57 @@ void rf5c400_device::sound_stream_update(sound_stream &stream, stream_sample_t * } } +void rf5c400_device::rom_bank_updated() +{ + m_stream->update(); +} /*****************************************************************************/ -static uint16_t rf5c400_status = 0; // a static one of these for all instances of the chip? how does that work? READ16_MEMBER( rf5c400_device::rf5c400_r ) { - switch(offset) + if (offset < 0x400) { - case 0x00: + //osd_printf_debug("%s:rf5c400_r: %08X, %08X\n", machine().describe_context().c_str(), offset, mem_mask); + + switch(offset) { - return rf5c400_status; + case 0x00: + { + return m_rf5c400_status; + } + + case 0x04: // unknown read + { + return 0; + } + + case 0x13: // memory read + { + return read_word(m_ext_mem_address<<1); + } + + default: + { + //osd_printf_debug("%s:rf5c400_r: %08X, %08X\n", machine().describe_context().c_str(), offset, mem_mask); + return 0; + } } + } + else + { + //int ch = (offset >> 5) & 0x1f; + int reg = (offset & 0x1f); - case 0x04: + switch (reg) { + case 0x0F: // unknown read return 0; - } - case 0x13: // memory read - { - return m_rom[m_ext_mem_address]; + default: + return 0; } } - - return 0; } WRITE16_MEMBER( rf5c400_device::rf5c400_w ) @@ -345,7 +372,7 @@ WRITE16_MEMBER( rf5c400_device::rf5c400_w ) { case 0x00: { - rf5c400_status = data; + m_rf5c400_status = data; break; } @@ -411,7 +438,7 @@ WRITE16_MEMBER( rf5c400_device::rf5c400_w ) { if ((data & 0x3) == 3) { - m_rom[m_ext_mem_address] = m_ext_mem_data; + this->space().write_word(m_ext_mem_address << 1, m_ext_mem_data); } break; } @@ -431,11 +458,11 @@ WRITE16_MEMBER( rf5c400_device::rf5c400_w ) default: { - //osd_printf_debug("%s:rf5c400_w: %08X, %08X, %08X\n", machine().describe_context(), data, offset, mem_mask); + //osd_printf_debug("%s:rf5c400_w: %08X, %08X, %08X\n", machine().describe_context().c_str(), data, offset, mem_mask); break; } } - //osd_printf_debug("%s:rf5c400_w: %08X, %08X, %08X at %08X\n", machine().describe_context(), data, offset, mem_mask); + //osd_printf_debug("%s:rf5c400_w: %08X, %08X, %08X\n", machine().describe_context().c_str(), data, offset, mem_mask); } else { @@ -504,12 +531,12 @@ WRITE16_MEMBER( rf5c400_device::rf5c400_w ) } case 0x0A: // relative to env attack ? { - // always 0x0100 + // always 0x0100/0x140 break; } case 0x0B: // relative to env decay ? { - // always 0x0100 + // always 0x0100/0x140/0x180 break; } case 0x0C: // env decay @@ -521,7 +548,7 @@ WRITE16_MEMBER( rf5c400_device::rf5c400_w ) } case 0x0D: // relative to env release ? { - // always 0x0100 + // always 0x0100/0x140 break; } case 0x0E: // env release @@ -530,6 +557,11 @@ WRITE16_MEMBER( rf5c400_device::rf5c400_w ) channel->release = data; break; } + case 0x0F: // unknown write + { + // always 0x0000 + break; + } case 0x10: // resonance, cutoff freq. { // bit 15-12: resonance diff --git a/src/devices/sound/rf5c400.h b/src/devices/sound/rf5c400.h index 6fe27863f70..4d681db3a94 100644 --- a/src/devices/sound/rf5c400.h +++ b/src/devices/sound/rf5c400.h @@ -25,7 +25,8 @@ // ======================> rf5c400_device class rf5c400_device : public device_t, - public device_sound_interface + public device_sound_interface, + public device_rom_interface { public: rf5c400_device(const machine_config &mconfig, const char *tag, device_t *owner, uint32_t clock); @@ -40,6 +41,9 @@ protected: // sound stream update overrides virtual void sound_stream_update(sound_stream &stream, stream_sample_t **inputs, stream_sample_t **outputs, int samples) override; + // device_rom_interface overrides + virtual void rom_bank_updated() override; + private: struct rf5c400_channel { @@ -88,16 +92,13 @@ private: uint8_t decode80(uint8_t val); - required_region_ptr<int16_t> m_rom; - - uint32_t m_rommask; - sound_stream *m_stream; envelope_tables m_env_tables; rf5c400_channel m_channels[32]; + uint16_t m_rf5c400_status; uint32_t m_ext_mem_address; uint16_t m_ext_mem_data; }; diff --git a/src/devices/sound/tms5110.cpp b/src/devices/sound/tms5110.cpp index 5f7ee0bddb0..b7bef7f741e 100644 --- a/src/devices/sound/tms5110.cpp +++ b/src/devices/sound/tms5110.cpp @@ -1345,7 +1345,7 @@ void tmsprom_device::device_timer(emu_timer &timer, device_timer_id id, int para if (ctrl & (1 << m_reset_bit)) m_address = 0; - m_ctl_cb((offs_t)0, BITSWAP8(ctrl,0,0,0,0,m_ctl8_bit, + m_ctl_cb((offs_t)0, bitswap<8>(ctrl,0,0,0,0,m_ctl8_bit, m_ctl4_bit,m_ctl2_bit,m_ctl1_bit)); m_pdc_cb((ctrl >> m_pdc_bit) & 0x01); diff --git a/src/devices/sound/ymz770.cpp b/src/devices/sound/ymz770.cpp index ae7a995ce21..968a1514072 100644 --- a/src/devices/sound/ymz770.cpp +++ b/src/devices/sound/ymz770.cpp @@ -110,6 +110,13 @@ void ymz770_device::device_start() save_item(NAME(m_sequences[ch].bank), ch); save_item(NAME(m_sequences[ch].is_playing), 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); + } } @@ -144,6 +151,11 @@ void ymz770_device::device_reset() sequence.bank = 0; sequence.is_playing = false; } + for (auto & sqc : m_sqcs) + { + sqc.is_playing = false; + sqc.loop = 0; + } } @@ -522,7 +534,7 @@ void ymz774_device::internal_reg_write(uint8_t reg, uint8_t data) if (reg & 1) m_sequences[sq].sequence = (m_sequences[sq].sequence & 0xff00) | data; else - m_sequences[sq].sequence = (m_sequences[sq].sequence & 0x00ff) | ((data & 0x0f) << 8); // TODO check if total number really upto 0x1000 + m_sequences[sq].sequence = (m_sequences[sq].sequence & 0x00ff) | ((data & 0x0f) << 8); break; case 0x70: // Start / Stop if (data) @@ -545,7 +557,7 @@ void ymz774_device::internal_reg_write(uint8_t reg, uint8_t data) break; case 0x88: // timer H and L case 0x90: - sq = (reg >> 1) & 7; + sq = (reg - 0x88) >> 1; if (reg & 1) m_sequences[sq].timer = (m_sequences[sq].timer & 0xff00) | data; else @@ -566,7 +578,26 @@ void ymz774_device::internal_reg_write(uint8_t reg, uint8_t data) } else { - if (data) logerror("SQC unimplemented %02X %02X\n", reg, data); + int sq = reg & 7; + switch (reg & 0xf8) + { + case 0xb0: + m_sqcs[sq].sqc = data; + break; + case 0xb8: + if (data) + { + m_sqcs[sq].data = &m_rom[get_sqc_offs(m_sqcs[sq].sqc)]; + m_sqcs[sq].is_playing = true; + m_sqcs[sq].is_waiting = false; + } + else + m_sqcs[sq].is_playing = false; + break; + case 0xc0: + m_sqcs[sq].loop = data; + break; + } } } // else bank1 - Equalizer control @@ -596,7 +627,32 @@ void ymz774_device::sequencer() { for (int i = 0; i < 8; i++) { + auto & sqc = m_sqcs[i]; auto & sequence = m_sequences[i]; + + if (sqc.is_playing && !sqc.is_waiting) + { + sequence.sequence = ((sqc.data[0] << 8) | sqc.data[1]) & 0xfff; + sequence.loop = sqc.data[2]; + sequence.data = &m_rom[get_seq_offs(sequence.sequence)]; + sequence.delay = 0; + sequence.is_playing = true; + sqc.is_waiting = true; + if (sqc.data[3] == 0xff) + { + if (sqc.loop) + { + if (sqc.loop != 255) + --sqc.loop; + sqc.data = &m_rom[get_sqc_offs(sqc.sqc)]; + } + else + sqc.is_playing = false; + } + else + sqc.data += 4; + } + if (sequence.is_playing) { if (sequence.delay > 0) @@ -623,6 +679,7 @@ void ymz774_device::sequencer() else { sequence.is_playing = false; + sqc.is_waiting = false; } break; case 0xfe: // timer delay diff --git a/src/devices/sound/ymz770.h b/src/devices/sound/ymz770.h index b640d780ef5..6723ac2bf1c 100644 --- a/src/devices/sound/ymz770.h +++ b/src/devices/sound/ymz770.h @@ -104,9 +104,18 @@ protected: uint8_t bank; bool is_playing; }; + struct ymz_sqc + { + uint8_t sqc; + uint8_t loop; + uint8_t *data; + bool is_playing; + bool is_waiting; + }; ymz_channel m_channels[16]; ymz_sequence m_sequences[8]; + ymz_sqc m_sqcs[8]; }; // ======================> ymz774_device @@ -122,6 +131,7 @@ protected: virtual void internal_reg_write(uint8_t reg, uint8_t data) override; virtual uint32_t get_phrase_offs(int phrase) override { int ph = phrase * 4; return ((m_rom[ph] & 0x0f) << 24 | m_rom[ph + 1] << 16 | m_rom[ph + 2] << 8 | m_rom[ph + 3]) * 2; }; virtual uint32_t get_seq_offs(int sqn) override { int sq = sqn * 4 + 0x2000; return ((m_rom[sq] & 0x0f) << 24 | m_rom[sq + 1] << 16 | m_rom[sq + 2] << 8 | m_rom[sq + 3]) * 2; }; + uint32_t get_sqc_offs(int sqc) { int sq = sqc * 4 + 0x6000; return ((m_rom[sq] & 0x0f) << 24 | m_rom[sq + 1] << 16 | m_rom[sq + 2] << 8 | m_rom[sq + 3]) * 2; }; virtual void sequencer() override; private: int m_bank; |