1 /*- 2 * Copyright (C) 1993 Allen K. Briggs, Chris P. Caputo, 3 * Michael L. Finch, Bradley A. Grantham, and 4 * Lawrence A. Kesteloot 5 * All rights reserved. 6 * 7 * Redistribution and use in source and binary forms, with or without 8 * modification, are permitted provided that the following conditions 9 * are met: 10 * 1. Redistributions of source code must retain the above copyright 11 * notice, this list of conditions and the following disclaimer. 12 * 2. Redistributions in binary form must reproduce the above copyright 13 * notice, this list of conditions and the following disclaimer in the 14 * documentation and/or other materials provided with the distribution. 15 * 3. All advertising materials mentioning features or use of this software 16 * must display the following acknowledgement: 17 * This product includes software developed by the Alice Group. 18 * 4. The names of the Alice Group or any of its members may not be used 19 * to endorse or promote products derived from this software without 20 * specific prior written permission. 21 * 22 * THIS SOFTWARE IS PROVIDED BY THE ALICE GROUP ``AS IS'' AND ANY EXPRESS OR 23 * IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES 24 * OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. 25 * IN NO EVENT SHALL THE ALICE GROUP BE LIABLE FOR ANY DIRECT, INDIRECT, 26 * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT 27 * NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, 28 * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY 29 * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT 30 * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE 31 * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. 32 * 33 */ 34 35 36 /* #include "stand.h" */ 37 #include "../dev/via.h" 38 39 #define PRAM_SIZE 256 40 #define PRAM_GET 256 41 #define RTC_DATA 0x1 42 #define RTC_CLOCK 0x2 43 #define RTC_ENB 0x4 44 45 #define PRAMCMD_SEC0 0x01 46 #define PRAMCMD_SEC1 0x05 47 #define PRAMCMD_SEC2 0x09 48 #define PRAMCMD_SEC3 0x0D 49 #define PRAMCMD_TEST 0x31 50 #define PRAMCMD_WPRT 0x35 51 #define PRAMCMD_RA1x 0x21 52 #define PRAMCMD_RA0x 0x41 53 #define PRAMCMD_READ 0x80 54 #define PRAMBIT_WRIT 0xf0 55 #define PRAMADDR_SHF 2 56 57 #define PRAMCMD_SEL 0x38 58 #define PRAMCMD_EXT 0x0 59 #define PRAM_SECT_MASK 0xE0 /* 0x1C0 */ 60 #define PRAM_BYTE_MASK 0x1F /* 0x3F */ 61 #define PRAM_SECT_SHF 5 62 #define PRAM_BYTE_SHF 2 63 64 unsigned char pram_save[PRAM_SIZE]; 65 int pram_chr = 0; 66 67 void pram_enable() 68 { 69 /* enable serial function */ 70 via_reg(VIA1, vDirB) = RTC_ENB; 71 via_reg(VIA1, vBufB) = RTC_ENB; /* flush? */ 72 via_reg(VIA1, vBufB) = 0; 73 } 74 75 76 void pram_disable() 77 { 78 /* disable serial function */ 79 via_reg(VIA1, vDirB) = RTC_ENB | vDirA_ADBState; 80 via_reg(VIA1, vBufB) = RTC_ENB; 81 } 82 83 84 unsigned char pram_getbyte(void) 85 { 86 int bitnum; 87 unsigned char data; 88 89 data = 0; 90 91 via_reg(VIA1, vDirB) |= RTC_CLOCK; 92 93 for(bitnum = 0; bitnum < 8; bitnum++){ 94 95 /* lower clock bit (please send data) */ 96 via_reg(VIA1, vBufB) = 0; 97 98 /* get data bit */ 99 data = (data << 1) | (via_reg(VIA1, vBufB) & RTC_DATA); 100 101 /* raise clock bit (please ready next data) */ 102 via_reg(VIA1, vBufB) = RTC_CLOCK; 103 } 104 105 via_reg(VIA1, vDirB) &= ~RTC_CLOCK; 106 107 return(data); 108 } 109 110 111 void pram_putbyte(unsigned char data) 112 { 113 int bitnum; 114 115 via_reg(VIA1, vDirB) |= RTC_CLOCK | RTC_DATA; 116 117 for(bitnum = 0; bitnum < 8; bitnum++){ 118 119 /* lower clock bit (please accept data) */ 120 via_reg(VIA1, vBufB) = 0; 121 122 /* send data bit */ 123 via_reg(VIA1, vBufB) = (data & (1 << (7 - bitnum))) ? RTC_DATA : 0; 124 125 /* raise clock bit (please store the data) */ 126 via_reg(VIA1, vBufB) = RTC_CLOCK; 127 } 128 129 via_reg(VIA1, vDirB) &= ~(RTC_CLOCK | RTC_DATA); 130 } 131 132 133 unsigned char pram_read(unsigned char cmd) 134 { 135 unsigned char data=0; 136 137 pram_enable(); 138 pram_putbyte(cmd | PRAMCMD_READ); 139 data = pram_getbyte(); 140 pram_disable(); 141 142 return(data); 143 } 144 145 146 void pram_write(unsigned char cmd, unsigned char val) 147 { 148 pram_enable(); 149 pram_putbyte(cmd); 150 pram_putbyte(val); 151 pram_disable(); 152 } 153 154 155 unsigned char pram_ext_read(int addr) 156 { 157 unsigned char data; 158 int sect, byte; 159 160 sect = (addr & PRAM_SECT_MASK) >> PRAM_SECT_SHF; 161 byte = (addr & PRAM_BYTE_MASK) << PRAM_BYTE_SHF; 162 pram_enable(); 163 pram_putbyte(PRAMCMD_READ | PRAMCMD_SEL | sect); 164 pram_putbyte(PRAMCMD_EXT | byte); 165 data = pram_getbyte(); 166 pram_disable(); 167 168 return(data); 169 } 170 171 172 void pram_ext_write(int addr, unsigned char val) 173 { 174 int sect, byte; 175 176 sect = (addr & PRAM_SECT_MASK) >> PRAM_SECT_SHF; 177 byte = (addr & PRAM_BYTE_MASK) << PRAM_BYTE_SHF; 178 pram_enable(); 179 pram_putbyte(PRAMCMD_SEL | sect); 180 pram_putbyte(PRAMCMD_EXT | byte); 181 pram_putbyte(val); 182 pram_disable(); 183 } 184 185 186 unsigned char *pram_get(void) 187 { 188 int byte_get; 189 190 printf("PRAM contents:\n"); 191 for(byte_get = 0; byte_get < PRAM_GET; byte_get++){ 192 193 pram_save[byte_get] = pram_ext_read(byte_get); 194 195 if(byte_get % 16 == 0) 196 printf("\n(%x)", byte_get); 197 printf("%x%s", pram_save[byte_get], (byte_get == PRAM_GET - 1)?"":", "); 198 } 199 printf("\n"); 200 } 201 202 char *convtime(unsigned long t) 203 { 204 static long daypmon[] = { 31,28,31,30,31,30,31,31,30,31,30,31 }; 205 static char *monstr[] = {"January","February","March","April","May","June", 206 "July","August","September","October","November","December" }; 207 static char s[200]; 208 long year,month,day,hour,minute,seconds,i,dayperyear; 209 210 year=1904; 211 month=0; /* Jan */ 212 day=1; 213 hour=0; 214 minute=0; 215 seconds=0; 216 217 if(t == 0xffffffff) 218 return("<time value is -1>"); 219 220 while (t > 0) 221 { 222 if (year % 4 == 0 && (year % 100 != 0 || year % 400 == 0)) 223 { 224 dayperyear=366; 225 daypmon[1]=29; 226 } 227 else 228 { 229 dayperyear=365; 230 daypmon[1]=28; 231 } 232 i=dayperyear*60*60*24; 233 if (t >= i) 234 { 235 t-=i; 236 year++; 237 continue; 238 } 239 i=daypmon[month]*60*60*24; 240 if (t >= i) 241 { 242 t-=i; 243 month++; 244 continue; 245 } 246 i=60*60*24; 247 if (t >= i) 248 { 249 t-=i; 250 day++; 251 continue; 252 } 253 i=60*60; 254 if (t >= i) 255 { 256 t-=i; 257 hour++; 258 continue; 259 } 260 i=60; 261 if (t >= i) 262 { 263 t-=i; 264 minute++; 265 continue; 266 } 267 seconds=t; 268 t=0; 269 } 270 271 sprintf(s,"%s %d, %d %d:%d:%d",monstr[month],day,year,hour,minute,seconds); 272 273 return s; 274 } 275 276 unsigned long pram_readtime(void) 277 { 278 unsigned long timedata,otim; 279 280 timedata = 0; 281 otim = 0xffffffff; 282 while(otim != timedata){ 283 otim = timedata; 284 285 timedata = pram_read(PRAMCMD_SEC3); 286 timedata = (timedata << 8) | pram_read(PRAMCMD_SEC2); 287 timedata = (timedata << 8) | pram_read(PRAMCMD_SEC1); 288 timedata = (timedata << 8) | pram_read(PRAMCMD_SEC0); 289 290 /* printf("time read from PRAM: %d\n", timedata); */ 291 /* printf("Date and time: %s\n",convtime(timedata)); */ 292 } 293 294 pram_write(PRAMCMD_WPRT, 0xff); 295 296 return(timedata); 297 } 298 299 300 int pram_settime(unsigned long time) 301 { 302 unsigned char t1, t2, t3, t4, tmp; 303 unsigned char ret; 304 305 t1 = time & 0xff; 306 t2 = (time >>= 8) & 0xff; 307 t3 = (time >>= 8) & 0xff; 308 t4 = (time >>= 8) & 0xff; 309 310 pram_write(PRAMCMD_WPRT, 0); 311 312 pram_write(PRAMCMD_SEC0, 0); 313 tmp = pram_read(PRAMCMD_SEC1); 314 pram_write(PRAMCMD_SEC1, (tmp + 1) & 0xff); 315 if((ret=pram_read(PRAMCMD_SEC1)) != ((tmp + 1) & 0xff)) 316 { 317 printf("we read ret=%x, tmp=%x (tmp+1) &0xff= %x\n",ret,tmp,(tmp +1) & 0xff); 318 return(0); 319 } 320 pram_write(PRAMCMD_SEC3, t4); 321 pram_write(PRAMCMD_SEC2, t3); 322 pram_write(PRAMCMD_SEC1, t2); 323 pram_write(PRAMCMD_SEC0, t1); 324 325 pram_write(PRAMCMD_WPRT, 0xff); 326 327 return(-1); 328 } 329