summaryrefslogtreecommitdiffstatshomepage
path: root/src/devices/sound
diff options
context:
space:
mode:
Diffstat (limited to 'src/devices/sound')
-rw-r--r--src/devices/sound/astrocde.cpp2
-rw-r--r--src/devices/sound/rf5c400.cpp82
-rw-r--r--src/devices/sound/rf5c400.h11
-rw-r--r--src/devices/sound/tms5110.cpp2
-rw-r--r--src/devices/sound/ymz770.cpp63
-rw-r--r--src/devices/sound/ymz770.h10
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;