snes_snd.cpp: merge timer counters into one single function [Angelo Salese]

This commit is contained in:
angelosa 2018-01-14 07:26:37 +01:00
parent 7a35ee6cf4
commit e42ca026d9
2 changed files with 62 additions and 31 deletions

View File

@ -170,7 +170,6 @@ snes_sound_device::snes_sound_device(const machine_config &mconfig, const char *
void snes_sound_device::device_start()
{
const int timerHz[3] = { 8000, 8000, 64000 };
m_channel = machine().sound().stream_alloc(*this, 0, 2, 32000);
m_ram = make_unique_clear<uint8_t[]>(SNES_SPCRAM_SIZE);
@ -178,14 +177,7 @@ void snes_sound_device::device_start()
/* put IPL image at the top of RAM */
memcpy(m_ipl_region, machine().root_device().memregion("sound_ipl")->base(), 64);
/* Initialize the timers */
for(int timerNumber=0;timerNumber<3;timerNumber++)
{
m_timer[timerNumber] = machine().scheduler().timer_alloc(timer_expired_delegate(FUNC(snes_sound_device::spc_timer),this));
m_timer[timerNumber]->adjust(attotime::from_hz(timerHz[timerNumber]), 0, attotime::from_hz(timerHz[timerNumber]));
m_timer[timerNumber]->enable(false);
m_TnDIV[timerNumber] = 256;
}
m_tick_timer = timer_alloc(TIMER_TICK_ID);
state_register();
save_pointer(NAME(m_ram.get()), SNES_SPCRAM_SIZE);
@ -197,19 +189,63 @@ void snes_sound_device::device_start()
void snes_sound_device::device_reset()
{
int i;
/* default to ROM visible */
m_ram[0xf1] = 0x80;
/* Sort out the ports */
for (int i = 0; i < 4; i++)
for (i = 0; i < 4; i++)
{
m_port_in[i] = 0;
m_port_out[i] = 0;
}
for(i=0; i<3; i++)
{
m_timer_enabled[i] = false;
m_TnDIV[i] = 256;
m_counter[i] = 0;
m_subcounter[i] = 0;
}
attotime period = attotime::from_hz(64000);
m_tick_timer->adjust(period, 0, period);
dsp_reset();
}
inline void snes_sound_device::update_timer_tick(uint8_t which)
{
if(m_timer_enabled[which] == false)
return;
m_subcounter[which]++;
// if timer channel is 0 or 1 we update at 64000/8
if(m_subcounter[which] >= 8 || which == 2)
{
m_subcounter[which] = 0;
m_counter[which]++;
if (m_counter[which] >= m_TnDIV[which] ) // minus =
{
m_counter[which] = 0;
m_ram[0xfd + which]++;
m_ram[0xfd + which] &= 0x0f;
}
}
}
void snes_sound_device::device_timer(emu_timer &timer, device_timer_id id, int param, void *ptr)
{
if(id != TIMER_TICK_ID)
{
assert_always(false, "Unknown id in snes_sound_device::device_timer");
return;
}
for(int ch=0;ch<3;ch++)
update_timer_tick(ch);
}
/*****************************************************************************
@ -986,20 +1022,6 @@ int snes_sound_device::advance_envelope( int v )
return envx;
}
TIMER_CALLBACK_MEMBER( snes_sound_device::spc_timer )
{
int which = param;
m_counter[which]++;
if (m_counter[which] >= m_TnDIV[which] ) // minus =
{
m_counter[which] = 0;
m_ram[0xfd + which]++;
m_ram[0xfd + which] &= 0x0f;
}
}
/*-------------------------------------------------
spc700_set_volume - sets SPC700 volume level
for both speakers, used for fade in/out effects
@ -1097,14 +1119,15 @@ WRITE8_MEMBER( snes_sound_device::spc_io_w )
case 0x1: /* Control */
for (int i = 0; i < 3; i++)
{
if (BIT(data, i) && !m_enabled[i])
if (BIT(data, i) && m_timer_enabled[i] == false)
{
m_subcounter[i] = 0;
m_counter[i] = 0;
m_ram[0xfd + i] = 0;
}
m_enabled[i] = BIT(data, i);
m_timer[i]->enable(m_enabled[i]);
m_timer_enabled[i] = BIT(data, i);
//m_timer[i]->enable(m_timer_enabled[i]);
}
if (BIT(data, 4))
@ -1205,7 +1228,8 @@ void snes_sound_device::state_register()
save_item(NAME(m_echo_ptr));
#endif
save_item(NAME(m_enabled));
save_item(NAME(m_timer_enabled));
save_item(NAME(m_subcounter));
save_item(NAME(m_counter));
save_item(NAME(m_port_in));
save_item(NAME(m_port_out));

View File

@ -38,6 +38,7 @@ protected:
// sound stream update overrides
virtual void sound_stream_update(sound_stream &stream, stream_sample_t **inputs, stream_sample_t **outputs, int samples) override;
virtual void device_timer(emu_timer &timer, device_timer_id id, int param, void *ptr) override;
private:
enum class env_state_t32 : u8
@ -82,7 +83,7 @@ private:
DECLARE_READ8_MEMBER(dsp_io_r);
DECLARE_WRITE8_MEMBER(dsp_io_w);
TIMER_CALLBACK_MEMBER(spc_timer);
// TIMER_CALLBACK_MEMBER(spc_timer);
void dsp_reset();
void dsp_update(short *sound_ptr);
int advance_envelope(int v);
@ -110,10 +111,16 @@ private:
int m_echo_ptr;
#endif
enum
{
TIMER_TICK_ID = 1
};
/* timers */
emu_timer *m_timer[3];
uint8_t m_enabled[3];
emu_timer *m_tick_timer;
bool m_timer_enabled[3];
uint16_t m_counter[3];
uint8_t m_subcounter[3];
inline void update_timer_tick(uint8_t which);
/* IO ports */
uint8_t m_port_in[4]; /* SPC input ports */