1 /*
2 * Copyright (C) 2003-2020 Anders Gavare. All rights reserved.
3 *
4 * Redistribution and use in source and binary forms, with or without
5 * modification, are permitted provided that the following conditions are met:
6 *
7 * 1. Redistributions of source code must retain the above copyright
8 * notice, this list of conditions and the following disclaimer.
9 * 2. Redistributions in binary form must reproduce the above copyright
10 * notice, this list of conditions and the following disclaimer in the
11 * documentation and/or other materials provided with the distribution.
12 * 3. The name of the author may not be used to endorse or promote products
13 * derived from this software without specific prior written permission.
14 *
15 * THIS SOFTWARE IS PROVIDED BY THE AUTHOR AND CONTRIBUTORS ``AS IS'' AND
16 * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
17 * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
18 * ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE
19 * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
20 * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
21 * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
22 * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
23 * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
24 * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
25 * SUCH DAMAGE.
26 *
27 *
28 * COMMENT: MC146818 real-time clock
29 *
30 * (DS1687 as used in some other machines is also similar to the MC146818.)
31 *
32 * This device contains Date/time, the machine's ethernet address (on
33 * DECstation 3100), and can cause periodic (hardware) interrupts.
34 *
35 * NOTE: Many register offsets are multiplied by 4 in this code; this is
36 * because I originally wrote it for DECstation 3100 emulation, where the
37 * registered are spaced that way.
38 */
39
40 #include <stdio.h>
41 #include <stdlib.h>
42 #include <string.h>
43 #include <time.h>
44
45 #include "cpu.h"
46 #include "devices.h"
47 #include "machine.h"
48 #include "memory.h"
49 #include "misc.h"
50 #include "timer.h"
51
52 #include "thirdparty/mc146818reg.h"
53
54
55 #define to_bcd(x) ( ((x)/10) * 16 + ((x)%10) )
56 #define from_bcd(x) ( ((x)>>4) * 10 + ((x)&15) )
57
58 /* #define MC146818_DEBUG */
59
60 #define MC146818_TICK_SHIFT 14
61
62
63 /* 256 on DECstation, SGI uses reg at 72*4 as the Century */
64 #define N_REGISTERS 1024
65 struct mc_data {
66 int access_style;
67 int last_addr;
68
69 int register_choice;
70 int reg[N_REGISTERS];
71 int addrdiv;
72
73 int use_bcd;
74
75 int timebase_hz;
76 int interrupt_hz;
77 int old_interrupt_hz;
78 struct interrupt irq;
79 struct timer *timer;
80 volatile int pending_timer_interrupts;
81
82 int previous_second;
83 int n_seconds_elapsed;
84 int uip_threshold;
85
86 int ugly_netbsd_prep_hack_done;
87 int ugly_netbsd_prep_hack_sec;
88 };
89
90
91 /*
92 * Ugly hack to fool NetBSD/prep to accept the clock. (See mcclock_isa_match
93 * in NetBSD's arch/prep/isa/mcclock_isa.c for details.)
94 */
95 #define NETBSD_HACK_INIT 0
96 #define NETBSD_HACK_FIRST_1 1
97 #define NETBSD_HACK_FIRST_2 2
98 #define NETBSD_HACK_SECOND_1 3
99 #define NETBSD_HACK_SECOND_2 4
100 #define NETBSD_HACK_DONE 5
101
102
103 /*
104 * timer_tick():
105 *
106 * Called d->interrupt_hz times per (real-world) second.
107 */
timer_tick(struct timer * timer,void * extra)108 static void timer_tick(struct timer *timer, void *extra)
109 {
110 struct mc_data *d = (struct mc_data *) extra;
111 d->pending_timer_interrupts ++;
112 }
113
114
DEVICE_TICK(mc146818)115 DEVICE_TICK(mc146818)
116 {
117 struct mc_data *d = (struct mc_data *) extra;
118 int pti = d->pending_timer_interrupts;
119
120 if ((d->reg[MC_REGB * 4] & MC_REGB_PIE) && pti > 0) {
121 #if 0
122 /* For debugging, to see how much the interrupts are
123 lagging behind the real clock: */
124 {
125 static int x = 0;
126 if (++x == 1) {
127 x = 0;
128 printf("%i ", pti);
129 fflush(stdout);
130 }
131 }
132 #endif
133
134 INTERRUPT_ASSERT(d->irq);
135
136 d->reg[MC_REGC * 4] |= MC_REGC_PF;
137 }
138
139 if (d->reg[MC_REGC * 4] & MC_REGC_UF ||
140 d->reg[MC_REGC * 4] & MC_REGC_AF ||
141 d->reg[MC_REGC * 4] & MC_REGC_PF)
142 d->reg[MC_REGC * 4] |= MC_REGC_IRQF;
143 }
144
145
146 /*
147 * dev_mc146818_jazz_access():
148 *
149 * It seems like JAZZ machines accesses the mc146818 by writing one byte to
150 * 0x90000070 and then reading or writing another byte at 0x......0004000.
151 */
DEVICE_ACCESS(mc146818_jazz)152 DEVICE_ACCESS(mc146818_jazz)
153 {
154 struct mc_data *d = (struct mc_data *) extra;
155
156 #ifdef MC146818_DEBUG
157 if (writeflag == MEM_WRITE) {
158 int i;
159 fatal("[ mc146818_jazz: write to addr=0x%04x: ",
160 (int)relative_addr);
161 for (i=0; i<len; i++)
162 fatal("%02x ", data[i]);
163 fatal("]\n");
164 } else
165 fatal("[ mc146818_jazz: read from addr=0x%04x ]\n",
166 (int)relative_addr);
167 #endif
168
169 if (writeflag == MEM_WRITE) {
170 d->last_addr = data[0];
171 return 1;
172 } else {
173 data[0] = d->last_addr;
174 return 1;
175 }
176 }
177
178
179 /*
180 * mc146818_update_time():
181 *
182 * This function updates the MC146818 registers by reading
183 * the host's clock.
184 */
mc146818_update_time(struct mc_data * d)185 static void mc146818_update_time(struct mc_data *d)
186 {
187 struct tm *tmp;
188 time_t timet;
189
190 timet = time(NULL);
191 tmp = gmtime(&timet);
192
193 d->reg[4 * MC_SEC] = tmp->tm_sec;
194 d->reg[4 * MC_MIN] = tmp->tm_min;
195 d->reg[4 * MC_HOUR] = tmp->tm_hour;
196 d->reg[4 * MC_DOW] = tmp->tm_wday + 1;
197 d->reg[4 * MC_DOM] = tmp->tm_mday;
198 d->reg[4 * MC_MONTH] = tmp->tm_mon + 1;
199 d->reg[4 * MC_YEAR] = tmp->tm_year;
200
201 /*
202 * Special hacks for emulating the behaviour of various machines:
203 */
204 switch (d->access_style) {
205 case MC146818_ALGOR:
206 /*
207 * NetBSD/evbmips sources indicate that the Algor year base
208 * is 1920. This makes the time work with NetBSD in Malta
209 * emulation. However, for Linux, commenting out this line
210 * works better. (TODO: Find a way to make both work?)
211 */
212 d->reg[4 * MC_YEAR] += 80;
213 break;
214 case MC146818_ARC_NEC:
215 d->reg[4 * MC_YEAR] += (0x18 - 104);
216 break;
217 case MC146818_CATS:
218 d->reg[4 * MC_YEAR] %= 100;
219 break;
220 case MC146818_SGI:
221 /*
222 * NetBSD/sgimips assumes data in BCD format.
223 * Also, IRIX stores the year value in a weird
224 * format, according to ../arch/sgimips/sgimips/clockvar.h
225 * in NetBSD:
226 *
227 * "If year < 1985, store (year - 1970), else
228 * (year - 1940). This matches IRIX semantics."
229 *
230 * Another rule: It seems that a real SGI IP32 box
231 * uses the value 5 for the year 2005.
232 */
233 d->reg[4 * MC_YEAR] =
234 d->reg[4 * MC_YEAR] >= 100 ?
235 (d->reg[4 * MC_YEAR] - 100) :
236 (
237 d->reg[4 * MC_YEAR] < 85 ?
238 (d->reg[4 * MC_YEAR] - 30 + 40)
239 : (d->reg[4 * MC_YEAR] - 40)
240 );
241 /* Century: */
242 d->reg[72 * 4] = 19 + (tmp->tm_year / 100);
243 break;
244 case MC146818_DEC:
245 /*
246 * DECstations must have 72 or 73 in the
247 * Year field, or Ultrix screems. (Weird.)
248 */
249 d->reg[4 * MC_YEAR] = 72;
250
251 /*
252 * Linux on DECstation stores the year in register 63,
253 * but no other DECstation OS does? (Hm.)
254 */
255 d->reg[4 * 63] = tmp->tm_year - 100;
256 break;
257 }
258
259 if (d->use_bcd) {
260 d->reg[4 * MC_SEC] = to_bcd(d->reg[4 * MC_SEC]);
261 d->reg[4 * MC_MIN] = to_bcd(d->reg[4 * MC_MIN]);
262 d->reg[4 * MC_HOUR] = to_bcd(d->reg[4 * MC_HOUR]);
263 d->reg[4 * MC_DOW] = to_bcd(d->reg[4 * MC_DOW]);
264 d->reg[4 * MC_DOM] = to_bcd(d->reg[4 * MC_DOM]);
265 d->reg[4 * MC_MONTH] = to_bcd(d->reg[4 * MC_MONTH]);
266 d->reg[4 * MC_YEAR] = to_bcd(d->reg[4 * MC_YEAR]);
267
268 /* Used by Linux on DECstation: (Hm) */
269 d->reg[4 * 63] = to_bcd(d->reg[4 * 63]);
270
271 /* Used on SGI: */
272 d->reg[4 * 72] = to_bcd(d->reg[4 * 72]);
273 }
274 }
275
276
DEVICE_ACCESS(mc146818)277 DEVICE_ACCESS(mc146818)
278 {
279 struct mc_data *d = (struct mc_data *) extra;
280 struct tm *tmp;
281 time_t timet;
282 size_t i;
283
284 /* NOTE/TODO: This access function only handles 8-bit accesses! */
285
286 relative_addr /= d->addrdiv;
287
288 /* Different ways of accessing the registers: */
289 switch (d->access_style) {
290 case MC146818_ALGOR:
291 case MC146818_CATS:
292 case MC146818_PC_CMOS:
293 if ((relative_addr & 1) == 0x00) {
294 if (writeflag == MEM_WRITE) {
295 d->last_addr = data[0];
296 return 1;
297 } else {
298 data[0] = d->last_addr;
299 return 1;
300 }
301 } else
302 relative_addr = d->last_addr * 4;
303 break;
304 case MC146818_ARC_NEC:
305 if (relative_addr == 0x01) {
306 if (writeflag == MEM_WRITE) {
307 d->last_addr = data[0];
308 return 1;
309 } else {
310 data[0] = d->last_addr;
311 return 1;
312 }
313 } else if (relative_addr == 0x00)
314 relative_addr = d->last_addr * 4;
315 else {
316 fatal("[ mc146818: not accessed as an "
317 "MC146818_ARC_NEC device! ]\n");
318 }
319 break;
320 case MC146818_ARC_JAZZ:
321 /* See comment for dev_mc146818_jazz_access(). */
322 relative_addr = d->last_addr * 4;
323 break;
324 case MC146818_DEC:
325 case MC146818_SGI:
326 /*
327 * This device was originally written for DECstation
328 * emulation, so no changes are necessary for that access
329 * style.
330 *
331 * SGI access bytes 0x0..0xd at offsets 0x0yz..0xdyz, where yz
332 * should be ignored. It works _almost_ as DEC, if offsets are
333 * divided by 0x40.
334 */
335 break;
336 case MC146818_PMPPC:
337 relative_addr *= 4;
338 break;
339 default:
340 ;
341 }
342
343 #ifdef MC146818_DEBUG
344 if (writeflag == MEM_WRITE) {
345 fatal("[ mc146818: write to addr=0x%04x (len %i): ",
346 (int)relative_addr, (int)len);
347 for (i=0; i<len; i++)
348 fatal("0x%02x ", data[i]);
349 fatal("]\n");
350 }
351 #endif
352
353 /*
354 * Sprite seems to wants UF interrupt status, once every second, or
355 * it hangs forever during bootup. (These do not cause interrupts,
356 * but it is good enough... Sprite polls this, iirc.)
357 *
358 * Linux on at least sgimips and evbmips (Malta) wants the UIP bit
359 * in REGA to be updated once a second.
360 */
361 if (relative_addr == MC_REGA*4 || relative_addr == MC_REGC*4) {
362 timet = time(NULL);
363 tmp = gmtime(&timet);
364 d->reg[MC_REGC * 4] &= ~MC_REGC_UF;
365 if (tmp->tm_sec != d->previous_second) {
366 d->n_seconds_elapsed ++;
367 d->previous_second = tmp->tm_sec;
368 }
369 if (d->n_seconds_elapsed > d->uip_threshold) {
370 d->n_seconds_elapsed = 0;
371
372 d->reg[MC_REGA * 4] |= MC_REGA_UIP;
373
374 d->reg[MC_REGC * 4] |= MC_REGC_UF;
375 d->reg[MC_REGC * 4] |= MC_REGC_IRQF;
376
377 /* For some reason, some Linux/DECstation KN04
378 kernels want the PF (periodic flag) bit set,
379 even though interrupts are not enabled? */
380 d->reg[MC_REGC * 4] |= MC_REGC_PF;
381 } else
382 d->reg[MC_REGA * 4] &= ~MC_REGA_UIP;
383 }
384
385 /* RTC data is in either BCD format or binary: */
386 if (d->use_bcd)
387 d->reg[MC_REGB * 4] &= ~(1 << 2);
388 else
389 d->reg[MC_REGB * 4] |= (1 << 2);
390
391 /* RTC date/time is always Valid: */
392 d->reg[MC_REGD * 4] |= MC_REGD_VRT;
393
394 if (writeflag == MEM_WRITE) {
395 /* WRITE: */
396 switch (relative_addr) {
397 case MC_REGA*4:
398 if ((data[0] & MC_REGA_DVMASK) == MC_BASE_32_KHz)
399 d->timebase_hz = 32000;
400 if ((data[0] & MC_REGA_DVMASK) == MC_BASE_1_MHz)
401 d->timebase_hz = 1000000;
402 if ((data[0] & MC_REGA_DVMASK) == MC_BASE_4_MHz)
403 d->timebase_hz = 4000000;
404 switch (data[0] & MC_REGA_RSMASK) {
405 case MC_RATE_NONE:
406 d->interrupt_hz = 0;
407 break;
408 case MC_RATE_1:
409 if (d->timebase_hz == 32000)
410 d->interrupt_hz = 256;
411 else
412 d->interrupt_hz = 32768;
413 break;
414 case MC_RATE_2:
415 if (d->timebase_hz == 32000)
416 d->interrupt_hz = 128;
417 else
418 d->interrupt_hz = 16384;
419 break;
420 case MC_RATE_8192_Hz: d->interrupt_hz = 8192; break;
421 case MC_RATE_4096_Hz: d->interrupt_hz = 4096; break;
422 case MC_RATE_2048_Hz: d->interrupt_hz = 2048; break;
423 case MC_RATE_1024_Hz: d->interrupt_hz = 1024; break;
424 case MC_RATE_512_Hz: d->interrupt_hz = 512; break;
425 case MC_RATE_256_Hz: d->interrupt_hz = 256; break;
426 case MC_RATE_128_Hz: d->interrupt_hz = 128; break;
427 case MC_RATE_64_Hz: d->interrupt_hz = 64; break;
428 case MC_RATE_32_Hz: d->interrupt_hz = 32; break;
429 case MC_RATE_16_Hz: d->interrupt_hz = 16; break;
430 case MC_RATE_8_Hz: d->interrupt_hz = 8; break;
431 case MC_RATE_4_Hz: d->interrupt_hz = 4; break;
432 case MC_RATE_2_Hz: d->interrupt_hz = 2; break;
433 default:/* debug("[ mc146818: unimplemented "
434 "MC_REGA RS: %i ]\n",
435 data[0] & MC_REGA_RSMASK); */
436 ;
437 }
438
439 if (d->interrupt_hz != d->old_interrupt_hz) {
440 debug("[ rtc changed to interrupt at %i Hz ]\n",
441 d->interrupt_hz);
442
443 d->old_interrupt_hz = d->interrupt_hz;
444
445 if (d->timer == NULL)
446 d->timer = timer_add(d->interrupt_hz,
447 timer_tick, d);
448 else
449 timer_update_frequency(d->timer,
450 d->interrupt_hz);
451 }
452
453 d->reg[MC_REGA * 4] =
454 data[0] & (MC_REGA_RSMASK | MC_REGA_DVMASK);
455 break;
456 case MC_REGB*4:
457 d->reg[MC_REGB*4] = data[0];
458 if (!(data[0] & MC_REGB_PIE)) {
459 INTERRUPT_DEASSERT(d->irq);
460 }
461
462 /* debug("[ mc146818: write to MC_REGB, data[0] "
463 "= 0x%02x ]\n", data[0]); */
464 break;
465 case MC_REGC*4:
466 d->reg[MC_REGC * 4] = data[0];
467 debug("[ mc146818: write to MC_REGC, data[0] = "
468 "0x%02x ]\n", data[0]);
469 break;
470 case 0x128:
471 d->reg[relative_addr] = data[0];
472 if (data[0] & 8) {
473 int j;
474
475 /* Used on SGI to power off the machine. */
476 fatal("[ md146818: power off ]\n");
477 for (j=0; j<cpu->machine->ncpus; j++)
478 cpu->machine->cpus[j]->running = 0;
479 cpu->machine->
480 exit_without_entering_debugger = 1;
481 }
482 break;
483 default:
484 d->reg[relative_addr] = data[0];
485
486 debug("[ mc146818: unimplemented write to "
487 "relative_addr = %08lx: ", (long)relative_addr);
488 for (i=0; i<len; i++)
489 debug("%02x ", data[i]);
490 debug("]\n");
491 }
492 } else {
493 /* READ: */
494 switch (relative_addr) {
495 case 0x01: /* Station's ethernet address (6 bytes) */
496 case 0x05: /* (on DECstation 3100) */
497 case 0x09:
498 case 0x0d:
499 case 0x11:
500 case 0x15:
501 break;
502 case 4 * MC_SEC:
503 if (d->ugly_netbsd_prep_hack_done < NETBSD_HACK_DONE) {
504 d->ugly_netbsd_prep_hack_done ++;
505 switch (d->ugly_netbsd_prep_hack_done) {
506 case NETBSD_HACK_FIRST_1:
507 d->ugly_netbsd_prep_hack_sec =
508 from_bcd(d->reg[relative_addr]);
509 break;
510 case NETBSD_HACK_FIRST_2:
511 d->reg[relative_addr] = to_bcd(
512 d->ugly_netbsd_prep_hack_sec);
513 break;
514 case NETBSD_HACK_SECOND_1:
515 case NETBSD_HACK_SECOND_2:
516 d->reg[relative_addr] = to_bcd((1 +
517 d->ugly_netbsd_prep_hack_sec) % 60);
518 break;
519 }
520 }
521 // fall through
522 case 4 * MC_MIN:
523 case 4 * MC_HOUR:
524 case 4 * MC_DOW:
525 case 4 * MC_DOM:
526 case 4 * MC_MONTH:
527 case 4 * MC_YEAR:
528 case 4 * 63: /* 63 is used by Linux on DECstation */
529 case 4 * 72: /* 72 is Century, on SGI (DS1687) */
530 /*
531 * If the SET bit is set, then we don't automatically
532 * update the values. Otherwise, we update them by
533 * reading from the host's clock:
534 */
535 if (d->reg[MC_REGB * 4] & MC_REGB_SET)
536 break;
537
538 if (d->ugly_netbsd_prep_hack_done >= NETBSD_HACK_DONE)
539 mc146818_update_time(d);
540 break;
541 case 4 * MC_REGA:
542 break;
543 case 4 * MC_REGC: /* Interrupt ack. */
544 /* NOTE: Acking is done below, _after_ the
545 register has been read. */
546 break;
547 default:debug("[ mc146818: read from relative_addr = "
548 "%04x ]\n", (int)relative_addr);
549 }
550
551 data[0] = d->reg[relative_addr];
552
553 if (relative_addr == MC_REGC*4) {
554 INTERRUPT_DEASSERT(d->irq);
555
556 /*
557 * Acknowledging an interrupt decreases the
558 * number of pending "real world" timer ticks.
559 */
560 if (d->reg[MC_REGC * 4] & MC_REGC_PF &&
561 d->pending_timer_interrupts > 0)
562 d->pending_timer_interrupts --;
563
564 d->reg[MC_REGC * 4] = 0x00;
565 }
566 }
567
568 #ifdef MC146818_DEBUG
569 if (writeflag == MEM_READ) {
570 fatal("[ mc146818: read from addr=0x%04x (len %i): ",
571 (int)relative_addr, (int)len);
572 for (i=0; i<len; i++)
573 fatal("0x%02x ", data[i]);
574 fatal("]\n");
575 }
576 #endif
577
578 return 1;
579 }
580
581
582 /*
583 * dev_mc146818_init():
584 *
585 * This needs to work for both DECstation emulation and other machine types,
586 * so it contains both rtc related stuff and the station's Ethernet address.
587 */
dev_mc146818_init(struct machine * machine,struct memory * mem,uint64_t baseaddr,char * irq_path,int access_style,int addrdiv)588 void dev_mc146818_init(struct machine *machine, struct memory *mem,
589 uint64_t baseaddr, char *irq_path, int access_style, int addrdiv)
590 {
591 unsigned char ether_address[6];
592 int i, dev_len;
593 struct mc_data *d;
594
595 CHECK_ALLOCATION(d = (struct mc_data *) malloc(sizeof(struct mc_data)));
596 memset(d, 0, sizeof(struct mc_data));
597
598 d->access_style = access_style;
599 d->addrdiv = addrdiv;
600
601 INTERRUPT_CONNECT(irq_path, d->irq);
602
603 d->use_bcd = 0;
604 switch (access_style) {
605 case MC146818_SGI:
606 case MC146818_PC_CMOS:
607 case MC146818_PMPPC:
608 d->use_bcd = 1;
609 }
610
611 if (machine->machine_type != MACHINE_PREP) {
612 /* NetBSD/prep has a really ugly clock detection code;
613 no other machines/OSes don't need this. */
614 d->ugly_netbsd_prep_hack_done = NETBSD_HACK_DONE;
615 }
616
617 if (access_style == MC146818_DEC) {
618 /* Station Ethernet Address, on DECstation 3100: */
619 for (i=0; i<6; i++)
620 ether_address[i] = 0x10 * (i+1);
621
622 d->reg[0x01] = ether_address[0];
623 d->reg[0x05] = ether_address[1];
624 d->reg[0x09] = ether_address[2];
625 d->reg[0x0d] = ether_address[3];
626 d->reg[0x11] = ether_address[4];
627 d->reg[0x15] = ether_address[5];
628 /* TODO: 19, 1d, 21, 25 = checksum bytes 1,2,2,1 resp. */
629 d->reg[0x29] = ether_address[5];
630 d->reg[0x2d] = ether_address[4];
631 d->reg[0x31] = ether_address[3];
632 d->reg[0x35] = ether_address[2];
633 d->reg[0x39] = ether_address[1];
634 d->reg[0x3d] = ether_address[1];
635 d->reg[0x41] = ether_address[0];
636 d->reg[0x45] = ether_address[1];
637 d->reg[0x49] = ether_address[2];
638 d->reg[0x4d] = ether_address[3];
639 d->reg[0x51] = ether_address[4];
640 d->reg[0x55] = ether_address[5];
641 /* TODO: 59, 5d = checksum bytes 1,2 resp. */
642 d->reg[0x61] = 0xff;
643 d->reg[0x65] = 0x00;
644 d->reg[0x69] = 0x55;
645 d->reg[0x6d] = 0xaa;
646 d->reg[0x71] = 0xff;
647 d->reg[0x75] = 0x00;
648 d->reg[0x79] = 0x55;
649 d->reg[0x7d] = 0xaa;
650
651 /* Battery valid, for DECstations */
652 d->reg[0xf8] = 1;
653 }
654
655 /*
656 * uip_threshold should ideally be 1, but when Linux polls the UIP bit
657 * it looses speed. This hack gives Linux the impression that the cpu
658 * is uip_threshold times faster than the slow clock it would
659 * otherwise detect.
660 *
661 * TODO: Find out if this messes up Sprite emulation; if so, then
662 * this hack has to be removed.
663 */
664 d->uip_threshold = 8;
665
666 if (access_style == MC146818_ARC_JAZZ)
667 memory_device_register(mem, "mc146818_jazz", 0x90000070ULL,
668 1, dev_mc146818_jazz_access, d, DM_DEFAULT, NULL);
669
670 dev_len = DEV_MC146818_LENGTH;
671 switch (access_style) {
672 case MC146818_CATS:
673 case MC146818_PC_CMOS:
674 dev_len = 2;
675 break;
676 case MC146818_SGI:
677 dev_len = 0x400;
678 }
679
680 memory_device_register(mem, "mc146818", baseaddr,
681 dev_len * addrdiv, dev_mc146818_access,
682 d, DM_DEFAULT, NULL);
683
684 mc146818_update_time(d);
685
686 machine_add_tickfunction(machine, dev_mc146818_tick, d,
687 MC146818_TICK_SHIFT);
688 }
689
690