|
DataMuseum.dkPresents historical artifacts from the history of: Commodore CBM-900 |
This is an automatic "excavation" of a thematic subset of
See our Wiki for more about Commodore CBM-900 Excavated with: AutoArchaeologist - Free & Open Source Software. |
top - download
Length: 7298 (0x1c82) Types: TextFile Notes: UNIX file Names: »SAV.date.c«
└─⟦f27320a65⟧ Bits:30001972 Commodore 900 hard disk image with partial source code └─⟦2d53db1df⟧ UNIX Filesystem └─ ⟦this⟧ »frankh/src/SAV.date.c«
/* * Print and set the date. */ #include <stdio.h> #include <ctype.h> #include <types.h> #include <time.h> #include <timeb.h> #include <utmp.h> #include <stat.h> #define TFCFLAG 0 /* Truly French GMT is UTC */ #define PBDDR 0x57 #define PCDD 0x0D #define PCDATA 0x1F #define PBDATA 0x1D #define MCCR 0x03 #define MICR 0x01 #define PBCSR 0x13 #define SIOCRC 0x0F int gmtflag; /* Do things in Greenwich Mean Time */ struct tm *gtime(); struct timeb tb; struct utmp utmps[2]; char utmpf[] = "/usr/adm/wtmp"; struct stat sbuf; time_t timep[2]; char btimf[] = "/etc/boottime"; #define MIN (60L) #define HOUR (60L*60L) #define DAY (60L*60L*24L) #define APR 3 #define OCT 9 /* * Table of days per month. * This will be adjusted for leap years. */ char dpm[] = { 31, 29, 31, 30, 31, 30, 31, 31, 30, 31, 30, 31 }; main(argc, argv) char *argv[]; { register char *s; register struct tm *tmp; long ltime; char *tzone; if (argc>1 && *argv[1]=='-') { if (argv[1][1]=='u' && argv[1][2]=='\0') gmtflag = 1; else usage(); argc--; argv++; } if (argc > 2) usage(); if (argc > 1) sdate(argv[1]); ftime(&tb); ltime = tb.time; s = asctime(tmp = gtime(<ime)); s[24] = '\0'; if (!gmtflag) tzone = tzname[tmp->tm_isdst]; else tzone = TFCFLAG ? "UTC" : "GMT"; printf("%s %s\n", s, tzone); } /* * Set the date/time based on * string `s'. */ sdate(s) char *s; { register char *sp; register int year; register int month; int status; int ufd; long ltime; struct tm *tmp; ftime(&tb); ltime = tb.time; utmps[0].ut_time = ltime; tmp = gtime(<ime); for (sp = s; *sp != '\0'; sp++) ; if ((sp -= 2) < s) usage(); if (sp>s && sp[-1]=='.') { tmp->tm_sec = convert(sp, 60, s); sp--; } else { sp += 2; tmp->tm_sec = 0; } tmp->tm_min = convert(sp-=2, 60, s); tmp->tm_hour = convert(sp-=2, 24, s); if ((sp-=2) >= s) { tmp->tm_mday = convert(sp, 31+1, s); if ((sp-=2) >= s) { tmp->tm_mon = convert(sp, 12+1, s) - 1; if ((sp-=2) >= s) tmp->tm_year = convert(sp, 100, s); } } if (tmp->tm_mday > dpm[tmp->tm_mon]) usage(); printf("%d\n", tmp->tm_sec); printf("%d\n", tmp->tm_min); printf("%d\n", tmp->tm_hour); printf("%d\n", tmp->tm_mday); printf("%d\n", tmp->tm_mon); printf("%d\n", tmp->tm_year); printf("%d\n", tmp->tm_wday); printf("%d\n", tmp->tm_yday); printf("%d\n", tmp->tm_isdst); okit(tmp); /* * Convert using the year, month, day, hour, minute, * and second values in the `tm' structure. * When all is completed, take care of timezone. */ ltime = tmp->tm_sec + MIN*tmp->tm_min + HOUR*tmp->tm_hour; ltime += (tmp->tm_mday-1) * DAY; year = 1900 + tmp->tm_year; /* * Adjust length of February in leap years. */ if (!isleap(year)) dpm[1] = 28; month = tmp->tm_mon; while (--month >= 0) ltime += dpm[month] * DAY; while (--year >= 1970) ltime += (long)DAY * (isleap(year) ? 366 : 365); if (!gmtflag) { ltime += timezone; tmp = localtime(<ime); if (tmp->tm_isdst) ltime -= HOUR; } status = stime(<ime); if (status < 0) { error("No permission\n"); return; } /* Correct the modtime of /etc/boottime */ stat(btimf, &sbuf); timep[0] = ltime - utmps[0].ut_time + sbuf.st_mtime; timep[1] = timep[0]; utime(btimf, timep); /* Note the change of time in /usr/adm/wtmp */ utmps[1].ut_time = ltime; utmps[0].ut_line[0] = '|'; utmps[1].ut_line[0] = '}'; if ((ufd = open(utmpf, 1)) >= 0) { lseek(ufd, 0L, 2); write(ufd, utmps, sizeof (utmps)); close(ufd); } } /* * Return 1 on leap years. */ isleap(yr) register yr; { if (yr%4000 == 0) return (0); if (yr%400==0 || (yr%100!=0 && yr%4==0)) return (1); return (0); } /* * Convert a piece of the time. * The pointer cp should never fall before * beg and the two digits parsed should be * less than max. */ convert(cp, max, beg) register char *cp; char *beg; { register val; if (cp<beg || !isdigit(cp[0]) || !isdigit(cp[1])) usage(); val = (cp[0]-'0')*10 + cp[1]-'0'; if (val >= max) usage(); return (val); } /* * Return either local time or Greenwich * Mean `tm' in a `tm' structure. */ struct tm * gtime(tp) register time_t *tp; { return (gmtflag ? gmtime(tp) : localtime(tp)); } usage() { error("Usage: date [-u] [yymmddhhmm[.ss]]\n"); } error(x) { printf("%r", &x); exit(1); } okit(tmm) struct tm *tmm; { register int fd; int i, j, status; int s1,s10,m1,m10,h1,h10,w,d1,d10,mo1,mo10,y1,y10; int stm[15]; unsigned int tmp; initio(); fd = open("/dev/port", 2); outb( fd, PCDATA, inb(fd, PCDATA) & 0x0F); /* enable 0-3 write */ outb( fd, PCDATA, (inb(fd, PCDATA) & 0x0F) | 0x02); /* set select = 1 */ outb( fd, PCDD, 0x05); /* set up CS line */ outb( fd, PCDATA, (inb(fd, PCDATA) & 0x0F) | 0x02); /* set select = 1 */ outb( fd, PBDATA, 0); outb( fd, PCDATA, inb(fd, PCDATA) & 0x0D); /* set select = 0 */ outb( fd, PBDATA, inb(fd, PBDATA) | 0x80); /* set stop = 1 */ stm[1] = tmm->tm_sec / 10; stm[0] = tmm->tm_sec - 10 * stm[1]; stm[3] = tmm->tm_min / 10; stm[2] = tmm->tm_min - 10 * stm[3]; stm[5] = tmm->tm_hour / 10; stm[4] = tmm->tm_hour - 10 * stm[5]; stm[6] = tmm->tm_wday; stm[8] = tmm->tm_mday / 10; stm[7] = tmm->tm_mday - 10 * stm[8]; stm[10] = (tmm->tm_mon + 1) / 10; stm[9] = (tmm->tm_mon + 1) - 10 * stm[10]; stm[12] = tmm->tm_year / 10; stm[11] = tmm->tm_year - 10 * stm[12]; stm[5] = stm[5] | 0x8; /* set to 24 hr mode */ for( i = 0; i < 13; ++i) wrt( i, stm[i], fd); /* wrt( 0x00, s1, fd); wrt( 0x01, s10, fd); wrt( 0x02, m1, fd); wrt( 0x03, m10, fd); wrt( 0x04, h1, fd); wrt( 0x05, h10+8, fd); wrt( 0x06, w, fd); wrt( 0x07, d1, fd); wrt( 0x08, d10, fd); wrt( 0x09, mo1, fd); wrt( 0x0a, mo10, fd); wrt( 0x0b, y1, fd); wrt( 0x0c, y10, fd); */ wrt( 0x0D, 0, fd); outb( fd, PBDATA, inb(fd, PBDATA) & ~0x80); /* set stop = 0 */ outb( fd, PCDATA, (inb(fd, PCDATA) & 0x0F) | 0x02); /* set select = 1 */ cloio(); } red(reg, fd) int fd; unsigned int reg; { unsigned int tmp; /* outb(fd, PBDATA, (inb(fd, PBDATA) & 0xF0) | reg); */ outb(fd, PBDATA, reg); outb(fd, PBDATA, (inb(fd, PBDATA) | 0x40)); tmp = 5 * 5; outb(fd, PBDATA, (inb(fd, PBDATA) & ~0x40)); /* * make PB0-3 input lines */ outb(fd, PBDDR, (inb(fd, PBDDR) | 0x0F)); tmp = 5 * 3 * 4; outb(fd, PBDATA, (inb(fd, PBDATA) | 0x10)); tmp = 9 * 8 * 9; tmp = inb(fd, PBDATA) & 0x0F; outb(fd, PBDATA, (inb(fd, PBDATA) & ~0x10)); /* * make PB0-3 output lines */ outb(fd, PBDDR, (inb(fd, PBDDR) & 0xF0)); return(tmp); } wrt(reg, data, fd) int fd; unsigned int reg; unsigned int data; { unsigned int tmp; /* outb(fd, PBDATA, (inb(fd, PBDATA) & 0xF0) | reg); */ outb(fd, PBDATA, reg); outb(fd, PBDATA, (inb(fd, PBDATA) | 0x40)); tmp = 5 * 5; outb(fd, PBDATA, (inb(fd, PBDATA) & ~0x40)); tmp = 5 * 3; outb(fd, PBDATA, ((inb(fd, PBDATA) & 0xF0) | data)); outb(fd, PBDATA, (inb(fd, PBDATA) | 0x20)); tmp = 3 * 4 * 7; outb(fd, PBDATA, (inb(fd, PBDATA) & ~0x20)); } dumpreg(fd) int fd; { printf("\nPBDDR:\t%x\n", inb(fd, PBDDR)); printf("PCDDR:\t%x\n", inb(fd, PCDD)); printf("PBDATA:\t%x\n", inb(fd, PBDATA)); printf("PCDATA:\t%x\n", inb(fd, PCDATA)); printf("MICR:\t%x\n", inb(fd, MICR)); printf("MCCR:\t%x\n", inb(fd, MCCR)); printf("PBCSR:\t%x\n", inb(fd, PBCSR)); printf("SIOCRC:\t%x\n\n", inb(fd, SIOCRC)); }