--- title: "Weather Forecast" id: 57524 type: "computer_media" slug: "weather-forecast" url: "http://localhost/computer_media/weather-forecast/" markdown_url: "http://localhost/computer_media/weather-forecast.md" published_at: "2024-10-05T21:27:01+00:00" modified_at: "2026-04-03T07:58:24+00:00" author: "David Anderson" featured_image: url: "http://localhost/wp-content/uploads/2024/10/279_WF.png" excerpt: "A four-section weather reference tool that deduces tomorrow's forecast from wind direction and barometer readings using an elaborate chain of Boolean conditions." 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 1000" slug: "ts1000" taxonomy: "post_tag" url: "http://localhost/tag/ts1000/" model: - name: "Timex/Sinclair 1000" slug: "ts-1000" taxonomy: "model" url: "http://localhost/model/ts-1000/" genre: - name: "Home" slug: "home" taxonomy: "genre" url: "http://localhost/type/home/" - name: "Science" slug: "science" taxonomy: "genre" url: "http://localhost/type/science/" media_contents: - id: 56737 title: "Timex Sinclair Public Domain Library Tape 1006" type: "computer_media" url: "http://localhost/computer_media/timex-sinclair-public-domain-library-tape-1006/" media_type: "Program" mediadate: "198x" images: - url: "http://localhost/wp-content/uploads/2024/10/279_WF.png" media_type_tags: "Home, Science" --- This program presents a menu-driven weather reference tool with four sub-sections: a barometric-pressure-and-wind-direction forecast engine, a wind chill chart, a relative humidity index table, and a millibars-to-inches conversion chart. The forecast engine encodes a lookup table entirely as a chain of compound Boolean conditions in lines 400–450, mapping nine wind directions against eight barometric readings to one of seven forecast messages. Subroutines at lines 2191–2194 provide reusable header-printing routines for forecast and error messages. The program uses FAST mode, inverse-video characters for labels and titles, and PAUSE 4E4 as a timed “press ENTER” gate. *** ## Program Analysis ### Program Structure The program is organised as a top-level menu dispatcher followed by largely independent sections. Control flow is summarised below: | Line(s) | Section | Purpose | | --- | --- | --- | | 1–10 | Initialisation | REM label and FAST mode | | 25–67 | Main menu | Display, INPUT M, dispatch to sub-section | | 80–99 | Disclaimer | Advisory text, timed pause | | 105–260 | Data entry | Wind direction (W) and barometer condition (B) inputs | | 400–450 | Forecast lookup | Boolean chain dispatching to forecast messages | | 820–840 | Input validation | Range checks on W and B (reached only if no condition matched) | | 1000–1675 | Forecast messages | Seven outcomes, each ending with STOP | | 1700–1790 | Error messages | Invalid menu, wind, and barometer entries | | 1900–1970 | Wind chill chart | Static AT-positioned table | | 2000–2090 | Humidity index | Static AT-positioned table | | 2100–2190 | Millibars chart | TAB-positioned conversion table | | 2191–2194 | Subroutines | Forecast/error header printers | | 2200–2220 | Save/restart | CLEAR, SAVE, RUN | ### Forecast Lookup Technique Rather than using arrays or DATA/READ, the entire 9×8 wind-direction/barometer matrix is encoded as long chains of `AND`/`OR` Boolean expressions across lines 400–450. Each line tests a set of (W,B) pairs that map to the same forecast outcome and jumps to the corresponding message block. This approach avoids the overhead of array subscripting and is a common space-saving idiom on memory-constrained systems, at the cost of very long lines. Because the ZX81 evaluates `AND` before `OR`, each `W=x AND B=y` pair is correctly formed without parentheses. The seven outcomes correspond to: fair/stable (1000), fair/warmer (1100), fair/cooler (1200), overcast (1300), overcast/light precipitation (1400), moderate precipitation (1500), and severe storm warning (1600). ### Input Validation Anomaly Input validation for wind (`W`) and barometer (`B`) at lines 820–840 is only reachable if none of the Boolean chains at lines 400–450 match. In practice, every valid (W,B) combination from 1–9 and 1–8 should be covered by those chains, so lines 820–840 would only fire for genuinely uncovered combinations. However, validation for out-of-range values (e.g. `W=0` or `W=10`) is correctly handled here because the lookup chains do not fire for those values. This is a somewhat fragile design: if any valid combination were accidentally omitted from the chains, the program would silently fall through to the range-check rather than displaying an error. ### Subroutine Usage Lines 2191–2194 define two tiny subroutines. `GOSUB 2191` prints the “F O R E C A S T” header; `GOSUB 2193` prints “INVALID ENTRY”. Each is two lines: a PRINT and a RETURN. This avoids repeating the header text in every forecast block, saving memory at the cost of a subroutine call. ### Display Techniques - Inverse-video characters (using `%X` escapes) are used for titles, menu items, and emphasis — e.g. the banner at line 25 and the “SEVERE STORM WARNING” message at line 1640. - The wind chill and humidity tables (lines 1900–2040) use `PRINT AT row,col` extensively to position each data cell individually, since there is no TAB-based column alignment that could handle the variable-width negative numbers cleanly. - The millibars chart (line 2100) instead uses `TAB` for its two-column layout, which is simpler given that all values are positive. - Multiple leading commas in PRINT statements are used as a newline-padding idiom to centre content vertically on screen. ### Timed Pause Line 97 uses `PAUSE 4E4` (40,000 frames ≈ 26 minutes at 50 Hz, or effectively indefinite) after the disclaimer text. This acts as a “press any key or wait” gate. On the ZX81, any key press or a sufficiently long wait will both exit PAUSE, so this is equivalent to a “press ENTER to continue” prompt without requiring an INPUT statement. ### Save Block Lines 2200–2220 perform a `CLEAR`, `SAVE "1027\9"` (the filename contains an inverse digit, signalling auto-run on load), and `RUN`. This is a standard ZX81 idiom to save an auto-running copy of the program to tape and immediately restart it. ### Notable Bugs - Line 80 contains a typo: “INTENED” instead of “INTENDED” — a cosmetic error only. - Line 2000 labels the column header as “AIR TEMPERTURE” (missing an ‘A’) and line 2018 has “APPARENT TEMPERTURE” — both spelling errors in the display text. - Line 67 validates the main menu input (`IF M<1 OR M>4`) but this line is only reached after the dispatch GOTOs at lines 60–66, meaning it is correctly positioned in the fall-through path for invalid values. ## Source Code ``` 1 REM "WEATHER" 10 FAST 25 PRINT ,,,,"% % % % %T%S%/%1%0%0%0% %W%E%A%T%H%E%R% %F%O%R%E%C%A%S%T% % % ",,,,,,TAB 11;"SELECT ONE";,,,,,"%1 WEATHER FORECAST";,,,,,"%2 WIND CHILL CHART";,,,,,"%3 HUMIDITY INDEX";,,,,,;"%4 MILLIBARS CONVERSION CHART" 50 INPUT M 55 CLS 60 IF M=1 THEN GOTO 75 62 IF M=2 THEN GOTO 1900 64 IF M=3 THEN GOTO 2000 66 IF M=4 THEN GOTO 2100 67 IF M<1 OR M>4 THEN GOTO 1700 80 PRINT ,,,,,,"THIS PROGRAM IS NOT INTENDED TO ";"FORECAST EVERY POSSIBLE WEATHER ";"CONDITION. IT IS INTENED TO BE ";" ONLY A GENERAL GUIDE.",,,,,"WHEN THIS PROGRAM IS RUN IN THE ";"EARLY EVENING, THE FORECAST WILL";"BE VALID FOR THE FOLLOWING ";"DAY ONLY UNLESS OTHERWISE STATED.",,,,,;TAB 8;"PRESS %E%N%T%E%R WHEN READY" 97 PAUSE 4E4 99 CLS 105 PRINT "ENTER WIND DIRECTION";,,,,,;"%1 CALM",,,,;"%2 NORTH",,,,;"%3 NORTHEAST",,,,;"%4 EAST",,,,;"%5 SOUTHEAST",,,,;"%6 SOUTH",,,,;"%7 SOUTHWEST",,,,;"%8 WEST",,,,;"%9 NORTHWEST" 195 INPUT W 199 CLS 205 PRINT ,,"ENTER BAROMETRIC CONDITION",,,,,"%1 30.5 OR HIGHER"," STEADY OR RISING";,"%2 30.5 OR HIGHER";," FALLING";,,"%3 30 TO 30.5";,," STEADY OR RISING";,"%4 30 TO 30.5";,," FALLING";,,"%5 29.5 TO 30";,," STEADY OR RISING";,"%6 29.5 TO 30";,," FALLING";,,"%7 29.4 OR LOWER";," STEADY OR RISING";,"%8 29.4 OR LOWER";," FALLING" 250 INPUT B 260 CLS 400 IF W=1 AND B=1 OR W=1 AND B=2 OR W=1 AND B=3 OR W=1 AND B=4 OR W=1 AND B=5 OR W=2 AND B=1 OR W=2 AND B=2 OR W=3 AND B=1 OR W=3 AND B=2 OR W=4 AND B=1 OR W=4 AND B=2 OR W=5 AND B=1 OR W=5 AND B=2 OR W=6 AND B=1 OR W=6 AND B=2 OR W=7 AND B=1 OR W=7 AND B=2 OR W=8 AND B=1 OR W=8 AND B=2 OR W=8 AND B=3 OR W=9 AND B=1 OR W=9 AND B=2 OR W=9 AND B=3 THEN GOTO 1000 425 IF W=6 AND B=3 OR W=6 AND B=5 OR W=6 AND B=7 OR W=7 AND B=3 OR W=7 AND B=5 OR W=7 AND B=7 THEN GOTO 1100 430 IF W=1 AND B=7 OR W=2 AND B=3 OR W=2 AND B=4 OR W=2 AND B=5 OR W=2 AND B=7 OR W=3 AND B=3 OR W=3 AND B=4 OR W=3 AND B=5 OR W=3 AND B=7 OR W=4 AND B=3 OR W=4 AND B=5 OR W=4 AND B=7 OR W=5 AND B=3 OR W=5 AND B=5 OR W=5 AND B=7 OR W=8 AND B=5 OR W=8 AND B=7 OR W=9 AND B=5 OR W=9 AND B=7 THEN GOTO 1200 435 IF W=2 AND B=6 OR W=3 AND B=6 OR W=6 AND B=4 OR W=7 AND B=4 OR W=8 AND B=4 OR W=9 AND B=4 THEN GOTO 1300 440 IF W=1 AND B=6 OR W=4 AND B=4 OR W=4 AND B=6 OR W=5 AND B=4 OR W=5 AND B=6 OR W=6 AND B=6 OR W=7 AND B=6 OR W=9 AND B=6 THEN GOTO 1400 445 IF W=1 AND B=8 OR W=2 AND B=8 OR W=4 AND B=8 OR W=5 AND B=8 OR W=6 AND B=8 OR W=8 AND B=6 OR W=9 AND B=8 THEN GOTO 1500 450 IF W=3 AND B=8 OR W=7 AND B=8 OR W=8 AND B=8 THEN GOTO 1600 820 IF W<1 OR W>9 THEN GOTO 1730 840 IF B<1 OR B>8 THEN GOTO 1760 1000 PRINT ,,,, 1010 GOSUB 2191 1030 PRINT ,,,,,,"FAIR FOR SEVERAL DAYS.",,,"LITTLE TEMPERATURE CHANGE." 1060 STOP 1100 PRINT ,,,, 1110 GOSUB 2191 1130 PRINT ,,,,"FAIR - TURNING WARMER." 1150 STOP 1200 PRINT ,,,, 1210 GOSUB 2191 1230 PRINT ,,,,,,"FAIR - TURNING COOLER." 1250 STOP 1300 PRINT ,,,, 1310 GOSUB 2191 1330 PRINT ,,,,,,,," OVER CAST" 1350 STOP 1400 PRINT ,,,, 1410 GOSUB 2191 1430 PRINT ,,,,,,"OVERCAST - CHANCE OF LIGHT",,,"PRECIPITATION." 1450 STOP 1500 PRINT ,,,, 1510 GOSUB 2191 1530 PRINT ,,,,,,"MODERATE PRECIPITATION." 1550 STOP 1600 PRINT ,, 1610 GOSUB 2191 1640 PRINT ,,,," %S%E%V%E%R%E% %S%T%O%R%M% %W%A%R%N%I%N%G",,,"IF SUMMER - POSSIBLE SEVERE","THUNDER STORMS WITH HIGH WIND","AND POSSIBLE HAIL. IF DANGEROUS","WEATHER SHOULD APPROACH, BE","PREPARED TO TAKE COVER.",,,"IF WINTER - BE ALERT FOR","BLIZZARD CONDITIONS, INCLUDING","HEAVY SNOW, HIGH WIND AND COLD","TEMPERATURES. WATCH FOR FALLING","TREE LIMBS AND POWER LINES." 1675 STOP 1700 PRINT ,,,, 1705 GOSUB 2193 1715 PRINT ,,,,,,,,"ENTER ONLY 1-4 FOR THE MAIN MENU",,,,,,,,"ENTER %R%U%N TO START OVER" 1725 STOP 1730 PRINT ,,,, 1735 GOSUB 2193 1745 PRINT ,,,,,,,,"ENTER ONLY 1-9 FOR WIND",,,"DIRECTION",,,,,,"ENTER %R%U%N TO START OVER." 1758 STOP 1760 PRINT ,,,, 1765 GOSUB 2193 1775 PRINT ,,,,,,,,"ENTER ONLY 1-8 FOR BAROMETRIC",,,"CONDITION",,,,,,"ENTER %R%U%N TO START OVER" 1790 STOP 1900 PRINT AT 2,9;"WIND CHILL CHART";AT 4,11;"TEMPERATURE";AT 6,9;"40 30 20 10 0 -10";AT 8,2;"W";AT 9,2;"I";AT 10,2;"N";AT 11,2;"D";AT 13,2;"S";AT 14,2;"P";AT 15,2;"E";AT 16,2;"E";AT 17,2;"D";AT 17,13;"WIND CHILL" 1910 PRINT AT 9,6;"%5";AT 10,5;"%1%0";AT 11,5;"%1%5";AT 12,5;"%2%0";AT 13,5;"%2%5";AT 14,5;"%3%0";AT 15,5;"%3%5";AT 9,9;"37";AT 10,9;"28";AT 11,9;"22";AT 12,9;"18";AT 13,9;"16";AT 14,9;"13";AT 15,9;"11" 1920 PRINT AT 9,12;"27";AT 10,12;"16";AT 11,13;"9";AT 12,13;"4";AT 13,13;"0";AT 14,12;"-2";AT 15,12;"-4";AT 9,16;"16";AT 10,17;"4";AT 11,16;"-5";AT 12,16;"-10";AT 13,16;"-15";AT 14,16;"-18";AT 15,16;"-20" 1930 PRINT AT 9,21;"6";AT 10,20;"-9";AT 11,20;"-18";AT 12,20;"-26";AT 13,20;"-29";AT 14,20;"-33";AT 15,20;"-35";AT 9,24;"-5";AT 10,24;"-21";AT 11,24;"-36";AT 12,24;"-39";AT 13,24;"-44";AT 14,24;"-48";AT 15,24;"-49";AT 9,28;"-15";AT 10,28;"-33";AT 11,28;"-45";AT 12,28;"-53";AT 13,28;"-59";AT 14,28;"-63";AT 15,28;"-67";AT 20,2;"ENTER %R%U%N TO RETURN TO MENU" 1970 STOP 2000 PRINT AT 2,5;"RELATIVE HUMIDITY INDEX";AT 4,9;"AIR TEMPERTURE";AT 6,7;"75 80 85 90 95 100";AT 8,1;"H";AT 9,1;"U";AT 10,1;"M";AT 11,1;"I";AT 12,1;"D";AT 13,1;"I";AT 14,1;"T";AT 15,1;"Y";AT 8,3;"%1%0";AT 9,3;"%2%0";AT 10,3;"%3%0";AT 11,3;"%4%0";AT 12,3;"%5%0";AT 13,3;"%6%0";AT 14,3;"%7%0";AT 15,3;"%8%0";AT 16,3;"%9%0";AT 17,2;"%1%0%0";AT 18,9;"APPARENT TEMPERTURE" 2010 PRINT AT 8,7;"70";AT 9,7;"72";AT 10,7;"73";AT 11,7;"74";AT 12,7;"75";AT 13,7;"76";AT 14,7;"77";AT 15,7;"78";AT 16,7;"79";AT 17,7;"80";AT 8,11;"75";AT 9,11;"77";AT 10,11;"78";AT 11,11;"79";AT 12,11;"81";AT 13,11;"82";AT 14,11;"85";AT 15,11;"86";AT 16,11;"88";AT 17,11;"91" 2020 PRINT AT 8,15;"80";AT 9,15;"82";AT 10,15;"84";AT 11,15;"86";AT 12,15;"88";AT 13,15;"90";AT 14,15;"93";AT 15,15;"97";AT 16,14;"102";AT 17,14;"108";AT 8,19;"85";AT 9,19;"87";AT 10,19;"90";AT 11,19;"93";AT 12,19;"96";AT 13,18;"100";AT 14,18;"106";AT 15,18;"113";AT 16,18;"122" 2040 PRINT AT 8,23;"90";AT 9,23;"93";AT 10,23;"96";AT 11,22;"101";AT 12,22;"107";AT 13,22;"114";AT 14,22;"124";AT 15,22;"136";AT 8,28;"95";AT 9,28;"99";AT 10,27;"104";AT 11,27;"110";AT 12,27;"120";AT 13,27;"132";AT 14,27;"144";AT 20,2;"ENTER %R%U%N TO RETURN TO MENU" 2090 STOP 2100 PRINT AT 1,4;"MILLIBARS CONVERSION CHART",,," INCHES"," MILLIBARS";,,,TAB 4;"29.06";TAB 19;"984";,TAB 4;"29.15";TAB 19;"987";,TAB 4;"29.24";TAB 19;"990";,TAB 4;"29.50";TAB 19;"999";,TAB 4;"29.68";TAB 19;"1005";,TAB 4;"29.94";TAB 19;"1014";,TAB 4;"30.03";TAB 19;"1017";,TAB 4;"30.21";TAB 19;"1023";,TAB 4;"30.30";TAB 19;"1026";,TAB 4;"30.39";TAB 19;"1029";,TAB 4;"30.56";TAB 19;"1035";,TAB 4;"30.74";TAB 19;"1041";,TAB 4;"30.92";TAB 19;"1047";,,,"ENTER %R%U%N TO RETURN TO MENU" 2190 STOP 2191 PRINT " F O R E C A S T" 2192 RETURN 2193 PRINT " INVALID ENTRY" 2194 RETURN 2200 CLEAR 2210 SAVE "1027%9" 2220 RUN ```