Financial

Date: 198x
Type: Program
Platform(s): TS 1000
Tags: Finance

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

ProgramLocationIssue
AmortizationLine 540IF 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.
AmortizationLines 145/180When 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.
CompoundLine 55IF 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.
DepreciationLine 680STOP makes lines 700–710 (SAVE and re-entry GOTO) unreachable during normal execution.

Content

Appears On

Related Products

Related Articles

Related Content

Image Gallery

Financial

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 
\n2000 SAVE "AMO%R"
\n2010 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
\n1500 LET Y=0
\n1505 LET Y1=0
\n1508 LET H=4
\n1510 FOR K=6 TO 31 STEP 2
\n1520 PRINT AT 19,K;CHR$ 7
\n1530 IF K>=25 THEN LET Y=1
\n1535 PRINT AT 20,K;Y
\n1540 LET Y=Y+1
\n1550 IF K<25 THEN GOTO 1600
\n1560 PRINT AT 21,K;Y1
\n1570 LET Y1=Y1+1
\n1600 NEXT K
\n1610 GOTO 20
\n2000 LET H=2
\n2030 FOR K=6 TO 31 STEP 5
\n2040 PRINT AT 19,K;CHR$ 7
\n2050 NEXT K
\n2060 PRINT AT 20,6;"0    5   10   15   20   25"
\n2070 GOTO 20
\n3000 SAVE "COM%P"
\n3010 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

Note: Type-in program listings on this website use ZMAKEBAS notation for graphics characters.

People

No people associated with this content.

Scroll to Top