diff options
Diffstat (limited to 'src/devices/machine/dp8573.cpp')
-rw-r--r-- | src/devices/machine/dp8573.cpp | 358 |
1 files changed, 0 insertions, 358 deletions
diff --git a/src/devices/machine/dp8573.cpp b/src/devices/machine/dp8573.cpp deleted file mode 100644 index d110ffa0656..00000000000 --- a/src/devices/machine/dp8573.cpp +++ /dev/null @@ -1,358 +0,0 @@ -// license:BSD-3-Clause -// copyright-holders:Ryan Holtz -/*************************************************************************** - - DP8573 Real Time Clock (RTC) - -***************************************************************************/ - -#include "emu.h" -#include "machine/dp8573.h" -#include "machine/timehelp.h" - -#define LOG_GENERAL (1 << 0) -#define LOG_TICKS (1 << 1) -#define LOG_ALL (LOG_GENERAL | LOG_TICKS) - -#define VERBOSE (0) -#include "logmacro.h" - -// device type definition -DEFINE_DEVICE_TYPE(DP8573, dp8573_device, "dp8573", "DP8573 Real-Time Clock") - -dp8573_device::dp8573_device(const machine_config &mconfig, const char *tag, device_t *owner, uint32_t clock) - : device_t(mconfig, DP8573, tag, owner, clock) - , device_nvram_interface(mconfig, *this) - , m_intr_cb(*this) - , m_mfo_cb(*this) -{ -} - -void dp8573_device::device_start() -{ - save_item(NAME(m_ram)); - save_item(NAME(m_tscr)); - save_item(NAME(m_pfr)); - save_item(NAME(m_millis)); - - m_timer = timer_alloc(TIMER_ID); - m_timer->adjust(attotime::never); - - m_intr_cb.resolve_safe(); - m_mfo_cb.resolve_safe(); - - memset(m_ram, 0, 32); - sync_time(); - - m_tscr = 0; - - m_timer->adjust(attotime::from_msec(1), 0, attotime::from_msec(1)); -} - -void dp8573_device::sync_time() -{ - system_time systime; - machine().base_datetime(systime); - - m_millis = 0; - m_ram[REG_HUNDREDTH] = 0; - m_ram[REG_SECOND] = time_helper::make_bcd(systime.utc_time.second); - m_ram[REG_MINUTE] = time_helper::make_bcd(systime.utc_time.minute); - m_ram[REG_HOUR] = time_helper::make_bcd(systime.utc_time.hour); - m_ram[REG_DAY] = time_helper::make_bcd(systime.utc_time.mday); - m_ram[REG_MONTH] = time_helper::make_bcd(systime.utc_time.month + 1); - m_ram[REG_YEAR] = time_helper::make_bcd(systime.utc_time.year % 100); - m_ram[REG_DAYOFWEEK] = time_helper::make_bcd(systime.utc_time.weekday + 1); - - m_pfr = 0; - - // FIXME: should probably rely on nvram start/stop state - m_ram[REG_RTMR] = RTMR_CSS; -} - -void dp8573_device::save_registers() -{ - m_ram[REG_SAVE_SECOND] = m_ram[REG_SECOND]; - m_ram[REG_SAVE_MINUTE] = m_ram[REG_MINUTE]; - m_ram[REG_SAVE_HOUR] = m_ram[REG_HOUR]; - m_ram[REG_SAVE_DAY] = m_ram[REG_DAY]; - m_ram[REG_SAVE_MONTH] = m_ram[REG_MONTH]; -} - -void dp8573_device::device_timer(emu_timer &timer, device_timer_id id, int param, void *ptr) -{ - if ((m_pfr & PFR_OSF) || !(m_ram[REG_RTMR] & RTMR_CSS)) - { - LOGMASKED(LOG_TICKS, "Tick suppressed due to OSF or !CSS\n"); - return; - } - - m_pfr |= PFR_1MS; - - bool carry = false; - bool tens_carry = false; - time_helper::inc_bcd(&m_millis, 0xff, 0x00, 0x09, &tens_carry); - if (tens_carry) - { - m_pfr |= PFR_10MS; - carry = time_helper::inc_bcd(&m_ram[REG_HUNDREDTH], 0xff, 0x00, 0x99, &tens_carry); - if (tens_carry) - m_pfr |= PFR_100MS; - } - if (carry) - { - m_pfr |= PFR_1S; - carry = time_helper::inc_bcd(&m_ram[REG_SECOND], 0xff, 0x00, 0x59, &tens_carry); - if (tens_carry) - m_pfr |= PFR_10S; - } - if (carry) - { - m_pfr |= PFR_1MIN; - carry = time_helper::inc_bcd(&m_ram[REG_MINUTE], 0xff, 0x00, 0x59); - } - if (carry) - { - if (m_ram[REG_RTMR] & RTMR_12H) - { - carry = time_helper::inc_bcd(&m_ram[REG_HOUR], 0xff, 0x01, 0x12); - if (carry) - { - m_ram[REG_HOUR] |= 0x20; - carry = !(m_ram[REG_HOUR] & 0x20); - } - } - else - { - carry = time_helper::inc_bcd(&m_ram[REG_HOUR], 0xff, 0x00, 0x23); - } - } - if (carry) - { - static const uint8_t daysinmonth[] = { 0x31, 0x28, 0x31, 0x30, 0x31, 0x30, 0x31, 0x31, 0x30, 0x31, 0x30, 0x31 }; - - time_helper::inc_bcd(&m_ram[REG_DAYOFWEEK], 0xff, 0x01, 0x07); - - uint8_t month = time_helper::from_bcd(m_ram[REG_MONTH]); - - uint8_t maxdays; - if (month == 2 && (m_ram[REG_RTMR] & RTMR_LY) == 0) - { - maxdays = 0x29; - } - else if (month >= 1 && month <= 12) - { - maxdays = daysinmonth[month - 1]; - } - else - { - maxdays = 0x31; - } - - carry = time_helper::inc_bcd(&m_ram[REG_DAY], 0xff, 0x01, maxdays); - } - if (carry) - { - carry = time_helper::inc_bcd(&m_ram[REG_MONTH], 0xff, 0x01, 0x12); - } - if (carry) - { - carry = time_helper::inc_bcd(&m_ram[REG_YEAR], 0xff, 0x00, 0x99); - } - if (carry) - { - // Advance the leap-year counter - uint8_t leap = m_ram[REG_RTMR] & RTMR_LY; - leap = (leap + 1) & RTMR_LY; - m_ram[REG_RTMR] &= ~RTMR_LY; - m_ram[REG_RTMR] |= leap; - } - - // Check for Time Save mode - if (m_tscr & TSCR_TS) - { - save_registers(); - } - - // Check for periodic interrupts - const uint8_t icr0 = m_ram[REG_PFR_ICR0] & ~ICR0_RAM_MASK; - const uint8_t pfr = m_pfr & ~ICR0_RAM_MASK; - if (icr0 & pfr) - { - set_interrupt(MSR_PER); - } - - const uint8_t icr1 = m_ram[REG_TSCR_ICR1] & ICR1_COMPARE_MASK; - if (icr1) - { - if (m_ram[REG_SECOND] == m_ram[REG_COMP_SECOND] || - m_ram[REG_MINUTE] == m_ram[REG_COMP_MINUTE] || - m_ram[REG_HOUR] == m_ram[REG_COMP_HOUR] || - m_ram[REG_DAY] == m_ram[REG_COMP_DAY] || - m_ram[REG_MONTH] == m_ram[REG_COMP_MONTH] || - m_ram[REG_DAYOFWEEK] == m_ram[REG_COMP_DAYOFWEEK]) - { - set_interrupt(MSR_AL); - } - } -} - -void dp8573_device::set_interrupt(uint8_t mask) -{ - bool was_intr = m_ram[REG_MSR] & MSR_INT; - m_ram[REG_MSR] |= mask; - - if (m_ram[REG_MSR] & MSR_INT_MASK) - m_ram[REG_MSR] |= MSR_INT; - - if (!was_intr && (m_ram[REG_MSR] & MSR_INT)) - m_intr_cb(0); -} - -void dp8573_device::clear_interrupt(uint8_t mask) -{ - bool was_intr = m_ram[REG_MSR] & MSR_INT; - m_ram[REG_MSR] &= ~mask; - - if (was_intr && !(m_ram[REG_MSR] & MSR_INT)) - m_intr_cb(1); -} - -void dp8573_device::write(offs_t offset, u8 data) -{ - LOGMASKED(LOG_GENERAL, "%s: DP8573 - Register Write: %02x = %02x\n", machine().describe_context(), offset, data); - - switch (offset) - { - case REG_MSR: // Main Status Register - m_ram[offset] &= ~MSR_RAM_MASK; - m_ram[offset] |= data & MSR_RAM_MASK; - if (data & MSR_CLEARABLE_MASK) - clear_interrupt(data & MSR_CLEARABLE_MASK); - break; - - case REG_RTMR: // Not Applicable / Real-Time Mode Register - if (m_ram[REG_MSR] & MSR_RS) - { - const uint8_t old = m_ram[offset]; - m_ram[offset] = data; - if ((old ^ data) & RTMR_12H) - { - uint8_t hour; - if (old & RTMR_12H) - hour = time_helper::from_bcd(m_ram[REG_HOUR] & 0x1f) + (BIT(m_ram[REG_HOUR], 5) ? 12 : 0); - else - hour = time_helper::from_bcd(m_ram[REG_HOUR]); - - if (data & RTMR_12H) - { - m_ram[REG_HOUR] = time_helper::make_bcd(hour % 12); - m_ram[REG_HOUR] |= (hour > 11) ? 0x20 : 0; - } - else - { - m_ram[REG_HOUR] = time_helper::make_bcd(hour); - } - } - } - break; - - case REG_OMR: // Not Applicable / Output Mode Register - if (m_ram[REG_MSR] & MSR_RS) - { - // Not yet implemented: Buffered Crystal Oscillator output on MFO pin - m_ram[offset] = data; - } - break; - - case REG_PFR_ICR0: // Periodic Flag Register / Interrupt Control Register 0 - if (m_ram[REG_MSR] & MSR_RS) - { - m_ram[offset] = data; - } - else - { - m_pfr &= ~PFR_TM; - m_pfr |= data & PFR_TM; - } - break; - - case REG_TSCR_ICR1: // Time Save Control Register / Interrupt Control Register 1 - if (m_ram[REG_MSR] & MSR_RS) - { - m_ram[offset] = data; - } - else - { - m_tscr = data & ~TSCR_NA; - if (data & TSCR_TS) - save_registers(); - } - break; - - case REG_RAM_D1D0: // RAM, D1/D0 bits only - m_ram[offset] = data & 3; - break; - - case REG_NA_0FH: - case REG_NA_10H: - case REG_NA_11H: - case REG_NA_12H: - break; - - default: - m_ram[offset] = data; - break; - } -} - -u8 dp8573_device::read(offs_t offset) -{ - uint8_t ret = m_ram[offset]; - - if (offset >= REG_RTMR && offset <= REG_TSCR_ICR1) - { - if (m_ram[REG_MSR] & MSR_RS) - { - } - else - { - switch (offset) - { - case REG_RTMR: - case REG_OMR: - ret = 0; - break; - case REG_PFR_ICR0: - ret = m_pfr; - m_pfr &= ~PFR_READ_CLEAR_MASK; - break; - case REG_TSCR_ICR1: - ret = m_tscr; - break; - default: - break; - } - } - } - - LOGMASKED(LOG_GENERAL, "%s: DP8573 - Register Read: %02x = %02x\n", machine().describe_context(), offset, ret); - return ret; -} - -void dp8573_device::nvram_default() -{ - memset(m_ram, 0, 32); - sync_time(); -} - -void dp8573_device::nvram_read(emu_file &file) -{ - file.read(m_ram, 32); - sync_time(); -} - -void dp8573_device::nvram_write(emu_file &file) -{ - file.write(m_ram, 32); -} |