10 REM: 20 REM: A Complete Biorhythm program 30 REM: 40 REM: Written by Stephen Maguire 50 REM: Copyright (C) 1980 60 REM: 70 REM: Simple variables: 80 REM: 90 REM: Cn indicates which keys have been knocked out. 100 REM: F used in deciding to print page 1 or not. 110 REM: I a general purpose loop counter. 120 REM: J a general purpose loop counter; 130 REM: Also, justify on/off. 140 REM: K a general purpose loop counter. 150 REM: Ln memory locations of various keys. 160 REM: N the number of days the person has lived. 170 REM: P a toggle indicating the paginating status. 180 REM: R a variable used to fake a gosub. 190 REM: R1 this contains the value of two times pi. 200 REM: Tn temporary storage; used only in functions. 210 REM: W1 this is a temporay text width. 220 REM: Xn all x variables are temporary storage. 230 REM: 240 REM: M1, D1, Y1 The day of birth. 250 REM: M2, D2, Y2 The starting date for the chart. 260 REM: M3, D3, Y3 The current date (while printing). 270 REM: M4, D4, Y4 The optional termination date. 280 REM: M8, D8, Y8 Temporary date holder. 290 REM: M9, D9, Y9 The date input from the keyboard. 300 REM: 310 REM: Simple strings: (not re-dimensioned) 320 REM: 330 REM: A$ the quotation mark. 340 REM: O$ the name of the output file. 350 REM: 360 REM: Functions: 370 REM: 380 REM: FNC$(string,width) centers string within width. 390 REM: FND$(month,day,year) converts date to a string. 400 REM: FNL(year) tests for a leapyear. 410 REM: FNF(month,day,year) returns the date's factor. 420 REM: FND(month,day,year) returns the day of the week. 430 REM: FNN(month,day,year) returns the following date. 440 REM: FNG(period) returns a point on the sine curve. 450 REM: FNS$(string) strips blanks from string. 460 REM: 470 REM: To be added: 480 REM: 490 REM: FNZ(day,year) returns corrosponding zodiac. 500 REM: 510 REM: Procedures: (subroutines) 520 REM: 530 REM: PRINT-DISPLAY prints the display w/o info update. 540 REM: PRINT-INFORMATION fills the display with info. 550 REM: PLOT-DAY plots a one day biorhythm. 560 REM: 570 REM: Arrays: 580 REM: 590 REM: C(n) contains various plot information. 600 REM: M(n) contains the number of days for the month. 610 REM: M$ contains the names of the months. 620 REM: L$ contains the line to be printed 630 REM: D$ contains the names of the days. 640 REM: N$ contains the current name. 650 REM: ( Z$ contains the names of the zodiac. ) 660 REM: C$ all purpose long string. 670 REM: S$ all purpose long string. 680 REM: P$ string containing the current plot line. 690 REM: I$ an input string. 700 REM: 710 DIM M$(12*9),M(12),D$(7*9),L$(132),N$(29) 720 DIM C$(29),S$(29),P$(130),C(4),I$(29) 730 REM: 740 REM: Intialize variables. 750 REM: 760 LET A$=CHR(34): REM: A quotation mark. 770 LET R1=8*ATN(1): REM: Set R equal to two-pi. 780 LET N$="",O$="Screen",W=64,P=1,F=1,A=-1,M=7 790 LET C(1)=M,C(2)=2,C(3)=7+M,C(4)=57 800 LET M1=0,D1=0,Y1=0: REM: Initialize the dates 810 LET M2=0,D2=0,Y2=0 820 LET M4=0,D4=0,Y4=0 830 SET LL=133: SET DS=15,2: SET CM=0 840 LET C1=0,C2=0,C3=0 850 ERRSET 9180 860 REM: 870 REM: Turn off the "CLEAR", "MODE", and "HOME" keys. 880 REM: Also, knock out the underline (make it printable). 890 REM: Knock out the control-X function also. 900 REM: 910 LET L1=13934,L2=13943 920 LET L3=13119,L4=13159,L5=13311,L6=13481,L7=13952,L8=13972 930 IF PEEK(L1)=11 THEN POKE L1,255: LET C1=1 940 IF PEEK(L2)=14 THEN POKE L2,255: LET C2=1 950 IF PEEK(L3)<>194 OR PEEK(L4)<>202 OR PEEK(L5)<>202 THEN 1000 960 POKE L3,195 970 POKE L4,0: POKE L4+1,0: POKE L4+2,0 980 POKE L5,0: POKE L5+1,0: POKE L5+2,0 990 LET C3=1 1000 IF PEEK(L6)<>95 OR PEEK(L7)<>95 THEN 1030 1010 POKE L6,127: POKE L7,127 1020 LET C4=1 1030 IF PEEK(L8)=24 THEN POKE L8,255: LET C5=1 1040 GOSUB 3610 1050 CURSOR 1,23: PRINT "The Software Shack" 1060 CURSOR 2,28: PRINT "presents" 1070 CURSOR 4,24: PRINT "B I O -- P L O T" 1080 CURSOR 5,13: PRINT "A complete Biorhythm plotting package." 1090 CURSOR 7,19: PRINT "Written by Stephen Maguire" 1100 CURSOR 8,23: PRINT "Copyright (C) 1980" 1110 PRINT : PRINT : PRINT 1120 PRINT TAB(5);"If you are unfamiliar with the system, type "; 1130 PRINT A$+"H"+A$+" after": PRINT TAB(5);"the screen clears." 1140 PRINT 1150 PRINT TAB(5);"Note: typing "+A$+"Q"+A$+" is the only way to exit this program."; 1160 SET DS=0: PAUSE 50 1170 REM: 1180 REM: Read the names of the months into the array M$. 1190 REM: 1200 FILL M$," " 1210 FOR I=0 TO 11: READ M$(I*9+1): NEXT I 1220 DATA "January","February","March","April","May","June" 1230 DATA "July","August","September","October","November" 1240 DATA "December" 1250 REM: 1260 REM: Read the number of days/month into the array M(n). 1270 REM: 1280 FOR I=1 TO 12: READ M(I): NEXT I 1290 DATA 31,28,31,30,31,30,31,31,30,31,30,31 1300 REM: 1310 REM: Read the names of the days into the array D$. 1320 REM: 1330 FILL D$," " 1340 FOR I=0 TO 6: READ D$(I*9+1): NEXT I 1350 DATA "Saturday","Sunday","Monday","Tuesday","Wednesday" 1360 DATA "Thursday","Friday" 1370 REM: 1380 REM: The following function, leapyear, indicates whether 1390 REM: the year passed to the function is a leapyear or 1400 REM: not. If the year is a leapyear, a one is returned, 1410 REM: otherwise a zero is returned. This is so that the 1420 REM: following type of assignment may be used: 1430 REM: 1440 REM: Number of days this february = 28 + FNL(year) 1450 REM: 1460 DEF FNL(Y) 1470 LET T=0 1480 IF Y/4<>INT(Y/4) THEN 1520 1490 IF Y/100<>INT(Y/100) THEN 1510 1500 IF NOT (Y/400=INT(Y/400) AND Y/4000<>INT(Y/4000)) THEN 1520 1510 LET T=1 1520 RETURN T 1530 FNEND 1540 REM: 1550 REM: The following function calculates the factor of the 1560 REM: date passed. This factor can be used to find what 1570 REM: day of the week it is, the number of days between 1580 REM: any two dates, and whether or not a date is legal. 1590 REM: 1600 DEF FNF(M,D,Y) 1610 LET T=365*Y+D+31*(M-1) 1620 IF M>2 THEN 1650 1630 LET T=T+INT((Y-1)/4)-INT(0.75*(INT((Y-1)/100)+1)) 1640 GOTO 1660 1650 LET T=T-INT(0.4*M+2.3)+INT(Y/4)-INT(0.75*(INT(Y/100)+1))-INT(Y/4000) 1660 RETURN T 1670 FNEND 1680 REM: 1690 REM: The following function indicates what the given 1700 REM: day is. The function returns the following: 1710 REM: 1720 REM: 0 = Saturday, 1 = Sunday, . . ., 6 = Friday 1730 REM: 1740 DEF FND(M,D,Y) 1750 LET T=FNF(M,D,Y): REM: Find the day's factor. 1760 RETURN INT(T-INT(T/7)*7) 1770 FNEND 1780 REM: 1790 REM: The next function centers the incoming string 1800 REM: in a string of blanks "width" wide. 1810 REM: 1820 DEF FNC$(C$,C) 1830 FILL S$," " 1840 LET S$((C-LEN(C$))/2+1)=C$ 1850 RETURN S$(1,C) 1860 FNEND 1870 REM: 1880 REM: The next function returns a string containing 1890 REM: the name of the day represented by the number 1900 REM: passed. 1910 REM: 1920 DEF FNW$(D) 1930 LET S$="" 1940 FOR K=D*9+1 TO D*9+9 1950 IF D$(K,K)=" " THEN EXIT 1980 1960 LET S$=S$+D$(K,K) 1970 NEXT K 1980 RETURN S$ 1990 FNEND 2000 REM: 2010 REM: The next function returns a string containing 2020 REM: the name of the day represented by the number 2030 REM: passed. 2040 REM: 2050 DEF FNM$(M) 2060 LET S$="" 2070 FOR K=(M-1)*9+1 TO (M-1)*9+9 2080 IF M$(K,K)=" " THEN EXIT 2110 2090 LET S$=S$+M$(K,K) 2100 NEXT K 2110 RETURN S$ 2120 FNEND 2130 REM: 2140 REM: Given the month, day, and year, the next function 2150 REM: returns a formatted string consisting of the day 2160 REM: of the week followed by the date. 2170 REM: 2180 DEF FND$(M,D,Y)=FNW$(FND(M,D,Y))+", "+FNM$(M)+" "+STR(D)+", "+STR(Y) 2190 REM: 2200 REM: The next function takes the date passed and 2210 REM: calculates the next date which it then stores 2220 REM: in M8, D8, and Y8. If the next date is the start 2230 REM: of a new month, a one is returned, otherwise zero. 2240 REM: 2250 DEF FNN(M,D,Y) 2260 LET M(2)=28+FNL(Y): REM: Set up in case of leapyear. 2270 IF D>=M(M) THEN LET M8=M+1,D8=1,T=1 ELSE LET D8=D+1,T=0,M8=M 2280 IF M8>12 THEN LET M8=1,Y8=Y+1 ELSE LET Y8=Y 2290 RETURN T 2300 FNEND 2310 REM: 2320 REM: The next function strips unwanted blanks. 2330 REM: 2340 DEF FNS$(C$) 2350 LET S$="" 2360 FOR T1=1 TO LEN(C$) 2370 IF C$(T1,T1)<>" " THEN LET S$=S$+C$(T1,T1) 2380 NEXT T1 2390 RETURN S$ 2400 FNEND 2410 REM: 2420 REM: The next function returns a value representing 2430 REM: the point on the curve of the passed period. 2440 REM: 2450 DEF FNG(Z)=INT(C(4)/2+SIN(R1*(N/Z-INT(N/Z)))*INT(C(4)/2-1))+1 2460 REM: 2470 REM: Jump around the procedures 2480 REM: 2490 GOTO 3850 2500 REM: 2510 REM: Procedure PLOT-DAY 2520 REM: 2530 REM: The following procedure prints the biorhythm plot 2540 REM: for the number of days since birth. This value 2550 REM: is contained in N. It prints two lines of text, 2560 REM: half a day each. Depending on the current settings, 2570 REM: the plot is printed differently. 2580 REM: 2590 FOR I=0 TO 0.5 STEP 0.5 2600 LET N=N+I 2610 FILL P$," " 2620 PRINT TAB(C(1)); 2630 IF (D3<>1 OR (D3=1 AND P=1)) AND I=0 THEN 2700 2640 IF (D3<>1 OR (D3=1 AND P=1)) AND I=0.5 THEN 2720 2650 IF D3=1 AND P=-1 AND I=0.5 THEN 2700 2660 LET C$=FNM$(M3)+" ": IF C(2)=2 THEN LET C$=C$(1,3) 2670 PRINT C$+" "; 2680 GOTO 2720 2690 REM: 2700 LET C$=FNW$(FND(M3,D3,Y3)): IF C(2)=2 THEN LET C$=C$(1,3) 2710 PRINT C$+" "; 2720 IF I=0 AND C(4)=111 THEN PRINT TAB(C(3)-3); 2730 IF I=0 THEN PRINT %2I;D3; 2740 PRINT TAB(C(3)); 2750 LET P$(C(4)/2+1)="!" 2760 LET T3=C(4)/2+1,T=FNG(23),T4=T 2770 IF T>T3 THEN LET T3=T 2780 IF P$(T,T)=" " THEN LET P$(T)="P" ELSE LET P$(T)="*" 2790 LET T=FNG(28),T4=T4+T 2800 IF T>T3 THEN LET T3=T 2810 IF P$(T,T)=" " THEN LET P$(T)="E" ELSE LET P$(T)="*" 2820 LET T=FNG(33),T4=INT((T4+T)/3+0.5) 2830 IF T>T3 THEN LET T3=T 2840 IF P$(T,T)=" " THEN LET P$(T)="I" ELSE LET P$(T)="*" 2850 IF A=1 THEN IF P$(T4,T4)=" " THEN LET P$(T4)="." 2860 PRINT P$(1,T3) 2870 NEXT 2880 LET N=N+0.5 2890 RETURN 2900 REM: 2910 REM: Procedure PRINT-DISPLAY 2920 REM: 2930 REM: This procedure prints the display. It does not 2940 REM: print the information such as NAME, BIRTHDAY, etc. 2950 REM: This routine simply prints the pretty boxes on 2960 REM: the screen. This assumes that a video display is 2970 REM: being used. 2980 REM: 2990 SET CM=0: GOSUB 3610: SET CP=1 3000 CURSOR 2,0 3010 PRINT " "+A$+"N"+A$+" Biorhythm chart for: "; 3020 CURSOR 2,36 3030 PRINT " "+A$+"O"+A$+" Output goes to: "; 3040 CURSOR 4,0 3050 PRINT " "+A$+"B"+A$+" Born on: "; 3060 CURSOR 4,36 3070 PRINT " "+A$+"W"+A$+" Output width: "; 3080 CURSOR 6,0 3090 PRINT " "+A$+"S"+A$+" Starting date: "; 3100 CURSOR 6,36 3110 PRINT " "+A$+"P"+A$+"aginate? "+A$+"I"+A$+"nfo page? "; 3120 CURSOR 8,0 3130 PRINT " "+A$+"E"+A$+" Termination date: "; 3140 CURSOR 8,36 3150 PRINT " "+A$+"M"+A$+" Margin "+A$+"A"+A$+" Average "; 3160 CURSOR 10,0 3170 PRINT " Type "+A$+"C"+A$+" to produce the chart. "; 3180 CURSOR 10,36 3190 PRINT " Type "+A$+"H"+A$+" to get help. "; 3200 FOR I=3 TO 9 STEP 2 3210 CURSOR I,0,160: CURSOR ,32,160: CURSOR ,36,160: CURSOR ,63,160 3220 NEXT I 3230 CURSOR 7,49,160: CURSOR 9,,160 3240 SET CP=0: REM: Go back to normal printing now 3250 CURSOR 12,19: PRINT "Written by Stephen Maguire" 3260 CURSOR 13,23: PRINT "Copyright (C) 1980" 3270 RETURN 3280 REM: 3290 REM: Procedure PRINT-INFORMATION 3300 REM: 3310 REM: This procedure puts all the current information 3320 REM: on the screen it the appropriate boxes. This is 3330 REM: called on initialization, after a SCREEN print, 3340 REM: and after responding to "Help". Any time the 3350 REM: information is completely erased, this routine 3360 REM: will be called. 3370 REM: 3380 SET CM=0: REM: Turn off the cursor 3390 CURSOR 3,2: PRINT FNC$(N$,29); 3400 CURSOR 3,38: PRINT FNC$(O$,24); 3410 IF M1*D1*Y1=0 THEN 3430 3420 CURSOR 5,2: PRINT FNC$(FND$(M1,D1,Y1),29); 3430 CURSOR 5,38: PRINT FNC$(STR(W)+" columns wide",24); 3440 IF M2*D2*Y2=0 THEN 3460 3450 CURSOR 7,2: PRINT FNC$(FND$(M2,D2,Y2),29); 3460 CURSOR 7,42: IF P=1 THEN PRINT "Yes"; ELSE PRINT "No "; 3470 CURSOR 7,55: IF F=1 THEN PRINT "Yes"; ELSE PRINT "No "; 3480 CURSOR 9,2 3490 IF M4*D4*Y4<>0 THEN 3520 3500 PRINT FNC$("Eternity",29); 3510 GOTO 3530 3520 PRINT FNC$(FND$(M4,D4,Y4),29); 3530 CURSOR 9,38: PRINT FNC$(STR(M)+" spaces",11); 3540 CURSOR 9,55: IF A=1 THEN PRINT "Yes"; ELSE PRINT "No "; 3550 RETURN 3560 REM: 3570 REM: Three very useful subroutines. 3580 REM: 3590 SET CM=1: INPUT ,(X1,0)"",I$: SET CM=0: RETURN 3600 CURSOR 0,0: PRINT : CURSOR : RETURN 3610 IF C1 THEN POKE L1,11 3620 PRINT CHR(11); 3630 IF C1 THEN POKE L1,255 3640 RETURN 3650 REM: 3660 REM: A short error message. 3670 REM: 3680 GOSUB 3600 3690 PRINT "Type ";A$;"H";A$;" to get some help."; 3700 ERRSET 9180 3710 PAUSE 30 3720 GOTO 3860 3730 REM: 3740 REM: When done printing the chart, set the output 3750 REM: back to the screen. Also, paginate if neccessary. 3760 REM: 3770 IF P=-1 THEN 3800 3780 IF X2<>M3 THEN LET X3=0 ELSE LET X3=M(X2)-(D3-X5) 3790 FOR I=M(X2)+1 TO 31+X3+X4: PRINT : PRINT : NEXT I 3800 SET OF=#0 3810 IF O$="Screen" THEN LET C(1)=C(1)+M,C(3)=C(3)+M 3820 REM: 3830 REM: Print the board, information, and prompt. 3840 REM: 3850 GOSUB 2990: GOSUB 3380 3860 GOSUB 3600 3870 PRINT "Command: [N, B, S, O, W, P, I, E, A, M, C, Q, H - elp] ? "; 3880 CURSOR 0,57,32 3890 LET X1=1: GOSUB 3590 3900 IF I$="" THEN 3890 3910 REM: 3920 REM: We have some input, if it is lowercase, convert 3930 REM: it to uppercase for proper checking. 3940 REM: 3950 IF I$>="a" THEN LET I$=CHR(ASC(I$)-32) 3960 SEARCH I$,"NBSOWPICHEMAQ",X 3970 ON X GOTO 4020,4190,4410,5600,6180,6560,6620,6820,8440,4630,6350,6680,9070 3980 GOTO 3680 3990 REM: 4000 REM: Routine to enter a new chart name. 4010 REM: 4020 GOSUB 3600 4030 PRINT "Biorhythm chart for: "; 4040 LET X1=30: GOSUB 3590 4050 IF I$="" THEN 3860 4060 FOR I=1 TO LEN(I$) 4070 IF I$(I,I)<" " THEN EXIT 4130 4080 NEXT I 4090 LET N$=I$ 4100 LET I$=FNS$(I$): IF I$="" THEN LET N$="" 4110 CURSOR 3,2: PRINT FNC$(N$,29); 4120 GOTO 3860 4130 GOSUB 3600 4140 PRINT "I'm sorry, but there is an illegal character in that name." 4150 GOTO 3710 4160 REM: 4170 REM: The next routine accepts a new birth date. 4180 REM: 4190 GOSUB 3600 4200 PRINT "Enter birth date: (month,day,year): "; 4210 LET R=1: GOTO 4870: REM: This is a faked "GOSUB". 4220 REM: 4230 REM: If no start date yet, then any legal date is okay. 4240 REM: 4250 IF M2*D2*Y2=0 THEN 4300 4260 IF FNF(M9,D9,Y9)<=FNF(M2,D2,Y2) THEN 4300 4270 GOSUB 3600 4280 PRINT "The birth date cannot be later than the starting date." 4290 GOTO 3710 4300 IF M4*D4*Y4=0 THEN 4350 4310 IF FNF(M9,D9,Y9)<=FNF(M4,D4,Y4) THEN 4350 4320 GOSUB 3600 4330 PRINT "The birth date cannot be later than the termination date." 4340 GOTO 3710 4350 LET M1=M9,D1=D9,Y1=Y9 4360 CURSOR 5,2: PRINT FNC$(FND$(M1,D1,Y1),29); 4370 GOTO 3860 4380 REM: 4390 REM: The next routine accepts a new start date. 4400 REM: 4410 GOSUB 3600 4420 PRINT "Enter starting date: (month,day,year): "; 4430 LET R=2: GOTO 4870: REM: This is a faked "GOSUB". 4440 REM: 4450 REM: If no birth date yet, then any legal date is okay. 4460 REM: 4470 IF M1*D1*Y1=0 THEN 4520 4480 IF FNF(M1,D1,Y1)<=FNF(M9,D9,Y9) THEN 4520 4490 GOSUB 3600 4500 PRINT "The starting date cannot be earlier than the birth date." 4510 GOTO 3710 4520 IF M4*D4*Y4=0 THEN 4570 4530 IF FNF(M4,D4,Y4)>=FNF(M9,D9,Y9) THEN 4570 4540 GOSUB 3600 4550 PRINT "The starting date cannot be later than the termination date." 4560 GOTO 3710 4570 LET M2=M9,D2=D9,Y2=Y9,M3=M9,D3=D9,Y3=Y9 4580 CURSOR 7,2: PRINT FNC$(FND$(M2,D2,Y2),29); 4590 GOTO 3860 4600 REM: 4610 REM: The next routine accepts a new end date. 4620 REM: 4630 GOSUB 3600 4640 PRINT "Enter "+A$+"E"+A$+" or end date: (month,day,year): "; 4650 LET R=3: GOTO 4870: REM: This is a faked "GOSUB". 4660 IF FNF(M2,D2,Y2)<=FNF(M9,D9,Y9) THEN 4700 4670 GOSUB 3600 4680 PRINT "The ending date cannot be earlier than the starting date." 4690 GOTO 3710 4700 IF FNF(M1,D1,Y1)<=FNF(M9,D9,Y9) THEN 4740 4710 GOSUB 3600 4720 PRINT "The ending date cannot be earlier than the birth date." 4730 GOTO 3710 4740 LET M4=M9,D4=D9,Y4=Y9 4750 CURSOR 9,2: PRINT FNC$(FND$(M4,D4,Y4),29); 4760 GOTO 3860 4770 LET M4=0,D4=0,Y4=0 4780 CURSOR 9,2: PRINT FNC$("Eternity",29); 4790 GOTO 3860 4800 REM: 4810 REM: This routine accepts a string containing a date 4820 REM: and converts it. If all is well, it returns with 4830 REM: with the good date in M9, D9, and Y9. If R=1 4840 REM: then it returns to birth date, if 2, then start date 4850 REM: otherwise, it returns to end date. 4860 REM: 4870 LET X1=23: GOSUB 3590 4880 IF I$="" THEN 3860 4890 REM: 4900 REM: Remove any unwanted blanks. 4910 REM: 4920 LET I$=FNS$(I$) 4930 IF I$="" THEN 3860 4940 REM: 4950 REM: Now, convert uppercase to lowercase. 4960 REM: 4970 IF I$(1,1)>="a" THEN LET I$(1,1)=CHR(ASC(I$(1,1))-32) 4980 FOR I=2 TO LEN(I$) 4990 IF I$(I,I)<"A" THEN EXIT 5060 5000 IF I$(I,I)="," THEN EXIT 5060 5010 IF I$(I,I)<"a" THEN LET I$(I,I)=CHR(ASC(I$(I,I))+32) 5020 NEXT I 5030 REM: 5040 REM: If it is the stop date, "E" means forever. 5050 REM: 5060 IF ASC(I$(1,1))=ASC("E") AND R=3 THEN 4770 5070 REM: 5080 REM: If no comma past the 1st character, then error. 5090 REM: 5100 SEARCH ",",I$,X: IF X<=1 THEN 3680 5110 REM: 5120 REM: Find out which month it is. 5130 REM: 5140 SEARCH I$(1,X-1),M$,X1 5150 IF X1<>0 THEN LET M9=(X1-1)/9+1: GOTO 5250 5160 REM: 5170 REM: Month name not there, how about a month number. 5180 REM: 5190 ERRSET 3680 5200 LET M9=VAL(I$(1,X-1)) 5210 ERRSET 9180 5220 REM: 5230 REM: Got the month, check legality. 5240 REM: 5250 IF M9<1 OR M9>12 THEN 5520 5260 IF M9<>INT(M9) THEN 3680 5270 REM: 5280 REM: Now check for the comma between day and year. 5290 REM: 5300 SEARCH ",",I$(X+1),X1: IF X1<=1 THEN 3680 5310 REM: 5320 REM: There is a day and a year, find their values. 5330 REM: 5340 ERRSET 3680 5350 LET D9=INT(VAL(I$(X+1,X+X1-1))),Y9=INT(VAL(I$(X+X1+1))) 5360 IF Y9>=1 AND Y9<100 THEN LET Y9=Y9+1900 5370 ERRSET 9180 5380 REM: 5390 REM: Got values, check for legality. 5400 REM: 5410 IF D9<1 OR D9>31 OR Y9<1 THEN 5520 5420 REM: 5430 REM: If the factor for this day is greater than or 5440 REM: equal to the factor of the next day, then the 5450 REM: date is illegal. 5460 REM: 5470 LET X=FNN(M9,D9,Y9) 5480 IF FNF(M9,D9,Y9)ASC("S") AND ASC(I$)<>ASC("s") THEN 5750 5660 REM: 5670 REM: Output goes to the screen; set column width to 64. 5680 REM: 5690 LET O$="Screen" 5700 CURSOR 3,38: PRINT FNC$(O$,24); 5710 LET I$="B": GOTO 6250 5720 REM: 5730 REM: Output goes to a disk (device?) file. 5740 REM: 5750 IF ASC(I$)<>ASC("O") AND ASC(I$)<>ASC("o") THEN 5620 5760 GOSUB 3600 5770 PRINT "Enter output file name: "; 5780 LET X1=11: GOSUB 3590 5790 IF I$="" THEN GOTO 3860 5800 REM: 5810 LET I$=FNS$(I$),X1=LEN(I$) 5820 IF I$="" THEN GOTO 3860 5830 IF X1>10 THEN 6100 5840 FOR I=1 TO X1 5850 IF I$(I,I)<" " THEN EXIT 6100 5860 NEXT I 5870 REM: 5880 REM: If there is a unit specifier ("/u") check legality. 5890 REM: 5900 IF X1<=2 THEN 5980 5910 IF I$(X1-1,X1-1)<>"/" THEN 5980 5920 IF I$(X1)<"0" THEN 6100 5930 IF I$(X1)>"7" THEN 6100 5940 SEARCH "/",I$(1,X1-2),X: IF X=0 THEN GOTO 6000 ELSE 6100 5950 REM: 5960 REM: Check for illegal file name characters. 5970 REM: 5980 IF X1>=9 THEN 6100 5990 SEARCH "/",I$,X: IF X<>0 THEN 6100 6000 LET C$="#,;<=>" 6010 FOR I=1 TO LEN(C$) 6020 SEARCH C$(I,I),I$,X: IF X<>0 THEN EXIT 6100 6030 NEXT I 6040 LET O$=I$ 6050 CURSOR 3,38: PRINT FNC$(O$,24); 6060 GOTO 3860 6070 REM: 6080 REM: If illegal name, come here. 6090 REM: 6100 GOSUB 3600 6110 PRINT "I'm sorry, but that file name is illegal." 6120 GOTO 3710 6130 REM: 6140 REM: Enter a new column width. This allows for 6150 REM: different size paper, and the wider the setting, 6160 REM: the more information that is printed. 6170 REM: 6180 GOSUB 3600 6190 PRINT "New width: A - 40, B - 64, C - 80, D - 132: "; 6200 CURSOR 0,48,32 6210 LET X1=1: GOSUB 3590 6220 IF I$="" THEN 3860 6230 IF I$>="a" THEN LET I$=CHR(ASC(I$)-32) 6240 IF ASC(I$)ASC("D") THEN 6200 6250 LET C(1)=M,C(2)=2,C(3)=7+M 6260 IF I$="A" THEN LET W=40,C(4)=33 6270 IF I$="B" THEN LET W=64,C(4)=57 6280 IF I$="C" THEN LET W=80,C(3)=10+M,C(4)=67 6290 IF I$="D" THEN LET W=132,C(2)=8,C(3)=13+M,C(4)=111 6300 CURSOR 5,38: PRINT FNC$(STR(W)+" columns wide",24); 6310 GOTO 3860 6320 REM: 6330 REM: Set a new margin value. 6340 REM: 6350 GOSUB 3600 6360 PRINT "Enter new margin setting: "; 6370 LET X1=5: GOSUB 3590 6380 IF I$="" THEN 3860 6390 ERRSET 3680 6400 LET X=VAL(I$) 6410 ERRSET 9180 6420 IF X<0 OR X>92 THEN 6500 6430 LET C(3)=C(3)-C(1),M=X,C(1)=M,C(3)=C(3)+M 6440 CURSOR 9,38: PRINT FNC$(STR(M)+" spaces",11); 6450 GOTO 3860 6460 REM: 6470 REM: Come here if the value is out of range. 6480 REM: The greatest value, 92, is 132 minus 40. 6490 REM: 6500 GOSUB 3600 6510 PRINT "The margin value must be between 0 and 92."; 6520 GOTO 3710 6530 REM: 6540 REM: Toggle the pagination switch. 6550 REM: 6560 LET P=-P 6570 CURSOR 7,42: IF P=1 THEN PRINT "Yes"; ELSE PRINT "No "; 6580 GOTO 3880 6590 REM: 6600 REM: Toggle the information page switch. 6610 REM: 6620 LET F=-F 6630 CURSOR 7,55: IF F=1 THEN PRINT "Yes"; ELSE PRINT "No "; 6640 GOTO 3880 6650 REM: 6660 REM: Toggle the average plot curve switch. 6670 REM: 6680 LET A=-A 6690 CURSOR 9,55: IF A=1 THEN PRINT "Yes"; ELSE PRINT "No "; 6700 GOTO 3880 6710 REM: 6720 REM: The following routine prints a biorhythm chart to 6730 REM: the specified output file. If pagination is on, then 6740 REM: it will paginate at the end of each month, and put 6750 REM: an informative title at the top of the next page. 6760 REM: If an "D" is typed while the chart is printing, it 6770 REM: will stop printing immediately. If an "M" is typed, 6780 REM: output will stop at the end of the current month. 6790 REM: If a "Y" is typed, output will stop at the end of 6800 REM: the current year. 6810 REM: 6820 CURSOR 0,0 6830 IF M1*D1*Y1=0 THEN PRINT "The birth date must first be entered.": GOTO 3710 6840 IF M2*D2*Y2=0 THEN PRINT "You must first enter the starting date.": GOTO 3710 6850 LET N=FNF(M2,D2,Y2)-FNF(M1,D1,Y1) 6860 IF N<0 THEN STOP : REM: Something wrong if so. 6870 GOSUB 3600 6880 PRINT "Position the paper, insert disk, then type return: "; 6890 LET X1=1: GOSUB 3590 6900 IF I$<>"" THEN 3860 6910 LET X1=C(3)+C(4)-131 6920 IF X1>0 THEN LET M=M-X1,C(1)=M,C(3)=C(3)-X1 6930 IF F<>1 THEN 7000 6940 GOSUB 3600 6950 PRINT "Should the information page be right-justified? (Y/N) "; 6960 LET X1=1: GOSUB 3590 6970 IF I$>"a" THEN LET I$=CHR(ASC(I$)-32) 6980 IF I$="N" THEN LET J=0: GOTO 7000 6990 IF I$<>"Y" THEN 6940 ELSE LET J=1 7000 GOSUB 3600 7010 PRINT "Type "+A$+"D"+A$+", "+A$+"M"+A$+", or "+A$+"Y"+A$+" to stop printing." 7020 LET M3=M2,D3=D2,Y3=Y2 7030 REM: 7040 REM: Now, We're all ready to start printing. 7050 REM: Print the information page first. 7060 REM: 7070 IF C1 THEN POKE L1,11 7080 IF O$="Screen" THEN SET OF=#0 ELSE SET OF=O$: GOTO 7100 7090 LET C(1)=C(1)-M,C(3)=C(3)-M 7100 IF C1 THEN POKE L1,255 7110 PRINT 7120 IF F<>1 THEN 8020: REM: No information page. 7130 IF O$="Screen" THEN SET CM=1 7140 REM: 7150 REM: Open the disk file and search for "INFOTEXT" 7160 REM: 7170 FILE #3;"BIOTEXT",1 7180 READ #3;L$ 7190 IF L$<>"INFOTEXT" THEN 7180 7200 LET X=0,P$="",X3=1,W1=(3*W)/4+1 7210 REM: 7220 REM: Get one line of text from the disk. 7230 REM: 7240 READ #3;L$ 7250 IF INP(252)=27 THEN 7930 7260 LET L$=L$+" " 7270 IF L$(1,1)<>"." THEN 7500 7280 IF L$(3,3)<>" " THEN LET C$=L$(3) ELSE LET C$="" 7290 REM: 7300 REM: Process any special commands. 7310 REM: (Described in REMTEXT in the file) 7320 REM: 7330 IF L$(2,2)="B" THEN LET L$=FND$(M1,D1,Y1)+C$ 7340 IF L$(2,2)="S" THEN LET L$=FND$(M2,D2,Y2)+C$ 7350 IF L$(2,2)="#" THEN LET L$=STR(N)+C$: GOTO 7500 7360 IF L$(2,2)="N" THEN LET L$=N$+C$: GOTO 7500 7370 IF L$(2,2)="Q" THEN 7930 7380 IF L$(2,2)="P" THEN 7590 7390 IF L$(2,2)<>"C" THEN 7440 7400 LET X1=INT((W1-LEN(P$))/2) 7410 FILL L$," " 7420 LET P$=L$(1,X1)+P$,L$=".C " 7430 GOTO 7590 7440 ERRSET 7460 7450 IF VAL(L$(2))=W THEN 7890 ELSE 7240 7460 ERRSET 9180 7470 REM: 7480 REM: Break the lines into the current column width. 7490 REM: 7500 SEARCH " ",L$,X1: IF X1=0 THEN LET X1=LEN(L$) 7510 IF LEN(P$)+X1>W1 THEN 7590 7520 LET P$=P$+L$(1,X1) 7530 IF X1=LEN(L$) THEN 7240 7540 LET L$=L$(X1+1) 7550 GOTO 7270 7560 REM: 7570 REM: Now, right justify the line before printing it. 7580 REM: 7590 IF O$="Screen" THEN PRINT TAB((W-W1)/2); ELSE PRINT TAB(M+(W-W1)/2); 7600 IF J=0 THEN 7800 7610 IF L$(1,2)=".P" THEN 7800 7620 IF L$(1,2)=".C" THEN 7800 7630 IF L$(1,1)=" " THEN LET L$=L$(2) 7640 LET X1=1 7650 IF P$(X1,X1)<>" " THEN 7670 7660 LET X1=X1+1: IF X1<=LEN(P$) THEN 7650 7670 IF X3=1 THEN LET X4=X1 ELSE LET X4=LEN(P$) 7680 IF LEN(P$)>W1 THEN 7760 7690 IF P$(LEN(P$))=" " THEN LET P$=P$(1,LEN(P$)-1) 7700 IF X4>LEN(P$) OR X4=X1 THEN 7680 ELSE 7670 7760 LET X3=-X3 7770 REM: 7780 REM: Now, print the line. 7790 REM: 7800 PRINT P$ 7810 LET X=X+1,P$="" 7820 IF L$(1,1)<>"." THEN 7520 7830 IF LEN(L$)>3 THEN 7520 7840 GOTO 7240 7850 REM: 7860 REM: When done, paginate so that the biorhythm starts 7870 REM: on a page boundry. If pagination is off, then don't. 7880 REM: 7890 IF W=40 THEN 7930 7900 READ #3;L$ 7910 IF L$<>".F" THEN 7900 7920 GOTO 7240 7930 IF P<>1 THEN 7970 7940 FOR I=1 TO 66-X 7950 PRINT 7960 NEXT I 7970 IF O$="Screen" THEN SET CM=0 7980 CLOSE #3 7990 REM: 8000 REM: Print the title at the top of the page. 8010 REM: 8020 LET X3=INT(4+(C(4)-15)/2) 8030 PRINT TAB(C(3));"Low"; 8040 LET P$="(" 8050 IF W=132 THEN LET P$=P$+"The month of " 8060 LET P$=P$+FNM$(M3)+", "+STR(Y3)+")" 8070 IF W=40 THEN LET P$=P$(1,4)+")" 8080 PRINT TAB(C(3)+4+INT((X3-4-LEN(P$))/2)); 8090 PRINT P$; 8100 PRINT TAB(C(3)+X3);"Critical"; 8110 IF W=40 THEN LET P$="("+STR(Y3)+")": GOTO 8140 8120 IF W=64 AND LEN(N$)>11 THEN 8140 8130 IF N$<>"" THEN LET P$="(For: "+N$+")" 8140 PRINT TAB(C(3)+X3+8+INT((C(4)-4-X3-8-LEN(P$))/2));P$; 8150 PRINT TAB(C(3)+C(4)-4);"High" 8160 REM: 8170 PRINT TAB(C(3)); 8180 FOR K=1 TO X3+3: PRINT "-";: NEXT K 8190 PRINT "!"; 8200 FOR K=X3+5 TO C(4): PRINT "-";: NEXT K 8210 PRINT 8220 REM: 8230 REM: Now, print the chart. 8240 REM: 8250 LET X4=D3-1,X5=1 8260 GOSUB 2590 8270 LET X2=M3 8280 IF M4*D4*Y4=0 THEN 8300 8290 IF M3>=M4 AND D3>=D4 AND Y3>=Y4 THEN LET X5=0: GOTO 3770 8300 LET X=FNN(M3,D3,Y3) 8310 LET M3=M8,D3=D8,Y3=Y8 8320 IF INP(252)=ASC("D") OR INP(252)=ASC("d") THEN 3770 8330 IF X<>1 THEN 8260 8340 IF INP(252)=ASC("M") OR INP(252)=ASC("m") THEN 3770 8350 IF X2=12 AND (INP(252)=ASC("Y") OR INP(252)=ASC("y")) THEN GOTO 3770 8360 IF P=-1 THEN 8260 8370 PRINT : PRINT 8380 FOR I=M(X2)+1 TO 31+X4: PRINT : PRINT : NEXT I 8390 LET X4=0 8400 GOTO 8020 8410 REM: 8420 REM: This routine gives help to the user. 8430 REM: 8440 GOSUB 3600 8450 PRINT "Help on which command? (return for entire description) "; 8460 LET X1=1: GOSUB 3590 8470 IF I$="" THEN 8610 8480 REM: 8490 REM: Convert to upper case for checking. 8500 REM: 8510 IF I$>="a" THEN LET I$=CHR(ASC(I$)-32) 8520 REM: 8530 REM: If a command letter has been entered, give help 8540 REM: only on that particular command, else abort. 8550 REM: 8560 SEARCH I$,"NBSOWPIEAMCQH",X: IF X=0 THEN 3860 8570 REM: 8580 REM: Open the biorhythm text file and search for the 8590 REM: help section. 8600 REM: 8610 FILE #3;"BIOTEXT",1 8620 READ #3;L$ 8630 IF L$<>"HELPTEXT" THEN 8620 8640 REM: 8650 REM: The help section has been found, now scan for wanted 8660 REM: command description, then display it. 8670 REM: 8680 READ #3;L$ 8690 IF I$="" THEN 8750 8700 IF LEN(L$)<6 THEN 8680 8710 IF L$(1,3)<>I$+" -" THEN 8680 8720 REM: 8730 REM: We've got it, now print it. 8740 REM: 8750 GOSUB 3610 8760 REM: 8770 REM: Start printing now. 8780 REM: 8790 IF L$<>"" THEN PRINT L$ 8800 READ #3;L$ 8810 IF EOF(3)=6 THEN 8980 8820 IF L$="" THEN LET L$=" " 8830 IF L$(1,1)<>"!" THEN 8790 8840 REM: 8850 REM: We're at the bottom of the screen, pause a bit. 8860 REM: 8870 CURSOR 15,0 8880 PRINT "Type any key to continue: ("+A$+"ESCAPE"+A$+" to abort) "; 8890 SET CM=1: INPUT ,(1,0)"",C$: SET CM=0 8900 IF C$=CHR(27) THEN 8980: REM: Escape? 8910 IF L$="!!" THEN 8980 8920 IF I$="" THEN LET L$="": GOTO 8750 8930 REM: 8940 REM: If "ESCAPE" has been typed, the end of the text 8950 REM: reached, or the end of a single, wanted command 8960 REM: has been reached, then come here to exit. 8970 REM: 8980 CLOSE #3 8990 GOTO 3850 9000 REM: 9010 REM: This is the "quit" routine. If the "CLEAR", 9020 REM: "HOME" and "MODE" keys have been knocked out, 9030 REM: this puts them back to life. Also, speed 9040 REM: control is turned on again and the cursor is 9050 REM: turned back an. 9060 REM: 9070 GOSUB 3600 9080 PRINT "Do you really want to quit? (Y/N): "; 9090 LET X1=1: GOSUB 3590 9100 IF I$="" THEN 3860 9110 IF ASC("Y")<>ASC(I$) AND ASC("y")<>ASC(I$) THEN 3860 9120 SET DS=3: CURSOR 0,0 9130 FOR I=1 TO 16: PRINT : NEXT I 9140 CURSOR 1: PRINT "Thank you very much.": PRINT 9150 REM: 9160 REM: Restore any knocked out keys. 9170 REM: 9180 CURSOR 12,0 9190 SET DS=0,0: SET CM=1 9200 IF C1 THEN POKE L1,11 9210 IF C2 THEN POKE L2,14 9220 IF NOT C3 THEN 9260 9230 POKE L3,194 9240 POKE L4,202: POKE L4+1,66: POKE L4+2,51 9250 POKE L5,202: POKE L5+1,66: POKE L5+2,51 9260 IF C4 THEN POKE L6,95: POKE L7,95 9270 IF C5 THEN POKE L8,24 9280 END