--- title: "Program Calendar" id: 72063 type: "computer_media" slug: "program-calendar" url: "http://localhost/computer_media/program-calendar/" markdown_url: "http://localhost/computer_media/program-calendar.md" published_at: "2026-10-21T05:29:43+00:00" modified_at: "2026-10-21T05:34:29+00:00" author: "David Anderson" featured_image: url: "http://localhost/wp-content/uploads/2026/10/cale40b2-1.png" excerpt: "Calendar printer that shows one month or a whole year, with optional printer headings such as “This calendar is for:” and a centered custom title line." 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/" indiv: - name: "Emmett Jenkins" slug: "emmett-jenkins" taxonomy: "indiv" url: "http://localhost/indiv/emmett-jenkins/" genre: - name: "Calendar" slug: "calendar" taxonomy: "genre" url: "http://localhost/type/calendar/" media_type: "Program" programmers: - name: "Emmett Jenkins" slug: "emmett-jenkins" taxonomy: "indiv" url: "http://localhost/indiv/emmett-jenkins/" download_url: "https://archive.org/download/timex-sinclair-software-archive/Program%20Calendar%20%28198x%29%28Jenkins%2C%20Emmett%29%28TS2068%29%28US%29%28Program%29.zip" tsrun_member: "Program Calendar (198x)(Jenkins, Emmett)(TS2068)(US)(Program)/Program Calendar (198x)(Jenkins, Emmett)(TS2068)(US)(Program).tap" mediadate: "1985" images: - url: "http://localhost/wp-content/uploads/2026/10/cale40b2-1.png" - url: "http://localhost/wp-content/uploads/2026/10/cale40b2-2.png" - url: "http://localhost/wp-content/uploads/2026/10/cale40b2-3.png" related_content: - id: 71175 title: "Calendar Program" type: "computer_media" url: "http://localhost/computer_media/calendar-program/" media_type_tags: "Calendar" --- # Program Calendar Prints a month calendar for any year from 1900 to 1999, either on screen only or copied to the printer. A printer can also be given a whole year, one month after another. Before the calendar you can send headings to the printer: “THIS CALENDAR IS FOR:”, “MONTH of BIRTH”, “YEAR of BIRTH”, or a line of your own of up to 32 characters, either centered or not. Each month is printed under its name in a bordered layout, with a decorative block-graphic panel below the dates. The title screen reads “PROGRAM CALENDAR BY: EMMETT L. JENKINS” and is dated September 1985. George Chambers’ disk notes rate it as probably nicer to view than the similar calendar programs on the disk. ## Program Analysis ### Program Structure Lines 1–4 set the keyboard click (`POKE 23609,20`), turn off caps lock and show the flashing title. The printer-heading menu at lines 1000–8510 loops until N is pressed, and its `RETURN` at line 7000 drops back into setup. Lines 10–53 read the month names into `m$` and ask for the year (two digits), the month and an output mode: `y` (whole year to the printer), `m` (one month to the printer) or `d` (display only). The calendar itself is printed by lines 65–188, and `COPY` at line 220 sends each screen to the printer. ### Weekday Calculation The month table is the string `a$="1440250361462"`, a digit for each month plus a thirteenth for wrap-around. Line 100 computes `a=x*y+y+x*VAL a$(m)` with `x=4`, which is 5y + 4k, and line 110 takes `INT ((a mod 28)/4)`. This works out to (y + INT (y/4) + k) mod 7 without a separate division by four. The number of days in the month comes from the difference between adjacent table digits plus 28, with 7 added when the difference is negative (lines 170–180). Each date is placed with `TAB (w*x-w-x+u)+5`, which is three columns per weekday. ### Notable Techniques - A day-of-week calculation folded into one expression using the constants 4 and 28. - Month lengths taken from the same 13-digit table used for the weekday offsets. - Several `GO TO` targets are missing lines (70, 64, 1100, 8000) and rely on the ROM moving on to the next line that exists. ### Potential Issues - There is no leap-year correction. February always has 28 days, and in leap years January and February start one weekday late. For example, January 1984 starts on Monday instead of Sunday. - The heading menu has keys for `j` and `f` that are not listed on screen; `j` jumps to the missing line 3000 and so prints “MONTH of BIRTH”. - Line 1 POKEs the low byte of ERR_SP (23613) with a value worked out from a ROM byte. The purpose is not clear from the listing. It comes from a Larken disk in the TS User Group’s collection (disk l-23). For this release it was converted to load and run from tape on a stock TS2068: the LKDOS `RANDOMIZE USR 100` before the `SAVE` line was removed. It was tested in ZEsarUX. ## Source Code ``` 1 LET W=PEEK 2361-2: POKE 23613,W 2 POKE 23609,20: POKE 23658,0 3 CLS : BORDER 1: PAPER 5: INK 1 4 PRINT AT 3,6; FLASH 1; PAPER 1; INK 7;"PROGRAM CALENDAR";AT 6,4; PAPER 2; INK 6;"BY: EMMETT L. JENKINS" ;AT 9,10; PAPER 2; INK 7;"Sept. 1985": PAUSE 290: CLS 5 CLS : GO SUB 1000 7 LET u=1: LET i=1: LET x=4: LET v=28: LET z=0: LET b=0 9 CLS 10 DIM m$(12,9) 12 FOR n=1 TO 12 13 READ m$(n) 14 NEXT n 15 DATA "JANUARY","FEBRUARY"," MARCH"," APRIL"," MAY"," JUNE"," JULY"," AUGUST","SEPTEMBER","OCTOBER","NOVEMBER","DECEMBER" 30 LET a$="1440250361462" 35 INPUT "Enter YEAR (19--):";y$: IF VAL y$<0 OR VAL y$>99 THEN GO TO 35 36 LET y=VAL y$ 37 PRINT "Year-- ";y 38 IF LEN y$<2 THEN LET y$="0": GO TO 40 39 LET y$="" 40 INPUT "Enter Month (1-12):";m: IF m<1 OR m>12 THEN GO TO 40 45 PRINT "month- ";m;" - ";m$(m) 50 PRINT '';"ENTER (y) to get copy of year ENTER (m) to get copy of month ENTER (d) to get display only" 52 INPUT "Enter ""y"",""m"",""d""";i$: IF i$<>"y" AND i$<>"m" AND i$<>"d" THEN GO TO 52 53 PRINT i$: PAUSE 40: CLS 60 GO TO 600 65 PRINT ">>>>>>>>>>>>> 19";y$;y;" <<<<<<<<<<<<<" 80 IF i$="y" THEN FOR m=1 TO 12 100 LET a=x*y+y+x*VAL a$(m) 110 LET w=u+INT ((a-v*INT (a/v))/x) 115 PRINT ' 120 PRINT TAB 12;m$(m) 122 PRINT " ****************************" 123 PRINT 124 PRINT TAB 5;"SU MO TU WE TH FR SA" 126 PRINT 130 PRINT TAB (w*x-w-x+u)+5;i; 140 LET i=i+1 150 LET w=w+1 155 IF w=8 THEN PRINT : PRINT 160 IF w=8 THEN LET w=1 170 IF a$(m+u)"d" THEN LPRINT : LPRINT : LPRINT ">>>>>>>>>>>>> 19";y$;y;" <<<<<<<<<<<<<": LPRINT : GO TO 70 605 GO TO 64 1000 CLS 1010 PRINT "To print the following press:" 1015 PRINT : PRINT 1040 PRINT "L--- To Lprint" 1045 PRINT "C--- ""THIS CALENDAR IS FOR:""" 1050 PRINT "M--- ""MONTH of BIRTH""" 1060 PRINT "Y--- ""YEAR of BIRTH""" 1070 PRINT "N--- If you don't want to Lprint" 1110 IF INKEY$="j" THEN GO TO 3000 1120 IF INKEY$="m" THEN GO TO 4000 1130 IF INKEY$="y" THEN GO TO 5000 1140 IF INKEY$="l" THEN GO TO 6000 1150 IF INKEY$="n" THEN GO TO 7000 1155 IF INKEY$="f" THEN GO TO 8000 1157 IF INKEY$="c" THEN GO TO 8500 1160 GO TO 1100 4000 LPRINT : LPRINT " MONTH of BIRTH": LPRINT : GO TO 1100 5000 LPRINT : LPRINT " YEAR of BIRTH": LPRINT : GO TO 1100 6000 CLS : PRINT : PRINT : PRINT "Do you want the Lprint CENTERED?" 6010 IF INKEY$="y" THEN GO TO 6100 6020 IF INKEY$="n" THEN GO TO 6300 6030 GO TO 6010 6100 PRINT : PRINT "Enter up to 32 characters." 6110 INPUT z$: IF LEN z$>32 THEN GO TO 6110 6150 LET l=(32-LEN z$)/2 6160 LPRINT TAB INT l;z$ 6170 GO TO 1000 6300 PRINT : PRINT "Enter up to 32 characters." 6310 INPUT z$: IF LEN z$>32 THEN GO TO 6310 6350 LPRINT z$ 6360 GO TO 1000 7000 RETURN 8005 LPRINT : LPRINT : GO TO 1000 8500 LPRINT : LPRINT " THIS CALENDAR IS FOR:" 8510 LPRINT : GO TO 1000 9998 RANDOMIZE USR 100: SAVE "cale40.B2" LINE 1 ```