/[gxemul]/upstream/0.3.6/src/devices/dev_mc146818.c
This is repository of my old source code which isn't updated any more. Go to git.rot13.org for current projects!
ViewVC logotype

Contents of /upstream/0.3.6/src/devices/dev_mc146818.c

Parent Directory Parent Directory | Revision Log Revision Log


Revision 15 - (show annotations)
Mon Oct 8 16:18:56 2007 UTC (16 years, 8 months ago) by dpavlin
File MIME type: text/plain
File size: 17838 byte(s)
0.3.6
1 /*
2 * Copyright (C) 2003-2005 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 * $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.
31 * (DS1687 as used in some SGI machines is similar to MC146818.)
32 *
33 * This device contains Date/time, the machine's ethernet address (on
34 * DECstation 3100), and can cause periodic (hardware) interrupts.
35 *
36 * NOTE: Many register offsets are multiplied by 4 in this code; this is
37 * because I originally wrote it for DECstation 3100 emulation, where the
38 * registered are spaced that way.
39 */
40
41 #include <stdio.h>
42 #include <stdlib.h>
43 #include <string.h>
44 #include <time.h>
45
46 #include "cpu.h"
47 #include "devices.h"
48 #include "machine.h"
49 #include "memory.h"
50 #include "misc.h"
51
52 #include "mc146818reg.h"
53
54
55 #define to_bcd(x) ( ((x)/10) * 16 + ((x)%10) )
56
57 /* #define MC146818_DEBUG */
58
59 #define TICK_SHIFT 14
60
61
62 /* 256 on DECstation, SGI uses reg at 72*4 as the Century */
63 #define N_REGISTERS 1024
64 struct mc_data {
65 int access_style;
66 int last_addr;
67
68 int register_choice;
69 int reg[N_REGISTERS];
70 int addrdiv;
71
72 int use_bcd;
73
74 int timebase_hz;
75 int interrupt_hz;
76 int irq_nr;
77
78 int previous_second;
79
80 int interrupt_every_x_cycles;
81 int cycles_left_until_interrupt;
82 };
83
84
85 /*
86 * recalc_interrupt_cycle():
87 *
88 * If automatic_clock_adjustment is turned on, then emulated_hz is modified
89 * dynamically. We have to recalculate how often interrupts are to be
90 * triggered.
91 */
92 static void recalc_interrupt_cycle(struct cpu *cpu, struct mc_data *d)
93 {
94 int64_t emulated_hz = cpu->machine->emulated_hz;
95 #if 0
96 static int warning_printed = 0;
97
98 /*
99 * A hack to make Ultrix run, even on very fast host machines.
100 *
101 * (Ultrix was probably never meant to be run on machines with
102 * faster CPUs than around 33 MHz or so.)
103 */
104 if (d->access_style == MC146818_DEC && emulated_hz > 30000000) {
105 if (!warning_printed) {
106 fatal("\n*********************************************"
107 "**********************************\n\n Your hos"
108 "t machine is too fast! The emulated CPU speed wil"
109 "l be limited to\n 30 MHz, and clocks inside the"
110 " emulated environment might go faster than\n in"
111 " the real world. You have been warned.\n\n******"
112 "*************************************************"
113 "************************\n\n");
114 warning_printed = 1;
115 }
116
117 emulated_hz = 30000000;
118 }
119 #endif
120
121 if (d->interrupt_hz > 0)
122 d->interrupt_every_x_cycles =
123 emulated_hz / d->interrupt_hz;
124 else
125 d->interrupt_every_x_cycles = 0;
126 }
127
128
129 /*
130 * dev_mc146818_tick():
131 */
132 void dev_mc146818_tick(struct cpu *cpu, void *extra)
133 {
134 struct mc_data *d = extra;
135
136 if (d == NULL)
137 return;
138
139 recalc_interrupt_cycle(cpu, d);
140
141 if ((d->reg[MC_REGB * 4] & MC_REGB_PIE) &&
142 d->interrupt_every_x_cycles > 0) {
143 d->cycles_left_until_interrupt -= (1 << TICK_SHIFT);
144
145 if (d->cycles_left_until_interrupt < 0 ||
146 d->cycles_left_until_interrupt >=
147 d->interrupt_every_x_cycles) {
148 /* debug("[ rtc interrupt (every %i cycles) ]\n",
149 d->interrupt_every_x_cycles); */
150 cpu_interrupt(cpu, d->irq_nr);
151
152 d->reg[MC_REGC * 4] |= MC_REGC_PF;
153
154 /* Reset the cycle countdown: */
155 while (d->cycles_left_until_interrupt < 0)
156 d->cycles_left_until_interrupt +=
157 d->interrupt_every_x_cycles;
158 }
159 }
160
161 if (d->reg[MC_REGC * 4] & MC_REGC_UF ||
162 d->reg[MC_REGC * 4] & MC_REGC_AF ||
163 d->reg[MC_REGC * 4] & MC_REGC_PF)
164 d->reg[MC_REGC * 4] |= MC_REGC_IRQF;
165 }
166
167
168 /*
169 * dev_mc146818_jazz_access():
170 *
171 * It seems like JAZZ machines accesses the mc146818 by writing one byte to
172 * 0x90000070 and then reading or writing another byte at 0x......0004000.
173 */
174 int dev_mc146818_jazz_access(struct cpu *cpu, struct memory *mem,
175 uint64_t relative_addr, unsigned char *data, size_t len,
176 int writeflag, void *extra)
177 {
178 struct mc_data *d = extra;
179
180 #ifdef MC146818_DEBUG
181 if (writeflag == MEM_WRITE) {
182 int i;
183 fatal("[ mc146818_jazz: write to addr=0x%04x: ",
184 (int)relative_addr);
185 for (i=0; i<len; i++)
186 fatal("%02x ", data[i]);
187 fatal("]\n");
188 } else
189 fatal("[ mc146818_jazz: read from addr=0x%04x ]\n",
190 (int)relative_addr);
191 #endif
192
193 if (writeflag == MEM_WRITE) {
194 d->last_addr = data[0];
195 return 1;
196 } else {
197 data[0] = d->last_addr;
198 return 1;
199 }
200 }
201
202
203 /*
204 * mc146818_update_time():
205 *
206 * This function updates the MC146818 registers by reading
207 * the host's clock.
208 */
209 static void mc146818_update_time(struct mc_data *d)
210 {
211 struct tm *tmp;
212 time_t timet;
213
214 timet = time(NULL);
215 tmp = gmtime(&timet);
216
217 d->reg[4 * MC_SEC] = tmp->tm_sec;
218 d->reg[4 * MC_MIN] = tmp->tm_min;
219 d->reg[4 * MC_HOUR] = tmp->tm_hour;
220 d->reg[4 * MC_DOW] = tmp->tm_wday + 1;
221 d->reg[4 * MC_DOM] = tmp->tm_mday;
222 d->reg[4 * MC_MONTH] = tmp->tm_mon + 1;
223 d->reg[4 * MC_YEAR] = tmp->tm_year;
224
225 switch (d->access_style) {
226 case MC146818_ARC_NEC:
227 d->reg[4 * MC_YEAR] += (0x18 - 104);
228 break;
229 case MC146818_SGI:
230 /*
231 * NetBSD/sgimips assumes data in BCD format.
232 * Also, IRIX stores the year value in a weird
233 * format, according to ../arch/sgimips/sgimips/clockvar.h
234 * in NetBSD:
235 *
236 * "If year < 1985, store (year - 1970), else
237 * (year - 1940). This matches IRIX semantics."
238 *
239 * Another rule: It seems that a real SGI IP32 box
240 * uses the value 5 for the year 2005.
241 */
242 d->reg[4 * MC_YEAR] =
243 d->reg[4 * MC_YEAR] >= 100 ?
244 (d->reg[4 * MC_YEAR] - 100) :
245 (
246 d->reg[4 * MC_YEAR] < 85 ?
247 (d->reg[4 * MC_YEAR] - 30 + 40)
248 : (d->reg[4 * MC_YEAR] - 40)
249 );
250
251 /* Century: */
252 d->reg[72 * 4] = 19 + (tmp->tm_year / 100);
253
254 break;
255 case MC146818_DEC:
256 /*
257 * DECstations must have 72 or 73 in the
258 * Year field, or Ultrix screems. (Weird.)
259 */
260 d->reg[4 * MC_YEAR] = 72;
261
262 /*
263 * Linux on DECstation stores the year in register 63,
264 * but no other DECstation OS does? (Hm.)
265 */
266 d->reg[4 * 63] = tmp->tm_year - 100;
267 break;
268 }
269
270 if (d->use_bcd) {
271 d->reg[4 * MC_SEC] = to_bcd(d->reg[4 * MC_SEC]);
272 d->reg[4 * MC_MIN] = to_bcd(d->reg[4 * MC_MIN]);
273 d->reg[4 * MC_HOUR] = to_bcd(d->reg[4 * MC_HOUR]);
274 d->reg[4 * MC_DOW] = to_bcd(d->reg[4 * MC_DOW]);
275 d->reg[4 * MC_DOM] = to_bcd(d->reg[4 * MC_DOM]);
276 d->reg[4 * MC_MONTH] = to_bcd(d->reg[4 * MC_MONTH]);
277 d->reg[4 * MC_YEAR] = to_bcd(d->reg[4 * MC_YEAR]);
278
279 /* Used by Linux on DECstation: (Hm) */
280 d->reg[4 * 63] = to_bcd(d->reg[4 * 63]);
281
282 /* Used on SGI: */
283 d->reg[4 * 72] = to_bcd(d->reg[4 * 72]);
284 }
285 }
286
287
288 /*
289 * dev_mc146818_access():
290 *
291 * TODO: This access function only handles 8-bit accesses!
292 */
293 int dev_mc146818_access(struct cpu *cpu, struct memory *mem,
294 uint64_t r, unsigned char *data, size_t len,
295 int writeflag, void *extra)
296 {
297 struct tm *tmp;
298 time_t timet;
299 struct mc_data *d = extra;
300 int i, relative_addr = r;
301
302 relative_addr /= d->addrdiv;
303
304 /* Different ways of accessing the registers: */
305 switch (d->access_style) {
306 case MC146818_PC_CMOS:
307 if (relative_addr == 0x70 || relative_addr == 0x00) {
308 if (writeflag == MEM_WRITE) {
309 d->last_addr = data[0];
310 return 1;
311 } else {
312 data[0] = d->last_addr;
313 return 1;
314 }
315 } else if (relative_addr == 0x71 || relative_addr == 0x01)
316 relative_addr = d->last_addr * 4;
317 else {
318 fatal("[ mc146818: not accessed as an "
319 "MC146818_PC_CMOS device! ]\n");
320 }
321 break;
322 case MC146818_ARC_NEC:
323 if (relative_addr == 0x01) {
324 if (writeflag == MEM_WRITE) {
325 d->last_addr = data[0];
326 return 1;
327 } else {
328 data[0] = d->last_addr;
329 return 1;
330 }
331 } else if (relative_addr == 0x00)
332 relative_addr = d->last_addr * 4;
333 else {
334 fatal("[ mc146818: not accessed as an "
335 "MC146818_ARC_NEC device! ]\n");
336 }
337 break;
338 case MC146818_ARC_JAZZ:
339 /* See comment for dev_mc146818_jazz_access(). */
340 relative_addr = d->last_addr * 4;
341 break;
342 case MC146818_DEC:
343 case MC146818_SGI:
344 /*
345 * This device was originally written for DECstation
346 * emulation, so no changes are necessary for that access
347 * style.
348 *
349 * SGI access bytes 0x0..0xd at offsets 0x0yz..0xdyz, where yz
350 * should be ignored. It works _almost_ as DEC, if offsets are
351 * divided by 0x40.
352 */
353 default:
354 ;
355 }
356
357 #ifdef MC146818_DEBUG
358 if (writeflag == MEM_WRITE) {
359 fatal("[ mc146818: write to addr=0x%04x (len %i): ",
360 (int)relative_addr, (int)len);
361 for (i=0; i<len; i++)
362 fatal("%02x ", data[i]);
363 fatal("]\n");
364 }
365 #endif
366
367 /*
368 * Sprite seems to wants UF interrupt status, once every second, or
369 * it hangs forever during bootup. (These do not cause interrupts,
370 * 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);
376 tmp = gmtime(&timet);
377 d->reg[MC_REGC * 4] &= ~MC_REGC_UF;
378
379 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;
383 d->reg[MC_REGC * 4] |= MC_REGC_IRQF;
384 d->previous_second = tmp->tm_sec;
385
386 /* For some reason, some Linux/DECstation KN04 kernels want
387 the PF (periodic flag) bit set, even though interrupts
388 are not enabled? */
389 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: */
394 if (d->use_bcd)
395 d->reg[MC_REGB * 4] &= ~(1 << 2);
396 else
397 d->reg[MC_REGB * 4] |= (1 << 2);
398
399 /* RTC date/time is always Valid: */
400 d->reg[MC_REGD * 4] |= MC_REGD_VRT;
401
402 if (writeflag == MEM_WRITE) {
403 /* WRITE: */
404 switch (relative_addr) {
405 case MC_REGA*4:
406 if ((data[0] & MC_REGA_DVMASK) == MC_BASE_32_KHz)
407 d->timebase_hz = 32000;
408 if ((data[0] & MC_REGA_DVMASK) == MC_BASE_1_MHz)
409 d->timebase_hz = 1000000;
410 if ((data[0] & MC_REGA_DVMASK) == MC_BASE_4_MHz)
411 d->timebase_hz = 4000000;
412 switch (data[0] & MC_REGA_RSMASK) {
413 case MC_RATE_NONE:
414 d->interrupt_hz = 0;
415 break;
416 case MC_RATE_1:
417 if (d->timebase_hz == 32000)
418 d->interrupt_hz = 256;
419 else
420 d->interrupt_hz = 32768;
421 break;
422 case MC_RATE_2:
423 if (d->timebase_hz == 32000)
424 d->interrupt_hz = 128;
425 else
426 d->interrupt_hz = 16384;
427 break;
428 case MC_RATE_8192_Hz: d->interrupt_hz = 8192; break;
429 case MC_RATE_4096_Hz: d->interrupt_hz = 4096; break;
430 case MC_RATE_2048_Hz: d->interrupt_hz = 2048; break;
431 case MC_RATE_1024_Hz: d->interrupt_hz = 1024; break;
432 case MC_RATE_512_Hz: d->interrupt_hz = 512; break;
433 case MC_RATE_256_Hz: d->interrupt_hz = 256; break;
434 case MC_RATE_128_Hz: d->interrupt_hz = 128; break;
435 case MC_RATE_64_Hz: d->interrupt_hz = 64; break;
436 case MC_RATE_32_Hz: d->interrupt_hz = 32; break;
437 case MC_RATE_16_Hz: d->interrupt_hz = 16; break;
438 case MC_RATE_8_Hz: d->interrupt_hz = 8; break;
439 case MC_RATE_4_Hz: d->interrupt_hz = 4; break;
440 case MC_RATE_2_Hz: d->interrupt_hz = 2; break;
441 default:
442 /* debug("[ mc146818: unimplemented "
443 "MC_REGA RS: %i ]\n",
444 data[0] & MC_REGA_RSMASK); */
445 ;
446 }
447
448 recalc_interrupt_cycle(cpu, d);
449
450 d->cycles_left_until_interrupt =
451 d->interrupt_every_x_cycles;
452
453 d->reg[MC_REGA * 4] =
454 data[0] & (MC_REGA_RSMASK | MC_REGA_DVMASK);
455
456 debug("[ rtc set to interrupt every %i:th cycle ]\n",
457 d->interrupt_every_x_cycles);
458 break;
459 case MC_REGB*4:
460 if (((data[0] ^ d->reg[MC_REGB*4]) & MC_REGB_PIE))
461 d->cycles_left_until_interrupt =
462 d->interrupt_every_x_cycles;
463 d->reg[MC_REGB*4] = data[0];
464 if (!(data[0] & MC_REGB_PIE)) {
465 cpu_interrupt_ack(cpu, d->irq_nr);
466 /* d->cycles_left_until_interrupt =
467 d->interrupt_every_x_cycles; */
468 }
469 /* debug("[ mc146818: write to MC_REGB, data[0] "
470 "= 0x%02x ]\n", data[0]); */
471 break;
472 case MC_REGC*4:
473 d->reg[MC_REGC * 4] = data[0];
474 debug("[ mc146818: write to MC_REGC, data[0] = "
475 "0x%02x ]\n", data[0]);
476 break;
477 case 0x128:
478 d->reg[relative_addr] = data[0];
479 if (data[0] & 8) {
480 /* Used on SGI to power off the machine. */
481 fatal("[ md146818: power off ]\n");
482 for (i=0; i<cpu->machine->ncpus; i++)
483 cpu->machine->cpus[i]->running = 0;
484 cpu->machine->
485 exit_without_entering_debugger = 1;
486 }
487 break;
488 default:
489 d->reg[relative_addr] = data[0];
490
491 debug("[ mc146818: unimplemented write to "
492 "relative_addr = %08lx: ", (long)relative_addr);
493 for (i=0; i<len; i++)
494 debug("%02x ", data[i]);
495 debug("]\n");
496 }
497 } else {
498 /* READ: */
499 switch (relative_addr) {
500 case 0x01: /* Station's ethernet address (6 bytes) */
501 case 0x05: /* (on DECstation 3100) */
502 case 0x09:
503 case 0x0d:
504 case 0x11:
505 case 0x15:
506 break;
507 case 4 * MC_SEC:
508 case 4 * MC_MIN:
509 case 4 * MC_HOUR:
510 case 4 * MC_DOW:
511 case 4 * MC_DOM:
512 case 4 * MC_MONTH:
513 case 4 * MC_YEAR:
514 case 4 * 63: /* 63 is used by Linux on DECstation */
515 case 4 * 72: /* 72 is Century, on SGI (DS1687) */
516 /*
517 * If the SET bit is set, then we don't automatically
518 * update the values. Otherwise, we update them by
519 * reading from the host's clock:
520 */
521 if (d->reg[MC_REGB * 4] & MC_REGB_SET)
522 break;
523
524 mc146818_update_time(d);
525 break;
526 case 4 * MC_REGC: /* Interrupt ack. */
527 /* NOTE: Acking is done below, _after_ the
528 register has been read. */
529 break;
530 default:
531 debug("[ mc146818: read from relative_addr = "
532 "%04x ]\n", (int)relative_addr);
533 ;
534 }
535
536 data[0] = d->reg[relative_addr];
537
538 if (relative_addr == MC_REGC*4) {
539 cpu_interrupt_ack(cpu, d->irq_nr);
540 /* d->cycles_left_until_interrupt =
541 d->interrupt_every_x_cycles; */
542 d->reg[MC_REGC * 4] = 0x00;
543 }
544 }
545
546 #ifdef MC146818_DEBUG
547 if (writeflag == MEM_READ) {
548 fatal("[ mc146818: read from addr=0x%04x (len %i): ",
549 (int)relative_addr, (int)len);
550 for (i=0; i<len; i++)
551 fatal("%02x ", data[i]);
552 fatal("]\n");
553 }
554 #endif
555
556 return 1;
557 }
558
559
560 /*
561 * dev_mc146818_init():
562 *
563 * This needs to work for both DECstation emulation and other machine types,
564 * so it contains both rtc related stuff and the station's Ethernet address.
565 */
566 void dev_mc146818_init(struct machine *machine, struct memory *mem,
567 uint64_t baseaddr, int irq_nr, int access_style, int addrdiv)
568 {
569 unsigned char ether_address[6];
570 int i, dev_len;
571 struct mc_data *d;
572
573 d = malloc(sizeof(struct mc_data));
574 if (d == NULL) {
575 fprintf(stderr, "out of memory\n");
576 exit(1);
577 }
578
579 memset(d, 0, sizeof(struct mc_data));
580 d->irq_nr = irq_nr;
581 d->access_style = access_style;
582 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: */
591 for (i=0; i<6; i++)
592 ether_address[i] = 0x10 * (i+1);
593
594 d->reg[0x01] = ether_address[0];
595 d->reg[0x05] = ether_address[1];
596 d->reg[0x09] = ether_address[2];
597 d->reg[0x0d] = ether_address[3];
598 d->reg[0x11] = ether_address[4];
599 d->reg[0x15] = ether_address[5];
600 /* TODO: 19, 1d, 21, 25 = checksum bytes 1,2,2,1 resp. */
601 d->reg[0x29] = ether_address[5];
602 d->reg[0x2d] = ether_address[4];
603 d->reg[0x31] = ether_address[3];
604 d->reg[0x35] = ether_address[2];
605 d->reg[0x39] = ether_address[1];
606 d->reg[0x3d] = ether_address[1];
607 d->reg[0x41] = ether_address[0];
608 d->reg[0x45] = ether_address[1];
609 d->reg[0x49] = ether_address[2];
610 d->reg[0x4d] = ether_address[3];
611 d->reg[0x51] = ether_address[4];
612 d->reg[0x55] = ether_address[5];
613 /* TODO: 59, 5d = checksum bytes 1,2 resp. */
614 d->reg[0x61] = 0xff;
615 d->reg[0x65] = 0x00;
616 d->reg[0x69] = 0x55;
617 d->reg[0x6d] = 0xaa;
618 d->reg[0x71] = 0xff;
619 d->reg[0x75] = 0x00;
620 d->reg[0x79] = 0x55;
621 d->reg[0x7d] = 0xaa;
622
623 /* Battery valid, for DECstations */
624 d->reg[0xf8] = 1;
625 }
626
627 if (access_style == MC146818_ARC_JAZZ)
628 memory_device_register(mem, "mc146818_jazz", 0x90000070ULL,
629 1, dev_mc146818_jazz_access, d, MEM_DEFAULT, NULL);
630
631 dev_len = DEV_MC146818_LENGTH;
632 switch (access_style) {
633 case MC146818_PC_CMOS:
634 dev_len = 2;
635 break;
636 case MC146818_SGI:
637 dev_len = 0x400;
638 }
639
640 memory_device_register(mem, "mc146818", baseaddr,
641 dev_len * addrdiv, dev_mc146818_access,
642 d, MEM_DEFAULT, NULL);
643
644 mc146818_update_time(d);
645
646 machine_add_tickfunction(machine, dev_mc146818_tick, d, TICK_SHIFT);
647 }
648

  ViewVC Help
Powered by ViewVC 1.1.26