summaryrefslogtreecommitdiffstatshomepage
path: root/src/devices/machine/ds1302.cpp
diff options
context:
space:
mode:
Diffstat (limited to 'src/devices/machine/ds1302.cpp')
-rw-r--r--src/devices/machine/ds1302.cpp129
1 files changed, 72 insertions, 57 deletions
diff --git a/src/devices/machine/ds1302.cpp b/src/devices/machine/ds1302.cpp
index c74faa2113a..5c2b90955cf 100644
--- a/src/devices/machine/ds1302.cpp
+++ b/src/devices/machine/ds1302.cpp
@@ -26,9 +26,6 @@
// MACROS / CONSTANTS
//**************************************************************************
-#define RAM_SIZE 0x1f // 31 bytes
-
-
enum
{
STATE_COMMAND,
@@ -56,7 +53,7 @@ enum
#define COMMAND_BURST (((m_cmd >> 1) & 0x1f) == 0x1f)
#define CLOCK_HALT (m_reg[REGISTER_SECONDS] & 0x80)
#define WRITE_PROTECT (m_reg[REGISTER_CONTROL] & 0x80)
-#define BURST_END (COMMAND_RAM ? 0x1f : 0x09)
+#define BURST_END (COMMAND_RAM ? m_ram_size : 0x09)
@@ -65,17 +62,34 @@ enum
//**************************************************************************
// device type definition
-DEFINE_DEVICE_TYPE(DS1302, ds1302_device, "ds1302", "DS1302 Timekeeper")
+DEFINE_DEVICE_TYPE(DS1202, ds1202_device, "ds1202", "Dallas DS1202 Serial Timekeeping Chip")
+DEFINE_DEVICE_TYPE(DS1302, ds1302_device, "ds1302", "Dallas DS1302 Trickle-Charge Timekeeping Chip")
//-------------------------------------------------
// ds1302_device - constructor
//-------------------------------------------------
-ds1302_device::ds1302_device(const machine_config &mconfig, const char *tag, device_t *owner, uint32_t clock)
- : device_t(mconfig, DS1302, tag, owner, clock),
+ds1302_device::ds1302_device(const machine_config &mconfig, device_type type, const char *tag, device_t *owner, uint32_t clock, uint8_t ram_size)
+ : device_t(mconfig, type, tag, owner, clock),
device_rtc_interface(mconfig, *this),
- device_nvram_interface(mconfig, *this)
+ device_nvram_interface(mconfig, *this),
+ m_ram_size(ram_size)
+{
+}
+
+ds1302_device::ds1302_device(const machine_config &mconfig, const char *tag, device_t *owner, uint32_t clock)
+ : ds1302_device(mconfig, DS1302, tag, owner, clock, 0x1f)
+{
+}
+
+
+//-------------------------------------------------
+// ds1202_device - constructor
+//-------------------------------------------------
+
+ds1202_device::ds1202_device(const machine_config &mconfig, const char *tag, device_t *owner, uint32_t clock)
+ : ds1302_device(mconfig, DS1202, tag, owner, clock, 0x18)
{
}
@@ -87,9 +101,15 @@ ds1302_device::ds1302_device(const machine_config &mconfig, const char *tag, dev
void ds1302_device::device_start()
{
// allocate timers
- m_clock_timer = timer_alloc();
+ m_clock_timer = timer_alloc(FUNC(ds1302_device::clock_tick), this);
m_clock_timer->adjust(attotime::from_hz(clock() / 32768), 0, attotime::from_hz(clock() / 32768));
+ m_clk = 0;
+ m_ce = 0;
+ m_state = STATE_COMMAND;
+ m_bits = 0;
+ m_cmd = 0;
+
for (auto & elem : m_reg)
elem = 0;
@@ -104,28 +124,15 @@ void ds1302_device::device_start()
save_item(NAME(m_addr));
save_item(NAME(m_reg));
save_item(NAME(m_user));
+ save_pointer(NAME(m_ram), m_ram_size);
}
//-------------------------------------------------
-// device_reset - device-specific reset
+// clock_tick - advance the clock if enabled
//-------------------------------------------------
-void ds1302_device::device_reset()
-{
- m_clk = 0;
- m_ce = 0;
- m_state = STATE_COMMAND;
- m_bits = 0;
- m_cmd = 0;
-}
-
-
-//-------------------------------------------------
-// device_timer - handler timer events
-//-------------------------------------------------
-
-void ds1302_device::device_timer(emu_timer &timer, device_timer_id id, int param, void *ptr)
+TIMER_CALLBACK_MEMBER(ds1302_device::clock_tick)
{
if (!CLOCK_HALT)
{
@@ -141,7 +148,7 @@ void ds1302_device::device_timer(emu_timer &timer, device_timer_id id, int param
void ds1302_device::nvram_default()
{
- memset(m_ram, 0, RAM_SIZE);
+ std::fill_n(&m_ram[0], m_ram_size, 0);
}
@@ -150,9 +157,10 @@ void ds1302_device::nvram_default()
// .nv file
//-------------------------------------------------
-void ds1302_device::nvram_read(emu_file &file)
+bool ds1302_device::nvram_read(util::read_stream &file)
{
- file.read(m_ram, RAM_SIZE);
+ auto const [err, actual] = read(file, &m_ram[0], m_ram_size);
+ return !err && (actual == m_ram_size);
}
@@ -161,9 +169,10 @@ void ds1302_device::nvram_read(emu_file &file)
// .nv file
//-------------------------------------------------
-void ds1302_device::nvram_write(emu_file &file)
+bool ds1302_device::nvram_write(util::write_stream &file)
{
- file.write(m_ram, RAM_SIZE);
+ auto const [err, actual] = write(file, &m_ram[0], m_ram_size);
+ return !err;
}
@@ -187,20 +196,22 @@ void ds1302_device::rtc_clock_updated(int year, int month, int day, int day_of_w
// ce_w - chip enable write
//-------------------------------------------------
-WRITE_LINE_MEMBER( ds1302_device::ce_w )
+void ds1302_device::ce_w(int state)
{
- LOG("DS1302 CE: %u\n", state);
-
- if (!state && m_ce)
+ if (state && !m_ce)
{
+ LOG("Data Transfer Initiated\n");
+
// synchronize user buffers
for (int i = 0; i < 9; i++)
{
m_user[i] = m_reg[i];
}
}
- else if (state && !m_ce)
+ else if (!state && m_ce)
{
+ LOG("Data Transfer Terminated\n");
+
// terminate data transfer
m_state = STATE_COMMAND;
m_bits = 0;
@@ -220,28 +231,29 @@ void ds1302_device::load_shift_register()
{
if (COMMAND_RAM)
{
- m_data = m_ram[m_addr];
+ m_data = m_addr < m_ram_size ? m_ram[m_addr] : 0;
- LOG("DS1302 Read RAM %u:%02x\n", m_addr, m_data);
+ LOG("Read RAM %u: %02x\n", m_addr, m_data);
}
else
{
- m_data = m_user[m_addr];
+ m_data = m_addr < 9 ? m_user[m_addr] : 0;
- LOG("DS1302 Read Clock %u:%02x\n", m_addr, m_data);
+ LOG("Read Clock %u: %02x\n", m_addr, m_data);
}
}
else
{
if (COMMAND_RAM)
{
- LOG("DS1302 Write RAM %u:%02x\n", m_addr, m_data);
+ LOG("Write RAM %u: %02x\n", m_addr, m_data);
- m_ram[m_addr] = m_data;
+ if (m_addr < m_ram_size)
+ m_ram[m_addr] = m_data;
}
else if (m_addr < 9)
{
- LOG("DS1302 Write Clock %u:%02x\n", m_addr, m_data);
+ LOG("Write Clock %u: %02x\n", m_addr, m_data);
m_reg[m_addr] = m_data;
}
@@ -262,9 +274,11 @@ void ds1302_device::input_bit()
m_cmd |= (m_io << 7);
m_bits++;
+ LOG("Serial Input Bit: %u\n", m_io);
+
if (m_bits == 8)
{
- LOG("DS1302 Command: %02x\n", m_cmd);
+ LOG("Command Received: %02x\n", m_cmd);
m_bits = 0;
m_addr = (m_cmd >> 1) & 0x1f;
@@ -299,9 +313,11 @@ void ds1302_device::input_bit()
m_data |= (m_io << 7);
m_bits++;
+ LOG("Serial Input Bit: %u\n", m_io);
+
if (m_bits == 8)
{
- LOG("DS1302 Data: %02x\n", m_data);
+ LOG("Data Received: %02x\n", m_data);
m_bits = 0;
@@ -363,6 +379,8 @@ void ds1302_device::output_bit()
m_state = STATE_COMMAND;
}
}
+
+ LOG("Serial Output Bit: %u\n", m_io);
}
@@ -370,19 +388,16 @@ void ds1302_device::output_bit()
// sclk_w - serial clock write
//-------------------------------------------------
-WRITE_LINE_MEMBER( ds1302_device::sclk_w )
+void ds1302_device::sclk_w(int state)
{
- LOG("DS1302 CLK: %u\n", state);
-
- if (!m_ce) return;
+ //LOG("Serial CLK: %u\n", state);
- if (!m_clk && state) // rising edge
- {
- input_bit();
- }
- else if (m_clk && !state) // falling edge
+ if (m_ce)
{
- output_bit();
+ if (!m_clk && state) // rising edge
+ input_bit();
+ else if (m_clk && !state) // falling edge
+ output_bit();
}
m_clk = state;
@@ -393,9 +408,9 @@ WRITE_LINE_MEMBER( ds1302_device::sclk_w )
// io_w - I/O write
//-------------------------------------------------
-WRITE_LINE_MEMBER( ds1302_device::io_w )
+void ds1302_device::io_w(int state)
{
- LOG("DS1302 I/O: %u\n", state);
+ //LOG("Serial I/O: %u\n", state);
m_io = state;
}
@@ -405,7 +420,7 @@ WRITE_LINE_MEMBER( ds1302_device::io_w )
// io_r - I/O read
//-------------------------------------------------
-READ_LINE_MEMBER( ds1302_device::io_r )
+int ds1302_device::io_r()
{
return m_io;
}