/[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

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

Parent Directory Parent Directory | Revision Log Revision Log | View Patch Patch

revision 32 by dpavlin, Mon Oct 8 16:20:58 2007 UTC revision 42 by dpavlin, Mon Oct 8 16:22:32 2007 UTC
# Line 1  Line 1 
1  /*  /*
2   *  Copyright (C) 2003-2006  Anders Gavare.  All rights reserved.   *  Copyright (C) 2003-2007  Anders Gavare.  All rights reserved.
3   *   *
4   *  Redistribution and use in source and binary forms, with or without   *  Redistribution and use in source and binary forms, with or without
5   *  modification, are permitted provided that the following conditions are met:   *  modification, are permitted provided that the following conditions are met:
# Line 25  Line 25 
25   *  SUCH DAMAGE.   *  SUCH DAMAGE.
26   *     *  
27   *   *
28   *  $Id: dev_mc146818.c,v 1.91 2006/10/07 03:20:19 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
# Line 58  Line 59 
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  */
# Line 76  struct mc_data { Line 77  struct mc_data {
77          int             timebase_hz;          int             timebase_hz;
78          int             interrupt_hz;          int             interrupt_hz;
79          int             old_interrupt_hz;          int             old_interrupt_hz;
80          int             irq_nr;          struct interrupt irq;
81          struct timer    *timer;          struct timer    *timer;
82          volatile int    pending_timer_interrupts;          volatile int    pending_timer_interrupts;
83    
# Line 119  DEVICE_TICK(mc146818) Line 120  DEVICE_TICK(mc146818)
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 > 800 && !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:  */
# Line 139  DEVICE_TICK(mc146818) Line 133  DEVICE_TICK(mc146818)
133                  }                  }
134  #endif  #endif
135    
136                  cpu_interrupt(cpu, d->irq_nr);                  INTERRUPT_ASSERT(d->irq);
137    
138                  d->reg[MC_REGC * 4] |= MC_REGC_PF;                  d->reg[MC_REGC * 4] |= MC_REGC_PF;
139          }          }
# Line 157  DEVICE_TICK(mc146818) Line 151  DEVICE_TICK(mc146818)
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    
# Line 284  static void mc146818_update_time(struct Line 276  static void mc146818_update_time(struct
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:  */
# Line 472  int dev_mc146818_access(struct cpu *cpu, Line 458  int dev_mc146818_access(struct cpu *cpu,
458                  case MC_REGB*4:                  case MC_REGB*4:
459                          d->reg[MC_REGB*4] = data[0];                          d->reg[MC_REGB*4] = data[0];
460                          if (!(data[0] & MC_REGB_PIE)) {                          if (!(data[0] & MC_REGB_PIE)) {
461                                  cpu_interrupt_ack(cpu, d->irq_nr);                                  INTERRUPT_DEASSERT(d->irq);
462                          }                          }
463    
464                          /*  debug("[ mc146818: write to MC_REGB, data[0] "                          /*  debug("[ mc146818: write to MC_REGB, data[0] "
# Line 566  int dev_mc146818_access(struct cpu *cpu, Line 552  int dev_mc146818_access(struct cpu *cpu,
552                  data[0] = d->reg[relative_addr];                  data[0] = d->reg[relative_addr];
553    
554                  if (relative_addr == MC_REGC*4) {                  if (relative_addr == MC_REGC*4) {
555                          cpu_interrupt_ack(cpu, d->irq_nr);                          INTERRUPT_DEASSERT(d->irq);
556    
557                          /*                          /*
558                           *  Acknowledging an interrupt decreases the                           *  Acknowledging an interrupt decreases the
559                           *  number of pending "real world" timer ticks.                           *  number of pending "real world" timer ticks.
560                           */                           */
561                          if (d->reg[MC_REGC * 4] & MC_REGC_PF)                          if (d->reg[MC_REGC * 4] & MC_REGC_PF &&
562                                d->pending_timer_interrupts > 0)
563                                  d->pending_timer_interrupts --;                                  d->pending_timer_interrupts --;
564    
565                          d->reg[MC_REGC * 4] = 0x00;                          d->reg[MC_REGC * 4] = 0x00;
# Line 600  int dev_mc146818_access(struct cpu *cpu, Line 587  int dev_mc146818_access(struct cpu *cpu,
587   *  so it contains both rtc related stuff and the station's Ethernet address.   *  so it contains both rtc related stuff and the station's Ethernet address.
588   */   */
589  void dev_mc146818_init(struct machine *machine, struct memory *mem,  void dev_mc146818_init(struct machine *machine, struct memory *mem,
590          uint64_t baseaddr, int irq_nr, int access_style, int addrdiv)          uint64_t baseaddr, char *irq_path, int access_style, int addrdiv)
591  {  {
592          unsigned char ether_address[6];          unsigned char ether_address[6];
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          d->irq_nr        = irq_nr;  
599          d->access_style  = access_style;          d->access_style  = access_style;
600          d->addrdiv       = addrdiv;          d->addrdiv       = addrdiv;
601    
602            INTERRUPT_CONNECT(irq_path, d->irq);
603    
604          d->use_bcd = 0;          d->use_bcd = 0;
605          switch (access_style) {          switch (access_style) {
606          case MC146818_SGI:          case MC146818_SGI:
# Line 632  void dev_mc146818_init(struct machine *m Line 616  void dev_mc146818_init(struct machine *m
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];
# Line 701  void dev_mc146818_init(struct machine *m Line 685  void dev_mc146818_init(struct machine *m
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    

Legend:
Removed from v.32  
changed lines
  Added in v.42

  ViewVC Help
Powered by ViewVC 1.1.26