25 |
* SUCH DAMAGE. |
* SUCH DAMAGE. |
26 |
* |
* |
27 |
* |
* |
28 |
* $Id: dev_mc146818.c,v 1.68 2005/02/07 05:51:54 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; |
581 |
d->access_style = access_style; |
d->access_style = access_style; |
582 |
d->addrdiv = addrdiv; |
d->addrdiv = addrdiv; |
583 |
|
|
584 |
|
/* Only SGIs and PCs use BCD format (?) */ |
585 |
|
d->use_bcd = 0; |
586 |
|
if (access_style == MC146818_SGI || access_style == MC146818_PC_CMOS) |
587 |
|
d->use_bcd = 1; |
588 |
|
|
589 |
|
if (access_style == MC146818_DEC) { |
590 |
/* Station Ethernet Address, on DECstation 3100: */ |
/* Station Ethernet Address, on DECstation 3100: */ |
591 |
for (i=0; i<6; i++) |
for (i=0; i<6; i++) |
592 |
ether_address[i] = 0x10 * (i+1); |
ether_address[i] = 0x10 * (i+1); |
593 |
|
|
594 |
d->reg[0x01] = ether_address[0]; |
d->reg[0x01] = ether_address[0]; |
595 |
d->reg[0x05] = ether_address[1]; |
d->reg[0x05] = ether_address[1]; |
596 |
d->reg[0x09] = ether_address[2]; |
d->reg[0x09] = ether_address[2]; |
597 |
d->reg[0x0d] = ether_address[3]; |
d->reg[0x0d] = ether_address[3]; |
598 |
d->reg[0x11] = ether_address[4]; |
d->reg[0x11] = ether_address[4]; |
599 |
d->reg[0x15] = ether_address[5]; |
d->reg[0x15] = ether_address[5]; |
600 |
/* TODO: 19, 1d, 21, 25 = checksum bytes 1,2,2,1 resp. */ |
/* TODO: 19, 1d, 21, 25 = checksum bytes 1,2,2,1 resp. */ |
601 |
d->reg[0x29] = ether_address[5]; |
d->reg[0x29] = ether_address[5]; |
602 |
d->reg[0x2d] = ether_address[4]; |
d->reg[0x2d] = ether_address[4]; |
603 |
d->reg[0x31] = ether_address[3]; |
d->reg[0x31] = ether_address[3]; |
604 |
d->reg[0x35] = ether_address[2]; |
d->reg[0x35] = ether_address[2]; |
605 |
d->reg[0x39] = ether_address[1]; |
d->reg[0x39] = ether_address[1]; |
606 |
d->reg[0x3d] = ether_address[1]; |
d->reg[0x3d] = ether_address[1]; |
607 |
d->reg[0x41] = ether_address[0]; |
d->reg[0x41] = ether_address[0]; |
608 |
d->reg[0x45] = ether_address[1]; |
d->reg[0x45] = ether_address[1]; |
609 |
d->reg[0x49] = ether_address[2]; |
d->reg[0x49] = ether_address[2]; |
610 |
d->reg[0x4d] = ether_address[3]; |
d->reg[0x4d] = ether_address[3]; |
611 |
d->reg[0x51] = ether_address[4]; |
d->reg[0x51] = ether_address[4]; |
612 |
d->reg[0x55] = ether_address[5]; |
d->reg[0x55] = ether_address[5]; |
613 |
/* TODO: 59, 5d = checksum bytes 1,2 resp. */ |
/* TODO: 59, 5d = checksum bytes 1,2 resp. */ |
614 |
d->reg[0x61] = 0xff; |
d->reg[0x61] = 0xff; |
615 |
d->reg[0x65] = 0x00; |
d->reg[0x65] = 0x00; |
616 |
d->reg[0x69] = 0x55; |
d->reg[0x69] = 0x55; |
617 |
d->reg[0x6d] = 0xaa; |
d->reg[0x6d] = 0xaa; |
618 |
d->reg[0x71] = 0xff; |
d->reg[0x71] = 0xff; |
619 |
d->reg[0x75] = 0x00; |
d->reg[0x75] = 0x00; |
620 |
d->reg[0x79] = 0x55; |
d->reg[0x79] = 0x55; |
621 |
d->reg[0x7d] = 0xaa; |
d->reg[0x7d] = 0xaa; |
622 |
|
|
|
/* Only SGI uses BCD format (?) */ |
|
|
d->use_bcd = 0; |
|
|
if (access_style == MC146818_SGI) |
|
|
d->use_bcd = 1; |
|
|
|
|
|
if (access_style == MC146818_DEC) { |
|
623 |
/* Battery valid, for DECstations */ |
/* Battery valid, for DECstations */ |
624 |
d->reg[0xf8] = 1; |
d->reg[0xf8] = 1; |
625 |
} |
} |
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 |
|
|