Tax Return Helper is an interactive BASIC application designed to guide users through completing U.S. tax return forms, loading form data from up to six separate tape files containing label, entry, property, rule, and numeric arrays. The program displays 20 form lines at a time on screen, allowing navigation forward and backward through form entries, with numeric values formatted right-aligned in a nine-character currency field. A built-in tax calculation routine uses bracket tables stored in arrays T(), M(), and S() to compute tax liability based on filing status (1–5) and taxable income, supporting all four standard filing categories. The program includes an undocumented debug/edit mode accessible via special keypress codes that allows direct modification of the internal form data arrays L$(), E$(), P$(), R$(), and N(). Calculated fields are propagated automatically through a chained update mechanism using a linked list encoded in the N() array, with negative values in N() indicating sign reversal during propagation.
Program Structure
The program is organized around a central control loop at line 120 that reads a keypress and dispatches via a computed GO TO at line 128: IF A >= 53 AND A <= 90 THEN GO TO (A+97). This maps ASCII key codes to line numbers in the 150–187 range, each of which immediately jumps to a functional subroutine area. The main functional blocks are:
- Lines 50–106: Initialization, tape loading, and title screen
- Lines 120–199: Key dispatch hub
- Lines 200–320: Navigation (move forward/backward through form lines)
- Lines 350–397: Numeric value entry
- Lines 400–470: Save current state to tape
- Lines 600–680: Reset all values to zero/defaults
- Lines 730–795: Print (LPRINT) or COPY form data
- Lines 800–915: Value update and chain propagation engine
- Lines 1300–1445: Display subroutines (screen update and full-page refresh)
- Lines 1500–1597: Search for a form line label
- Lines 1700–1740: Number formatting subroutine
- Lines 2000–2160: Tax calculation from bracket tables
- Lines 2200–2292: Debug/edit mode
- Lines 2300–2355: Dump all arrays to LPRINT or screen
- Lines 2400–3890: Specialized computed field subroutines
- Lines 4000–4450: Data entry and manipulation utilities for tax tables
Data Model
The form is represented as parallel arrays of length 160, all indexed by a single entry number:
| Array | Dimensions | Purpose |
|---|---|---|
L$(160,4) | 160 × 4 chars | Line label (e.g., “L37”) |
E$(160,17) | 160 × 17 chars | Entry description/prompt |
P$(160,1) | 160 × 1 char | Property flags: “N”=no numeric, “=”=calculated, “-“=can be negative |
R$(160,1) | 160 × 1 char | Rule flags: “?”=user-editable |
V(160) | 160 floats | Current numeric values |
N(160) | 160 integers | Propagation link: next field index, negative=negate, >IM=GO SUB target |
Tax bracket data is held in three arrays of length 65: T() (income thresholds), M() (base tax), and S() (marginal rate percent). Filing status selects a range of 16 or 17 bracket rows within these arrays.
Value Propagation Engine
The core of the program is the update loop at lines 800–915. When a user enters a numeric value NV for field I, the difference D = NV - V(I) is computed. The engine then walks a chain of fields defined by N(J):
- If
N(J)is a positive integer ≤IM(145), the deltaDis added toV(J)and propagation continues to fieldN(J). - If
N(J)is negative,Dis negated (sign flip) and propagation continues toABS N(J). - If
N(J) > IM, aGO SUB N(J)is executed, calling a specialized calculation subroutine. - The chain ends when
J = 0.
A secondary deferred jump is supported via the variables SJ and SD: a subroutine can set these to schedule a second propagation pass after the primary chain completes (used at lines 3230–3240 and 3465–3470).
Screen Management
The program displays a 20-line window onto the form array, governed by variables TP (top pointer), LS (last shown), J1, J2, and LRST (current line row). When the cursor moves past the top or bottom of the window, the subroutine at 1570 re-centers the window on the current entry and calls the full-page redraw at 1400. Individual field updates use the subroutine at 1300, which maps the array index to a screen row via LIN = J - TP.
Number Formatting
The subroutine at lines 1700–1740 formats a value right-aligned in a nine-character field N$. It converts V(J) to a string, locates the decimal point position K, and then places the string so that the units digit always falls at position 8. This ensures currency values line up on screen regardless of their magnitude.
Tax Calculation
The routine at lines 2000–2160 implements piecewise-linear tax bracket interpolation. After checking that filing status (V(3)) is set, it selects a 16- or 17-element slice of the T()/M()/S() arrays based on status values 1–5 (with statuses 2 and 5 sharing the same table). It then finds the applicable bracket with a FOR loop and computes: TX = M(K-1) + S(K-1) * (IN - T(K-1)) / 100. The result is fed back into the value propagation engine via GO SUB 800.
Key Dispatch Technique
The expression GO TO (A+97) at line 128 is a computed GO TO using the ASCII code of the pressed key. For example, pressing a key with code 53 jumps to line 150, code 54 to line 151, and so on up to code 90 → line 187. Most of these stub lines simply redirect to a functional block, acting as a jump table. Keys with codes outside 53–90 are handled by explicit checks for A=33, A=35, and A=64 (the debug, dump, and search commands).
Tape Loading
The program constructs filenames dynamically by appending digits 1–6 to the form name entered by the user (e.g., W$ = F$ + "1"). The six files hold the six parallel arrays in sequence. Saving (line 460) uses SAVE H$ LINE 80 to save the entire program with auto-run at line 80, preserving the current state of all arrays in memory.
Debug and Development Utilities
The program contains several features clearly intended for development rather than end-user use. The debug mode at lines 2200–2292, triggered by a keypress mapping to code 33, displays the internal flags for the current entry and allows direct editing of all five parallel arrays. Lines 4000–4450 (never called from the main dispatch) contain utilities for inserting array rows, entering tax bracket table data interactively, printing the bracket tables, and shifting entries — all terminated with STOP.
Notable Anomalies
- Line
2022is the target ofGO TO 2022from line2005, but the actual code at that line number is line2025— the program jumps to the next line after 2022, which is standard behavior for a non-existent target line. - The subroutine at line
2410is called asGO SUB 2410from lines2665and2710, but line 2410 containsIF NV<0 THEN LET NV=0(part of the2400subroutine block that continues from2400); this is intentional mid-subroutine entry. - Variable
WLis set to 4 at both line25and line88, making the second assignment redundant. - The
CRSTcolumn constant (22) andWL(4) define fixed screen layout columns used throughout but are never changed during normal operation.
Source Code
1 REM 1984 TAX RETURN HELPER
2 REM COPYRIGHT KSOFT CO.
16 DIM L$(160,4):DIM \{16}\{0}E$(160,17)
18 DIM P$(160,1):DIM R$(160,1)
20 DIM V(160):DIM N(160)
22 DIM T(65):DIM M(65):DIM S(65)
24 DIM Q$(4)
25 LET WL=4
30 LET SJ=0
32 LET O$=" "
50 PRINT AT 21,0;"WHAT FORM?"
52 INPUT F$
53 PRINT AT 21,0;"PRESS PLAY ON TAPE"
54 LET W$=F$+"1"
56 LOAD W$ DATA L$()
60 LET W$=F$+"2"
62 LOAD W$ DATA E$()
64 LET W$=F$+"3"
66 LOAD W$ DATA P$()
70 LET W$=F$+"4"
72 LOAD W$ DATA R$()
74 LET W$=F$+"5"
76 LOAD W$ DATA N()
78 LET W$=F$+"6"
80 CLS
81 BORDER 5
82 PRINT AT 5,5;"TAX RETURN HELPER"
84 PRINT TAB 5;"COPYRIGHT KSOFT CO."
85 PAUSE 240
86 LET IM=145
88 LET WL=4
94 LET CRST=22
96 LET CP=WL+1
100 LET TP=1:LET LS=20
104 LET J1=1:LET J2=20
106 GO SUB 1400
110 LET LRST=2:LET I=3
120 PRINT AT LRST,CRST;\{20}\{1}\{20}\{0}"\{20}\{1}>\{20}\{0}"
122 IF INKEY$="" THEN GO TO 122
124 LET A= CODE INKEY$
125 PRINT AT LRST,CRST;" "
128 IF A >=53 AND A <=90 THEN GO TO (A+97)
129 IF A=33 THEN GO TO 2200
130 IF A=35 THEN GO TO 2340
131 IF A=64 THEN GO TO 2300
149 GO TO 200
150 GO TO 210
151 GO TO 250
152 GO TO 300
153 GO TO 350
172 GO TO 200
173 GO TO 1500
174 GO TO 200
176 GO TO 200
177 GO TO 730
179 GO TO 200
180 GO TO 400
181 GO TO 2000
184 GO TO 200
185 GO TO 600
186 GO TO 200
187 GO TO 790
199 GO TO 200
200 PRINT AT LRST,CRST;" "
205 GO TO 120
210 IF INKEY$ <>"" THEN GO TO 210
215 IF R$(I) <>"?" THEN GO TO 120
220 PRINT AT LRST,CP;"\{20}\{1}>\{20}\{0}";O$( TO 15)
230 INPUT S$
235 IF S$="" THEN GO TO 242
240 LET E$(I)=S$
242 PRINT AT LRST,CP;E$(I)
246 GO TO 120
250 IF INKEY$ <>"" THEN GO TO 250
252 IF I=IM THEN GO TO 100
255 LET I=I+1
260 IF I>LS THEN GO TO 1570
265 LET LRST=LRST+1
270 GO TO 120
300 IF INKEY$ <>"" THEN GO TO 300
302 IF I=1 THEN GO TO 120
305 LET I=I-1
310 IF I<TP THEN GO TO 1570
315 LET LRST=LRST-1
320 GO TO 120
350 IF INKEY$ <>"" THEN GO TO 350
355 IF P$(I)="N" OR P$(I)="=" THEN GO TO 120
360 PRINT AT LRST,23;"\{20}\{1}>\{20}\{0}";O$( TO 8)
365 INPUT S$
370 IF S$="" THEN GO TO 390
375 LET NV= VAL S$
376 IF NV>999999.99 THEN GO TO 390
380 GO SUB 800
385 GO TO 120
390 LET J=I:LET V(J)=V(I)
395 GO SUB 1300
397 GO TO 120
400 PRINT AT LRST,CRST;" "
402 PRINT AT 21,0;"WHAT NAME?"
405 INPUT U$
410 IF U$="" THEN GO TO 455
415 LET E$(1)=U$
420 LET H$=U$
455 CLS
460 SAVE H$ LINE 80
470 GO TO 100
600 FOR I=1 TO IM
610 LET V(I)=0
615 IF R$(I)="?" THEN LET E$(I)="?"
620 NEXT I
622 LET E$(6)="CHILDREN?"
624 LET E$(7)="OTHER DEPENDENTS?"
626 LET E$(30)="OTHER INCOME?"
630 LET E$(97)="OTHER?"
632 LET E$(111)="OTHER?"
634 LET E$(119)="OTHER?"
636 LET E$(137)="OTHER?"
638 LET E$(126)="CONTRIB.>$3000?"
640 LET E$(117)="H.M.(TO WHOM?)"
642 LET E$(138)="TAX PROGRAMS?"
680 GO TO 100
730 FOR J=1 TO IM
735 LPRINT L$(J);" ";E$(J);
740 IF P$(J)="N" THEN GO TO 770
750 GO SUB 1700
755 LPRINT TAB 23;N$
760 NEXT J
765 GO TO 120
770 LPRINT
775 NEXT J
780 GO TO 120
790 COPY
795 GO TO 120
800 IF NV<0 AND P$(I) <>"-" THEN GO TO 910
805 LET D=NV-V(I)
810 LET J=I
815 IF D=0 THEN GO SUB 1300:GO TO 865
820 LET NJ=N(J)
825 IF NJ>IM THEN GO TO 855
830 LET V(J)=V(J)+D
835 GO SUB 1300
840 IF NJ<0 THEN LET D=-D
845 LET J= ABS NJ
850 GO TO 860
855 GO SUB NJ
860 IF J>0 THEN GO TO 815
865 IF SJ=0 THEN GO TO 900
870 LET J=SJ
875 LET SJ=0
880 LET D=SD
890 GO TO 815
900 PRINT AT 21,0;O$
905 RETURN
910 PRINT AT 21,0;"\{20}\{1}WARNING\{20}\{0}:NEGATIVE VALUE"
912 PAUSE 120
915 GO TO 805
1300 IF J<TP OR J>LS THEN RETURN
1305 LET LIN=J-TP
1310 GO SUB 1700
1320 PRINT AT LIN,23;N$
1330 RETURN
1400 CLS
1405 FOR J=J1 TO J2
1410 PRINT L$(J);" ";E$(J);
1415 IF P$(J)="N" THEN GO TO 1440
1420 GO SUB 1700
1425 PRINT TAB 23;N$
1430 NEXT J
1435 RETURN
1440 PRINT
1445 NEXT J:RETURN
1500 INPUT U$
1505 LET Q$=U$
1510 FOR J=I+1 TO IM
1515 IF L$(J)=Q$ THEN GO TO 1560
1520 NEXT J
1525 FOR J=1 TO I
1530 IF L$(J)=Q$ THEN GO TO 1560
1535 NEXT J
1540 PRINT AT 21,0;"L";U$;" NOT FOUND"
1545 PAUSE 120
1550 PRINT AT 21,0;O$
1555 GO TO 120
1560 LET I=J
1570 LET TP=I:LET J1=I
1575 LET LS=I+19
1580 IF LS>IM THEN LET LS=IM
1585 LET J2=LS
1590 GO SUB 1400
1595 LET LRST=0
1597 GO TO 120
1700 LET V$= STR$ V(J)
1705 LET LV= LEN V$
1710 LET N$=" "
1715 FOR K=1 TO LV
1720 IF V$(K)="." THEN GO TO 1730
1725 NEXT K
1730 LET N$(8-K TO 9)=V$(1 TO LV)
1740 RETURN
2000 IF IM <>145 THEN GO TO 200
2005 IF V(3) <>0 THEN GO TO 2022
2010 PRINT AT 21,0;"FILL L1/5 FIRST"
2015 PAUSE 120
2017 PRINT AT 21,0;O$
2020 GO TO 120
2025 LET I=50
2030 LET TP=49
2035 LET J1=49
2040 LET LS=68
2045 LET J2=68
2050 GO SUB 1400
2055 LET LRST=1
2060 PRINT AT 21,0;"INCOME FROM L37? (Y/N)"
2065 INPUT A$
2070 PRINT AT 21,0;O$
2075 IF A$="N" THEN GO TO 2080
2077 LET IN=V(49)
2078 GO TO 2090
2080 PRINT AT 21,0;"ENTER TAXABLE INCOME"
2085 INPUT IN
2090 IF IN>0 THEN GO TO 2100
2095 LET TX=0
2097 GO TO 2140
2100 IF V(3)=1 THEN LET K1=1:LET K2=17:GO TO 2120
2105 IF V(3)=2 OR V(3)=5 THEN LET K1=18:LET K2=33:GO TO 2120
2110 IF V(3)=3 THEN LET K1=34:LET K2=49:GO TO 2120
2115 IF V(3)=4 THEN LET K1=50:LET K2=65
2120 FOR K=K1 TO K2
2125 IF IN<T(K) THEN GO TO 2135
2130 NEXT K
2135 LET TX=M(K-1)+S(K-1)*(IN-T(K-1))/100
2140 LET NV=TX
2145 GO SUB 800
2150 PAUSE 120
2155 PRINT AT 21,0;O$
2160 GO TO 120
2200 PRINT AT 21,0;"I ";I;" P ";P$(I);" R ";R$(I);" N ";N(I);" "
2205 IF INKEY$="" THEN GO TO 2205
2210 LET A$= INKEY$
2215 IF INKEY$ <>"" THEN GO TO 2215
2220 IF A$="E" THEN GO TO 2240
2222 IF A$="L" THEN GO TO 2250
2224 IF A$="P" THEN GO TO 2260
2226 IF A$="R" THEN GO TO 2270
2228 IF A$="N" THEN GO TO 2280
2230 GO TO 2290
2240 INPUT E$(I)
2242 PRINT AT LRST,WL+1;E$(I)
2244 GO TO 2205
2250 INPUT L$(I)
2252 PRINT \{16}\{0} AT LRST,0;L$(I)
2254 GO TO 2205
2260 INPUT P$(I)
2262 GO TO 2200
2270 INPUT R$(I)
2272 GO TO 2200
2280 INPUT N(I)
2282 GO TO 2200
2290 PRINT AT 21,0;O$
2292 GO TO 120
2300 FOR I=1 TO IM
2310 LPRINT I; TAB 4;L$(I);" ";E$(I)( TO 10);" ";P$(I);" ";R$(I);" ";N(I)
2320 NEXT I
2330 GO TO 100
2340 CLS
2341 FOR I=1 TO IM
2345 PRINT I; TAB 4;L$(I);" ";P$(I);" ";R$(I);" ";N(I)
2350 NEXT I
2355 STOP
2400 LET NV=V(J-2)-V(J-1)
2410 IF NV<0 THEN LET NV=0
2415 LET NV=(INT (NV*100))/100
2420 LET D=NV-V(J)
2430 LET V(J)=NV
2435 GO SUB 1300
2440 RETURN
2450 IF NV<1 OR NV>5 THEN GO TO 2470
2455 LET V(3)=NV
2460 GO SUB 1300
2465 LET J=144
2467 RETURN
2470 PRINT AT 21,0;"\{20}\{1}FILING STATUS MUST BE 1...5\{20}\{0}"
2475 PAUSE 120
2480 PRINT AT 21,0;O$
2481 LET J=I:LET V(J)=V(I)
2482 GO SUB 1300
2483 LET J=0
2485 RETURN
2500 GO SUB 2400
2520 LET J=31
2540 RETURN
2600 LET NV=V(8)*1000
2610 LET D=V(48)-NV
2620 LET V(48)=NV
2630 GO SUB 1300
2640 LET J=49
2650 RETURN
2660 LET NV=V(52)-V(58)
2665 GO SUB 2410
2670 LET J=63
2680 RETURN
2700 LET NV=V(59)-V(62)
2710 GO SUB 2410
2750 LET J=70
2760 RETURN
2800 LET V(J)=V(J)+D
2810 GO SUB 1300
2820 LET D=V(70)-V(80)
2840 IF D>0 THEN GO TO 2900
2860 LET V(82)=-D
2865 LET J=82
2867 GO SUB 1300
2870 LET V(85)=0
2875 LET J=85
2877 GO SUB 1300
2880 GO TO 2940
2900 LET V(85)=D
2905 LET J=85
2910 GO SUB 1300
2920 LET V(82)=0
2922 LET J=82
2925 GO SUB 1300
2930 LET V(83)=0
2932 LET J=83
2933 GO SUB 1300
2935 LET V(84)=0
2937 LET J=84
2938 GO SUB 1300
2940 LET J=0
2945 RETURN
2950 IF V(83)+V(84)=V(82) THEN RETURN
2960 PRINT AT 21,0;"\{20}\{1}\{20}\{1}\{20}\{0}\{20}\{1}WARNING\{20}\{0}:L66+L67 SHOULD MATCH L65"
2970 PAUSE 120
2980 PRINT AT 21,0;O$
2985 LET J=0
2990 RETURN
3000 LET V(J)=V(J)+D
3010 GO SUB 1300
3015 LET J=0
3020 GO TO 2950
3100 LET V(J)=V(J)+D
3105 GO SUB 1300
3110 IF V(45) <>0 AND V(46) <>0 THEN GO TO 3150
3120 LET J=47
3130 LET D=-D
3140 RETURN
3150 PRINT AT 21,0;"\{20}\{1}WARNING\{20}\{0}\{20}\{1}\{20}\{0}:FILL L34A \{20}\{1}OR\{20}\{0} L34B"
3160 PAUSE 120
3170 PRINT AT 21,0;O$
3180 GO TO 3120
3200 LET V(44)=V(44)+D
3210 GO SUB 1300
3220 LET J=47
3230 LET SJ=102
3240 LET SD=D
3250 RETURN
3300 IF V(43) <=0 THEN GO TO 3365
3305 LET NV=5*(INT V(44))/100
3310 LET D=NV-V(102)
3315 LET V(102)=NV
3320 GO SUB 1300
3330 LET J=94
3340 LET SJ=102
3350 LET SD=D
3360 RETURN
3365 LET NV=0
3370 GO TO 3310
3400 GO SUB 2400
3410 LET J=101
3420 RETURN
3450 LET V(95)=V(95)+D
3455 GO SUB 1300
3460 LET J=101
3465 LET SJ=104
3470 LET SD=D
3475 RETURN
3500 IF V(44) <=0 THEN GO TO 3575
3505 LET NV=5*(INT V(44))/100
3510 LET D=NV-V(102)
3515 LET V(102)=NV
3520 GO SUB 1300
3525 LET J=103
3530 RETURN
3550 GO SUB 2400
3560 LET J=143
3570 RETURN
3575 LET NV=0
3580 GO TO 3510
3700 IF V(3)=2 OR V(3)=5 THEN LET V(144)=3400
3710 IF V(3)=1 OR V(3)=4 THEN LET V(144)=2300
3720 IF V(3)=3 THEN LET V(144)=1700
3730 GO SUB 1300
3740 LET J=145
3750 RETURN
3800 GO SUB 2400
3810 LET J=45
3820 RETURN
3850 IF NV<1 OR NV>6 THEN GO TO 3870
3855 LET V(5)=NV
3860 GO SUB 1300
3865 LET J=8
3867 RETURN
3870 PRINT AT 21,0;"\{20}\{1}WARNING\{20}\{0}:MORE THAN 6 EXEMPTIONS"
3875 PAUSE 120
3880 PRINT AT 21,0;O$
3882 LET J=I:LET V(J)=V(I)
3883 GO SUB 1300
3885 LET J=0
3890 RETURN
4000 FOR I=33 TO 40 STEP -1
4010 LET L$(I+1)=L$(I)
4020 LET E$(I+1)=E$(I)
4030 LET P$(I+1)=P$(I)
4040 LET R$(I+1)=R$(I)
4050 LET N(I+1)=N(I)
4060 NEXT I
4100 FOR I=33 TO 40
4110 LET N(I)=41
4120 NEXT I
4200 FOR I=1 TO 65
4210 PRINT I
4220 INPUT T(I):PRINT T(I)
4230 INPUT M(I):PRINT M(I)
4240 INPUT S(I):PRINT S(I)
4250 NEXT I
4300 FOR I=1 TO 65
4310 LPRINT T(I);" ";M(I);" ";S(I)
4320 NEXT I
4330 STOP
4400 FOR I=65 TO 15 STEP -1
4410 LET T(I)=T(I-1)
4420 LET M(I)=M(I-1)
4430 LET S(I)=S(I-1)
4440 NEXT I
4450 STOP
9992 SAVE "1040-A" LINE 80
9998 REM
Note: Type-in program listings on this website use ZMAKEBAS notation for graphics characters.
