Program Calendar

Developer(s): Emmett Jenkins
Date: 198x
Type: Program
Platform(s): TS 2068
Tags: 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.

Related Content

Image Gallery

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)<a$(m) THEN LET b=7
  180 IF i<=v+VAL a$(m+u)-VAL a$(m)+b THEN GO TO 130
  182 PRINT : PRINT 
  185 PRINT TAB 10;".'.'.'.'.''.'.'.'.'."
  186 PRINT TAB 9;"::**********::"
  187 PRINT TAB 10;"'.'.'.'.'..'.'.'.'.'"
  188 PLOT 0,0: DRAW 255,0: DRAW 0,175: DRAW -255,0: DRAW 0,-175
  190 LET i=u
  200 LET b=0
  205 IF i$="y" THEN GO TO 220
  210 IF i$="d" THEN GO TO 250
  220 COPY 
  225 IF i$="m" THEN GO TO 249
  230 CLS 
  240 NEXT m
  241 LPRINT : LPRINT : LPRINT : LPRINT 
  242 PRINT : PRINT TAB 3;"Another year or month?(Y/N)"
  245 IF INKEY$="y" THEN CLEAR : GO TO 5
  246 IF INKEY$="n" THEN STOP 
  247 GO TO 245
  249 LPRINT : LPRINT : LPRINT : LPRINT 
  250 PRINT AT 21,2;"Another year or month? (Y/N)"
  255 GO TO 245
  600 IF i$<>"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

Note: Type-in program listings on this website use ZMAKEBAS notation for graphics characters.