mirror of
https://github.com/holub/mame
synced 2025-04-24 01:11:11 +03:00
Merge pull request #6669 from cam900/c352_memmask
c352.cpp: Allow byte accessing, Modernize save states
This commit is contained in:
commit
265c858e3b
@ -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);
|
||||
}
|
||||
|
@ -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.
|
||||
};
|
||||
|
||||
|
||||
|
Loading…
Reference in New Issue
Block a user