25 |
* SUCH DAMAGE. |
* SUCH DAMAGE. |
26 |
* |
* |
27 |
* |
* |
28 |
* $Id: dev_mc146818.c,v 1.95 2007/02/03 16:55:55 debug Exp $ |
* $Id: dev_mc146818.c,v 1.99 2007/06/15 19:57:33 debug Exp $ |
29 |
* |
* |
30 |
* MC146818 real-time clock, used by many different machines types. |
* COMMENT: MC146818 real-time clock |
31 |
|
* |
32 |
* (DS1687 as used in some other machines is also similar to the MC146818.) |
* (DS1687 as used in some other machines is also similar to the MC146818.) |
33 |
* |
* |
34 |
* This device contains Date/time, the machine's ethernet address (on |
* This device contains Date/time, the machine's ethernet address (on |
59 |
|
|
60 |
/* #define MC146818_DEBUG */ |
/* #define MC146818_DEBUG */ |
61 |
|
|
62 |
#define TICK_SHIFT 14 |
#define MC146818_TICK_SHIFT 14 |
63 |
|
|
64 |
|
|
65 |
/* 256 on DECstation, SGI uses reg at 72*4 as the Century */ |
/* 256 on DECstation, SGI uses reg at 72*4 as the Century */ |
120 |
int pti = d->pending_timer_interrupts; |
int pti = d->pending_timer_interrupts; |
121 |
|
|
122 |
if ((d->reg[MC_REGB * 4] & MC_REGB_PIE) && pti > 0) { |
if ((d->reg[MC_REGB * 4] & MC_REGB_PIE) && pti > 0) { |
|
static int warned = 0; |
|
|
if (pti > 1500 && !warned) { |
|
|
warned = 1; |
|
|
fatal("[ WARNING: MC146818 interrupts lost, " |
|
|
"host too slow? ]\n"); |
|
|
} |
|
|
|
|
123 |
#if 0 |
#if 0 |
124 |
/* For debugging, to see how much the interrupts are |
/* For debugging, to see how much the interrupts are |
125 |
lagging behind the real clock: */ |
lagging behind the real clock: */ |
151 |
* It seems like JAZZ machines accesses the mc146818 by writing one byte to |
* It seems like JAZZ machines accesses the mc146818 by writing one byte to |
152 |
* 0x90000070 and then reading or writing another byte at 0x......0004000. |
* 0x90000070 and then reading or writing another byte at 0x......0004000. |
153 |
*/ |
*/ |
154 |
int dev_mc146818_jazz_access(struct cpu *cpu, struct memory *mem, |
DEVICE_ACCESS(mc146818_jazz) |
|
uint64_t relative_addr, unsigned char *data, size_t len, |
|
|
int writeflag, void *extra) |
|
155 |
{ |
{ |
156 |
struct mc_data *d = extra; |
struct mc_data *d = extra; |
157 |
|
|
276 |
} |
} |
277 |
|
|
278 |
|
|
279 |
/* |
DEVICE_ACCESS(mc146818) |
|
* dev_mc146818_access(): |
|
|
* |
|
|
* TODO: This access function only handles 8-bit accesses! |
|
|
*/ |
|
|
int dev_mc146818_access(struct cpu *cpu, struct memory *mem, |
|
|
uint64_t r, unsigned char *data, size_t len, |
|
|
int writeflag, void *extra) |
|
280 |
{ |
{ |
281 |
|
struct mc_data *d = extra; |
282 |
struct tm *tmp; |
struct tm *tmp; |
283 |
time_t timet; |
time_t timet; |
|
struct mc_data *d = extra; |
|
|
int relative_addr = r; |
|
284 |
size_t i; |
size_t i; |
285 |
|
|
286 |
|
/* NOTE/TODO: This access function only handles 8-bit accesses! */ |
287 |
|
|
288 |
relative_addr /= d->addrdiv; |
relative_addr /= d->addrdiv; |
289 |
|
|
290 |
/* Different ways of accessing the registers: */ |
/* Different ways of accessing the registers: */ |
593 |
int i, dev_len; |
int i, dev_len; |
594 |
struct mc_data *d; |
struct mc_data *d; |
595 |
|
|
596 |
d = malloc(sizeof(struct mc_data)); |
CHECK_ALLOCATION(d = malloc(sizeof(struct mc_data))); |
|
if (d == NULL) { |
|
|
fprintf(stderr, "out of memory\n"); |
|
|
exit(1); |
|
|
} |
|
|
|
|
597 |
memset(d, 0, sizeof(struct mc_data)); |
memset(d, 0, sizeof(struct mc_data)); |
598 |
|
|
599 |
d->access_style = access_style; |
d->access_style = access_style; |
616 |
} |
} |
617 |
|
|
618 |
if (access_style == MC146818_DEC) { |
if (access_style == MC146818_DEC) { |
619 |
/* Station Ethernet Address, on DECstation 3100: */ |
/* Station Ethernet Address, on DECstation 3100: */ |
620 |
for (i=0; i<6; i++) |
for (i=0; i<6; i++) |
621 |
ether_address[i] = 0x10 * (i+1); |
ether_address[i] = 0x10 * (i+1); |
622 |
|
|
623 |
d->reg[0x01] = ether_address[0]; |
d->reg[0x01] = ether_address[0]; |
624 |
d->reg[0x05] = ether_address[1]; |
d->reg[0x05] = ether_address[1]; |
685 |
mc146818_update_time(d); |
mc146818_update_time(d); |
686 |
|
|
687 |
machine_add_tickfunction(machine, dev_mc146818_tick, d, |
machine_add_tickfunction(machine, dev_mc146818_tick, d, |
688 |
TICK_SHIFT, 0.0); |
MC146818_TICK_SHIFT); |
689 |
} |
} |
690 |
|
|