diff options
Diffstat (limited to 'src/devices/machine/ds1302.cpp')
-rw-r--r-- | src/devices/machine/ds1302.cpp | 129 |
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; } |