ZCALC

Date: 198x
Type: Cassette
Platform(s): TS 1000

This program implements a spreadsheet application called “Z CALC”, supporting a grid of named columns and rows with numeric data entry, scrolling display, formula-based cell computation, named constants, and column/row totalling. The main data store is a single large two-dimensional string array A$(22,149), which packs cell values, row labels, and column headers into fixed-width fields within its columns. Formula evaluation at lines 6700–7210 supports four arithmetic operators and an assignment operator, with operands drawn either from other cells or from a 24-element constant bank stored in W$(120). A custom title-screen routine (lines 9550–9680) manually renders bitmap characters from the ROM font by PEEKing character data at address 7680, printing block graphics pixel by pixel. Division by zero is silently handled by substituting 0.01 for a zero divisor.


Program Structure

The program is organised as a menu-driven application entered at line 500 after the title screen at 9550. A numeric menu at line 565 dispatches to one of seven functional modules at fixed line-number offsets computed by 700+((Q-1)*1000):

QModule startFunction
1700Data input (columns, rows, values)
21700Change a single cell value
32700Change column/row function strings
43700Edit named constants
54700Column total and average
65700Row total and average
76700Formula recalculation (ANS)

Shared subroutines occupy lines 1082: GOSUB 10 waits 200 frames, GOSUB 12 clears the status line, GOSUB 16 computes the column byte-range into X and U, and GOSUB 22 prints the column-header labels. The scroll/view routine beginning at line 28 is used by the change-cell module via GOSUB 46 (branching into the middle of the subroutine block).

Data Layout in A$

All spreadsheet data lives in one array DIM A$(22,149) declared at line 702. The layout within each row of A$ is:

  • Row 1: column names, stored in 7-character fields starting at positions (H*7)-6 for column H (columns 1–3, positions 1–21).
  • Row 2: column function strings, same positional encoding.
  • Rows 3–22: data rows. Positions 1–(H1*7) hold numeric cell values in 7-character fields. Positions 141–144 hold a 4-character row name; positions 145–149 hold a 5-character row function string.

The column index formula X=(H*7)-6, U=X+6 (lines 1620) consistently maps a 1-based column number to its byte slice in A$. This same offset I=(H*7)-6 is recomputed inline at line 997 without calling the subroutine, a minor inconsistency.

Scrolling Display

The scrolling view (lines 2882) shows up to three columns side by side in screen positions K=11,18,25 (controlled by FOR K=11 TO 25 STEP 7). Horizontal position is tracked by H (column index) and vertical by V (row index). Navigation keys are numeric: 5=left, 8=right, 7=up, 6=down, 0=exit. The wrapping logic uses a compact idiom:

  • LET H=-(H1=H)+H+1 — increments H and wraps to 1 when H equals H1.
  • LET H=H-1+(H=1) — decrements H and wraps to H1 when H is 1.
  • Similar logic applies to V with boundary at 4 (minimum) and V1 (maximum).

Formula Evaluation Engine

The recalculation module (lines 67007210) performs two passes: first across columns (lines 67006950), then across rows (lines 69607210). Each pass reads a 6-character function string. The first character is the operator (+, -, *, /, or =). The second character identifies the operand source: a column letter or W for a named constant. If = and there is a second operand (position 3 is not a space), a pointer K1 is advanced by 2 and the lookup is repeated, allowing a two-operand chain.

Results are stored back into A$(V,K TO K+6) as strings via STR$, with rounding to one decimal place using the idiom INT(value*10)/10. Division by zero substitutes 0.01 for the divisor (line 6830), silently corrupting results rather than reporting an error.

A column function starting with £ (line 6710) and a row function starting with £ (line 6980) cause that column or row to be skipped entirely during recalculation, serving as a “no formula” sentinel.

Named Constants

Up to 24 named constants are stored in DIM W$(120), each occupying 5 characters at position (Z*5)-4. They are labelled WAWX (using CHR$(37+Z) for the suffix letter). The constant-entry screen at lines 10671125 and the edit screen at 37003870 both display 12 constants per column. Referencing a constant in a formula uses the character W as a flag, with the following character decoded via CODE(...)-37 to obtain the index.

Title Screen Bitmap Renderer

Lines 95509680 contain a hand-written ROM-font renderer. The string X$="CAL" is rendered as large characters by reading each character’s 8×8 bitmap from the ROM character table at base address 7680 using PEEK(7680+C*8+H). Each bit is extracted by repeated halving of a bitmask (V=128 down to 1), printing a block graphic for set bits and a space for clear bits. The three characters are placed at screen columns 5, 12, and 19 (via FOR L=5 TO 19 STEP 7), producing oversized pixel-art lettering.

Key BASIC Idioms

  • Boolean arithmetic for wrapping: -(H1=H) evaluates to -1 when true, effectively adding 1 after subtraction.
  • Computed GOTO: GOTO 700+((Q-1)*1000) dispatches to modules without a chain of IF statements.
  • Fixed-width string fields within a single array row substitute for a two-dimensional numeric array, conserving memory at the cost of needing VAL and STR$ conversions.
  • Character encoding: column letters are stored and decoded via CHR$(H+37) / CODE(...)-37, mapping A=1, B=2, etc. Row letters similarly use offset 35.

Content

Appears On

Related Products

Related Articles

Related Content

Image Gallery

ZCALC

Source Code

  10 PAUSE 200
  12 PRINT AT 0,0;"                                "
  14 RETURN 
  16 LET X=(H*7)-6
  18 LET U=X+6
  20 RETURN 
  22 PRINT AT 2,6;"NAME"
  24 PRINT AT 3,0;"  NAME%F%U%N%C="
  26 RETURN 
  28 GOSUB 12
  30 PRINT AT 0,0;"SCROLL:U=7,D=6,R=8,L=5,NONE=0"
  32 INPUT Q
  34 GOSUB 12
  36 IF Q=0 THEN RETURN 
  38 IF Q=5 THEN LET H=-(H1=H)+H+1
  40 IF Q=8 THEN LET H=H-1+(H=1)
  42 IF Q=7 THEN LET V=V+1-(V>V1)
  44 IF Q=6 THEN LET V=V-1+(V<4)
  46 LET H2=H
  47 FOR K=11 TO 25 STEP 7
  48 IF H>H1 THEN GOTO 76
  50 GOSUB 16
  52 PRINT AT 1,K+3;CHR$ (H+37)
  54 PRINT AT 2,K;A$(1,X TO U)
  56 PRINT AT 3,K;A$(2,X TO U)
  57 LET V2=V
  58 FOR J=4 TO 18
  60 IF V>V1 THEN GOTO 73
  61 PRINT AT J,0;CHR$ (V+35);".";A$(V,141 TO 149)
  62 PRINT AT J,K;A$(V,X TO U)
  64 LET V=V+1
  66 NEXT J
  68 LET H=H+1
  69 LET V=V2
  70 NEXT K
  71 LET H=H2
  72 GOTO 30
  73 PRINT AT J,0;"                              "
  74 GOTO 68
  76 FOR J=1 TO 18
  78 PRINT AT J,K;"       "
  80 NEXT J
  82 GOTO 71
 500 PRINT AT 10,0;" %C%A%U%T%I%O%N: REFER TO INSTRUCTIONS     FOR RULES AND PROCEDURES"
 510 PAUSE 200
 520 CLS 
 565 PRINT AT 0,0;"1=IN,2=C,3=F,4=W,5=TC,6=TR,7=ANS" 
 580 INPUT Q
 590 IF Q<1 OR Q>7 THEN GOTO 570
 600 GOSUB 12
 610 GOTO 700+((Q-1)*1000)
 700 LET Q1=0
 701 CLS 
 702 DIM A$(22,149)
 705 LET H=1
 710 GOSUB 22
 715 FOR K=11 TO 25 STEP 7
 716 DIM X$(6)
 717 PRINT AT 0,0;"INPUT COLUMN NAME;*=END"
 720 PRINT AT 1,K+3;CHR$ (H+37)
 725 PRINT AT 2,K;"%       "
 727 PRINT AT 3,K;"       "
 730 INPUT X$
 732 GOSUB 12
 735 IF X$(1)="*" THEN GOTO 805
 740 GOSUB 16
 745 LET A$(1,X TO U)=X$(1 TO 6)
 750 PRINT AT 2,K;A$(1,X TO U)
 765 PRINT AT 0,0;"INPUT COLUMN FUNCTION"
 767 PRINT AT 3,K;"%     "
 770 INPUT A$(2,X TO U)
 775 GOSUB 12
 785 LET H=H+1
 790 PRINT AT 3,K;A$(2,X TO U)
 792 LET V=1
 795 NEXT K
 800 GOTO 715
 805 LET H1=H-1
 810 LET H=1
 820 LET V=3
 825 LET L=18
 830 FOR K=4 TO L
 835 PRINT AT 0,0;"INPUT ROW NAME;*=END"
 837 PRINT AT K,0;CHR$ (V+35);"."
 840 PRINT AT K,2;"%    "
 845 INPUT X$
 850 GOSUB 12
 855 IF X$(1)="*" THEN GOTO 920
 860 LET A$(V,141 TO 144)=X$(1 TO 4)
 865 PRINT AT K,2;A$(V,141 TO 144)
 870 PRINT AT 0,0;"INPUT ROW FUNCTION"
 875 PRINT AT K,6;"%     "
 880 INPUT A$(V,145 TO 149)
 885 GOSUB 12
 890 PRINT AT K,6;A$(V,145 TO 149)
 895 LET V=V+1
 900 NEXT K
 905 IF L=8 THEN GOTO 820
 910 LET L=8
 915 GOTO 830
 920 LET V1=V-1
 925 LET H=1
 930 LET V=3
 935 PRINT AT 0,0;"INPUT VALUES"
 940 FOR K=11 TO 25 STEP 7
 945 IF H>H1 THEN GOTO 1065
 950 GOSUB 16
 952 PRINT AT 1,K+3;CHR$ (H+37)
 955 PRINT AT 2,K;A$(1,X TO U)
 957 PRINT AT 3,K;A$(2,X TO U)
 960 FOR J=4 TO 18
 965 PRINT AT J,K;"       "
 970 NEXT J
 980 LET L=18
 985 FOR J=4 TO L
 986 IF V>V1 THEN GOTO 1045
 995 PRINT AT J,0;CHR$ (V+35);".";A$(V,141 TO 149)
 997 LET I=(H*7)-6
 998 IF A$(V,145)="=" OR A$(2,X)="=" THEN GOTO 1130
\n1000 PRINT AT J,K;"%       "
\n1010 INPUT A$(V,I TO I+6)
\n1015 PRINT AT J,K;A$(V,I TO I+6)
\n1020 LET V=V+1
\n1025 NEXT J
\n1030 IF V1<16 OR L=8 THEN GOTO 1045
\n1035 LET L=8
\n1040 GOTO 985
\n1045 LET H=H+1
\n1050 LET V=3
\n1055 NEXT K
\n1060 GOTO 940
\n1065 GOSUB 12
\n1067 PRINT AT 0,0;"INPUT CONSTANTS"
\n1070 LET Z=1
\n1075 DIM W$(120)
\n1080 FOR K=0 TO 24 STEP 8
\n1085 FOR J=19 TO 21
\n1090 PRINT AT J,K;"W";CHR$ (37+Z);"=";
\n1095 LET W1=(5*Z)-4
\n1100 INPUT X$
\n1105 IF X$(1)="*" THEN GOTO 565
\n1107 LET W$(W1 TO W1+4)=X$(1 TO 4)
\n1110 LET Z=Z+1
\n1112 PRINT W$(W1 TO W1+4)
\n1115 NEXT J
\n1120 NEXT K
\n1125 GOTO 565
\n1130 LET A$(V,I)="0"
\n1135 GOTO 1015
\n1700 LET H=1
\n1710 LET V=3
\n1720 PRINT AT 0,0;"MOVE CELL TO 1ST COL £ ROW"
\n1725 GOSUB 10
\n1730 GOSUB 46
\n1740 GOSUB 12
\n1750 PRINT AT 0,0;"INPUT NEW VALUE"
\n1760 GOSUB 16
\n1770 INPUT A$(V,X TO U)
\n1780 PRINT AT 4,11;A$(V,X TO U)
\n1790 PRINT AT 0,0;"ANOTHER CHANGE Y OR N"
\n1800 INPUT X$
\n1810 IF X$(1)="Y" THEN GOTO 1730
\n1820 GOTO 565
\n2700 CLS 
\n2705 FOR H=1 TO H1
\n2710 GOSUB 16
\n2720 PRINT AT H,0;CHR$ (H+37);".";A$(1,X TO U);" ";A$(2,X TO U)
\n2730 NEXT H
\n2740 PRINT AT 0,0;"INPUT COLUMN LETTER,*=FINISHED"
\n2750 INPUT X$
\n2760 IF X$(1)="*" THEN GOTO 2860
\n2770 LET H=(CODE X$)-37
\n2780 PRINT AT H,10;"%     "
\n2800 GOSUB 12
\n2810 PRINT AT 0,0;"INPUT VALUE"
\n2820 GOSUB 16
\n2830 INPUT A$(2,X TO U)
\n2835 GOSUB 12
\n2840 PRINT AT H,10;A$(2,X TO U)
\n2850 GOTO 2740
\n2860 CLS 
\n2870 FOR V=3 TO V1
\n2880 PRINT AT V-2,0;CHR$ (V+35);".";A$(V,141 TO 149)
\n2900 NEXT V
\n2910 PRINT AT 0,0;"INPUT ROW LETTER,*=FINISHED"
\n2920 INPUT X$
\n2930 IF X$(1)<>"*" THEN GOTO 2955
\n2940 CLS 
\n2950 GOTO 565
\n2955 LET V=CODE X$(1)-37
\n2960 PRINT AT V,6;"%     "
\n2970 GOSUB 12
\n2980 PRINT AT 0,0;"INPUT VALUE"
\n2990 INPUT A$(V+2,145 TO 149)
\n3000 PRINT AT V,6;A$(V+2,145 TO 149)
\n3010 GOTO 2910
\n3700 CLS 
\n3710 FOR K=1 TO 12
\n3720 PRINT AT K,0;"W";CHR$ (37+K);"=";W$((K*5)-4 TO K*5)
\n3730 PRINT AT K,15;"W";CHR$ (49+K);"=";W$(((K+12)*5)-4 TO (K+12)*5)
\n3740 NEXT K
\n3750 PRINT AT 0,0;"INPUT CONSTANT"
\n3770 INPUT X$
\n3775 GOSUB 12
\n3780 LET Z=CODE X$(2)-37
\n3790 PRINT AT Z-(12*(Z>12)),3+(15*(Z>12));"%        "
\n3800 PRINT AT 0,0;"INPUT VALUE"
\n3810 INPUT X$
\n3820 IF X$(1)="*" THEN GOTO 565
\n3830 GOSUB 12
\n3840 LET W1=(Z*5)-4
\n3850 LET W$(W1 TO W1+4)=X$
\n3860 PRINT AT Z-(12*(Z>12)),3+(15*(Z>12));W$(W1 TO W1+4)
\n3870 GOTO 3750
\n4700 CLS 
\n4710 PRINT AT 0,0;"INPUT COLUMN LETTER=";
\n4720 INPUT X$
\n4730 PRINT X$
\n4740 LET H=CODE X$(1)-37
\n4750 GOSUB 16
\n4760 PRINT AT 2,0;"COLUMN NAME=";A$(1,X TO U)
\n4765 LET Z=0
\n4770 FOR V=3 TO V1
\n4775 IF A$(V,X)=" " THEN GOTO 4790
\n4780 LET Z=Z+VAL A$(V,X TO U)
\n4790 NEXT V
\n4800 PRINT AT 4,0;"COLUMN TOTAL=";Z
\n4820 PRINT AT 6,0;"COLUMN AVERAGE=";(INT ((Z*100)/(V1-2)))/100
\n4830 PRINT AT 8,0;"ANOTHER COLUMN TOTAL Y OR N"
\n4840 INPUT X$
\n4850 IF X$(1)="N" THEN GOTO 520
\n4860 CLS 
\n4870 GOTO 4700
\n5700 CLS 
\n5710 PRINT AT 0,0;"INPUT ROW LETTER=";
\n5720 INPUT X$
\n5730 PRINT X$
\n5740 LET V=CODE X$(1)-35
\n5760 PRINT AT 2,0;"ROW NAME=";A$(V,141 TO 144)
\n5765 LET Z=0
\n5770 FOR H=1 TO H1
\n5775 GOSUB 16
\n5777 IF A$(V,X)=" " THEN GOTO 5790
\n5780 LET Z=Z+VAL A$(V,X TO U)
\n5790 NEXT H
\n5800 PRINT AT 4,0;"ROW TOTAL=";Z
\n5820 PRINT AT 6,0;"ROW AVERAGE=";(INT ((Z*100)/H1))/100
\n5830 PRINT AT 8,0;"ANOTHER ROW TOTAL Y OR N"
\n5840 INPUT X$
\n5850 IF X$(1)="N" THEN GOTO 520
\n5860 CLS 
\n5870 GOTO 5700
\n6700 FOR K=1 TO (H1*7)-6 STEP 7
\n6710 IF A$(2,K)="£" THEN GOTO 6950
\n6720 FOR V=3 TO V1
\n6722 LET K1=K
\n6730 IF A$(2,K1+1)="W" THEN GOTO 6770
\n6740 LET H=CODE (A$(2,K1+1))-37
\n6745 GOSUB 16
\n6750 LET X=VAL A$(V,X TO U)
\n6760 GOTO 6800
\n6770 LET Z=CODE (A$(2,K1+2))-37
\n6780 LET Z=(Z*5)-4
\n6790 LET X=VAL W$(Z TO Z+4)
\n6800 IF A$(2,K1)="+" THEN LET A$(V,K TO K+6)=STR$ ((INT (((VAL A$(V,K TO K+6))+X)*10))/10)
\n6810 IF A$(2,K1)="-" THEN LET A$(V,K TO K+6)=STR$ ((INT (((VAL A$(V,K TO K+6))-X)*10))/10)
\n6820 IF A$(2,K1)="*" THEN LET A$(V,K TO K+6)=STR$ ((INT (((VAL A$(V,K TO K+6))*X)*10))/10)
\n6830 IF A$(2,K1)="/" AND X=0 THEN LET X=.01
\n6850 IF A$(2,K1)="/" THEN LET A$(V,K TO K+6)=STR$ ((INT (((VAL A$(V,K TO K+6))*X)/10))/10)
\n6870 IF A$(2,K1)<>"=" THEN GOTO 6940
\n6890 LET A$(V,K TO K+6)=STR$ X
\n6910 IF A$(2,K1+1)="W" OR A$(2,K1+2)=" " THEN GOTO 6940
\n6920 LET K1=K+2
\n6930 GOTO 6730
\n6940 NEXT V
\n6950 NEXT K
\n6960 FOR V=3 TO V1
\n6980 IF A$(V,145)="£" THEN GOTO 7210
\n6990 FOR H=1 TO (H1*7)-6 STEP 7
\n6995 LET K1=145
\n7010 IF A$(V,K1+1)="W" THEN GOTO 7050
\n7020 LET Z=CODE A$(V,K1+1)-35
\n7030 LET X=VAL (A$(Z,H TO H+6))
\n7040 GOTO 7080
\n7050 LET Z=CODE A$(V,K1+2)-37
\n7060 LET Z=(Z*5)-4
\n7070 LET X=VAL W$(Z TO Z+4)
\n7080 IF A$(V,K1)="+" THEN LET A$(V,H TO H+6)=STR$ ((INT (((VAL A$(V,H TO H+6))+X)*10))/10)
\n7090 IF A$(V,K1)="-" THEN LET A$(V,H TO H+6)=STR$ ((INT (((VAL A$(V,H TO H+6))-X)*10))/10)
\n7100 IF A$(V,K1)="*" THEN LET A$(V,H TO H+6)=STR$ ((INT (((VAL A$(V,H TO H+6))*X)*10))/10)
\n7110 IF A$(V,K1)="/" AND X=0 THEN LET X=.01
\n7120 IF A$(V,K1)="/" THEN LET A$(V,H TO H+6)=STR$ ((INT (((VAL A$(V,H TO H+6))/X)*10))/10)
\n7130 IF A$(V,K1)<>"=" THEN GOTO 7200
\n7150 LET A$(V,H TO H+6)=STR$ X
\n7160 IF A$(V,K1+1)="W" OR A$(V,K1+2)=" " THEN GOTO 7200
\n7180 LET K1=147
\n7190 GOTO 7010
\n7200 NEXT H
\n7210 NEXT V
\n7710 LET H=1
\n7720 LET V=3
\n7730 GOSUB 46
\n7740 GOTO 565
\n9550 SAVE "CA%L"
\n9555 LET X$="CAL"
\n9560 FAST 
\n9565 LET N=0
\n9570 FOR L=5 TO 19 STEP 7
\n9575 LET N=N+1
\n9580 LET C=CODE X$(N)
\n9585 FOR H=0 TO 7
\n9590 LET P=PEEK (7680+C*8+H)
\n9595 LET V=128
\n9600 FOR G=0 TO 7
\n9605 IF P<V THEN GOTO 9625
\n9610 PRINT AT H+3,G+L;"% "
\n9615 LET P=P-V
\n9620 GOTO 9630
\n9625 PRINT AT H+3,G+L;"\@@"
\n9630 LET V=V/2
\n9635 NEXT G
\n9640 NEXT H
\n9645 NEXT L
\n9650 PRINT "      Z CALC COPYRIGHT UAS"
\n9655 PRINT "BOX 612 HADDONFIELD,N.J. 08033"
\n9660 PAUSE 200
\n9670 CLS 
\n9680 GOTO 500

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

People

No people associated with this content.

Scroll to Top