/[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 11 by dpavlin, Mon Oct 8 16:18:11 2007 UTC revision 12 by dpavlin, Mon Oct 8 16:18:38 2007 UTC
# Line 25  Line 25 
25   *  SUCH DAMAGE.   *  SUCH DAMAGE.
26   *     *  
27   *   *
28   *  $Id: dev_mc146818.c,v 1.69 2005/05/20 07:42:12 debug Exp $   *  $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.   *  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 SGI machines is similar to MC146818.)
# Line 56  Line 56 
56    
57  /*  #define MC146818_DEBUG  */  /*  #define MC146818_DEBUG  */
58    
59  #define TICK_STEPS_SHIFT        14  #define TICK_SHIFT      14
60    
61    
62  /*  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 140  void dev_mc146818_tick(struct cpu *cpu, Line 140  void dev_mc146818_tick(struct cpu *cpu,
140    
141          if ((d->reg[MC_REGB * 4] & MC_REGB_PIE) &&          if ((d->reg[MC_REGB * 4] & MC_REGB_PIE) &&
142               d->interrupt_every_x_cycles > 0) {               d->interrupt_every_x_cycles > 0) {
143                  d->cycles_left_until_interrupt -=                  d->cycles_left_until_interrupt -= (1 << TICK_SHIFT);
                     (1 << TICK_STEPS_SHIFT);  
144    
145                  if (d->cycles_left_until_interrupt < 0 ||                  if (d->cycles_left_until_interrupt < 0 ||
146                      d->cycles_left_until_interrupt >=                      d->cycles_left_until_interrupt >=
# Line 366  int dev_mc146818_access(struct cpu *cpu, Line 365  int dev_mc146818_access(struct cpu *cpu,
365  #endif  #endif
366    
367          /*          /*
368           *  For some reason, Linux/sgimips relies on the UIP bit to go           *  Sprite seems to wants UF interrupt status, once every second, or
          *  on and off. Without this code, booting Linux takes forever:  
          */  
         d->reg[MC_REGA * 4] &= ~MC_REGA_UIP;  
 #if 1  
         /*  TODO:  solve this more nicely  */  
         if ((random() & 0xff) == 0)  
                 d->reg[MC_REGA * 4] ^= MC_REGA_UIP;  
 #endif  
   
         /*  
          *  Sprite seens to wants UF interrupt status, once every second, or  
369           *  it hangs forever during bootup.  (These do not cause interrupts,           *  it hangs forever during bootup.  (These do not cause interrupts,
370           *  but it is good enough... Sprite polls this, iirc.)           *  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);          timet = time(NULL);
376          tmp = gmtime(&timet);          tmp = gmtime(&timet);
377          d->reg[MC_REGC * 4] &= ~MC_REGC_UF;          d->reg[MC_REGC * 4] &= ~MC_REGC_UF;
378    
379          if (tmp->tm_sec != d->previous_second) {          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;                  d->reg[MC_REGC * 4] |= MC_REGC_UF;
383                  d->reg[MC_REGC * 4] |= MC_REGC_IRQF;                  d->reg[MC_REGC * 4] |= MC_REGC_IRQF;
384                  d->previous_second = tmp->tm_sec;                  d->previous_second = tmp->tm_sec;
# Line 393  int dev_mc146818_access(struct cpu *cpu, Line 387  int dev_mc146818_access(struct cpu *cpu,
387                      the PF (periodic flag) bit set, even though interrupts                      the PF (periodic flag) bit set, even though interrupts
388                      are not enabled?  */                      are not enabled?  */
389                  d->reg[MC_REGC * 4] |= MC_REGC_PF;                  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:  */          /*  RTC data is in either BCD format or binary:  */
394          if (d->use_bcd) {          if (d->use_bcd)
395                  d->reg[MC_REGB * 4] &= ~(1 << 2);                  d->reg[MC_REGB * 4] &= ~(1 << 2);
396          } else {          else
397                  d->reg[MC_REGB * 4] |= (1 << 2);                  d->reg[MC_REGB * 4] |= (1 << 2);
         }  
398    
399          /*  RTC date/time is always Valid:  */          /*  RTC date/time is always Valid:  */
400          d->reg[MC_REGD * 4] |= MC_REGD_VRT;          d->reg[MC_REGD * 4] |= MC_REGD_VRT;
# Line 649  void dev_mc146818_init(struct machine *m Line 643  void dev_mc146818_init(struct machine *m
643    
644          mc146818_update_time(d);          mc146818_update_time(d);
645    
646          machine_add_tickfunction(machine, dev_mc146818_tick,          machine_add_tickfunction(machine, dev_mc146818_tick, d, TICK_SHIFT);
             d, TICK_STEPS_SHIFT);  
647  }  }
648    

Legend:
Removed from v.11  
changed lines
  Added in v.12

  ViewVC Help
Powered by ViewVC 1.1.26