25 |
* SUCH DAMAGE. |
* SUCH DAMAGE. |
26 |
* |
* |
27 |
* |
* |
28 |
* $Id: dev_mc146818.c,v 1.69 2005/05/20 07:42:12 debug Exp $ |
* $Id: dev_mc146818.c,v 1.72 2005/08/02 07:56:37 debug Exp $ |
29 |
* |
* |
30 |
* MC146818 real-time clock, used by many different machines types. |
* MC146818 real-time clock, used by many different machines types. |
31 |
* (DS1687 as used in some SGI machines is similar to MC146818.) |
* (DS1687 as used in some SGI machines is similar to MC146818.) |
56 |
|
|
57 |
/* #define MC146818_DEBUG */ |
/* #define MC146818_DEBUG */ |
58 |
|
|
59 |
#define TICK_STEPS_SHIFT 14 |
#define TICK_SHIFT 14 |
60 |
|
|
61 |
|
|
62 |
/* 256 on DECstation, SGI uses reg at 72*4 as the Century */ |
/* 256 on DECstation, SGI uses reg at 72*4 as the Century */ |
140 |
|
|
141 |
if ((d->reg[MC_REGB * 4] & MC_REGB_PIE) && |
if ((d->reg[MC_REGB * 4] & MC_REGB_PIE) && |
142 |
d->interrupt_every_x_cycles > 0) { |
d->interrupt_every_x_cycles > 0) { |
143 |
d->cycles_left_until_interrupt -= |
d->cycles_left_until_interrupt -= (1 << TICK_SHIFT); |
|
(1 << TICK_STEPS_SHIFT); |
|
144 |
|
|
145 |
if (d->cycles_left_until_interrupt < 0 || |
if (d->cycles_left_until_interrupt < 0 || |
146 |
d->cycles_left_until_interrupt >= |
d->cycles_left_until_interrupt >= |
365 |
#endif |
#endif |
366 |
|
|
367 |
/* |
/* |
368 |
* For some reason, Linux/sgimips relies on the UIP bit to go |
* Sprite seems to wants UF interrupt status, once every second, or |
|
* on and off. Without this code, booting Linux takes forever: |
|
|
*/ |
|
|
d->reg[MC_REGA * 4] &= ~MC_REGA_UIP; |
|
|
#if 1 |
|
|
/* TODO: solve this more nicely */ |
|
|
if ((random() & 0xff) == 0) |
|
|
d->reg[MC_REGA * 4] ^= MC_REGA_UIP; |
|
|
#endif |
|
|
|
|
|
/* |
|
|
* Sprite seens to wants UF interrupt status, once every second, or |
|
369 |
* it hangs forever during bootup. (These do not cause interrupts, |
* it hangs forever during bootup. (These do not cause interrupts, |
370 |
* but it is good enough... Sprite polls this, iirc.) |
* but it is good enough... Sprite polls this, iirc.) |
371 |
|
* |
372 |
|
* Linux on at least sgimips and evbmips (Malta) wants the UIP bit |
373 |
|
* in REGA to be updated once a second. |
374 |
*/ |
*/ |
375 |
timet = time(NULL); |
timet = time(NULL); |
376 |
tmp = gmtime(&timet); |
tmp = gmtime(&timet); |
377 |
d->reg[MC_REGC * 4] &= ~MC_REGC_UF; |
d->reg[MC_REGC * 4] &= ~MC_REGC_UF; |
378 |
|
|
379 |
if (tmp->tm_sec != d->previous_second) { |
if (tmp->tm_sec != d->previous_second) { |
380 |
|
d->reg[MC_REGA * 4] &= ~MC_REGA_UIP; |
381 |
|
|
382 |
d->reg[MC_REGC * 4] |= MC_REGC_UF; |
d->reg[MC_REGC * 4] |= MC_REGC_UF; |
383 |
d->reg[MC_REGC * 4] |= MC_REGC_IRQF; |
d->reg[MC_REGC * 4] |= MC_REGC_IRQF; |
384 |
d->previous_second = tmp->tm_sec; |
d->previous_second = tmp->tm_sec; |
387 |
the PF (periodic flag) bit set, even though interrupts |
the PF (periodic flag) bit set, even though interrupts |
388 |
are not enabled? */ |
are not enabled? */ |
389 |
d->reg[MC_REGC * 4] |= MC_REGC_PF; |
d->reg[MC_REGC * 4] |= MC_REGC_PF; |
390 |
} |
} else |
391 |
|
d->reg[MC_REGA * 4] |= MC_REGA_UIP; |
392 |
|
|
393 |
/* RTC data is in either BCD format or binary: */ |
/* RTC data is in either BCD format or binary: */ |
394 |
if (d->use_bcd) { |
if (d->use_bcd) |
395 |
d->reg[MC_REGB * 4] &= ~(1 << 2); |
d->reg[MC_REGB * 4] &= ~(1 << 2); |
396 |
} else { |
else |
397 |
d->reg[MC_REGB * 4] |= (1 << 2); |
d->reg[MC_REGB * 4] |= (1 << 2); |
|
} |
|
398 |
|
|
399 |
/* RTC date/time is always Valid: */ |
/* RTC date/time is always Valid: */ |
400 |
d->reg[MC_REGD * 4] |= MC_REGD_VRT; |
d->reg[MC_REGD * 4] |= MC_REGD_VRT; |
643 |
|
|
644 |
mc146818_update_time(d); |
mc146818_update_time(d); |
645 |
|
|
646 |
machine_add_tickfunction(machine, dev_mc146818_tick, |
machine_add_tickfunction(machine, dev_mc146818_tick, d, TICK_SHIFT); |
|
d, TICK_STEPS_SHIFT); |
|
647 |
} |
} |
648 |
|
|