--- title: "Bio-Graph" id: 55963 type: "computer_media" slug: "bio-graph" url: "http://localhost/computer_media/bio-graph/" markdown_url: "http://localhost/computer_media/bio-graph.md" published_at: "2024-07-14T12:54:44+00:00" modified_at: "2026-03-30T21:41:07+00:00" author: "David Anderson" featured_image: url: "http://localhost/wp-content/uploads/2024/07/SCR-20240714-ihpm.png" excerpt: "Enter your birthday and a target month to watch three sinusoidal biorhythm curves — Physical, Sensitivity, and Intellectual — plotted live across the screen." category: - name: "Archived Media" slug: "archived-media" taxonomy: "category" url: "http://localhost/category/archived-media/" post_tag: - name: "Downloadable" slug: "downloadable" taxonomy: "post_tag" url: "http://localhost/tag/downloadable/" - name: "TS 2068" slug: "ts2068" taxonomy: "post_tag" url: "http://localhost/tag/ts2068/" model: - name: "Timex/Sinclair 2068" slug: "ts-2068" taxonomy: "model" url: "http://localhost/model/ts-2068/" genre: - name: "Entertainment" slug: "entertainment" taxonomy: "genre" url: "http://localhost/type/entertainment/" media_contents: - id: 55923 title: "Timex Sinclair Public Domain Library Tape 2003" type: "computer_media" url: "http://localhost/computer_media/timex-sinclair-public-domain-library-tape-2003/" media_type: "Program" download_url: "https://archive.org/download/timex-sinclair-software-archive/Bio-graph%20%28198x%29%28TS2068%29%28US%29%28Program%29.zip" mediadate: "198x" images: - url: "http://localhost/wp-content/uploads/2024/07/SCR-20240714-ihpm.png" media_type_tags: "Entertainment" --- # Bio-Graph This program plots a biorhythm chart, graphing the Physical (23-day), Sensitivity (28-day), and Intellectual (33-day) sinusoidal cycles for a given person and calendar month. The user inputs their birth date and the target month, and the program computes the elapsed days between those dates using a Julian-day-style integer accumulation routine at line 3000. Each cycle is drawn pixel-by-pixel using PLOT, with the sine argument converted from degrees to radians by multiplying by the constant 0.0174533. When a curve exceeds the screen boundaries (above row 18 or below row 158), the cycle identifier letter (“P”, “S”, or “I”) is printed at the top or bottom of the screen to indicate overflow. The calendar logic at lines 2082–2088 correctly handles month lengths including a basic leap-year check for February. *** ## Program Analysis ### Program Structure The program is organized into well-separated functional blocks: 1. **Lines 105–210:** Draw the chart grid — vertical lines every 8 pixels for each day, and a horizontal baseline at y=88. 2. **Lines 400–430:** Print day-number labels along the x-axis. 3. **Lines 500–740:** Plot the three biorhythm curves (Physical, Sensitivity, Intellectual) by calling the shared curve-drawing subroutine at line 1000. 4. **Line 999:**`STOP` to halt after display. 5. **Lines 1000–1040:** Generic sine-curve plotter; shared by all three cycles. 6. **Lines 2000–2095:** Main input and setup subroutine — collects birth date, graph month, computes elapsed days, determines month length, and prints the chart header. 7. **Lines 2200–2420:** Cycle-specific phase-calculation subroutines for Physical (23), Sensitivity (28), and Intellectual (33) cycles. 8. **Lines 3000–3400:** Date-to-integer-day conversion routine, producing an absolute day count in `dt`. 9. **Lines 4000–4010:**`SAVE` block, separated from the main program flow. ### Date Arithmetic (Lines 3000–3400) The date-to-day-number routine at line 3000 converts a calendar date into an absolute integer day count stored in `dt`. It computes years elapsed since 1901 (`yt`), counts leap years (`lt`), and uses a hard-coded cumulative day-of-year table via a chain of `IF … GO TO` statements for each month. The formula `yt*365+306+lt+mt+d` is applied, with an additional `+1` added at line 3310 if the year being processed is itself a leap year. There is a subtlety: the caller decrements `y` by 1 before the call (`LET y=y-1` at lines 2000 and 2020), and the subroutine increments it back at line 3300 (`LET y=y+1`) before the leap-year check at 3310, meaning January and February of a leap year are handled via the `lt` adjustment at line 3020 rather than the post-increment check. ### Curve-Drawing Subroutine (Lines 1000–1040) The single generic plotter at line 1000 iterates `x` from 0 to `8*days` pixels. For each pixel column, it computes `y=88+72*SIN(s*0.0174533)`, converting the accumulated angle `s` in degrees to radians using the approximation `π/180 ≈ 0.0174533`. The center baseline is y=88 and the amplitude is 72 pixels. The PAPER color is set by each caller before invoking the subroutine, coloring the ink of subsequent PLOTs. If the computed y-coordinate falls outside the visible plot area (above 158 or below 18), the cycle’s letter identifier is printed at the screen edge to signal overflow. ### Phase Calculation Subroutines Lines 2200–2420 each calculate the starting phase for one biorhythm cycle from the total elapsed days `r` (the difference between graph-month start and birth date). The integer quotient `q` is discarded; the remainder `d` gives the number of days into the current cycle. The angular increment per pixel `a` and starting angle `s` are then set in the calling block before the curve subroutine is invoked. The current phase day is also printed on the screen as a status line. | Cycle | Period (days) | Subroutine | Color (PAPER) | Label | | --- | --- | --- | --- | --- | | Physical | 23 | 2200 | 5 (Cyan) | P | | Sensitivity | 28 | 2300 | (unchanged) | S | | Intellectual | 33 | 2400 | 4 (Green) | I | ### Month-Length Calculation (Lines 2082–2088) After the user inputs the graph month number, `days` is initially set equal to the month number (`LET days=m`). Lines 2082–2088 then replace `days` with the actual number of days in that month. February gets 28 days by default, bumped to 29 if the year is divisible by 4. April, June, September, and November get 30 days. All other months (except already-handled February) get 31. Note that the leap-year test (`years/4=INT(years/4)`) is a simple divisibility-by-4 check and does not account for century years. ### Key BASIC Idioms and Notable Techniques - The shared curve subroutine at line 1000 is parameterized entirely through global variables (`a`, `s`, `a$`, `days`), avoiding code duplication across the three cycles. - The delay loop `FOR t=1 TO 250: NEXT t` at line 2040 provides a brief pause before clearing the screen on an input error, a common BASIC timing idiom. - The grid lines are drawn using `PLOT`/`DRAW` within a `FOR` loop stepping by 8 pixels, matching each screen column to one day. - `PAPER` is used to change the color context for each curve, with `PAPER 7` restoring white at line 740 after all curves are drawn. - The month table at lines 3100–3210 uses explicit `GO TO 3300` or `GO TO 3400` branches to handle months needing the post-increment leap adjustment separately from those that do not. ### Bugs and Anomalies - Line 2000 contains a typo in the prompt string: `"Your BIIRTHDAY (MM/DD/YY)?"` — “BIRTHDAY” is misspelled with a double “I”. - Line 2100 contains a `REM *S/cycle*` comment that appears to be a leftover stub; it is never reached by normal program flow (line 2095 returns before reaching it). - The leap-year test at line 2084 uses only divisibility by 4, not the full Gregorian rule (divisible by 100 and 400 exceptions), so years like 1900 would be incorrectly treated as leap years if entered. - The `SENSITIVITY` curve subroutine at line 2300 does not set a PAPER color before plotting, so it inherits whatever color was last set (Cyan from the Physical curve). This may be intentional to distinguish it visually, but it is not explicit. ## Source Code ``` 105 GO SUB 2000 110 FOR l=0 TO 8*days STEP 8 120 PLOT l,16: DRAW 0,144: NEXT l 200 PLOT 0,88 210 DRAW days*8,0 400 PRINT AT 11,0;"0": PRINT AT 11,5;"5" 410 FOR n=10 TO days STEP 5 420 PRINT AT 11,n-1;n 430 NEXT n 500 REM *p/curve* 510 PAPER 5: GO SUB 2200 520 LET a=360/(8*23): LET s=a*d*8: LET a$="P" 530 GO SUB 1000 600 REM *s/curve* 610 GO SUB 2300 620 LET a=360/(8*28): LET s=a*d*8: LET a$="S" 630 GO SUB 1000 700 REM *I/curve* 710 PAPER 4: GO SUB 2400 720 LET a=360/(8*33): LET s=a*d*8: LET a$="I" 730 GO SUB 1000 740 PAPER 7 999 STOP 1000 FOR x=0 TO 8*days 1005 LET y=88+72*SIN (s*.0174533) 1006 IF y>158 AND x/8=INT (x/8) THEN PRINT AT 2,x/8;a$ 1007 IF y<18 AND x/8=INT (x/8) THEN PRINT AT 19,x/8;a$ 1010 PLOT x,y 1020 LET s=s+a 1030 NEXT x 1040 RETURN 2000 INPUT "Your BIIRTHDAY (MM/DD/YY)?";m,d,y: LET y=y-1 2005 GO SUB 3000 2010 LET ds=dt 2020 INPUT "BIO-GRAPH month (MM/YY)?";m,y: LET d=1: LET days=m: LET month=m: LET years=y: LET y=y-1 2025 GO SUB 3000 2030 LET de=dt 2040 LET r=de-ds: IF r<0 THEN PRINT "OOPS!! Dates entered wrong!": FOR t=1 TO 250: NEXT t: CLS : GO TO 2000 2082 IF days=2 THEN LET days=28 2084 IF days=28 AND years/4=INT (years/4) THEN LET days=29 2087 IF days=4 OR days=6 OR days=9 OR days=11 THEN LET days=30: GO TO 2090 2088 IF days<>28 AND days<>29 THEN LET days=31 2090 INPUT "What is your FIRST NAME?";n$ 2092 PRINT " B I O - G R A P H" 2093 PRINT "For: ";n$;" Month: ";month;"/";years 2095 RETURN 2100 REM *S/cycle* 2200 REM *P/cycle* 2210 LET q=INT (r/23): LET d=r-(q*23): PRINT AT 20,0;"Physical=";d 2220 RETURN 2300 REM 2310 LET q=INT (r/28): LET d=r-q*28: PRINT AT 20,16;"Sensitivity=";d 2320 RETURN 2400 REM 2410 LET q=INT (r/33): LET d=r-q*33: PRINT AT 21,8;"Intellectual=";d 2420 RETURN 3000 LET yt=y-1901 3010 LET lt=INT (yt/4) 3020 IF y/4=INT (y/4) AND m<3 THEN LET lt=lt+1 3100 IF m=1 THEN LET mt=0: GO TO 3400 3110 IF m=2 THEN LET mt=31: GO TO 3400 3120 IF m=3 THEN LET mt=59: GO TO 3300 3130 IF m=4 THEN LET mt=90: GO TO 3300 3140 IF m=5 THEN LET mt=120: GO TO 3300 3150 IF m=6 THEN LET mt=151: GO TO 3300 3160 IF m=7 THEN LET mt=181: GO TO 3300 3170 IF m=8 THEN LET mt=212: GO TO 3300 3180 IF m=9 THEN LET mt=243: GO TO 3300 3190 IF m=10 THEN LET mt=273: GO TO 3300 3200 IF m=11 THEN LET mt=304: GO TO 3300 3210 IF m=12 THEN LET mt=334 3300 LET dt=(yt*365+306)+lt+mt+d: LET y=y+1 3310 IF y/4=INT (y/4) THEN LET dt=dt+1 3330 RETURN 3400 LET dt=(yt*365+306)+lt+mt+d: RETURN 4000 SAVE "BIO-GRAPH" 4010 STOP ```