This program implements an income tax return assistant that handles data entry, tax calculation, data review, and tape storage for US tax forms 1040 and Schedule A. It uses a 107-element numeric array L() to store line-item amounts and a parallel 107-element string array C$() of 18-character descriptions for each tax line. Navigation is driven by a two-level menu system: a main menu with five options and a sub-menu for selecting between Form 1040 and Schedule A, with GOSUB dispatch performed via VAL K$*1000 and VAL K$*100+2000 arithmetic on the keypress. Initialization at line 9000 prompts the user to enter all 107 line descriptions interactively in FAST mode before use, with the instruction at line 51 directing users to GO TO 9000 first. The SAVE at line 4050 preserves the entire program and its data arrays to tape under the name “TAX”.
Program Analysis
Program Structure
The program is organized into clearly delineated routines, each prefixed by an inverse-video REM label. The main loop runs from lines 100–200, presenting a five-option menu and dispatching to one of five subroutines. A second-level dispatcher at line 7000 handles form selection (1040 or Schedule A). The overall flow is:
- Lines 51–52: Bootstrap message and STOP — user must first run line 9000.
- Lines 100–200: Main menu loop.
- Lines 1000–1120: Option 1 — Enter Data.
- Lines 2000–2248: Option 2 — Calculate Tax (Form 1040 at 2100, Schedule A at 2200).
- Lines 3000–3080: Option 3 — Review Data.
- Lines 4000–4060: Option 4 — Record Data (SAVE to tape).
- Lines 5000–5030: Option 5 — Erase All Entries.
- Lines 6000–6030: Shared pause/continue subroutine.
- Lines 7000–7214: Form selection subroutine and form setup routines.
- Lines 9000–9090: Initialization — dimensions arrays and prompts for 107 line descriptions.
Menu Dispatch via Arithmetic on INKEY$
The program uses a compact but powerful idiom for computed GOSUB dispatch. At line 180, GOSUB VAL K$*1000 converts the character “1”–”5″ to the integer 1000–5000, jumping directly to the correct routine. Similarly, GOSUB VAL K$*100+2000 at line 2020 and GOSUB VAL K$*100+7000 at line 7090 select sub-forms. This eliminates a chain of IF/THEN statements and is a recognized memory and speed optimization in Sinclair BASIC.
Data Model
Two parallel arrays form the core data structure:
L(107)— numeric array holding the dollar amount for each of 107 tax line items.C$(107,18)— string array holding an 18-character description for each line item, entered by the user at initialization time.
A offset variable Z is used to map logical line numbers (as entered by the user) to physical array indices. For Form 1040, Z=0; for Schedule A, Z=66, allowing Schedule A entries 1–41 to occupy L(67)–L(107).
Form Setup Routines
Lines 7100–7130 (Form 1040) and 7200–7214 (Schedule A) configure four variables used by the Review Data and Enter Data routines:
| Variable | Purpose |
|---|---|
Z | Array offset (0 for 1040, 66 for Schedule A) |
P | Number of sections to display in review |
J(N) | Start line number for section N |
K(N) | End line number for section N |
This gives the Review Data routine (lines 3000–3080) a generic paginated display loop that works for both forms without hardcoded ranges.
Tax Calculation Logic
The Form 1040 calculation (lines 2100–2182) manually replicates the aggregation rules of the actual IRS Form 1040, using FOR loops to sum ranges of L()L(21), L(30), L(31)). A rounding idiom appears at line 2160: INT(100*X+.5)/10 — note this divides by 10 rather than 100, which appears to be an intentional scaling (perhaps converting cents to a percentage or applying a rate), though it could also be a bug depending on intended semantics. The refund/amount-owed logic at lines 2156–2172 correctly handles negative results by branching and zeroing out the opposing field.
Initialization and FAST Mode
Line 9000 begins the initialization sequence, which must be run manually via GO TO 9000. It dimensions all four arrays, then enters FAST mode (line 9012) before looping through all 107 entries to accept user-typed descriptions via INPUT C$(I). FAST mode suppresses the display interrupt, greatly accelerating the input loop. After completion, SLOW is restored at line 9055 and execution falls through to the main menu. Lines 9070–9090 (CLEAR, SAVE, LIST) appear to be a development artifact for saving the initialized program state; CLEAR before SAVE would erase variables, so these lines are presumably not reached in normal operation.
Notable Techniques and Idioms
- The
PAUSE 40000/INKEY$pattern is used throughout as a keypress wait at lines 155, 160, 4030, 7032, and 7034. STR$ Iat line 3025 converts the line number to a string for display, avoiding a separatePRINTof a numeric variable.- The
SAVE "TAX"at line 4050 saves the entire program including current variable state, providing a simple data persistence mechanism without any file format overhead. - Inverse-video REM labels (e.g.,
%E%N%T%E%R% %D%A%T%A) serve as section markers that are visually distinct in the listing.
Anomalies and Potential Issues
- Line 5030 prints “ALL ENTRIES ERASED” but does not return or GOTO anywhere — it falls through to line 5999 (a REM), then to line 6000. This accidentally calls the pause/continue routine after erasing, which may or may not be intentional.
- The rounding expression at line 2160,
INT(100*X+.5)/10, divides by 10 instead of 100. If the intent was to round to the nearest cent, the divisor should be 100. As written, it multiplies by 10 instead of rounding to two decimal places. DIM I$(3)at line 9010 dimensions a string array of three 1-character elements, but the program usesI$as a simple string variable (e.g.,LET I$=STR$ Iat line 3025). In Sinclair BASIC, once a variable is dimensioned as an array, the simple variable of the same name is inaccessible; this would cause an error at line 3025 unlessI$was intended to beI$(N).- Line 9080 saves the file as
"1030%5"where%5is inverse “5”. This appears to be a development save with a specific filename.
Content
Source Code
51 PRINT "USE GOTO 9000,TO FILL IN LINES"
52 STOP
100 PRINT AT 3,6;"INCOME TAX RETURN"
110 PRINT AT 6,4;"PRESS DESIRED FUNCTION"
120 PRINT AT 8,6;"1. ENTER DATA"
130 PRINT AT 9,6;"2. CALCULATE TAX"
140 PRINT AT 10,6;"3. REVIEW DATA"
150 PRINT AT 11,6;"4. RECORD DATA"
152 PRINT AT 12,6;"5. ERASE ALL ENTRIES"
155 PAUSE 40000
160 LET K$=INKEY$
170 IF K$<"1" OR K$>"5" THEN GOTO 100
180 GOSUB VAL K$*1000
200 GOTO 100
999 REM %E%N%T%E%R% %D%A%T%A
\n1000 GOSUB 7000
\n1010 PRINT AT 6,8;"LINE NUMBER"
\n1020 INPUT Y
\n1030 PRINT AT 6,20;Y
\n1040 LET X=Y+Z
\n1050 PRINT AT 8,8;"AMOUNT $"
\n1060 INPUT A
\n1070 PRINT AT 8,16;A
\n1080 LET L(X)=L(X)+A
\n1090 PRINT AT 10,8;"TOTAL $";L(X)
\n1100 GOSUB 6000
\n1120 RETURN
\n1999 REM %C%A%L%C%U%L%A%T%E% %T%A%X
\n2000 GOSUB 7000
\n2020 GOSUB VAL K$*100+2000
\n2030 RETURN
\n2099 REM %F%O%R%M% %1%0%4%0
\n2100 LET L(21)=0
\n2102 FOR I=7 TO 20
\n2104 LET L(21)=L(21)+L(I)
\n2106 NEXT I
\n2108 LET L(30)=0
\n2110 FOR I=22 TO 29
\n2112 LET L(30)=L(30)+L(I)
\n2114 NEXT I
\n2116 LET L(31)=L(21)-L(30)
\n2117 LET L(32)=L(107)
\n2118 LET L(34)=L(31)-L(32)-L(33)
\n2120 PRINT AT 21,0;"ENTER TAX FOR $";L(34)
\n2122 INPUT L(35)
\n2124 PRINT AT 21,0;"ENTER ADDITIONAL TAXES"
\n2126 INPUT L(36)
\n2128 LET L(37)=L(35)+L(36)
\n2130 LET L(46)=0
\n2132 FOR I=38 TO 45
\n2134 LET L(46)=L(46)+L(I)
\n2136 NEXT I
\n2138 LET L(47)=L(37)-L(46)
\n2140 LET L(54)=0
\n2142 FOR I=47 TO 53
\n2144 LET L(54)=L(54)+L(I)
\n2146 NEXT I
\n2148 LET L(62)=0
\n2150 FOR I=55 TO 61
\n2152 LET L(62)=L(62)+L(I)
\n2154 NEXT I
\n2156 LET X=L(62)-L(54)
\n2158 IF X<0 THEN GOTO 2166
\n2160 LET L(63)=INT (100*X+.5)/10
\n2162 LET L(64)=L(63)-L(65)
\n2164 GOTO 2174
\n2166 LET L(63)=0
\n2168 LET L(64)=0
\n2170 LET L(65)=0
\n2172 LET L(66)=X*-1
\n2174 FOR I=63 TO 66
\n2176 PRINT AT I-53,0;I;" ";C$(I);" $";L(I)
\n2178 NEXT I
\n2180 GOSUB 6000
\n2182 RETURN
\n2199 REM %S%C%H%E%D%U%L%E% %A
\n2200 LET L(69)=INT (L(31)+.5)/100
\n2201 LET L(70)=L(68)-L(69)
\n2202 IF L(69)>L(68) THEN LET L(70)=0
\n2204 LET L(73)=L(70)+L(71)+L(72)
\n2206 LET L(74)=3*L(69)
\n2208 LET L(75)=L(73)-L(74)
\n2210 IF L(74)>L(73) THEN LET L(75)=0
\n2212 LET L(76)=L(67)+L(75)
\n2214 LET L(82)=L(77)+L(78)+L(79)+L(80)+L(81)
\n2216 LET L(86)=L(83)+L(84)+L(85)
\n2218 LET L(90)=L(87)+L(88)+L(89)
\n2220 LET L(95)=L(91)+L(92)+L(93)+L(94)
\n2222 LET L(98)=L(96)+L(97)
\n2224 LET L(99)=L(76)
\n2226 LET L(100)=L(82)
\n2228 LET L(101)=L(86)
\n2230 LET L(102)=L(90)
\n2232 LET L(103)=L(95)
\n2234 LET L(104)=L(98)
\n2236 LET L(105)=L(99)+L(100)+L(101)+L(102)+L(103)+L(104)
\n2238 LET L(107)=L(105)-L(106)
\n2240 IF L(106)>L(105) THEN LET L(107)=0
\n2242 PRINT AT 15,0;"41 ";C$(107);" $";L(107)
\n2244 GOSUB 6000
\n2248 RETURN
\n2999 REM %R%E%V%I%E%W% %D%A%T%A
\n3000 GOSUB 7000
\n3010 FOR N=1 TO P
\n3020 FOR I=J(N) TO K(N)
\n3025 LET I$=STR$ I
\n3030 PRINT I$;" ";C$(I+Z);" $";L(I+Z)
\n3040 NEXT I
\n3050 GOSUB 6000
\n3070 NEXT N
\n3080 RETURN
\n3999 REM %R%E%C%O%R%D% %D%A%T%A
\n4000 CLS
\n4010 PRINT AT 6,7;"PREPARE RECORDER"
\n4020 PRINT AT 10,3;"PRESS ANY KEY WHEN READY"
\n4030 PAUSE 40000
\n4040 CLS
\n4050 SAVE "TAX"
\n4060 RETURN
\n4999 REM %E%R%A%S%E% %A%L%L% %E%N%T%R%I%E%S
\n5000 CLS
\n5005 FOR I=1 TO 107
\n5010 LET L(I)=0
\n5020 NEXT I
\n5030 PRINT AT 10,7;"ALL ENTRIES ERASED"
\n5999 REM %P%A%U%S%E
\n6000 PRINT AT 21,0;"PRESS ANY KEY TO CONTINUE"
\n6010 PAUSE 40000
\n6020 CLS
\n6030 RETURN
\n6999 REM %F%O%R%M% %S%E%L%E%C%T%I%O%N
\n7000 CLS
\n7010 PRINT AT 6,7;"PRESS DESIRED FORM"
\n7020 PRINT AT 8,9;"1. FORM 1040"
\n7030 PRINT AT 9,9;"2. SCHEDULE A"
\n7032 PAUSE 40000
\n7034 LET K$=INKEY$
\n7036 IF K$<"1" OR K$>"2" THEN GOTO 7000
\n7088 CLS
\n7090 GOSUB VAL K$*100+7000
\n7092 RETURN
\n7099 REM %F%O%R%M% %1%0%4%0
\n7100 PRINT AT 0,11;"FORM 1040"
\n7102 LET Z=0
\n7104 LET P=4
\n7106 LET J(1)=7
\n7108 LET J(2)=21
\n7110 LET J(3)=37
\n7112 LET J(4)=47
\n7114 LET K(1)=21
\n7116 LET K(2)=37
\n7118 LET K(3)=54
\n7120 LET K(4)=66
\n7130 RETURN
\n7199 REM %S%C%H%E%D%U%L%E% %A
\n7200 PRINT AT 0,11;"SCHEDULE A"
\n7202 LET Z=66
\n7204 LET P=2
\n7206 LET J(1)=1
\n7208 LET J(2)=21
\n7210 LET K(1)=20
\n7212 LET K(2)=41
\n7214 RETURN
\n8999 REM %I%N%I%T%I%A%L%I%Z%A%T%I%O%N
\n9000 LET J=1
\n9002 DIM J(4)
\n9004 DIM K(4)
\n9006 DIM C$(107,18)
\n9008 DIM L(107)
\n9010 DIM I$(3)
\n9012 FAST
\n9020 FOR I=J TO 107
\n9025 LET I$=STR$ I
\n9030 PRINT AT 21,0;I$;"****************"
\n9040 INPUT C$(I)
\n9050 NEXT I
\n9055 SLOW
\n9060 GOTO 100
\n9070 CLEAR
\n9080 SAVE "1030%5"
\n9090 LIST
Note: Type-in program listings on this website use ZMAKEBAS notation for graphics characters.
