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 #ident "$Id: pram.c,v 1.1.1.1 1993/09/29 06:09:15 briggs Exp $" 35 36 37 /* #include "stand.h" */ 38 #include "../dev/via.h" 39 40 #define PRAM_SIZE 256 41 #define PRAM_GET 256 42 #define RTC_DATA 0x1 43 #define RTC_CLOCK 0x2 44 #define RTC_ENB 0x4 45 46 #define PRAMCMD_SEC0 0x01 47 #define PRAMCMD_SEC1 0x05 48 #define PRAMCMD_SEC2 0x09 49 #define PRAMCMD_SEC3 0x0D 50 #define PRAMCMD_TEST 0x31 51 #define PRAMCMD_WPRT 0x35 52 #define PRAMCMD_RA1x 0x21 53 #define PRAMCMD_RA0x 0x41 54 #define PRAMCMD_READ 0x80 55 #define PRAMBIT_WRIT 0xf0 56 #define PRAMADDR_SHF 2 57 58 #define PRAMCMD_SEL 0x38 59 #define PRAMCMD_EXT 0x0 60 #define PRAM_SECT_MASK 0xE0 /* 0x1C0 */ 61 #define PRAM_BYTE_MASK 0x1F /* 0x3F */ 62 #define PRAM_SECT_SHF 5 63 #define PRAM_BYTE_SHF 2 64 65 unsigned char pram_save[PRAM_SIZE]; 66 int pram_chr = 0; 67 68 69 void pram_enable() 70 { 71 /* enable serial function */ 72 via_reg(VIA1, vDirB) = RTC_ENB; 73 via_reg(VIA1, vBufB) = RTC_ENB; /* flush? */ 74 via_reg(VIA1, vBufB) = 0; 75 } 76 77 78 void pram_disable() 79 { 80 /* disable serial function */ 81 via_reg(VIA1, vDirB) = RTC_ENB | vDirA_ADBState; 82 via_reg(VIA1, vBufB) = RTC_ENB; 83 } 84 85 86 unsigned char pram_getbyte(void) 87 { 88 int bitnum; 89 unsigned char data; 90 91 data = 0; 92 93 via_reg(VIA1, vDirB) |= RTC_CLOCK; 94 95 for(bitnum = 0; bitnum < 8; bitnum++){ 96 97 /* lower clock bit (please send data) */ 98 via_reg(VIA1, vBufB) = 0; 99 100 /* get data bit */ 101 data = (data << 1) | (via_reg(VIA1, vBufB) & RTC_DATA); 102 103 /* raise clock bit (please ready next data) */ 104 via_reg(VIA1, vBufB) = RTC_CLOCK; 105 } 106 107 via_reg(VIA1, vDirB) &= ~RTC_CLOCK; 108 109 return(data); 110 } 111 112 113 void pram_putbyte(unsigned char data) 114 { 115 int bitnum; 116 117 via_reg(VIA1, vDirB) |= RTC_CLOCK | RTC_DATA; 118 119 for(bitnum = 0; bitnum < 8; bitnum++){ 120 121 /* lower clock bit (please accept data) */ 122 via_reg(VIA1, vBufB) = 0; 123 124 /* send data bit */ 125 via_reg(VIA1, vBufB) = (data & (1 << (7 - bitnum))) ? RTC_DATA : 0; 126 127 /* raise clock bit (please store the data) */ 128 via_reg(VIA1, vBufB) = RTC_CLOCK; 129 } 130 131 via_reg(VIA1, vDirB) &= ~(RTC_CLOCK | RTC_DATA); 132 } 133 134 135 unsigned char pram_read(unsigned char cmd) 136 { 137 unsigned char data=0; 138 139 pram_enable(); 140 pram_putbyte(cmd | PRAMCMD_READ); 141 data = pram_getbyte(); 142 pram_disable(); 143 144 return(data); 145 } 146 147 148 void pram_write(unsigned char cmd, unsigned char val) 149 { 150 pram_enable(); 151 pram_putbyte(cmd); 152 pram_putbyte(val); 153 pram_disable(); 154 } 155 156 157 unsigned char pram_ext_read(int addr) 158 { 159 unsigned char data; 160 int sect, byte; 161 162 sect = (addr & PRAM_SECT_MASK) >> PRAM_SECT_SHF; 163 byte = (addr & PRAM_BYTE_MASK) << PRAM_BYTE_SHF; 164 pram_enable(); 165 pram_putbyte(PRAMCMD_READ | PRAMCMD_SEL | sect); 166 pram_putbyte(PRAMCMD_EXT | byte); 167 data = pram_getbyte(); 168 pram_disable(); 169 170 return(data); 171 } 172 173 174 void pram_ext_write(int addr, unsigned char val) 175 { 176 int sect, byte; 177 178 sect = (addr & PRAM_SECT_MASK) >> PRAM_SECT_SHF; 179 byte = (addr & PRAM_BYTE_MASK) << PRAM_BYTE_SHF; 180 pram_enable(); 181 pram_putbyte(PRAMCMD_SEL | sect); 182 pram_putbyte(PRAMCMD_EXT | byte); 183 pram_putbyte(val); 184 pram_disable(); 185 } 186 187 188 unsigned char *pram_get(void) 189 { 190 int byte_get; 191 192 printf("PRAM contents:\n"); 193 for(byte_get = 0; byte_get < PRAM_GET; byte_get++){ 194 195 pram_save[byte_get] = pram_ext_read(byte_get); 196 197 if(byte_get % 16 == 0) 198 printf("\n(%x)", byte_get); 199 printf("%x%s", pram_save[byte_get], (byte_get == PRAM_GET - 1)?"":", "); 200 } 201 printf("\n"); 202 } 203 204 char *convtime(unsigned long t) 205 { 206 static long daypmon[] = { 31,28,31,30,31,30,31,31,30,31,30,31 }; 207 static char *monstr[] = {"January","February","March","April","May","June", 208 "July","August","September","October","November","December" }; 209 static char s[200]; 210 long year,month,day,hour,minute,seconds,i,dayperyear; 211 212 year=1904; 213 month=0; /* Jan */ 214 day=1; 215 hour=0; 216 minute=0; 217 seconds=0; 218 219 if(t == 0xffffffff) 220 return("<time value is -1>"); 221 222 while (t > 0) 223 { 224 if (year % 4 == 0 && (year % 100 != 0 || year % 400 == 0)) 225 { 226 dayperyear=366; 227 daypmon[1]=29; 228 } 229 else 230 { 231 dayperyear=365; 232 daypmon[1]=28; 233 } 234 i=dayperyear*60*60*24; 235 if (t >= i) 236 { 237 t-=i; 238 year++; 239 continue; 240 } 241 i=daypmon[month]*60*60*24; 242 if (t >= i) 243 { 244 t-=i; 245 month++; 246 continue; 247 } 248 i=60*60*24; 249 if (t >= i) 250 { 251 t-=i; 252 day++; 253 continue; 254 } 255 i=60*60; 256 if (t >= i) 257 { 258 t-=i; 259 hour++; 260 continue; 261 } 262 i=60; 263 if (t >= i) 264 { 265 t-=i; 266 minute++; 267 continue; 268 } 269 seconds=t; 270 t=0; 271 } 272 273 sprintf(s,"%s %d, %d %d:%d:%d",monstr[month],day,year,hour,minute,seconds); 274 275 return s; 276 } 277 278 unsigned long pram_readtime(void) 279 { 280 unsigned long timedata,otim; 281 282 timedata = 0; 283 otim = 0xffffffff; 284 while(otim != timedata){ 285 otim = timedata; 286 287 timedata = pram_read(PRAMCMD_SEC3); 288 timedata = (timedata << 8) | pram_read(PRAMCMD_SEC2); 289 timedata = (timedata << 8) | pram_read(PRAMCMD_SEC1); 290 timedata = (timedata << 8) | pram_read(PRAMCMD_SEC0); 291 292 /* printf("time read from PRAM: %d\n", timedata); */ 293 /* printf("Date and time: %s\n",convtime(timedata)); */ 294 } 295 296 pram_write(PRAMCMD_WPRT, 0xff); 297 298 return(timedata); 299 } 300 301 302 int pram_settime(unsigned long time) 303 { 304 unsigned char t1, t2, t3, t4, tmp; 305 unsigned char ret; 306 307 t1 = time & 0xff; 308 t2 = (time >>= 8) & 0xff; 309 t3 = (time >>= 8) & 0xff; 310 t4 = (time >>= 8) & 0xff; 311 312 pram_write(PRAMCMD_WPRT, 0); 313 314 pram_write(PRAMCMD_SEC0, 0); 315 tmp = pram_read(PRAMCMD_SEC1); 316 pram_write(PRAMCMD_SEC1, (tmp + 1) & 0xff); 317 if((ret=pram_read(PRAMCMD_SEC1)) != ((tmp + 1) & 0xff)) 318 { 319 printf("we read ret=%x, tmp=%x (tmp+1) &0xff= %x\n",ret,tmp,(tmp +1) & 0xff); 320 return(0); 321 } 322 pram_write(PRAMCMD_SEC3, t4); 323 pram_write(PRAMCMD_SEC2, t3); 324 pram_write(PRAMCMD_SEC1, t2); 325 pram_write(PRAMCMD_SEC0, t1); 326 327 pram_write(PRAMCMD_WPRT, 0xff); 328 329 return(-1); 330 } 331