--- title: "Tax Planner" id: 56035 type: "computer_media" slug: "tax-planner" url: "http://localhost/computer_media/tax-planner/" markdown_url: "http://localhost/computer_media/tax-planner.md" published_at: "2024-07-14T19:55:42+00:00" modified_at: "2026-03-30T21:45:56+00:00" author: "David Anderson" featured_image: url: "http://localhost/wp-content/uploads/2019/02/20230809-041332.jpg" excerpt: "A dual-year tax planning tool compares your 1982 and 1983 US federal income tax side by side, walking through income, deductions, exemptions, and bracket lookups." category: - name: "Archived Media" slug: "archived-media" taxonomy: "category" url: "http://localhost/category/archived-media/" post_tag: - name: "Downloadable" slug: "downloadable" taxonomy: "post_tag" url: "http://localhost/tag/downloadable/" - name: "TS 2068" slug: "ts2068" taxonomy: "post_tag" url: "http://localhost/tag/ts2068/" model: - name: "Timex/Sinclair 2068" slug: "ts-2068" taxonomy: "model" url: "http://localhost/model/ts-2068/" indiv: - name: "Herman Geschwind" slug: "herman-geschwind" taxonomy: "indiv" url: "http://localhost/indiv/herman-geschwind/" genre: - name: "Finance" slug: "finance" taxonomy: "genre" url: "http://localhost/type/finance/" - name: "Tax" slug: "tax" taxonomy: "genre" url: "http://localhost/type/tax/" media_type: "Program" programmers: - name: "Herman Geschwind" slug: "herman-geschwind" taxonomy: "indiv" url: "http://localhost/indiv/herman-geschwind/" download_url: "https://archive.org/download/timex-sinclair-software-archive/Tax%20Planner%20%281983%29%28Geschwind%2C%20Herman%29%28TS2068%29%28US%29%28Program%29.zip" mediadate: "1982" images: - url: "http://localhost/wp-content/uploads/2024/07/SCR-20240714-oapi.png" media_type_tags: "Finance, Tax" --- # Tax Planner This program is a US federal income tax planning tool that compares projected 1982 and 1983 tax liabilities side by side. It collects income items (wages, dividends, interest, business income, and up to 13 categories), calculates adjusted gross income, itemized deductions (including the medical expense floor at 3% of AGI for 1982 and 5% for 1983), zero bracket amounts, exemptions, and taxable income, then looks up the computed tax using bracket tables stored in parallel arrays. Three filing statuses are supported: single, married filing jointly, and married filing separately. Data for both tax years is held simultaneously in the arrays S() and T(), and results can be printed to a ZX printer using the COPY command triggered by pressing “Z” at review screens. *** ## Program Analysis ### Program Structure The program is organized into clearly labeled subroutine blocks separated by REM lines and `STOP` guards. Control flows through a main menu at line `500` that dispatches on a single keypress to five functions. 1. Lines 1–195: Constants and string initialization 2. Line 240 / 1000–1060: Description loader (populates `D$()`) 3. Lines 500–690: Main menu loop 4. Lines 2000–2310: Data clear submenu 5. Lines 3000–3280: 1982 value entry 6. Lines 3500–3785: 1983 value entry 7. Lines 4000–4070: Tape save 8. Lines 5000–5490: 1982 tax table loader and bracket calculation 9. Lines 5500–5900: 1983 tax table loader and bracket calculation 10. Lines 6000–6897: Results display with optional hardcopy 11. Lines 6900–7299: 1982 tax bracket data (single and married) 12. Lines 7400–7639: 1983 tax bracket data (single and married) 13. Lines 9500–9560: Right-justify number display subroutine ### Data Storage All 26 tax line items for 1982 are stored in the numeric array `S(26)` and for 1983 in `T(26)`. Line descriptions are stored in the string array `D$(26,18)` (26 entries, 18 characters wide). The tax bracket tables are loaded at runtime into three parallel arrays: bracket floor values (`A()`/`D()`), base tax amounts (`B()`/`E()`), and marginal rates (`C()`/`F()`). ### Tax Calculation Logic The bracket lookup at lines 5420–5470 (1982) and 5810–5870 (1983) scans the bracket floor array until the taxable income falls below the next bracket, then backs up one step and applies the formula: `base_tax + (taxable_income − bracket_floor) × rate / 100`, rounded to the nearest dollar using `INT(...+.5)`. Medical expense deduction logic differs between years: 1982 uses a 3% AGI floor (line `3104`) and also incorporates a medical insurance premium half-deduction capped at $150; 1983 uses a 5% AGI floor (line `3604`) with no insurance premium split, reflecting actual tax law changes between the two years. Line `3185` applies a special rule: if only charitable contributions are entered among deductions (medical, taxes, interest, and miscellaneous all zero), the contribution amount is divided by 4. Line `3192` then collapses the entire deduction total to just that contribution value. The 1983 equivalent at lines `3685`–`3692` handles this similarly. ### Filing Status Handling Filing status is stored in the variable `S` (1=single, 2=married, 3=married filing separately). After the zero bracket amount is assigned for status 3 (line `3210`/`3710`), status is immediately reset to 1 (line `3215`/`3715`) so that the single-filer tax bracket table is used for married filing separately — which matches IRS rules of the era. ### Notable Techniques - The `PAUSE 4E4` idiom (approximately 40,000 frame pause) combined with `INKEY$` is used throughout the menu system to wait for a keypress without blocking execution indefinitely. - The right-justify subroutine at line `9500` uses `STR$` and `LEN` to position values at a fixed column `C` by computing `TAB(C - LEN J$ + 1)`, giving the results screen a column-aligned appearance. - The `COPY` command is offered at both results screens (lines `6056` and `6894`) by testing for keypress “Z”, sending the screen contents to a ZX printer. - Income credits at `D$(13)` are forced negative by `LET S(13)=-1*S(13)` (line `3035`) so they reduce the running income total correctly when summed. - The bracket data subroutine at line `6900` is called once per bracket entry via a `FOR` loop (lines 5070–5080), causing each pass to overwrite all array entries — effectively the loop only needs one iteration since the subroutine sets all values unconditionally. The loop is harmless but redundant. ### Bugs and Anomalies - Line `1027` misspells “PARTNERSHIP” as “PARTNERSJIP” — a data entry error that will appear on-screen and in printouts. - Line `7611` sets `D(12)=27278` for the 1983 married bracket floor, which is clearly wrong (it should be approximately 85,600 by analogy with the 1982 table and actual 1983 rates). The corresponding base tax `E(12)=27278` coincidentally matches the bracket floor value, suggesting a copy-paste error. - At line `3192`, the code sets `S(2)` (dividends) rather than `S(20)` (total deductions), which appears to be a typographical error where a zero was dropped — this would corrupt the dividends entry rather than setting total deductions. - The variable `S` serves double duty as both the filing status integer and the index into the `S()` income array. After status is used to set `S(21)` and then reassigned to 1 for married-separate filers, subsequent code using `S` as a numeric index could produce unexpected results if not carefully tracked. - The `FOR` loop calling `GO SUB 6900` at lines 5070–5080 iterates `B` times (12 or 13), but the subroutine unconditionally sets all array elements on every call. Only one call is necessary; the repetition wastes time but does not cause incorrect results. - Line `3106` applies the medical insurance premium amount `I` only when the net medical deduction would otherwise be zero or negative, but `I` holds a halved, capped value from lines 3058–3060 rather than the full premium — this matches the 1982 half-premium rule but the logic flow is non-obvious. ## Source Code ``` 1 REM TAX ***PLANER*** 2 REM ...COPYRIGHT..1982..... 3 REM ...BY..H.GESCHWIND..... 100 REM ***INITIALIZE*** 110 DIM D$(26,18) 120 DIM S(26) 130 DIM T(26) 135 LET M$="PRESS ANY KEY TO CONTINUE" 140 LET P$="ENTER" 150 LET X$="--------------------------------" 160 LET Y$=" 1982" 170 LET Z$=" 1983" 180 LET V$="INCOME" 190 LET W$="DEDUCTIONS" 195 LET H$="---->" 200 LET S=0 210 LET M=0 220 LET N=0 225 LET F$=" ENTER FILING STATUS:-->1 FOR SINGLE,-->2 FOR MARRIED,-->3 FORMARRIED FILING SEPARATELY" 240 GO SUB 1000 499 REM ***MENU*** 500 PRINT AT 3,6;" TAX PLANNER" 510 PRINT AT 6,4;"-->PRESS DESIRED FUNCTION" 520 PRINT AT 8,6;"1. ENTER VALUES" 525 PRINT AT 9,6;"2. REVIEW RESULTS" 530 PRINT AT 10,6;"3. CLEAR DATA" 570 PRINT AT 11,6;"4. SAVE DATA" 580 PRINT AT 12,6;"5. ENTER 1983 VALUES ONLY" 590 PAUSE 4E4 600 LET K$=INKEY$ 610 IF K$<"1" OR K$>"5" THEN GO TO 690 620 IF K$="1" THEN GO TO 3000 622 IF K$="2" THEN GO TO 6000 624 IF K$="3" THEN GO TO 2000 626 IF K$="4" THEN GO TO 4000 627 IF K$="5" THEN GO TO 3500 690 GO TO 500 998 STOP 999 REM ***DESCRIPTIONS*** 1000 CLS 1005 PRINT AT 21,5;"LOADING DESCRIPTIONS" 1020 LET D$(1)="SALARIES, WAGES" 1021 LET D$(2)="DIVIDENDS" 1022 LET D$(3)="INTEREST INCOME" 1023 LET D$(4)="NET BUS. INCOME" 1024 LET D$(5)="OTHER GAINS/LOSSES" 1025 LET D$(7)="PENSIONS,ANNUITIES" 1026 LET D$(8)="RENTS, ROYALTIES" 1027 LET D$(9)="PARTNERSJIP INC." 1028 LET D$(10)="TRUST/ESTATE INC." 1029 LET D$(11)="CHAPTER""S""CORP." 1030 LET D$(12)="OTHER INCOME" 1031 LET D$(13)="INCOME CREDITS(*)" 1032 LET D$(14)="ADJ. GROSS INCOME" 1034 LET D$(15)="MEDICAL EXPENSES" 1035 LET D$(16)="TAXES" 1036 LET D$(17)="CONTRIBUTIONS" 1037 LET D$(18)="INTEREST EXPENSES" 1038 LET D$(19)="CASUALTY LOSS,MISC." 1039 LET D$(20)="TOTAL DEDUCTIONS" 1040 LET D$(21)="ZERO BRACKET" 1041 LET D$(22)="NET DEDUCTIONS" 1042 LET D$(23)="INC.BEF.EXEMPTIONS" 1043 LET D$(24)="EXEMPTIONS" 1044 LET D$(25)="TAXABLE INCOME" 1045 LET D$(26)="INCOME TAX" 1050 CLS 1060 RETURN 1998 STOP 1999 REM ***CLEAR*** 2000 CLS 2010 PRINT AT 6,4;"-->PRESS DESIRED FUNCTION" 2020 PRINT AT 8,6;"1. DELETE 1982 VALUES" 2030 PRINT AT 9,6;"2. DELETE 1983 VALUES" 2050 PAUSE 4E4 2060 LET K$=INKEY$ 2070 IF K$<"1" OR K$>"2" THEN GO TO 2090 2072 IF K$="1" THEN GO TO 2100 2074 IF K$="2" THEN GO TO 2300 2090 GO TO 2010 2100 DIM S(26) 2101 LET S=0 2105 CLS 2110 GO TO 500 2300 DIM T(26) 2301 LET S=0 2305 CLS 2310 GO TO 500 2999 REM ***82 VALUES*** 3000 CLS 3001 LET M=0 3002 LET N=0 3003 LET I=0 3005 PRINT F$ 3006 INPUT S 3007 IF S<1 OR S>3 THEN GO TO 3005 3008 CLS 3010 FOR I=1 TO 13 3015 PRINT AT 10,(31-LEN V$)/2;V$ 3016 PRINT X$ 3020 PRINT P$ 3025 PRINT D$(I)+" FOR "+Y$ 3030 INPUT S(I) 3035 IF S(13) THEN LET S(13)=-1*S(13) 3036 PRINT H$; S(I) 3037 PAUSE 180 3038 CLS 3039 LET M=M+S(I) 3040 NEXT I 3041 LET S(14)=M 3042 LET M=0 3050 PRINT AT 10,(31-LEN W$)/2;W$ 3051 PRINT X$ 3052 PRINT P$+" FULL AMOUNT OF MEDICAL INSURANCE PREMIUMS" 3053 INPUT I 3054 PRINT H$;I 3055 PAUSE 180 3056 CLS 3058 LET I=I/2 3060 IF I>150 THEN LET I=150 3062 PRINT AT 10,(31-LEN W$)/2;W$ 3064 PRINT X$ 3066 PRINT P$ 3068 PRINT D$(15)+" FOR "+Y$ 3102 INPUT N 3103 PRINT H$;N 3104 LET M=INT (3/100*S(14)+.5) 3105 LET S(15)=N-M 3106 IF S(15)<=0 THEN LET S(15)=0+I 3107 LET M=0 3108 LET N=0 3109 CLS 3110 FOR I=16 TO 19 3111 PRINT AT 10,(31-LEN W$)/2;W$ 3112 PRINT X$ 3120 PRINT P$ 3125 PRINT D$(I)+" FOR "+Y$ 3130 INPUT S(I) 3140 PRINT H$;S(I) 3150 PAUSE 180 3160 CLS 3170 LET M=M+S(I) 3180 NEXT I 3185 IF S(15) AND S(16)=0 AND S(18)=0 AND S(19)=0 THEN LET S(17)=S(17)/4 3190 LET S(20)=M+S(15) 3192 IF S(15)=0 AND S(16)=0 AND S(18)=0 AND S(19)=0 THEN LET S(2)=S(17) 3195 LET M=0 3200 IF S=1 THEN LET S(21)=2300 3205 IF S=2 THEN LET S(21)=3400 3210 IF S=3 THEN LET S(21)=1700 3215 IF S=3 THEN LET S=1 3220 LET S(22)=S(20)-S(21) 3225 IF S(22)<=0 THEN LET S(22)=0 3230 LET S(23)=S(14)-S(22) 3240 PRINT "ENTER NUMBER OF EXEMPTIONS" 3250 INPUT M 3255 IF M<1 THEN LET M=1 3260 LET S(24)=M*1000 3265 LET M=0 3270 LET S(25)=S(23)-S(24) 3275 CLS 3280 GO SUB 5000 3499 REM ***83 VALUES*** 3500 CLS 3501 LET M=0 3502 LET N=0 3503 LET I=0 3505 PRINT F$ 3506 INPUT S 3507 IF S<1 OR S>3 THEN GO TO 3505 3508 CLS 3510 FOR I=1 TO 13 3515 PRINT AT 10,(31-LEN V$)/2;V$ 3516 PRINT X$ 3520 PRINT P$ 3525 PRINT D$(I)+" FOR "+Z$ 3538 INPUT T(I) 3539 IF T(13) THEN LET T(13)=-1*T(13) 3540 PRINT H$;T(I) 3550 PAUSE 180 3560 CLS 3570 LET N=N+T(I) 3580 NEXT I 3590 LET T(14)=N 3595 LET N=0 3596 PRINT AT 10,(31-LEN W$)/2;W$ 3597 PRINT X$ 3598 PRINT P$ 3599 PRINT D$(15)+" FOR "+Z$ 3602 INPUT N 3603 PRINT H$;N 3604 LET M=INT (5/100*T(14)+.5) 3605 LET T(15)=N-M 3606 IF T(15)<=0 THEN LET T(15)=0 3607 LET M=0 3608 LET N=0 3609 CLS 3610 FOR I=16 TO 19 3611 PRINT AT 10,(31-LEN W$)/2;W$ 3612 PRINT X$ 3620 PRINT P$ 3625 PRINT D$(I)+" FOR "+Z$ 3630 INPUT T(I) 3640 PRINT H$;T(I) 3650 PAUSE 180 3660 CLS 3670 LET N=N+T(I) 3680 NEXT I 3685 IF T(15)=0 AND T(16)=0 AND T(18)=0 AND T(19)=0 THEN LET T(17)=T(17)/4 3690 LET T(20)=N+T(15) 3692 IF T(15)=0 AND T(16)=0 AND T(18)=0 AND T(19)=0 THEN LET T(20)=T(17) 3695 LET N=0 3700 IF S=1 THEN LET T(21)=2300 3705 IF S=2 THEN LET T(21)=3400 3710 IF S=3 THEN LET T(21)=1700 3715 IF S=3 THEN LET S=1 3717 LET M=0 3718 LET N=0 3720 LET T(22)=T(20)-T(21) 3725 IF T(22)<=0 THEN LET T(22)=0 3730 LET T(23)=T(14)-T(22) 3740 PRINT "ENTER NUMBER OF EXEMPTIONS" 3750 INPUT M 3755 IF M<1 THEN LET M=1 3760 LET T(24)=M*1000 3765 LET M=0 3770 LET T(25)=T(23)-T(24) 3780 GO SUB 5500 3785 GO TO 500 3990 STOP 3999 REM ***SAVE*** 4000 CLS 4020 PRINT AT 8,7;"PREPARE RECORDER" 4030 PRINT AT 10,3;M$ 4040 PAUSE 4E4 4050 CLS 4060 SAVE "TAX PLANNER" 4070 GO TO 500 4999 REM ***82 TABLE*** 5000 CLS 5010 IF S=1 THEN LET B=13 5011 IF S=2 THEN LET B=12 5040 DIM A(B) 5050 DIM B(B) 5060 DIM C(B) 5065 PRINT AT 21,0;"LOADING TAX TABLE" 5070 FOR I=1 TO B 5075 GO SUB 6900 5080 NEXT I 5350 GO TO 5399 5361 STOP 5399 REM ***82 CALC*** 5400 LET S(26)=0 5420 IF S(25)