--- title: "Home Mortgage" id: 56666 type: "computer_media" slug: "boss-t117-home-mortgage" url: "http://localhost/computer_media/boss-t117-home-mortgage/" markdown_url: "http://localhost/computer_media/boss-t117-home-mortgage.md" published_at: "2024-09-22T23:31:36+00:00" modified_at: "2026-04-03T07:59:02+00:00" author: "David Anderson" featured_image: url: "http://localhost/wp-content/uploads/2024/09/PrePay.png" excerpt: "Two interlocking mortgage programs calculate full amortisation schedules and show exactly how much money extra monthly payments can save over the life of a loan." 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: "S & S Company" slug: "s-s-company-the" taxonomy: "post_tag" url: "http://localhost/tag/s-s-company-the/" - 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: "Cassette" download_url: "https://archive.org/download/timex-sinclair-software-archive/Boss%20T117%20Home%20Mortgage%20%28198X%29%28BOSS%29%28TS1000%29%28US%29%28Program%29.zip" mediadate: "198X" producer_company: - id: 11258 title: "S & S Company, The" type: "company" url: "http://localhost/company/s-s-company-the/" images: - url: "http://localhost/wp-content/uploads/2024/09/PrePay.png" - url: "http://localhost/wp-content/uploads/2024/09/MortAna.png" - url: "http://localhost/wp-content/uploads/2024/09/Tape-4.jpg" media_type_tags: "Finance" --- # Home Mortgage 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 | Line | Issue | | --- | --- | | 530 | `A = 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. | | 591 | `IF 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. | | 570 | Uses rounding bias `+0.05` instead of `+0.5` for two decimal places — same systematic issue as Program 1. | | 80–90 | Long 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. ## 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 ```