/[gxemul]/trunk/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

Annotation of /trunk/src/devices/dev_mc146818.c

Parent Directory Parent Directory | Revision Log Revision Log


Revision 16 - (hide annotations)
Mon Oct 8 16:19:01 2007 UTC (16 years, 6 months ago) by dpavlin
File MIME type: text/plain
File size: 17859 byte(s)
++ trunk/HISTORY	(local)
$Id: HISTORY,v 1.988 2005/10/11 03:53:57 debug Exp $

==============  RELEASE 0.3.6  ==============

20051008	The bug was not because of faulty ARM documentation after all,
		but it was related to those parts of the code.
		Fixing the RTC (dev_mc146818) to work with CATS.
20051009	Rewriting the R() function; now there are 8192 automatically
		generated smaller functions doing the same thing, but hopefully
		faster. This also fixes some bugs which were triggered when
		trying to compile GXemul inside itself. :-)
		Adding a dummy dev_lpt.
20051010	Small hack to not update virtual translation tables if memory
		accesses are done with the NO_EXCEPTION flag; a time reduction
		of almost a factor 2 for a full NetBSD/cats install. :-)
20051011	Passing -A as the default boot arg for CATS (works fine with
		OpenBSD/cats).

==============  RELEASE 0.3.6.1  ==============


1 dpavlin 4 /*
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 dpavlin 16 * $Id: dev_mc146818.c,v 1.75 2005/10/09 22:21:31 debug Exp $
29 dpavlin 4 *
30     * MC146818 real-time clock, used by many different machines types.
31 dpavlin 16 * (DS1687 as used in some other machines is also similar to the MC146818.)
32 dpavlin 4 *
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 dpavlin 12 #define TICK_SHIFT 14
60 dpavlin 4
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 dpavlin 12 d->cycles_left_until_interrupt -= (1 << TICK_SHIFT);
144 dpavlin 4
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 dpavlin 16 /*
226     * Special hacks for emulating the behaviour of various machines:
227     */
228 dpavlin 4 switch (d->access_style) {
229     case MC146818_ARC_NEC:
230     d->reg[4 * MC_YEAR] += (0x18 - 104);
231     break;
232 dpavlin 16 case MC146818_CATS:
233     d->reg[4 * MC_YEAR] %= 100;
234     break;
235 dpavlin 4 case MC146818_SGI:
236     /*
237     * NetBSD/sgimips assumes data in BCD format.
238     * Also, IRIX stores the year value in a weird
239     * format, according to ../arch/sgimips/sgimips/clockvar.h
240     * in NetBSD:
241     *
242     * "If year < 1985, store (year - 1970), else
243     * (year - 1940). This matches IRIX semantics."
244     *
245     * Another rule: It seems that a real SGI IP32 box
246     * uses the value 5 for the year 2005.
247     */
248     d->reg[4 * MC_YEAR] =
249     d->reg[4 * MC_YEAR] >= 100 ?
250     (d->reg[4 * MC_YEAR] - 100) :
251     (
252     d->reg[4 * MC_YEAR] < 85 ?
253     (d->reg[4 * MC_YEAR] - 30 + 40)
254     : (d->reg[4 * MC_YEAR] - 40)
255     );
256     /* Century: */
257     d->reg[72 * 4] = 19 + (tmp->tm_year / 100);
258     break;
259     case MC146818_DEC:
260     /*
261     * DECstations must have 72 or 73 in the
262     * Year field, or Ultrix screems. (Weird.)
263     */
264     d->reg[4 * MC_YEAR] = 72;
265    
266     /*
267     * Linux on DECstation stores the year in register 63,
268     * but no other DECstation OS does? (Hm.)
269     */
270     d->reg[4 * 63] = tmp->tm_year - 100;
271     break;
272     }
273    
274     if (d->use_bcd) {
275     d->reg[4 * MC_SEC] = to_bcd(d->reg[4 * MC_SEC]);
276     d->reg[4 * MC_MIN] = to_bcd(d->reg[4 * MC_MIN]);
277     d->reg[4 * MC_HOUR] = to_bcd(d->reg[4 * MC_HOUR]);
278     d->reg[4 * MC_DOW] = to_bcd(d->reg[4 * MC_DOW]);
279     d->reg[4 * MC_DOM] = to_bcd(d->reg[4 * MC_DOM]);
280     d->reg[4 * MC_MONTH] = to_bcd(d->reg[4 * MC_MONTH]);
281     d->reg[4 * MC_YEAR] = to_bcd(d->reg[4 * MC_YEAR]);
282    
283     /* Used by Linux on DECstation: (Hm) */
284     d->reg[4 * 63] = to_bcd(d->reg[4 * 63]);
285    
286     /* Used on SGI: */
287     d->reg[4 * 72] = to_bcd(d->reg[4 * 72]);
288     }
289     }
290    
291    
292     /*
293     * dev_mc146818_access():
294     *
295     * TODO: This access function only handles 8-bit accesses!
296     */
297     int dev_mc146818_access(struct cpu *cpu, struct memory *mem,
298     uint64_t r, unsigned char *data, size_t len,
299     int writeflag, void *extra)
300     {
301     struct tm *tmp;
302     time_t timet;
303     struct mc_data *d = extra;
304     int i, relative_addr = r;
305    
306     relative_addr /= d->addrdiv;
307    
308     /* Different ways of accessing the registers: */
309     switch (d->access_style) {
310 dpavlin 16 case MC146818_CATS:
311 dpavlin 4 case MC146818_PC_CMOS:
312 dpavlin 16 if ((relative_addr & 1) == 0x00) {
313 dpavlin 4 if (writeflag == MEM_WRITE) {
314     d->last_addr = data[0];
315     return 1;
316     } else {
317     data[0] = d->last_addr;
318     return 1;
319     }
320 dpavlin 16 } else
321 dpavlin 4 relative_addr = d->last_addr * 4;
322     break;
323     case MC146818_ARC_NEC:
324     if (relative_addr == 0x01) {
325     if (writeflag == MEM_WRITE) {
326     d->last_addr = data[0];
327     return 1;
328     } else {
329     data[0] = d->last_addr;
330     return 1;
331     }
332     } else if (relative_addr == 0x00)
333     relative_addr = d->last_addr * 4;
334     else {
335     fatal("[ mc146818: not accessed as an "
336     "MC146818_ARC_NEC device! ]\n");
337     }
338     break;
339     case MC146818_ARC_JAZZ:
340     /* See comment for dev_mc146818_jazz_access(). */
341     relative_addr = d->last_addr * 4;
342     break;
343     case MC146818_DEC:
344     case MC146818_SGI:
345     /*
346     * This device was originally written for DECstation
347     * emulation, so no changes are necessary for that access
348     * style.
349     *
350     * SGI access bytes 0x0..0xd at offsets 0x0yz..0xdyz, where yz
351     * should be ignored. It works _almost_ as DEC, if offsets are
352     * divided by 0x40.
353     */
354     default:
355     ;
356     }
357    
358     #ifdef MC146818_DEBUG
359     if (writeflag == MEM_WRITE) {
360     fatal("[ mc146818: write to addr=0x%04x (len %i): ",
361     (int)relative_addr, (int)len);
362     for (i=0; i<len; i++)
363     fatal("%02x ", data[i]);
364     fatal("]\n");
365     }
366     #endif
367    
368     /*
369 dpavlin 12 * Sprite seems to wants UF interrupt status, once every second, or
370 dpavlin 4 * it hangs forever during bootup. (These do not cause interrupts,
371     * but it is good enough... Sprite polls this, iirc.)
372 dpavlin 12 *
373     * Linux on at least sgimips and evbmips (Malta) wants the UIP bit
374     * in REGA to be updated once a second.
375 dpavlin 4 */
376     timet = time(NULL);
377     tmp = gmtime(&timet);
378     d->reg[MC_REGC * 4] &= ~MC_REGC_UF;
379 dpavlin 12
380 dpavlin 4 if (tmp->tm_sec != d->previous_second) {
381 dpavlin 12 d->reg[MC_REGA * 4] &= ~MC_REGA_UIP;
382    
383 dpavlin 4 d->reg[MC_REGC * 4] |= MC_REGC_UF;
384     d->reg[MC_REGC * 4] |= MC_REGC_IRQF;
385     d->previous_second = tmp->tm_sec;
386    
387     /* For some reason, some Linux/DECstation KN04 kernels want
388     the PF (periodic flag) bit set, even though interrupts
389     are not enabled? */
390     d->reg[MC_REGC * 4] |= MC_REGC_PF;
391 dpavlin 12 } else
392     d->reg[MC_REGA * 4] |= MC_REGA_UIP;
393 dpavlin 4
394     /* RTC data is in either BCD format or binary: */
395 dpavlin 12 if (d->use_bcd)
396 dpavlin 4 d->reg[MC_REGB * 4] &= ~(1 << 2);
397 dpavlin 12 else
398 dpavlin 4 d->reg[MC_REGB * 4] |= (1 << 2);
399    
400     /* RTC date/time is always Valid: */
401     d->reg[MC_REGD * 4] |= MC_REGD_VRT;
402    
403     if (writeflag == MEM_WRITE) {
404     /* WRITE: */
405     switch (relative_addr) {
406     case MC_REGA*4:
407     if ((data[0] & MC_REGA_DVMASK) == MC_BASE_32_KHz)
408     d->timebase_hz = 32000;
409     if ((data[0] & MC_REGA_DVMASK) == MC_BASE_1_MHz)
410     d->timebase_hz = 1000000;
411     if ((data[0] & MC_REGA_DVMASK) == MC_BASE_4_MHz)
412     d->timebase_hz = 4000000;
413     switch (data[0] & MC_REGA_RSMASK) {
414     case MC_RATE_NONE:
415     d->interrupt_hz = 0;
416     break;
417     case MC_RATE_1:
418     if (d->timebase_hz == 32000)
419     d->interrupt_hz = 256;
420     else
421     d->interrupt_hz = 32768;
422     break;
423     case MC_RATE_2:
424     if (d->timebase_hz == 32000)
425     d->interrupt_hz = 128;
426     else
427     d->interrupt_hz = 16384;
428     break;
429     case MC_RATE_8192_Hz: d->interrupt_hz = 8192; break;
430     case MC_RATE_4096_Hz: d->interrupt_hz = 4096; break;
431     case MC_RATE_2048_Hz: d->interrupt_hz = 2048; break;
432     case MC_RATE_1024_Hz: d->interrupt_hz = 1024; break;
433     case MC_RATE_512_Hz: d->interrupt_hz = 512; break;
434     case MC_RATE_256_Hz: d->interrupt_hz = 256; break;
435     case MC_RATE_128_Hz: d->interrupt_hz = 128; break;
436     case MC_RATE_64_Hz: d->interrupt_hz = 64; break;
437     case MC_RATE_32_Hz: d->interrupt_hz = 32; break;
438     case MC_RATE_16_Hz: d->interrupt_hz = 16; break;
439     case MC_RATE_8_Hz: d->interrupt_hz = 8; break;
440     case MC_RATE_4_Hz: d->interrupt_hz = 4; break;
441     case MC_RATE_2_Hz: d->interrupt_hz = 2; break;
442     default:
443     /* debug("[ mc146818: unimplemented "
444     "MC_REGA RS: %i ]\n",
445     data[0] & MC_REGA_RSMASK); */
446     ;
447     }
448    
449     recalc_interrupt_cycle(cpu, d);
450    
451     d->cycles_left_until_interrupt =
452     d->interrupt_every_x_cycles;
453    
454     d->reg[MC_REGA * 4] =
455     data[0] & (MC_REGA_RSMASK | MC_REGA_DVMASK);
456    
457     debug("[ rtc set to interrupt every %i:th cycle ]\n",
458     d->interrupt_every_x_cycles);
459     break;
460     case MC_REGB*4:
461     if (((data[0] ^ d->reg[MC_REGB*4]) & MC_REGB_PIE))
462     d->cycles_left_until_interrupt =
463     d->interrupt_every_x_cycles;
464     d->reg[MC_REGB*4] = data[0];
465     if (!(data[0] & MC_REGB_PIE)) {
466     cpu_interrupt_ack(cpu, d->irq_nr);
467     /* d->cycles_left_until_interrupt =
468     d->interrupt_every_x_cycles; */
469     }
470     /* debug("[ mc146818: write to MC_REGB, data[0] "
471     "= 0x%02x ]\n", data[0]); */
472     break;
473     case MC_REGC*4:
474     d->reg[MC_REGC * 4] = data[0];
475     debug("[ mc146818: write to MC_REGC, data[0] = "
476     "0x%02x ]\n", data[0]);
477     break;
478     case 0x128:
479     d->reg[relative_addr] = data[0];
480     if (data[0] & 8) {
481     /* Used on SGI to power off the machine. */
482     fatal("[ md146818: power off ]\n");
483     for (i=0; i<cpu->machine->ncpus; i++)
484     cpu->machine->cpus[i]->running = 0;
485     cpu->machine->
486     exit_without_entering_debugger = 1;
487     }
488     break;
489     default:
490     d->reg[relative_addr] = data[0];
491    
492     debug("[ mc146818: unimplemented write to "
493     "relative_addr = %08lx: ", (long)relative_addr);
494     for (i=0; i<len; i++)
495     debug("%02x ", data[i]);
496     debug("]\n");
497     }
498     } else {
499     /* READ: */
500     switch (relative_addr) {
501     case 0x01: /* Station's ethernet address (6 bytes) */
502     case 0x05: /* (on DECstation 3100) */
503     case 0x09:
504     case 0x0d:
505     case 0x11:
506     case 0x15:
507     break;
508     case 4 * MC_SEC:
509     case 4 * MC_MIN:
510     case 4 * MC_HOUR:
511     case 4 * MC_DOW:
512     case 4 * MC_DOM:
513     case 4 * MC_MONTH:
514     case 4 * MC_YEAR:
515     case 4 * 63: /* 63 is used by Linux on DECstation */
516     case 4 * 72: /* 72 is Century, on SGI (DS1687) */
517     /*
518     * If the SET bit is set, then we don't automatically
519     * update the values. Otherwise, we update them by
520     * reading from the host's clock:
521     */
522     if (d->reg[MC_REGB * 4] & MC_REGB_SET)
523     break;
524    
525     mc146818_update_time(d);
526     break;
527     case 4 * MC_REGC: /* Interrupt ack. */
528     /* NOTE: Acking is done below, _after_ the
529     register has been read. */
530     break;
531     default:
532     debug("[ mc146818: read from relative_addr = "
533     "%04x ]\n", (int)relative_addr);
534     ;
535     }
536    
537     data[0] = d->reg[relative_addr];
538    
539     if (relative_addr == MC_REGC*4) {
540     cpu_interrupt_ack(cpu, d->irq_nr);
541     /* d->cycles_left_until_interrupt =
542     d->interrupt_every_x_cycles; */
543     d->reg[MC_REGC * 4] = 0x00;
544     }
545     }
546    
547     #ifdef MC146818_DEBUG
548     if (writeflag == MEM_READ) {
549     fatal("[ mc146818: read from addr=0x%04x (len %i): ",
550     (int)relative_addr, (int)len);
551     for (i=0; i<len; i++)
552     fatal("%02x ", data[i]);
553     fatal("]\n");
554     }
555     #endif
556    
557     return 1;
558     }
559    
560    
561     /*
562     * dev_mc146818_init():
563     *
564     * This needs to work for both DECstation emulation and other machine types,
565     * so it contains both rtc related stuff and the station's Ethernet address.
566     */
567     void dev_mc146818_init(struct machine *machine, struct memory *mem,
568     uint64_t baseaddr, int irq_nr, int access_style, int addrdiv)
569     {
570     unsigned char ether_address[6];
571     int i, dev_len;
572     struct mc_data *d;
573    
574     d = malloc(sizeof(struct mc_data));
575     if (d == NULL) {
576     fprintf(stderr, "out of memory\n");
577     exit(1);
578     }
579    
580     memset(d, 0, sizeof(struct mc_data));
581     d->irq_nr = irq_nr;
582     d->access_style = access_style;
583     d->addrdiv = addrdiv;
584    
585 dpavlin 6 /* Only SGIs and PCs use BCD format (?) */
586     d->use_bcd = 0;
587     if (access_style == MC146818_SGI || access_style == MC146818_PC_CMOS)
588     d->use_bcd = 1;
589    
590     if (access_style == MC146818_DEC) {
591 dpavlin 4 /* Station Ethernet Address, on DECstation 3100: */
592     for (i=0; i<6; i++)
593     ether_address[i] = 0x10 * (i+1);
594    
595 dpavlin 6 d->reg[0x01] = ether_address[0];
596     d->reg[0x05] = ether_address[1];
597     d->reg[0x09] = ether_address[2];
598     d->reg[0x0d] = ether_address[3];
599     d->reg[0x11] = ether_address[4];
600     d->reg[0x15] = ether_address[5];
601     /* TODO: 19, 1d, 21, 25 = checksum bytes 1,2,2,1 resp. */
602     d->reg[0x29] = ether_address[5];
603     d->reg[0x2d] = ether_address[4];
604     d->reg[0x31] = ether_address[3];
605     d->reg[0x35] = ether_address[2];
606     d->reg[0x39] = ether_address[1];
607     d->reg[0x3d] = ether_address[1];
608     d->reg[0x41] = ether_address[0];
609     d->reg[0x45] = ether_address[1];
610     d->reg[0x49] = ether_address[2];
611     d->reg[0x4d] = ether_address[3];
612     d->reg[0x51] = ether_address[4];
613     d->reg[0x55] = ether_address[5];
614     /* TODO: 59, 5d = checksum bytes 1,2 resp. */
615     d->reg[0x61] = 0xff;
616     d->reg[0x65] = 0x00;
617     d->reg[0x69] = 0x55;
618     d->reg[0x6d] = 0xaa;
619     d->reg[0x71] = 0xff;
620     d->reg[0x75] = 0x00;
621     d->reg[0x79] = 0x55;
622     d->reg[0x7d] = 0xaa;
623 dpavlin 4
624     /* Battery valid, for DECstations */
625     d->reg[0xf8] = 1;
626     }
627    
628     if (access_style == MC146818_ARC_JAZZ)
629     memory_device_register(mem, "mc146818_jazz", 0x90000070ULL,
630     1, dev_mc146818_jazz_access, d, MEM_DEFAULT, NULL);
631    
632     dev_len = DEV_MC146818_LENGTH;
633     switch (access_style) {
634 dpavlin 16 case MC146818_CATS:
635 dpavlin 4 case MC146818_PC_CMOS:
636     dev_len = 2;
637     break;
638     case MC146818_SGI:
639     dev_len = 0x400;
640     }
641    
642     memory_device_register(mem, "mc146818", baseaddr,
643     dev_len * addrdiv, dev_mc146818_access,
644     d, MEM_DEFAULT, NULL);
645    
646     mc146818_update_time(d);
647    
648 dpavlin 12 machine_add_tickfunction(machine, dev_mc146818_tick, d, TICK_SHIFT);
649 dpavlin 4 }
650    

  ViewVC Help
Powered by ViewVC 1.1.26