From 8191fd96fe667cf231ff20bbcec912098500bc46 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Jean-Fran=C3=A7ois=20DEL=20NERO?= Date: Wed, 1 Nov 2017 14:35:40 +0100 Subject: 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. --- src/devices/machine/ds128x.cpp | 12 ++++++-- src/devices/machine/ds128x.h | 1 + src/devices/machine/mc146818.cpp | 61 ++++++++++++++++++++++++---------------- src/devices/machine/mc146818.h | 3 +- 4 files changed, 48 insertions(+), 29 deletions(-) diff --git a/src/devices/machine/ds128x.cpp b/src/devices/machine/ds128x.cpp index 7c824aba638..7a397aab303 100644 --- a/src/devices/machine/ds128x.cpp +++ b/src/devices/machine/ds128x.cpp @@ -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 +} diff --git a/src/devices/machine/ds128x.h b/src/devices/machine/ds128x.h index e74227e58b1..e525d7a79d3 100644 --- a/src/devices/machine/ds128x.h +++ b/src/devices/machine/ds128x.h @@ -18,6 +18,7 @@ public: protected: virtual int data_size() override { return 128; } + virtual int get_timer_bypass() override; }; // device type definition diff --git a/src/devices/machine/mc146818.cpp b/src/devices/machine/mc146818.cpp index 4cdb4f37b5e..afe912a7d0d 100644 --- a/src/devices/machine/mc146818.cpp +++ b/src/devices/machine/mc146818.cpp @@ -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 diff --git a/src/devices/machine/mc146818.h b/src/devices/machine/mc146818.h index 408f9f717d8..85256106abf 100644 --- a/src/devices/machine/mc146818.h +++ b/src/devices/machine/mc146818.h @@ -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(); -- cgit v1.2.3