Tax Return Helper

Date: 1984
Type: Program
Platform(s): TS 2068
Tags: Tax

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:

ArrayDimensionsPurpose
L$(160,4)160 × 4 charsLine label (e.g., “L37”)
E$(160,17)160 × 17 charsEntry description/prompt
P$(160,1)160 × 1 charProperty flags: “N”=no numeric, “=”=calculated, “-“=can be negative
R$(160,1)160 × 1 charRule flags: “?”=user-editable
V(160)160 floatsCurrent numeric values
N(160)160 integersPropagation 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 delta D is added to V(J) and propagation continues to field N(J).
  • If N(J) is negative, D is negated (sign flip) and propagation continues to ABS N(J).
  • If N(J) > IM, a GO 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 2022 is the target of GO TO 2022 from line 2005, but the actual code at that line number is line 2025 — the program jumps to the next line after 2022, which is standard behavior for a non-existent target line.
  • The subroutine at line 2410 is called as GO SUB 2410 from lines 2665 and 2710, but line 2410 contains IF NV<0 THEN LET NV=0 (part of the 2400 subroutine block that continues from 2400); this is intentional mid-subroutine entry.
  • Variable WL is set to 4 at both line 25 and line 88, making the second assignment redundant.
  • The CRST column constant (22) and WL (4) define fixed screen layout columns used throughout but are never changed during normal operation.

Related Products

Form 1040 and most schedules. Enter and modify data on a screen copy of the form. TS 2068 version in...

Image Gallery

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.