Merge pull request #6669 from cam900/c352_memmask

c352.cpp: Allow byte accessing, Modernize save states
This commit is contained in:
R. Belmont 2020-05-09 08:36:16 -04:00 committed by GitHub
commit 265c858e3b
No known key found for this signature in database
GPG Key ID: 4AEE18F83AFDEB23
2 changed files with 89 additions and 93 deletions

View File

@ -27,7 +27,7 @@
#if C352_LOG_PCM
#include <map>
static std::map<uint32_t, bool> s_found_pcm;
static std::map<u32, bool> s_found_pcm;
#endif
// device type definition
@ -41,7 +41,7 @@ DEFINE_DEVICE_TYPE(C352, c352_device, "c352", "Namco C352")
// c352_device - constructor
//-------------------------------------------------
c352_device::c352_device(const machine_config &mconfig, const char *tag, device_t *owner, uint32_t clock)
c352_device::c352_device(const machine_config &mconfig, const char *tag, device_t *owner, u32 clock)
: device_t(mconfig, C352, tag, owner, clock)
, device_sound_interface(mconfig, *this)
, device_rom_interface(mconfig, *this, 24)
@ -69,14 +69,14 @@ void c352_device::fetch_sample(c352_voice_t& v)
}
else
{
int8_t s = (int8_t)read_byte(v.pos);
s8 s = (s8)read_byte(v.pos);
if (v.flags & C352_FLG_MULAW)
v.sample = m_mulawtab[s & 0xff];
else
v.sample = s << 8;
uint16_t pos = v.pos & 0xffff;
u16 pos = v.pos & 0xffff;
if ((v.flags & C352_FLG_LOOP) && v.flags & C352_FLG_REVERSE)
{
@ -115,9 +115,9 @@ void c352_device::fetch_sample(c352_voice_t& v)
}
}
void c352_device::ramp_volume(c352_voice_t &v, int ch, uint8_t val)
void c352_device::ramp_volume(c352_voice_t &v, int ch, u8 val)
{
int16_t vol_delta = v.curr_vol[ch] - val;
s16 vol_delta = v.curr_vol[ch] - val;
if (vol_delta != 0)
v.curr_vol[ch] += (vol_delta > 0) ? -1 : 1;
}
@ -131,16 +131,16 @@ void c352_device::sound_stream_update(sound_stream &stream, stream_sample_t **in
for (int i = 0; i < samples; i++)
{
long out[4] = { 0, 0, 0, 0 };
int out[4] = { 0, 0, 0, 0 };
for (int j = 0; j < 32; j++)
{
c352_voice_t &v = m_c352_v[j];
int16_t s = 0;
s16 s = 0;
if (v.flags & C352_FLG_BUSY)
{
int32_t next_counter = v.counter + v.freq;
s32 next_counter = v.counter + v.freq;
if (next_counter & 0x10000)
{
@ -173,32 +173,32 @@ void c352_device::sound_stream_update(sound_stream &stream, stream_sample_t **in
out[3] += (((v.flags & C352_FLG_PHASEFR) ? -s : s) * v.curr_vol[3]) >> 8;
}
*buffer_fl++ = (int16_t)(out[0] >> 3);
*buffer_fr++ = (int16_t)(out[1] >> 3);
*buffer_rl++ = (int16_t)(out[2] >> 3);
*buffer_rr++ = (int16_t)(out[3] >> 3);
*buffer_fl++ = (s16)(out[0] >> 3);
*buffer_fr++ = (s16)(out[1] >> 3);
*buffer_rl++ = (s16)(out[2] >> 3);
*buffer_rr++ = (s16)(out[3] >> 3);
}
}
uint16_t c352_device::read_reg16(unsigned long address)
u16 c352_device::read_reg16(offs_t offset)
{
m_stream->update();
const int reg_map[8] =
{
offsetof(c352_voice_t, vol_f) / sizeof(uint16_t),
offsetof(c352_voice_t, vol_r) / sizeof(uint16_t),
offsetof(c352_voice_t, freq) / sizeof(uint16_t),
offsetof(c352_voice_t, flags) / sizeof(uint16_t),
offsetof(c352_voice_t, wave_bank) / sizeof(uint16_t),
offsetof(c352_voice_t, wave_start) / sizeof(uint16_t),
offsetof(c352_voice_t, wave_end) / sizeof(uint16_t),
offsetof(c352_voice_t, wave_loop) / sizeof(uint16_t),
offsetof(c352_voice_t, vol_f) / sizeof(u16),
offsetof(c352_voice_t, vol_r) / sizeof(u16),
offsetof(c352_voice_t, freq) / sizeof(u16),
offsetof(c352_voice_t, flags) / sizeof(u16),
offsetof(c352_voice_t, wave_bank) / sizeof(u16),
offsetof(c352_voice_t, wave_start) / sizeof(u16),
offsetof(c352_voice_t, wave_end) / sizeof(u16),
offsetof(c352_voice_t, wave_loop) / sizeof(u16),
};
if (address < 0x100)
return *((uint16_t*)&m_c352_v[address / 8] + reg_map[address % 8]);
else if (address == 0x200)
if (offset < 0x100)
return *((u16*)&m_c352_v[offset / 8] + reg_map[offset % 8]);
else if (offset == 0x200)
return m_control;
else
return 0;
@ -206,33 +206,38 @@ uint16_t c352_device::read_reg16(unsigned long address)
return 0;
}
void c352_device::write_reg16(unsigned long address, unsigned short val)
void c352_device::write_reg16(offs_t offset, u16 data, u16 mem_mask)
{
m_stream->update();
const int reg_map[8] =
{
offsetof(c352_voice_t, vol_f) / sizeof(uint16_t),
offsetof(c352_voice_t, vol_r) / sizeof(uint16_t),
offsetof(c352_voice_t, freq) / sizeof(uint16_t),
offsetof(c352_voice_t, flags) / sizeof(uint16_t),
offsetof(c352_voice_t, wave_bank) / sizeof(uint16_t),
offsetof(c352_voice_t, wave_start) / sizeof(uint16_t),
offsetof(c352_voice_t, wave_end) / sizeof(uint16_t),
offsetof(c352_voice_t, wave_loop) / sizeof(uint16_t),
offsetof(c352_voice_t, vol_f) / sizeof(u16),
offsetof(c352_voice_t, vol_r) / sizeof(u16),
offsetof(c352_voice_t, freq) / sizeof(u16),
offsetof(c352_voice_t, flags) / sizeof(u16),
offsetof(c352_voice_t, wave_bank) / sizeof(u16),
offsetof(c352_voice_t, wave_start) / sizeof(u16),
offsetof(c352_voice_t, wave_end) / sizeof(u16),
offsetof(c352_voice_t, wave_loop) / sizeof(u16),
};
if (address < 0x100)
if (offset < 0x100)
{
*((uint16_t*)&m_c352_v[address / 8] + reg_map[address % 8]) = val;
u16 newval = read_reg16(offset);
COMBINE_DATA(&newval);
*((u16*)&m_c352_v[offset / 8] + reg_map[offset % 8]) = newval;
}
else if (address == 0x200)
else if (offset == 0x200)
{
m_control = val;
logerror("C352 control register write: %04x\n",val);
COMBINE_DATA(&m_control);
logerror("C352 control register write: %04x & %04x\n", data, mem_mask);
}
else if (address == 0x202) // execute keyons/keyoffs
else if (offset == 0x202) // execute keyons/keyoffs
{
if (mem_mask != 0xffff) // 16 bit only?
return;
for (int i = 0; i < 32; i++)
{
if (m_c352_v[i].flags & C352_FLG_KEYON)
@ -252,7 +257,7 @@ void c352_device::write_reg16(unsigned long address, unsigned short val)
#if C352_LOG_PCM
if (!(m_c352_v[i].flags & C352_FLG_NOISE))
{
std::map<uint32_t, bool>::iterator iter = s_found_pcm.find(m_c352_v[i].pos);
std::map<u32, bool>::iterator iter = s_found_pcm.find(m_c352_v[i].pos);
if (iter != s_found_pcm.end())
{
return;
@ -266,27 +271,27 @@ void c352_device::write_reg16(unsigned long address, unsigned short val)
if (file != nullptr)
{
c352_voice_t &v = m_c352_v[i];
uint32_t pos = v.pos;
uint32_t flags = v.flags;
uint32_t counter = v.counter;
int16_t sample = 0;
u32 pos = v.pos;
u32 flags = v.flags;
u32 counter = v.counter;
s16 sample = 0;
while (pos != v.wave_end && !(flags & C352_FLG_KEYOFF))
{
int32_t next_counter = counter + v.freq;
s32 next_counter = counter + v.freq;
if (next_counter & 0x10000)
{
counter = next_counter & 0xffff;
int8_t s = (int8_t)read_byte(pos);
s8 s = (s8)read_byte(pos);
if (v.flags & C352_FLG_MULAW)
sample = m_mulawtab[s & 0xff];
else
sample = s << 8;
uint16_t subpos = pos & 0xffff;
u16 subpos = pos & 0xffff;
if ((flags & C352_FLG_LOOP) && flags & C352_FLG_REVERSE)
{
@ -382,22 +387,20 @@ void c352_device::device_start()
m_mulawtab[i + 128] = (~m_mulawtab[i]) & 0xffe0;
// register save state info
for (int i = 0; i < 32; i++)
{
save_item(NAME(m_c352_v[i].pos), i);
save_item(NAME(m_c352_v[i].counter), i);
save_item(NAME(m_c352_v[i].sample), i);
save_item(NAME(m_c352_v[i].last_sample), i);
save_item(NAME(m_c352_v[i].vol_f), i);
save_item(NAME(m_c352_v[i].vol_r), i);
save_item(NAME(m_c352_v[i].curr_vol), i);
save_item(NAME(m_c352_v[i].freq), i);
save_item(NAME(m_c352_v[i].flags), i);
save_item(NAME(m_c352_v[i].wave_bank), i);
save_item(NAME(m_c352_v[i].wave_start), i);
save_item(NAME(m_c352_v[i].wave_end), i);
save_item(NAME(m_c352_v[i].wave_loop), i);
}
save_item(STRUCT_MEMBER(m_c352_v, pos));
save_item(STRUCT_MEMBER(m_c352_v, counter));
save_item(STRUCT_MEMBER(m_c352_v, sample));
save_item(STRUCT_MEMBER(m_c352_v, last_sample));
save_item(STRUCT_MEMBER(m_c352_v, vol_f));
save_item(STRUCT_MEMBER(m_c352_v, vol_r));
save_item(STRUCT_MEMBER(m_c352_v, curr_vol));
save_item(STRUCT_MEMBER(m_c352_v, freq));
save_item(STRUCT_MEMBER(m_c352_v, flags));
save_item(STRUCT_MEMBER(m_c352_v, wave_bank));
save_item(STRUCT_MEMBER(m_c352_v, wave_start));
save_item(STRUCT_MEMBER(m_c352_v, wave_end));
save_item(STRUCT_MEMBER(m_c352_v, wave_loop));
save_item(NAME(m_random));
save_item(NAME(m_control));
}
@ -419,12 +422,5 @@ READ16_MEMBER( c352_device::read )
WRITE16_MEMBER( c352_device::write )
{
if (mem_mask == 0xffff)
{
write_reg16(offset, data);
}
else
{
logerror("C352: byte-wide write unsupported at this time!\n");
}
write_reg16(offset, data, mem_mask);
}

View File

@ -18,13 +18,13 @@ class c352_device : public device_t,
{
public:
// construction/destruction
c352_device(const machine_config &mconfig, const char *tag, device_t *owner, uint32_t clock, int divider)
c352_device(const machine_config &mconfig, const char *tag, device_t *owner, u32 clock, int divider)
: c352_device(mconfig, tag, owner, clock)
{
set_divider(divider);
}
c352_device(const machine_config &mconfig, const char *tag, device_t *owner, uint32_t clock);
c352_device(const machine_config &mconfig, const char *tag, device_t *owner, u32 clock);
void set_divider(int divider) { m_divider = divider; }
@ -67,31 +67,31 @@ private:
struct c352_voice_t
{
uint32_t pos;
uint32_t counter;
u32 pos;
u32 counter;
int16_t sample;
int16_t last_sample;
s16 sample;
s16 last_sample;
uint16_t vol_f;
uint16_t vol_r;
uint8_t curr_vol[4];
u16 vol_f;
u16 vol_r;
u8 curr_vol[4];
uint16_t freq;
uint16_t flags;
u16 freq;
u16 flags;
uint16_t wave_bank;
uint16_t wave_start;
uint16_t wave_end;
uint16_t wave_loop;
u16 wave_bank;
u16 wave_start;
u16 wave_end;
u16 wave_loop;
};
void fetch_sample(c352_voice_t &v);
void ramp_volume(c352_voice_t &v, int ch, uint8_t val);
void ramp_volume(c352_voice_t &v, int ch, u8 val);
unsigned short read_reg16(unsigned long address);
void write_reg16(unsigned long address, unsigned short val);
u16 read_reg16(offs_t offset);
void write_reg16(offs_t offset, u16 data, u16 mem_mask = 0);
sound_stream *m_stream;
@ -100,10 +100,10 @@ private:
c352_voice_t m_c352_v[32];
int16_t m_mulawtab[256];
s16 m_mulawtab[256];
uint16_t m_random;
uint16_t m_control; // control flags, purpose unknown.
u16 m_random;
u16 m_control; // control flags, purpose unknown.
};