1: /* 2: * GT307 3: * 4: * Read and set a Computer Products inc GT307 clock calendar card 5: * 6: * Author R Birch 7: * Date July 1999 8: * 9: * You can use this in two ways. If you use Daylight Savings Time when 10: * the card is intialised then it can be used to maintain local time. 11: * If DST is not used then this is probably best used to maintain the card 12: * on UTC. 13: * 14: * Usage: 15: * 16: * gt307 [-d n][-l] [yymmddhhmm.ss] 17: * 18: * -d sets DST on or off n = 1 (on) n = 0 (off) 19: * -l switches output between long or short. Short is suitable 20: * as an input into date(8) 21: * The time string is the same as date(8) for input. 22: */ 23: 24: #if !defined(lint) && defined(DOSCCS) 25: static char sccsid[] = "@(#)GT307.c 1.00 (2.11BSD) 99/7/4"; 26: #endif 27: 28: #include <stdlib.h> 29: #include <unistd.h> 30: #include <stdio.h> 31: #include <assert.h> 32: #include <sys/errno.h> 33: #include <sys/types.h> 34: 35: #define BASE_ADDR 0177704 36: #define IO_VEC 0450 37: #define SEG_REG 6 38: #define IO_SIZE 1 39: 40: #define REG_A 012 41: #define REG_B 013 42: #define REG_C 014 43: #define REG_D 015 44: 45: #define UIP 0200 46: #define DV2 0100 47: #define DV1 040 48: #define DV0 020 49: #define RS3 010 50: #define RS2 04 51: #define RS1 02 52: #define RS0 01 53: 54: #define SET 0200 55: #define PIE 0100 56: #define AIE 040 57: #define UIE 020 58: #define SQWE 010 59: #define DM 04 60: #define D24 02 61: #define DSE 01 62: 63: #define IRQF 0200 64: #define PF 0100 65: #define AF 040 66: #define UF 020 67: 68: #define VRT 0200 69: 70: #define CONST 1 71: 72: char *days[] = {"Sun","Mon","Tue","Wed","Thu","Fri","Sat"}; 73: char *months[] = {"Jan","Feb","Mar","Apr","May","Jun", 74: "Jul","Aug","Sep","Oct","Nov","Dec"}; 75: 76: main(argc, argv) 77: int argc; 78: char *argv[]; 79: { 80: 81: register unsigned char *io_ptr; 82: char time_str[80]; 83: unsigned int seg_reg = SEG_REG; 84: unsigned int io_size = IO_SIZE; 85: unsigned int physaddr = BASE_ADDR; 86: unsigned char memval; 87: int ch; 88: int lflag; 89: int dst_flag; 90: int year; 91: int bigyear; 92: int month; 93: int date; 94: int day; 95: int hours; 96: int minutes; 97: int seconds; 98: 99: /* 100: * Set up the page address pointer. This is written to allow simple 101: * changing of the #defines at the start of the program to ripple through 102: * to the rest of the code. Do not allow 0 because that would collide 103: * with the first 8kb of code or data. Do not allow 7 because that would 104: * collide with our stack. 105: */ 106: assert(seg_reg > 0 && seg_reg < 7); 107: io_ptr = (unsigned char *)((u_int)020000 * seg_reg); 108: /* 109: * Map the new page to the physical address of the card. 110: */ 111: if (phys(seg_reg, io_size, physaddr) == -1) 112: err(1, "phys(%d, %d, 0%o)", seg_reg, io_size, physaddr); 113: /* 114: * process command line 115: */ 116: dst_flag = 0; /* Set defaults */ 117: lflag = 0; 118: 119: while ((ch = getopt(argc, argv,"d:l")) != EOF) 120: switch((char)ch){ 121: case 'd': 122: dst_flag = atoi(optarg) ? 1 : 0; 123: break; 124: case 'l': 125: lflag = 1; 126: break; 127: default: 128: errx(1,"invalid parameters.\n"); 129: } 130: argc -= optind; 131: argv += optind; 132: 133: if (argc > 1) 134: errx(1,"invalid parameters."); 135: 136: /* 137: * If we still have an argument left then we are setting the clock, 138: * otherwise we are displaying what is in the card. 139: */ 140: if (!argc) 141: goto display; 142: goto setup; 143: 144: display: 145: /* 146: * Look at the card to check whether the time on the card is 147: * valid or not. 148: */ 149: memval = (unsigned char)*(io_ptr + REG_D); 150: if ((memval & VRT) == 0) 151: errx(1," board clock invalid, reinitialise."); 152: /* 153: Get the time from the card 154: */ 155: memval = (unsigned char)*(io_ptr + REG_A); 156: while((memval & UIP) == 1) 157: memval = (unsigned char)*(io_ptr + REG_A); 158: 159: seconds = (int)*(io_ptr); 160: minutes = (int)*(io_ptr + 2); 161: hours = (int)*(io_ptr + 4); 162: day = (int)*(io_ptr + 6); 163: date = (int)*(io_ptr + 7); 164: month = (int)*(io_ptr + 8); 165: year = (int)*(io_ptr + 9); 166: 167: if(year <= 70) 168: bigyear = year + 2000; 169: else 170: bigyear = year + 1900; 171: 172: if (lflag == 0) 173: printf("%02d%02d%02d%02d%02d.%02d\n",year,month,date, 174: hours,minutes,seconds); 175: else 176: printf("%s %s %d %02d:%02d:%02d %04d\n", 177: days[weekday(date,month, bigyear)],months[month - 1], 178: date,hours,minutes,seconds,bigyear); 179: exit(0); 180: 181: /* 182: * set the card up given the input time contained in command line. 183: */ 184: setup: 185: 186: /* 187: * Reset card for interrupts 188: */ 189: memval = (unsigned char)(SET | D24 | DM); 190: if (dst_flag == 1) 191: memval = memval | DSE; 192: *(io_ptr + REG_B) = (unsigned char)memval; 193: 194: memval = (unsigned char)DV1; 195: *(io_ptr + REG_A) = (unsigned char)memval; 196: 197: strcpy(time_str,*argv); 198: 199: seconds = 0; 200: minutes = 0; 201: hours = 0; 202: day = 0; 203: date = 0; 204: month = 0; 205: year = 0; 206: 207: (void)sscanf(time_str,"%2d%2d%2d%2d%2d.%2d",&year,&month,&date,&hours, 208: &minutes,&seconds); 209: 210: if (year <= 70) 211: bigyear = year + 2000; 212: else 213: bigyear = year + 1900; 214: 215: day = weekday(date,month,bigyear) + 1; 216: 217: *(io_ptr) = (unsigned char)seconds; 218: *(io_ptr + 2) = (unsigned char)minutes; 219: *(io_ptr + 4) = (unsigned char)hours; 220: *(io_ptr + 6) = (unsigned char)day; 221: *(io_ptr + 7) = (unsigned char)date; 222: *(io_ptr + 8) = (unsigned char)month; 223: *(io_ptr + 9) = (unsigned char)year; 224: 225: /* 226: * Start the card 227: */ 228: memval = (unsigned char)*(io_ptr + 013); 229: memval = memval & 0177; 230: *(io_ptr + 013) = (unsigned char)memval; 231: 232: exit(0); 233: } 234: 235: int weekday(day, month, year) 236: int day, month, year; 237: { 238: int index, yrndx, mondx; 239: 240: if(month <= 2) 241: { 242: month += 12; 243: year--; 244: } 245: 246: yrndx = year + (year/4) - (year/100) + (year/400); 247: mondx = (2 * month) + (3 * (month + 1)) / 5; 248: index = day + mondx + yrndx + CONST; 249: 250: return(index % 7); 251: }