trunk/src/emu/machine/msm6242.c
| r19469 | r19470 | |
| 60 | 60 | //------------------------------------------------- |
| 61 | 61 | |
| 62 | 62 | msm6242_device::msm6242_device(const machine_config &mconfig, const char *tag, device_t *owner, UINT32 clock) |
| 63 | | : device_t(mconfig, msm6242, "msm6242", tag, owner, clock) |
| 63 | : device_t(mconfig, msm6242, "msm6242", tag, owner, clock), |
| 64 | device_rtc_interface(mconfig, *this) |
| 64 | 65 | { |
| 65 | 66 | |
| 66 | 67 | } |
| r19469 | r19470 | |
| 86 | 87 | |
| 87 | 88 | if(m_tick & 0x8000) // 32,768 KHz == 0x8000 ticks |
| 88 | 89 | { |
| 90 | int sec = get_clock_register(RTC_SECOND); |
| 91 | int minute = get_clock_register(RTC_MINUTE); |
| 92 | int hour = get_clock_register(RTC_HOUR); |
| 93 | int day = get_clock_register(RTC_DAY); |
| 94 | int month = get_clock_register(RTC_MONTH); |
| 95 | int weekday = get_clock_register(RTC_DAY_OF_WEEK); |
| 96 | int year = get_clock_register(RTC_YEAR); |
| 97 | |
| 89 | 98 | m_tick = 0; |
| 90 | | m_rtc.sec++; |
| 99 | sec++; |
| 91 | 100 | |
| 92 | 101 | if(m_irq_flag == 1 && m_irq_type == 1) // 1 second clock |
| 93 | 102 | if ( !m_res_out_int_func.isnull() ) |
| 94 | 103 | m_res_out_int_func(ASSERT_LINE); |
| 95 | 104 | |
| 96 | | if(m_rtc.sec >= 60) |
| 105 | if(sec >= 60) |
| 97 | 106 | { |
| 98 | | m_rtc.min++; m_rtc.sec = 0; |
| 107 | minute++; sec = 0; |
| 99 | 108 | if(m_irq_flag == 1 && m_irq_type == 2) // 1 minute clock |
| 100 | 109 | if ( !m_res_out_int_func.isnull() ) |
| 101 | 110 | m_res_out_int_func(ASSERT_LINE); |
| 102 | 111 | } |
| 103 | | if(m_rtc.min >= 60) |
| 112 | if(minute >= 60) |
| 104 | 113 | { |
| 105 | | m_rtc.hour++; m_rtc.min = 0; |
| 114 | hour++; minute = 0; |
| 106 | 115 | if(m_irq_flag == 1 && m_irq_type == 3) // 1 hour clock |
| 107 | 116 | if ( !m_res_out_int_func.isnull() ) |
| 108 | 117 | m_res_out_int_func(ASSERT_LINE); |
| 109 | 118 | } |
| 110 | | if(m_rtc.hour >= 24) { m_rtc.day++; m_rtc.wday++; m_rtc.hour = 0; } |
| 111 | | if(m_rtc.wday >= 6) { m_rtc.wday = 1; } |
| 119 | if(hour >= 24) { day++; weekday++; hour = 0; } |
| 120 | if(weekday >= 6) { weekday = 1; } |
| 112 | 121 | |
| 113 | 122 | /* TODO: crude leap year support */ |
| 114 | | dpm_count = (m_rtc.month)-1; |
| 123 | dpm_count = (month)-1; |
| 115 | 124 | |
| 116 | | if(((m_rtc.year % 4) == 0) && m_rtc.month == 2) |
| 125 | if(((year % 4) == 0) && month == 2) |
| 117 | 126 | { |
| 118 | | if((m_rtc.day) >= dpm[dpm_count]+1+1) |
| 119 | | { m_rtc.month++; m_rtc.day = 0x01; } |
| 127 | if((day) >= dpm[dpm_count]+1+1) |
| 128 | { month++; day = 0x01; } |
| 120 | 129 | } |
| 121 | | else if(m_rtc.day >= dpm[dpm_count]+1) { m_rtc.month++; m_rtc.day = 0x01; } |
| 122 | | if(m_rtc.month >= 0x13) { m_rtc.year++; m_rtc.month = 1; } |
| 123 | | if(m_rtc.year >= 100) { m_rtc.year = 0; } //1900-1999 possible timeframe |
| 130 | else if(day >= dpm[dpm_count]+1) { month++; day = 0x01; } |
| 131 | if(month >= 0x13) { year++; month = 1; } |
| 132 | if(year >= 100) { year = 0; } //1900-1999 possible timeframe |
| 133 | |
| 134 | set_clock_register(RTC_SECOND, sec); |
| 135 | set_clock_register(RTC_MINUTE, minute); |
| 136 | set_clock_register(RTC_HOUR, hour); |
| 137 | set_clock_register(RTC_DAY, day); |
| 138 | set_clock_register(RTC_MONTH, month); |
| 139 | set_clock_register(RTC_DAY_OF_WEEK, weekday); |
| 140 | set_clock_register(RTC_YEAR, year); |
| 124 | 141 | } |
| 125 | 142 | } |
| 126 | 143 | |
| r19469 | r19470 | |
| 157 | 174 | m_timer->adjust(attotime::zero, 0, attotime::from_hz(clock())); |
| 158 | 175 | |
| 159 | 176 | // get real time from system |
| 160 | | system_time systime; |
| 161 | | machine().base_datetime(systime); |
| 177 | set_current_time(machine()); |
| 162 | 178 | |
| 163 | | // ...and set the RTC time |
| 164 | | m_rtc.day = (systime.local_time.mday); |
| 165 | | m_rtc.month = (systime.local_time.month+1); |
| 166 | | m_rtc.wday = (systime.local_time.weekday); |
| 167 | | m_rtc.year = (systime.local_time.year % 100); |
| 168 | | m_rtc.hour = (systime.local_time.hour); |
| 169 | | m_rtc.min = (systime.local_time.minute); |
| 170 | | m_rtc.sec = (systime.local_time.second); |
| 179 | // set up registers |
| 171 | 180 | m_tick = 0; |
| 172 | 181 | m_irq_flag = 0; |
| 173 | 182 | m_irq_type = 0; |
| r19469 | r19470 | |
| 182 | 191 | save_item(NAME(m_irq_flag)); |
| 183 | 192 | save_item(NAME(m_irq_type)); |
| 184 | 193 | save_item(NAME(m_tick)); |
| 185 | | save_item(NAME(m_rtc.sec)); |
| 186 | | save_item(NAME(m_rtc.min)); |
| 187 | | save_item(NAME(m_rtc.hour)); |
| 188 | | save_item(NAME(m_rtc.wday)); |
| 189 | | save_item(NAME(m_rtc.day)); |
| 190 | | save_item(NAME(m_rtc.month)); |
| 191 | | save_item(NAME(m_rtc.year)); |
| 192 | 194 | } |
| 193 | 195 | |
| 194 | 196 | |
| r19469 | r19470 | |
| 215 | 217 | |
| 216 | 218 | READ8_MEMBER( msm6242_device::read ) |
| 217 | 219 | { |
| 218 | | rtc_regs_t cur_time; |
| 220 | int sec = get_clock_register(RTC_SECOND); |
| 221 | int minute = get_clock_register(RTC_MINUTE); |
| 222 | int hour = get_clock_register(RTC_HOUR); |
| 223 | int day = get_clock_register(RTC_DAY); |
| 224 | int month = get_clock_register(RTC_MONTH); |
| 225 | int weekday = get_clock_register(RTC_DAY_OF_WEEK); |
| 226 | int year = get_clock_register(RTC_YEAR); |
| 219 | 227 | |
| 220 | | cur_time = m_rtc; |
| 221 | | |
| 222 | 228 | switch(offset) |
| 223 | 229 | { |
| 224 | | case MSM6242_REG_S1: return (cur_time.sec % 10) & 0xf; |
| 225 | | case MSM6242_REG_S10: return (cur_time.sec / 10) & 0xf; |
| 226 | | case MSM6242_REG_MI1: return (cur_time.min % 10) & 0xf; |
| 227 | | case MSM6242_REG_MI10: return (cur_time.min / 10) & 0xf; |
| 230 | case MSM6242_REG_S1: return (sec % 10) & 0xf; |
| 231 | case MSM6242_REG_S10: return (sec / 10) & 0xf; |
| 232 | case MSM6242_REG_MI1: return (minute % 10) & 0xf; |
| 233 | case MSM6242_REG_MI10: return (minute / 10) & 0xf; |
| 228 | 234 | case MSM6242_REG_H1: |
| 229 | 235 | case MSM6242_REG_H10: |
| 230 | 236 | { |
| 231 | | int hour = cur_time.hour; |
| 232 | 237 | int pm = 0; |
| 233 | 238 | |
| 234 | 239 | /* check for 12/24 hour mode */ |
| r19469 | r19470 | |
| 249 | 254 | return (hour / 10) | (pm <<2); |
| 250 | 255 | } |
| 251 | 256 | |
| 252 | | case MSM6242_REG_D1: return (cur_time.day % 10) & 0xf; |
| 253 | | case MSM6242_REG_D10: return (cur_time.day / 10) & 0xf; |
| 254 | | case MSM6242_REG_MO1: return (cur_time .month % 10) & 0xf; |
| 255 | | case MSM6242_REG_MO10: return (cur_time.month / 10) & 0xf; |
| 256 | | case MSM6242_REG_Y1: return (cur_time.year % 10) & 0xf; |
| 257 | | case MSM6242_REG_Y10: return ((cur_time.year / 10) % 10) & 0xf; |
| 258 | | case MSM6242_REG_W: return cur_time.wday; |
| 257 | case MSM6242_REG_D1: return (day % 10) & 0xf; |
| 258 | case MSM6242_REG_D10: return (day / 10) & 0xf; |
| 259 | case MSM6242_REG_MO1: return (month % 10) & 0xf; |
| 260 | case MSM6242_REG_MO10: return (month / 10) & 0xf; |
| 261 | case MSM6242_REG_Y1: return (year % 10) & 0xf; |
| 262 | case MSM6242_REG_Y10: return ((year / 10) % 10) & 0xf; |
| 263 | case MSM6242_REG_W: return weekday; |
| 259 | 264 | case MSM6242_REG_CD: return m_reg[0]; |
| 260 | 265 | case MSM6242_REG_CE: return m_reg[1]; |
| 261 | 266 | case MSM6242_REG_CF: return m_reg[2]; |