Skip to content
Open
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
58 changes: 42 additions & 16 deletions src/devices/machine/bq4847.cpp
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

In general, adding device type flags that need to be checked all over the place is an ugly way of doing things. Can you think of a way of doing this without needing intrusive checks inserted throughout the code?

Original file line number Diff line number Diff line change
Expand Up @@ -31,6 +31,7 @@
#include "logmacro.h"

// device type definition
DEFINE_DEVICE_TYPE(BQ4802, bq4802_device, "bq4802", "Benchmarq BQ4802 RTC")
DEFINE_DEVICE_TYPE(BQ4845, bq4845_device, "bq4845", "Benchmarq BQ4845 RTC")
DEFINE_DEVICE_TYPE(BQ4847, bq4847_device, "bq4847", "Benchmarq BQ4847 RTC")

Expand All @@ -51,7 +52,7 @@ enum
reg_interrupts, // 0 0 0 0 AIE PIE PWRIE ABE 0x00 on powerup
reg_flags, // 0 0 0 0 AF PF PWRF BVF 0x00 after reading
reg_control, // 0 0 0 0 UTI STOP* 24/12* DSE
reg_unused // 0x00
reg_century, // 0x00-0x99
};

enum
Expand All @@ -74,7 +75,7 @@ enum
// Constructors for basetype
//-------------------------------------------------

bq4847_device::bq4847_device(const machine_config& mconfig, device_type type, const char* tag, device_t* owner, uint32_t clock)
bq4847_device::bq4847_device(const machine_config &mconfig, device_type type, const char *tag, device_t *owner, uint32_t clock)
: device_t(mconfig, type, tag, owner, clock),
device_nvram_interface(mconfig, *this),
device_rtc_interface(mconfig, *this),
Expand All @@ -88,20 +89,26 @@ bq4847_device::bq4847_device(const machine_config& mconfig, device_type type, co
m_int_state(1),
m_rst_state(1),
m_wdi_state(-1),
m_writing(false)
m_writing(false),
m_century(false)
{
}

bq4847_device::bq4847_device(const machine_config& mconfig, const char* tag, device_t* owner, uint32_t clock)
bq4847_device::bq4847_device(const machine_config &mconfig, const char *tag, device_t *owner, uint32_t clock)
: bq4847_device(mconfig, BQ4847, tag, owner, clock)
{
}

bq4845_device::bq4845_device(const machine_config& mconfig, const char* tag, device_t* owner, uint32_t clock)
bq4845_device::bq4845_device(const machine_config &mconfig, const char *tag, device_t *owner, uint32_t clock)
: bq4847_device(mconfig, BQ4845, tag, owner, clock)
{
}

bq4802_device::bq4802_device(const machine_config &mconfig, const char *tag, device_t *owner, uint32_t clock)
: bq4847_device(mconfig, BQ4802, tag, owner, clock)
{
set_century(true);
}
// device_rtc_interface

void bq4847_device::rtc_clock_updated(int year, int month, int day, int day_of_week, int hour, int minute, int second)
Expand All @@ -112,10 +119,15 @@ void bq4847_device::rtc_clock_updated(int year, int month, int day, int day_of_w
(((hour % 24) >= 12) ? 0x80 : 0x00) | convert_to_bcd((hour % 12) ? (hour % 12) : 12);
m_register[reg_minutes] = convert_to_bcd(minute);
m_register[reg_seconds] = convert_to_bcd(second);
m_register[reg_year] = convert_to_bcd(year);
m_register[reg_year] = convert_to_bcd(year % 100);
m_register[reg_month] = convert_to_bcd(month);
m_register[reg_date] = convert_to_bcd(day);
m_register[reg_days] = convert_to_bcd(day_of_week);
if (m_century)
{
m_register[reg_century] = convert_to_bcd(year / 100);
}

}

// Clear the saved flags (TODO: check that flags set before power down, or during battery backup are lost)
Expand All @@ -132,7 +144,7 @@ void bq4847_device::rtc_clock_updated(int year, int month, int day, int day_of_w
// What about the DSE flag?
}

bool bq4847_device::increment_bcd(uint8_t& bcdnumber, uint8_t limit, uint8_t min)
bool bq4847_device::increment_bcd(uint8_t &bcdnumber, uint8_t limit, uint8_t min)
{
if (bcdnumber >= limit)
{
Expand Down Expand Up @@ -183,16 +195,26 @@ TIMER_CALLBACK_MEMBER(bq4847_device::update_callback)
if (carry)
advance_days_bcd();

LOGMASKED(LOG_CLOCK, "%s 20%02x-%02x-%02x %02x:%02x:%02x\n",
dow[m_register[reg_days] - 1], m_register[reg_year], m_register[reg_month], m_register[reg_date],
m_register[reg_hours], m_register[reg_minutes], m_register[reg_seconds]);
if (!m_century)
{
LOGMASKED(LOG_CLOCK, "%s 20%02x-%02x-%02x %02x:%02x:%02x\n",
dow[m_register[reg_days] - 1], m_register[reg_year], m_register[reg_month], m_register[reg_date],
m_register[reg_hours], m_register[reg_minutes], m_register[reg_seconds]);
}
else
{
LOGMASKED(LOG_CLOCK, "%s %02x%02x-%02x-%02x %02x:%02x:%02x\n",
dow[m_register[reg_days] - 1], m_register[reg_century], m_register[reg_year], m_register[reg_month], m_register[reg_date],
m_register[reg_hours], m_register[reg_minutes], m_register[reg_seconds]);
}


if (newsec)
{
if ((m_register[reg_control] & CONTROL_UTI) == 0)
{
LOGMASKED(LOG_TRANSFER, "Transfer to external regs\n");
for (int i = reg_seconds; i < reg_unused; i++)
for (int i = reg_seconds; i < reg_century + 1; i++)
{
if (is_clock_register(i)) m_userbuffer[i] = m_register[i];
}
Expand Down Expand Up @@ -289,9 +311,13 @@ void bq4847_device::advance_days_bcd()
if (m_register[reg_month] == 0x13)
{
m_register[reg_month] = 0x01;
increment_bcd(m_register[reg_year], 0xff, 0);
carry = increment_bcd(m_register[reg_year], 0xff, 0);
}
}
if (m_century && carry)
{
increment_bcd(m_register[reg_century], 0xff, 1);
}
}

bool bq4847_device::check_alarm(int now, int alarm)
Expand All @@ -313,8 +339,8 @@ uint8_t bq4847_device::read(offs_t address)
}
else if (regnum >= reg_interrupts && regnum <= reg_control)
value &= 0xf;
else if (regnum == reg_unused)
value = 0; // Reg 15 is locked to 0 in BQ4847
else if (regnum == reg_century)
value = m_century? m_register[reg_century]: 0; // Reg 15 is locked to 0 in BQ4847

LOGMASKED(LOG_REG, "Reg %d -> %02x\n", regnum, value);

Expand Down Expand Up @@ -358,7 +384,7 @@ void bq4847_device::write(offs_t address, uint8_t data)
if (uti_set && !uti_set_now && m_writing)
{
LOGMASKED(LOG_TRANSFER, "Transfer to internal regs\n");
for (int i = reg_seconds; i < reg_unused; i++)
for (int i = reg_seconds; i < reg_century + 1; i++)
{
if (is_clock_register(i)) m_register[i] = m_userbuffer[i];
}
Expand All @@ -372,7 +398,7 @@ bool bq4847_device::is_clock_register(int regnum)
{
return (regnum == reg_seconds || regnum == reg_minutes || regnum == reg_hours ||
regnum == reg_date || regnum == reg_days || regnum == reg_month
|| regnum == reg_year);
|| regnum == reg_year || regnum == reg_century);
}
Comment on lines 399 to 402
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

This, combined with the change to write, will change the behaviour of all devices in this file to copy the contents of what’s the century register on some devices only on an update transfer.


void bq4847_device::set_periodic_timer()
Expand Down
17 changes: 15 additions & 2 deletions src/devices/machine/bq4847.h
Original file line number Diff line number Diff line change
Expand Up @@ -45,10 +45,14 @@ class bq4847_device : public device_t,
virtual bool nvram_write(util::write_stream& file) override;

// device_rtc_interface
virtual bool rtc_feature_y2k() const override { return false; }
virtual bool rtc_feature_y2k() const override { return m_century; }
virtual bool rtc_feature_leap_year() const override { return true; }
virtual bool rtc_battery_backed() const override { return true; }
virtual void rtc_clock_updated(int year, int month, int day, int day_of_week, int hour, int minute, int second) override;
void set_century(bool value)
{
m_century = value;
}

private:
optional_memory_region m_region;
Expand Down Expand Up @@ -84,14 +88,23 @@ class bq4847_device : public device_t,
int m_rst_state;
int m_wdi_state;
bool m_writing;
bool m_century;
};

class bq4845_device : public bq4847_device
{
public:
bq4845_device(const machine_config& mconfig, const char* tag, device_t* owner, uint32_t clock);
bq4845_device(const machine_config &mconfig, const char *tag, device_t *owner, uint32_t clock);
};

class bq4802_device : public bq4847_device
{
public:
bq4802_device(const machine_config &mconfig, const char *tag, device_t *owner, uint32_t clock);
private:
};

DECLARE_DEVICE_TYPE(BQ4802, bq4802_device)
DECLARE_DEVICE_TYPE(BQ4845, bq4845_device)
DECLARE_DEVICE_TYPE(BQ4847, bq4847_device)

Expand Down
Loading