ng@pur-phy (Nicholas J. Giordano) (12/31/87)
Many months ago I asked for information from the net about the Jtime clock project. Jtime is a small battery backed up real time clock for the Amiga, which is described on one of the Fish disks. I had asked for help locating the source to the Jtime program, and any other information. Well, I didn't get any help, although a number of people did want to know if I found out anything. So, I built the clock, and it works just great. Also, I wrote my own program to read from and write to the clock. This program is in many ways better than the original jtime program (see the readme file below). Anyway, I thought that someone out there might be interested, so here it is. Following is the source and uuencoded executable for this program, along with some miscellaneous comments. I hope someone finds it to be useful. The jtime clock is an ideal first project for a novice (like me). I strongly recommend it. Let me add that any and all comments would be appreciated (although I don't think that I need to say this with this newsgroup). #! /bin/sh # This is a shell archive, meaning: # 1. Remove everything above the #! /bin/sh line. # 2. Save the resulting text in a file. # 3. Execute the file with /bin/sh (not csh) to create the files: # readme # makefile # time.c # time.uue # This archive created: Wed Dec 30 13:47:59 1987 export PATH; PATH=/bin:$PATH if test -f 'readme' then echo shar: will not over-write existing file "'readme'" else cat << \SHAR_EOF > 'readme' This shar file contains the source and executable of a program to run the Jtime battery backed up real time clock. Jtime is a home project described on Fish disk #65. I recently built it, and it works fine, just as advertised. However, I wanted to write my own program to run the clock for several reasons. First, I was curious how to do it. Second, the Fish disk contains only the executable (no source), so I couldn't get a look at how the program works. Third, the executable on the Fish disk (which works just fine) is 21K, which is a bit large. [Presumably it was compiled with Lattice.] I have Manx, so I hoped to produce a much smaller version (which I did - mine is less than 10K - without any special effort to avoid printf's, etc.). Fourth, I didn't like the way the Jtime program worked. It writes the date into a file in ram:; one then has to use the Date command to set the Amiga system clock, and then delete the temporary file. I wanted to set the Amiga clock directly. Fifth, just before I began this project I came across the plans for a different home project clock module. While I prefer the Jtime circuit, the source program for reading and setting the other clock module was available, and was a big help for me in putting together my program. [That is another way of saying that I used several of the routines from the other program.] My program was compiled with Manx 3.4a. It is called time (although you can of course rename it anything you like, I just didn't want it confused with the original Jtime program) and can be used in several ways. (1) time [-]read will read the time stored in Jtime, use it to set the Amiga system time, and print out the time. (2) time [-]set will prompt the user for the current time, and use it to set both Jtime and the Amiga system time. (3) time just prints out the Jtime time (4) time ? gives usage information. I hope you find the program useful. Any comments or suggestions would be welcome. Nick Giordano Physics Department Purdue University West Lafayette, IN 47907 10-87 SHAR_EOF fi # end of overwriting check if test -f 'makefile' then echo shar: will not over-write existing file "'makefile'" else cat << \SHAR_EOF > 'makefile' time : time.o ln -o time time.o -lc time.o : time.c cc time.c SHAR_EOF fi # end of overwriting check if test -f 'time.c' then echo shar: will not over-write existing file "'time.c'" else cat << \SHAR_EOF > 'time.c' /* * time.c * * A program for reading from and writing to the Jtime battery * backed up real time clock for the Amiga 1000. * * Copyright 1987, Nick Giordano * Feel free to use this, but don't sell it!! * * The Jtime clock was designed by Michael Keryan. * A description of the Jtime clock circuit and its operation can be * found on Fish disk #65. * * A program to talk to the Jtime clock can also be found on Fish disk * #65, but this program is, in my opinion, "better" for several reasons: * (1) This program writes the date and time obtained from the Jtime * clock directly into the Amiga timer device - there is no need * to create (and then delete) a temporary file in ram: * (2) This program is less than half the size of the old one. * * Portions of this code were obtained from the programs clockrd.c, * clockwr.c, and clocktest.c by Graeme Clark (9/87). * Thanks Graeme. * * This program was compiled using Manx 3.4a using 16 bit integers: * * cc time.c * ln -o time time.o -lc * ********************************************************************* * * usage : * * "time -set" or "time set" * * prompts user for the time and uses it to set Jtime * and the Amiga time * * * "time -read" or "time read" * * sets the Amiga clock using the time as read from Jtime * * * "time" * * print the Jtime time but don't set the Amiga system time * * * "time ?" * * gives usage information * */ #include <stdio.h> #include <exec/types.h> #include <hardware/custom.h> #include <hardware/cia.h> #include <resources/potgo.h> #include <functions.h> #include <devices/timer.h> /* * nice_time - structure to hold the time in convenient format * */ struct nice_time { int year; /* e.g. 1986 */ int month; /* 1 ... 12 */ int day; /* 1 ... 31 */ int day_of_week; /* 0(Sun) ... 6(Sat) */ int hour; /* 0 ... 23 */ int minute; /* 0 ... 59 */ int second; /* 0 ... 59 */ }; int * JOY1DAT = 0xDFF00C; /* needed to read mouse port lines */ #define BIT0 0001 #define BIT1 0002 #define BIT8 0400 #define BIT9 01000 #define SEC_1 0 #define SEC_10 1 #define MIN_1 2 #define MIN_10 3 #define HOUR_1 4 #define HOUR_10 5 #define WEEK 6 #define DAY_1 7 #define DAY_10 8 #define MON_1 9 #define MON_10 10 #define YEAR_1 11 #define YEAR_10 12 #define ADDRESS_WRITE 16 #define READ 32 #define DATA_WRITE 64 #define ERROR -1 #define OK 0 int getline(), term_port(), l5(), h5(), l9(), h9(); int rr1(), rr2(), rr3(), rr4(); int get_time(), set_time(), print_time(); int init_port(),term_port(); main(argc,argv) int argc; char *argv[]; { struct nice_time tm; if(argc < 2) { if(read_jtime(&tm) == OK) { print_time(&tm); } } else if((strcmp(argv[1],"-set") == 0) || (strcmp(argv[1],"set") == 0)) { if(input_time(&tm) == OK) { if(set_jtime(&tm) == OK) { if(set_amiga_time(&tm) == OK) { print_time(&tm); } } } } else if((strcmp(argv[1],"-read") == 0) || (strcmp(argv[1],"read") == 0)) { if(read_jtime(&tm) == OK) { printf("Reading clock and setting the time to\n"); set_amiga_time(&tm); print_time(&tm); } } else print_usage(); } int print_usage() { printf("usage :\n\ttime [-]set\t\tset Jtime and Amiga time\n"); printf("\ttime [-]read\t\tread Jtime and set Amiga time\n"); printf("\ttime\t\tjust print the Jtime time\n"); printf("\ttime?\t\tprint usage information\n"); return; } /* * input_time() -- prompt for the time and date and place in the * * given nice_time structure * returns OK normally, ERROR if error */ int input_time(tm) struct nice_time *tm; { int get_int(); printf("If you goof or change your mind and don't want to set the\n"); printf("clocks, just press return\n"); printf("\n"); if ((tm->year = get_int("Year, e.g. 1986")) == ERROR) return(ERROR); if ((tm->month = get_int("Month (1..12)" )) == ERROR) return(ERROR); if ((tm->day = get_int("Day (1..31)" )) == ERROR) return(ERROR); if ((tm->day_of_week = get_int("Day of Week (0=Sun, ..., 6=Sat)")) == ERROR) return(ERROR); if ((tm->hour = get_int("Hour (0..23)" )) == ERROR) return(ERROR); if ((tm->minute = get_int("Minute (0..59)" )) == ERROR) return(ERROR); tm->second = 0; if(check_time(tm) == ERROR) { printf("The time you entered makes no sense\n"); return(ERROR); } return(OK); } /* * get_int() -- display the given prompt and read an integer, * returning it or ERROR if a blank line is input */ int get_int(prompt) char *prompt; { char buf[80]; char *cp; int atoi(), getline(); printf("%s: ", prompt); fflush(stdout); getline(buf); for (cp=buf; *cp == ' '; ++cp) ; if (*cp == '\0') return(ERROR); else return(atoi(cp)); } /* * getline() -- read a line from stdin */ int getline(buf) char *buf; { int ch; while ((ch = getchar()) != '\n' && ch != EOF) *buf++ = ch; *buf = '\0'; } /* * set the jtime clock to the time specified in tm */ int set_jtime(tm) struct nice_time *tm; { if(init_port() == ERROR) { return(ERROR); } set_time(tm); term_port(); return(OK); } /* * read the jtime clock and return the result in tm */ int read_jtime(tm) struct nice_time *tm; { int status = OK; if(init_port() == ERROR) { return(ERROR); } get_time(tm); if(check_time(tm) == ERROR) { printf("Clock error - time reading from Jtime makes no sense\n"); status = ERROR; } term_port(); return(status); } /* * nice_to_sec() -- convert the given nice_time structure into * seconds since 00:00:00 January 1, 1978 * as needed for setting the amiga time */ long nice_to_sec(tm) struct nice_time *tm; { long days_since_base; static int mdays[] = { 0, 0, 31, 31+28, 31+28+31, 31+28+31+30, 31+28+31+30+31, 31+28+31+30+31+30, 31+28+31+30+31+30+31, 31+28+31+30+31+30+31+31, 31+28+31+30+31+30+31+31+30, 31+28+31+30+31+30+31+31+30+31, 31+28+31+30+31+30+31+31+30+31+30 }; static int leapmdays[] = { 0, 0, 31, 31+29, 31+29+31, 31+29+31+30, 31+29+31+30+31, 31+29+31+30+31+30, 31+29+31+30+31+30+31, 31+29+31+30+31+30+31+31, 31+29+31+30+31+30+31+31+30, 31+29+31+30+31+30+31+31+30+31, 31+29+31+30+31+30+31+31+30+31+30 }; /* first compute number of days since January 1, 1978 */ days_since_base = (tm->year-1978) * 365L + (tm->year-1977)/4; if (tm->year%4 == 0) days_since_base += leapmdays[tm->month]; else days_since_base += mdays[tm->month]; days_since_base += tm->day-1; /* now the rest is easy */ return(days_since_base * (60L*60L*24L) + tm->hour * (60L*60L) + tm->minute * (60L) + tm->second); } /* * set_amiga_time() -- set the amiga system time * Returns OK normally, and ERROR if an error occurs */ int set_amiga_time(tm) struct nice_time *tm; { long nice_to_secs(), secs; struct timerequest tr; secs = nice_to_sec(tm); if (OpenDevice (TIMERNAME, UNIT_VBLANK, &tr, 0L) != 0L) { printf("Clock error: can't open timer device\n"); return(ERROR); } tr.tr_node.io_Message.mn_Node.ln_Type = NT_MESSAGE; tr.tr_node.io_Message.mn_Node.ln_Pri = 0L; tr.tr_node.io_Message.mn_Node.ln_Name = NULL; tr.tr_node.io_Message.mn_ReplyPort = NULL; tr.tr_node.io_Command = TR_SETSYSTIME; tr.tr_time.tv_secs = secs; tr.tr_time.tv_micro = 0L; if (DoIO (&tr) != 0) { printf("Clock error: can't talk to timer device\n"); CloseDevice(&tr); return(ERROR); } CloseDevice (&tr); return(OK); } /* * check_time() -- see if the given nice_time structure contains * reasonable values; return OK if so, ERROR otherwise */ int check_time(tm) struct nice_time *tm; { #define WITHIN(val, lower, upper) ((lower<=val) & (val<=upper)) if (WITHIN(tm->year, 1978, 1999) && WITHIN(tm->month, 1, 12) && WITHIN(tm->day, 1, 31) && WITHIN(tm->day_of_week, 0, 6) && WITHIN(tm->hour, 0, 23) && WITHIN(tm->minute, 0, 59) && WITHIN(tm->second, 0, 59)) return(OK); else return(ERROR); } /* * Variables for the clock routines */ struct Library *PotgoBase; /* points to Potgo Resource */ long potgo_bits; /* mask indicating which bits of the */ /* potgo resource we have allocated */ /* * init_port -- initialize the joystick port (right game port) so * that we can talk to the clock * Returns OK normally, and ERROR if an error occurs */ int init_port() { /* open the Potgo resource so we can allocate ourselves the port */ PotgoBase = (struct Library *)OpenResource(POTGONAME); if (PotgoBase == NULL) { printf("Clock error: can't open Potgo resource\n"); return(ERROR); } /* ask for the output bits of the right game port */ potgo_bits = AllocPotBits(0xF000L); /* see if we got all the bits we asked for */ if (!((potgo_bits & 0x4000L) && (potgo_bits & 0x1000L) && (potgo_bits & 0x8000L) && (potgo_bits & 0x2000L))) { printf("Clock error: can't allocate gameport bits\n"); return(ERROR); } /* enable pins 5 and 9 for output, setting them both to 1 */ WritePotgo(0xF000L, 0xF000L); pause(); /* wait for lines to settle */ l5(); /* needed because when first turned on, line 5 seems to always be high */ pulse9(1); /* clear the jtime counter */ return(OK); } /* * term_port() -- release the game port */ int term_port() { /* set pins 5 and 9 back to input mode */ WritePotgo(0x0000L, 0xF000L); FreePotBits(potgo_bits); /* I would think we should close the resource here, but */ /* CloseResource() doesn't seem to exist */ } /* * l5() -- set the pin 5 of the game port low */ int l5() { WritePotgo(0x0000L, 0x1000L); pause(); } /* * h5() -- set pin 5 of the game port high */ int h5() { WritePotgo(0x1000L, 0x1000L); pause(); } /* * l9() -- set pin 9 of the game port low */ int l9() { WritePotgo(0x0000L, 0x4000L); pause(); } /* * h9() -- set pin 9 of the game port high */ int h9() { WritePotgo(0x4000L, 0x4000L); pause(); } /* * xor() function needed below */ int xor(i,j) int i,j; { if(i != j) return(1); else return(0); } /* * pause() -- delay for enough time for the gameport output lines * to settle. The RKM gives this time as 300 micro- * seconds, so to be on the safe side this routine * pauses for about 500 microseconds. * This routine depends on the CPU being a 68000 running * at 7.16 Mhz */ int pause() { int i; for (i=1; i<= 70; ++i) ; } /* * get_time() -- read the time from jtime and place it in a * nice_time structure. */ int get_time(tm) struct nice_time *tm; { int read_reg(); tm->year = 1900 + 10 * read_reg(YEAR_10) + read_reg(YEAR_1); tm->month = 10 * (read_reg(MON_10) & 1) + read_reg(MON_1); tm->day = 10 * (read_reg(DAY_10) & 3) + read_reg(DAY_1); tm->day_of_week = read_reg(WEEK); tm->hour = 10 * (read_reg(HOUR_10) & 3) + read_reg(HOUR_1); tm->minute = 10 * (read_reg(MIN_10) & 7) + read_reg(MIN_1); tm->second = 10 * (read_reg(SEC_10) & 7) + read_reg(SEC_1); } /* * print_time() -- display the contents of a nice_time structure */ int print_time(tm) struct nice_time *tm; { static char *mnames[12] = {"Jan", "Feb", "Mar", "Apr", "May", "Jun", "Jul", "Aug", "Sep", "Oct", "Nov", "Dec"}; static char *dnames[7] = {"Sunday", "Monday", "Tuesday", "Wednesday", "Thursday", "Friday", "Saturday"}; if(check_time(tm) == OK) { printf("%-9s %2d-%s-%02d %2d:%02d:%02d", dnames[tm->day_of_week], tm->day, mnames[tm->month-1], tm->year % 100, (tm->hour==0) ? 12 : (tm->hour<=12) ? tm->hour : tm->hour-12, tm->minute, tm->second); if (tm->hour < 12) printf(" AM\n"); else printf(" PM\n"); } } /* * set_time() -- set the jtime clock */ int set_time(tm) struct nice_time *tm; { int write_reg(); int leap_year, pm; leap_year = (tm->year%4 == 0); pm = (tm->hour >= 12); write_reg(YEAR_10, (tm->year%100)/10); write_reg(YEAR_1, tm->year%10); write_reg(MON_10, tm->month/10); write_reg(MON_1, tm->month%10); write_reg(DAY_10, (tm->day/10) | (leap_year<<2)); write_reg(DAY_1, tm->day%10); write_reg(WEEK, tm->day_of_week); write_reg(HOUR_10, (tm->hour/10) | (pm<<2) | 8); write_reg(HOUR_1, tm->hour%10); write_reg(MIN_10, tm->minute/10); write_reg(MIN_1, tm->minute%10); write_reg(SEC_10, tm->second/10); write_reg(SEC_1, tm->second%10); } /* * write "num" into the jtime clock register # reg */ int write_reg(reg, num) int reg, num; { pulse5(ADDRESS_WRITE + reg); pulse9(1); pulse5(DATA_WRITE + num); pulse9(1); return; } /* * pulse line 5 high num times */ int pulse5(num) int num; { while(num-- > 0) { h5(); pause(1); l5(); pause(1); } return; } /* * pulse line 9 high num times */ int pulse9(num) int num; { while(num-- > 0) { h9(); Delay(1L); /* needed to allow lines to settle */ l9(); Delay(1L); } return; } /* * read jtime register num */ int read_reg(num) int num; { int rr1(),rr2(),rr3(),rr4(); int tmp; pulse5(ADDRESS_WRITE + num); pulse9(1); pulse5(READ); h9(); Delay(1L); tmp = rr4() * 8 + rr3() * 4 + rr2() * 2 + rr1(); l9(); Delay(1L); return(tmp); } /* * return the value of line 1 * * This implementation assumes the right mouse port contents are * found at address JOY1DAT. This will probably be the case until * the amiga custom chips are changed. After that, who knows?? * A better method would be to communicate through the exec * which I will do in the next version. */ int rr1() { int i,j; int xor(); if((BIT8 & *JOY1DAT) == 0) i = 0; else i = 1; if((BIT9 & *JOY1DAT) == 0) j = 0; else j = 1; pause(); return(xor(i,j)); } /* * return the value of line 2 */ int rr2() { int i,j; int xor(); if((BIT0 & *JOY1DAT) == 0) i = 0; else i = 1; if((BIT1 & *JOY1DAT) == 0) j = 0; else j = 1; pause(); return(xor(i,j)); } /* * return the value of line 3 */ int rr3() { int i; if((BIT9 & *JOY1DAT) == 0) i = 0; else i = 1; pause(); return(i); } /* * return the value of line 4 */ int rr4() { int i; if((BIT1 & *JOY1DAT) == 0) i = 0; else i = 1; pause(); return(i); } SHAR_EOF fi # end of overwriting check if test -f 'time.uue' then echo shar: will not over-write existing file "'time.uue'" else cat << \SHAR_EOF > 'time.uue' begin 3 time.uue M #\P # ( B] R $ /I (O4[Z$41. M5?_R#&T @ (;!Q(;?_R3KH$@EA/2D!F"DAM__).N@JF6$]@ # 2'H P"!M M HO* $3KH5-E!/2D!G%DAZ *\@;0 *+R@ !$ZZ%2!03TI 9C9(;?_R3KH! MGEA/2D!F)DAM__).N@0&6$]*0&882&W_\DZZ!6)83TI 9@I(;?_R3KH*0EA/ M8%Q(>@!G(&T "B\H 1.NA344$]*0&<62'H 5R!M HO* $3KH4OE!/2D!F M+DAM__).N@/86$]*0&8>2'H .$ZZ%;I83TAM__).N@4$6$](;?_R3KH)Z%A/ M8 )A0$Y=3G4M<V5T '-E= M<F5A9 !R96%D %)E861I;F<@8VQO8VL@86YD M('-E='1I;F<@=&AE('1I;64@=&\* !.50 2'H *DZZ%5183TAZ %!.NA5* M6$](>@!T3KH50%A/2'H C$ZZ%3983TY=3G5U<V%G92 Z"@ET:6UE(%LM77-E M= D)<V5T($IT:6UE(&%N9"!!;6EG82!T:6UE"@ )=&EM92!;+5UR96%D"0ER M96%D($IT:6UE(&%N9"!S970@06UI9V$@=&EM90H "71I;64)"6IU<W0@<')I M;G0@=&AE($IT:6UE('1I;64* ET:6UE/PD)<')I;G0@=7-A9V4@:6YF;W)M M871I;VX* !.50 2'H ]$ZZ%()83TAZ 25.NA1X6$](>@$V3KH4;EA/2'H! M+DZZ ;983R!M @P@+!\__]F!G#_3EU.=4AZ 2).N@&:6$\@;0 (,4 K!\ M__]F!'#_8.!(>@$43KH!?EA/(&T "#% 2P?/__9@1P_V#$2'H!!$ZZ 6)8 M3R!M @Q0 &L'S__V8$</]@J$AZ 0A.N@%&6$\@;0 (,4 "+!\__]F!'#_ M8(Q(>@#Y3KH!*EA/(&T "#% JP?/__9@9P_V _W @;0 (0F@ #"\M A. MN@/T6$^P?/__9A!(>@#23KH3HEA/</]@ /](< !@ /]"268@>6]U(&=O;V8@ M;W(@8VAA;F=E('EO=7(@;6EN9"!A;F0@9&]N)W0@=V%N="!T;R!S970@=&AE M"@!C;&]C:W,L(&IU<W0@<')E<W,@<F5T=7)N"@ * %EE87(L(&4N9RX@,3DX M-@!-;VYT:" H,2XN,3(I $1A>2 H,2XN,S$I $1A>2!O9B!7965K("@P/5-U M;BP@+BXN+" V/5-A="D 2&]U<B H,"XN,C,I $UI;G5T92 H,"XN-3DI %1H M92!T:6UE('EO=2!E;G1E<F5D(&UA:V5S(&YO('-E;G-E"@ 3E7_K"\M A( M>@!03KH2H%!//SS__TAL@3!.NAA27$](;?^P83I83T'M_[ K2/^L8 12K?^L M(&W_K P0 "!G\B!M_ZQ*$&8&</].74YU+RW_K$ZZ"WA83V#P)7,Z( 3E7_ M_DAL@1I.N@O46$\[0/_^L'P "F<6#&W____^9PX@;0 (4JT "!"M__]@UB!M M A"$$Y=3G5.50 3KH#=K!\__]F!G#_3EU.=2\M A.N@>:6$].N@1,< !@ MZDY5__Y";?_^3KH#3+!\__]F!G#_3EU.=2\M A.N@366$\O+0 (3KH""EA/ ML'S__V802'H &$ZZ$;A83SM\_____DZZ! (P+?_^8,A#;&]C:R!E<G)O<B M M('1I;64@<F5A9&EN9R!F<F]M($IT:6UE(&UA:V5S(&YO('-E;G-E"@!.5?_\ M(&T "# 0D'P'NL'\ 6TB;0 (,A&2? >Y2,&#_ $2,'0@2M __P@;0 (,!!( MP('\ 1(0$I 9AP@;0 (,"@ DC XX!#[( @,C$( $C!TZW__& :(&T "# H M )(P.. 0^R !C(Q" !(P=.M__P@;0 (,"@ !%- 2,#1K?_\(&T "# H C! M_ X0(FT "#(I K#_ \T($L;0 (-"X #$C"T((B/ !48 O " M__Q.N@_@ M)@ @']"#3EU.=4Y5_]0O+0 (3KK_-%A/*T#__$*G2&W_U$AX %(>@!T3KH< M2D_O !!*@&<02'H <4ZZ$'I83W#_3EU.=1M\ 7_W$(M_]U"K?_>0JW_XCM\ M O_\"MM__S_]$*M__A(;?_43KH;PEA/2H!G&$AZ %=.NA Z6$](;?_43KH; M@%A/</]@M$AM_]1.NAMR6$]P &"F=&EM97(N9&5V:6-E $-L;V-K(&5R<F]R M.B!C86XG="!O<&5N('1I;65R(&1E=FEC90H 0VQO8VL@97)R;W(Z(&-A;B=T M('1A;&L@=&\@=&EM97(@9&5V:6-E"@!.50 (&T "# \![JP4&X$<@%@ G( M(FT " Q1!\]N!'0!8 )T ,)"9P ]BQM AV ;9N )N!'8!8 )V "QM @, M;@ , )N!'0!8 )T ,9"9P S"QM @R? !LNX !&X$=@%@ G8 +&T " QN M !\ !&X$= %@ G0 QD)G "@+&T "$IN 9M!'8!8 )V "QM @,;@ & 9N M!'0!8 )T ,9"9W@L;0 (2FX "&T$=@%@ G8 +&T " QN !< "&X$= %@ G0 MQD)G4BQM A*;@ *;01V 6 "=@ L;0 (#&X .P *;@1T 6 "= #&0F<L+&T M"$IN QM!'8!8 )V "QM @,;@ [ QN!'0!8 )T ,9"9P9P $Y=3G5P_V#X M3E4 $AZ (A.NAIV6$\I0(,62JR#%F802'H @TZZ#GQ83W#_3EU.=4AY #P M $ZZ&JQ83RE @QH(+ &@QQG& @L 2#'&<0""P !X,<9P@(+ %@QQF#DAZ M &M.N@X\6$]P_V"^2'D / 2'D / 3KH:@%!/3KH!"DZZ )(_/ !3KH% MLE1/< !@EG!O=&=O+G)E<V]U<F-E $-L;V-K(&5R<F]R.B!C86XG="!O<&5N M(%!O=&=O(')E<V]U<F-E"@!#;&]C:R!E<G)O<CH@8V%N)W0@86QL;V-A=&4@ M9V%M97!O<G0@8FET<PH 3E4 $AY #P $*G3KH9]E!/+RR#&DZZ&>!83TY= M3G5.50 2'@0 $*G3KH9V%!/86).74YU3E4 $AX$ !(>! 3KH9P%!/84I. M74YU3E4 $AX0 !"ITZZ&:I03V$T3EU.=4Y5 !(>$ 2'A $ZZ&9)03V$< M3EU.=4Y5 P+0 (L&T "F<&< %.74YU< !@^$Y5__X[? !__Y2;?_^#&T M1O_^;_1.74YU3E4 "!M @O"#\\ Q.N@2\5$_!_ */P _/ +3KH$K%1/ M,A_20"!?TGP';#"!(&T ""\(/SP "DZZ!)!43\!\ '!_ *(%\_ "\(/SP M"4ZZ!'A43R!?,A_20#%! (@;0 (+P@_/ (3KH$7E1/P'P \'\ H@7S\ M+P@_/ '3KH$1E1/(%\R']) ,4$ !#\\ 9.N@0R5$\@;0 (,4 !B!M @O M"#\\ 5.N@0:5$_ ? #P?P "B!?/P O"#\\ 1.N@0"5$\@7S(?TD Q00 ( M(&T ""\(/SP TZZ ^A43\!\ ?!_ *(%\_ "\(/SP DZZ ]!43R!?,A_2 M0#%! H@;0 (+P@_/ !3KH#ME1/P'P !\'\ H@7S\ +PA"9TZZ Z!43R!? M,A_20#%! Q.74YU3E4 "\M A.NOOV6$]*0&8 +0@;0 (/R@ #")M @_ M*0 *+&T "$IN AF!' ,8"(L;0 (#&X # (;@HL;0 (,"X "& ,+&T "# N M B0? ,/P L;0 (,A9(P8/\ &1(03\!+&T "#0N )30DC"Y8)-[( Z+S8H M "QM @_+@ $+&T "#8N 9(P^6#3>R :B\V. !(>@"93KH+($_O !8@;0 ( M#&@ # (; Q(>@"@3KH+"%A/8 I(>@"93KH*_%A/3EU.=4IA;@!&96( 36%R M $%P<@!-87D 2G5N $IU; !!=6< 4V5P $]C= !.;W8 1&5C %-U;F1A>0!- M;VYD87D 5'5E<V1A>0!7961N97-D87D 5&AU<G-D87D 1G)I9&%Y %-A='5R M9&%Y "4M.7,@)3)D+25S+24P,F0@)3)D.B4P,F0Z)3 R9 @04T* "!030H M3E7__"!M @P$$C @?P !$A L'P %?!PGP 3M!__X@;0 (#&@ # (7,# M? !.T#__"!M @P$$C @?P 9$A 2,"!_ */P _/ ,3KH!2EA/(&T "# 0 M2,"!_ *2$ _ #\\ M.N@$P6$\@;0 (,"@ DC @?P "C\ /SP "DZZ 198 M3R!M @P* "2,"!_ *2$ _ #\\ E.N@#Z6$\@;0 (,"@ !$C @?P "C(M M__[E08!!/P _/ (3KH V%A/(&T "# H 1(P('\ I(0#\ /SP !TZZ +Q8 M3R!M @_* &/SP !DZZ *I83R!M @P* (2,"!_ *,BW__.5!@$$(P # M/P _/ %3KH A%A/(&T "# H A(P('\ I(0#\ /SP !&%H6$\@;0 (,"@ M"DC @?P "C\ /SP V%06$\@;0 (,"@ "DC @?P "DA /P _/ "83983R!M M @P* ,2,"!_ */P _/ !81Y83R!M @P* ,2,"!_ *2$ _ $)G8098 M3TY=3G5.50 ,"T "-!\ ! _ &$D5$\_/ !84Y43S M K0? ! /P!A#E1/ M/SP 6$X5$].74YU3E4 # M A3;0 (2D!O'DZZ^PX_/ !3KK[9%1/3KKZ MZC\\ %.NOM65$]@UDY=3G5.50 ,"T "%-M A*0&\>3KK["DAX %.NA,: M6$].NOKF2'@ 4ZZ$PQ83V#63EU.=4Y5__XP+0 (T'P $#\ 88Q43S\\ %A MME1//SP ($ZZ_WQ43TZZ^L1(> !3KH2U%A/3KH \N= /P!.N@#$Y4 R']) M/P%A;N- ,A_20#\!81XR']) .T'__DZZ^GA(> !3KH2GEA/,"W__DY=3G5. M5?_\(&R @@0 !F!D)M__Y@!CM\ '__B!L@ (($ !9@9";?_\8 8[? ! M__Q.NOIX/RW__#\M__Y.NOI46$].74YU3E7__"!L@ ((* %F!D)M__Y@ M!CM\ '__B!L@ ((* ! %F!D)M__Q@!CM\ '__$ZZ^BX_+?_\/RW__DZZ M^@I83TY=3G5.5?_^(&R @@0 %F!D)M__Y@!CM\ '__DZZ^?XP+?_^3EU. M=4Y5__X@;( """@ 0 !9@9";?_^8 8[? !__Y.NOG6,"W__DY=3G5.50 M2.<,("1M @,$@ @9P8,$@ )9@12BF#P>@ ,$@ M9@9Z 5**8 @,$@ K9@)2 MBG@ 8!8@2E**$!!(@#($POP "M!!. "8? P$!)(@%) 0>R F @P ( &;8 M2D5G!C $1$!@ C $3-\$,$Y=3G5.50 2.<(("1M @O"DZZ #)83S@ L'S_ M_V<B, 1(P& 44Y((Z@ # QP_TS?!!!.74YU8-9*@&?Z68!GY# $8.I.50 M+PHD;0 ((%*QZ@ $90PO"F$66$\D7TY=3G4@4E*2$!!(@,!\ /]@[$Y5 !( MYP@P)&T "! J S / 89PIP_TS?#!!.74YU"*H @ ,2JH "&8(+PI.N@RL M6$\0*@ ,2( ( '9S!![($:)D@0*P ,2(# ? "$L'P A&8,/SS__R\+3KH+ M9%Q/U_P 60>R"TK?(9=8_*@ 0+RH "! J U(@#\ 3KH#O%!/. !*0&X4 M2D1F!' (8 )P$($J QP_V _WHP!$C )*H "-"J @E0 $(%)2DA 02(# M? #_8 #_6F%P0^R"UD7L@M:UR68.,CP $FL(= BPE')__PI3X+:+'@ !"E. M@MY(YX" ""X ! $I9Q!+^@ (3J[_XF &0J?S7TYS0_H ($ZN_F@I0(+B9@PN M/ #@ =.KO^48 1.N@ :4$].=61O<RYL:6)R87)Y $GY !__DYU3E4 "\* M2'D 0 ,"R"TL'\ 8O $ZZ$!Q03RE @N9F%$*G2'D 0 3KH/U%!/+FR" MVDYU(&R"YD)H 0@;(+F,7P 0 0(FR"YC-\ $ "B!L@MH@+(+:D*@ !%" M*4""ZB!L@NH@O$U!3EA"ITZZ#^983R1 2JH K&<N+RT #"\M @O"DZZ +)/ M[P ,.7P 8+N(&R"Y@!H@ !"!L@N8 :( I@1$AJ %Q.NA F6$](:@!< M3KH/P%A/*4""\"!L@O!*J D9Q @;(+P(F@ )"\13KH.M%A/+RR"\"\*3KH# M+E!/*6R"\(+T3KH.P"!L@N8@@$ZZ#N @;(+F(4 !F<62'@#[4AZ "Q.N@Z\ M4$\@;(+F(4 #"\L@O0_+(+X3KKM'%Q/0F=.N@SX5$\D7TY=3G4J $Y5 !( MYPPP)&T $"!M @@* "LY8 H "!$("@ $.6 )D 0$TB 2,#0K0 ,5( Y0(+Z M0J<P+(+Z2, O $ZZ#KI03RE @OQF"$S?##!.74YU$!-(@#\ ($M2B"\(+RR" M_$ZZ 41/[P *2'H!.A 32(!(P-"L@OPO $ZZ BI03S\M XO"B\L@OQ.N@'& M3^\ "D)L@O@F;(+\)$L0$TB .@"P? @9QBZ? )9Q*Z? ,9PRZ? -9P:Z M? *9@12BV#8#!, (&UZ#!, (F8N4HL@2U*+$!!(@#H 9QX@2E**$(6Z? B M9A ,$P B9@12BV &0BK__V "8-9@."!+4HL0$$B .@!G)KI\ "!G(+I\ EG M&KI\ QG%+I\ UG#KI\ IG""!*4HH0A6#.($I2BD(02D5F E.+4FR"^& M_UI"$D*G,"R"^%) 2,#E@"\ 3KH-I%!/*4""]&8(0FR"^& _N1Z "9L@OQ@ M'C %2,#E@"!L@O0ABP@ +PM.N@9X6$]20$C U\!21;IL@OAMW# %2,#E@"!L M@O1"L @ 8 #^IB 3.\# $( @R+P ,8 (0V5?)__QG!E)!8 )"&%')__Q. M=4Y5 !(YPP@."T "$ZZ"KHP!,'\ 8D0-7L@N9*1&T*N&R"TFP$2I)F$#E\ M *# '#_3-\$,$Y=3G4P*@ $P'P [!\ %F"CE\ 6# '#_8.!P # M XO M "\M HO$DZZ#'Y/[P ,*@"PO/____]F#$ZZ#$(Y0(, </]@M" %8+ P/'__ M8 0P+P ,(&\ !$H89OQ32")O A30!#95\C__&<"0A @+P $3G4P/'__8 0P M+P ,4T!K%"!O 0B;P (L0EF#%-(2AA7R/_V< !.=6,$< %.=7#_3G4@;P $ M( @B;P ($-EF_$YU2.=P #0!Q, F 4A#QL!(0T)#U(-(0,#!2$!"0-""3-\ M#DYU3E4 $CG#C D;0 (0J=(>@".3KH,=E!/*4"#'F8(3-\,<$Y=3G4@;0 , M(F@ )"\I 1.N@RV6$\H &=22'H ;2!$+R@ -DZZ#(A03R9 2H!G-$AX ^TO M"TZZ"V!03RP 9R0@!N6 *@ @125H @ I"5& )Q(> /M2'H .$ZZ"SQ03R5 M * O!$ZZ#%183R\L@QY.N@M\6$]"K(,>8(!I8V]N+FQI8G)A<GD 5TE.1$]7 M "H 3E4 $AM PO+0 (2'H$<$ZZ )A/[P ,3EU.=4Y5 !(YP@@)&T #@QM M 0 $F8((&T ""@08!Q*;0 ,;PP@;0 (< P$"@ 8 H@;0 (,!!(P"@ 0FT M$DIM QL$$1M Q*A&P(1(0[? ! !(R+0 ,2,$@!$ZZ XY![("&4XH4L M,BT #$C!( 1.N@.$* !FVDIM !)G!E.*%+P +2 *3-\$$$Y=3G5.5?\B2.<( M,"1M @F;0 ,0FW_^BMM !#__"!+4HL0$$B . !G +LN'P )68 LI"+?\P M.WP ?_X.WP (/_V.WPG$/_T($M2BQ 02( X +!\ "UF#D)M__@@2U*+$!!( M@#@ N'P ,&80.WP ,/_V($M2BQ 02( X +A\ "IF&"!M__Q4K?_\.U#_\B!+ M4HL0$$B . !@,D)M__)@'# M__+!_ *T$20? P.T#_\B!+4HL0$$B . P M!%) 0>R F @P ( &;4N'P +F9:($M2BQ 02( X +!\ "IF&"!M__Q4K?_\ M.U#_]"!+4HL0$$B . !@,D)M__1@'# M__3!_ *T$20? P.T#_]"!+4HL0 M$$B . P!%) 0>R F @P ( &;4.WP O_PN'P ;&82($M2BQ 02( X #M\ M 3_\& 0N'P :&8*($M2BQ 02( X # $2,!@>#M\ C_[F 6.WP "O_N8 X[ M? 0_^Y@!CM\__;_[C\M__!(;?\P/RW_[B\M__Q.NOWD3^\ #"M _^HP+?_P M2,#1K?_\8%H@;?_\6*W__"M0_^HO+?_J3KH"#%A/.T#_\&!*(&W__%2M__PX M$$'M_R\K2/_J$(1@*)"\ 8V?B4X!GE)"\ "V< _W19@&>T58!G /]R M5X!G /]T8,Q![?\PD>W_ZCM(__ P+?_PL&W_]&\&.VW_]/_P2FW_^&=H(&W_ MZ@P0 "UG"B)M_^H,$0 K9BX,;0 P__9F)E-M__(@;?_J4JW_ZA 02( _ $Z2 M5$^P?/__9@IP_TS?#!!.74YU8!8_+?_V3I)43[!\__]F!'#_8.12;?_Z,"W_ M\E-M__*P;?_P;MQ";?_N8" @;?_J4JW_ZA 02( _ $Z25$^P?/__9@1P_V"P M4FW_[B!M_^I*$&<*,"W_[K!M__1MSC M_^[1;?_Z2FW_^&8H8!@_/ @3I)4 M3[!\__]F!G#_8 #_>%)M__HP+?_R4VW_\K!M__!NVF 6/P1.DE1/L'S__V8& M</]@ /]24FW_^F _0HP+?_Z8 #_0DCG2 !"A$J :@1$@%)$2H%J!D2!"D0 M 6$^2D1G D2 3-\ $DJ 3G5(YT@ 0H1*@&H$1(!21$J!:@)$@6$:( %@V"\! M81(@ 2(?2H!.=2\!808B'TJ 3G5(YS 2$%*068@2$$V 30 0D!(0(##(@!( M0#("@L,P 4)!2$%,WP ,3G5(028!(@!"04A!2$!"0'0/T(#3@;:!8@22@U) M4<K_\DS? Q.=2!O 0@"$H89OR1P" (4X!.=4Y5 !(;($P/RT "$ZZ A< M3TY=3G5.50 +P0X+0 (+RT "C\$3KH ,%Q/N'P "F8D(&T "A H Q(@ @ M =G%#\\__\O+0 *3KH ]EQ/*!].74YU8/A.50 +PHD;0 *(%*QZ@ $91@P M+0 (P'P _S\ +PI.N@#*7$\D7TY=3G4@4E*2$"T "1" 2(# ? #_8.A.50 M+PI![($:)$@@2M7\ %B\(81!83T'L@M*UR&7J)%].74YU3E4 $CG"" D M;0 (> @"F8*</],WP003EU.=4HJ QG4@@J ( #&<,/SS__R\*851<3S@ M$"H #4B /P!.N@3R5$^(0 @J $ #&<*+RH "$ZZ C!83P@J 4 #&<4+RH M$DZZ L)83R\J !).N@(46$]"DD*J 1"J@ (0BH ## $8(Y.5?_^2.<(("1M M A!^O]$*4B# @@J 0 #&<*</],WP003EU.=0@J ( #&<P(!*0J@ (. _ M!"\J @0*@ -2( _ $ZZ H!03[!$9Q (Z@ $ Q"DD*J 1P_V# #&W__P , M9A (J@ " Q"DD*J 1P &"H2JH "&8(+PI.N@":6$\,:@ ! !!F*AMM W_ M_S\\ %(;?__$"H #4B /P!.N@(B4$^P? !9J P+0 ,8 #_:B2J @P*@ 0 M2,#0J@ ()4 ! CJ ( #"!24I(0+0 -$(!(@,!\ /]@ /\^3E4 "\*0>R! M&B1(2BH #&<8U?P 60>R"TK7(90AP "1?3EU.=6#B0I)"J@ $0JH "" * M8.I.5?_\+PHD;0 (/SP$ $ZZ ,!43RM __QF\ $ $" *T+P .)4 M""1?3EU.=35\! $ CJ $ #"5M__P "! J U(@#\ 3KH XE1/2D!G!@ J M ( #&#.3E4 $CG # D;(+68!0F4B J 10@"\ +PI.N@104$\D2R *9NA" MK(+63-\, $Y=3G5.50 +PI!^O_&*4B#!D*G("T "%" +P!.N@/H4$\D0$J M9@AP "1?3EU.=22L@M8E;0 ( 0I2H+6( I0@&#F3E4 ' ,"T ""\ 8;)8 M3TY=3G5.50 2.< ,)?+)&R"UF .(&T "%&(L<IG$B9*)%(@"F;N</],WPP M3EU.=2 +9P0FDF $*5*"UB J 10@"\ +PI.N@.B4$]P SE4 "\*,"T M",'\ 8D0-7L@N9*;0 (;0XP+0 (L&R"TFP$2I)F#CE\ *# '#_)%].74YU M,"T ",'\ 8@;(+F+S ( $ZZ JA83TJ 9P1P 6 "< !@V$Y5 O+0 (3KH" M<EA/2H!F#DZZ GPY0(, </].74YU< !@^$Y5 !(YPP@."T "$ZZ ' P!,'\ M 8D0-7L@N9*1&T*N&R"TFP$2I)F$#E\ *# '#_3-\$,$Y=3G4P*@ $P'P M V8*.7P !8, </]@Y' ,"T #B\ +RT "B\23KH"1D_O PJ +"\_____V8, M3KH!_#E @P!P_V"X( 5@M$Y5__Q(>! 0J=.N@+R4$\K0/_\" #&<22FR" M[F8(("W__$Y=3G5.N@ &< !@]$Y5 !(> $2'H 'DZZ =(O $ZZ >)/[P , M/SP 4ZZ Q43TY=3G5>0PH 3E4 $JL@P)G!B!L@P).D#\M A.N@ (5$]. M74YU3E7__"\$,"T "$C *T#__$JL@N9G*'@ 8 H_!$ZZ -!43U)$N&R"TFWP M,"R"TL'\ 8O "\L@N9.N@'L4$]*K(,&9P8@;(,&3I!*K(,*9PHO+(,*3KH! MC%A/2JR##F<*+RR##DZZ 7Q83TJL@Q)G"B\L@Q).N@%L6$\L> $""X ! $I M9Q0O#4OZ I.KO_B*E]@!D*G\U].<TJL@O!F,$JL@OQG*# L@OI(P"\ +RR" M_$ZZ 7)03S L@OA20$C Y8 O "\L@O1.N@%<4$]@#DZZ 4PO+(+P3KH!GEA/ M("W__"YL@MI.=2@?3EU.=4Y5 !(YPX@."T "# $P?P !B1 U>R"YDI$;0JX M;(+2; 1*DF80.7P H, </],WP1P3EU.=3 J 3 ?( 9@@O$DZZ I83T*2 M< !@X"(O 0L;(+B3N[_W"(O 0L;(+B3N[_@B(O 0L;(+B3N[_.B(O 0L M;(+B3N[_N"QL@N).[O_*+&R"XD[N_WPB+P $+&R"XD[N_RA,[P & 0L;(+B M3N[_XBQL@N).[O_$3.\ #@ $+&R"XD[N_]9,[P . 0L;(+B3N[_T$CG 01, M[R" PL;(+>3J[_E$S?((!.=2)O 0L;(+>3N[^/D[Z (B;P $+&R"WD[N M_F),[P # 0L;(+>3N[_.DCG P B;P ,+&R"WDZN_CA,WP# 3G4B;P $+&R" MWD[N_MHL;(+>3N[_?")O 0@+P (+&R"WD[N_RX@;P $+&R"WD[N_HP@;P $ M3.\" 0 ((B\ $"QL@MY.[OY$+&R"WB)O 0@+P (3N[]V")O 0@+P (+&R" MWD[N_@XB;P $+&R"WD[N_H9,[P # 0L;(+>3N[^SB!O 0L;(+>3N[^@$SO M P !"QL@QY.[O^@(&\ !"QL@QY.[O^F(&\ !"QL@QY.[O^R("\ !"QL@Q9. M[O_Z("\ !"QL@Q9.[O_T("\ !"(O @L;(,63N[_[@ #[ $ ! M 1N@ /R #Z@ +4 W_ , ? #L 6@!X )< M0#4 /,! M$0$P 4X !\ / !; 'D F "V -4 ] $2 3$!3P "Y0 N8 +G M"Z ND +J "ZP NP +M "[@ N\ +P "\0 O+ + MT@ "]H OD +[0 "_0P,3(S-#4V-S@Y86)C9&5F (" @(" @(" @ M,# P,# @(" @(" @(" @(" @(" @(""00$! 0$! 0$! 0$! 0$! # P,# P, M# P,#$! 0$! 0$ )"0D)"0D! 0$! 0$! 0$! 0$! 0$! 0$! 4! 0$! 0 H* M"@H*"@(" @(" @(" @(" @(" @(" @("0$! 0" 0 M ! $! 0 ! @ M $ M M M M M M M M % #[ !, . #P M ! 1 $@ !, 4 %0 !8 7 & !D : J &P !P = '@ !\ @ /R #ZP $ /R end SHAR_EOF fi # end of overwriting check # End of shell archive exit 0
glewis@cit-vax.Caltech.Edu (Glenn M. Lewis) (12/31/87)
For those of you having trouble uudecoding "time", change the line in the shar file that says: "begin 3 time.uue" to: "begin 644 time" It should then work. (The 644 is personal preference - '.uue' MUST be removed) Thanks for the posting of your project! -- Glenn Lewis -- glewis@cit-vax.caltech.edu