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.
master
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();