/[gxemul]/trunk/src/devices/dev_mk48txx.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_mk48txx.c

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

revision 41 by dpavlin, Mon Oct 8 16:21:17 2007 UTC revision 42 by dpavlin, Mon Oct 8 16:22:32 2007 UTC
# Line 25  Line 25 
25   *  SUCH DAMAGE.   *  SUCH DAMAGE.
26   *   *
27   *   *
28   *  $Id: dev_mk48txx.c,v 1.4 2007/02/03 20:14:23 debug Exp $   *  $Id: dev_mk48txx.c,v 1.8 2007/06/15 19:57:33 debug Exp $
29   *   *
30   *  Mostek MK48Txx Real Time Clock.   *  COMMENT: Mostek MK48Txx Real Time Clock
31   *   *
32   *  TODO: Actually implement it. This is just enough to fool NetBSD/mvmeppc   *  TODO:
33   *        into thinking that the clock exists.   *      Only the MK48T08 is implemented so far.
34   */   */
35    
36  #include <stdio.h>  #include <stdio.h>
37  #include <stdlib.h>  #include <stdlib.h>
38  #include <string.h>  #include <string.h>
39    #include <time.h>
40    
41  #include "cpu.h"  #include "cpu.h"
42  #include "device.h"  #include "device.h"
# Line 48  Line 49 
49  #include "mk48txxreg.h"  #include "mk48txxreg.h"
50    
51    
52  #define MK48TXX_LEN             16  #define MK48TXX_LEN             MK48T08_CLKSZ
53    
54    #define BCD(x)  ((((x) / 10) << 4) + ((x) % 10))
55    
56  struct mk48txx_data {  struct mk48txx_data {
57          unsigned char   reg[MK48TXX_LEN];          uint8_t         reg[MK48TXX_LEN];
58  };  };
59    
60    
61  /*  void mk48txx_update_regs(struct mk48txx_data *d)
62   *  dev_mk48txx_access():  {
63   */          struct tm *tmp;
64            time_t timet;
65    
66            timet = time(NULL);
67            tmp = gmtime(&timet);
68    
69            d->reg[MK48T08_CLKOFF + MK48TXX_ISEC] = BCD(tmp->tm_sec);
70            d->reg[MK48T08_CLKOFF + MK48TXX_IMIN] = BCD(tmp->tm_min);
71            d->reg[MK48T08_CLKOFF + MK48TXX_IHOUR] = BCD(tmp->tm_hour);
72            d->reg[MK48T08_CLKOFF + MK48TXX_IWDAY] = tmp->tm_wday + 1;
73            d->reg[MK48T08_CLKOFF + MK48TXX_IDAY] = BCD(tmp->tm_mday);
74            d->reg[MK48T08_CLKOFF + MK48TXX_IMON] = BCD(tmp->tm_mon + 1);
75            d->reg[MK48T08_CLKOFF + MK48TXX_IYEAR] = BCD(tmp->tm_year % 100);
76    }
77    
78    
79  DEVICE_ACCESS(mk48txx)  DEVICE_ACCESS(mk48txx)
80  {  {
81          struct mk48txx_data *d = (struct mk48txx_data *) extra;          struct mk48txx_data *d = extra;
82          uint64_t idata = 0, odata = 0;          uint64_t idata = 0, odata = 0;
83    
84          if (writeflag == MEM_WRITE)          if (writeflag == MEM_WRITE)
85                  idata = memory_readmax64(cpu, data, len);                  idata = memory_readmax64(cpu, data, len);
86    
87          switch (relative_addr) {          if (writeflag == MEM_READ)
88                    odata = d->reg[relative_addr];
89    
90          case MK48TXX_ICSR:          if (relative_addr < MK48T08_CLKOFF ||
91                  if (writeflag == MEM_READ)              relative_addr >= MK48T08_CLKOFF + MK48TXX_ISEC) {
92                          odata = d->reg[relative_addr];                  /*  Reads and writes to the RAM part of the mk48txx, or
93                  else                      the clock registers, are OK:  */
94                    if (writeflag == MEM_WRITE)
95                          d->reg[relative_addr] = idata;                          d->reg[relative_addr] = idata;
96                  break;                  goto ret;
97            }
98    
99          case MK48TXX_ISEC:          switch (relative_addr) {
100  {  
101  /*  TODO: this is just a hack for NetBSD/mvmeppc mkclock detection :(  */          case MK48T08_CLKOFF + MK48TXX_ICSR:
102  static int x = 0;                  if (writeflag == MEM_WRITE) {
103  odata = x >> 1;                          if ((idata & MK48TXX_CSR_READ) &&
104  x++;                              !(d->reg[relative_addr] & MK48TXX_CSR_READ)) {
105  }                                  /*  Switching the read bit from 0 to 1 causes
106                                        registers to be "froozen". In the emulator,
107                                        simply updating them with data from the
108                                        host should be good enough.  */
109                                    mk48txx_update_regs(d);
110                            }
111                            d->reg[relative_addr] = idata;
112                    }
113                  break;                  break;
114    
115          default:if (writeflag == MEM_READ)          default:if (writeflag == MEM_READ)
116                          fatal("[ mk48txx: unimplemented READ from offset %i ]"                          fatal("[ mk48txx: unimplemented READ from offset 0x%x ]"
117                              "\n", (int)relative_addr);                              "\n", (int)relative_addr);
118                  else                  else
119                          fatal("[ mk48txx: unimplemented WRITE to offset %i: "                          fatal("[ mk48txx: unimplemented WRITE to offset 0x%x: "
120                              "0x%x ]\n", (int)relative_addr, (int)idata);                              "0x%x ]\n", (int)relative_addr, (int)idata);
121                    exit(1);
122          }          }
123    
124    ret:
125          if (writeflag == MEM_READ)          if (writeflag == MEM_READ)
126                  memory_writemax64(cpu, data, len, odata);                  memory_writemax64(cpu, data, len, odata);
127    
# Line 101  x++; Line 131  x++;
131    
132  DEVINIT(mk48txx)  DEVINIT(mk48txx)
133  {  {
134          struct mk48txx_data *d = malloc(sizeof(struct mk48txx_data));          struct mk48txx_data *d;
135          if (d == NULL) {  
136                  fprintf(stderr, "out of memory\n");          CHECK_ALLOCATION(d = malloc(sizeof(struct mk48txx_data)));
                 exit(1);  
         }  
137          memset(d, 0, sizeof(struct mk48txx_data));          memset(d, 0, sizeof(struct mk48txx_data));
138    
139            mk48txx_update_regs(d);
140    
141          memory_device_register(devinit->machine->memory, devinit->name,          memory_device_register(devinit->machine->memory, devinit->name,
142              devinit->addr, MK48TXX_LEN, dev_mk48txx_access, (void *)d,              devinit->addr, MK48TXX_LEN, dev_mk48txx_access, (void *)d,
143              DM_DEFAULT, NULL);              DM_DEFAULT, NULL);

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

  ViewVC Help
Powered by ViewVC 1.1.26