mirror of
https://github.com/holub/mame
synced 2025-04-23 00:39:36 +03:00
commit
d7493d5291
@ -34,9 +34,9 @@
|
||||
void k051649_device::scc_map(address_map &map)
|
||||
{
|
||||
map(0x00, 0x7f).rw(FUNC(k051649_device::k051649_waveform_r), FUNC(k051649_device::k051649_waveform_w));
|
||||
map(0x80, 0x89).w(FUNC(k051649_device::k051649_frequency_w));
|
||||
map(0x8a, 0x8e).w(FUNC(k051649_device::k051649_volume_w));
|
||||
map(0x8f, 0x8f).w(FUNC(k051649_device::k051649_keyonoff_w));
|
||||
map(0x80, 0x89).mirror(0x10).w(FUNC(k051649_device::k051649_frequency_w));
|
||||
map(0x8a, 0x8e).mirror(0x10).w(FUNC(k051649_device::k051649_volume_w));
|
||||
map(0x8f, 0x8f).mirror(0x10).w(FUNC(k051649_device::k051649_keyonoff_w));
|
||||
map(0xe0, 0xe0).mirror(0x1f).rw(FUNC(k051649_device::k051649_test_r), FUNC(k051649_device::k051649_test_w));
|
||||
}
|
||||
|
||||
@ -52,15 +52,15 @@ DEFINE_DEVICE_TYPE(K051649, k051649_device, "k051649", "K051649 SCC1")
|
||||
// k051649_device - constructor
|
||||
//-------------------------------------------------
|
||||
|
||||
k051649_device::k051649_device(const machine_config &mconfig, const char *tag, device_t *owner, uint32_t clock)
|
||||
: device_t(mconfig, K051649, tag, owner, clock),
|
||||
device_sound_interface(mconfig, *this),
|
||||
m_stream(nullptr),
|
||||
m_mclock(0),
|
||||
m_rate(0),
|
||||
m_mixer_table(nullptr),
|
||||
m_mixer_lookup(nullptr),
|
||||
m_test(0)
|
||||
k051649_device::k051649_device(const machine_config &mconfig, const char *tag, device_t *owner, u32 clock)
|
||||
: device_t(mconfig, K051649, tag, owner, clock)
|
||||
, device_sound_interface(mconfig, *this)
|
||||
, m_stream(nullptr)
|
||||
, m_mclock(0)
|
||||
, m_rate(0)
|
||||
, m_mixer_table(nullptr)
|
||||
, m_mixer_lookup(nullptr)
|
||||
, m_test(0)
|
||||
{
|
||||
}
|
||||
|
||||
@ -81,6 +81,17 @@ void k051649_device::device_start()
|
||||
|
||||
// build the mixer table
|
||||
make_mixer_table(5);
|
||||
|
||||
// save states
|
||||
for (int voice = 0; voice < 5; voice++)
|
||||
{
|
||||
save_item(NAME(m_channel_list[voice].counter), voice);
|
||||
save_item(NAME(m_channel_list[voice].frequency), voice);
|
||||
save_item(NAME(m_channel_list[voice].volume), voice);
|
||||
save_item(NAME(m_channel_list[voice].key), voice);
|
||||
save_item(NAME(m_channel_list[voice].waveram), voice);
|
||||
}
|
||||
save_item(NAME(m_test));
|
||||
}
|
||||
|
||||
|
||||
@ -96,7 +107,7 @@ void k051649_device::device_reset()
|
||||
voice.frequency = 0;
|
||||
voice.volume = 0xf;
|
||||
voice.counter = 0;
|
||||
voice.key = 0;
|
||||
voice.key = false;
|
||||
}
|
||||
|
||||
// other parameters
|
||||
@ -121,7 +132,7 @@ void k051649_device::device_post_load()
|
||||
|
||||
void k051649_device::device_clock_changed()
|
||||
{
|
||||
uint32_t old_rate = m_rate;
|
||||
const u32 old_rate = m_rate;
|
||||
m_rate = clock()/16;
|
||||
m_mclock = clock();
|
||||
|
||||
@ -147,19 +158,16 @@ void k051649_device::sound_stream_update(sound_stream &stream, stream_sample_t *
|
||||
// channel is halted for freq < 9
|
||||
if (voice.frequency > 8)
|
||||
{
|
||||
const signed char *w = voice.waveram;
|
||||
int v=voice.volume * voice.key;
|
||||
int c=voice.counter;
|
||||
int step = ((int64_t(m_mclock) << FREQ_BITS) / float((voice.frequency + 1) * 16 * (m_rate / 32))) + 0.5f;
|
||||
const int v = voice.volume * voice.key;
|
||||
int c = voice.counter;
|
||||
const int step = ((s64(m_mclock) << FREQ_BITS) / float((voice.frequency + 1) * 16 * (m_rate / 32))) + 0.5f;
|
||||
|
||||
// add our contribution
|
||||
for (int i = 0; i < samples; i++)
|
||||
{
|
||||
int offs;
|
||||
|
||||
c += step;
|
||||
offs = (c >> FREQ_BITS) & 0x1f;
|
||||
m_mixer_buffer[i] += (w[offs] * v)>>3;
|
||||
const int offs = (c >> FREQ_BITS) & 0x1f;
|
||||
m_mixer_buffer[i] += (voice.waveram[offs] * v) >> 3;
|
||||
}
|
||||
|
||||
// update the counter for this voice
|
||||
@ -177,7 +185,7 @@ void k051649_device::sound_stream_update(sound_stream &stream, stream_sample_t *
|
||||
/********************************************************************************/
|
||||
|
||||
|
||||
void k051649_device::k051649_waveform_w(offs_t offset, uint8_t data)
|
||||
void k051649_device::k051649_waveform_w(offs_t offset, u8 data)
|
||||
{
|
||||
// waveram is read-only?
|
||||
if (m_test & 0x40 || (m_test & 0x80 && offset >= 0x60))
|
||||
@ -188,15 +196,15 @@ void k051649_device::k051649_waveform_w(offs_t offset, uint8_t data)
|
||||
if (offset >= 0x60)
|
||||
{
|
||||
// channel 5 shares waveram with channel 4
|
||||
m_channel_list[3].waveram[offset&0x1f]=data;
|
||||
m_channel_list[4].waveram[offset&0x1f]=data;
|
||||
m_channel_list[3].waveram[offset & 0x1f] = data;
|
||||
m_channel_list[4].waveram[offset & 0x1f] = data;
|
||||
}
|
||||
else
|
||||
m_channel_list[offset>>5].waveram[offset&0x1f]=data;
|
||||
m_channel_list[offset >> 5].waveram[offset & 0x1f] = data;
|
||||
}
|
||||
|
||||
|
||||
uint8_t k051649_device::k051649_waveform_r(offs_t offset)
|
||||
u8 k051649_device::k051649_waveform_r(offs_t offset)
|
||||
{
|
||||
// test-register bits 6/7 expose the internal counter
|
||||
if (m_test & 0xc0)
|
||||
@ -206,45 +214,45 @@ uint8_t k051649_device::k051649_waveform_r(offs_t offset)
|
||||
if (offset >= 0x60)
|
||||
offset += (m_channel_list[3 + (m_test >> 6 & 1)].counter >> FREQ_BITS);
|
||||
else if (m_test & 0x40)
|
||||
offset += (m_channel_list[offset>>5].counter >> FREQ_BITS);
|
||||
offset += (m_channel_list[offset >> 5].counter >> FREQ_BITS);
|
||||
}
|
||||
return m_channel_list[offset>>5].waveram[offset&0x1f];
|
||||
return m_channel_list[offset >> 5].waveram[offset & 0x1f];
|
||||
}
|
||||
|
||||
|
||||
void k051649_device::k052539_waveform_w(offs_t offset, uint8_t data)
|
||||
void k051649_device::k052539_waveform_w(offs_t offset, u8 data)
|
||||
{
|
||||
// waveram is read-only?
|
||||
if (m_test & 0x40)
|
||||
return;
|
||||
|
||||
m_stream->update();
|
||||
m_channel_list[offset>>5].waveram[offset&0x1f]=data;
|
||||
m_channel_list[offset >> 5].waveram[offset & 0x1f] = data;
|
||||
}
|
||||
|
||||
|
||||
uint8_t k051649_device::k052539_waveform_r(offs_t offset)
|
||||
u8 k051649_device::k052539_waveform_r(offs_t offset)
|
||||
{
|
||||
// test-register bit 6 exposes the internal counter
|
||||
if (m_test & 0x40)
|
||||
{
|
||||
m_stream->update();
|
||||
offset += (m_channel_list[offset>>5].counter >> FREQ_BITS);
|
||||
offset += (m_channel_list[offset >> 5].counter >> FREQ_BITS);
|
||||
}
|
||||
return m_channel_list[offset>>5].waveram[offset&0x1f];
|
||||
return m_channel_list[offset >> 5].waveram[offset & 0x1f];
|
||||
}
|
||||
|
||||
|
||||
void k051649_device::k051649_volume_w(offs_t offset, uint8_t data)
|
||||
void k051649_device::k051649_volume_w(offs_t offset, u8 data)
|
||||
{
|
||||
m_stream->update();
|
||||
m_channel_list[offset&0x7].volume=data&0xf;
|
||||
m_channel_list[offset & 0x7].volume = data & 0xf;
|
||||
}
|
||||
|
||||
|
||||
void k051649_device::k051649_frequency_w(offs_t offset, uint8_t data)
|
||||
void k051649_device::k051649_frequency_w(offs_t offset, u8 data)
|
||||
{
|
||||
int freq_hi = offset & 1;
|
||||
const int freq_hi = offset & 1;
|
||||
offset >>= 1;
|
||||
|
||||
m_stream->update();
|
||||
@ -263,26 +271,24 @@ void k051649_device::k051649_frequency_w(offs_t offset, uint8_t data)
|
||||
}
|
||||
|
||||
|
||||
void k051649_device::k051649_keyonoff_w(uint8_t data)
|
||||
void k051649_device::k051649_keyonoff_w(u8 data)
|
||||
{
|
||||
int i;
|
||||
m_stream->update();
|
||||
|
||||
for (i = 0; i < 5; i++)
|
||||
for (int i = 0; i < 5; i++)
|
||||
{
|
||||
m_channel_list[i].key=data&1;
|
||||
data >>= 1;
|
||||
m_channel_list[i].key = BIT(data, i);
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
void k051649_device::k051649_test_w(uint8_t data)
|
||||
void k051649_device::k051649_test_w(u8 data)
|
||||
{
|
||||
m_test = data;
|
||||
}
|
||||
|
||||
|
||||
uint8_t k051649_device::k051649_test_r()
|
||||
u8 k051649_device::k051649_test_r()
|
||||
{
|
||||
// reading the test register sets it to $ff!
|
||||
if (!machine().side_effects_disabled())
|
||||
@ -297,19 +303,16 @@ uint8_t k051649_device::k051649_test_r()
|
||||
|
||||
void k051649_device::make_mixer_table(int voices)
|
||||
{
|
||||
int i;
|
||||
|
||||
// allocate memory
|
||||
m_mixer_table = std::make_unique<int16_t[]>(512 * voices);
|
||||
m_mixer_table = std::make_unique<s16[]>(512 * voices);
|
||||
|
||||
// find the middle of the table
|
||||
m_mixer_lookup = m_mixer_table.get() + (256 * voices);
|
||||
|
||||
// fill in the table - 16 bit case
|
||||
for (i = 0; i < (voices * 256); i++)
|
||||
for (int i = 0; i < (voices * 256); i++)
|
||||
{
|
||||
int val = i * DEF_GAIN * 16 / voices;
|
||||
if (val > 32767) val = 32767;
|
||||
const int val = std::min(32767, i * DEF_GAIN * 16 / voices);
|
||||
m_mixer_lookup[ i] = val;
|
||||
m_mixer_lookup[-i] = -val;
|
||||
}
|
||||
|
@ -16,18 +16,18 @@ class k051649_device : public device_t,
|
||||
public device_sound_interface
|
||||
{
|
||||
public:
|
||||
k051649_device(const machine_config &mconfig, const char *tag, device_t *owner, uint32_t clock);
|
||||
k051649_device(const machine_config &mconfig, const char *tag, device_t *owner, u32 clock);
|
||||
|
||||
void k051649_waveform_w(offs_t offset, uint8_t data);
|
||||
uint8_t k051649_waveform_r(offs_t offset);
|
||||
void k051649_volume_w(offs_t offset, uint8_t data);
|
||||
void k051649_frequency_w(offs_t offset, uint8_t data);
|
||||
void k051649_keyonoff_w(uint8_t data);
|
||||
void k051649_test_w(uint8_t data);
|
||||
uint8_t k051649_test_r();
|
||||
void k051649_waveform_w(offs_t offset, u8 data);
|
||||
u8 k051649_waveform_r(offs_t offset);
|
||||
void k051649_volume_w(offs_t offset, u8 data);
|
||||
void k051649_frequency_w(offs_t offset, u8 data);
|
||||
void k051649_keyonoff_w(u8 data);
|
||||
void k051649_test_w(u8 data);
|
||||
u8 k051649_test_r();
|
||||
|
||||
void k052539_waveform_w(offs_t offset, uint8_t data);
|
||||
uint8_t k052539_waveform_r(offs_t offset);
|
||||
void k052539_waveform_w(offs_t offset, u8 data);
|
||||
u8 k052539_waveform_r(offs_t offset);
|
||||
|
||||
void scc_map(address_map &map);
|
||||
protected:
|
||||
@ -48,16 +48,16 @@ private:
|
||||
counter(0),
|
||||
frequency(0),
|
||||
volume(0),
|
||||
key(0)
|
||||
key(false)
|
||||
{
|
||||
std::fill(std::begin(waveram), std::end(waveram), 0);
|
||||
}
|
||||
|
||||
unsigned long counter;
|
||||
u64 counter;
|
||||
int frequency;
|
||||
int volume;
|
||||
int key;
|
||||
signed char waveram[32];
|
||||
bool key;
|
||||
s8 waveram[32];
|
||||
};
|
||||
|
||||
void make_mixer_table(int voices);
|
||||
@ -70,12 +70,12 @@ private:
|
||||
int m_rate;
|
||||
|
||||
/* mixer tables and internal buffers */
|
||||
std::unique_ptr<int16_t[]> m_mixer_table;
|
||||
int16_t *m_mixer_lookup;
|
||||
std::vector<short> m_mixer_buffer;
|
||||
std::unique_ptr<s16[]> m_mixer_table;
|
||||
s16 *m_mixer_lookup;
|
||||
std::vector<s16> m_mixer_buffer;
|
||||
|
||||
/* chip registers */
|
||||
uint8_t m_test;
|
||||
u8 m_test;
|
||||
};
|
||||
|
||||
DECLARE_DEVICE_TYPE(K051649, k051649_device)
|
||||
|
Loading…
Reference in New Issue
Block a user