--- title: "Financial" id: 56678 type: "computer_media" slug: "financial" url: "http://localhost/computer_media/financial/" markdown_url: "http://localhost/computer_media/financial.md" published_at: "2024-09-22T23:31:42+00:00" modified_at: "2026-04-03T07:58:59+00:00" author: "David Anderson" featured_image: url: "http://localhost/wp-content/uploads/2024/09/1_AMOR.png" excerpt: "Four financial tools in one listing — loan amortization, Rule of 78s, compound interest with a plotted graph, and depreciation — each with clever string formatting tricks to fake two-decimal-place currency output." 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 1000" slug: "ts1000" taxonomy: "post_tag" url: "http://localhost/tag/ts1000/" - name: "UAS" slug: "uas" taxonomy: "post_tag" url: "http://localhost/tag/uas/" 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/Financial%20%28198x%29%28UAS%29%28TS1000%29%28US%29%28Program%29.zip" mediadate: "198x" producer_company: - id: 11418 title: "UAS" type: "company" url: "http://localhost/company/uas/" images: - url: "http://localhost/wp-content/uploads/2024/09/1_AMOR.png" - url: "http://localhost/wp-content/uploads/2024/09/2_COMP.png" - url: "http://localhost/wp-content/uploads/2024/09/3_78.png" - url: "http://localhost/wp-content/uploads/2024/09/4_DEP.png" - url: "http://localhost/wp-content/uploads/2024/09/Tape-9-scaled.jpg" media_type_tags: "Finance" --- # Financial This listing contains four separate financial calculation programs: a loan amortization scheduler, a Rule of 78s interest calculator, a compound interest plotter, and a straight-line/sum-of-years depreciation table generator. The amortization program uses a shared subroutine at line 10 to normalize floating-point numbers to two decimal places by examining the string representation produced by STR$, compensating for the lack of built-in currency formatting. The compound interest program uses PLOT to draw a graphical chart of investment growth, dynamically scaling the Y-axis and adjusting the X-axis tick labels based on whether the term is ≤12, 13–25, or >25 years. A hardware status check via PEEK 16442 in the amortization loop triggers a COPY/CLS subroutine at line 500 when display memory is nearly full, preventing scroll overflow during long payment schedules. *** ## Program Analysis This file contains four independent BASIC programs saved sequentially, each self-contained with its own `SAVE` and re-entry `GOTO` at the end. They share a common origin (UAS, Haddonfield NJ) and several coding idioms. Each program is analysed in turn. ### Program 1 – Amortization Scheduler (lines 10–2010) Calculates and prints a loan amortization table, solving either for the monthly payment (given term) or for the term (given payment). The core payment formula uses the standard annuity present-value equation at line 150, and the term-solving path at line 440 inverts it using `LN`. ### Structure 1. Lines 10–24: Subroutine — normalise a float `X1` to two decimal places and return its string length in `Z`. 2. Lines 25–95: Title banner, input collection (loan amount, rate, periods/year, mode choice). 3. Lines 100–175: Initialise balance, compute periodic interest rate `I`, compute payment `P` (or skip if solving for term). 4. Lines 180–310: Input print-depth `D`, main amortization loop printing each period’s payment, interest, principal, and balance. 5. Lines 320–341: Final period handling — last payment clears the residual balance exactly. 6. Lines 350–379: Summary, re-run prompt, `NEW` on exit. 7. Lines 400–450: Alternate entry for “solve for term” mode. 8. Lines 500–580: Subroutine — prompts for COPY (print), then `CLS`; uses `SLOW`/`FAST` to ensure a clean print. ### Notable Techniques - **Decimal normalisation subroutine (lines 10–24):** Because `STR$` may produce `"5"`, `".5"`, `"5.5"`, or `"5.50"`, the subroutine examines the string character by character to determine how many characters short of two decimal places the result is, then adds the deficit to `Z` so callers can back-compute correct `TAB` positions. It does not pad the string itself — it only adjusts the column offset used in the subsequent `PRINT TAB`. - **Display-full guard (line 265):**`IF PEEK 16442<4 THEN GOSUB 500` — location 16442 (DFILE pointer low byte) is checked to detect that the display file is close to overflowing the 24-line screen. When true, a COPY/CLS cycle is triggered. - **Clamping D to N (line 200):**`LET D=D+(N-D)*(D>N)` uses a Boolean-as-integer idiom (true=1, false=0) to silently cap the print-depth at the total payment count without an `IF` statement. - **Loop endpoint adjustment (line 260):**`FOR J=1 TO D-(N=D)` — again uses Boolean arithmetic; when printing all periods, the loop runs to `D-1` and the final period is handled separately (lines 330–341) so the last payment can be adjusted to clear any floating-point residual in the balance. - **INKEY$ debounce (lines 520–540):** Three-stage loop — flush any held key, wait for a keypress, validate it is Y or N — preventing accidental COPY triggering. ### Program 2 – Rule of 78s Interest Allocator (lines 10–510) Computes the cumulative interest rebate schedule under the Rule of 78s (sum-of-digits) method. For a loan with `N` payments and total interest `I`, it iterates from payment `N` down to 1, accumulating digit sums to derive the interest earned in each period and the interest remaining. ### Structure 1. Lines 10–90: Subroutine — append `"0"` if string ends one digit after the decimal point, or append `".00"` if no decimal present. Updates `H` to the new length. 2. Lines 91–94: Title, pause, clear. 3. Lines 100–165: Input interest total and number of payments. 4. Lines 170–260: Compute `Z=N*(N+1)/2`, then loop printing cumulative interest paid and interest remaining. ### Notable Techniques - This program’s decimal subroutine (lines 10–90) *modifies*`A$` directly by appending characters, unlike Program 1’s subroutine which only adjusts a column counter. - The loop runs `FOR K=N TO 1 STEP -1` and accumulates `M=M+K`, so `M/Z` gives the fraction of total interest attributed to periods 1 through `N-K+1` — a clean implementation of the sum-of-digits method. - Column alignment uses `TAB 13-H` and `TAB 23-H` where `H` is the post-normalisation string length, right-aligning the two money columns. ### Program 3 – Compound Interest Graph (lines 10–3010) Accepts investment amount, annual rate, periods per year, and term in years, then plots a graphical growth curve using `PLOT` against drawn axes, with dynamic Y-axis scaling and X-axis labels adapted to the term length. ### Structure 1. Lines 10–90: Subroutine (same decimal normalisation as Program 1’s version). 2. Lines 450–480: Title banner and CLS. 3. Lines 500–630: Input collection; compute effective annual growth factor `B=(I/100/P+1)**P`. 4. Lines 640–710: Compute final value `A1`; if too small for the plot grid, multiply by 10 and note the scaling. 5. Lines 720–860: Draw Y-axis (vertical PLOT), X-axis (horizontal PLOT), tick marks, and Y-axis labels. 6. Lines 870–940 / 1500–1610 / 2000–2070: Three branches select X-axis tick spacing and labels based on term (≤12, 13–25, >25 years). 7. Lines 20–190: Subroutine entry point — plot the growth curve, print final yield, prompt to repeat. ### Notable Techniques - **Ceiling division (line 700):**`LET X=(INT (A1/32))+((A1/32)>INT (A1/32))` computes ⌈A1/32⌉ using Boolean arithmetic, ensuring the Y-axis scale unit always covers the full range. - **Incremental plotting (lines 60–130):** Rather than computing each Y value from scratch, the loop tracks the previous bar height in `B1` and distributes the height gain evenly across the `H` pixels in each interval using integer division, producing a smooth stepped curve. - **Inverse-video title (line 150):**`"%Y%I%E%L%D%S"` prints “YIELDS” in inverse video characters, immediately followed by the numeric yield ratio. - The REM at line 10 contains a quoted `"X"` — this is a common ZX81/TS1000 technique to store a single byte (here the character X) inside a REM for later PEEK/POKE use, though it is not used programmatically here. - `CHR$ 7` at lines 910/1520/2040 prints the ↑ (up-arrow / exponentiation) character, used decoratively as a tick mark on the X-axis. ### Program 4 – Depreciation Table (lines 100–710) Prints a side-by-side comparison of straight-line depreciation and sum-of-years-digits depreciation for a fixed asset, showing annual depreciation charge and book value for each year. ### Structure 1. Lines 100–130: Title, pause, CLS. 2. Lines 200–320: Input cost `C`, scrap value `SV`, years `N`; precompute straight-line charge `DC` and sum-of-digits denominator `S`. 3. Lines 490–510: Column headers. 4. Lines 520–670: Main loop — each iteration prints year number, straight-line depreciation and running book value, then sum-of-years depreciation (`T/S * (C-SV)`) and its running book value. 5. Line 680: `STOP`. ### Notable Techniques - Column alignment is handled throughout with the pattern `TAB (N-LEN A$)` after converting the value to a string, right-aligning numbers in fixed-width columns without any padding subroutine. - The sum-of-years fraction at line 610 is `T/S` where `T=N+1-K` counts down the remaining useful years — a textbook implementation of the SYD method. - Unlike the other programs, this one ends with `STOP` at line 680, with the `SAVE`/`GOTO` pair unreachably at lines 700–710, suggesting the `STOP` was added during development and the save lines were not updated. ### Bugs and Anomalies | Program | Location | Issue | | --- | --- | --- | | Amortization | Line 540 | `IF INKEY$<>"Y" AND INKEY$<>"N"` samples INKEY$ twice in one statement; since INKEY$ is re-evaluated each reference, the two reads may return different values if keys are transitioning. | | Amortization | Lines 145/180 | When `Z$="B"`, the program jumps from line 145 to 180, skipping line 150 where `P` would be computed — but line 400 has already set `P` from input, so this is intentional. | | Compound | Line 55 | `IF N>T THEN GOTO 150` exits the outer loop early when the number of plotted periods exceeds the term, but `N` is also used as the loop counter for the compound periods — reuse of `N` across different contexts could cause confusion if the program is modified. | | Depreciation | Line 680 | `STOP` makes lines 700–710 (SAVE and re-entry GOTO) unreachable during normal execution. | ## Source Code ``` 10 LET X1=(INT (X1*100))/100 11 LET A$=STR$ X1 12 LET Z=(LEN A$) 13 IF Z=1 THEN GOTO 23 14 IF Z<>2 THEN GOTO 18 15 IF A$(1)<>"." THEN GOTO 23 16 LET Z=Z+1 17 GOTO 24 18 IF A$(Z-1)<>"." THEN GOTO 22 19 LET Z=Z+1 20 GOTO 24 22 IF A$(Z-2)="." THEN GOTO 24 23 LET Z=Z+3 24 RETURN 25 PRINT " AMORTIZATION" 26 PRINT " COPYRIGHT UAS" 27 PRINT "BOX612 HADDONFIELD,N.J. 08033" 28 PRINT "*******************************" 29 PRINT "AMOUNT OF LOAN="; 30 INPUT A 35 PRINT A 40 PRINT "ANNUAL INTEREST RATE(O/O)="; 50 INPUT A0 55 PRINT A0 60 PRINT "NO. PAYMENTS PERIODS PER YEAR="; 70 INPUT P0 75 PRINT P0 76 PRINT "INPUT CHOICE:" 77 PRINT "A=SOLVE FOR MONTHLY PAYMENT" 78 PRINT "B=SOLVE FOR TERM OF LOAN" 79 INPUT Z$ 80 IF Z$="B" THEN GOTO 400 82 PRINT "NUMBER OF PAYMENTS="; 90 INPUT N 95 PRINT N 100 LET B=A 130 LET I=A0/(100*P0) 140 LET X=1+I 145 IF Z$="B" THEN GOTO 180 150 LET S=(1-1/X**N)/(X-1) 160 LET P=A/S 180 PRINT "NUMBER OF PAYMENTS TO PRINT="; 190 INPUT D 195 PRINT D 200 LET D=D+(N-D)*(D>N) 210 PRINT 220 PRINT "********************************" 230 PRINT "NO.% PAYMNT% INTRST% PRINPL% BALANCE" 250 PRINT 255 LET I2=0 260 FOR J=1 TO D-(N=D) 265 IF PEEK 16442<4 THEN GOSUB 500 270 LET I1=B*I 275 LET I2=I2+I1 280 LET P1=P-I1 290 LET B=B-P1 291 PRINT J; 292 LET X1=P 293 GOSUB 10 294 PRINT TAB 10-Z;X1; 295 LET X1=I1 296 GOSUB 10 297 PRINT TAB 17-Z;X1; 298 LET X1=P1 299 GOSUB 10 300 PRINT TAB 24-Z;X1; 306 PRINT TAB 25;INT B 310 NEXT J 320 IF D<>N THEN GOTO 350 330 LET I1=B*I 331 PRINT N; 332 LET X1=I1+B 333 GOSUB 10 334 PRINT TAB 10-Z;X1; 335 LET X1=I1 336 GOSUB 10 337 PRINT TAB 17-Z;X1; 338 LET X1=B 339 GOSUB 10 340 PRINT TAB 24-Z;X1; 341 PRINT TAB 25;"0" 350 PRINT "UP TO PERIOD ";J 360 PRINT "THE INTEREST IS ";INT I2 365 GOSUB 500 370 PRINT "ANOTHER SCHEDULE Y OR N" 375 INPUT X$ 376 CLS 378 IF X$="Y" THEN GOTO 25 379 NEW 400 PRINT "MONTHLY PAYMENT="; 410 INPUT P 420 PRINT P 430 LET S=A/P 440 LET N=LN (1/(1-(S*(X-1))))/LN X 450 GOTO 100 500 PRINT AT 21,0;"COPY Y OR N" 510 SLOW 520 IF INKEY$<>"" THEN GOTO 520 530 IF INKEY$="" THEN GOTO 530 540 IF INKEY$<>"Y" AND INKEY$<>"N" THEN GOTO 520 550 FAST 560 IF INKEY$="Y" THEN COPY 570 CLS 580 RETURN 2000 SAVE "AMO%R" 2010 GOTO 25 10 LET H=LEN A$ 20 IF A$(H-1)<>"." THEN GOTO 60 30 LET A$=A$+"0" 40 LET H=H+1 50 RETURN 60 IF A$(H-2)="." THEN RETURN 70 LET A$=A$+".00" 80 LET H=H+3 90 RETURN 91 PRINT AT 5,11;"RULE OF 78" 92 PRINT "UAS BOX 612 HADDONFIELD NJ 08033" 93 PAUSE 200 94 CLS 100 PRINT "AMOUNT OF INTEREST=% " 110 INPUT I 120 PRINT AT 0,19;I 130 PRINT "NUMBER OF PAYMENTS=% " 140 INPUT N 150 PRINT AT 1,19;N 160 LET Z=N*(N+1)/2 170 PRINT "*******************************" 180 PRINT "NO. CUM INT INT LEFT" 185 LET M=0 190 FOR K=N TO 1 STEP -1 195 LET M=M+K 196 LET X=(INT (I*M*100/Z))/100 200 LET A$=STR$ X 210 GOSUB 10 220 PRINT N-K+1;TAB 13-H;A$; 230 LET A$=STR$ (I-X) 240 GOSUB 10 250 PRINT TAB 23-H;A$ 260 NEXT K 500 SAVE "7%8" 510 GOTO 91 10 REM "X" 20 LET B1=A 30 LET C1=A 40 LET N=1 50 FOR K=12+H TO 62 STEP H 55 IF N>T THEN GOTO 150 60 LET V=INT (A*B**N) 70 FOR L=K-H+1 TO K 80 LET B1=(INT ((V-C1)/H))+B1 90 PLOT L,4+(B1/(X)) 100 NEXT L 110 LET C1=V 120 LET B1=V 130 LET N=N+1 140 NEXT K 150 PRINT AT 0,18;"%Y%I%E%L%D%S";A1/C 160 PRINT AT 21,0;"AGAIN Y OR N" 170 INPUT U$ 180 IF U$="Y" THEN GOTO 500 190 STOP 450 PRINT AT 5,6;"COMPOUND COPYRIGHT UAS" 460 PRINT "UAS BOX 612 HADDONFIELD NJ 08033" 470 PAUSE 200 480 CLS 500 PRINT "INVESTMENT=% " 510 INPUT A 520 PRINT AT 0,11;A 530 PRINT "ANNUAL INTEREST RATE (O/O)=% " 540 INPUT I 550 PRINT AT 1,27;I 560 PRINT "PERIODS/YR=% " 570 INPUT P 580 PRINT AT 2,11;P 590 PRINT AT 2,25;"YRS=% " 600 INPUT T 610 PRINT AT 2,29;T 630 LET B=(I/100/P+1)**P 640 LET A0=INT A 650 LET A1=INT (A*B**T) 655 LET C=1 660 IF A1>8 THEN GOTO 700 670 LET C=10 680 PRINT AT 18,20;"%P%L%O%T%T%E%D% %X% %1%0" 690 LET A1=INT (C*A*B**T) 700 LET X=(INT (A1/32))+((A1/32)>INT (A1/32)) 710 LET X1=X*32 720 FOR K=5 TO 37 730 PLOT 12,K 740 NEXT K 750 FOR K=12 TO 62 760 PLOT K,5 770 NEXT K 780 FOR K=5 TO 37 STEP 8 790 PLOT 11,K 800 NEXT K 805 LET J=4 810 FOR K=3 TO 19 STEP 4 820 LET A$=STR$ (8*X*J) 830 LET Z=LEN A$ 840 PRINT AT K,5-Z;8*J*X 850 LET J=J-1 860 NEXT K 870 IF T<=12 THEN GOTO 1500 880 IF T>13 AND T<=25 THEN GOTO 2000 890 LET H=1 900 FOR K=6 TO 31 STEP 5 910 PRINT AT 19,K;CHR$ 7 920 NEXT K 930 PRINT AT 20,6;"0 10 20 30 40 50" 940 GOTO 20 1500 LET Y=0 1505 LET Y1=0 1508 LET H=4 1510 FOR K=6 TO 31 STEP 2 1520 PRINT AT 19,K;CHR$ 7 1530 IF K>=25 THEN LET Y=1 1535 PRINT AT 20,K;Y 1540 LET Y=Y+1 1550 IF K<25 THEN GOTO 1600 1560 PRINT AT 21,K;Y1 1570 LET Y1=Y1+1 1600 NEXT K 1610 GOTO 20 2000 LET H=2 2030 FOR K=6 TO 31 STEP 5 2040 PRINT AT 19,K;CHR$ 7 2050 NEXT K 2060 PRINT AT 20,6;"0 5 10 15 20 25" 2070 GOTO 20 3000 SAVE "COM%P" 3010 GOTO 450 100 PRINT AT 5,9;"DEPRECIATION" 110 PRINT AT 6,0;"UAS BOX 612 HADDONFIELD,NJ 08033" 120 PAUSE 200 130 CLS 200 PRINT "COST OF ASSET=% " 210 INPUT C 220 PRINT AT 0,14;C 230 PRINT "SCRAP VALUE=% " 240 INPUT SV 250 PRINT AT 1,12;SV 260 PRINT "NO. OF YEARS=% " 270 INPUT N 280 PRINT AT 2,13;N 290 LET DC=INT ((C-SV)/N) 300 LET S=(N*(N+1))/2 310 LET N1=N 320 LET L=INT C 330 LET O=INT C 490 PRINT "********************************" 500 PRINT "YR :STRAIGHT LINE :SUM OF YEARS" 510 PRINT " : DEPR. BK VAL : DEPR. BK VAL" 520 FOR K=1 TO N 530 LET A$=STR$ K 540 PRINT TAB (2-LEN A$);K;" :"; 550 LET A$=STR$ DC 560 PRINT TAB (10-LEN A$);DC; 570 LET L=L-DC 580 LET A$=STR$ L 590 PRINT TAB (17-LEN A$);L;" :"; 600 LET T=N+1-K 610 LET X=INT ((T/S)*(C-SV)) 620 LET A$=STR$ X 630 PRINT TAB (25-LEN A$);X; 640 LET O=O-X 650 LET A$=STR$ O 660 PRINT TAB (32-LEN A$);O 670 NEXT K 680 STOP 700 SAVE "DE%P" 710 GOTO 100 ```