25 |
* SUCH DAMAGE. |
* SUCH DAMAGE. |
26 |
* |
* |
27 |
* |
* |
28 |
* $Id: dev_mc146818.c,v 1.72 2005/08/02 07:56:37 debug Exp $ |
* $Id: dev_mc146818.c,v 1.75 2005/10/09 22:21:31 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 other machines is also similar to the MC146818.) |
32 |
* |
* |
33 |
* This device contains Date/time, the machine's ethernet address (on |
* This device contains Date/time, the machine's ethernet address (on |
34 |
* DECstation 3100), and can cause periodic (hardware) interrupts. |
* DECstation 3100), and can cause periodic (hardware) interrupts. |
222 |
d->reg[4 * MC_MONTH] = tmp->tm_mon + 1; |
d->reg[4 * MC_MONTH] = tmp->tm_mon + 1; |
223 |
d->reg[4 * MC_YEAR] = tmp->tm_year; |
d->reg[4 * MC_YEAR] = tmp->tm_year; |
224 |
|
|
225 |
|
/* |
226 |
|
* Special hacks for emulating the behaviour of various machines: |
227 |
|
*/ |
228 |
switch (d->access_style) { |
switch (d->access_style) { |
229 |
case MC146818_ARC_NEC: |
case MC146818_ARC_NEC: |
230 |
d->reg[4 * MC_YEAR] += (0x18 - 104); |
d->reg[4 * MC_YEAR] += (0x18 - 104); |
231 |
break; |
break; |
232 |
|
case MC146818_CATS: |
233 |
|
d->reg[4 * MC_YEAR] %= 100; |
234 |
|
break; |
235 |
case MC146818_SGI: |
case MC146818_SGI: |
236 |
/* |
/* |
237 |
* NetBSD/sgimips assumes data in BCD format. |
* NetBSD/sgimips assumes data in BCD format. |
253 |
(d->reg[4 * MC_YEAR] - 30 + 40) |
(d->reg[4 * MC_YEAR] - 30 + 40) |
254 |
: (d->reg[4 * MC_YEAR] - 40) |
: (d->reg[4 * MC_YEAR] - 40) |
255 |
); |
); |
|
|
|
256 |
/* Century: */ |
/* Century: */ |
257 |
d->reg[72 * 4] = 19 + (tmp->tm_year / 100); |
d->reg[72 * 4] = 19 + (tmp->tm_year / 100); |
|
|
|
258 |
break; |
break; |
259 |
case MC146818_DEC: |
case MC146818_DEC: |
260 |
/* |
/* |
307 |
|
|
308 |
/* Different ways of accessing the registers: */ |
/* Different ways of accessing the registers: */ |
309 |
switch (d->access_style) { |
switch (d->access_style) { |
310 |
|
case MC146818_CATS: |
311 |
case MC146818_PC_CMOS: |
case MC146818_PC_CMOS: |
312 |
if (relative_addr == 0x70 || relative_addr == 0x00) { |
if ((relative_addr & 1) == 0x00) { |
313 |
if (writeflag == MEM_WRITE) { |
if (writeflag == MEM_WRITE) { |
314 |
d->last_addr = data[0]; |
d->last_addr = data[0]; |
315 |
return 1; |
return 1; |
317 |
data[0] = d->last_addr; |
data[0] = d->last_addr; |
318 |
return 1; |
return 1; |
319 |
} |
} |
320 |
} else if (relative_addr == 0x71 || relative_addr == 0x01) |
} else |
321 |
relative_addr = d->last_addr * 4; |
relative_addr = d->last_addr * 4; |
|
else { |
|
|
fatal("[ mc146818: not accessed as an " |
|
|
"MC146818_PC_CMOS device! ]\n"); |
|
|
} |
|
322 |
break; |
break; |
323 |
case MC146818_ARC_NEC: |
case MC146818_ARC_NEC: |
324 |
if (relative_addr == 0x01) { |
if (relative_addr == 0x01) { |
631 |
|
|
632 |
dev_len = DEV_MC146818_LENGTH; |
dev_len = DEV_MC146818_LENGTH; |
633 |
switch (access_style) { |
switch (access_style) { |
634 |
|
case MC146818_CATS: |
635 |
case MC146818_PC_CMOS: |
case MC146818_PC_CMOS: |
636 |
dev_len = 2; |
dev_len = 2; |
637 |
break; |
break; |