summaryrefslogtreecommitdiffstatshomepage
diff options
context:
space:
mode:
author holub <andrei.holub@gmail.com>2025-07-08 22:59:23 -0400
committer GitHub <noreply@github.com>2025-07-08 22:59:23 -0400
commite0ab4c41964d097ba71c4c58e521d94a7cd6bcd2 (patch)
tree6e2f82c62a68c814be3e6599adfb67875068a8ec
parent5060de54a9ff5a294c0050597bbc766ecfa448fc (diff)
machine/i2cds1307.cpp: Added I2C DS1307; Used the device in Spectrum Next (#13930)
-rw-r--r--scripts/src/machine.lua11
-rw-r--r--src/devices/machine/i2cds1307.cpp66
-rw-r--r--src/devices/machine/i2cds1307.h36
-rw-r--r--src/mame/sinclair/specnext.cpp18
4 files changed, 124 insertions, 7 deletions
diff --git a/scripts/src/machine.lua b/scripts/src/machine.lua
index cbb0d706b64..e2f95bfe99f 100644
--- a/scripts/src/machine.lua
+++ b/scripts/src/machine.lua
@@ -1524,6 +1524,17 @@ if (MACHINES["1MB5"]~=null) then
end
---------------------------------------------------
+--@src/devices/machine/i2cds1307.h,MACHINES["I2C_DS1307"] = true
+---------------------------------------------------
+
+if (MACHINES["I2C_DS1307"]~=null) then
+ files {
+ MAME_DIR .. "src/devices/machine/i2cds1307.cpp",
+ MAME_DIR .. "src/devices/machine/i2cds1307.h",
+ }
+end
+
+---------------------------------------------------
--@src/devices/machine/i2chle.h,MACHINES["I2CHLE"] = true
---------------------------------------------------
diff --git a/src/devices/machine/i2cds1307.cpp b/src/devices/machine/i2cds1307.cpp
new file mode 100644
index 00000000000..d5eda632ddc
--- /dev/null
+++ b/src/devices/machine/i2cds1307.cpp
@@ -0,0 +1,66 @@
+// license:BSD-3-Clause
+// copyright-holders:Andrei I. Holub
+/**********************************************************************
+ DS1307 64x8, Serial, I2C Real-Time Clock (Maxim Integrated Products)
+**********************************************************************/
+
+#include "emu.h"
+
+#include "i2cds1307.h"
+
+
+DEFINE_DEVICE_TYPE(I2C_DS1307, i2c_ds1307_device, "i2c_ds1307", "I2C DS1307 RTC/SRAM")
+
+
+i2c_ds1307_device::i2c_ds1307_device(const machine_config &mconfig, const char *tag, device_t *owner, u32 clock)
+ : device_t(mconfig, I2C_DS1307, tag, owner, clock)
+ , i2c_hle_interface(mconfig, *this, 0xd0 >> 1)
+ , device_rtc_interface(mconfig, *this)
+ , m_nvram(*this, "nvram")
+{
+}
+
+
+u8 i2c_ds1307_device::read_data(u16 offset)
+{
+ return m_cmos[offset & 0x3f];
+}
+
+void i2c_ds1307_device::write_data(u16 offset, u8 data)
+{
+ m_cmos[offset & 0x3f] = data;
+}
+
+void i2c_ds1307_device::rtc_clock_updated(int year, int month, int day, int day_of_week, int hour, int minute, int second)
+{
+ m_cmos[0x00] = convert_to_bcd(second);
+ m_cmos[0x01] = convert_to_bcd(minute);
+ m_cmos[0x02] = convert_to_bcd(hour);
+ m_cmos[0x03] = convert_to_bcd(day_of_week);
+ m_cmos[0x04] = convert_to_bcd(day);
+ m_cmos[0x05] = convert_to_bcd(month);
+ m_cmos[0x06] = convert_to_bcd(year % 100);
+}
+
+TIMER_CALLBACK_MEMBER(i2c_ds1307_device::timer_callback)
+{
+ advance_seconds();
+}
+
+
+void i2c_ds1307_device::device_add_mconfig(machine_config &config)
+{
+ NVRAM(config, m_nvram, nvram_device::DEFAULT_ALL_0);
+}
+
+void i2c_ds1307_device::device_start()
+{
+ m_nvram->set_base(&m_cmos, sizeof(m_cmos));
+
+ m_timer = timer_alloc(FUNC(i2c_ds1307_device::timer_callback), this);
+ m_timer->adjust(attotime::from_hz(clock() / XTAL(32'768)), 0, attotime::from_hz(clock() / XTAL(32'768)));
+}
+
+void i2c_ds1307_device::device_reset()
+{
+}
diff --git a/src/devices/machine/i2cds1307.h b/src/devices/machine/i2cds1307.h
new file mode 100644
index 00000000000..248c8b7e246
--- /dev/null
+++ b/src/devices/machine/i2cds1307.h
@@ -0,0 +1,36 @@
+// license:BSD-3-Clause
+// copyright-holders:Andrei I. Holub
+#ifndef MAME_MACHINE_I2CDS1307_H
+#define MAME_MACHINE_I2CDS1307_H
+
+#include "dirtc.h"
+#include "i2chle.h"
+#include "machine/nvram.h"
+
+class i2c_ds1307_device : public device_t, public i2c_hle_interface, public device_rtc_interface
+{
+public:
+ i2c_ds1307_device(const machine_config &mconfig, const char *tag, device_t *owner, u32 clock = 32'768);
+
+ TIMER_CALLBACK_MEMBER(timer_callback);
+
+protected:
+ virtual void device_add_mconfig(machine_config &config) override ATTR_COLD;
+ virtual void device_start() override ATTR_COLD;
+ virtual void device_reset() override ATTR_COLD;
+
+ virtual void rtc_clock_updated(int year, int month, int day, int day_of_week, int hour, int minute, int second) override;
+
+ virtual u8 read_data(u16 offset) override;
+ virtual void write_data(u16 offset, u8 data) override;
+
+private:
+ u8 m_cmos[0x40];
+ required_device<nvram_device> m_nvram;
+ emu_timer *m_timer;
+
+};
+
+DECLARE_DEVICE_TYPE(I2C_DS1307, i2c_ds1307_device)
+
+#endif // MAME_MACHINE_I2CDS1307_H
diff --git a/src/mame/sinclair/specnext.cpp b/src/mame/sinclair/specnext.cpp
index d15494d2ad2..c808b696cce 100644
--- a/src/mame/sinclair/specnext.cpp
+++ b/src/mame/sinclair/specnext.cpp
@@ -34,7 +34,7 @@
#include "bus/spectrum/zxbus/bus.h"
#include "cpu/z80/z80n.h"
-#include "machine/i2cmem.h"
+#include "machine/i2cds1307.h"
#include "machine/spi_sdcard.h"
#include "sound/ay8910.h"
#include "sound/dac.h"
@@ -81,7 +81,7 @@ public:
, m_copper(*this, "copper")
, m_ctc(*this, "ctc")
, m_dma(*this, "ndma")
- , m_i2cmem(*this, "i2cmem")
+ , m_i2c(*this, "i2c")
, m_sdcard(*this, "sdcard")
, m_ay(*this, "ay%u", 0U)
, m_dac(*this, "dac%u", 0U)
@@ -293,7 +293,7 @@ private:
required_device<specnext_copper_device> m_copper;
required_device<specnext_ctc_device> m_ctc;
required_device<specnext_dma_device> m_dma;
- required_device<i2cmem_device> m_i2cmem;
+ optional_device<i2c_ds1307_device> m_i2c;
required_device<spi_sdcard_device> m_sdcard;
required_device_array<ym2149_device, 3> m_ay;
required_device_array<dac_byte_interface, 4> m_dac;
@@ -535,6 +535,7 @@ private:
u8 m_spi_mosi_dat;
u8 m_spi_miso_dat;
bool m_i2c_scl_data;
+ bool m_i2c_sda_data;
u16 m_irq_mask;
};
@@ -1006,7 +1007,7 @@ void specnext_state::i2c_scl_w(u8 data)
if (port_i2c_io_en())
{
m_i2c_scl_data = data & 1;
- m_i2cmem->write_scl(m_i2c_scl_data);
+ m_i2c->scl_write(m_i2c_scl_data);
}
}
@@ -2616,10 +2617,10 @@ void specnext_state::map_io(address_map &map)
return port_i2c_io_en() ? (0xfe | m_i2c_scl_data) : 0x00;
})).w(FUNC(specnext_state::i2c_scl_w));
map(0x113b, 0x113b).lrw8(NAME([this]() {
- return port_i2c_io_en() ? (0xfe | (m_i2cmem->read_sda() & 1)) : 0x00;
+ return port_i2c_io_en() ? (0xfe | (m_i2c_sda_data & 1)) : 0x00;
}), NAME([this](u8 data) {
if(port_i2c_io_en())
- m_i2cmem->write_sda(data & 1);
+ m_i2c->sda_write(data & 1);
}));
map(0x183b, 0x183b).select(0x0700).lrw8(NAME([this](offs_t offset) {
u8 chanel = offset >> 8;
@@ -3024,6 +3025,7 @@ void specnext_state::machine_start()
save_item(NAME(m_spi_mosi_dat));
save_item(NAME(m_spi_miso_dat));
save_item(NAME(m_i2c_scl_data));
+ save_item(NAME(m_i2c_sda_data));
save_item(NAME(m_irq_mask));
}
@@ -3175,6 +3177,7 @@ void specnext_state::machine_reset()
//port_253b_rd_qq = 0b00;
//sram_req_d = 0;
m_i2c_scl_data = 1;
+ m_i2c_sda_data = 1;
port_e7_reg_w(0xff);
//joy_iomode_pin7 = 1;
@@ -3461,7 +3464,8 @@ void specnext_state::tbblue(machine_config &config)
ADDRESS_MAP_BANK(config, m_regs_map).set_map(&specnext_state::map_regs).set_options(ENDIANNESS_LITTLE, 8, 8, 0);
- I2C_24C01(config, m_i2cmem).set_address(0xd0); // RTC + DEFAULT_ALL_0; confitm size
+ I2C_DS1307(config, m_i2c);
+ m_i2c->sda_callback().set([this](int state) { m_i2c_sda_data = state & 1; });
SPI_SDCARD(config, m_sdcard, 0);
m_sdcard->set_prefer_sdhc();