this chip is write-only

This commit is contained in:
Michaël Banaan Ananas 2013-11-30 18:51:38 +00:00
parent 8057efb522
commit 3085a18e1e
2 changed files with 137 additions and 142 deletions

View File

@ -24,41 +24,43 @@ ymz770_device::ymz770_device(const machine_config &mconfig, const char *tag, dev
{
}
//-------------------------------------------------
// device_start - device-specific startup
//-------------------------------------------------
void ymz770_device::device_start()
{
// create the stream
m_stream = machine().sound().stream_alloc(*this, 0, 2, 16000, this);
rom_base = device().machine().root_device().memregion(":ymz770")->base();
rom_size = device().machine().root_device().memregion(":ymz770")->bytes() * 8;
m_rom_base = device().machine().root_device().memregion(":ymz770")->base();
m_rom_size = device().machine().root_device().memregion(":ymz770")->bytes() * 8;
for (int i = 0; i < 8; i++)
{
channels[i].is_playing = false;
channels[i].is_seq_playing = false;
channels[i].decoder = new mpeg_audio(rom_base, mpeg_audio::AMM, false, 0);
m_channels[i].is_playing = false;
m_channels[i].is_seq_playing = false;
m_channels[i].decoder = new mpeg_audio(m_rom_base, mpeg_audio::AMM, false, 0);
}
// register for save states
save_item(NAME(m_cur_reg));
for (int i = 0; i < 8; i++)
{
save_item(NAME(channels[i].phrase), i);
save_item(NAME(channels[i].pan), i);
save_item(NAME(channels[i].volume), i);
save_item(NAME(channels[i].control), i);
save_item(NAME(channels[i].is_playing), i);
save_item(NAME(channels[i].last_block), i);
save_item(NAME(channels[i].output_remaining), i);
save_item(NAME(channels[i].output_ptr), i);
save_item(NAME(channels[i].pptr), i);
save_item(NAME(channels[i].sequence), i);
save_item(NAME(channels[i].seqcontrol), i);
save_item(NAME(channels[i].seqdelay), i);
save_item(NAME(channels[i].is_seq_playing), i);
save_item(NAME(channels[i].output_data), i);
save_item(NAME(m_channels[i].phrase), i);
save_item(NAME(m_channels[i].pan), i);
save_item(NAME(m_channels[i].volume), i);
save_item(NAME(m_channels[i].control), i);
save_item(NAME(m_channels[i].is_playing), i);
save_item(NAME(m_channels[i].last_block), i);
save_item(NAME(m_channels[i].output_remaining), i);
save_item(NAME(m_channels[i].output_ptr), i);
save_item(NAME(m_channels[i].pptr), i);
save_item(NAME(m_channels[i].sequence), i);
save_item(NAME(m_channels[i].seqcontrol), i);
save_item(NAME(m_channels[i].seqdelay), i);
save_item(NAME(m_channels[i].is_seq_playing), i);
save_item(NAME(m_channels[i].output_data), i);
}
}
@ -71,18 +73,19 @@ void ymz770_device::device_reset()
{
for (int i = 0; i < 8; i++)
{
channels[i].phrase = 0;
channels[i].pan = 8;
channels[i].volume = 0;
channels[i].control = 0;
channels[i].sequence = 0;
channels[i].seqcontrol = 0;
channels[i].seqdelay = 0;
channels[i].is_playing = false;
channels[i].is_seq_playing = false;
m_channels[i].phrase = 0;
m_channels[i].pan = 8;
m_channels[i].volume = 0;
m_channels[i].control = 0;
m_channels[i].sequence = 0;
m_channels[i].seqcontrol = 0;
m_channels[i].seqdelay = 0;
m_channels[i].is_playing = false;
m_channels[i].is_seq_playing = false;
}
}
//-------------------------------------------------
// sound_stream_update - handle update requests for
// our sound stream
@ -104,32 +107,32 @@ void ymz770_device::sound_stream_update(sound_stream &stream, stream_sample_t **
for (ch = 0; ch < 8; ch++)
{
if (channels[ch].is_seq_playing)
if (m_channels[ch].is_seq_playing)
{
if (channels[ch].seqdelay != 0)
if (m_channels[ch].seqdelay != 0)
{
channels[ch].seqdelay--;
m_channels[ch].seqdelay--;
}
else
{
int reg = *channels[ch].seqdata++;
UINT8 data = *channels[ch].seqdata++;
int reg = *m_channels[ch].seqdata++;
UINT8 data = *m_channels[ch].seqdata++;
switch (reg)
{
case 0x0f:
if (channels[ch].seqcontrol & 1)
if (m_channels[ch].seqcontrol & 1)
{
UINT8 sqn = channels[ch].sequence;
UINT32 pptr = rom_base[(4*sqn)+1+0x400]<<16 | rom_base[(4*sqn)+2+0x400]<<8 | rom_base[(4*sqn)+3+0x400];
channels[ch].seqdata = &rom_base[pptr];
UINT8 sqn = m_channels[ch].sequence;
UINT32 pptr = m_rom_base[(4*sqn)+1+0x400]<<16 | m_rom_base[(4*sqn)+2+0x400]<<8 | m_rom_base[(4*sqn)+3+0x400];
m_channels[ch].seqdata = &m_rom_base[pptr];
}
else
{
channels[ch].is_seq_playing = false;
m_channels[ch].is_seq_playing = false;
}
break;
case 0x0e:
channels[ch].seqdelay = 32 - 1;
m_channels[ch].seqdelay = 32 - 1;
break;
default:
internal_reg_write(reg, data);
@ -137,48 +140,48 @@ void ymz770_device::sound_stream_update(sound_stream &stream, stream_sample_t **
}
}
}
if (channels[ch].is_playing)
if (m_channels[ch].is_playing)
{
if (channels[ch].output_remaining > 0)
if (m_channels[ch].output_remaining > 0)
{
mix += (channels[ch].output_data[channels[ch].output_ptr++]*2*channels[ch].volume);
channels[ch].output_remaining--;
mix += (m_channels[ch].output_data[m_channels[ch].output_ptr++]*2*m_channels[ch].volume);
m_channels[ch].output_remaining--;
}
else
{
retry:
if (channels[ch].last_block)
if (m_channels[ch].last_block)
{
if (channels[ch].control & 1)
if (m_channels[ch].control & 1)
{
UINT8 phrase = channels[ch].phrase;
channels[ch].pptr = 8*(rom_base[(4*phrase)+1]<<16 | rom_base[(4*phrase)+2]<<8 | rom_base[(4*phrase)+3]);
UINT8 phrase = m_channels[ch].phrase;
m_channels[ch].pptr = 8*(m_rom_base[(4*phrase)+1]<<16 | m_rom_base[(4*phrase)+2]<<8 | m_rom_base[(4*phrase)+3]);
}
else
{
channels[ch].is_playing = false;
m_channels[ch].is_playing = false;
}
}
if (channels[ch].is_playing)
if (m_channels[ch].is_playing)
{
int sample_rate, channel_count;
if(!channels[ch].decoder->decode_buffer(channels[ch].pptr,
rom_size,
channels[ch].output_data,
channels[ch].output_remaining,
if(!m_channels[ch].decoder->decode_buffer(m_channels[ch].pptr,
m_rom_size,
m_channels[ch].output_data,
m_channels[ch].output_remaining,
sample_rate,
channel_count))
{
channels[ch].last_block = true;
m_channels[ch].last_block = true;
goto retry;
}
channels[ch].last_block = channels[ch].output_remaining < 1152;
channels[ch].output_remaining--;
channels[ch].output_ptr = 1;
m_channels[ch].last_block = m_channels[ch].output_remaining < 1152;
m_channels[ch].output_remaining--;
m_channels[ch].output_ptr = 1;
mix += (channels[ch].output_data[0]*2*channels[ch].volume);
mix += (m_channels[ch].output_data[0]*2*m_channels[ch].volume);
}
}
}
@ -188,86 +191,6 @@ retry:
}
}
//-------------------------------------------------
// read - read from the chip's registers
//-------------------------------------------------
READ8_MEMBER( ymz770_device::read )
{
return 0;
}
void ymz770_device::internal_reg_write(UINT8 reg, UINT8 data)
{
if (reg >= 0x40 && reg <= 0x5f)
{
int voice = reg >> 2 & 0x07;
switch (reg & 0x03)
{
case 0:
channels[voice].phrase = data;
break;
case 1:
channels[voice].volume = data;
break;
case 2:
channels[voice].pan = data;
break;
case 3:
if (data & 6)
{
UINT8 phrase = channels[voice].phrase;
channels[voice].pptr = 8*(rom_base[(4*phrase)+1]<<16 | rom_base[(4*phrase)+2]<<8 | rom_base[(4*phrase)+3]);
channels[voice].output_remaining = 0;
channels[voice].output_ptr = 0;
channels[voice].last_block = false;
channels[voice].is_playing = true;
}
else
{
channels[voice].is_playing = false;
}
channels[voice].control = data;
break;
}
}
else if (reg >= 0x80)
{
int voice = reg >> 4 & 0x07;
switch (reg & 0x0f)
{
case 0:
channels[voice].sequence = data;
break;
case 1:
if (data & 6)
{
UINT8 sqn = channels[voice].sequence;
UINT32 pptr = rom_base[(4*sqn)+1+0x400]<<16 | rom_base[(4*sqn)+2+0x400]<<8 | rom_base[(4*sqn)+3+0x400];
channels[voice].seqdata = &rom_base[pptr];
channels[voice].seqdelay = 0;
channels[voice].is_seq_playing = true;
}
else
{
channels[voice].is_seq_playing = false;
}
channels[voice].seqcontrol = data;
break;
default:
break;
}
}
}
//-------------------------------------------------
// write - write to the chip's registers
@ -285,3 +208,76 @@ WRITE8_MEMBER( ymz770_device::write )
m_cur_reg = data;
}
}
void ymz770_device::internal_reg_write(UINT8 reg, UINT8 data)
{
if (reg >= 0x40 && reg <= 0x5f)
{
int voice = reg >> 2 & 0x07;
switch (reg & 0x03)
{
case 0:
m_channels[voice].phrase = data;
break;
case 1:
m_channels[voice].volume = data;
break;
case 2:
m_channels[voice].pan = data;
break;
case 3:
if (data & 6)
{
UINT8 phrase = m_channels[voice].phrase;
m_channels[voice].pptr = 8*(m_rom_base[(4*phrase)+1]<<16 | m_rom_base[(4*phrase)+2]<<8 | m_rom_base[(4*phrase)+3]);
m_channels[voice].output_remaining = 0;
m_channels[voice].output_ptr = 0;
m_channels[voice].last_block = false;
m_channels[voice].is_playing = true;
}
else
{
m_channels[voice].is_playing = false;
}
m_channels[voice].control = data;
break;
}
}
else if (reg >= 0x80)
{
int voice = reg >> 4 & 0x07;
switch (reg & 0x0f)
{
case 0:
m_channels[voice].sequence = data;
break;
case 1:
if (data & 6)
{
UINT8 sqn = m_channels[voice].sequence;
UINT32 pptr = m_rom_base[(4*sqn)+1+0x400]<<16 | m_rom_base[(4*sqn)+2+0x400]<<8 | m_rom_base[(4*sqn)+3+0x400];
m_channels[voice].seqdata = &m_rom_base[pptr];
m_channels[voice].seqdelay = 0;
m_channels[voice].is_seq_playing = true;
}
else
{
m_channels[voice].is_seq_playing = false;
}
m_channels[voice].seqcontrol = data;
break;
default:
break;
}
}
}

View File

@ -62,7 +62,6 @@ public:
// construction/destruction
ymz770_device(const machine_config &mconfig, const char *tag, device_t *owner, UINT32 clock);
DECLARE_READ8_MEMBER(read);
DECLARE_WRITE8_MEMBER(write);
sound_stream *m_stream;
@ -79,10 +78,10 @@ protected:
// data
UINT8 m_cur_reg;
UINT8 *rom_base;
int rom_size;
UINT8 *m_rom_base;
int m_rom_size;
ymz_channel channels[8];
ymz_channel m_channels[8];
};