Fix DS128X/DS1288X main frequency divider. The output frequency must be fixed to 1HZ with these devices.

In  the  MC146818, DV2-DV0  were  used  to  select  the input frequency to provide a proper time base.
Since the DS12885/87 and DS1685/87 use only the 32.768kHz  crystal  these  3  bits  are  used to  turn  the  oscillator  on  or  off  and  to  reset  the  countdown  chain.
There are not used anymore to select the main clock divider value.
This commit is contained in:
Jean-François DEL NERO 2017-11-01 14:35:40 +01:00 committed by Vas Crabb
parent 8dc0166cfc
commit 8191fd96fe
4 changed files with 48 additions and 29 deletions

View File

@ -3,8 +3,6 @@
#include "emu.h"
#include "ds128x.h"
/// TODO: Only DV2/DV1/DV0 == 0/1/0 is supported as the chip only has a 15 stage divider and not 22.
DEFINE_DEVICE_TYPE(DS12885, ds12885_device, "ds12885", "DS12885 RTC/NVRAM")
//-------------------------------------------------
@ -15,3 +13,13 @@ ds12885_device::ds12885_device(const machine_config &mconfig, const char *tag, d
: mc146818_device(mconfig, DS12885, tag, owner, clock)
{
}
int ds12885_device::get_timer_bypass()
{
if( !( m_data[REG_A] & REG_A_DV0 ) ) //DV0 must be 0 for timekeeping
{
return 7; // Fixed at 1 Hz with clock at 32768Hz
}
return 22; // No tick
}

View File

@ -18,6 +18,7 @@ public:
protected:
virtual int data_size() override { return 128; }
virtual int get_timer_bypass() override;
};
// device type definition

View File

@ -412,31 +412,7 @@ void mc146818_device::update_timer()
{
int bypass;
switch (m_data[REG_A] & (REG_A_DV2 | REG_A_DV1 | REG_A_DV0))
{
case 0:
bypass = 0;
break;
case REG_A_DV0:
bypass = 2;
break;
case REG_A_DV1:
bypass = 7;
break;
case REG_A_DV2 | REG_A_DV1:
case REG_A_DV2 | REG_A_DV1 | REG_A_DV0:
bypass = 22;
break;
default:
// TODO: other combinations of divider bits are used for test purposes only
bypass = 22;
break;
}
bypass = get_timer_bypass();
attotime update_period = attotime::never;
attotime update_interval = attotime::never;
@ -472,6 +448,41 @@ void mc146818_device::update_timer()
m_periodic_timer->adjust(periodic_period, 0, periodic_interval);
}
//---------------------------------------------------------------
// get_timer_bypass - get main clock divisor based on A register
//---------------------------------------------------------------
int mc146818_device::get_timer_bypass()
{
int bypass;
switch (m_data[REG_A] & (REG_A_DV2 | REG_A_DV1 | REG_A_DV0))
{
case 0:
bypass = 0;
break;
case REG_A_DV0:
bypass = 2;
break;
case REG_A_DV1:
bypass = 7;
break;
case REG_A_DV2 | REG_A_DV1:
case REG_A_DV2 | REG_A_DV1 | REG_A_DV0:
bypass = 22;
break;
default:
// TODO: other combinations of divider bits are used for test purposes only
bypass = 22;
break;
}
return bypass;
}
//-------------------------------------------------
// update_irq - Update irq based on B & C register

View File

@ -91,7 +91,6 @@ protected:
virtual int data_size() { return 64; }
private:
enum
{
REG_SECONDS = 0,
@ -153,7 +152,7 @@ private:
void set_base_datetime();
void update_irq();
void update_timer();
virtual int get_timer_bypass();
int get_seconds();
void set_seconds(int seconds);
int get_minutes();