Home Mortgage

Date: 198X
Type: Cassette
Platform(s): TS 1000
Tags: Finance

This listing contains two separate mortgage-related financial programs. The first, “MORTGAGE PAYMENT ANALYSIS,” calculates amortisation schedules for a loan given principal, number of periods, and annual interest rate, printing each period’s payment breakdown to screen and optionally to a printer via LPRINT. The second, “PREPAYMENT,” shows the effect of making extra monthly payments on a mortgage, displaying a table of years remaining, effective interest rate, extra payment per month, and total dollars saved compared to the original repayment schedule. Both programs use a 32-character DIM’d string as a right-justification spacer for formatted numeric output, and both support optional hard-copy output. The amortisation formula uses the standard present-value annuity calculation, with rounding applied via the INT(x*100+0.05)/100 pattern to two decimal places.


Program Analysis

The listing contains two entirely independent BASIC programs saved back-to-back. The first (lines 10–9999) is a period-by-period amortisation schedule generator named MORTGAGE ANALYSI S. The second (lines 10–9999, restarting) is a prepayment-savings calculator named PREPAYMENT. Both share structural idioms but differ in purpose.

Program 1 – Mortgage Payment Analysis

Program Structure

  • Lines 10–30: Initialise counter C, dimension spacer string C$, enter SLOW mode.
  • Line 100: Title banner in inverse video.
  • Lines 1000–1130: User input phase — principal P, periods L, annual rate R, hard-copy flag Y$, starting period WP.
  • Line 1900: Switch to FAST mode for calculation.
  • Lines 2000–2070: Compute monthly payment M using the annuity formula.
  • Lines 2090–2320: Main amortisation loop over N from 1 to L.
  • Lines 3000–3220: GOSUB for LPRINT hard-copy output of one period’s data.
  • Lines 3500–3550: GOSUB to format a number string to exactly two decimal places.

Annuity Calculation

The monthly payment is derived by the standard present-value annuity formula. The monthly interest rate is I = R/1200. The compound factor T is built iteratively in a loop rather than using a power function (which is unavailable as a single operator):

  1. Lines 2020–2040: T = (1+I)^L computed by repeated multiplication.
  2. Line 2050: T = 1 - 1/T, giving the annuity denominator.
  3. Line 2060: M = P*I/T.
  4. Line 2070: Rounds M to two decimal places using INT(M*100+0.05)/100.

Screen vs. Printer Output

The main loop at line 2185 skips screen output for periods before WP or when hard copy is requested (Y$="Y"). The GOSUB at line 2310 handles printer output and itself returns immediately unless both conditions are met (line 3000). This means screen and printer output are mutually exclusive by design — if Y$="Y", no screen display of individual periods occurs.

String Right-Justification

The 32-character string C$ (initialised by DIM to all spaces) is sliced with C$( TO 18-LEN STR$ N) to pad labels and values to a fixed column width for LPRINT output. This is a compact ZX81 idiom that avoids explicit space-printing loops.

Decimal Formatting Subroutine (Lines 3500–3550)

The subroutine at 3500 ensures a number always prints with exactly two decimal places:

  • Re-rounds to two places via INT(100*PP+0.05)/100.
  • If the result is a whole number (no decimal part), appends ".00".
  • If there is only one decimal digit, appends "0".

Note that the test at line 3530 uses VAL P$=INT VAL P$; because STR$ on a ZX81 never produces a trailing .0 for integers, this correctly detects integer values.

Keypress Pause

Line 2302 uses IF INKEY$<>"" THEN PAUSE 40000 — if any key is held during scrolling output, it triggers a long pause, giving the user time to read the screen. This is a common ZX81 technique since there is no built-in “press any key to continue” facility.

Anomalies and Notes – Program 1

  • Line 2110 is REM (empty remark) — it appears to be a vestigial page-break handler stub; the counter C is incremented at 2315 and checked at 2100, but the only action taken is resetting C=0 with no actual page-break output.
  • The rounding bias of +0.05 (rather than the standard +0.5) at lines 2070 and 2140 introduces a systematic downward rounding bias for values with three or more decimal places, which may cause the running principal P to drift slightly over a long schedule.
  • Line 1110 truncates Y$ to its first character, ensuring only “Y” or “N” is compared later.

Program 2 – Prepayment Savings Calculator

Program Structure

  • Lines 10–50: Optional instructions display, gated by PAUSE 40000 / INKEY$ keypress.
  • Lines 60–100: Multi-screen instruction text about prepayment savings.
  • Lines 190–299: Input — mortgage amount P, years Y, interest rate R, hard-copy flag via INKEY$.
  • Lines 300–379: Column header output to screen or printer.
  • Lines 380–640: Outer loop over Q (years remaining, descending); inner loop at 520 simulates one full year.
  • Lines 650–730: Summary output, then RUN to restart.
  • Lines 1000–1010: GOSUB captures original payment OP.
  • Lines 2000–2020: GOSUB formats and LPRINTs one row.
  • Lines 3000–3050: GOSUB prints header to printer.

Hard-Copy Input Technique

Lines 294–296 use a polling loop on INKEY$ rather than INPUT to capture the hard-copy flag. This avoids requiring the user to press ENTER after a single keypress, giving a more responsive feel.

Effective Interest Rate Calculation

Lines 582–585 compute a scaled “effective interest rate” IR for display. The interest component of the current payment minus the principal-only portion is computed, then normalised against its value at the original term (ZZ, saved at line 583), and scaled by the nominal rate R. This produces an approximate effective rate column rather than the nominal rate, though the methodology is heuristic rather than actuarially precise.

Extra Payment Column

EM at line 570 is INT((M - OP)*100 + 0.05)/100 — the difference between the current scenario’s payment and the original full-term payment, representing how much extra per month would be needed to pay off in Y years rather than YY years.

Dollars Saved Column

MX (line 510) holds the total cost of the mortgage at the original term. MY = Y*M*12 is the total cost at the current (shorter) term. The column INT(MX-MY) is the gross saving, truncated to whole dollars.

Anomalies and Notes – Program 2

LineIssue
530A = INT(P*I*100*100+0.5)/100 — multiplies by 10000 then divides by 100, yielding a value 100× too large for the interest component. This appears to be a bug: the division should be by 10000, or the multiply should be by 100. The result is that A (interest portion) and B (principal portion) in this program are scaled incorrectly, though since only the payment total M is displayed rather than the split, the visible output is unaffected.
591IF YY-Q>14 THEN PAUSE 10000 — after 14 rows have scrolled, a pause is inserted to prevent the display from scrolling past readable range. This is a pragmatic screen-paging substitute.
570Uses rounding bias +0.05 instead of +0.5 for two decimal places — same systematic issue as Program 1.
80–90Long string literals exploit the ZX81’s ability to wrap display across multiple screen lines within a single PRINT statement, producing formatted multi-paragraph text from two lines of BASIC.

Shared Idioms Across Both Programs

  • DIM spacer string: Both programs DIM a 32-character string (C$ / Z$) and slice it to generate right-aligned padding for LPRINT columns.
  • FAST/SLOW switching: Both switch to FAST mode for computation and SLOW for display, maximising calculation speed while keeping output readable.
  • Iterative power: Both compute (1+I)^N via a FOR loop, working around the absence of a general exponentiation function for this use case.
  • RUN at line 9999: Both end with RUN to restart after completion, creating a continuous-loop kiosk-style operation.

Content

Appears On

Related Products

Related Articles

Related Content

Image Gallery

Home Mortgage

Source Code

  10 LET C=0
  20 DIM C$(32)
  30 SLOW 
 100 PRINT AT 0,3;"% %M%O%R%T%G%A%G%E% %P%A%Y%M%E%N%T% %A%N%A%L%Y%S%I%S% "
 1000 PRINT ,,"PRINCIPAL OR MORTGAGE AMOUNT    LEFT TO BE PAID?  ";
 1010 INPUT P
 1020 PRINT P
 1030 PRINT ,,"TOTAL NUMBER OF MONTHS OR       PERIODS LEFT? ";
 1040 INPUT L
 1050 PRINT L
 1060 PRINT ,,"ANNUAL INTEREST RATE?  ";
 1070 INPUT R
 1080 PRINT R
 1090 PRINT ,,"DO YOU WANT HARD COPY?"
 1100 INPUT Y$
 1110 LET Y$=Y$(1)
 1120 PRINT ,,"STARTING WITH WHAT PERIOD?"
 1130 INPUT WP
 1900 FAST 
 2000 LET I=R/1200
 2010 LET T=1
 2020 FOR N=1 TO L
 2030 LET T=T*(1+I)
 2040 NEXT N
 2050 LET T=1-(1/T)
 2060 LET M=P*I/T
 2070 LET M=INT (M*100+.05)/100
 2090 FOR N=1 TO L
 2100 IF C<13 THEN GOTO 2140
 2110 REM 
 2120 LET C=0
 2140 LET A=(INT (P*I*100+.05))/100
 2150 LET B=M-A
 2160 LET P=P-B
 2170 SCROLL 
 2185 IF WP>N THEN GOTO 2310
 2186 IF Y$="Y" THEN GOTO 2310
 2190 PRINT "PAYMT NUMBER",N
 2200 SCROLL 
 2210 PRINT "PRINCIPAL LEFT",P
 2220 SCROLL 
 2230 PRINT "PER. PAYMT.",M
 2240 SCROLL 
 2250 PRINT "PRINCIPAL/PER.",B
 2260 SCROLL 
 2270 PRINT "INTEREST/PER.",A
 2280 FOR Z=1 TO 3
 2290 SCROLL 
 2300 NEXT Z
 2302 IF INKEY$<>"" THEN PAUSE 40000
 2305 SLOW 
 2310 GOSUB 3000
 2315 LET C=C+1
 2320 NEXT N
 2500 STOP 
 3000 IF WP>N OR Y$<>"Y" THEN RETURN 
 3010 LET B$="PAYMENT NUMBER"+C$( TO 18-LEN STR$ N)+STR$ N
 3020 LPRINT B$
 3030 LET P$=STR$ P
 3040 GOSUB 3500
 3050 LET B$="PRINCIPAL LEFT"+C$( TO 18-LEN P$)+P$
 3070 LPRINT B$
 3080 LET P$=STR$ M
 3090 GOSUB 3500
 3100 LET B$="PERIOD PAYMENT"+C$( TO 18-LEN P$)+P$
 3110 LPRINT B$
 3120 LET P$=STR$ B
 3130 GOSUB 3500
 3140 LET B$="PD. PRINC./PER."+C$( TO 17-LEN P$)+P$
 3150 LPRINT B$
 3160 LET P$=STR$ A
 3170 GOSUB 3500
 3180 LET B$="PD. INTEREST/PER."+C$( TO 15-LEN P$)+P$
 3190 LPRINT B$
 3200 LPRINT 
 3210 LPRINT 
 3220 RETURN 
 3500 LET PP=VAL P$
 3510 LET PP=INT (100*PP+.05)/100
 3520 LET P$=STR$ PP
 3530 IF VAL P$=INT VAL P$ THEN LET P$=P$+".00"
 3540 IF 10*VAL P$=INT (10*VAL P$) THEN LET P$=P$+"0"
 3550 RETURN 
 9998 SAVE "MORTGAGE ANALYSI%S"
 9999 RUN 
 
 
  10 LET YS=0
  15 DIM Z$(32)
  20 LET A$="..............................."
  30 PRINT "%I%N%S%T%R%U%C%T%I%O%N%S%?"
  40 PAUSE 40000
  50 IF INKEY$<>"Y" THEN GOTO 190
  60 CLS 
  70 PRINT "%H%O%W% %T%O% %S%A%V%E% %M%O%N%E%Y% %O%N% %A% %M%O%R%T%G%A%G%E"
  80 PRINT ,,"   THIS PROGRAM IS DESIGNED TO  SHOW YOU HOW BY PAYING A SMALL  ADDIONAL AMOUNT TO A MONTHLY    MORTGAGE PAYMENT CAN PRODUCE A  DRASTIC CHANGE IN THE LIFE AND  FINAL AMOUNT PAID INTO A MORT-  GAGE."
  90 PRINT "   YOU MAY BE SUPRISED HOW A    LITTLE MORE MONEY ADDED TO A    MONTHLY PAYMENT CAN SUBTRACT    YEARS AND THOUSANDS OF DOLLARS  FROM THE ORIGINAL TOTALS, PAR-  TICULARLY AT TODAY' S 29 AND 30  YEAR MATURITIES AND DOUBLE DIGITINTEREST RATES."
 100 PRINT AT 21,0;"PRESS ENTER TO CONTINUE :::"
 110 INPUT B$
 190 CLS 
 200 PRINT "WHAT IS THE ORIGINAL OR REMAIN- ING AMOUNT OF THE MORTGAGE?" 
 205 SLOW 
 210 INPUT P
 220 LET PP=P
 230 PRINT ,,"HOW MANY YEARS ARE LEFT TO PAY?"
 240 INPUT Y
 260 LET L=12*Y
 270 LET YY=Y
 280 PRINT ,,"WHAT IS THE INTEREST RATE?"
 290 INPUT R
 292 PRINT ,,"DO YOU WANT HARD COPY?"
 294 LET Y$=INKEY$
 296 IF Y$="" THEN GOTO 294
 300 CLS 
 310 FAST 
 315 IF Y$="Y" THEN GOTO 365
 320 SCROLL 
 325 PRINT A$
 326 SCROLL 
 330 PRINT "TTL MON    EFF   XTR      $"
 335 SCROLL 
 340 PRINT "YRS PYMT   INT   PER    SAVED"
 350 SCROLL 
 360 PRINT "           RT.   MON"
 365 IF Y$="Y" THEN GOSUB 3000
 366 IF Y$="Y" THEN GOTO 380
 370 SCROLL 
 375 PRINT A$
 376 SCROLL 
 380 FOR Q=Y TO 1 STEP -1
 390 FAST 
 400 LET I=R/1200
 410 LET T=1
 420 FOR X=1 TO L
 430 LET T=T*(1+I)
 440 NEXT X
 450 LET T=1/T
 460 LET T=1-T
 470 LET M=P*I/T
 480 LET M=INT (M*100+.5)/100
 490 IF YY<>Y THEN GOTO 520
 500 LET MX=INT ((PP*I/T)*100+.5)/100
 510 LET MX=MX*12*YY
 520 FOR Z=1 TO L
 530 LET A=(INT (P*I*100*100+.5))/100
 540 LET B=M-A
 550 LET P=P-B
 560 IF YS=0 THEN GOSUB 1000
 570 LET EM=INT ((M-OP)*100+.05)/100
 580 LET MY=Y*M*12
 582 LET IR=M-(PP/(Y*12))
 583 IF Y=YY THEN LET ZZ=IR
 584 LET IR=R*(IR/ZZ)
 585 LET IR=INT ((IR)*100+.05)/100
 586 IF Y$="Y" THEN GOTO 592
 588 SCROLL 
 590 PRINT Y;TAB 3;M;TAB 11;IR;TAB 17;EM;TAB 25;INT (MX-MY)
 591 IF YY-Q>14 THEN PAUSE 10000
 592 IF Y$="Y" THEN GOSUB 2000
 600 LET P=PP
 610 LET YS=YS+1
 620 LET L=L-12
 630 LET Y=Y-1
 640 NEXT Q
 650 SCROLL 
 660 PRINT A$
 665 SCROLL 
 670 PRINT "ORIGINAL MORTGAGE IF PAID IN"
 680 SCROLL 
 690 PRINT YY;" YEARS WOULD COST $";MX
 700 IF Y$="Y" THEN LPRINT "ORIGINAL MORTGAGE IF PAID IN"
 710 IF Y$="Y" THEN LPRINT YY;" YEARS WOULD COST $";MX
 720 PAUSE 1000
 730 CLS 
 740 RUN 
 1000 LET OP=M
 1010 RETURN 
 2000 LET B$=STR$ Y+Z$( TO 3-LEN STR$ Y)+STR$ M+Z$( TO 8-LEN STR$ M)+STR$ IR+Z$( TO 6-LEN STR$ IR)+STR$ EM+Z$( TO 8-LEN STR$ EM)+STR$ (MX-MY)
 2010 LPRINT B$
 2020 RETURN 
 3000 LPRINT A$
 3010 LPRINT "TTL MON    EFF   XTR      $"
 3020 LPRINT "YRS PYMT   INT   PER    SAVED"
 3030 LPRINT "           RT.   MON"
 3040 LPRINT A$
 3050 RETURN 
 9998 SAVE "PREPAYMEN%T"
 9999 RUN 

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

People

No people associated with this content.

Scroll to Top