trunk/src/emu/machine/msm6242.c
| r19426 | r19427 | |
| 3 | 3 | MSM6242 / Epson RTC 62421 / 62423 Real Time Clock |
| 4 | 4 | |
| 5 | 5 | TODO: |
| 6 | - Stop timer callbacks on every single tick |
| 6 | 7 | - HOLD mechanism |
| 7 | 8 | - IRQs are grossly mapped |
| 8 | 9 | - STOP / RESET mechanism |
| r19426 | r19427 | |
| 14 | 15 | #include "machine/msm6242.h" |
| 15 | 16 | |
| 16 | 17 | |
| 18 | //************************************************************************** |
| 19 | // CONSTANTS |
| 20 | //************************************************************************** |
| 21 | |
| 17 | 22 | enum |
| 18 | 23 | { |
| 19 | 24 | MSM6242_REG_S1 = 0, |
| r19426 | r19427 | |
| 34 | 39 | MSM6242_REG_CF |
| 35 | 40 | }; |
| 36 | 41 | |
| 42 | #define TIMER_RTC_CALLBACK 1 |
| 43 | |
| 44 | |
| 45 | |
| 37 | 46 | //************************************************************************** |
| 38 | 47 | // GLOBAL VARIABLES |
| 39 | 48 | //************************************************************************** |
| r19426 | r19427 | |
| 47 | 56 | //************************************************************************** |
| 48 | 57 | |
| 49 | 58 | //------------------------------------------------- |
| 50 | | // xxx_device - constructor |
| 59 | // msm6242_device - constructor |
| 51 | 60 | //------------------------------------------------- |
| 52 | 61 | |
| 53 | 62 | msm6242_device::msm6242_device(const machine_config &mconfig, const char *tag, device_t *owner, UINT32 clock) |
| r19426 | r19427 | |
| 56 | 65 | |
| 57 | 66 | } |
| 58 | 67 | |
| 68 | |
| 69 | |
| 70 | //------------------------------------------------- |
| 71 | // rtc_timer_callback |
| 72 | //------------------------------------------------- |
| 73 | |
| 59 | 74 | void msm6242_device::rtc_timer_callback() |
| 60 | 75 | { |
| 61 | 76 | static const UINT8 dpm[12] = { 0x31, 0x28, 0x31, 0x30, 0x31, 0x30, 0x31, 0x31, 0x30, 0x31, 0x30, 0x31 }; |
| r19426 | r19427 | |
| 109 | 124 | } |
| 110 | 125 | } |
| 111 | 126 | |
| 112 | | TIMER_CALLBACK( msm6242_device::rtc_inc_callback ) |
| 127 | |
| 128 | |
| 129 | //------------------------------------------------- |
| 130 | // device_timer - handle timer callbacks |
| 131 | //------------------------------------------------- |
| 132 | |
| 133 | void msm6242_device::device_timer(emu_timer &timer, device_timer_id id, int param, void *ptr) |
| 113 | 134 | { |
| 114 | | reinterpret_cast<msm6242_device *>(ptr)->rtc_timer_callback(); |
| 135 | switch(id) |
| 136 | { |
| 137 | case TIMER_RTC_CALLBACK: |
| 138 | rtc_timer_callback(); |
| 139 | break; |
| 140 | } |
| 115 | 141 | } |
| 116 | 142 | |
| 143 | |
| 144 | |
| 117 | 145 | //------------------------------------------------- |
| 118 | 146 | // device_validity_check - perform validity checks |
| 119 | 147 | // on this device |
| r19426 | r19427 | |
| 123 | 151 | { |
| 124 | 152 | } |
| 125 | 153 | |
| 154 | |
| 155 | |
| 126 | 156 | //------------------------------------------------- |
| 127 | 157 | // device_start - device-specific startup |
| 128 | 158 | //------------------------------------------------- |
| r19426 | r19427 | |
| 131 | 161 | { |
| 132 | 162 | m_out_int_func.resolve( m_out_int_cb, *this ); |
| 133 | 163 | |
| 134 | | /* let's call the timer callback every second */ |
| 135 | | machine().scheduler().timer_pulse(attotime::from_hz(clock()), FUNC(rtc_inc_callback), 0, (void *)this); |
| 164 | // let's call the timer callback every tick |
| 165 | m_timer = timer_alloc(TIMER_RTC_CALLBACK); |
| 166 | m_timer->adjust(attotime::zero, 0, attotime::from_hz(clock())); |
| 136 | 167 | |
| 168 | // get real time from system |
| 137 | 169 | system_time systime; |
| 138 | 170 | machine().base_datetime(systime); |
| 139 | 171 | |
| 172 | // ...and set the RTC time |
| 140 | 173 | m_rtc.day = (systime.local_time.mday); |
| 141 | 174 | m_rtc.month = (systime.local_time.month+1); |
| 142 | 175 | m_rtc.wday = (systime.local_time.weekday); |
| r19426 | r19427 | |
| 148 | 181 | m_irq_flag = 0; |
| 149 | 182 | m_irq_type = 0; |
| 150 | 183 | |
| 151 | | /* TODO: skns writes 0x4 to D then expects E == 6 and F == 4, perhaps those are actually saved in the RTC CMOS? */ |
| 184 | // TODO: skns writes 0x4 to D then expects E == 6 and F == 4, perhaps those are actually saved in the RTC CMOS? |
| 152 | 185 | m_reg[0] = 0; |
| 153 | 186 | m_reg[1] = 0x6; |
| 154 | 187 | m_reg[2] = 0x4; |
| 155 | 188 | } |
| 156 | 189 | |
| 157 | 190 | |
| 191 | |
| 158 | 192 | //------------------------------------------------- |
| 159 | 193 | // device_reset - device-specific reset |
| 160 | 194 | //------------------------------------------------- |
| r19426 | r19427 | |
| 166 | 200 | } |
| 167 | 201 | |
| 168 | 202 | |
| 203 | |
| 169 | 204 | //------------------------------------------------- |
| 170 | 205 | // device_config_complete - perform any |
| 171 | 206 | // operations now that the configuration is |
| r19426 | r19427 | |
| 178 | 213 | |
| 179 | 214 | if ( intf != NULL ) |
| 180 | 215 | { |
| 181 | | *static_cast<msm6242_interface *>(this) = *intf; |
| 216 | m_out_int_cb = intf->m_out_int_cb; |
| 182 | 217 | } |
| 183 | 218 | else |
| 184 | 219 | { |
| r19426 | r19427 | |
| 186 | 221 | } |
| 187 | 222 | } |
| 188 | 223 | |
| 224 | |
| 225 | |
| 189 | 226 | //************************************************************************** |
| 190 | 227 | // READ/WRITE HANDLERS |
| 191 | 228 | //************************************************************************** |
| 192 | 229 | |
| 230 | //------------------------------------------------- |
| 231 | // read |
| 232 | //------------------------------------------------- |
| 233 | |
| 193 | 234 | READ8_MEMBER( msm6242_device::read ) |
| 194 | 235 | { |
| 195 | 236 | rtc_regs_t cur_time; |
| 196 | 237 | |
| 197 | | //cur_time = (m_reg[0] & 1) ? m_hold : m_rtc; |
| 198 | | |
| 199 | 238 | cur_time = m_rtc; |
| 200 | 239 | |
| 201 | 240 | switch(offset) |
| r19426 | r19427 | |
| 244 | 283 | return 0; |
| 245 | 284 | } |
| 246 | 285 | |
| 286 | |
| 287 | |
| 288 | //------------------------------------------------- |
| 289 | // write |
| 290 | //------------------------------------------------- |
| 291 | |
| 247 | 292 | WRITE8_MEMBER( msm6242_device::write ) |
| 248 | 293 | { |
| 249 | 294 | switch(offset) |
| 250 | 295 | { |
| 251 | 296 | case MSM6242_REG_CD: |
| 252 | 297 | { |
| 253 | | /* |
| 254 | | x--- 30s ADJ |
| 255 | | -x-- IRQ FLAG |
| 256 | | --x- BUSY |
| 257 | | ---x HOLD |
| 258 | | */ |
| 298 | // x--- 30s ADJ |
| 299 | // -x-- IRQ FLAG |
| 300 | // --x- BUSY |
| 301 | // ---x HOLD |
| 259 | 302 | |
| 260 | 303 | m_reg[0] = data & 0x0f; |
| 261 | 304 | |
| 262 | | #if 0 |
| 263 | | if (data & 1) /* was Hold set? */ |
| 264 | | { |
| 265 | | m_hold.day = m_rtc.day; |
| 266 | | m_hold.month = m_rtc.month; |
| 267 | | m_hold.hour = m_rtc.hour; |
| 268 | | m_hold.day = m_rtc.day; |
| 269 | | m_hold.month = m_rtc.month; |
| 270 | | m_hold.year = m_rtc.year; |
| 271 | | m_hold.wday = m_rtc.wday; |
| 272 | | } |
| 273 | | #endif |
| 274 | | |
| 275 | 305 | return; |
| 276 | 306 | } |
| 277 | 307 | |
| 278 | 308 | case MSM6242_REG_CE: |
| 279 | 309 | { |
| 280 | | /* |
| 281 | | xx-- t0,t1 (timing irq) |
| 282 | | --x- STD |
| 283 | | ---x MASK |
| 284 | | */ |
| 310 | // xx-- t0,t1 (timing irq) |
| 311 | // --x- STD |
| 312 | // ---x MASK |
| 285 | 313 | |
| 286 | 314 | m_reg[1] = data & 0x0f; |
| 287 | 315 | if((data & 3) == 0) // MASK & STD = 0 |
| 288 | 316 | { |
| 289 | 317 | m_irq_flag = 1; |
| 290 | 318 | m_irq_type = (data & 0xc) >> 2; |
| 291 | | //m_std_timer->adjust(attotime::from_msec(timer_param[(data & 0xc) >> 2]), 0, attotime::from_msec(timer_param[(data & 0xc) >> 2])); |
| 292 | 319 | } |
| 293 | 320 | else |
| 294 | 321 | { |
| r19426 | r19427 | |
| 302 | 329 | |
| 303 | 330 | case MSM6242_REG_CF: |
| 304 | 331 | { |
| 305 | | /* |
| 306 | | x--- TEST |
| 307 | | -x-- 24/12 |
| 308 | | --x- STOP |
| 309 | | ---x RESET |
| 310 | | */ |
| 332 | // x--- TEST |
| 333 | // -x-- 24/12 |
| 334 | // --x- STOP |
| 335 | // ---x RESET |
| 311 | 336 | |
| 312 | | /* the 12/24 mode bit can only be changed when RESET does a 1 -> 0 transition */ |
| 337 | // the 12/24 mode bit can only be changed when RESET does a 1 -> 0 transition |
| 313 | 338 | if (((data & 0x01) == 0x00) && (m_reg[2] & 0x01)) |
| 314 | 339 | m_reg[2] = (m_reg[2] & ~0x04) | (data & 0x04); |
| 315 | 340 | else |
| r19426 | r19427 | |
| 321 | 346 | |
| 322 | 347 | logerror("%s: MSM6242 unmapped offset %02x written with %02x\n", machine().describe_context(), offset, data); |
| 323 | 348 | } |
| 324 | | |
| 325 | | |
| 326 | | |
| 327 | | |
| 328 | | |
| 329 | | |