--- title: "Tax" id: 58456 type: "computer_media" slug: "tax" url: "http://localhost/computer_media/tax/" markdown_url: "http://localhost/computer_media/tax.md" published_at: "2024-11-17T22:14:45+00:00" modified_at: "2026-04-03T07:58:01+00:00" author: "David Anderson" featured_image: url: "http://localhost/wp-content/uploads/2024/11/Tax1.jpeg" excerpt: "A two-part cassette-based US tax return calculator that parses delimited category strings, handles capital-gain carry-forwards, and hands off computed values to a side-B program." 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: "Practical Programs Inc." slug: "practical-programs-inc" taxonomy: "post_tag" url: "http://localhost/tag/practical-programs-inc/" - name: "TS 1000" slug: "ts1000" taxonomy: "post_tag" url: "http://localhost/tag/ts1000/" model: - name: "Timex/Sinclair 1000" slug: "ts-1000" taxonomy: "model" url: "http://localhost/model/ts-1000/" genre: - name: "Finance" slug: "finance" taxonomy: "genre" url: "http://localhost/type/finance/" media_type: "Program" download_url: "https://archive.org/download/timex-sinclair-software-archive/Tax%20%281983%29%28Practical%20Products%29%28TS1000%29%28US%29%28Program%29.zip" mediadate: "1983" producer_company: - id: 11189 title: "Practical Programs Inc." type: "company" url: "http://localhost/company/practical-programs-inc/" images: - url: "http://localhost/wp-content/uploads/2024/11/Tax1.jpeg" - url: "http://localhost/wp-content/uploads/2024/11/Tax2.jpeg" - url: "http://localhost/wp-content/uploads/2024/11/Tape1-2.jpg" - url: "http://localhost/wp-content/uploads/2024/11/Tape2-2.jpg" related_products: - id: 14222 title: "Tax Command" type: "product" url: "http://localhost/product/tax-command/" media_type_tags: "Finance" --- This program is Part 1 of a two-part 1983 US income tax computation aid. It guides users through entering wages, interest, dividends, capital gains, other income, adjustments to income, and itemized deductions (medical, taxes, interest, contributions, and miscellaneous), then calculates gross income and total deductions. A subroutine at line 5500 parses colon-delimited string literals (C$ and D$) into a string array V$(21,20) and numeric array V(21) for storing deduction category names and values. At the end of Part 1 the program instructs the user to note key computed values (adjusted income AI and deductions DE), flip the cassette tape, and LOAD “TAX 2” to continue with tax calculation in Part 2. The program uses SLOW/FAST mode switching and INKEY$-based menu navigation throughout. *** ## Program Structure The program is divided into clearly separated functional blocks, invoked via `GOSUB` from two main menu loops: 1. Lines 1–78: Initialisation — arrays, variables, and the category-string parser (`GOSUB 5500`). 2. Lines 80–600: Income sub-sections — wages (`80`), dividends (`180`), interest (`300`), other income (`430`). 3. Lines 610–820: Income summary screen with letter-key dispatch. 4. Lines 840–1350: Capital gains — short-term (`1100`) and long-term (`1230`) entry, carry-forward calculation. 5. Lines 1360–1480: Main Part-1 menu (gross income, adjustments, deductions, jump to Part 2). 6. Lines 1490–1770: Adjustments-to-income sub-menu (moving, IRA, Keogh, alimony, etc.). 7. Lines 1840–2870: Deductions — medical (`1980`), taxes (`2280`), interest (`2430`), contributions (`2570`), miscellaneous (`2700`), losses (`2691`). 8. Lines 2880–2936: Display/input helper subroutines using the `V$()`/`V()` arrays. 9. Lines 3000–4000: Part-2 handoff — prints computed values, instructs LOAD “TAX 2”. 10. Lines 5500–5570: String parser — splits `F$` on `:`/`;` into `V$(H)`. 11. Lines 9000–9030: Utility block for saving the program (not reached in normal execution). ## Category String Parser (lines 5500–5570) Rather than embedding each deduction category name as a separate string variable or DATA statement, the author encodes all names into two long strings `C$` (line 14) and `D$` (line 15), delimited by `:` between fields and terminated by `;`. The subroutine at `5500` walks the string character by character, accumulating characters into `E$` until a `:` triggers storage of `E$` into `V$(H)`, and a `;` terminates the loop. This is a compact way to initialise a string array from a single literal, saving both line overhead and memory. Each entry in `V$(21,20)` holds a 20-character padded name. The display subroutine at line `2880` slices columns 1–4 as a line-number prefix (`L$`), column 5 as a colour/highlight character (`M$`), and columns 6 onward as the label text (`R$`). It then adds 128 to the character code of `M$` to produce an inverse-video character — a simple way to render menu key letters in inverse. ## Key BASIC Idioms - **INKEY$ polling loops** — e.g. `IF INKEY$="" THEN GOTO 770` — used throughout instead of `INPUT` for single-key menu selection, giving immediate response. - **SLOW/FAST toggling** — `SLOW` at line 2 and 77, `FAST` at line 70, brackets the string-parser calls to allow display during the loop. - **Array reuse** — `V(21)` stores numeric values for all deduction categories by index, allowing a single pair of subroutines (`2880`, `2930`) to handle display and input for any category. - **Zero-entry sentinel** — `IF D(I)=0 THEN GOTO 280` (line 250) terminates a data-entry loop on a zero input rather than requiring a fixed count, a common idiom for variable-length lists. ## Capital Gains Computation (lines 840–1010) The capital-gains section implements the 1983 US tax rules with some complexity: - If net gain `NG = NS + NL` is positive, 60% of the long-term portion (`GG`) is excluded: `CG = NG - 0.6*GG`. - If net gain is negative and short-term is positive: `CG = 0.5*NG`. - If net loss exceeds −3000, carry-forwards are computed and displayed (lines 950–1006), and `CG` is clamped to −3000. There is a structural anomaly: lines 910–930 contain orphaned conditional branches (`IF NS>0`, `IF NL>0`, `LET CG=NS+.5*NL`) that are never reached because the preceding `GOTO 940` at line 902 skips them entirely. These appear to be dead code from an earlier version of the logic. ## Notable Techniques | Technique | Location | Purpose | | --- | --- | --- | | Inverse-video key hint via `CODE + 128` | Lines 2902–2906 | Highlights menu letter in display without separate PRINT AT/INK statements | | Delimited string as array initialiser | Lines 14–15, 5500–5570 | Compresses 21 category names into two string literals | | Part handoff via cassette flip | Lines 3100–3165 | Splits computation across two cassette sides; user notes AI and DE manually | | `INT(x + 0.5)` rounding | Lines 1020, 2000, 2100 | Banker-friendly rounding of currency values | | `CHR$ 118` as ENTER key test | Line 1072 | Allows pressing ENTER as an alternative to “R” to return | ## Source Code ``` 1 REM "TAX 1" 2 SLOW 3 PRINT AT 11,9;"PLEASE WAIT" 4 LET GI=0 5 LET AD=0 6 LET DE=0 7 LET TX=0 8 LET P=0 9 LET TT=0 12 DIM V$(21,20) 13 DIM V(21) 14 LET C$=" 1 MEDICINE:: 4A DOCTORS, ETC.: 4B TRANSPORT.: 4C OTHER MEDICAL: 8 INCOME TAXES: 9 PROPERTY:10A SALES TAXES:10B VEHICLE:11 OTHER TAXES:13A BANK MORT:13B IND. MORT:14 CREDIT CARDS:15 OTHER INTER.:17ABCASH CONT.:18 OTHER CONT.:19 PRIOR YEARS:;" 15 LET D$="21 CASUALTY:22 DUES-UN. AND PR.:23 TAX FEE:24 OTHER DEDUC.:;" 22 LET H$="NO" 24 LET EX=1 25 LET NN=0 26 LET FS=1 28 LET SD=2300 30 DIM I(10) 31 LET ND=0 32 DIM D(10) 33 LET NS=0 34 LET NL=0 35 LET IG=0 36 DIM S(10) 37 DIM L(10) 38 LET IL=0 39 DIM O(10) 40 LET W2=0 41 LET IN=0 42 LET D=0 43 LET EC=0 44 LET CG=0 45 LET IO=0 47 LET MV=0 48 LET BS=0 49 LET IR=0 50 LET K=0 51 LET SP=0 52 LET AL=0 53 LET MP=0 54 LET DS=0 55 LET M=0 56 LET T=0 57 LET ID=0 58 LET CO=0 59 LET MS=0 60 LET LO=0 62 LET B=0 65 LET H=0 66 LET F$=C$ 68 CLS 70 FAST 72 GOSUB 5500 74 LET F$=D$ 76 GOSUB 5500 77 SLOW 78 GOTO 1360 80 CLS 84 PRINT AT 1,0;"7.TYPE TOTAL WAGES" 94 PRINT AT 4,0;" ";W2 120 INPUT W2 124 PRINT AT 4,0;" ";W2;" " 170 RETURN 180 CLS 184 PRINT AT 1,0;"9.TYPE DIVIDEND" 185 PRINT "TYPE 0 TO QUIT" 186 PRINT 190 IF ND=0 THEN GOTO 220 200 FOR I=14 TO ND 210 PRINT " ";D(I) 212 NEXT I 220 LET D=0 230 FOR I=1 TO 10 240 INPUT D(I) 245 PRINT D(I);" " 250 IF D(I)=0 THEN GOTO 280 260 LET D=D+D(I) 270 NEXT I 280 LET ND=I-1 290 RETURN 300 CLS 302 PRINT AT 1,0;"8.TYPE INTEREST" 306 PRINT "TYPE 0 TO QUIT" 308 PRINT 310 IF NN=0 THEN GOTO 350 320 FOR I=1 TO NN 330 PRINT " ";I(I) 332 NEXT I 340 PRINT AT 3,0 350 LET IN=0 360 FOR I=1 TO 10 370 INPUT I(I) 375 PRINT " ";I(I);" " 380 IF I(I)=0 THEN GOTO 410 390 LET IN=IN+I(I) 400 NEXT I 410 LET NN=I-1 420 RETURN 430 CLS 432 PRINT AT 1,0;"OTHER INCOME" 436 PRINT 440 PRINT "10%TAX REFUND ";O(1) 450 PRINT "11%ALIMONY REC. ";O(2) 460 PRINT "12%BUSINESS INC.";O(3) 470 PRINT "14%OTHER GAIN ";O(4) 480 PRINT "15%SUPP. GAIN ";O(5) 490 PRINT "16/17%PENSION ";O(6) 500 PRINT "18R%ENTS, ROYAL.";O(7) 510 PRINT "19%FARM INCOME ";O(8) 520 PRINT "20%UNEMP. COM. ";O(9) 530 PRINT "21OTHER %INCOME ";O(10) 531 PRINT 532 PRINT " %RETURN" 533 PRINT 534 PRINT "TYPE BLACK LETTER" 535 PRINT 536 IF INKEY$="" THEN GOTO 536 538 LET A$=INKEY$ 540 IF A$="R" THEN GOTO 593 541 IF A$<>"T" THEN GOTO 546 542 PRINT "TAX REFUND" 543 INPUT O(1) 544 PRINT AT 3,15;O(1);" " 545 GOTO 590 546 IF A$<>"A" THEN GOTO 551 547 PRINT "ALIMONY REC." 548 INPUT O(2) 549 PRINT AT 4,15;O(2);" " 550 GOTO 590 551 IF A$<>"B" THEN GOTO 556 552 PRINT "BUSINESS INC." 553 INPUT O(3) 554 PRINT AT 5,15;O(3);" " 555 GOTO 590 556 IF A$<>"O" THEN GOTO 561 557 PRINT "OTHER GAIN" 558 INPUT O(4) 559 PRINT AT 6,15;O(4);" " 560 GOTO 590 561 IF A$<>"S" THEN GOTO 566 562 PRINT "SUPP. GAIN" 563 INPUT O(5) 564 PRINT AT 7,15;O(5);" " 565 GOTO 590 566 IF A$<>"P" THEN GOTO 571 567 PRINT "PENSION" 568 INPUT O(6) 569 PRINT AT 8,15;O(6);" " 570 GOTO 590 571 IF A$<>"E" THEN GOTO 576 572 PRINT "RENTS, ROYAL." 573 INPUT O(7) 574 PRINT AT 9,15;O(7);" " 575 GOTO 590 576 IF A$<>"F" THEN GOTO 581 577 PRINT "FARM INC." 578 INPUT O(8) 579 PRINT AT 10,15;O(8);" " 580 GOTO 590 581 IF A$<>"U" THEN GOTO 586 582 PRINT "UNEMP. COM." 583 INPUT O(9) 584 PRINT AT 11,15;O(9);" " 585 GOTO 590 586 IF A$<>"I" THEN GOTO 590 587 PRINT "OTHER INCOME" 588 INPUT O(10) 589 PRINT AT 12,15;O(10);" " 590 PRINT AT 18,0;" " 591 PRINT AT 17,0 592 GOTO 536 593 LET IO=0 594 FOR I=1 TO 10 596 LET IO=IO+O(I) 598 NEXT I 600 RETURN 610 CLS 612 PRINT 614 PRINT "1983 TAX: INCOME" 616 PRINT "TYPE BLACK LETTERS" 620 PRINT 622 PRINT " 7%WAGES, SAL.",W2 630 PRINT " 8%INTEREST",IN 640 LET DV=D-EC 642 IF DV<0 THEN LET DV=0 650 PRINT " 9%DIVIDEND",DV 660 PRINT "(";D;"-";EC;")" 670 PRINT " (%EXCL.)",EC 680 PRINT "13%CAP. GAIN",CG 690 PRINT " %OTHER INCOME",IO 700 LET GI=W2+DV+IN+IO+CG 710 IF GI<0 THEN LET GI=0 720 PRINT 722 PRINT "22TOTAL INCOME",GI 740 PRINT 742 PRINT " %RETURN" 750 PRINT AT 21,0;"COPR 1983 PRACTIC PROG" 770 IF INKEY$="" THEN GOTO 770 772 LET A$=INKEY$ 780 IF A$="R" THEN RETURN 790 IF A$="W" THEN GOSUB 80 792 IF A$="D" THEN GOSUB 180 800 IF A$="I" THEN GOSUB 300 802 IF A$="O" THEN GOSUB 430 804 IF A$="C" THEN GOSUB 840 810 IF A$="E" THEN GOSUB 830 820 GOTO 610 830 CLS 832 PRINT 834 PRINT "EXCLUSION" 836 INPUT EC 837 PRINT " ";EC 838 RETURN 840 CLS 842 PRINT 844 PRINT "D.CAPITAL GAIN" 850 PRINT 852 PRINT "I. %SHORT",NS 860 PRINT 862 PRINT "II.%LONG",NL 870 LET NG=NS+NL 880 IF NG<0 THEN GOTO 910 890 LET GG=NG 892 IF NL0 THEN LET CG=.5*NG 912 GOTO 940 920 IF NL>0 THEN LET CG=NG 922 GOTO 940 930 LET CG=NS+.5*NL 940 IF CG>-3000 THEN GOTO 1010 950 LET CF=CG+3000 952 LET CG=-3000 960 LET S1=NS+3000 970 IF S1>0 THEN LET S1=0 980 IF S1