nec v25: Implement programmable clock divider via execute_clocks_to_cycles() instead of set_clock_scale(). Properly restore the clock divider on state load [Alex Jackson]

This commit is contained in:
Alex W. Jackson 2014-07-05 07:41:03 +00:00
parent f22f324e27
commit 8cfe802f60
3 changed files with 15 additions and 12 deletions

View File

@ -159,7 +159,6 @@ UINT8 v25_common_device::fetchop()
void v25_common_device::device_reset() void v25_common_device::device_reset()
{ {
int tmp;
attotime time; attotime time;
m_ip = 0; m_ip = 0;
@ -201,8 +200,7 @@ void v25_common_device::device_reset()
m_PCK = 8; m_PCK = 8;
m_IDB = 0xFFE00; m_IDB = 0xFFE00;
set_clock_scale(1.0 / m_PCK); int tmp = m_PCK << m_TB;
tmp = m_PCK << m_TB;
time = attotime::from_hz(unscaled_clock()) * tmp; time = attotime::from_hz(unscaled_clock()) * tmp;
m_timers[3]->adjust(time, INTTB, time); m_timers[3]->adjust(time, INTTB, time);
@ -436,6 +434,8 @@ void v25_common_device::device_start()
Mod_RM.RM.b[i] = breg_name[i & 7]; Mod_RM.RM.b[i] = breg_name[i & 7];
} }
m_PCK = 8;
m_no_interrupt = 0; m_no_interrupt = 0;
m_prefetch_count = 0; m_prefetch_count = 0;
m_prefetch_reset = 0; m_prefetch_reset = 0;

View File

@ -41,8 +41,11 @@ protected:
// device-level overrides // device-level overrides
virtual void device_start(); virtual void device_start();
virtual void device_reset(); virtual void device_reset();
virtual void device_post_load() { notify_clock_changed(); }
// device_execute_interface overrides // device_execute_interface overrides
virtual UINT64 execute_clocks_to_cycles(UINT64 clocks) const { return clocks / m_PCK; }
virtual UINT64 execute_cycles_to_clocks(UINT64 cycles) const { return cycles * m_PCK; }
virtual UINT32 execute_min_cycles() const { return 1; } virtual UINT32 execute_min_cycles() const { return 1; }
virtual UINT32 execute_max_cycles() const { return 80; } virtual UINT32 execute_max_cycles() const { return 80; }
virtual UINT32 execute_input_lines() const { return 1; } virtual UINT32 execute_input_lines() const { return 1; }

View File

@ -192,8 +192,8 @@ void v25_common_device::write_sfr(unsigned o, UINT8 d)
{ {
if(d & 0x80) if(d & 0x80)
{ {
tmp = m_TM0 * ((d & 0x40) ? 128 : 12 ); tmp = m_PCK * m_TM0 * ((d & 0x40) ? 128 : 12 );
time = attotime::from_hz(clock()) * tmp; time = attotime::from_hz(unscaled_clock()) * tmp;
m_timers[0]->adjust(time, INTTU0); m_timers[0]->adjust(time, INTTU0);
} }
else else
@ -201,8 +201,8 @@ void v25_common_device::write_sfr(unsigned o, UINT8 d)
if(d & 0x20) if(d & 0x20)
{ {
tmp = m_MD0 * ((d & 0x10) ? 128 : 12 ); tmp = m_PCK * m_MD0 * ((d & 0x10) ? 128 : 12 );
time = attotime::from_hz(clock()) * tmp; time = attotime::from_hz(unscaled_clock()) * tmp;
m_timers[1]->adjust(time, INTTU1); m_timers[1]->adjust(time, INTTU1);
} }
else else
@ -212,8 +212,8 @@ void v25_common_device::write_sfr(unsigned o, UINT8 d)
{ {
if(d & 0x80) if(d & 0x80)
{ {
tmp = m_MD0 * ((d & 0x40) ? 128 : 6 ); tmp = m_PCK * m_MD0 * ((d & 0x40) ? 128 : 6 );
time = attotime::from_hz(clock()) * tmp; time = attotime::from_hz(unscaled_clock()) * tmp;
m_timers[0]->adjust(time, INTTU0, time); m_timers[0]->adjust(time, INTTU0, time);
m_timers[1]->adjust(attotime::never); m_timers[1]->adjust(attotime::never);
m_TM0 = m_MD0; m_TM0 = m_MD0;
@ -229,8 +229,8 @@ void v25_common_device::write_sfr(unsigned o, UINT8 d)
m_TMC1 = d & 0xC0; m_TMC1 = d & 0xC0;
if(d & 0x80) if(d & 0x80)
{ {
tmp = m_MD1 * ((d & 0x40) ? 128 : 6 ); tmp = m_PCK * m_MD1 * ((d & 0x40) ? 128 : 6 );
time = attotime::from_hz(clock()) * tmp; time = attotime::from_hz(unscaled_clock()) * tmp;
m_timers[2]->adjust(time, INTTU2, time); m_timers[2]->adjust(time, INTTU2, time);
m_TM1 = m_MD1; m_TM1 = m_MD1;
} }
@ -261,10 +261,10 @@ void v25_common_device::write_sfr(unsigned o, UINT8 d)
logerror(" Warning: invalid clock divider\n"); logerror(" Warning: invalid clock divider\n");
m_PCK = 8; m_PCK = 8;
} }
set_clock_scale(1.0 / m_PCK);
tmp = m_PCK << m_TB; tmp = m_PCK << m_TB;
time = attotime::from_hz(unscaled_clock()) * tmp; time = attotime::from_hz(unscaled_clock()) * tmp;
m_timers[3]->adjust(time, INTTB, time); m_timers[3]->adjust(time, INTTB, time);
notify_clock_changed(); /* make device_execute_interface pick up the new clocks_to_cycles() */
logerror(" Internal RAM %sabled\n", (m_RAMEN ? "en" : "dis")); logerror(" Internal RAM %sabled\n", (m_RAMEN ? "en" : "dis"));
logerror(" Time base set to 2^%d\n", m_TB); logerror(" Time base set to 2^%d\n", m_TB);
logerror(" Clock divider set to %d\n", m_PCK); logerror(" Clock divider set to %d\n", m_PCK);