c352.cpp: Allow byte accessing, Modernize save states

Add notes, Use shorter/correct type/argument values
This commit is contained in:
cam900 2020-05-09 10:31:56 +09:00
parent c185de04da
commit c59d320df4
2 changed files with 89 additions and 93 deletions

View File

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

View File

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